An update to this patch series: I found the gpio that was keeping the pcie slots in reset. Azalia HDAC is also working now.
Remaining problems: - While my ati pcie graphics card works in the peg slot, a network card (x1 link) doesn't, but with the asus bios both work. - ACPI still giving stop 0xa5 (next debugging target)
This adds pci device ids and pci_driver structs for the K8T890 CF variant. It also adds additional dev_find_device calls in k8t890_ctrl.c for subfunctions 3 and 7.
Signed-off-by: Tobias Diedrich ranma+coreboot@tdiedrich.de
---
Index: src/southbridge/via/k8t890/k8t890_host.c =================================================================== --- src/southbridge/via/k8t890/k8t890_host.c.orig 2010-10-27 11:34:19.000000000 +0200 +++ src/southbridge/via/k8t890/k8t890_host.c 2010-10-27 11:40:16.000000000 +0200 @@ -76,6 +76,12 @@ .device = PCI_DEVICE_ID_VIA_K8T890CE_0, };
+static const struct pci_driver northbridge_driver_tcf __pci_driver = { + .ops = &host_ops_t, + .vendor = PCI_VENDOR_ID_VIA, + .device = PCI_DEVICE_ID_VIA_K8T890CF_0, +}; + static const struct pci_driver northbridge_driver_m __pci_driver = { .ops = &host_ops_m, .vendor = PCI_VENDOR_ID_VIA, Index: src/southbridge/via/k8t890/k8t890_traf_ctrl.c =================================================================== --- src/southbridge/via/k8t890/k8t890_traf_ctrl.c.orig 2010-10-27 11:34:19.000000000 +0200 +++ src/southbridge/via/k8t890/k8t890_traf_ctrl.c 2010-10-27 11:40:16.000000000 +0200 @@ -144,6 +144,12 @@ .device = PCI_DEVICE_ID_VIA_K8T890CE_5, };
+static const struct pci_driver northbridge_driver_tcf __pci_driver = { + .ops = &traf_ctrl_ops_t, + .vendor = PCI_VENDOR_ID_VIA, + .device = PCI_DEVICE_ID_VIA_K8T890CF_5, +}; + static const struct pci_driver northbridge_driver_m __pci_driver = { .ops = &traf_ctrl_ops_m, .vendor = PCI_VENDOR_ID_VIA, Index: src/southbridge/via/k8t890/k8t890_dram.c =================================================================== --- src/southbridge/via/k8t890/k8t890_dram.c.orig 2010-10-27 11:34:19.000000000 +0200 +++ src/southbridge/via/k8t890/k8t890_dram.c 2010-10-27 11:40:16.000000000 +0200 @@ -170,6 +170,12 @@ .device = PCI_DEVICE_ID_VIA_K8T890CE_3, };
+static const struct pci_driver northbridge_driver_tcf __pci_driver = { + .ops = &dram_ops_t, + .vendor = PCI_VENDOR_ID_VIA, + .device = PCI_DEVICE_ID_VIA_K8T890CF_3, +}; + static const struct pci_driver northbridge_driver_m __pci_driver = { .ops = &dram_ops_m, .vendor = PCI_VENDOR_ID_VIA, Index: src/southbridge/via/k8t890/k8t890_error.c =================================================================== --- src/southbridge/via/k8t890/k8t890_error.c.orig 2010-10-27 11:34:19.000000000 +0200 +++ src/southbridge/via/k8t890/k8t890_error.c 2010-10-27 11:40:16.000000000 +0200 @@ -48,6 +48,12 @@ .device = PCI_DEVICE_ID_VIA_K8T890CE_1, };
+static const struct pci_driver northbridge_driver_tcf __pci_driver = { + .ops = &error_ops, + .vendor = PCI_VENDOR_ID_VIA, + .device = PCI_DEVICE_ID_VIA_K8T890CF_1, +}; + static const struct pci_driver northbridge_driver_m __pci_driver = { .ops = &error_ops, .vendor = PCI_VENDOR_ID_VIA, Index: src/southbridge/via/k8t890/k8t890_ctrl.c =================================================================== --- src/southbridge/via/k8t890/k8t890_ctrl.c.orig 2010-10-27 11:34:19.000000000 +0200 +++ src/southbridge/via/k8t890/k8t890_ctrl.c 2010-10-27 11:42:58.000000000 +0200 @@ -36,8 +36,12 @@ devfun3 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_K8T890CE_3, 0);
- if (!devfun3) - devfun3 = dev_find_device(PCI_VENDOR_ID_VIA, + if (!devfun3) + devfun3 = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_K8T890CF_3, 0); + + if (!devfun3) + devfun3 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_K8M890CE_3, 0);
pci_write_config8(dev, 0x70, 0xc2); @@ -175,6 +179,12 @@ .device = PCI_DEVICE_ID_VIA_K8T890CE_7, };
+static const struct pci_driver northbridge_driver_tcf __pci_driver = { + .ops = &ctrl_ops, + .vendor = PCI_VENDOR_ID_VIA, + .device = PCI_DEVICE_ID_VIA_K8T890CF_7, +}; + static const struct pci_driver northbridge_driver_m __pci_driver = { .ops = &ctrl_ops, .vendor = PCI_VENDOR_ID_VIA, Index: src/southbridge/via/vt8237r/vt8237_ctrl.c =================================================================== --- src/southbridge/via/vt8237r/vt8237_ctrl.c.orig 2010-10-27 11:34:19.000000000 +0200 +++ src/southbridge/via/vt8237r/vt8237_ctrl.c 2010-10-27 11:48:47.000000000 +0200 @@ -37,6 +37,9 @@ devfun3 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_K8M890CE_3, 0); if (!devfun3) + devfun3 = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_K8T890CF_3, 0); + if (!devfun3) die("Unknown NB");
/* CPU to PCI Flow Control 1 & 2, just fill in recommended. */ @@ -109,6 +112,9 @@ if (!devfun7) devfun7 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_K8M890CE_7, 0); + if (!devfun7) + devfun7 = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_K8T890CF_7, 0); /* No pairing NB was found. */ if (!devfun7) return; Index: src/include/device/pci_ids.h =================================================================== --- src/include/device/pci_ids.h.orig 2010-10-27 11:34:19.000000000 +0200 +++ src/include/device/pci_ids.h 2010-10-27 11:40:16.000000000 +0200 @@ -1204,6 +1204,13 @@ #define PCI_DEVICE_ID_VIA_K8T890CE_4 0x4238 #define PCI_DEVICE_ID_VIA_K8T890CE_5 0x5238 #define PCI_DEVICE_ID_VIA_K8T890CE_7 0x7238 +#define PCI_DEVICE_ID_VIA_K8T890CF_0 0x0351 +#define PCI_DEVICE_ID_VIA_K8T890CF_1 0x1351 +#define PCI_DEVICE_ID_VIA_K8T890CF_2 0x2351 +#define PCI_DEVICE_ID_VIA_K8T890CF_3 0x3351 +#define PCI_DEVICE_ID_VIA_K8T890CF_4 0x4351 +#define PCI_DEVICE_ID_VIA_K8T890CF_5 0x5351 +#define PCI_DEVICE_ID_VIA_K8T890CF_7 0x7351 #define PCI_DEVICE_ID_VIA_K8M890CE_0 0x0336 #define PCI_DEVICE_ID_VIA_K8M890CE_1 0x1336 #define PCI_DEVICE_ID_VIA_K8M890CE_2 0x2336
Hi,
Acked-by: Rudolf Marek r.marek@assembler.cz
Committed revision 6012.
Thanks, Rudolf
=================================================================== --- src/southbridge/via/k8t890/k8t890_ctrl.c.orig 2010-10-27 11:34:19.000000000 +0200 +++ src/southbridge/via/k8t890/k8t890_ctrl.c 2010-10-27 11:42:58.000000000 +0200 @@ -36,8 +36,12 @@ devfun3 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_K8T890CE_3, 0);
if (!devfun3)
devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
if (!devfun3)
devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_K8T890CF_3, 0);
if (!devfun3)
devfun3 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_K8M890CE_3, 0);
pci_write_config8(dev, 0x70, 0xc2);
@@ -175,6 +179,12 @@ .device = PCI_DEVICE_ID_VIA_K8T890CE_7, };
+static const struct pci_driver northbridge_driver_tcf __pci_driver = {
- .ops =&ctrl_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CF_7,
+};
- static const struct pci_driver northbridge_driver_m __pci_driver = { .ops =&ctrl_ops, .vendor = PCI_VENDOR_ID_VIA,
Index: src/southbridge/via/vt8237r/vt8237_ctrl.c
--- src/southbridge/via/vt8237r/vt8237_ctrl.c.orig 2010-10-27 11:34:19.000000000 +0200 +++ src/southbridge/via/vt8237r/vt8237_ctrl.c 2010-10-27 11:48:47.000000000 +0200 @@ -37,6 +37,9 @@ devfun3 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_K8M890CE_3, 0); if (!devfun3)
devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_K8T890CF_3, 0);
if (!devfun3) die("Unknown NB");
/* CPU to PCI Flow Control 1& 2, just fill in recommended. */
@@ -109,6 +112,9 @@ if (!devfun7) devfun7 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_K8M890CE_7, 0);
- if (!devfun7)
devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
/* No pairing NB was found. */ if (!devfun7) return;PCI_DEVICE_ID_VIA_K8T890CF_7, 0);
Index: src/include/device/pci_ids.h
--- src/include/device/pci_ids.h.orig 2010-10-27 11:34:19.000000000 +0200 +++ src/include/device/pci_ids.h 2010-10-27 11:40:16.000000000 +0200 @@ -1204,6 +1204,13 @@ #define PCI_DEVICE_ID_VIA_K8T890CE_4 0x4238 #define PCI_DEVICE_ID_VIA_K8T890CE_5 0x5238 #define PCI_DEVICE_ID_VIA_K8T890CE_7 0x7238 +#define PCI_DEVICE_ID_VIA_K8T890CF_0 0x0351 +#define PCI_DEVICE_ID_VIA_K8T890CF_1 0x1351 +#define PCI_DEVICE_ID_VIA_K8T890CF_2 0x2351 +#define PCI_DEVICE_ID_VIA_K8T890CF_3 0x3351 +#define PCI_DEVICE_ID_VIA_K8T890CF_4 0x4351 +#define PCI_DEVICE_ID_VIA_K8T890CF_5 0x5351 +#define PCI_DEVICE_ID_VIA_K8T890CF_7 0x7351 #define PCI_DEVICE_ID_VIA_K8M890CE_0 0x0336 #define PCI_DEVICE_ID_VIA_K8M890CE_1 0x1336 #define PCI_DEVICE_ID_VIA_K8M890CE_2 0x2336
This adds the VT8237A LPC device id and corresponding pci_locate_device calls in vt8237r_early_smbus.c plus the pci_driver struct in vt8237r_lpc.c
Signed-off-by: Tobias Diedrich ranma+coreboot@tdiedrich.de
---
Index: src/southbridge/via/vt8237r/vt8237r_early_smbus.c =================================================================== --- src/southbridge/via/vt8237r/vt8237r_early_smbus.c.orig 2010-10-27 11:34:19.000000000 +0200 +++ src/southbridge/via/vt8237r/vt8237r_early_smbus.c 2010-10-27 11:55:50.000000000 +0200 @@ -149,6 +149,11 @@ /* Power management controller */ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT8237S_LPC), 0); + if (dev == PCI_DEV_INVALID) { + /* Power management controller */ + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237A_LPC), 0); + } if (dev == PCI_DEV_INVALID) die("Power management controller not found\n"); } @@ -243,6 +248,11 @@ /* Power management controller */ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT8237S_LPC), 0); + if (dev == PCI_DEV_INVALID) { + /* Power management controller */ + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237A_LPC), 0); + } if (dev == PCI_DEV_INVALID) return;
@@ -298,6 +308,11 @@ /* Power management controller */ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT8237S_LPC), 0); + if (dev == PCI_DEV_INVALID) { + /* Power management controller */ + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237A_LPC), 0); + } if (dev == PCI_DEV_INVALID) return; } @@ -322,6 +337,11 @@ /* Power management controller */ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT8237S_LPC), 0); + if (dev == PCI_DEV_INVALID) { + /* Power management controller */ + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237A_LPC), 0); + } if (dev == PCI_DEV_INVALID) die("Power management controller not found\n"); } Index: src/southbridge/via/vt8237r/vt8237r_lpc.c =================================================================== --- src/southbridge/via/vt8237r/vt8237r_lpc.c.orig 2010-10-27 11:34:19.000000000 +0200 +++ src/southbridge/via/vt8237r/vt8237r_lpc.c 2010-10-27 11:48:47.000000000 +0200 @@ -537,12 +537,26 @@ .scan_bus = scan_static_bus, };
+static const struct device_operations vt8237r_lpc_ops_a = { + .read_resources = vt8237r_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = vt8237r_init, + .scan_bus = scan_static_bus, +}; + static const struct pci_driver lpc_driver_r __pci_driver = { .ops = &vt8237r_lpc_ops_r, .vendor = PCI_VENDOR_ID_VIA, .device = PCI_DEVICE_ID_VIA_VT8237R_LPC, };
+static const struct pci_driver lpc_driver_a __pci_driver = { + .ops = &vt8237r_lpc_ops_a, + .vendor = PCI_VENDOR_ID_VIA, + .device = PCI_DEVICE_ID_VIA_VT8237A_LPC, +}; + static const struct pci_driver lpc_driver_s __pci_driver = { .ops = &vt8237r_lpc_ops_s, .vendor = PCI_VENDOR_ID_VIA, Index: src/include/device/pci_ids.h =================================================================== --- src/include/device/pci_ids.h.orig 2010-10-27 11:40:16.000000000 +0200 +++ src/include/device/pci_ids.h 2010-10-27 11:48:47.000000000 +0200 @@ -1226,6 +1226,7 @@ #define PCI_DEVICE_ID_VIA_K8T890CE_BR 0xb188 #define PCI_DEVICE_ID_VIA_VT6420_SATA 0x3149 #define PCI_DEVICE_ID_VIA_VT8237R_LPC 0x3227 +#define PCI_DEVICE_ID_VIA_VT8237A_LPC 0x3337 #define PCI_DEVICE_ID_VIA_VT8237S_LPC 0x3372 #define PCI_DEVICE_ID_VIA_VT8237_SATA 0x5372 #define PCI_DEVICE_ID_VIA_VT8237_VLINK 0x287e
Hi,
I think following is not true. The VT8237A has something else at 0x50, so vt8237_sb_enable_fid_vid should not be neccessary to call. Do you call it or not? If not then we either need to fix it for the "old" location 0x11 iirc or not to put there any test for A version.
+static const struct device_operations vt8237r_lpc_ops_a = {
- .read_resources = vt8237r_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = vt8237r_init,
- .scan_bus = scan_static_bus,
+};
I think you dont need this for now, if you use "r" init version you can cange it directly:
+static const struct pci_driver lpc_driver_a __pci_driver = {
- .ops =&vt8237r_lpc_ops_a,
_r here.
Thanks, Rudolf
Rudolf Marek wrote:
Hi,
I think following is not true. The VT8237A has something else at 0x50, so vt8237_sb_enable_fid_vid should not be neccessary to call. Do you call it or not? If not then we either need to fix it for the "old" location 0x11 iirc or not to put there any test for A version.
+static const struct device_operations vt8237r_lpc_ops_a = {
- .read_resources = vt8237r_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = vt8237r_init,
- .scan_bus = scan_static_bus,
+};
I think you dont need this for now, if you use "r" init version you can cange it directly:
+static const struct pci_driver lpc_driver_a __pci_driver = {
- .ops =&vt8237r_lpc_ops_a,
Updated patch:
This adds the VT8237A LPC device id and corresponding pci_locate_device calls in vt8237r_early_smbus.c plus the pci_driver struct in vt8237r_lpc.c
Signed-off-by: Tobias Diedrich ranma+coreboot@tdiedrich.de
---
Index: src/southbridge/via/vt8237r/vt8237r_early_smbus.c =================================================================== --- src/southbridge/via/vt8237r/vt8237r_early_smbus.c.orig 2010-11-03 15:15:02.000000000 +0100 +++ src/southbridge/via/vt8237r/vt8237r_early_smbus.c 2010-11-03 15:15:25.000000000 +0100 @@ -146,6 +146,11 @@
dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT8237S_LPC), 0); + if (dev != PCI_DEV_INVALID) + return dev; + + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237A_LPC), 0); return dev; }
Index: src/southbridge/via/vt8237r/vt8237r_lpc.c =================================================================== --- src/southbridge/via/vt8237r/vt8237r_lpc.c.orig 2010-11-03 14:54:54.000000000 +0100 +++ src/southbridge/via/vt8237r/vt8237r_lpc.c 2010-11-03 15:16:35.000000000 +0100 @@ -543,6 +543,12 @@ .device = PCI_DEVICE_ID_VIA_VT8237R_LPC, };
+static const struct pci_driver lpc_driver_a __pci_driver = { + .ops = &vt8237r_lpc_ops_r, + .vendor = PCI_VENDOR_ID_VIA, + .device = PCI_DEVICE_ID_VIA_VT8237A_LPC, +}; + static const struct pci_driver lpc_driver_s __pci_driver = { .ops = &vt8237r_lpc_ops_s, .vendor = PCI_VENDOR_ID_VIA, Index: src/include/device/pci_ids.h =================================================================== --- src/include/device/pci_ids.h.orig 2010-11-03 14:54:54.000000000 +0100 +++ src/include/device/pci_ids.h 2010-11-03 15:14:49.000000000 +0100 @@ -1226,6 +1226,7 @@ #define PCI_DEVICE_ID_VIA_K8T890CE_BR 0xb188 #define PCI_DEVICE_ID_VIA_VT6420_SATA 0x3149 #define PCI_DEVICE_ID_VIA_VT8237R_LPC 0x3227 +#define PCI_DEVICE_ID_VIA_VT8237A_LPC 0x3337 #define PCI_DEVICE_ID_VIA_VT8237S_LPC 0x3372 #define PCI_DEVICE_ID_VIA_VT8237_SATA 0x5372 #define PCI_DEVICE_ID_VIA_VT8237_VLINK 0x287e
Instead of duplicating the pci_locate_device calls multiple times, add a get_vt8237_lpc() function.
Signed-off-by: Tobias Diedrich ranma+coreboot@tdiedrich.de
---
Index: src/southbridge/via/vt8237r/vt8237r_early_smbus.c =================================================================== --- src.orig/southbridge/via/vt8237r/vt8237r_early_smbus.c 2010-10-27 12:47:15.000000000 +0200 +++ src/southbridge/via/vt8237r/vt8237r_early_smbus.c 2010-10-27 12:49:15.000000000 +0200 @@ -134,6 +134,26 @@
#define PSONREADY_TIMEOUT 0x7fffffff
+static device_t get_vt8237_lpc(void) +{ + device_t dev; + + /* Power management controller */ + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237R_LPC), 0); + if (dev != PCI_DEV_INVALID) + return dev; + + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237S_LPC), 0); + if (dev != PCI_DEV_INVALID) + return dev; + + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237A_LPC), 0); + return dev; +} + /** * Enable the SMBus on VT8237R-based systems. */ @@ -143,20 +163,10 @@ int loops;
/* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237R_LPC), 0); - if (dev == PCI_DEV_INVALID) { - /* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237S_LPC), 0); - if (dev == PCI_DEV_INVALID) { - /* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237A_LPC), 0); - } - if (dev == PCI_DEV_INVALID) - die("Power management controller not found\n"); - } + dev = get_vt8237_lpc(); + + if (dev == PCI_DEV_INVALID) + die("VT8237 Power management controller not found\n");
/* Make sure the RTC power well is up before touching smbus. */ loops = 0; @@ -240,34 +250,41 @@ void vt8237_sb_enable_fid_vid(void) { device_t dev, devctl; + int devid;
/* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237R_LPC), 0); - if (dev == PCI_DEV_INVALID) { - /* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237S_LPC), 0); - if (dev == PCI_DEV_INVALID) { - /* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237A_LPC), 0); - } - if (dev == PCI_DEV_INVALID) - return; + dev = get_vt8237_lpc(); + if (dev == PCI_DEV_INVALID) + return;
- devctl = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237_VLINK), 0); + devctl = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237_VLINK), 0);
- if (devctl == PCI_DEV_INVALID) - return; + devid = pci_read_config16(dev, PCI_DEVICE_ID);
- /* Set ACPI base address to I/O VT8237R_ACPI_IO_BASE. */ - pci_write_config16(dev, 0x88, VT8237R_ACPI_IO_BASE | 0x1); + /* generic setup */
- /* Enable ACPI accessm RTC signal gated with PSON. */ - pci_write_config8(dev, 0x81, 0x84); + /* Set ACPI base address to I/O VT8237R_ACPI_IO_BASE. */ + pci_write_config16(dev, 0x88, VT8237R_ACPI_IO_BASE | 0x1);
+ /* Enable ACPI accessm RTC signal gated with PSON. */ + pci_write_config8(dev, 0x81, 0x84); + + /* chipset-specific parts */ + + /* VLINK: FIXME: can we drop the devid check and just look for the VLINK device? */ + if (devid == PCI_DEVICE_ID_VIA_VT8237S_LPC || + devid == PCI_DEVICE_ID_VIA_VT8237A_LPC) { + devctl = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237_VLINK), 0); + + if (devctl != PCI_DEV_INVALID) { + /* So the chip knows we are on AMD. */ + pci_write_config8(devctl, 0x7c, 0x7f); + } + } + + if (devid == PCI_DEVICE_ID_VIA_VT8237S_LPC) { /* * Allow SLP# signal to assert LDTSTOP_L. * Will work for C3 and for FID/VID change. @@ -278,17 +295,10 @@ /* Reduce further the STPCLK/LDTSTP signal to 5us. */ pci_write_config8(dev, 0xec, 0x4);
- /* So the chip knows we are on AMD. */ - pci_write_config8(devctl, 0x7c, 0x7f); - return; }
- /* Set ACPI base address to I/O VT8237R_ACPI_IO_BASE. */ - pci_write_config16(dev, 0x88, VT8237R_ACPI_IO_BASE | 0x1); - - /* Enable ACPI accessm RTC signal gated with PSON. */ - pci_write_config8(dev, 0x81, 0x84); + /* VT8237R and VT8237A */
/* * Allow SLP# signal to assert LDTSTOP_L. @@ -302,20 +312,10 @@ device_t dev;
/* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237R_LPC), 0); - if (dev == PCI_DEV_INVALID) { - /* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237S_LPC), 0); - if (dev == PCI_DEV_INVALID) { - /* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237A_LPC), 0); - } - if (dev == PCI_DEV_INVALID) - return; - } + dev = get_vt8237_lpc(); + + if (dev == PCI_DEV_INVALID) + return;
/* ROM decode last 1MB FFC00000 - FFFFFFFF. */ pci_write_config8(dev, 0x41, 0x7f); @@ -330,21 +330,10 @@
print_debug("IN TEST WAKEUP\n");
- /* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237R_LPC), 0); - if (dev == PCI_DEV_INVALID) { - /* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237S_LPC), 0); - if (dev == PCI_DEV_INVALID) { - /* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237A_LPC), 0); - } - if (dev == PCI_DEV_INVALID) - die("Power management controller not found\n"); - } + dev = get_vt8237_lpc(); + + if (dev == PCI_DEV_INVALID) + die("Power management controller not found\n");
/* Set ACPI base address to I/O VT8237R_ACPI_IO_BASE. */ pci_write_config16(dev, 0x88, VT8237R_ACPI_IO_BASE | 0x1);
On 29.10.2010 13:59, Tobias Diedrich wrote:
Instead of duplicating the pci_locate_device calls multiple times, add a get_vt8237_lpc() function.
Yeah nice idea! Can I get separate patch for that? In the meanwhile do we need to call the enablefidvid for "A" ? I think we dont scritly need that. Maybe we can make it part of 2/7 and leave this just for the grand get_vt8237_lpc() function? (and I can apply that before 2/7 so you don't need to re-do the stuff)
Thanks, Rudolf
Rudolf Marek wrote:
On 29.10.2010 13:59, Tobias Diedrich wrote:
Instead of duplicating the pci_locate_device calls multiple times, add a get_vt8237_lpc() function.
Yeah nice idea! Can I get separate patch for that? In the meanwhile do we need to call the enablefidvid for "A" ? I think we dont scritly need that. Maybe we can make it part of 2/7 and leave this just for the grand get_vt8237_lpc() function? (and I can apply that before 2/7 so you don't need to re-do the stuff)
Here you go:
Instead of duplicating the pci_locate_device calls multiple times, add a get_vt8237_lpc() function.
The devid variable introduced to vt8237_sb_enable_fid_vid() in hunk 3 will come in handy in the patch adding vt8237a support. I think it also makes the logic a bit more clear. The other option would be to not use get_vt8237_lpc() in vt8237_sb_enable_fid_vid() and leave that bit to the vt8237a support patch.
Signed-off-by: Tobias Diedrich ranma+coreboot@tdiedrich.de
---
Index: src/southbridge/via/vt8237r/vt8237r_early_smbus.c =================================================================== --- src/southbridge/via/vt8237r/vt8237r_early_smbus.c.orig 2010-11-03 14:54:54.000000000 +0100 +++ src/southbridge/via/vt8237r/vt8237r_early_smbus.c 2010-11-03 15:00:34.000000000 +0100 @@ -134,6 +134,21 @@
#define PSONREADY_TIMEOUT 0x7fffffff
+static device_t get_vt8237_lpc(void) +{ + device_t dev; + + /* Power management controller */ + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237R_LPC), 0); + if (dev != PCI_DEV_INVALID) + return dev; + + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237S_LPC), 0); + return dev; +} + /** * Enable the SMBus on VT8237R-based systems. */ @@ -143,15 +158,9 @@ int loops;
/* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237R_LPC), 0); - if (dev == PCI_DEV_INVALID) { - /* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237S_LPC), 0); - if (dev == PCI_DEV_INVALID) - die("Power management controller not found\n"); - } + dev = get_vt8237_lpc(); + if (dev == PCI_DEV_INVALID) + die("Power management controller not found\n");
/* Make sure the RTC power well is up before touching smbus. */ loops = 0; @@ -235,17 +244,15 @@ void vt8237_sb_enable_fid_vid(void) { device_t dev, devctl; + u16 devid;
/* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237R_LPC), 0); - if (dev == PCI_DEV_INVALID) { - /* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237S_LPC), 0); - if (dev == PCI_DEV_INVALID) - return; + dev = get_vt8237_lpc(); + if (dev == PCI_DEV_INVALID) + return;
+ devid = pci_read_config16(dev, PCI_DEVICE_ID); + if (devid == PCI_DEVICE_ID_VIA_VT8237S_LPC) { devctl = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT8237_VLINK), 0);
@@ -292,15 +292,9 @@ device_t dev;
/* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237R_LPC), 0); - if (dev == PCI_DEV_INVALID) { - /* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237S_LPC), 0); - if (dev == PCI_DEV_INVALID) - return; - } + dev = get_vt8237_lpc(); + if (dev == PCI_DEV_INVALID) + return;
/* ROM decode last 1MB FFC00000 - FFFFFFFF. */ pci_write_config8(dev, 0x41, 0x7f); @@ -316,15 +310,9 @@ print_debug("IN TEST WAKEUP\n");
/* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237R_LPC), 0); - if (dev == PCI_DEV_INVALID) { - /* Power management controller */ - dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237S_LPC), 0); - if (dev == PCI_DEV_INVALID) - die("Power management controller not found\n"); - } + dev = get_vt8237_lpc(); + if (dev == PCI_DEV_INVALID) + die("Power management controller not found\n");
/* Set ACPI base address to I/O VT8237R_ACPI_IO_BASE. */ pci_write_config16(dev, 0x88, VT8237R_ACPI_IO_BASE | 0x1);
This adds VT8237A specific VLINK/LPC init functions in vt8237_ctrl.c and vt8237r_lpc.c
Signed-off-by: Tobias Diedrich ranma+coreboot@tdiedrich.de
---
Index: src/southbridge/via/vt8237r/vt8237_ctrl.c =================================================================== --- src/southbridge/via/vt8237r/vt8237_ctrl.c.orig 2010-10-29 13:30:49.000000000 +0200 +++ src/southbridge/via/vt8237r/vt8237_ctrl.c 2010-10-29 13:30:51.000000000 +0200 @@ -168,6 +168,69 @@
}
+static void vt8237a_vlink_init(struct device *dev) +{ + u8 reg; + device_t devfun7; + + devfun7 = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_K8T890CE_7, 0); + if (!devfun7) + devfun7 = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_K8M890CE_7, 0); + if (!devfun7) + devfun7 = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_K8T890CF_7, 0); + /* No pairing NB was found. */ + if (!devfun7) + return; + + /* + * This init code is valid only for the VT8237A! For different + * sounthbridges (e.g. VT8237S, VT8237R (without plus R) + * and VT8251) a different init code is required. + */ + + /* disable auto disconnect */ + reg = pci_read_config8(devfun7, 0x42); + reg &= ~0x4; + pci_write_config8(devfun7, 0x42, reg); + + /* NB part setup */ + pci_write_config8(devfun7, 0xb5, 0x88); + pci_write_config8(devfun7, 0xb6, 0x88); + pci_write_config8(devfun7, 0xb7, 0x61); + + reg = pci_read_config8(devfun7, 0xb4); + reg |= 0x11; + pci_write_config8(devfun7, 0xb4, reg); + + pci_write_config8(devfun7, 0xb0, 0x6); + pci_write_config8(devfun7, 0xb1, 0x1); + + /* SB part setup */ + pci_write_config8(dev, 0xb7, 0x50); + pci_write_config8(dev, 0xb9, 0x88); + pci_write_config8(dev, 0xba, 0x8a); + pci_write_config8(dev, 0xbb, 0x88); + + reg = pci_read_config8(dev, 0xbd); + reg |= 0x3; + reg &= ~0x4; + pci_write_config8(dev, 0xbd, reg); + + reg = pci_read_config8(dev, 0xbc); + reg &= ~0x7; + pci_write_config8(dev, 0xbc, reg); + + pci_write_config8(dev, 0x48, 0x23); + + /* enable auto disconnect, for STPGNT and HALT */ + reg = pci_read_config8(devfun7, 0x42); + reg |= 0x7; + pci_write_config8(devfun7, 0x42, reg); +} + static void ctrl_enable(struct device *dev) { /* Enable the 0:13 and 0:13.1. */ @@ -193,6 +256,12 @@ vt8237s_vlink_init(dev); }
+ devsb = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237A_LPC, 0); + if (devsb) { + vt8237a_vlink_init(dev); + } + /* Configure PCI1 and copy mirror registers from D0F3. */ vt8237_cfg(dev); dump_south(dev); Index: src/southbridge/via/vt8237r/vt8237r_lpc.c =================================================================== --- src/southbridge/via/vt8237r/vt8237r_lpc.c.orig 2010-10-29 13:30:50.000000000 +0200 +++ src/southbridge/via/vt8237r/vt8237r_lpc.c 2010-10-29 13:31:16.000000000 +0200 @@ -319,6 +319,50 @@ printk(BIOS_SPEW, "Leaving %s.\n", __func__); }
+static void vt8237a_init(struct device *dev) +{ + u32 tmp; + device_t pdev; + + /* Set bit 3 of 0x4f (use INIT# as CPU reset). */ + tmp = pci_read_config8(dev, 0x4f); + tmp |= 0x08; + pci_write_config8(dev, 0x4f, tmp); + + /* + * bit2: REQ5 as PCI request input - should be together with INTE-INTH. + * bit5: usb power control lines as gpio + */ + pci_write_config8(dev, 0xe4, 0x24); + /* + * Enable APIC wakeup from INTH + * Enable SATA LED, disable special CPU Frequency Change - + * GPIO28 GPIO22 GPIO29 GPIO23 are GPIOs. + */ + pci_write_config8(dev, 0xe5, 0x69); + + /* Reduce further the STPCLK/LDTSTP signal to 5us. */ + pci_write_config8(dev, 0xec, 0x4); + + /* Host Bus Power Management Control, maybe not needed */ + pci_write_config8(dev, 0x8c, 0x5); + + /* Enable HPET at VT8237R_HPET_ADDR. */ + pci_write_config32(dev, 0x68, (VT8237R_HPET_ADDR | 0x80)); + + southbridge_init_common(dev); + + /* FIXME: Intel needs more bit set for C2/C3. */ + + /* + * Allow SLP# signal to assert LDTSTOP_L. + * Will work for C3 and for FID/VID change. FIXME FIXME, pre rev A2. + */ + outb(0x1, VT8237R_ACPI_IO_BASE + 0x11); + + dump_south(dev); +} + static void vt8237s_init(struct device *dev) { u32 tmp; @@ -541,7 +585,7 @@ .read_resources = vt8237r_read_resources, .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources, - .init = vt8237r_init, + .init = vt8237a_init, .scan_bus = scan_static_bus, };
Hmpf, forgot to compiletest this one and missed the unused pdev, fixed.
This adds VT8237A specific VLINK/LPC init functions in vt8237_ctrl.c and vt8237r_lpc.c
Signed-off-by: Tobias Diedrich ranma+coreboot@tdiedrich.de
---
Index: src/southbridge/via/vt8237r/vt8237_ctrl.c =================================================================== --- src/southbridge/via/vt8237r/vt8237_ctrl.c.orig 2010-10-29 14:05:23.000000000 +0200 +++ src/southbridge/via/vt8237r/vt8237_ctrl.c 2010-10-29 14:06:09.000000000 +0200 @@ -168,6 +168,69 @@
}
+static void vt8237a_vlink_init(struct device *dev) +{ + u8 reg; + device_t devfun7; + + devfun7 = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_K8T890CE_7, 0); + if (!devfun7) + devfun7 = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_K8M890CE_7, 0); + if (!devfun7) + devfun7 = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_K8T890CF_7, 0); + /* No pairing NB was found. */ + if (!devfun7) + return; + + /* + * This init code is valid only for the VT8237A! For different + * sounthbridges (e.g. VT8237S, VT8237R (without plus R) + * and VT8251) a different init code is required. + */ + + /* disable auto disconnect */ + reg = pci_read_config8(devfun7, 0x42); + reg &= ~0x4; + pci_write_config8(devfun7, 0x42, reg); + + /* NB part setup */ + pci_write_config8(devfun7, 0xb5, 0x88); + pci_write_config8(devfun7, 0xb6, 0x88); + pci_write_config8(devfun7, 0xb7, 0x61); + + reg = pci_read_config8(devfun7, 0xb4); + reg |= 0x11; + pci_write_config8(devfun7, 0xb4, reg); + + pci_write_config8(devfun7, 0xb0, 0x6); + pci_write_config8(devfun7, 0xb1, 0x1); + + /* SB part setup */ + pci_write_config8(dev, 0xb7, 0x50); + pci_write_config8(dev, 0xb9, 0x88); + pci_write_config8(dev, 0xba, 0x8a); + pci_write_config8(dev, 0xbb, 0x88); + + reg = pci_read_config8(dev, 0xbd); + reg |= 0x3; + reg &= ~0x4; + pci_write_config8(dev, 0xbd, reg); + + reg = pci_read_config8(dev, 0xbc); + reg &= ~0x7; + pci_write_config8(dev, 0xbc, reg); + + pci_write_config8(dev, 0x48, 0x23); + + /* enable auto disconnect, for STPGNT and HALT */ + reg = pci_read_config8(devfun7, 0x42); + reg |= 0x7; + pci_write_config8(devfun7, 0x42, reg); +} + static void ctrl_enable(struct device *dev) { /* Enable the 0:13 and 0:13.1. */ @@ -193,6 +256,12 @@ vt8237s_vlink_init(dev); }
+ devsb = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237A_LPC, 0); + if (devsb) { + vt8237a_vlink_init(dev); + } + /* Configure PCI1 and copy mirror registers from D0F3. */ vt8237_cfg(dev); dump_south(dev); Index: src/southbridge/via/vt8237r/vt8237r_lpc.c =================================================================== --- src/southbridge/via/vt8237r/vt8237r_lpc.c.orig 2010-10-29 14:05:39.000000000 +0200 +++ src/southbridge/via/vt8237r/vt8237r_lpc.c 2010-10-29 14:06:27.000000000 +0200 @@ -319,6 +319,49 @@ printk(BIOS_SPEW, "Leaving %s.\n", __func__); }
+static void vt8237a_init(struct device *dev) +{ + u32 tmp; + + /* Set bit 3 of 0x4f (use INIT# as CPU reset). */ + tmp = pci_read_config8(dev, 0x4f); + tmp |= 0x08; + pci_write_config8(dev, 0x4f, tmp); + + /* + * bit2: REQ5 as PCI request input - should be together with INTE-INTH. + * bit5: usb power control lines as gpio + */ + pci_write_config8(dev, 0xe4, 0x24); + /* + * Enable APIC wakeup from INTH + * Enable SATA LED, disable special CPU Frequency Change - + * GPIO28 GPIO22 GPIO29 GPIO23 are GPIOs. + */ + pci_write_config8(dev, 0xe5, 0x69); + + /* Reduce further the STPCLK/LDTSTP signal to 5us. */ + pci_write_config8(dev, 0xec, 0x4); + + /* Host Bus Power Management Control, maybe not needed */ + pci_write_config8(dev, 0x8c, 0x5); + + /* Enable HPET at VT8237R_HPET_ADDR. */ + pci_write_config32(dev, 0x68, (VT8237R_HPET_ADDR | 0x80)); + + southbridge_init_common(dev); + + /* FIXME: Intel needs more bit set for C2/C3. */ + + /* + * Allow SLP# signal to assert LDTSTOP_L. + * Will work for C3 and for FID/VID change. FIXME FIXME, pre rev A2. + */ + outb(0x1, VT8237R_ACPI_IO_BASE + 0x11); + + dump_south(dev); +} + static void vt8237s_init(struct device *dev) { u32 tmp; @@ -541,7 +584,7 @@ .read_resources = vt8237r_read_resources, .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources, - .init = vt8237r_init, + .init = vt8237a_init, .scan_bus = scan_static_bus, };
On 29.10.2010 14:15, Tobias Diedrich wrote:
Hmpf, forgot to compiletest this one and missed the unused pdev, fixed.
This adds VT8237A specific VLINK/LPC init functions in vt8237_ctrl.c and vt8237r_lpc.c
Signed-off-by: Tobias Diedrichranma+coreboot@tdiedrich.de
Index: src/southbridge/via/vt8237r/vt8237_ctrl.c
--- src/southbridge/via/vt8237r/vt8237_ctrl.c.orig 2010-10-29 14:05:23.000000000 +0200 +++ src/southbridge/via/vt8237r/vt8237_ctrl.c 2010-10-29 14:06:09.000000000 +0200 @@ -168,6 +168,69 @@
}
+static void vt8237a_vlink_init(struct device *dev) +{
- u8 reg;
- device_t devfun7;
- devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_K8T890CE_7, 0);
- if (!devfun7)
devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_K8M890CE_7, 0);
- if (!devfun7)
devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_K8T890CF_7, 0);
- /* No pairing NB was found. */
- if (!devfun7)
return;
- /*
* This init code is valid only for the VT8237A! For different
* sounthbridges (e.g. VT8237S, VT8237R (without plus R)
typo :) maybe was just copied? Did you get the values from orig bios? Or just copied? For what vlink mode it is 8x? I got some VIA recommended values but they are bit different 0xb5 is 0x88.
=================================================================== --- src/southbridge/via/vt8237r/vt8237r_lpc.c.orig 2010-10-29 14:05:39.000000000 +0200 +++ src/southbridge/via/vt8237r/vt8237r_lpc.c 2010-10-29 14:06:27.000000000 +0200 @@ -319,6 +319,49 @@ printk(BIOS_SPEW, "Leaving %s.\n", __func__); }
+static void vt8237a_init(struct device *dev)
Aha now I see why you need the own struct.
+{
- u32 tmp;
- /* Set bit 3 of 0x4f (use INIT# as CPU reset). */
- tmp = pci_read_config8(dev, 0x4f);
- tmp |= 0x08;
- pci_write_config8(dev, 0x4f, tmp);
- /*
* bit2: REQ5 as PCI request input - should be together with INTE-INTH.
* bit5: usb power control lines as gpio
*/
- pci_write_config8(dev, 0xe4, 0x24);
- /*
* Enable APIC wakeup from INTH
* Enable SATA LED, disable special CPU Frequency Change -
* GPIO28 GPIO22 GPIO29 GPIO23 are GPIOs.
*/
- pci_write_config8(dev, 0xe5, 0x69);
- /* Reduce further the STPCLK/LDTSTP signal to 5us. */
- pci_write_config8(dev, 0xec, 0x4);
- /* Host Bus Power Management Control, maybe not needed */
- pci_write_config8(dev, 0x8c, 0x5);
- /* Enable HPET at VT8237R_HPET_ADDR. */
- pci_write_config32(dev, 0x68, (VT8237R_HPET_ADDR | 0x80));
- southbridge_init_common(dev);
- /* FIXME: Intel needs more bit set for C2/C3. */
- /*
* Allow SLP# signal to assert LDTSTOP_L.
* Will work for C3 and for FID/VID change. FIXME FIXME, pre rev A2.
What is fixme fixme pre revA2?
*/
- outb(0x1, VT8237R_ACPI_IO_BASE + 0x11);
- dump_south(dev);
+}
- static void vt8237s_init(struct device *dev) { u32 tmp;
@@ -541,7 +584,7 @@ .read_resources = vt8237r_read_resources, .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources,
- .init = vt8237r_init,
- .init = vt8237a_init, .scan_bus = scan_static_bus, };
Otherwise fine.
Thanks, Rudolf
Rudolf Marek wrote:
- if (!devfun7)
return;
- /*
* This init code is valid only for the VT8237A! For different
* sounthbridges (e.g. VT8237S, VT8237R (without plus R)
typo :) maybe was just copied? Did you get the values from orig bios? Or just copied? For what vlink mode it is 8x? I got some VIA recommended values but they are bit different 0xb5 is 0x88.
- /* FIXME: Intel needs more bit set for C2/C3. */
- /*
* Allow SLP# signal to assert LDTSTOP_L.
* Will work for C3 and for FID/VID change. FIXME FIXME, pre rev A2.
What is fixme fixme pre revA2?
*/
- outb(0x1, VT8237R_ACPI_IO_BASE + 0x11);
- dump_south(dev);
+}
- static void vt8237s_init(struct device *dev) { u32 tmp;
@@ -541,7 +584,7 @@ .read_resources = vt8237r_read_resources, .set_resources = pci_dev_set_resources, .enable_resources = pci_dev_enable_resources,
- .init = vt8237r_init,
- .init = vt8237a_init, .scan_bus = scan_static_bus, };
Otherwise fine.
Updated patch:
This adds VT8237A specific VLINK/LPC init functions in vt8237_ctrl.c, vt8237r_lpc.c and vt8237r_early_smbus.c I ran some tests and apparently both the
| /* So the chip knows we are on AMD. */ | pci_write_config8(devctl, 0x7c, 0x7f);
and
| /* | * Allow SLP# signal to assert LDTSTOP_L. | * Will work for C3 and for FID/VID change. | */ | outb(0x1, VT8237R_ACPI_IO_BASE + 0x11);
in vt8237r_early_smbus.c are needed on VT8237A, otherwise I get a (non-fatal) fid/vid change error on boot.
While vt8237a_vlink_init() in vt8237_ctrl.c is a modified vt8237r_vlink_init(), vt8237a_init() in vt8237r_lpc.c is a modified vt8237s_init().
Signed-off-by: Tobias Diedrich ranma+coreboot@tdiedrich.de
---
Index: src/southbridge/via/vt8237r/vt8237_ctrl.c =================================================================== --- src/southbridge/via/vt8237r/vt8237_ctrl.c.orig 2010-11-03 15:23:19.000000000 +0100 +++ src/southbridge/via/vt8237r/vt8237_ctrl.c 2010-11-03 15:37:25.000000000 +0100 @@ -168,6 +168,75 @@
}
+static void vt8237a_vlink_init(struct device *dev) +{ + u8 reg; + device_t devfun7; + + devfun7 = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_K8T890CE_7, 0); + if (!devfun7) + devfun7 = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_K8M890CE_7, 0); + if (!devfun7) + devfun7 = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_K8T890CF_7, 0); + /* No pairing NB was found. */ + if (!devfun7) + return; + + /* + * This init code is valid only for the VT8237A! For different + * sounthbridges (e.g. VT8237S, VT8237R and VT8251) a different + * init code is required. + * + * FIXME: This is based on vt8237r_vlink_init() in + * k8t890/k8t890_ctrl.c and modified to fit what the AMI + * BIOS on my M2V wrote to these registers (by looking + * at lspci -nxxx output). + * Works for me. + */ + + /* disable auto disconnect */ + reg = pci_read_config8(devfun7, 0x42); + reg &= ~0x4; + pci_write_config8(devfun7, 0x42, reg); + + /* NB part setup */ + pci_write_config8(devfun7, 0xb5, 0x88); + pci_write_config8(devfun7, 0xb6, 0x88); + pci_write_config8(devfun7, 0xb7, 0x61); + + reg = pci_read_config8(devfun7, 0xb4); + reg |= 0x11; + pci_write_config8(devfun7, 0xb4, reg); + + pci_write_config8(devfun7, 0xb0, 0x6); + pci_write_config8(devfun7, 0xb1, 0x1); + + /* SB part setup */ + pci_write_config8(dev, 0xb7, 0x50); + pci_write_config8(dev, 0xb9, 0x88); + pci_write_config8(dev, 0xba, 0x8a); + pci_write_config8(dev, 0xbb, 0x88); + + reg = pci_read_config8(dev, 0xbd); + reg |= 0x3; + reg &= ~0x4; + pci_write_config8(dev, 0xbd, reg); + + reg = pci_read_config8(dev, 0xbc); + reg &= ~0x7; + pci_write_config8(dev, 0xbc, reg); + + pci_write_config8(dev, 0x48, 0x23); + + /* enable auto disconnect, for STPGNT and HALT */ + reg = pci_read_config8(devfun7, 0x42); + reg |= 0x7; + pci_write_config8(devfun7, 0x42, reg); +} + static void ctrl_enable(struct device *dev) { /* Enable the 0:13 and 0:13.1. */ @@ -193,6 +262,12 @@ vt8237s_vlink_init(dev); }
+ devsb = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237A_LPC, 0); + if (devsb) { + vt8237a_vlink_init(dev); + } + /* Configure PCI1 and copy mirror registers from D0F3. */ vt8237_cfg(dev); dump_south(dev); Index: src/southbridge/via/vt8237r/vt8237r_lpc.c =================================================================== --- src/southbridge/via/vt8237r/vt8237r_lpc.c.orig 2010-11-03 15:23:19.000000000 +0100 +++ src/southbridge/via/vt8237r/vt8237r_lpc.c 2010-11-03 15:50:51.000000000 +0100 @@ -319,6 +319,55 @@ printk(BIOS_SPEW, "Leaving %s.\n", __func__); }
+static void vt8237a_init(struct device *dev) +{ + /* + * FIXME: This is based on vt8237s_init() and the values the AMI + * BIOS on my M2V wrote to these registers (by loking + * at lspci -nxxx output). + * Works for me. + */ + u32 tmp; + + /* Set bit 3 of 0x4f (use INIT# as CPU reset). */ + tmp = pci_read_config8(dev, 0x4f); + tmp |= 0x08; + pci_write_config8(dev, 0x4f, tmp); + + /* + * bit2: REQ5 as PCI request input - should be together with INTE-INTH. + * bit5: usb power control lines as gpio + */ + pci_write_config8(dev, 0xe4, 0x24); + /* + * Enable APIC wakeup from INTH + * Enable SATA LED, disable special CPU Frequency Change - + * GPIO28 GPIO22 GPIO29 GPIO23 are GPIOs. + */ + pci_write_config8(dev, 0xe5, 0x69); + + /* Reduce further the STPCLK/LDTSTP signal to 5us. */ + pci_write_config8(dev, 0xec, 0x4); + + /* Host Bus Power Management Control, maybe not needed */ + pci_write_config8(dev, 0x8c, 0x5); + + /* Enable HPET at VT8237R_HPET_ADDR. */ + pci_write_config32(dev, 0x68, (VT8237R_HPET_ADDR | 0x80)); + + southbridge_init_common(dev); + + /* FIXME: Intel needs more bit set for C2/C3. */ + + /* + * Allow SLP# signal to assert LDTSTOP_L. + * Will work for C3 and for FID/VID change. + */ + outb(0x1, VT8237R_ACPI_IO_BASE + 0x11); + + dump_south(dev); +} + static void vt8237s_init(struct device *dev) { u32 tmp; @@ -537,6 +586,14 @@ .scan_bus = scan_static_bus, };
+static const struct device_operations vt8237r_lpc_ops_a = { + .read_resources = vt8237r_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = vt8237a_init, + .scan_bus = scan_static_bus, +}; + static const struct pci_driver lpc_driver_r __pci_driver = { .ops = &vt8237r_lpc_ops_r, .vendor = PCI_VENDOR_ID_VIA, @@ -544,7 +601,7 @@ };
static const struct pci_driver lpc_driver_a __pci_driver = { - .ops = &vt8237r_lpc_ops_r, + .ops = &vt8237r_lpc_ops_a, .vendor = PCI_VENDOR_ID_VIA, .device = PCI_DEVICE_ID_VIA_VT8237A_LPC, }; Index: src/southbridge/via/vt8237r/vt8237r_early_smbus.c =================================================================== --- src/southbridge/via/vt8237r/vt8237r_early_smbus.c.orig 2010-11-03 15:23:19.000000000 +0100 +++ src/southbridge/via/vt8237r/vt8237r_early_smbus.c 2010-11-03 15:23:22.000000000 +0100 @@ -257,19 +257,30 @@ return;
devid = pci_read_config16(dev, PCI_DEVICE_ID); - if (devid == PCI_DEVICE_ID_VIA_VT8237S_LPC) { - devctl = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_VT8237_VLINK), 0);
- if (devctl == PCI_DEV_INVALID) - return; + /* generic setup */ + + /* Set ACPI base address to I/O VT8237R_ACPI_IO_BASE. */ + pci_write_config16(dev, 0x88, VT8237R_ACPI_IO_BASE | 0x1); + + /* Enable ACPI accessm RTC signal gated with PSON. */ + pci_write_config8(dev, 0x81, 0x84); + + /* chipset-specific parts */
- /* Set ACPI base address to I/O VT8237R_ACPI_IO_BASE. */ - pci_write_config16(dev, 0x88, VT8237R_ACPI_IO_BASE | 0x1); + /* VLINK: FIXME: can we drop the devid check and just look for the VLINK device? */ + if (devid == PCI_DEVICE_ID_VIA_VT8237S_LPC || + devid == PCI_DEVICE_ID_VIA_VT8237A_LPC) { + devctl = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237_VLINK), 0);
- /* Enable ACPI accessm RTC signal gated with PSON. */ - pci_write_config8(dev, 0x81, 0x84); + if (devctl != PCI_DEV_INVALID) { + /* So the chip knows we are on AMD. */ + pci_write_config8(devctl, 0x7c, 0x7f); + } + }
+ if (devid == PCI_DEVICE_ID_VIA_VT8237S_LPC) { /* * Allow SLP# signal to assert LDTSTOP_L. * Will work for C3 and for FID/VID change. @@ -280,17 +291,10 @@ /* Reduce further the STPCLK/LDTSTP signal to 5us. */ pci_write_config8(dev, 0xec, 0x4);
- /* So the chip knows we are on AMD. */ - pci_write_config8(devctl, 0x7c, 0x7f); - return; }
- /* Set ACPI base address to I/O VT8237R_ACPI_IO_BASE. */ - pci_write_config16(dev, 0x88, VT8237R_ACPI_IO_BASE | 0x1); - - /* Enable ACPI accessm RTC signal gated with PSON. */ - pci_write_config8(dev, 0x81, 0x84); + /* VT8237R and VT8237A */
/* * Allow SLP# signal to assert LDTSTOP_L.
Need to clear downstream read cycle retry bit, or the bus scan will hang. Also need to set lane config to 0x00 for autonegotiation.
Signed-off-by: Tobias Diedrich ranma+coreboot@tdiedrich.de
---
Index: src/southbridge/via/k8t890/k8t890_pcie.c =================================================================== --- src/southbridge/via/k8t890/k8t890_pcie.c.orig 2010-10-29 13:36:04.000000000 +0200 +++ src/southbridge/via/k8t890/k8t890_pcie.c 2010-10-29 13:45:11.000000000 +0200 @@ -35,7 +35,23 @@ reg = pci_read_config8(dev, 0x50); pci_write_config8(dev, 0x50, reg | 0x10);
- /* Award has 0xb, VIA recomends 0x4. */ + /* Disable downstream read cycle retry, + * otherwise the bus scan will hang if no device is plugged in. */ + reg = pci_read_config8(dev, 0xa3); + pci_write_config8(dev, 0xa3, reg & ~0x01); + + /* Use PHY negotiation for lane config */ + reg = pci_read_config8(dev, 0xc1); + pci_write_config8(dev, 0xc1, reg & ~0x1f); + + /* Award has 0xb, VIA recommends 0xd, default 0x8. + * bit4: receive polarity change control + * bits3:2: squelch window select 64~175mv + * bit1: Number of non-idle bits detected before exiting idle state + * 0: 10 bits, 1: 2 bits + * bit0: Number of idle bits detected before entering idle state + * 0: 10 bits, 1: 2 bits + */ pci_write_config8(dev, 0xe1, 0xb);
/* @@ -75,8 +91,25 @@ reg = pci_read_config8(dev, 0x50); pci_write_config8(dev, 0x50, reg | 0x10);
- /* Award has 0xb, VIA recommends 0x4. */ + /* Disable downstream read cycle retry, + * otherwise the bus scan will hang if no device is plugged in. */ + reg = pci_read_config8(dev, 0xa3); + pci_write_config8(dev, 0xa3, reg & ~0x01); + + /* Use PHY negotiation for lane config */ + reg = pci_read_config8(dev, 0xc1); + pci_write_config8(dev, 0xc1, reg & ~0x1f); + + /* Award has 0xb, VIA recommends 0xd, default 0x8. + * bit4: receive polarity change control + * bits3:2: squelch window select 64~175mv + * bit1: Number of non-idle bits detected before exiting idle state + * 0: 10 bits, 1: 2 bits + * bit0: Number of idle bits detected before entering idle state + * 0: 10 bits, 1: 2 bits + */ pci_write_config8(dev, 0xe1, 0xb); + /* Set replay timer limit. */ pci_write_config8(dev, 0xb1, 0xf0);
OK hope it fixes your PCIe issues. The "M" and CE variant has default 0s.
Acked-by: Rudolf Marek r.marek@assembler.cz
Committed revision 6013.
Thanks, Rudolf
Minor comment changes, add pointer to PCIe bridge documentation.
Signed-off-by: Tobias Diedrich ranma+coreboot@tdiedrich.de
---
Index: src/southbridge/via/k8t890/k8t890_ctrl.c =================================================================== --- src/southbridge/via/k8t890/k8t890_ctrl.c.orig 2010-10-29 13:47:38.000000000 +0200 +++ src/southbridge/via/k8t890/k8t890_ctrl.c 2010-10-29 13:47:57.000000000 +0200 @@ -154,7 +154,11 @@
pci_write_config8(dev, 0x47, 0x30);
- /* VT8237R specific configuration other SB are done in their own directories */ + /* + * VT8237R specific configuration, + * other SB are done in their own directories: + * VT8237A and VT8237S are handled in vt8237_ctrl.c + */
device_t devsb = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT8237R_LPC, 0); Index: src/southbridge/via/vt8237r/vt8237r_lpc.c =================================================================== --- src/southbridge/via/vt8237r/vt8237r_lpc.c.orig 2010-10-29 13:47:38.000000000 +0200 +++ src/southbridge/via/vt8237r/vt8237r_lpc.c 2010-10-29 13:47:57.000000000 +0200 @@ -452,7 +452,7 @@ /* I/O recovery time, default IDE routing */ pci_write_config8(dev, 0x4c, 0x04);
- /* ROM memory cycles go to LPC. */ + /* Only ROM memory cycles go to LPC. */ pci_write_config8(dev, 0x59, 0x80);
/* @@ -474,7 +474,7 @@ /* I/O recovery time, default IDE routing */ pci_write_config8(dev, 0x4c, 0x44);
- /* ROM memory cycles go to LPC. */ + /* Only ROM memory cycles go to LPC. */ pci_write_config8(dev, 0x59, 0x80);
/* Index: src/southbridge/via/k8t890/k8t890_pcie.c =================================================================== --- src/southbridge/via/k8t890/k8t890_pcie.c.orig 2010-10-29 13:48:04.000000000 +0200 +++ src/southbridge/via/k8t890/k8t890_pcie.c 2010-10-29 13:48:25.000000000 +0200 @@ -24,6 +24,12 @@ #include <device/pci_ids.h> #include "k8t890.h"
+/* + * Note: + * The pcie bridges are similar to the VX800 ones documented at + * http://linux.via.com.tw/ + */ + static void peg_init(struct device *dev) { u8 reg;
- /* ROM memory cycles go to LPC. */
- /* Only ROM memory cycles go to LPC. */
I think it should be,
- /* Only memory ROM cycles go to LPC. */
Because this bit is telling if all memory cycles should go to LPC or just those from ROM range. Please try to rephase that.
Thanks, Rudolf
Rudolf Marek wrote:
- /* ROM memory cycles go to LPC. */
- /* Only ROM memory cycles go to LPC. */
I think it should be,
- /* Only memory ROM cycles go to LPC. */
Because this bit is telling if all memory cycles should go to LPC or just those from ROM range. Please try to rephase that.
Updated patch:
Comment changes, add pointer to PCIe bridge documentation.
Signed-off-by: Tobias Diedrich ranma+coreboot@tdiedrich.de
---
Index: src/southbridge/via/k8t890/k8t890_ctrl.c =================================================================== --- src/southbridge/via/k8t890/k8t890_ctrl.c.orig 2010-11-03 14:53:07.000000000 +0100 +++ src/southbridge/via/k8t890/k8t890_ctrl.c 2010-11-03 15:51:23.000000000 +0100 @@ -154,7 +154,11 @@
pci_write_config8(dev, 0x47, 0x30);
- /* VT8237R specific configuration other SB are done in their own directories */ + /* + * VT8237R specific configuration, + * other SB are done in their own directories: + * VT8237A and VT8237S are handled in vt8237_ctrl.c + */
device_t devsb = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT8237R_LPC, 0); Index: src/southbridge/via/vt8237r/vt8237r_lpc.c =================================================================== --- src/southbridge/via/vt8237r/vt8237r_lpc.c.orig 2010-11-03 15:50:51.000000000 +0100 +++ src/southbridge/via/vt8237r/vt8237r_lpc.c 2010-11-03 16:02:37.000000000 +0100 @@ -457,7 +457,18 @@ /* I/O recovery time, default IDE routing */ pci_write_config8(dev, 0x4c, 0x04);
- /* ROM memory cycles go to LPC. */ + /* + * Bit | Meaning + * 7 | 1: Only ROM memory cycles go to LPC instead of all memory + * | cycles. + * 6 | 0: Internal ISA cycles do not arbitrate with secondary IDE + * 5 | 0: Disable LPC RTC + * 4 | 0: Disable LPC Keyboard + * 3 | 0: Disable Port 0x62/0x66 to LPC + * 2 | 0: Disable Port 0x62/0x66 MCCS# chipselect decoding + * 1 | 0: Disable A20M# signal (signal not asserted) + * 0 | 0: Disable NMI on PCI parity error + */ pci_write_config8(dev, 0x59, 0x80);
/* @@ -479,7 +490,18 @@ /* I/O recovery time, default IDE routing */ pci_write_config8(dev, 0x4c, 0x44);
- /* ROM memory cycles go to LPC. */ + /* + * Bit | Meaning + * 7 | 1: Only ROM memory cycles go to LPC instead of all memory + * | cycles. + * 6 | 0: Internal ISA cycles do not arbitrate with secondary IDE + * 5 | 0: Disable LPC RTC + * 4 | 0: Disable LPC Keyboard + * 3 | 0: Disable Port 0x62/0x66 to LPC + * 2 | 0: Disable Port 0x62/0x66 MCCS# chipselect decoding + * 1 | 0: Disable A20M# signal (signal not asserted) + * 0 | 0: Disable NMI on PCI parity error + */ pci_write_config8(dev, 0x59, 0x80);
/* Index: src/southbridge/via/k8t890/k8t890_pcie.c =================================================================== --- src/southbridge/via/k8t890/k8t890_pcie.c.orig 2010-11-03 14:53:07.000000000 +0100 +++ src/southbridge/via/k8t890/k8t890_pcie.c 2010-11-03 15:51:23.000000000 +0100 @@ -24,6 +24,12 @@ #include <device/pci_ids.h> #include "k8t890.h"
+/* + * Note: + * The pcie bridges are similar to the VX800 ones documented at + * http://linux.via.com.tw/ + */ + static void peg_init(struct device *dev) { u8 reg;
This adds the m2v directory to src/mainboards/asus and adjusts the Kconfig. Note:
I added pci irq routing setup based on pirq tables: pci_fixup_irqs() in irq_tables.c
I didn't see any existing functionality that will just take the pirq information and use that to setup pci interrupts. For example, in src/southbridge/via/vt8237r/vt8237r_lpc.c there is some epia specific setup, which may really belong into the corresponding mainboard directory...
Signed-off-by: Tobias Diedrich ranma+coreboot@tdiedrich.de
---
Index: src/mainboard/asus/Kconfig =================================================================== --- src/mainboard/asus/Kconfig.orig 2010-10-29 14:03:28.000000000 +0200 +++ src/mainboard/asus/Kconfig 2010-10-29 14:07:37.000000000 +0200 @@ -25,6 +25,8 @@ bool "A8N-E" config BOARD_ASUS_A8V_E_SE bool "A8V-E SE" +config BOARD_ASUS_M2V + bool "M2V" config BOARD_ASUS_M2V_MX_SE bool "M2V-MX SE" config BOARD_ASUS_M4A785M @@ -50,6 +52,7 @@
source "src/mainboard/asus/a8n_e/Kconfig" source "src/mainboard/asus/a8v-e_se/Kconfig" +source "src/mainboard/asus/m2v/Kconfig" source "src/mainboard/asus/m2v-mx_se/Kconfig" source "src/mainboard/asus/m4a785-m/Kconfig" source "src/mainboard/asus/mew-am/Kconfig" Index: src/mainboard/asus/m2v/acpi_tables.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/mainboard/asus/m2v/acpi_tables.c 2010-10-29 14:07:37.000000000 +0200 @@ -0,0 +1,195 @@ +/* + * This file is part of the coreboot project. + * + * Written by Stefan Reinauer stepan@openbios.org. + * ACPI FADT, FACS, and DSDT table support added by + * + * Copyright (C) 2004 Stefan Reinauer stepan@openbios.org + * Copyright (C) 2005 Nick Barker nick.barker9@btinternet.com + * Copyright (C) 2007, 2008 Rudolf Marek r.marek@assembler.cz + * + * 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 <console/console.h> +#include <string.h> +#include <arch/acpi.h> +#include <arch/smp/mpspec.h> +#include <arch/ioapic.h> +#include <device/device.h> +#include <device/pci_ids.h> +#include "southbridge/via/vt8237r/vt8237r.h" +#include "southbridge/via/k8t890/k8t890.h" +#include "northbridge/amd/amdk8/amdk8_acpi.h" +#include <cpu/amd/model_fxx_powernow.h> + +extern const unsigned char AmlCode[]; + +unsigned long acpi_fill_mcfg(unsigned long current) +{ + device_t dev; + struct resource *res; + + dev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_K8T890CF_5, 0); + if (!dev) + return current; + + res = find_resource(dev, K8T890_MMCONFIG_MBAR); + if (res) { + current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *) + current, res->base, 0x0, 0x0, 0xff); + } + return current; +} + +unsigned long acpi_fill_madt(unsigned long current) +{ + unsigned int gsi_base = 0x18; + + /* Create all subtables for processors. */ + current = acpi_create_madt_lapics(current); + + /* Write SB IOAPIC. */ + current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, + VT8237R_APIC_ID, IO_APIC_ADDR, 0); + + /* Write NB IOAPIC. */ + current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, + K8T890_APIC_ID, K8T890_APIC_BASE, gsi_base); + + /* IRQ9 ACPI active low. */ + current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) + current, 0, 9, 9, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_LOW); + + /* IRQ0 -> APIC IRQ2. */ + current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) + current, 0, 0, 2, 0x0); + + /* Create all subtables for processors. */ + current = acpi_create_madt_lapic_nmis(current, + MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, 1); + + return current; +} + +unsigned long acpi_fill_ssdt_generator(unsigned long current, const char *oem_table_id) +{ + k8acpi_write_vars(); + amd_model_fxx_generate_powernow(0, 0, 0); + return (unsigned long) (acpigen_get_current()); +} + +unsigned long write_acpi_tables(unsigned long start) +{ + unsigned long current; + acpi_rsdp_t *rsdp; + acpi_srat_t *srat; + acpi_rsdt_t *rsdt; + acpi_mcfg_t *mcfg; + acpi_hpet_t *hpet; + acpi_madt_t *madt; + acpi_fadt_t *fadt; + acpi_facs_t *facs; + acpi_slit_t *slit; + acpi_header_t *ssdt; + acpi_header_t *dsdt; + + /* Align ACPI tables to 16 byte. */ + start = (start + 0x0f) & -0x10; + current = start; + + printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx...\n", start); + + /* We need at least an RSDP and an RSDT table. */ + rsdp = (acpi_rsdp_t *) current; + current += sizeof(acpi_rsdp_t); + rsdt = (acpi_rsdt_t *) current; + current += sizeof(acpi_rsdt_t); + + /* Clear all table memory. */ + memset((void *) start, 0, current - start); + + acpi_write_rsdp(rsdp, rsdt, NULL); + acpi_write_rsdt(rsdt); + + /* We explicitly add these tables later on: */ + printk(BIOS_DEBUG, "ACPI: * FACS\n"); + + /* we should align FACS to 64B as per ACPI specs */ + + current = ALIGN(current, 64); + facs = (acpi_facs_t *) current; + current += sizeof(acpi_facs_t); + acpi_create_facs(facs); + + dsdt = (acpi_header_t *) current; + memcpy(dsdt, &AmlCode, sizeof(acpi_header_t)); + current += dsdt->length; + memcpy(dsdt, &AmlCode, dsdt->length); + dsdt->checksum = 0; /* Don't trust iasl to get this right. */ + dsdt->checksum = acpi_checksum((u8*)dsdt, dsdt->length); + printk(BIOS_DEBUG, "ACPI: * DSDT @ %p Length %x\n", dsdt, + dsdt->length); + printk(BIOS_DEBUG, "ACPI: * FADT\n"); + + fadt = (acpi_fadt_t *) current; + current += sizeof(acpi_fadt_t); + + acpi_create_fadt(fadt, facs, dsdt); + acpi_add_table(rsdp, fadt); + + printk(BIOS_DEBUG, "ACPI: * HPET\n"); + hpet = (acpi_hpet_t *) current; + current += sizeof(acpi_hpet_t); + acpi_create_hpet(hpet); + acpi_add_table(rsdp, hpet); + + /* If we want to use HPET timers Linux wants an MADT. */ + printk(BIOS_DEBUG, "ACPI: * MADT\n"); + madt = (acpi_madt_t *) current; + acpi_create_madt(madt); + current += madt->header.length; + acpi_add_table(rsdp, madt); + + printk(BIOS_DEBUG, "ACPI: * MCFG\n"); + mcfg = (acpi_mcfg_t *) current; + acpi_create_mcfg(mcfg); + current += mcfg->header.length; + acpi_add_table(rsdp, mcfg); + + printk(BIOS_DEBUG, "ACPI: * SRAT\n"); + srat = (acpi_srat_t *) current; + acpi_create_srat(srat); + current += srat->header.length; + acpi_add_table(rsdp, srat); + + /* SLIT */ + printk(BIOS_DEBUG, "ACPI: * SLIT\n"); + slit = (acpi_slit_t *) current; + acpi_create_slit(slit); + current+=slit->header.length; + acpi_add_table(rsdp,slit); + + /* SSDT */ + printk(BIOS_DEBUG, "ACPI: * SSDT\n"); + ssdt = (acpi_header_t *)current; + + acpi_create_ssdt_generator(ssdt, "DYNADATA"); + current += ssdt->length; + acpi_add_table(rsdp, ssdt); + + printk(BIOS_INFO, "ACPI: done.\n"); + + return current; +} Index: src/mainboard/asus/m2v/chip.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/mainboard/asus/m2v/chip.h 2010-10-29 14:07:37.000000000 +0200 @@ -0,0 +1,22 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Rudolf Marek r.marek@assembler.cz + * + * 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 + */ + +extern struct chip_operations mainboard_ops; + +struct mainboard_config {}; Index: src/mainboard/asus/m2v/cmos.layout =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/mainboard/asus/m2v/cmos.layout 2010-10-29 14:07:37.000000000 +0200 @@ -0,0 +1,98 @@ +entries + +#start-bit length config config-ID name +#0 8 r 0 seconds +#8 8 r 0 alarm_seconds +#16 8 r 0 minutes +#24 8 r 0 alarm_minutes +#32 8 r 0 hours +#40 8 r 0 alarm_hours +#48 8 r 0 day_of_week +#56 8 r 0 day_of_month +#64 8 r 0 month +#72 8 r 0 year +#80 4 r 0 rate_select +#84 3 r 0 REF_Clock +#87 1 r 0 UIP +#88 1 r 0 auto_switch_DST +#89 1 r 0 24_hour_mode +#90 1 r 0 binary_values_enable +#91 1 r 0 square-wave_out_enable +#92 1 r 0 update_finished_enable +#93 1 r 0 alarm_interrupt_enable +#94 1 r 0 periodic_interrupt_enable +#95 1 r 0 disable_clock_updates +#96 288 r 0 temporary_filler +0 384 r 0 reserved_memory +384 1 e 4 boot_option +385 1 e 4 last_boot +386 1 e 1 ECC_memory +388 4 r 0 reboot_bits +392 3 e 5 baud_rate +395 1 e 1 hw_scrubber +396 1 e 1 interleave_chip_selects +397 2 e 8 max_mem_clock +399 1 e 2 multi_core +400 1 e 1 power_on_after_fail +412 4 e 6 debug_level +416 4 e 7 boot_first +420 4 e 7 boot_second +424 4 e 7 boot_third +428 4 h 0 boot_index +432 8 h 0 boot_countdown +440 4 e 9 slow_cpu +444 1 e 1 nmi +445 1 e 1 iommu +728 256 h 0 user_data +984 16 h 0 check_sum +# Reserve the extended AMD configuration registers +1000 24 r 0 amd_reserved + + + +enumerations + +#ID value text +1 0 Disable +1 1 Enable +2 0 Enable +2 1 Disable +4 0 Fallback +4 1 Normal +5 0 115200 +5 1 57600 +5 2 38400 +5 3 19200 +5 4 9600 +5 5 4800 +5 6 2400 +5 7 1200 +6 6 Notice +6 7 Info +6 8 Debug +6 9 Spew +7 0 Network +7 1 HDD +7 2 Floppy +7 8 Fallback_Network +7 9 Fallback_HDD +7 10 Fallback_Floppy +#7 3 ROM +8 0 DDR400 +8 1 DDR333 +8 2 DDR266 +8 3 DDR200 +9 0 off +9 1 87.5% +9 2 75.0% +9 3 62.5% +9 4 50.0% +9 5 37.5% +9 6 25.0% +9 7 12.5% + +checksums + +checksum 392 983 984 + + Index: src/mainboard/asus/m2v/devicetree.cb =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/mainboard/asus/m2v/devicetree.cb 2010-10-29 14:07:37.000000000 +0200 @@ -0,0 +1,74 @@ +chip northbridge/amd/amdk8/root_complex # Root complex + device lapic_cluster 0 on # APIC cluster + chip cpu/amd/socket_AM2 # CPU + device lapic 0 on end # APIC + end + end + device pci_domain 0 on # PCI domain + chip northbridge/amd/amdk8 # mc0 + device pci 18.0 on # Northbridge + # Devices on link 0, link 0 == LDT 0 + chip southbridge/via/vt8237r # Southbridge + register "ide0_enable" = "1" # Enable IDE channel 0 + register "ide1_enable" = "1" # Enable IDE channel 1 + register "ide0_80pin_cable" = "1" # 80pin cable on IDE channel 0 + register "ide1_80pin_cable" = "1" # 80pin cable on IDE channel 1 + register "fn_ctrl_lo" = "0xc0" # Enable SB functions + register "fn_ctrl_hi" = "0x0d" # Enable SB functions + device pci 0.0 on end # HT + device pci f.1 on end # IDE + device pci 11.0 on # LPC + chip drivers/generic/generic # DIMM 0-0-0 + device i2c 50 on end + end + chip drivers/generic/generic # DIMM 0-0-1 + device i2c 51 on end + end + chip drivers/generic/generic # DIMM 0-1-0 + device i2c 52 on end + end + chip drivers/generic/generic # DIMM 0-1-1 + device i2c 53 on end + end + chip superio/ite/it8712f # Super I/O + device pnp 2e.0 on # Floppy + io 0x60 = 0x3f0 + irq 0x70 = 6 + drq 0x74 = 2 + end + device pnp 2e.1 on # Com1 + io 0x60 = 0x3f8 + irq 0x70 = 4 + end + device pnp 2e.2 off end # Com2 (N/A on this board) + device pnp 2e.3 on # Lpt1 + io 0x60 = 0x378 + irq 0x70 = 7 + drq 0x74 = 3 + end + device pnp 2e.4 on # Environment controller + io 0x60 = 0xd00 + io 0x62 = 0xc00 + irq 0x70 = 0x00 + end + device pnp 2e.5 off end # PS/2 keyboard + device pnp 2e.6 off end # PS/2 mouse + device pnp 2e.7 off end # GPIO config + device pnp 2e.8 off end # Midi port + device pnp 2e.9 off end # Game port + device pnp 2e.a off end # IR + end + end + device pci 12.0 off end # VIA LAN (off, other chip used) + device pci 13.0 on end # br + device pci 13.1 on end # br2, need to have it here to discover it + end + chip southbridge/via/k8t890 # "Southbridge" K8T890 + end + end + device pci 18.1 on end + device pci 18.2 on end + device pci 18.3 on end + end + end +end Index: src/mainboard/asus/m2v/dsdt.asl =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/mainboard/asus/m2v/dsdt.asl 2010-10-29 14:07:37.000000000 +0200 @@ -0,0 +1,967 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Nick Barker Nick.Barker9@btinternet.com + * Copyright (C) 2007 Rudolf Marek r.marek@assembler.cz + * Copyright (C) 2010 Tobias Diedrich ranma+coreboot@tdiedrich.de + * + * 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 + */ + +/* + * ISA portions taken from QEMU acpi-dsdt.dsl. + */ + +DefinitionBlock ("DSDT.aml", "DSDT", 2, "CORE ", "COREBOOT", 1) +{ + /* Data to be patched by the BIOS during POST */ + /* FIXME the patching is not done yet! */ + /* Memory related values */ + Name(LOMH, 0x0) /* Start of unused memory in C0000-E0000 range */ + Name(PBAD, 0x0) /* Address of BIOS area (If TOM2 != 0, Addr >> 16) */ + Name(PBLN, 0x0) /* Length of BIOS area */ + + Name(PCBA, 0xE0000000) /* Base address of PCIe config space */ + Name(HPBA, 0xFED00000) /* Base address of HPET table */ + + /* global variables */ + Name(APIC, 0) // 0=>8259, 1=>IOAPIC + Name(LINX, 0) + Name(OSYS, 0x0000) + + /* very generic stuff */ + + /* Port 80 POST */ + + OperationRegion (POST, SystemIO, 0x80, 1) + Field (POST, ByteAcc, Lock, Preserve) + { + DBG0, 8 + } + + Method (DEBG, 1, NotSerialized) + { + Store (Arg0, DBG0) + } + + Method (MIN, 2, NotSerialized) + { + If (LLess (Arg0, Arg1)) { + Return (Arg0) + } + Return (Arg1) + } + + /* generic acpi */ + + /* The _PIC method is called by the OS to choose between interrupt + * routing via the i8259 interrupt controller or the APIC. + * + * _PIC is called with a parameter of 0 for i8259 configuration and + * with a parameter of 1 for Local Apic/IOAPIC configuration. + */ + + Method(_PIC, 1) + { + // Remember the OS' IRQ routing choice. + Store(Arg0, APIC) + } + + Scope(_SB) + { + /* This method is placed on the top level, so we can make sure it's the + * first executed _INI method. + */ + Method(_INI, 0) + { + /* Determine the Operating System and save the value in OSYS. + * We have to do this in order to be able to work around + * certain windows bugs. + * + * OSYS value | Operating System + * -----------+------------------ + * 2000 | Windows 2000 + * 2001 | Windows XP(+SP1) + * 2002 | Windows XP SP2 + * 2006 | Windows Vista + * ???? | Windows 7 + */ + + /* Let's assume we're running at least Windows 2000 */ + Store (2000, OSYS) + + If (CondRefOf(_OSI, Local0)) { + /* Linux answers _OSI with "True" for a couple of + * Windows version queries. But unlike Windows it + * needs a Video repost, so let's determine whether + * we're running Linux. + */ + + If (_OSI("Linux")) { + Store (1, LINX) + } + + If (_OSI("Windows 2001")) { + Store (2001, OSYS) + } + + If (_OSI("Windows 2001 SP1")) { + Store (2001, OSYS) + } + + If (_OSI("Windows 2001 SP2")) { + Store (2002, OSYS) + } + + If (_OSI("Windows 2006")) { + Store (2006, OSYS) + } + } + } + } + + /* _PR CPU0 is dynamically supplied by SSDT */ + + /* For now only define 2 power states: + * - S0 which is fully on + * - S5 which is soft off + * Any others would involve declaring the wake up methods. + * + * Package contents: + * ofs len desc + * 0 1 Value for PM1a_CNT.SLP_TYP register to enter this system state. + * 1 1 Value for PM1b_CNT.SLP_TYP register to enter this system state. To enter any + * given state, OSPM must write the PM1a_CNT.SLP_TYP register before the + * PM1b_CNT.SLP_TYP register. + * 2 2 Reserved + */ + Name (_S0, Package () { 0x00, 0x00, 0x00, 0x00 }) + Name (_S5, Package () { 0x02, 0x02, 0x00, 0x00 }) + + /* + * Prepare to sleep + * + * Arg0 – An Integer containing the value of the sleeping state (1 for S1, 2 for S2, etc.) + * Return Value: None + */ + Method (_PTS, 1, NotSerialized) + { + // FIXME: Not implemented + } + + /* + * Transition to state + * + * Arg0 – An Integer containing the value of the sleeping state (1 for S1, 2 for S2, etc.) + * Return Value: None + */ + Method (_TTS, 1, NotSerialized) + { + // FIXME: Not implemented + } + + /* + * System wake + * + * Arg0 – An Integer containing the value of the sleeping state (1 for S1, 2 for S2, etc.) + * Return Value: A Package containing two Integers containing status and the power supply S-state + * + * Element 0 – An Integer containing a bitfield that represents conditions that occurred during sleep. + * 0x00000000 – Wake was signaled and was successful + * 0x00000001 – Wake was signaled but failed due to lack of power + * 0x00000002 – Wake was signaled but failed due to thermal condition + * Other values – Reserved + * Element 1 – An Integer containing the power supply S-state. + * If non-zero, this is the effective S-state the power supply that was actually entered. This value is used + * to detect when the targeted S-state was not entered because of too much current being drawn from the + * power supply. For example, this might occur when some active device’s current consumption pushes + * the system’s power requirements over the low power supply mark, thus preventing the lower power + * mode from being entered as desired. + */ + Method (_WAK, 1, NotSerialized) + { + // FIXME: Not implemented + Return ( Package () {0x00, 0x00} ) /* successful, S0 */ + } + +/* +OSPM will invoke _GTS, _PTS, _TTS, _WAK, and _BFS in the following order: + 1. OSPM decides (through a policy scheme) to place the system into a sleeping state + 2. _TTS(Sx) is run, where Sx is the desired sleep state to enter + 3. OSPM notifies all native device drivers of the sleep state transition + 4. _PTS is run + 5. OSPM readies system for the sleep state transition + 6. _GTS is run + 7. OSPM writes the sleep vector and the system enters the specified Sx sleep state + 8. System Wakes up + 9. _BFS is run + 10. OSPM readies system for the return from the sleep state transition + 11. _WAK is run + 12. OSPM notifies all native device drivers of the return from the sleep state transition + 13. _TTS(0) is run to indicate the return to the S0 state +*/ + + /* Root of the bus hierarchy */ + Scope (_SB) + { + /* Top PCI device */ + Device (PCI0) + { + Name (_HID, EisaId ("PNP0A03")) + Name (_ADR, 0x00180000) + Name (_BBN, 0x00) + + Name (APRT, Package() { + /* AGP? */ + Package (0x04) { 0x0001FFFF, 0x00, 0x00, 0x10 }, + Package (0x04) { 0x0001FFFF, 0x01, 0x00, 0x11 }, + Package (0x04) { 0x0001FFFF, 0x02, 0x00, 0x12 }, + Package (0x04) { 0x0001FFFF, 0x03, 0x00, 0x13 }, + /* PCIe graphics bridge */ + Package (0x04) { 0x0002FFFF, 0x00, 0x00, 0x1B }, + Package (0x04) { 0x0002FFFF, 0x01, 0x00, 0x1B }, + Package (0x04) { 0x0002FFFF, 0x02, 0x00, 0x1B }, + Package (0x04) { 0x0002FFFF, 0x03, 0x00, 0x1B }, + /* PCIe bridge */ + Package (0x04) { 0x0003FFFF, 0x00, 0x00, 0x1F }, + Package (0x04) { 0x0003FFFF, 0x01, 0x00, 0x23 }, + Package (0x04) { 0x0003FFFF, 0x02, 0x00, 0x27 }, + Package (0x04) { 0x0003FFFF, 0x03, 0x00, 0x2B }, + /* SATA */ + Package (0x04) { 0x000FFFFF, 0x01, 0x00, 0x15 }, + /* IDE */ + Package (0x04) { 0x000FFFFF, 0x00, 0x00, 0x15 }, + /* USB */ + Package (0x04) { 0x0010FFFF, 0x00, 0x00, 0x14 }, + Package (0x04) { 0x0010FFFF, 0x01, 0x00, 0x16 }, + Package (0x04) { 0x0010FFFF, 0x02, 0x00, 0x15 }, + Package (0x04) { 0x0010FFFF, 0x03, 0x00, 0x17 }, + /* PCI bridge */ + Package (0x04) { 0x0013FFFF, 0x00, 0x00, 0x14 }, + Package (0x04) { 0x0013FFFF, 0x01, 0x00, 0x14 }, + Package (0x04) { 0x0013FFFF, 0x02, 0x00, 0x14 }, + Package (0x04) { 0x0013FFFF, 0x03, 0x00, 0x14 }, + }) + Name (PPRT, Package() { + /* ?? */ + Package (0x04) { 0x0001FFFF, 0x00, LNKA, 0x00 }, + Package (0x04) { 0x0001FFFF, 0x01, LNKB, 0x00 }, + Package (0x04) { 0x0001FFFF, 0x02, LNKC, 0x00 }, + Package (0x04) { 0x0001FFFF, 0x03, LNKD, 0x00 }, + /* PCIe graphics bridge */ + Package (0x04) { 0x0002FFFF, 0x00, LNKH, 0x00 }, + Package (0x04) { 0x0002FFFF, 0x01, LNKH, 0x00 }, + Package (0x04) { 0x0002FFFF, 0x02, LNKH, 0x00 }, + Package (0x04) { 0x0002FFFF, 0x03, LNKH, 0x00 }, + /* PCIe bridge */ + Package (0x04) { 0x0003FFFF, 0x00, LNKH, 0x00 }, + Package (0x04) { 0x0003FFFF, 0x01, LNKH, 0x00 }, + Package (0x04) { 0x0003FFFF, 0x02, LNKH, 0x00 }, + Package (0x04) { 0x0003FFFF, 0x03, LNKH, 0x00 }, + /* SATA */ + Package (0x04) { 0x000FFFFF, 0x01, LNKB, 0x00 }, + /* USB */ + Package (0x04) { 0x0010FFFF, 0x00, LNKA, 0x00 }, + Package (0x04) { 0x0010FFFF, 0x01, LNKB, 0x00 }, + Package (0x04) { 0x0010FFFF, 0x02, LNKC, 0x00 }, + Package (0x04) { 0x0010FFFF, 0x03, LNKD, 0x00 }, + /* PCI bridge */ + Package (0x04) { 0x0013FFFF, 0x00, LNKD, 0x00 }, + Package (0x04) { 0x0013FFFF, 0x01, LNKD, 0x00 }, + Package (0x04) { 0x0013FFFF, 0x02, LNKD, 0x00 }, + Package (0x04) { 0x0013FFFF, 0x03, LNKD, 0x00 }, + }) + + /* PCI Routing Table */ + Method (_PRT, 0, NotSerialized) + { + If (APIC) + { + Return (APRT) + } + Return (PPRT) + } + + Device (K8T0) { Name (_ADR, 0x00000000) } + Device (K8T1) { Name (_ADR, 0x00000001) } + Device (K8T2) { Name (_ADR, 0x00000002) } + Device (K8T3) { Name (_ADR, 0x00000003) } + Device (K8T4) { Name (_ADR, 0x00000004) } + Device (K8T5) { Name (_ADR, 0x00000005) } + Device (K8T7) { Name (_ADR, 0x00000007) } + + Device (PCI1) { Name (_ADR, 0x00010000) } + + Device (PEGG) + { + Name (_ADR, 0x00020000) + Name (APRT, Package () { + Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x18 }, /* PCIE IRQ24-IRQ27 */ + Package (0x04) { 0x0000FFFF, 0x01, 0x00, 0x19 }, + Package (0x04) { 0x0000FFFF, 0x02, 0x00, 0x1A }, + Package (0x04) { 0x0000FFFF, 0x03, 0x00, 0x1B }, + }) + Name (PPRT, Package () { + Package (0x04) { 0x0000FFFF, 0x00, LNKH, 0x00 }, + Package (0x04) { 0x0000FFFF, 0x01, LNKH, 0x00 }, + Package (0x04) { 0x0000FFFF, 0x02, LNKH, 0x00 }, + Package (0x04) { 0x0000FFFF, 0x03, LNKH, 0x00 }, + }) + Method (_PRT, 0, NotSerialized) + { + If (APIC) + { + Return (APRT) + } + Return (PPRT) + } + } + + Device (PEX0) + { + Name (_ADR, 0x00030000) + Name (APRT, Package () { + Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x1C }, /* PCIE IRQ28-IRQ31 */ + Package (0x04) { 0x0000FFFF, 0x01, 0x00, 0x1D }, + Package (0x04) { 0x0000FFFF, 0x02, 0x00, 0x1E }, + Package (0x04) { 0x0000FFFF, 0x03, 0x00, 0x1F }, + }) + Name (PPRT, Package () { + Package (0x04) { 0x0000FFFF, 0x00, LNKH, 0x00 }, + Package (0x04) { 0x0000FFFF, 0x01, LNKH, 0x00 }, + Package (0x04) { 0x0000FFFF, 0x02, LNKH, 0x00 }, + Package (0x04) { 0x0000FFFF, 0x03, LNKH, 0x00 }, + }) + Method (_PRT, 0, NotSerialized) + { + If (APIC) + { + Return (APRT) + } + Return (PPRT) + } + } + + Device (PEX1) + { + Name (_ADR, 0x00030001) + Name (APRT, Package () { + Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x20 }, /* PCIE IRQ32-IRQ35 */ + Package (0x04) { 0x0000FFFF, 0x01, 0x00, 0x21 }, + Package (0x04) { 0x0000FFFF, 0x02, 0x00, 0x22 }, + Package (0x04) { 0x0000FFFF, 0x03, 0x00, 0x23 }, + }) + Name (PPRT, Package () { + Package (0x04) { 0x0000FFFF, 0x00, LNKH, 0x00 }, + Package (0x04) { 0x0000FFFF, 0x01, LNKH, 0x00 }, + Package (0x04) { 0x0000FFFF, 0x02, LNKH, 0x00 }, + Package (0x04) { 0x0000FFFF, 0x03, LNKH, 0x00 }, + }) + Method (_PRT, 0, NotSerialized) + { + If (APIC) + { + Return (APRT) + } + Return (PPRT) + } + } + + Device (PEX2) + { + Name (_ADR, 0x00030002) + Name (APRT, Package () { + Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x24 }, /* PCIE IRQ36-IRQ39 */ + Package (0x04) { 0x0000FFFF, 0x01, 0x00, 0x25 }, + Package (0x04) { 0x0000FFFF, 0x02, 0x00, 0x26 }, + Package (0x04) { 0x0000FFFF, 0x03, 0x00, 0x27 }, + }) + Name (PPRT, Package () { + Package (0x04) { 0x0000FFFF, 0x00, LNKH, 0x00 }, + Package (0x04) { 0x0000FFFF, 0x01, LNKH, 0x00 }, + Package (0x04) { 0x0000FFFF, 0x02, LNKH, 0x00 }, + Package (0x04) { 0x0000FFFF, 0x03, LNKH, 0x00 }, + }) + Method (_PRT, 0, NotSerialized) + { + If (APIC) + { + Return (APRT) + } + Return (PPRT) + } + } + + Device (SATA) { Name (_ADR, 0x000f0000) } + Device (PATA) { Name (_ADR, 0x000f0001) } + + Device (PCI6) + { + Name (_ADR, 0x00130000) + Name (APRT, Package () { + Package (0x04) { 0x0001FFFF, 0x00, 0x00, 0x11 }, /* IRQ17 */ + }) + Name (PPRT, Package () { + Package (0x04) { 0x0001FFFF, 0x00, LNKB, 0x00 }, + }) + Method (_PRT, 0, NotSerialized) + { + If (APIC) + { + Return (APRT) + } + Return (PPRT) + } + } + + Device (PCI7) + { + Name (_ADR, 0x00130001) + Name (APR8, Package () { + /* PCI slot 1 */ + Package (0x04) { 0x0006FFFF, 0x00, 0x00, 0x10 }, + Package (0x04) { 0x0006FFFF, 0x01, 0x00, 0x11 }, + Package (0x04) { 0x0006FFFF, 0x02, 0x00, 0x12 }, + Package (0x04) { 0x0006FFFF, 0x03, 0x00, 0x13 }, + + /* PCI slot 2 */ + Package (0x04) { 0x0007FFFF, 0x00, 0x00, 0x11 }, + Package (0x04) { 0x0007FFFF, 0x01, 0x00, 0x12 }, + Package (0x04) { 0x0007FFFF, 0x02, 0x00, 0x13 }, + Package (0x04) { 0x0007FFFF, 0x03, 0x00, 0x10 }, + + /* PCI slot 3 */ + Package (0x04) { 0x0008FFFF, 0x00, 0x00, 0x12 }, + Package (0x04) { 0x0008FFFF, 0x01, 0x00, 0x13 }, + Package (0x04) { 0x0008FFFF, 0x02, 0x00, 0x10 }, + Package (0x04) { 0x0008FFFF, 0x03, 0x00, 0x11 }, + + /* PCI slot 4 */ + Package (0x04) { 0x0009FFFF, 0x00, 0x00, 0x13 }, + Package (0x04) { 0x0009FFFF, 0x01, 0x00, 0x10 }, + Package (0x04) { 0x0009FFFF, 0x02, 0x00, 0x11 }, + Package (0x04) { 0x0009FFFF, 0x03, 0x00, 0x12 }, + }) + Name (PPR8, Package () { + /* PCI slot 1 */ + Package (0x04) { 0x0006FFFF, 0x00, LNKA, 0x00 }, + Package (0x04) { 0x0006FFFF, 0x01, LNKB, 0x00 }, + Package (0x04) { 0x0006FFFF, 0x02, LNKC, 0x00 }, + Package (0x04) { 0x0006FFFF, 0x03, LNKD, 0x00 }, + + /* PCI slot 2 */ + Package (0x04) { 0x0007FFFF, 0x00, LNKB, 0x00 }, + Package (0x04) { 0x0007FFFF, 0x01, LNKC, 0x00 }, + Package (0x04) { 0x0007FFFF, 0x02, LNKD, 0x00 }, + Package (0x04) { 0x0007FFFF, 0x03, LNKA, 0x00 }, + + /* PCI slot 3 */ + Package (0x04) { 0x0008FFFF, 0x00, LNKC, 0x00 }, + Package (0x04) { 0x0008FFFF, 0x01, LNKD, 0x00 }, + Package (0x04) { 0x0008FFFF, 0x02, LNKA, 0x00 }, + Package (0x04) { 0x0008FFFF, 0x03, LNKB, 0x00 }, + + /* PCI slot 4 */ + Package (0x04) { 0x0009FFFF, 0x00, LNKD, 0x00 }, + Package (0x04) { 0x0009FFFF, 0x01, LNKA, 0x00 }, + Package (0x04) { 0x0009FFFF, 0x02, LNKB, 0x00 }, + Package (0x04) { 0x0009FFFF, 0x03, LNKC, 0x00 }, + }) + + Method (_PRT, 0, NotSerialized) + { + If (APIC) + { + Return (APR8) + } + Return (PPR8) + } + } + + Device (PCIE) + { + Name (_HID, EisaId ("PNP0C02")) + Method (_CRS, 0, NotSerialized) + { + Name (TMP, ResourceTemplate () { + Memory32Fixed(ReadOnly, + 0xE0000000, + 0x10000000, + ) + }) + Return (TMP) + } + } + + Device (SBRG) { /* southbridge */ + Name (_ADR, 0x00110000) + Device (HPET) { + Name (_HID, EisaId ("PNP0103")) + Method (_STA, 0, NotSerialized) + { + Return (0x0F) + } + Method (_CRS, 0, NotSerialized) + { + Name (TMP, ResourceTemplate () { + Memory32Fixed(ReadOnly, + 0xFED00000, + 0x00000400, + ) + IRQNoFlags () {0} + IRQNoFlags () {8} + }) + Return (TMP) + } + } + + /* PS/2 keyboard (seems to be important for WinXP install) */ + Device (KBD) + { + Name (_HID, EisaId ("PNP0303")) + Method (_STA, 0, NotSerialized) + { + Return (0x0f) + } + Method (_CRS, 0, NotSerialized) + { + Name (TMP, ResourceTemplate () { + IO (Decode16, 0x0060, 0x0060, 0x01, 0x01) + IO (Decode16, 0x0064, 0x0064, 0x01, 0x01) + IRQNoFlags () {1} + }) + Return (TMP) + } + } + + /* PS/2 mouse */ + Device (MOU) + { + Name (_HID, EisaId ("PNP0F13")) + Method (_STA, 0, NotSerialized) + { + Return (0x0f) + } + Method (_CRS, 0, NotSerialized) + { + Name (TMP, ResourceTemplate () { + IRQNoFlags () {12} + }) + Return (TMP) + } + } + + /* Parallel port */ + Device (LPT0) + { + Name (_HID, EisaId ("PNP0401")) + Method (_STA, 0, NotSerialized) + { + Return (0x0f) + } + Method (_CRS, 0, NotSerialized) + { + Name (TMP, ResourceTemplate () { + IO (Decode16, 0x0378, 0x0378, 0x01, 0x08) + IO (Decode16, 0x0778, 0x0778, 0x01, 0x08) + IRQNoFlags () {7} + DMA (Compatibility, NotBusMaster, Transfer8) {3} + }) + Return (TMP) + } + } + } + + Name(CRES, ResourceTemplate() { + WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode, + 0x0000, // Granularity + 0x0000, // Range Minimum + 0x00FF, // Range Maximum + 0x0000, // Translation Offset + 0x0100, // Length + ,, + ) + IO(Decode16, 0x0CF8, 0x0CF8, 1, 8) + + WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, + 0x0000, /* address granularity */ + 0x0000, /* range minimum */ + 0x0CF7, /* range maximum */ + 0x0000, /* translation */ + 0x0CF8 /* length */ + ) + + WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, + 0x0000, /* address granularity */ + 0x0D00, /* range minimum */ + 0xFFFF, /* range maximum */ + 0x0000, /* translation */ + 0xF300 /* length */ + ) + + Memory32Fixed(READWRITE, 0, 0xA0000, BSMM) + Memory32Fixed(READONLY, 0x000A0000, 0x00020000, VGAM) /* VGA memory space */ + Memory32Fixed(READONLY, 0x000C0000, 0x00020000, EMM1) /* Assume C0000-E0000 empty */ + Memory32Fixed(READONLY, 0x000E0000, 0x00020000, RDBS) /* BIOS ROM area */ + /* DRAM Memory from 1MB to TopMem */ + Memory32Fixed(READWRITE, 0x00100000, 0x00000000, DMLO) /* 1MB to TopMem */ + Memory32Fixed(ReadOnly, 0xE0000000, 0x10000000, MCFG) /* MMCONFIG area */ + Memory32Fixed(READONLY, 0xF0000000, 0x10000000, MMIO) /* PCI mapping space */ + +#if 0 + /* BIOS space just below 4GB */ + DWORDMemory( + ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, + 0x00, /* Granularity */ + 0x00000000, /* Min */ + 0x00000000, /* Max */ + 0x00000000, /* Translation */ + 0x00000001, /* Max-Min, RLEN */ + ,, + PCBM + ) + + /* BIOS space just below 16EB */ + QWORDMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, + 0x00000000, /* Granularity */ + 0x00000000, /* Min */ + 0x00000000, /* Max */ + 0x00000000, /* Translation */ + 0x00000001, /* Max-Min, RLEN */ + ,, + PEBM + ) +#endif + + /* DRAM memory from 4GB to TopMem2 */ + QWORDMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite, + 0x00000000, /* Granularity */ + 0x00000000, /* Min */ + 0x00000000, /* Max */ + 0x00000000, /* Translation */ + 0x00000001, /* Max-Min, RLEN */ + ,, + DMHI + ) + + }) /* End Name(_SB.PCI0.CRES) */ + + External(TOM1) /* 32bit top of memory from SSDT */ + External(TOM2) /* 64bit top of memory from SSDT */ + + Method(_CRS, 0) { + /* DBGO("\_SB\PCI0\_CRS\n") */ + + CreateDWordField(CRES, ^EMM1._BAS, EM1B) + CreateDWordField(CRES, ^EMM1._LEN, EM1L) + CreateDWordField(CRES, ^DMLO._BAS, DMLB) + CreateDWordField(CRES, ^DMLO._LEN, DMLL) +#if 0 + CreateDWordField(CRES, ^PCBM._MIN, PBMB) + CreateDWordField(CRES, ^PCBM._LEN, PBML) + CreateQWordField(CRES, ^PEBM._MIN, EBMB) + CreateQWordField(CRES, ^PEBM._LEN, EBML) +#endif + + CreateQWordField(CRES, ^DMHI._MIN, DMHB) + CreateQWordField(CRES, ^DMHI._MAX, DMHT) + CreateQWordField(CRES, ^DMHI._LEN, DMHL) + +// If(LGreater(LOMH, 0xC0000)){ +// Store(0xC0000, EM1B) /* Hole above C0000 and below E0000 */ +// Subtract(LOMH, 0xC0000, EM1L) /* subtract start, assumes allocation from C0000 going up */ +// } + + /* Set size of memory from 1MB to TopMem */ + Subtract(TOM1, 0x100000, DMLL) + + If(LNotEqual(TOM2, 0x00000000)){ + Store(0x100000000,DMHB) /* DRAM from 4GB to TopMem2 */ + Store(TOM2,DMHT) + Subtract(TOM2, 0x100000000, DMHL) + } + +// /* If there is no memory above 4GB, put the BIOS just below 4GB */ +// If(LEqual(TOM2, 0x00000000)){ +// Store(PBAD,PBMB) /* Reserve the "BIOS" space */ +// Store(PBLN,PBML) +// } +// Else { /* Otherwise, put the BIOS just below 16EB */ +// ShiftLeft(PBAD,16,EBMB) /* Reserve the "BIOS" space */ +// Store(PBLN,EBML) +// } + + Return(CRES) /* note to change the Name buffer */ + } /* end of Method(_SB.PCI0._CRS) */ + } + } + + Scope (_SB) + { + OperationRegion (PCI0.SBRG.PIX0, PCI_Config, 0x55, 0x04) + OperationRegion (PCI0.SBRG.PIX1, PCI_Config, 0x50, 0x02) + OperationRegion (PCI0.SBRG.PIX2, PCI_Config, 0x44, 0x02) + OperationRegion (PCI0.SBRG.PIX3, PCI_Config, 0x67, 0x03) + OperationRegion (PCI0.SBRG.PIX4, PCI_Config, 0x6C, 0x04) + OperationRegion (PCI0.SBRG.PIEF, PCI_Config, 0x46, 0x01) + Field (PCI0.SBRG.PIX0, ByteAcc, NoLock, Preserve) + { + , 4, + PIRA, 4, + PIRB, 4, + PIRC, 4, + , 4, + PIRD, 4, + , 4 + } + Field (PCI0.SBRG.PIX1, ByteAcc, NoLock, Preserve) + { + , 1, + EP3C, 1, + EN3C, 1, + , 6, + KBFG, 1 + } + Field (PCI0.SBRG.PIX2, ByteAcc, NoLock, Preserve) + { + PIRE, 4, + PIRF, 4, + PIRG, 4, + PIRH, 4, + } + Field (PCI0.SBRG.PIX3, ByteAcc, NoLock, Preserve) + { + ENIR, 1, + IRSD, 1, + Offset (0x02), + IRBA, 8 + } + Field (PCI0.SBRG.PIX4, ByteAcc, NoLock, Preserve) + { + PS0E, 1, + PS1E, 1, + ROME, 1, + APCE, 1, + LPMS, 2, + MSEN, 1, + IXEN, 1, + LPMD, 2, + MDEN, 1, + GMEN, 1, + LPLP, 2, + LPEN, 1, + FDEN, 1, + LPCA, 3, + CAEN, 1, + LPCB, 3, + CBEN, 1, + LPSB, 2, + SBEN, 1, + FDSE, 1, + Offset (0x04) + } + Field (PCI0.SBRG.PIEF, ByteAcc, NoLock, Preserve) + { + POLE, 1, + POLF, 1, + POLG, 1, + POLH, 1, + ENR8, 1 + } + Name (IRQA, 0x00) + Name (IRQB, 0x00) + Name (IRQC, 0x00) + Name (IRQD, 0x00) + Name (IRQE, 0x00) + Name (IRQF, 0x00) + Name (IRQG, 0x00) + Name (IRQH, 0x00) + Name (ICRS, ResourceTemplate () { IRQ (Level, ActiveLow, Shared, ) {15} } ) + Name (IPRS, ResourceTemplate () { + IRQ (Level, ActiveLow, Shared, ) {3,4,5,6,7,10,11,12,14,15} + }) + + Device (LNKA) + { + Name (_HID, EisaId ("PNP0C0F")) + Name (_UID, 0x01) + Method (_PRS, 0, NotSerialized) { Return (IPRS) } + Method (_STA, 0, NotSerialized) + { + Store (PIRA, IRQA) + If (PIRA) { + Return (0x0B) + } Else { + Return (0x09) + } + } + Method (_DIS, 0, NotSerialized) + { + Store (Zero, PIRA) + } + Method (_CRS, 0, NotSerialized) + { + CreateWordField (ICRS, One, IRA0) + Store (One, Local1) + ShiftLeft (Local1, IRQA, IRA0) + Return (ICRS) + } + Method (_SRS, 1, NotSerialized) + { + CreateWordField (Arg0, One, IRA) + FindSetRightBit (IRA, Local0) + Decrement (Local0) + Store (Local0, PIRA) + Store (PIRA, IRQA) + } + } + Device (LNKB) + { + Name (_HID, EisaId ("PNP0C0F")) + Name (_UID, 0x02) + Method (_PRS, 0, NotSerialized) { Return (IPRS) } + Method (_STA, 0, NotSerialized) + { + Store (PIRB, IRQB) + If (PIRB) { + Return (0x0B) + } Else { + Return (0x09) + } + } + Method (_DIS, 0, NotSerialized) + { + Store (Zero, PIRB) + } + Method (_CRS, 0, NotSerialized) + { + CreateWordField (ICRS, One, IRB0) + Store (One, Local1) + ShiftLeft (Local1, IRQB, IRB0) + Return (ICRS) + } + Method (_SRS, 1, NotSerialized) + { + CreateWordField (Arg0, One, IRA) + FindSetRightBit (IRA, Local0) + Decrement (Local0) + Store (Local0, PIRB) + Store (PIRB, IRQB) + } + } + Device (LNKC) + { + Name (_HID, EisaId ("PNP0C0F")) + Name (_UID, 0x03) + Method (_PRS, 0, NotSerialized) { Return (IPRS) } + Method (_STA, 0, NotSerialized) + { + Store (PIRC, IRQC) + If (PIRC) { + Return (0x0B) + } Else { + Return (0x09) + } + } + Method (_DIS, 0, NotSerialized) + { + Store (Zero, PIRC) + } + Method (_CRS, 0, NotSerialized) + { + CreateWordField (ICRS, One, IRB0) + Store (One, Local1) + ShiftLeft (Local1, IRQC, IRB0) + Return (ICRS) + } + Method (_SRS, 1, NotSerialized) + { + CreateWordField (Arg0, One, IRA) + FindSetRightBit (IRA, Local0) + Decrement (Local0) + Store (Local0, PIRC) + Store (PIRC, IRQC) + } + } + Device (LNKD) + { + Name (_HID, EisaId ("PNP0C0F")) + Name (_UID, 0x04) + Method (_PRS, 0, NotSerialized) { Return (IPRS) } + Method (_STA, 0, NotSerialized) + { + Store (PIRD, IRQD) + If (PIRD) { + Return (0x0B) + } Else { + Return (0x09) + } + } + Method (_DIS, 0, NotSerialized) + { + Store (Zero, PIRD) + } + Method (_CRS, 0, NotSerialized) + { + CreateWordField (ICRS, One, IRB0) + Store (One, Local1) + ShiftLeft (Local1, IRQD, IRB0) + Return (ICRS) + } + Method (_SRS, 1, NotSerialized) + { + CreateWordField (Arg0, One, IRA) + FindSetRightBit (IRA, Local0) + Decrement (Local0) + Store (Local0, PIRD) + Store (PIRD, IRQD) + } + } + Device (LNKH) + { + Name (_HID, EisaId ("PNP0C0F")) + Name (_UID, 0x08) + Method (_PRS, 0, NotSerialized) { Return (IPRS) } + Method (_STA, 0, NotSerialized) + { + Store (PIRH, IRQH) + If (PIRH) { + Return (0x0B) + } Else { + Return (0x09) + } + } + Method (_DIS, 0, NotSerialized) + { + Store (Zero, PIRH) + } + Method (_CRS, 0, NotSerialized) + { + CreateWordField (ICRS, One, IRA0) + Store (One, Local1) + ShiftLeft (Local1, IRQH, IRA0) + Return (ICRS) + } + Method (_SRS, 1, NotSerialized) + { + CreateWordField (Arg0, One, IRA) + FindSetRightBit (IRA, Local0) + Decrement (Local0) + Store (Local0, PIRH) + Store (PIRH, IRQH) + Store (One, ENR8) + } + } + } +} Index: src/mainboard/asus/m2v/Kconfig =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/mainboard/asus/m2v/Kconfig 2010-10-29 14:12:34.000000000 +0200 @@ -0,0 +1,84 @@ +if BOARD_ASUS_M2V + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select ARCH_X86 + select CPU_AMD_SOCKET_AM2 + select DIMM_DDR2 + select K8_HT_FREQ_1G_SUPPORT + select NORTHBRIDGE_AMD_AMDK8 + select NORTHBRIDGE_AMD_AMDK8_ROOT_COMPLEX + select SOUTHBRIDGE_VIA_VT8237R + select SOUTHBRIDGE_VIA_K8T890 + select SUPERIO_ITE_IT8712F + select CACHE_AS_RAM + select HAVE_OPTION_TABLE + select HAVE_ACPI_TABLES + select HAVE_MP_TABLE + select HAVE_PIRQ_TABLE + select HAVE_MAINBOARD_RESOURCES + select BOARD_ROMSIZE_KB_512 + select RAMINIT_SYSINFO + select TINY_BOOTBLOCK + +config MAINBOARD_DIR + string + default asus/m2v + +config DCACHE_RAM_BASE + hex + default 0xcc000 + +config DCACHE_RAM_SIZE + hex + default 0x4000 + +config DCACHE_RAM_GLOBAL_VAR_SIZE + hex + default 0x1000 + +config APIC_ID_OFFSET + hex + default 0x10 + +config SB_HT_CHAIN_ON_BUS0 + int + default 1 + +config MAINBOARD_PART_NUMBER + string + default "M2V" + +config HW_MEM_HOLE_SIZEK + hex + default 0 + +config MAX_CPUS + int + default 2 + +config MAX_PHYSICAL_CPUS + int + default 1 + +config HEAP_SIZE + hex + default 0x40000 + +config HT_CHAIN_END_UNITID_BASE + hex + default 0x20 + +config HT_CHAIN_UNITID_BASE + hex + default 0x0 + +config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID + hex + default 0x1043 + +config IRQ_SLOT_COUNT + int + default 17 + +endif # BOARD_ASUS_M2V Index: src/mainboard/asus/m2v/mainboard.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/mainboard/asus/m2v/mainboard.c 2010-10-29 14:07:37.000000000 +0200 @@ -0,0 +1,233 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2010 Tobias Diedrich ranma+coreboot@tdiedrich.de + * + * 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 <console/console.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <arch/io.h> +#include <arch/ioapic.h> +#include <arch/pci_ops.h> +#include <boot/tables.h> +#include <cpu/x86/msr.h> +#include <cpu/amd/mtrr.h> +#include <device/pci_def.h> +#include "southbridge/via/vt8237r/vt8237r.h" +#include "southbridge/via/k8t890/k8t890.h" +#include "chip.h" +#include "superio/ite/it8712f/it8712f.h" + +/* The base address is 0x2e or 0x4e, depending on config bytes. */ +#define SIO_BASE 0x2e +#define SIO_INDEX SIO_BASE +#define SIO_DATA SIO_BASE+1 + +/* Global configuration registers. */ +#define IT8712F_CONFIG_REG_CC 0x02 /* Configure Control (write-only). */ +#define IT8712F_CONFIG_REG_LDN 0x07 /* Logical Device Number. */ +#define IT8712F_CONFIG_REG_CONFIGSEL 0x22 /* Configuration Select. */ +#define IT8712F_CONFIG_REG_CLOCKSEL 0x23 /* Clock Selection. */ +#define IT8712F_CONFIG_REG_SWSUSP 0x24 /* Software Suspend, Flash I/F. */ +#define IT8712F_CONFIG_REG_MFC 0x2a /* Multi-function control */ +#define IT8712F_CONFIG_REG_WATCHDOG 0x72 /* Watchdog control. */ + +#define IT8712F_CONFIGURATION_PORT 0x2e /* Write-only. */ + +#define IT8712F_GPIO_BASE 0x0a20 + +/* The content of IT8712F_CONFIG_REG_LDN (index 0x07) must be set to the + LDN the register belongs to, before you can access the register. */ +static void it8712f_sio_write(uint8_t ldn, uint8_t index, uint8_t value) +{ + outb(IT8712F_CONFIG_REG_LDN, SIO_BASE); + outb(ldn, SIO_DATA); + outb(index, SIO_BASE); + outb(value, SIO_DATA); +} + +static void it8712f_enter_conf(void) +{ + /* Enter the configuration state (MB PnP mode). */ + + /* Perform MB PnP setup to put the SIO chip at 0x2e. */ + /* Base address 0x2e: 0x87 0x01 0x55 0x55. */ + /* Base address 0x4e: 0x87 0x01 0x55 0xaa. */ + outb(0x87, IT8712F_CONFIGURATION_PORT); + outb(0x01, IT8712F_CONFIGURATION_PORT); + outb(0x55, IT8712F_CONFIGURATION_PORT); + outb(0x55, IT8712F_CONFIGURATION_PORT); +} + +static void it8712f_exit_conf(void) +{ + /* Exit the configuration state (MB PnP mode). */ + it8712f_sio_write(0x00, IT8712F_CONFIG_REG_CC, 0x02); +} + +struct gpio_init_val { + u8 addr; + u8 val; +}; + +static const struct gpio_init_val gpio_init_data[] = { + /* multi-function pin selection */ + { 0x25, 0x00 }, + { 0x28, 0x00 }, /* gp46 is infrared receive input */ + { 0x29, 0x40 }, /* reserved value?!? */ + { 0x2a, 0x00 }, + { 0x2c, 0x1d }, /* pin91 is VIN7 instead of PCIRSTIN# */ + /* gpio i/o port base */ + { 0x62, IT8712F_GPIO_BASE >> 8 }, + { 0x63, IT8712F_GPIO_BASE & 0xff }, + /* 0xb8 - 0xbc: gpio pull-up enable */ + { 0xb8, 0x00 }, + /* 0xc0 - 0xc4: gpio alternate function select */ + { 0xc0, 0x00 }, + { 0xc3, 0x00 }, + { 0xc4, 0xc0 }, + /* 0xc8 - 0xcc: gpio output enable */ + { 0xc8, 0x00 }, + { 0xcb, 0x00 }, + { 0xcc, 0xc0 }, + /* end of list */ + { 0, 0 }, +}; + +static void m2v_it8712f_gpio_init(void) +{ + const struct gpio_init_val *giv; + + /* + * it8712f gpio config + * + * Most importantly this switches pin 91 from + * PCIRSTIN# to VIN7. + * Note that only PCIRST3# and PCIRST5# are affected + * by PCIRSTIN#, the PCIRST1#, PCIRST2#, PCIRST4# are always + * direct buffers of #LRESET (low pin count bus reset). + * If this is not done All PCIRST are in reset state and the + * pcie slots don't initialize. + * + * pci reset handling: + * pin 91: VIN7 (alternate PCIRSTIN#) + * pin 48: PCIRST5# / gpio port 5 bit 0 + * pin 84: PCIRST4# / gpio port 1 bit 0 + * pin 31: PCIRST1# / gpio port 1 bit 4 + * pin 33: PCIRST2# / gpio port 1 bit 2 + * pin 34: PCIRST3# / gpio port 1 bit 1 + * + * PCIRST[0-5]# are connected as follows: + * pcirst1# -> pci bus + * pcirst2# -> ide bus + * pcirst3# -> pcie devices + * pcirst4# -> pcie graphics + * pcirst5# -> maybe n/c (untested) + * + * For software control of PCIRST[1-5]#: + * 0x2a=0x17 (deselect pcirst# hardwiring, enable 0x25 control) + * 0x25=0x17 (select gpio function) + * 0xc0=0x17, 0xc8=0x17 gpio port 1 select & output enable + * 0xc4=0xc1, 0xcc=0xc1 gpio port 5 select & output enable + */ + it8712f_enter_conf(); + giv = gpio_init_data; + while (giv->addr) { + printk(BIOS_DEBUG, "it8712f gpio: %02x=%02x\n", giv->addr, giv->val); + it8712f_sio_write(IT8712F_GPIO, giv->addr, giv->val); + giv++; + } + it8712f_exit_conf(); +} + +static void m2v_bus_init(void) +{ + u8 tmp; + + pci_cf8_conf1.write8(NULL, 0, PCI_DEVFN(0, 0), K8T890_MULTIPLE_FN_EN, 0x01); + /* + * Northbridge pcie bridge 3.3 is not connected to anything, hide it. + */ + tmp = pci_cf8_conf1.read8(NULL, 0, PCI_DEVFN(0x0, 5), 0xf0); + tmp &= ~0x10; /* hide pcie bridge 0:3.3 */ + tmp &= ~0x40; /* hide scratch register function 0:0.6 */ + pci_cf8_conf1.write8(NULL, 0, PCI_DEVFN(0x0, 5), 0xf0, tmp); + /* Enable southbridge bridges 13.0 and 13.1 */ + pci_cf8_conf1.write8(NULL, 0, PCI_DEVFN(0x11, 7), 0X4F, 0x43); +} + +static void m2v_enable(device_t dev) +{ + + printk(BIOS_INFO, "Mainboard M2V enable. dev=0x%p\n", dev); + + m2v_it8712f_gpio_init(); + m2v_bus_init(); +} + +static void m2v_init(void) +{ + device_t dev; + + dev = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237A_LPC, 0); + + printk(BIOS_INFO, "Mainboard M2V init.\n"); + + if (dev) { + /* VT8237A LPC gpio function/direction settings */ + pci_write_config8(dev, 0xe0, 0x00); + pci_write_config8(dev, 0xe1, 0x00); + pci_write_config8(dev, 0xe2, 0x06); + pci_write_config8(dev, 0xe3, 0x00); + pci_write_config8(dev, 0xe4, 0x24); + pci_write_config8(dev, 0xe5, 0x69); + pci_write_config8(dev, 0xe6, 0xef); + } + + /* VT8237A LPC gpio output value */ + outl(0x00000208, VT8237R_ACPI_IO_BASE + 0x4c); + + /* Override dev 1 device id to match asus bios */ + dev = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_K8T890CE_BR, 0); + if (dev) + pci_write_config16(dev, 0x46, 0xb999); +} + +int add_mainboard_resources(struct lb_memory *mem) +{ + m2v_init(); + + printk(BIOS_INFO, "Adding APIC + BIOS reserved memory resources\n"); + /* + * Mark APIC memory as reserved to get closer to ASUS E820 map + */ + lb_add_memory_range(mem, LB_MEM_RESERVED, IO_APIC_ADDR, 0x1000); + lb_add_memory_range(mem, LB_MEM_RESERVED, K8T890_APIC_BASE, 0x1000); + /* + * Mark BIOS ROM space as reserved + */ + lb_add_memory_range(mem, LB_MEM_RESERVED, 0xffc00000, 0x400000); + return 0; +} + +struct chip_operations mainboard_ops = { + CHIP_NAME("ASUS M2V") + .enable_dev = m2v_enable, +}; Index: src/mainboard/asus/m2v/mptable.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/mainboard/asus/m2v/mptable.c 2010-10-29 14:07:37.000000000 +0200 @@ -0,0 +1,178 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Rudolf Marek r.marek@assembler.cz + * Copyright (C) 2010 Tobias Diedrich ranma+coreboot@tdiedrich.de + * + * 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 <string.h> +#include <stdint.h> +#include <arch/smp/mpspec.h> +#include <arch/ioapic.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include "southbridge/via/vt8237r/vt8237r.h" +#include "southbridge/via/k8t890/k8t890.h" + +static void smp_write_intsrc_pci(struct mp_config_table *mc, + unsigned char srcbus, unsigned char srcbusirq, + unsigned char dstapic, unsigned char dstirq) +{ + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, + srcbus, srcbusirq, dstapic, dstirq); +} + +static void *smp_write_config_table(void *v) +{ + static const char sig[4] = "PCMP"; + static const char oem[8] = "COREBOOT"; + static const char productid[12] = "M2V "; + struct mp_config_table *mc; + int bus_isa = 42; + + mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); + memset(mc, 0, sizeof(*mc)); + + memcpy(mc->mpc_signature, sig, sizeof(sig)); + mc->mpc_length = sizeof(*mc); /* Initially just the header. */ + mc->mpc_spec = 0x04; + mc->mpc_checksum = 0; /* Not yet computed. */ + memcpy(mc->mpc_oem, oem, sizeof(oem)); + memcpy(mc->mpc_productid, productid, sizeof(productid)); + mc->mpc_oemptr = 0; + mc->mpc_oemsize = 0; + mc->mpc_entry_count = 0; /* No entries yet. */ + mc->mpc_lapic = LAPIC_ADDR; + mc->mpe_length = 0; + mc->mpe_checksum = 0; + mc->reserved = 0; + + smp_write_processors(mc); + + /* Bus: Bus ID Type */ + smp_write_bus(mc, 0, "PCI "); /* root bus */ + smp_write_bus(mc, 1, "PCI "); /* agp? */ + smp_write_bus(mc, 2, "PCI "); /* pcie x16 */ + smp_write_bus(mc, 3, "PCI "); /* pcie x1 */ + smp_write_bus(mc, 4, "PCI "); /* pcie x1 */ + smp_write_bus(mc, 5, "PCI "); /* pcie x1 */ + smp_write_bus(mc, 6, "PCI "); /* azalia audio */ + smp_write_bus(mc, 7, "PCI "); /* pci */ + smp_write_bus(mc, bus_isa, "ISA "); + + /* I/O APICs: APIC ID Version State Address */ + smp_write_ioapic(mc, VT8237R_APIC_ID, 0x3, IO_APIC_ADDR); + smp_write_ioapic(mc, K8T890_APIC_ID, 0x3, K8T890_APIC_BASE); + + mptable_add_isa_interrupts(mc, bus_isa, VT8237R_APIC_ID, 0); + + /* agp? bridge */ + smp_write_intsrc_pci(mc, 0, (0x1 << 2) | 0, VT8237R_APIC_ID, 0x10); + smp_write_intsrc_pci(mc, 0, (0x1 << 2) | 1, VT8237R_APIC_ID, 0x11); + smp_write_intsrc_pci(mc, 0, (0x1 << 2) | 2, VT8237R_APIC_ID, 0x12); + smp_write_intsrc_pci(mc, 0, (0x1 << 2) | 3, VT8237R_APIC_ID, 0x13); + + /* peg bridge */ + smp_write_intsrc_pci(mc, 0, (0x2 << 2) | 0, K8T890_APIC_ID, 0x3); + smp_write_intsrc_pci(mc, 0, (0x2 << 2) | 1, K8T890_APIC_ID, 0x3); + smp_write_intsrc_pci(mc, 0, (0x2 << 2) | 2, K8T890_APIC_ID, 0x3); + smp_write_intsrc_pci(mc, 0, (0x2 << 2) | 3, K8T890_APIC_ID, 0x3); + + /* pex bridge */ + smp_write_intsrc_pci(mc, 0, (0x3 << 2) | 0, K8T890_APIC_ID, 0x7); + smp_write_intsrc_pci(mc, 0, (0x3 << 2) | 1, K8T890_APIC_ID, 0xb); + smp_write_intsrc_pci(mc, 0, (0x3 << 2) | 2, K8T890_APIC_ID, 0xf); + smp_write_intsrc_pci(mc, 0, (0x3 << 2) | 3, K8T890_APIC_ID, 0x13); + + /* SATA / IDE */ + smp_write_intsrc_pci(mc, 0, (0xf << 2) | 0, VT8237R_APIC_ID, 0x15); + + /* USB */ + smp_write_intsrc_pci(mc, 0, (0x10 << 2) | 0, VT8237R_APIC_ID, 0x14); + smp_write_intsrc_pci(mc, 0, (0x10 << 2) | 1, VT8237R_APIC_ID, 0x16); + smp_write_intsrc_pci(mc, 0, (0x10 << 2) | 2, VT8237R_APIC_ID, 0x15); + smp_write_intsrc_pci(mc, 0, (0x10 << 2) | 3, VT8237R_APIC_ID, 0x17); + + /* PCIE graphics */ + smp_write_intsrc_pci(mc, 2, (0x00 << 2) | 0, K8T890_APIC_ID, 0x0); + smp_write_intsrc_pci(mc, 2, (0x00 << 2) | 1, K8T890_APIC_ID, 0x1); + smp_write_intsrc_pci(mc, 2, (0x00 << 2) | 2, K8T890_APIC_ID, 0x2); + smp_write_intsrc_pci(mc, 2, (0x00 << 2) | 3, K8T890_APIC_ID, 0x3); + + /* onboard PCIE atl1 ethernet */ + smp_write_intsrc_pci(mc, 3, (0x00 << 2) | 0, K8T890_APIC_ID, 0x4); + smp_write_intsrc_pci(mc, 3, (0x00 << 2) | 1, K8T890_APIC_ID, 0x5); + smp_write_intsrc_pci(mc, 3, (0x00 << 2) | 2, K8T890_APIC_ID, 0x6); + smp_write_intsrc_pci(mc, 3, (0x00 << 2) | 3, K8T890_APIC_ID, 0x7); + + /* PCIE slot */ + smp_write_intsrc_pci(mc, 4, (0x00 << 2) | 0, K8T890_APIC_ID, 0x8); + smp_write_intsrc_pci(mc, 4, (0x00 << 2) | 1, K8T890_APIC_ID, 0x9); + smp_write_intsrc_pci(mc, 4, (0x00 << 2) | 2, K8T890_APIC_ID, 0xa); + smp_write_intsrc_pci(mc, 4, (0x00 << 2) | 3, K8T890_APIC_ID, 0xb); + + /* onboard marvell mv6121 sata */ + smp_write_intsrc_pci(mc, 5, (0x00 << 2) | 0, K8T890_APIC_ID, 0xc); + smp_write_intsrc_pci(mc, 5, (0x00 << 2) | 1, K8T890_APIC_ID, 0xd); + smp_write_intsrc_pci(mc, 5, (0x00 << 2) | 2, K8T890_APIC_ID, 0xe); + smp_write_intsrc_pci(mc, 5, (0x00 << 2) | 3, K8T890_APIC_ID, 0xf); + + /* azalia HDCA */ + smp_write_intsrc_pci(mc, 6, (0x01 << 2) | 0, VT8237R_APIC_ID, 0x11); + + /* pci slot 1 */ + smp_write_intsrc_pci(mc, 7, (6 << 2) | 0, VT8237R_APIC_ID, 0x10); + smp_write_intsrc_pci(mc, 7, (6 << 2) | 1, VT8237R_APIC_ID, 0x11); + smp_write_intsrc_pci(mc, 7, (6 << 2) | 2, VT8237R_APIC_ID, 0x12); + smp_write_intsrc_pci(mc, 7, (6 << 2) | 3, VT8237R_APIC_ID, 0x13); + + /* pci slot 2 */ + smp_write_intsrc_pci(mc, 7, (7 << 2) | 0, VT8237R_APIC_ID, 0x11); + smp_write_intsrc_pci(mc, 7, (7 << 2) | 1, VT8237R_APIC_ID, 0x12); + smp_write_intsrc_pci(mc, 7, (7 << 2) | 2, VT8237R_APIC_ID, 0x13); + smp_write_intsrc_pci(mc, 7, (7 << 2) | 3, VT8237R_APIC_ID, 0x10); + + /* pci slot 3 */ + smp_write_intsrc_pci(mc, 7, (8 << 2) | 0, VT8237R_APIC_ID, 0x12); + smp_write_intsrc_pci(mc, 7, (8 << 2) | 1, VT8237R_APIC_ID, 0x13); + smp_write_intsrc_pci(mc, 7, (8 << 2) | 2, VT8237R_APIC_ID, 0x10); + smp_write_intsrc_pci(mc, 7, (8 << 2) | 3, VT8237R_APIC_ID, 0x11); + + /* pci slot 4 */ + smp_write_intsrc_pci(mc, 7, (9 << 2) | 0, VT8237R_APIC_ID, 0x13); + smp_write_intsrc_pci(mc, 7, (9 << 2) | 1, VT8237R_APIC_ID, 0x10); + smp_write_intsrc_pci(mc, 7, (9 << 2) | 2, VT8237R_APIC_ID, 0x11); + smp_write_intsrc_pci(mc, 7, (9 << 2) | 3, VT8237R_APIC_ID, 0x12); + + /* Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */ + smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0, 0x0, MP_APIC_ALL, 0x0); + smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0, 0x0, MP_APIC_ALL, 0x1); + /* There is no extension information... */ + + /* Compute the checksums. */ + mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), + mc->mpe_length); + mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length); + + return smp_next_mpe_entry(mc); +} + +unsigned long write_smp_table(unsigned long addr) +{ + void *v; + v = smp_write_floating_table(addr); + return (unsigned long)smp_write_config_table(v); +} Index: src/mainboard/asus/m2v/romstage.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/mainboard/asus/m2v/romstage.c 2010-10-29 14:07:37.000000000 +0200 @@ -0,0 +1,210 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2006 AMD + * (Written by Yinghai Lu yinghailu@amd.com for AMD) + * Copyright (C) 2006 MSI + * (Written by Bingxun Shi bingxunshi@gmail.com for MSI) + * Copyright (C) 2008 Rudolf Marek r.marek@assembler.cz + * + * 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; either version 2 of the License, or + * (at your option) any later version. + * + * 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 + */ + +unsigned int get_sbdn(unsigned bus); + +/* Used by raminit. */ +#define QRANK_DIMM_SUPPORT 1 + +/* Used by init_cpus and fidvid */ +#define SET_FIDVID 1 + +/* If we want to wait for core1 done before DQS training, set it to 0. */ +#define SET_FIDVID_CORE0_ONLY 1 + +#if CONFIG_K8_REV_F_SUPPORT == 1 +#define K8_REV_F_SUPPORT_F0_F1_WORKAROUND 0 +#endif + +#include <stdint.h> +#include <string.h> +#include <device/pci_def.h> +#include <arch/io.h> +#include <device/pnp_def.h> +#include <arch/romcc_io.h> +#include <cpu/amd/mtrr.h> +#include <cpu/x86/lapic.h> +#include <pc80/mc146818rtc.h> +#include <console/console.h> +#include <cpu/amd/model_fxx_rev.h> +#include "northbridge/amd/amdk8/raminit.h" +#include "cpu/amd/model_fxx/apic_timer.c" +#include "lib/delay.c" +#include "northbridge/amd/amdk8/reset_test.c" +#include "northbridge/amd/amdk8/debug.c" +#include "superio/ite/it8712f/it8712f_early_serial.c" +#include "southbridge/via/vt8237r/vt8237r_early_smbus.c" +#include "cpu/x86/mtrr/earlymtrr.c" +#include "cpu/x86/bist.h" +#include "northbridge/amd/amdk8/setup_resource_map.c" + +#define SERIAL_DEV PNP_DEV(0x2e, IT8712F_SP1) +#define WATCHDOG_DEV PNP_DEV(0x2e, IT8712F_GPIO) + +static void memreset(int controllers, const struct mem_controller *ctrl) +{ +} + +static inline int spd_read_byte(unsigned device, unsigned address) +{ + return smbus_read_byte(device, address); +} + +static void activate_spd_rom(const struct mem_controller *ctrl) +{ +} + +// defines S3_NVRAM_EARLY: +#include "southbridge/via/k8t890/k8t890_early_car.c" + +#include "northbridge/amd/amdk8/amdk8.h" +#include "northbridge/amd/amdk8/incoherent_ht.c" +#include "northbridge/amd/amdk8/coherent_ht.c" +#include "northbridge/amd/amdk8/raminit_f.c" +#include "lib/generic_sdram.c" + +#include "cpu/amd/dualcore/dualcore.c" + +#include "cpu/amd/car/post_cache_as_ram.c" +#include "cpu/amd/model_fxx/init_cpus.c" + +#define SB_VFSMAF 0 + +/* this function might fail on some K8 CPUs with errata #181 */ +static void ldtstop_sb(void) +{ + print_debug("toggle LDTSTP#\n"); + u8 reg = inb (VT8237R_ACPI_IO_BASE + 0x5c); + reg = reg ^ (1 << 0); + outb(reg, VT8237R_ACPI_IO_BASE + 0x5c); + reg = inb(VT8237R_ACPI_IO_BASE + 0x15); + print_debug("done\n"); +} + +#include "cpu/amd/model_fxx/fidvid.c" +#include "northbridge/amd/amdk8/resourcemap.c" + +void soft_reset(void) +{ + uint8_t tmp; + + set_bios_reset(); + print_debug("soft reset \n"); + + /* PCI reset */ + tmp = pci_read_config8(PCI_DEV(0, 0x11, 0), 0x4f); + tmp |= 0x01; + /* FIXME from S3 set bit1 to disable USB reset VT8237A/S */ + pci_write_config8(PCI_DEV(0, 0x11, 0), 0x4f, tmp); + + while (1) { + /* daisy daisy ... */ + hlt(); + } +} + +unsigned int get_sbdn(unsigned bus) +{ + device_t dev; + + dev = pci_locate_device_on_bus(PCI_ID(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VT8237R_LPC), bus); + return (dev >> 15) & 0x1f; +} + +void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) +{ + static const uint16_t spd_addr[] = { + // Node 0 + (0xa << 3) | 0, (0xa << 3) | 2, 0, 0, + (0xa << 3) | 1, (0xa << 3) | 3, 0, 0, + // Node 1 + (0xa << 3) | 4, (0xa << 3) | 6, 0, 0, + (0xa << 3) | 5, (0xa << 3) | 7, 0, 0, + }; + unsigned bsp_apicid = 0; + int needs_reset = 0; + struct sys_info *sysinfo = + (struct sys_info *)(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE - CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE); + + it8712f_24mhz_clkin(); + it8712f_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); + it8712f_kill_watchdog(); + uart_init(); + console_init(); + enable_rom_decode(); + + printk(BIOS_INFO, "now booting... \n"); + + if (bist == 0) + bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo); + + /* Halt if there was a built in self test failure. */ + report_bist_failure(bist); + setup_default_resource_map(); + setup_coherent_ht_domain(); + wait_all_core0_started(); + + printk(BIOS_INFO, "now booting... All core 0 started\n"); + +#if CONFIG_LOGICAL_CPUS==1 + /* It is said that we should start core1 after all core0 launched. */ + start_other_cores(); + wait_all_other_cores_started(bsp_apicid); +#endif + init_timer(); + ht_setup_chains_x(sysinfo); /* Init sblnk and sbbusn, nodes, sbdn. */ + + needs_reset = optimize_link_coherent_ht(); + print_debug_hex8(needs_reset); + needs_reset |= optimize_link_incoherent_ht(sysinfo); + print_debug_hex8(needs_reset); + needs_reset |= k8t890_early_setup_ht(); + print_debug_hex8(needs_reset); + + if (needs_reset) { + printk(BIOS_DEBUG, "ht reset -\n"); + soft_reset(); + printk(BIOS_DEBUG, "FAILED!\n"); + } + + /* the HT settings needs to be OK, because link freq chnage may cause HT disconnect */ + /* allow LDT STOP asserts */ + vt8237_sb_enable_fid_vid(); + + enable_fid_change(); + print_debug("after enable_fid_change\n"); + + init_fidvid_bsp(bsp_apicid); + + /* Stop the APs so we can start them later in init. */ + allow_all_aps_stop(bsp_apicid); + + /* It's the time to set ctrl now. */ + fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr); + enable_smbus(); + sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo); + post_cache_as_ram(); +} + Index: src/mainboard/asus/m2v/irq_tables.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/mainboard/asus/m2v/irq_tables.c 2010-10-29 14:07:37.000000000 +0200 @@ -0,0 +1,202 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2010 Tobias Diedrich ranma+coreboot@tdiedrich.de + * + * 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 + * + * IRQ Routing Table + * + * Documentation at : http://www.microsoft.com/hwdev/busbios/PCIIRQ.HTM + */ +#include <console/console.h> +#include <device/pci.h> +#include <string.h> +#include <stdint.h> +#include <arch/pirq_routing.h> +#include <pc80/i8259.h> + +const struct irq_routing_table intel_irq_routing_table = { + PIRQ_SIGNATURE, /* u32 signature */ + PIRQ_VERSION, /* u16 version */ + 32+16*CONFIG_IRQ_SLOT_COUNT, /* there can be total CONFIG_IRQ_SLOT_COUNT devices on the bus */ + 0, /* Where the interrupt router lies (bus) */ + (0x11<<3)|0, /* Where the interrupt router lies (dev) */ + 0, /* IRQs devoted exclusively to PCI usage */ + 0x1106, /* Vendor */ + 0x3337, /* Device */ + 0, /* Miniport data */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ + 0xb8, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structu +re (including checksum) */ + { + /* bus, dev | fn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */ + /* peg bridge */ + {0x00, (0x02 << 3) | 0x0, {{0x05, 0xdcf8}, {0x05, 0xdcf8}, {0x05, 0xdcf8}, {0x05, 0xdcf8}}, 0x0, 0x0}, + /* pcie bridge */ + {0x00, (0x03 << 3) | 0x0, {{0x05, 0xdcf8}, {0x05, 0xdcf8}, {0x05, 0xdcf8}, {0x05, 0xdcf8}}, 0x0, 0x0}, + /* sata/ide */ + {0x00, (0x0f << 3) | 0x0, {{0x00, 0x0000}, {0x02, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x0, 0x0}, + /* usb */ + {0x00, (0x10 << 3) | 0x0, {{0x01, 0xdcf8}, {0x02, 0xdcf8}, {0x03, 0xdcf8}, {0x04, 0xdcf8}}, 0x0, 0x0}, + /* agp bus? */ + {0x01, (0x00 << 3) | 0x0, {{0x01, 0xdcf8}, {0x02, 0xdcf8}, {0x03, 0xdcf8}, {0x04, 0xdcf8}}, 0xa, 0x0}, + /* pcie graphics */ + {0x02, (0x00 << 3) | 0x0, {{0x05, 0xdcf8}, {0x05, 0xdcf8}, {0x05, 0xdcf8}, {0x05, 0xdcf8}}, 0xb, 0x0}, + /* onboard pcie atl1 ethernet */ + {0x03, (0x00 << 3) | 0x0, {{0x05, 0xdcf8}, {0x05, 0xdcf8}, {0x05, 0xdcf8}, {0x05, 0xdcf8}}, 0xf, 0x0}, + /* pcie slot */ + {0x04, (0x00 << 3) | 0x0, {{0x05, 0xdcf8}, {0x05, 0xdcf8}, {0x05, 0xdcf8}, {0x05, 0xdcf8}}, 0x0, 0x0}, + /* onboard marvell mv6121 sata */ + {0x05, (0x00 << 3) | 0x0, {{0x05, 0xdcf8}, {0x05, 0xdcf8}, {0x05, 0xdcf8}, {0x05, 0xdcf8}}, 0xd, 0x0}, + /* Azalia HDAC */ + {0x06, (0x01 << 3) | 0x0, {{0x02, 0xdcf8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x0000}}, 0x0, 0x0}, + /* PCI slots */ + {0x07, (0x06 << 3) | 0x0, {{0x01, 0xdcf8}, {0x02, 0xdcf8}, {0x03, 0xdcf8}, {0x04, 0xdcf8}}, 0x1, 0x0}, + {0x07, (0x07 << 3) | 0x0, {{0x02, 0xdcf8}, {0x03, 0xdcf8}, {0x04, 0xdcf8}, {0x01, 0xdcf8}}, 0x2, 0x0}, + {0x07, (0x08 << 3) | 0x0, {{0x03, 0xdcf8}, {0x04, 0xdcf8}, {0x01, 0xdcf8}, {0x02, 0xdcf8}}, 0x3, 0x0}, + {0x07, (0x09 << 3) | 0x0, {{0x04, 0xdcf8}, {0x01, 0xdcf8}, {0x02, 0xdcf8}, {0x03, 0xdcf8}}, 0x4, 0x0}, + } +}; + +static void pci_fixup_irqs(void) +{ + const struct irq_routing_table *pirq = &intel_irq_routing_table; + /* We don't have a secondary serial port or an isa soundcard, so we + * can use irqs 3 and 5 in addition to 10 and 11. + */ + char route[5] = { + 3, 5, 10, 10, 11 + }; + int i; + device_t dev; + + /* pci is level triggered */ + for (i=0; i<sizeof(route); i++) + i8259_configure_irq_trigger(route[i], IRQ_LEVEL_TRIGGERED); + + /* set up router */ + dev = dev_find_slot(0, PCI_DEVFN(0x11, 0)); + pci_write_config8(dev, 0x55, route[0] << 4); + pci_write_config8(dev, 0x56, (route[2] << 4) | route[1]); + pci_write_config8(dev, 0x57, route[3] << 4); + + pci_write_config8(dev, 0x45, route[4] << 4); /* INTH */ + pci_write_config8(dev, 0x46, 0x10); /* enable INTE-H routing */ + + for (i=0; i<CONFIG_IRQ_SLOT_COUNT; i++) { + const struct irq_info *slot = &pirq->slots[i]; + int intx, irq, link, d, fn; + + for (intx=0; intx<4; intx++) { + link = slot->irq[intx].link; + if (link != 0) + break; + } + if (link>0 && link<=sizeof(route)) { + irq = route[link-1]; + intx++; + } else { + irq = -1; + } + + d = slot->devfn >> 3; + fn = slot->devfn & 7; + + dev = dev_find_slot(slot->bus, slot->devfn); + if (!dev) { + printk(BIOS_DEBUG, "Could not find device %02x:%02x.%d from routing table!\n", slot->bus, d, fn); + continue; + } + + intx = 0; + do { + int j, tmp; + + /* find first INTx that has link info and can be used */ + for (j=0; j<4; intx++, j++) { + intx %= 4; + link = slot->irq[intx].link; + if (link != 0) + break; + } + if (link == 0) + break; + + irq = route[link-1]; + pci_write_config8(dev, PCI_INTERRUPT_LINE, irq); + printk(BIOS_INFO, "PCI %02x:%02x.%d (%08x) routed to pin %d irq %d.\n", + slot->bus, d, fn, pci_read_config32(dev, 0), intx+1, irq); + + pci_write_config8(dev, PCI_INTERRUPT_PIN, intx+1); + /* read back (may be fixed and unchangable) */ + tmp = pci_read_config8(dev, PCI_INTERRUPT_PIN); + if (tmp != intx+1) { + if (tmp < 1 || tmp > 4) { + printk(BIOS_ERR, "PCI %02x:%02x.%d (%08x) is not configurable!\n", + slot->bus, d, fn, pci_read_config32(dev, 0)); + } else { + printk(BIOS_ERR, "PCI %02x:%02x.%d (%08x) line fixed at %d!\n", + slot->bus, d, fn, pci_read_config32(dev, 0), tmp); + + link = slot->irq[tmp-1].link; + if (link != 0) { + irq = route[link-1]; + pci_write_config8(dev, PCI_INTERRUPT_LINE, irq); + printk(BIOS_INFO, "PCI %02x:%02x.%d (%08x) routed to pin %d irq %d.\n", + slot->bus, d, fn, pci_read_config32(dev, 0), tmp, irq); + } + } + } + + if (fn == 7) + break; /* last subdevice */ + + if (!(pci_read_config8(dev, PCI_HEADER_TYPE) & 0x80)) + break; /* not multifunction device */ + + intx++; + fn++; + dev = dev_find_slot(slot->bus, PCI_DEVFN(d, fn)); + } while (dev); + } +} + +unsigned long write_pirq_routing_table(unsigned long addr) +{ + struct irq_routing_table *pirq; + unsigned long ret; + uint8_t *v; + uint8_t sum; + int i; + + ret = copy_pirq_routing_table(addr); + pci_fixup_irqs(); + + /* fixup checksum */ + v = (void*)(addr); + pirq = (void*)(addr); + + sum = 0; + for (i = 0; i < pirq->size; i++) + sum += v[i]; + sum = pirq->checksum - sum; + + if (sum != pirq->checksum) { + printk(BIOS_INFO, "Setting PIRQ checksum to %02x!\n", sum); + pirq->checksum = sum; + } + + return ret; +}
Hi,
On 29.10.2010 14:14, Tobias Diedrich wrote:
This adds the m2v directory to src/mainboards/asus and adjusts the Kconfig. Note:
I added pci irq routing setup based on pirq tables: pci_fixup_irqs() in irq_tables.c
I didn't see any existing functionality that will just take the pirq information and use that to setup pci interrupts. For example, in src/southbridge/via/vt8237r/vt8237r_lpc.c there is some epia specific setup, which may really belong into the corresponding mainboard directory...
Hmm the legacy PIC routing may not work. In linux it could. I never tested that.
- /* Write SB IOAPIC. */
- current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
VT8237R_APIC_ID, IO_APIC_ADDR, 0);
- /* Write NB IOAPIC. */
- current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
K8T890_APIC_ID, K8T890_APIC_BASE, gsi_base);
I never used the VIA system on multicore CPU, dunno what to do if we have in fact more cpus... The IDs should be shifted then.
+++ src/mainboard/asus/m2v/dsdt.asl 2010-10-29 14:07:37.000000000 +0200 @@ -0,0 +1,967 @@ +/*
- This file is part of the coreboot project.
- Copyright (C) 2004 Nick BarkerNick.Barker9@btinternet.com
- Copyright (C) 2007 Rudolf Marekr.marek@assembler.cz
- Copyright (C) 2010 Tobias Diedrichranma+coreboot@tdiedrich.de
Where you have taken parts of it? Some parts feel like AMD 7xx code? Maybe we miss copyright here?
- 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
- */
+/*
- ISA portions taken from QEMU acpi-dsdt.dsl.
- */
+DefinitionBlock ("DSDT.aml", "DSDT", 2, "CORE ", "COREBOOT", 1) +{
- /* Data to be patched by the BIOS during POST */
- /* FIXME the patching is not done yet! */
- /* Memory related values */
- Name(LOMH, 0x0) /* Start of unused memory in C0000-E0000 range */
- Name(PBAD, 0x0) /* Address of BIOS area (If TOM2 != 0, Addr>> 16) */
- Name(PBLN, 0x0) /* Length of BIOS area */
We dont do patching we do apcigen stuff instead into SSDT.
- Name(PCBA, 0xE0000000) /* Base address of PCIe config space */
This cannot be hardcoded.
- Name(HPBA, 0xFED00000) /* Base address of HPET table */
- /* global variables */
- Name(APIC, 0) // 0=>8259, 1=>IOAPIC
- Name(LINX, 0)
- Name(OSYS, 0x0000)
- /* very generic stuff */
- /* Port 80 POST */
- OperationRegion (POST, SystemIO, 0x80, 1)
- Field (POST, ByteAcc, Lock, Preserve)
- {
DBG0, 8
- }
- Method (DEBG, 1, NotSerialized)
- {
Store (Arg0, DBG0)
- }
I dont think you need this. My philosophy for ACPI code is: Put there only what is needed even no extra bit more.
- Method (MIN, 2, NotSerialized)
- {
If (LLess (Arg0, Arg1)) {
Return (Arg0)
}
Return (Arg1)
- }
- /* generic acpi */
- /* The _PIC method is called by the OS to choose between interrupt
* routing via the i8259 interrupt controller or the APIC.
*
* _PIC is called with a parameter of 0 for i8259 configuration and
* with a parameter of 1 for Local Apic/IOAPIC configuration.
*/
- Method(_PIC, 1)
- {
// Remember the OS' IRQ routing choice.
Store(Arg0, APIC)
- }
- Scope(_SB)
- {
/* This method is placed on the top level, so we can make sure it's the
* first executed _INI method.
*/
Method(_INI, 0)
{
/* Determine the Operating System and save the value in OSYS.
* We have to do this in order to be able to work around
* certain windows bugs.
*
* OSYS value | Operating System
* -----------+------------------
* 2000 | Windows 2000
* 2001 | Windows XP(+SP1)
* 2002 | Windows XP SP2
* 2006 | Windows Vista
* ???? | Windows 7
*/
/* Let's assume we're running at least Windows 2000 */
Store (2000, OSYS)
If (CondRefOf(_OSI, Local0)) {
/* Linux answers _OSI with "True" for a couple of
* Windows version queries. But unlike Windows it
* needs a Video repost, so let's determine whether
* we're running Linux.
*/
If (_OSI("Linux")) {
Store (1, LINX)
}
If (_OSI("Windows 2001")) {
Store (2001, OSYS)
}
If (_OSI("Windows 2001 SP1")) {
Store (2001, OSYS)
}
If (_OSI("Windows 2001 SP2")) {
Store (2002, OSYS)
}
If (_OSI("Windows 2006")) {
Store (2006, OSYS)
}
}
}
- }
You dont need this.
- /* _PR CPU0 is dynamically supplied by SSDT */
- /* For now only define 2 power states:
* - S0 which is fully on
* - S5 which is soft off
* Any others would involve declaring the wake up methods.
*
* Package contents:
* ofs len desc
* 0 1 Value for PM1a_CNT.SLP_TYP register to enter this system state.
* 1 1 Value for PM1b_CNT.SLP_TYP register to enter this system state. To enter any
* given state, OSPM must write the PM1a_CNT.SLP_TYP register before the
* PM1b_CNT.SLP_TYP register.
* 2 2 Reserved
*/
- Name (_S0, Package () { 0x00, 0x00, 0x00, 0x00 })
- Name (_S5, Package () { 0x02, 0x02, 0x00, 0x00 })
- /*
* Prepare to sleep
*
* Arg0 – An Integer containing the value of the sleeping state (1 for S1, 2 for S2, etc.)
* Return Value: None
*/
- Method (_PTS, 1, NotSerialized)
- {
// FIXME: Not implemented
- }
- /*
* Transition to state
*
* Arg0 – An Integer containing the value of the sleeping state (1 for S1, 2 for S2, etc.)
* Return Value: None
*/
- Method (_TTS, 1, NotSerialized)
- {
// FIXME: Not implemented
- }
get rif of those please
- /*
* System wake
*
* Arg0 – An Integer containing the value of the sleeping state (1 for S1, 2 for S2, etc.)
* Return Value: A Package containing two Integers containing status and the power supply S-state
*
* Element 0 – An Integer containing a bitfield that represents conditions that occurred during sleep.
* 0x00000000 – Wake was signaled and was successful
* 0x00000001 – Wake was signaled but failed due to lack of power
* 0x00000002 – Wake was signaled but failed due to thermal condition
* Other values – Reserved
* Element 1 – An Integer containing the power supply S-state.
* If non-zero, this is the effective S-state the power supply that was actually entered. This value is used
* to detect when the targeted S-state was not entered because of too much current being drawn from the
* power supply. For example, this might occur when some active device’s current consumption pushes
* the system’s power requirements over the low power supply mark, thus preventing the lower power
* mode from being entered as desired.
*/
- Method (_WAK, 1, NotSerialized)
- {
// FIXME: Not implemented
Return ( Package () {0x00, 0x00} ) /* successful, S0 */
- }
same here
+/* +OSPM will invoke _GTS, _PTS, _TTS, _WAK, and _BFS in the following order:
- OSPM decides (through a policy scheme) to place the system into a sleeping state
- _TTS(Sx) is run, where Sx is the desired sleep state to enter
- OSPM notifies all native device drivers of the sleep state transition
- _PTS is run
- OSPM readies system for the sleep state transition
- _GTS is run
- OSPM writes the sleep vector and the system enters the specified Sx sleep state
- System Wakes up
- _BFS is run
- OSPM readies system for the return from the sleep state transition
- _WAK is run
- OSPM notifies all native device drivers of the return from the sleep state transition
- _TTS(0) is run to indicate the return to the S0 state
+*/
and here
- /* Root of the bus hierarchy */
- Scope (_SB)
- {
/* Top PCI device */
Device (PCI0)
{
Name (_HID, EisaId ("PNP0A03"))
Name (_ADR, 0x00180000)
Name (_BBN, 0x00)
Name (APRT, Package() {
/* AGP? */
Package (0x04) { 0x0001FFFF, 0x00, 0x00, 0x10 },
Package (0x04) { 0x0001FFFF, 0x01, 0x00, 0x11 },
Package (0x04) { 0x0001FFFF, 0x02, 0x00, 0x12 },
Package (0x04) { 0x0001FFFF, 0x03, 0x00, 0x13 },
/* PCIe graphics bridge */
Package (0x04) { 0x0002FFFF, 0x00, 0x00, 0x1B },
Package (0x04) { 0x0002FFFF, 0x01, 0x00, 0x1B },
Package (0x04) { 0x0002FFFF, 0x02, 0x00, 0x1B },
Package (0x04) { 0x0002FFFF, 0x03, 0x00, 0x1B },
/* PCIe bridge */
Package (0x04) { 0x0003FFFF, 0x00, 0x00, 0x1F },
Package (0x04) { 0x0003FFFF, 0x01, 0x00, 0x23 },
Package (0x04) { 0x0003FFFF, 0x02, 0x00, 0x27 },
Package (0x04) { 0x0003FFFF, 0x03, 0x00, 0x2B },
/* SATA */
Package (0x04) { 0x000FFFFF, 0x01, 0x00, 0x15 },
/* IDE */
Package (0x04) { 0x000FFFFF, 0x00, 0x00, 0x15 },
/* USB */
Package (0x04) { 0x0010FFFF, 0x00, 0x00, 0x14 },
Package (0x04) { 0x0010FFFF, 0x01, 0x00, 0x16 },
Package (0x04) { 0x0010FFFF, 0x02, 0x00, 0x15 },
Package (0x04) { 0x0010FFFF, 0x03, 0x00, 0x17 },
/* PCI bridge */
Package (0x04) { 0x0013FFFF, 0x00, 0x00, 0x14 },
Package (0x04) { 0x0013FFFF, 0x01, 0x00, 0x14 },
Package (0x04) { 0x0013FFFF, 0x02, 0x00, 0x14 },
Package (0x04) { 0x0013FFFF, 0x03, 0x00, 0x14 },
})
Name (PPRT, Package() {
/* ?? */
Package (0x04) { 0x0001FFFF, 0x00, LNKA, 0x00 },
Package (0x04) { 0x0001FFFF, 0x01, LNKB, 0x00 },
Package (0x04) { 0x0001FFFF, 0x02, LNKC, 0x00 },
Package (0x04) { 0x0001FFFF, 0x03, LNKD, 0x00 },
/* PCIe graphics bridge */
Package (0x04) { 0x0002FFFF, 0x00, LNKH, 0x00 },
Package (0x04) { 0x0002FFFF, 0x01, LNKH, 0x00 },
Package (0x04) { 0x0002FFFF, 0x02, LNKH, 0x00 },
Package (0x04) { 0x0002FFFF, 0x03, LNKH, 0x00 },
/* PCIe bridge */
Package (0x04) { 0x0003FFFF, 0x00, LNKH, 0x00 },
Package (0x04) { 0x0003FFFF, 0x01, LNKH, 0x00 },
Package (0x04) { 0x0003FFFF, 0x02, LNKH, 0x00 },
Package (0x04) { 0x0003FFFF, 0x03, LNKH, 0x00 },
/* SATA */
Package (0x04) { 0x000FFFFF, 0x01, LNKB, 0x00 },
/* USB */
Package (0x04) { 0x0010FFFF, 0x00, LNKA, 0x00 },
Package (0x04) { 0x0010FFFF, 0x01, LNKB, 0x00 },
Package (0x04) { 0x0010FFFF, 0x02, LNKC, 0x00 },
Package (0x04) { 0x0010FFFF, 0x03, LNKD, 0x00 },
/* PCI bridge */
Package (0x04) { 0x0013FFFF, 0x00, LNKD, 0x00 },
Package (0x04) { 0x0013FFFF, 0x01, LNKD, 0x00 },
Package (0x04) { 0x0013FFFF, 0x02, LNKD, 0x00 },
Package (0x04) { 0x0013FFFF, 0x03, LNKD, 0x00 },
})
/* PCI Routing Table */
Method (_PRT, 0, NotSerialized)
{
If (APIC)
{
Return (APRT)
}
Return (PPRT)
}
Device (K8T0) { Name (_ADR, 0x00000000) }
Device (K8T1) { Name (_ADR, 0x00000001) }
Device (K8T2) { Name (_ADR, 0x00000002) }
Device (K8T3) { Name (_ADR, 0x00000003) }
Device (K8T4) { Name (_ADR, 0x00000004) }
Device (K8T5) { Name (_ADR, 0x00000005) }
Device (K8T7) { Name (_ADR, 0x00000007) }
no need
Device (PCI1) { Name (_ADR, 0x00010000) }
Device (PEGG)
{
Name (_ADR, 0x00020000)
Name (APRT, Package () {
Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x18 }, /* PCIE IRQ24-IRQ27 */
Package (0x04) { 0x0000FFFF, 0x01, 0x00, 0x19 },
Package (0x04) { 0x0000FFFF, 0x02, 0x00, 0x1A },
Package (0x04) { 0x0000FFFF, 0x03, 0x00, 0x1B },
})
Name (PPRT, Package () {
Package (0x04) { 0x0000FFFF, 0x00, LNKH, 0x00 },
Package (0x04) { 0x0000FFFF, 0x01, LNKH, 0x00 },
Package (0x04) { 0x0000FFFF, 0x02, LNKH, 0x00 },
Package (0x04) { 0x0000FFFF, 0x03, LNKH, 0x00 },
})
Method (_PRT, 0, NotSerialized)
{
If (APIC)
{
Return (APRT)
}
Return (PPRT)
}
}
Device (PEX0)
{
Name (_ADR, 0x00030000)
Name (APRT, Package () {
Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x1C }, /* PCIE IRQ28-IRQ31 */
Package (0x04) { 0x0000FFFF, 0x01, 0x00, 0x1D },
Package (0x04) { 0x0000FFFF, 0x02, 0x00, 0x1E },
Package (0x04) { 0x0000FFFF, 0x03, 0x00, 0x1F },
})
Name (PPRT, Package () {
Package (0x04) { 0x0000FFFF, 0x00, LNKH, 0x00 },
Package (0x04) { 0x0000FFFF, 0x01, LNKH, 0x00 },
Package (0x04) { 0x0000FFFF, 0x02, LNKH, 0x00 },
Package (0x04) { 0x0000FFFF, 0x03, LNKH, 0x00 },
})
Method (_PRT, 0, NotSerialized)
{
If (APIC)
{
Return (APRT)
}
Return (PPRT)
}
}
Device (PEX1)
{
Name (_ADR, 0x00030001)
Name (APRT, Package () {
Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x20 }, /* PCIE IRQ32-IRQ35 */
Package (0x04) { 0x0000FFFF, 0x01, 0x00, 0x21 },
Package (0x04) { 0x0000FFFF, 0x02, 0x00, 0x22 },
Package (0x04) { 0x0000FFFF, 0x03, 0x00, 0x23 },
})
Name (PPRT, Package () {
Package (0x04) { 0x0000FFFF, 0x00, LNKH, 0x00 },
Package (0x04) { 0x0000FFFF, 0x01, LNKH, 0x00 },
Package (0x04) { 0x0000FFFF, 0x02, LNKH, 0x00 },
Package (0x04) { 0x0000FFFF, 0x03, LNKH, 0x00 },
})
Method (_PRT, 0, NotSerialized)
{
If (APIC)
{
Return (APRT)
}
Return (PPRT)
}
}
Device (PEX2)
{
Name (_ADR, 0x00030002)
Name (APRT, Package () {
Package (0x04) { 0x0000FFFF, 0x00, 0x00, 0x24 }, /* PCIE IRQ36-IRQ39 */
Package (0x04) { 0x0000FFFF, 0x01, 0x00, 0x25 },
Package (0x04) { 0x0000FFFF, 0x02, 0x00, 0x26 },
Package (0x04) { 0x0000FFFF, 0x03, 0x00, 0x27 },
})
Name (PPRT, Package () {
Package (0x04) { 0x0000FFFF, 0x00, LNKH, 0x00 },
Package (0x04) { 0x0000FFFF, 0x01, LNKH, 0x00 },
Package (0x04) { 0x0000FFFF, 0x02, LNKH, 0x00 },
Package (0x04) { 0x0000FFFF, 0x03, LNKH, 0x00 },
})
Method (_PRT, 0, NotSerialized)
{
If (APIC)
{
Return (APRT)
}
Return (PPRT)
}
}
Device (SATA) { Name (_ADR, 0x000f0000) }
Device (PATA) { Name (_ADR, 0x000f0001) }
Device (PCI6)
{
Name (_ADR, 0x00130000)
Name (APRT, Package () {
Package (0x04) { 0x0001FFFF, 0x00, 0x00, 0x11 }, /* IRQ17 */
})
Name (PPRT, Package () {
Package (0x04) { 0x0001FFFF, 0x00, LNKB, 0x00 },
})
Method (_PRT, 0, NotSerialized)
{
If (APIC)
{
Return (APRT)
}
Return (PPRT)
}
}
Device (PCI7)
{
Name (_ADR, 0x00130001)
Name (APR8, Package () {
/* PCI slot 1 */
Package (0x04) { 0x0006FFFF, 0x00, 0x00, 0x10 },
Package (0x04) { 0x0006FFFF, 0x01, 0x00, 0x11 },
Package (0x04) { 0x0006FFFF, 0x02, 0x00, 0x12 },
Package (0x04) { 0x0006FFFF, 0x03, 0x00, 0x13 },
/* PCI slot 2 */
Package (0x04) { 0x0007FFFF, 0x00, 0x00, 0x11 },
Package (0x04) { 0x0007FFFF, 0x01, 0x00, 0x12 },
Package (0x04) { 0x0007FFFF, 0x02, 0x00, 0x13 },
Package (0x04) { 0x0007FFFF, 0x03, 0x00, 0x10 },
/* PCI slot 3 */
Package (0x04) { 0x0008FFFF, 0x00, 0x00, 0x12 },
Package (0x04) { 0x0008FFFF, 0x01, 0x00, 0x13 },
Package (0x04) { 0x0008FFFF, 0x02, 0x00, 0x10 },
Package (0x04) { 0x0008FFFF, 0x03, 0x00, 0x11 },
/* PCI slot 4 */
Package (0x04) { 0x0009FFFF, 0x00, 0x00, 0x13 },
Package (0x04) { 0x0009FFFF, 0x01, 0x00, 0x10 },
Package (0x04) { 0x0009FFFF, 0x02, 0x00, 0x11 },
Package (0x04) { 0x0009FFFF, 0x03, 0x00, 0x12 },
})
Name (PPR8, Package () {
/* PCI slot 1 */
Package (0x04) { 0x0006FFFF, 0x00, LNKA, 0x00 },
Package (0x04) { 0x0006FFFF, 0x01, LNKB, 0x00 },
Package (0x04) { 0x0006FFFF, 0x02, LNKC, 0x00 },
Package (0x04) { 0x0006FFFF, 0x03, LNKD, 0x00 },
/* PCI slot 2 */
Package (0x04) { 0x0007FFFF, 0x00, LNKB, 0x00 },
Package (0x04) { 0x0007FFFF, 0x01, LNKC, 0x00 },
Package (0x04) { 0x0007FFFF, 0x02, LNKD, 0x00 },
Package (0x04) { 0x0007FFFF, 0x03, LNKA, 0x00 },
/* PCI slot 3 */
Package (0x04) { 0x0008FFFF, 0x00, LNKC, 0x00 },
Package (0x04) { 0x0008FFFF, 0x01, LNKD, 0x00 },
Package (0x04) { 0x0008FFFF, 0x02, LNKA, 0x00 },
Package (0x04) { 0x0008FFFF, 0x03, LNKB, 0x00 },
/* PCI slot 4 */
Package (0x04) { 0x0009FFFF, 0x00, LNKD, 0x00 },
Package (0x04) { 0x0009FFFF, 0x01, LNKA, 0x00 },
Package (0x04) { 0x0009FFFF, 0x02, LNKB, 0x00 },
Package (0x04) { 0x0009FFFF, 0x03, LNKC, 0x00 },
})
Method (_PRT, 0, NotSerialized)
{
If (APIC)
{
Return (APR8)
}
Return (PPR8)
}
}
Device (PCIE)
{
Name (_HID, EisaId ("PNP0C02"))
Method (_CRS, 0, NotSerialized)
{
Name (TMP, ResourceTemplate () {
Memory32Fixed(ReadOnly,
0xE0000000,
Sorry this cannot be hardcoded. I dont think you need this at all.
0x10000000,
)
})
Return (TMP)
}
}
Device (SBRG) { /* southbridge */
Name (_ADR, 0x00110000)
Device (HPET) {
Name (_HID, EisaId ("PNP0103"))
Method (_STA, 0, NotSerialized)
{
Return (0x0F)
}
Method (_CRS, 0, NotSerialized)
{
Name (TMP, ResourceTemplate () {
Memory32Fixed(ReadOnly,
0xFED00000,
0x00000400,
)
IRQNoFlags () {0}
IRQNoFlags () {8}
})
Return (TMP)
}
}
/* PS/2 keyboard (seems to be important for WinXP install) */
Device (KBD)
{
Name (_HID, EisaId ("PNP0303"))
Method (_STA, 0, NotSerialized)
{
Return (0x0f)
}
Method (_CRS, 0, NotSerialized)
{
Name (TMP, ResourceTemplate () {
IO (Decode16, 0x0060, 0x0060, 0x01, 0x01)
IO (Decode16, 0x0064, 0x0064, 0x01, 0x01)
IRQNoFlags () {1}
})
Return (TMP)
}
}
/* PS/2 mouse */
Device (MOU)
{
Name (_HID, EisaId ("PNP0F13"))
Method (_STA, 0, NotSerialized)
{
Return (0x0f)
}
Method (_CRS, 0, NotSerialized)
{
Name (TMP, ResourceTemplate () {
IRQNoFlags () {12}
})
Return (TMP)
}
}
/* Parallel port */
Device (LPT0)
{
Name (_HID, EisaId ("PNP0401"))
Method (_STA, 0, NotSerialized)
{
Return (0x0f)
}
Method (_CRS, 0, NotSerialized)
{
Name (TMP, ResourceTemplate () {
IO (Decode16, 0x0378, 0x0378, 0x01, 0x08)
IO (Decode16, 0x0778, 0x0778, 0x01, 0x08)
IRQNoFlags () {7}
DMA (Compatibility, NotBusMaster, Transfer8) {3}
})
Return (TMP)
}
}
}
Name(CRES, ResourceTemplate() {
WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode,
0x0000, // Granularity
0x0000, // Range Minimum
0x00FF, // Range Maximum
0x0000, // Translation Offset
0x0100, // Length
,,
)
IO(Decode16, 0x0CF8, 0x0CF8, 1, 8)
WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0x0000, /* address granularity */
0x0000, /* range minimum */
0x0CF7, /* range maximum */
0x0000, /* translation */
0x0CF8 /* length */
)
WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0x0000, /* address granularity */
0x0D00, /* range minimum */
0xFFFF, /* range maximum */
0x0000, /* translation */
0xF300 /* length */
)
Memory32Fixed(READWRITE, 0, 0xA0000, BSMM)
Memory32Fixed(READONLY, 0x000A0000, 0x00020000, VGAM) /* VGA memory space */
Memory32Fixed(READONLY, 0x000C0000, 0x00020000, EMM1) /* Assume C0000-E0000 empty */
Memory32Fixed(READONLY, 0x000E0000, 0x00020000, RDBS) /* BIOS ROM area */
/* DRAM Memory from 1MB to TopMem */
Memory32Fixed(READWRITE, 0x00100000, 0x00000000, DMLO) /* 1MB to TopMem */
Memory32Fixed(ReadOnly, 0xE0000000, 0x10000000, MCFG) /* MMCONFIG area */
Memory32Fixed(READONLY, 0xF0000000, 0x10000000, MMIO) /* PCI mapping space */
+#if 0
/* BIOS space just below 4GB */
DWORDMemory(
ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
0x00, /* Granularity */
0x00000000, /* Min */
0x00000000, /* Max */
0x00000000, /* Translation */
0x00000001, /* Max-Min, RLEN */
,,
PCBM
)
/* BIOS space just below 16EB */
QWORDMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
0x00000000, /* Granularity */
0x00000000, /* Min */
0x00000000, /* Max */
0x00000000, /* Translation */
0x00000001, /* Max-Min, RLEN */
,,
PEBM
)
+#endif
/* DRAM memory from 4GB to TopMem2 */
QWORDMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
0x00000000, /* Granularity */
0x00000000, /* Min */
0x00000000, /* Max */
0x00000000, /* Translation */
0x00000001, /* Max-Min, RLEN */
,,
DMHI
)
}) /* End Name(_SB.PCI0.CRES) */
External(TOM1) /* 32bit top of memory from SSDT */
External(TOM2) /* 64bit top of memory from SSDT */
Maybe windows will accept only IO resorce without any memory resource. It is PITA. Please try to investigate what we should relly tell here:
Name(CRES, ResourceTemplate() { IO(Decode16, 0x0CF8, 0x0CF8, 1, 8)
WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, 0x0000, /* address granularity */ 0x0000, /* range minimum */ 0x0CF7, /* range maximum */ 0x0000, /* translation */ 0x0CF8 /* length */ )
WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, 0x0000, /* address granularity */ 0x0D00, /* range minimum */ 0xFFFF, /* range maximum */ 0x0000, /* translation */ 0xF300 /* length */ ) }) /* End Name(_SB.PCI0.CRES) */
Method(_CRS, 0) { /* DBGO("\_SB\PCI0\_CRS\n") */ Return(CRES) /* note to change the Name buffer */ } /* end of Method(_SB.PCI0._CRS) */ } /* End Device(PCI0) */
If this works for XP it would be nice...
- Scope (_SB)
- {
OperationRegion (PCI0.SBRG.PIX0, PCI_Config, 0x55, 0x04)
OperationRegion (PCI0.SBRG.PIX1, PCI_Config, 0x50, 0x02)
OperationRegion (PCI0.SBRG.PIX2, PCI_Config, 0x44, 0x02)
OperationRegion (PCI0.SBRG.PIX3, PCI_Config, 0x67, 0x03)
OperationRegion (PCI0.SBRG.PIX4, PCI_Config, 0x6C, 0x04)
OperationRegion (PCI0.SBRG.PIEF, PCI_Config, 0x46, 0x01)
This code comes from where? You wrote it?
Field (PCI0.SBRG.PIX0, ByteAcc, NoLock, Preserve)
{
, 4,
PIRA, 4,
PIRB, 4,
PIRC, 4,
, 4,
PIRD, 4,
, 4
}
Field (PCI0.SBRG.PIX1, ByteAcc, NoLock, Preserve)
{
, 1,
EP3C, 1,
EN3C, 1,
, 6,
KBFG, 1
}
Field (PCI0.SBRG.PIX2, ByteAcc, NoLock, Preserve)
{
PIRE, 4,
PIRF, 4,
PIRG, 4,
PIRH, 4,
}
Field (PCI0.SBRG.PIX3, ByteAcc, NoLock, Preserve)
{
ENIR, 1,
IRSD, 1,
Offset (0x02),
IRBA, 8
}
Field (PCI0.SBRG.PIX4, ByteAcc, NoLock, Preserve)
{
PS0E, 1,
PS1E, 1,
ROME, 1,
APCE, 1,
LPMS, 2,
MSEN, 1,
IXEN, 1,
LPMD, 2,
MDEN, 1,
GMEN, 1,
LPLP, 2,
LPEN, 1,
FDEN, 1,
LPCA, 3,
CAEN, 1,
LPCB, 3,
CBEN, 1,
LPSB, 2,
SBEN, 1,
FDSE, 1,
Offset (0x04)
This looks suspicius. We cannot copy anything from orig bios. I think you dont need legacy IRQ anyway windows should work with APIC only. Please try to keep the ACPI stuff as simple as possible.
+/* The content of IT8712F_CONFIG_REG_LDN (index 0x07) must be set to the
- LDN the register belongs to, before you can access the register. */
+static void it8712f_sio_write(uint8_t ldn, uint8_t index, uint8_t value) +{
- outb(IT8712F_CONFIG_REG_LDN, SIO_BASE);
- outb(ldn, SIO_DATA);
- outb(index, SIO_BASE);
- outb(value, SIO_DATA);
+}
I think we have some generic function like pnp_enter_ext_func_mode etc please check it.
- /*
* it8712f gpio config
*
* Most importantly this switches pin 91 from
* PCIRSTIN# to VIN7.
* Note that only PCIRST3# and PCIRST5# are affected
* by PCIRSTIN#, the PCIRST1#, PCIRST2#, PCIRST4# are always
* direct buffers of #LRESET (low pin count bus reset).
* If this is not done All PCIRST are in reset state and the
* pcie slots don't initialize.
*
* pci reset handling:
* pin 91: VIN7 (alternate PCIRSTIN#)
* pin 48: PCIRST5# / gpio port 5 bit 0
* pin 84: PCIRST4# / gpio port 1 bit 0
* pin 31: PCIRST1# / gpio port 1 bit 4
* pin 33: PCIRST2# / gpio port 1 bit 2
* pin 34: PCIRST3# / gpio port 1 bit 1
*
* PCIRST[0-5]# are connected as follows:
* pcirst1# -> pci bus
* pcirst2# -> ide bus
* pcirst3# -> pcie devices
* pcirst4# -> pcie graphics
* pcirst5# -> maybe n/c (untested)
nice how did you found out?
Btw we usually have sio setup in romstage.c But maybe it makes more sense here if it is not critical.
Maybe resets and voltage setup should be really in romstage.c (so it is called before memory etc is setup).
+static void m2v_bus_init(void) +{
- u8 tmp;
- pci_cf8_conf1.write8(NULL, 0, PCI_DEVFN(0, 0), K8T890_MULTIPLE_FN_EN, 0x01);
- /*
* Northbridge pcie bridge 3.3 is not connected to anything, hide it.
*/
- tmp = pci_cf8_conf1.read8(NULL, 0, PCI_DEVFN(0x0, 5), 0xf0);
- tmp&= ~0x10; /* hide pcie bridge 0:3.3 */
- tmp&= ~0x40; /* hide scratch register function 0:0.6 */
- pci_cf8_conf1.write8(NULL, 0, PCI_DEVFN(0x0, 5), 0xf0, tmp);
- /* Enable southbridge bridges 13.0 and 13.1 */
- pci_cf8_conf1.write8(NULL, 0, PCI_DEVFN(0x11, 7), 0X4F, 0x43);
Hmm this most likely shoudl be done with the help of devicetree.cb
- /*
* Mark APIC memory as reserved to get closer to ASUS E820 map
*/
- lb_add_memory_range(mem, LB_MEM_RESERVED, IO_APIC_ADDR, 0x1000);
- lb_add_memory_range(mem, LB_MEM_RESERVED, K8T890_APIC_BASE, 0x1000);
Dont think this is neccessary.
- /*
* Mark BIOS ROM space as reserved
*/
- lb_add_memory_range(mem, LB_MEM_RESERVED, 0xffc00000, 0x400000);
Dont think this is neccessary.
- return 0;
+}
+struct chip_operations mainboard_ops = {
- CHIP_NAME("ASUS M2V")
- .enable_dev = m2v_enable,
+}; Index: src/mainboard/asus/m2v/mptable.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/mainboard/asus/m2v/mptable.c 2010-10-29 14:07:37.000000000 +0200
THis was recently fixed are you using fixed version?
+#define SB_VFSMAF 0
I think for you would work normal way (without this ldstop_sb. I had troubles with integrated VGA on K8M890.
Otherwise well done! Please try to address the remaining issues.
Thanks, Rudolf
Rudolf Marek wrote:
On 29.10.2010 14:14, Tobias Diedrich wrote:
This adds the m2v directory to src/mainboards/asus and adjusts the Kconfig. Note:
I added pci irq routing setup based on pirq tables: pci_fixup_irqs() in irq_tables.c
I didn't see any existing functionality that will just take the pirq information and use that to setup pci interrupts. For example, in src/southbridge/via/vt8237r/vt8237r_lpc.c there is some epia specific setup, which may really belong into the corresponding mainboard directory...
Hmm the legacy PIC routing may not work. In linux it could. I never tested that.
I currently working on cleaning up the mainboard part, but I tested legacy pic routing (which is why I added this function), acpi w/o apic, acpi with apic and mptables with apic, each in both XP and Linux.
- /* Write SB IOAPIC. */
- current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
VT8237R_APIC_ID, IO_APIC_ADDR, 0);
- /* Write NB IOAPIC. */
- current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
K8T890_APIC_ID, K8T890_APIC_BASE, gsi_base);
I never used the VIA system on multicore CPU, dunno what to do if we have in fact more cpus... The IDs should be shifted then.
The IDs are currently hardcoded:
src/southbridge/via/k8t890/k8t890.h: #define K8T890_APIC_ID 0x3 #define K8T890_APIC_BASE 0xfecc0000
src/southbridge/via/vt8237r/vt8237r.h #define VT8237R_APIC_ID 0x2
Which is good for up to dual-core, should be shifted up for quad-core... Maybe we should change this to 0x10 and 0x11? (up to 16 cores) Not sure how many bits are available for the ID by default, but I saw that there is an enable bit for extended ID numbers somewhere.
+++ src/mainboard/asus/m2v/dsdt.asl 2010-10-29 14:07:37.000000000 +0200 @@ -0,0 +1,967 @@ +/*
- This file is part of the coreboot project.
- Copyright (C) 2004 Nick BarkerNick.Barker9@btinternet.com
- Copyright (C) 2007 Rudolf Marekr.marek@assembler.cz
- Copyright (C) 2010 Tobias Diedrichranma+coreboot@tdiedrich.de
Where you have taken parts of it? Some parts feel like AMD 7xx code? Maybe we miss copyright here?
Portions (e.g. "Remember the OS' IRQ routing choice" are from src/mainboard/ibase/mb899/acpi/), I'll add "Copyright (C) 2007-2009 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
- */
+/*
- ISA portions taken from QEMU acpi-dsdt.dsl.
- */
+DefinitionBlock ("DSDT.aml", "DSDT", 2, "CORE ", "COREBOOT", 1) +{
- /* Data to be patched by the BIOS during POST */
- /* FIXME the patching is not done yet! */
- /* Memory related values */
- Name(LOMH, 0x0) /* Start of unused memory in C0000-E0000 range */
- Name(PBAD, 0x0) /* Address of BIOS area (If TOM2 != 0, Addr>> 16) */
- Name(PBLN, 0x0) /* Length of BIOS area */
We dont do patching we do apcigen stuff instead into SSDT.
That's copied from gigabyte/ma78gm/dsdt.asl, I'll remove it, it isn't used anyway. As I already said elsewhere, I haven't cleaned up the mainboard bits yet, especially the acpi stuff.
- Name(PCBA, 0xE0000000) /* Base address of PCIe config space */
This cannot be hardcoded.
Ok, then I'll add it to the SSDT generation code and use an external.
- Name(HPBA, 0xFED00000) /* Base address of HPET table */
- /* global variables */
- Name(APIC, 0) // 0=>8259, 1=>IOAPIC
- Name(LINX, 0)
- Name(OSYS, 0x0000)
- /* very generic stuff */
- /* Port 80 POST */
- OperationRegion (POST, SystemIO, 0x80, 1)
- Field (POST, ByteAcc, Lock, Preserve)
- {
DBG0, 8
- }
- Method (DEBG, 1, NotSerialized)
- {
Store (Arg0, DBG0)
- }
I dont think you need this. My philosophy for ACPI code is: Put there only what is needed even no extra bit more.
I thought the POST port might come in handy for debugging, but haven't used it so far.
- /* _PR CPU0 is dynamically supplied by SSDT */
- /* For now only define 2 power states:
* - S0 which is fully on
* - S5 which is soft off
* Any others would involve declaring the wake up methods.
*
* Package contents:
* ofs len desc
* 0 1 Value for PM1a_CNT.SLP_TYP register to enter this system state.
* 1 1 Value for PM1b_CNT.SLP_TYP register to enter this system state. To enter any
* given state, OSPM must write the PM1a_CNT.SLP_TYP register before the
* PM1b_CNT.SLP_TYP register.
* 2 2 Reserved
*/
- Name (_S0, Package () { 0x00, 0x00, 0x00, 0x00 })
- Name (_S5, Package () { 0x02, 0x02, 0x00, 0x00 })
- /*
* Prepare to sleep
*
* Arg0 – An Integer containing the value of the sleeping state (1 for S1, 2 for S2, etc.)
* Return Value: None
*/
- Method (_PTS, 1, NotSerialized)
- {
// FIXME: Not implemented
- }
- /*
* Transition to state
*
* Arg0 – An Integer containing the value of the sleeping state (1 for S1, 2 for S2, etc.)
* Return Value: None
*/
- Method (_TTS, 1, NotSerialized)
- {
// FIXME: Not implemented
- }
get rif of those please
I thought they were required methods, and put them in when I was trying to get XP to boot with ACPI on. I'll remove them if they are unneeded.
I probably will have to add them back when I look at suspend to ram support though...
Device (PCIE)
{
Name (_HID, EisaId ("PNP0C02"))
Method (_CRS, 0, NotSerialized)
{
Name (TMP, ResourceTemplate () {
Memory32Fixed(ReadOnly,
0xE0000000,
Sorry this cannot be hardcoded. I dont think you need this at all.
Win Vista/7 might need it for MMCONF. I'll remove the hardcoding. Linux is contempt with 0xe0000000-0xefffffff resered in either e820 or acpi, but one must be there for MMCONF / pcie extended config space.
Name(CRES, ResourceTemplate() {
WordBusNumber(ResourceProducer, MinFixed, MaxFixed, PosDecode,
0x0000, // Granularity
0x0000, // Range Minimum
0x00FF, // Range Maximum
0x0000, // Translation Offset
0x0100, // Length
,,
)
IO(Decode16, 0x0CF8, 0x0CF8, 1, 8)
WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0x0000, /* address granularity */
0x0000, /* range minimum */
0x0CF7, /* range maximum */
0x0000, /* translation */
0x0CF8 /* length */
)
WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
0x0000, /* address granularity */
0x0D00, /* range minimum */
0xFFFF, /* range maximum */
0x0000, /* translation */
0xF300 /* length */
)
Memory32Fixed(READWRITE, 0, 0xA0000, BSMM)
Memory32Fixed(READONLY, 0x000A0000, 0x00020000, VGAM) /* VGA memory space */
Memory32Fixed(READONLY, 0x000C0000, 0x00020000, EMM1) /* Assume C0000-E0000 empty */
Memory32Fixed(READONLY, 0x000E0000, 0x00020000, RDBS) /* BIOS ROM area */
/* DRAM Memory from 1MB to TopMem */
Memory32Fixed(READWRITE, 0x00100000, 0x00000000, DMLO) /* 1MB to TopMem */
Memory32Fixed(ReadOnly, 0xE0000000, 0x10000000, MCFG) /* MMCONFIG area */
Memory32Fixed(READONLY, 0xF0000000, 0x10000000, MMIO) /* PCI mapping space */
+#if 0
/* BIOS space just below 4GB */
DWORDMemory(
ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
0x00, /* Granularity */
0x00000000, /* Min */
0x00000000, /* Max */
0x00000000, /* Translation */
0x00000001, /* Max-Min, RLEN */
,,
PCBM
)
/* BIOS space just below 16EB */
QWORDMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
0x00000000, /* Granularity */
0x00000000, /* Min */
0x00000000, /* Max */
0x00000000, /* Translation */
0x00000001, /* Max-Min, RLEN */
,,
PEBM
)
+#endif
/* DRAM memory from 4GB to TopMem2 */
QWORDMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, ReadWrite,
0x00000000, /* Granularity */
0x00000000, /* Min */
0x00000000, /* Max */
0x00000000, /* Translation */
0x00000001, /* Max-Min, RLEN */
,,
DMHI
)
}) /* End Name(_SB.PCI0.CRES) */
External(TOM1) /* 32bit top of memory from SSDT */
External(TOM2) /* 64bit top of memory from SSDT */
Maybe windows will accept only IO resorce without any memory resource. It is PITA. Please try to investigate what we should relly tell here:
Declaring main memory there turned out to be a problem actually. AFAICS the asus dsdt doesn't declare main memory in ACPI, E820 or the efi equivalent is used for main memory map according to the ACPI standard if I read it right.
What needs to be there: Unused IO port and memory ranges which can be assigned to PCI/PCIE devices.
If we don't want to declare all legacy ports, using IO 0x400-0xcf8 and 0xd00-0xffff, as well as memory TOM-0xdfffffff and 0xf0000000-first apic? should be ok.
Name(CRES, ResourceTemplate() { IO(Decode16, 0x0CF8, 0x0CF8, 1, 8)
WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode,
EntireRange, 0x0000, /* address granularity */ 0x0000, /* range minimum */ 0x0CF7, /* range maximum */ 0x0000, /* translation */ 0x0CF8 /* length */ )
WORDIO(ResourceProducer, MinFixed, MaxFixed, PosDecode,
EntireRange, 0x0000, /* address granularity */ 0x0D00, /* range minimum */ 0xFFFF, /* range maximum */ 0x0000, /* translation */ 0xF300 /* length */ ) }) /* End Name(_SB.PCI0.CRES) */
Method(_CRS, 0) { /* DBGO("\\_SB\\PCI0\\_CRS\n") */ Return(CRES) /* note to change the Name buffer */ } /* end of Method(_SB.PCI0._CRS) */ } /* End Device(PCI0) */
If this works for XP it would be nice...
Memory resources are needed too for PCI BARs.
- Scope (_SB)
- {
OperationRegion (PCI0.SBRG.PIX0, PCI_Config, 0x55, 0x04)
OperationRegion (PCI0.SBRG.PIX1, PCI_Config, 0x50, 0x02)
OperationRegion (PCI0.SBRG.PIX2, PCI_Config, 0x44, 0x02)
OperationRegion (PCI0.SBRG.PIX3, PCI_Config, 0x67, 0x03)
OperationRegion (PCI0.SBRG.PIX4, PCI_Config, 0x6C, 0x04)
OperationRegion (PCI0.SBRG.PIEF, PCI_Config, 0x46, 0x01)
Field (PCI0.SBRG.PIX0, ByteAcc, NoLock, Preserve)
{
, 4,
PIRA, 4,
PIRB, 4,
PIRC, 4,
, 4,
PIRD, 4,
, 4
}
Field (PCI0.SBRG.PIX1, ByteAcc, NoLock, Preserve)
{
, 1,
EP3C, 1,
EN3C, 1,
, 6,
KBFG, 1
}
Field (PCI0.SBRG.PIX2, ByteAcc, NoLock, Preserve)
{
PIRE, 4,
PIRF, 4,
PIRG, 4,
PIRH, 4,
}
Field (PCI0.SBRG.PIX3, ByteAcc, NoLock, Preserve)
{
ENIR, 1,
IRSD, 1,
Offset (0x02),
IRBA, 8
}
Field (PCI0.SBRG.PIX4, ByteAcc, NoLock, Preserve)
{
PS0E, 1,
PS1E, 1,
ROME, 1,
APCE, 1,
LPMS, 2,
MSEN, 1,
IXEN, 1,
LPMD, 2,
MDEN, 1,
GMEN, 1,
LPLP, 2,
LPEN, 1,
FDEN, 1,
LPCA, 3,
CAEN, 1,
LPCB, 3,
CBEN, 1,
LPSB, 2,
SBEN, 1,
FDSE, 1,
Offset (0x04)
This code comes from where? You wrote it? This looks suspicius. We cannot copy anything from orig bios. I think you dont need legacy IRQ anyway windows should work with APIC only. Please try to keep the ACPI stuff as simple as possible.
That was copied from asus dsdt, good catch. I'll rewrite it from scratch. (Even though it an barely be called code, it's mostly IO space defines).
I'd like to have legacy IRQ as well as APIC working. I think working legacy support is required for ACPI compliance.
+/* The content of IT8712F_CONFIG_REG_LDN (index 0x07) must be set to the
- LDN the register belongs to, before you can access the register. */
+static void it8712f_sio_write(uint8_t ldn, uint8_t index, uint8_t value) +{
- outb(IT8712F_CONFIG_REG_LDN, SIO_BASE);
- outb(ldn, SIO_DATA);
- outb(index, SIO_BASE);
- outb(value, SIO_DATA);
+}
I think we have some generic function like pnp_enter_ext_func_mode etc please check it.
Ok, I'll have a look.
- /*
* it8712f gpio config
*
* Most importantly this switches pin 91 from
* PCIRSTIN# to VIN7.
* Note that only PCIRST3# and PCIRST5# are affected
* by PCIRSTIN#, the PCIRST1#, PCIRST2#, PCIRST4# are always
* direct buffers of #LRESET (low pin count bus reset).
* If this is not done All PCIRST are in reset state and the
* pcie slots don't initialize.
*
* pci reset handling:
* pin 91: VIN7 (alternate PCIRSTIN#)
* pin 48: PCIRST5# / gpio port 5 bit 0
* pin 84: PCIRST4# / gpio port 1 bit 0
* pin 31: PCIRST1# / gpio port 1 bit 4
* pin 33: PCIRST2# / gpio port 1 bit 2
* pin 34: PCIRST3# / gpio port 1 bit 1
*
* PCIRST[0-5]# are connected as follows:
* pcirst1# -> pci bus
* pcirst2# -> ide bus
* pcirst3# -> pcie devices
* pcirst4# -> pcie graphics
* pcirst5# -> maybe n/c (untested)
nice how did you found out?
I configured it for software control, wiggled the bits and saw what happened. :)
Btw we usually have sio setup in romstage.c But maybe it makes more sense here if it is not critical.
Maybe resets and voltage setup should be really in romstage.c (so it is called before memory etc is setup).
The pcie resets are not critical, so I'm thinking romstage should only contain what's strictly necessary at that point. I tried finding the memory slot voltage setting, but I didn't find any noticable gpio differences. :/ TODO: Measure the memory slot voltage.
+static void m2v_bus_init(void) +{
- u8 tmp;
- pci_cf8_conf1.write8(NULL, 0, PCI_DEVFN(0, 0), K8T890_MULTIPLE_FN_EN, 0x01);
- /*
* Northbridge pcie bridge 3.3 is not connected to anything, hide it.
*/
- tmp = pci_cf8_conf1.read8(NULL, 0, PCI_DEVFN(0x0, 5), 0xf0);
- tmp&= ~0x10; /* hide pcie bridge 0:3.3 */
- tmp&= ~0x40; /* hide scratch register function 0:0.6 */
- pci_cf8_conf1.write8(NULL, 0, PCI_DEVFN(0x0, 5), 0xf0, tmp);
- /* Enable southbridge bridges 13.0 and 13.1 */
- pci_cf8_conf1.write8(NULL, 0, PCI_DEVFN(0x11, 7), 0X4F, 0x43);
Hmm this most likely shoudl be done with the help of devicetree.cb
I don't see how this can be done with devicetree.cb.
- /*
* Mark APIC memory as reserved to get closer to ASUS E820 map
*/
- lb_add_memory_range(mem, LB_MEM_RESERVED, IO_APIC_ADDR, 0x1000);
- lb_add_memory_range(mem, LB_MEM_RESERVED, K8T890_APIC_BASE, 0x1000);
- /*
* Mark BIOS ROM space as reserved
*/
- lb_add_memory_range(mem, LB_MEM_RESERVED, 0xffc00000, 0x400000);
Dont think this is neccessary.
I think all ranges that have mapped devices and are unavailable for PCI bars should be marked as reserved in E820 for correctness. Should probably be done in the chipset code and not in the mainboard code though.
- return 0;
+}
+struct chip_operations mainboard_ops = {
- CHIP_NAME("ASUS M2V")
- .enable_dev = m2v_enable,
+}; Index: src/mainboard/asus/m2v/mptable.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/mainboard/asus/m2v/mptable.c 2010-10-29 14:07:37.000000000 +0200
THis was recently fixed are you using fixed version?
Well, I was the one who fixed it. ;)
+#define SB_VFSMAF 0
I think for you would work normal way (without this ldstop_sb. I had troubles with integrated VGA on K8M890.
It's there because I started with a copy of m2v-mx_se/romstage.c. I'll remove it.
Tobias Diedrich wrote:
- /*
* Northbridge pcie bridge 3.3 is not connected to anything, hide it.
*/
- tmp = pci_cf8_conf1.read8(NULL, 0, PCI_DEVFN(0x0, 5), 0xf0);
- tmp&= ~0x10; /* hide pcie bridge 0:3.3 */
- tmp&= ~0x40; /* hide scratch register function 0:0.6 */
- pci_cf8_conf1.write8(NULL, 0, PCI_DEVFN(0x0, 5), 0xf0, tmp);
- /* Enable southbridge bridges 13.0 and 13.1 */
- pci_cf8_conf1.write8(NULL, 0, PCI_DEVFN(0x11, 7), 0X4F, 0x43);
Hmm this most likely shoudl be done with the help of devicetree.cb
I don't see how this can be done with devicetree.cb.
device pci 3.3 off end
I think all ranges that have mapped devices and are unavailable for PCI bars should be marked as reserved in E820 for correctness. Should probably be done in the chipset code and not in the mainboard code though.
I agree - and that would be wonderful!
//Peter
Peter Stuge wrote:
Tobias Diedrich wrote:
- /*
* Northbridge pcie bridge 3.3 is not connected to anything, hide it.
*/
- tmp = pci_cf8_conf1.read8(NULL, 0, PCI_DEVFN(0x0, 5), 0xf0);
- tmp&= ~0x10; /* hide pcie bridge 0:3.3 */
- tmp&= ~0x40; /* hide scratch register function 0:0.6 */
- pci_cf8_conf1.write8(NULL, 0, PCI_DEVFN(0x0, 5), 0xf0, tmp);
- /* Enable southbridge bridges 13.0 and 13.1 */
- pci_cf8_conf1.write8(NULL, 0, PCI_DEVFN(0x11, 7), 0X4F, 0x43);
Hmm this most likely shoudl be done with the help of devicetree.cb
I don't see how this can be done with devicetree.cb.
device pci 3.3 off end
That does something different though I think. I.e. the bridge is still visible as a device, even if we leave it unconfigured. The code above completely removes the device so it is no longer visible at all. Since we don't use the scratch register function 0:0.6 and the 4th pcie bridge 0:3.3 is not physically wired to anything I thought it would be neat to just disable those two completely.
I think all ranges that have mapped devices and are unavailable for PCI bars should be marked as reserved in E820 for correctness. Should probably be done in the chipset code and not in the mainboard code though.
I agree - and that would be wonderful!
I'll look into it.
-----Original Message----- From: coreboot-bounces@coreboot.org [mailto:coreboot-bounces@coreboot.org] On Behalf Of Tobias Diedrich Sent: Friday, October 29, 2010 06:56 AM To: coreboot@coreboot.org Subject: [coreboot] [PATCH 0/7] ASUS M2V support (v2)
]An update to this patch series: ]I found the gpio that was keeping the pcie slots in reset. ]Azalia HDAC is also working now. ] ]Remaining problems: ]- While my ati pcie graphics card works in the peg slot, a network ] card (x1 link) doesn't, but with the asus bios both work. ]- ACPI still giving stop 0xa5 (next debugging target)
The stop A5 can be easy to debug if you go through the pain of setting up a checked build with windbg. For me the first thing it reported was e820 ranges overlapping with other (ACPI) ranges. I found Windows wants no range reserved in e820 unless it is truly off limits to the OS ands its drivers. The exception is mmconf, which is often reserved in e820. An annoyance with checked build (at least win7) is the e820 range error message prints garbage. The reason is that the DbgPrint format string and arg list do not match. One is 32-bit and the other 64-bit. It will work if patched in memory before executing. Another problem is that Windows wants ACPI to report the address space available to the PCI bus. Here is how mine looks. It is hard-coded for 2MB TOM at the moment:
// starts at TOM and ends at first E820 reserved range (mmconf) DWORDMemory(ResourceProducer,PosDecode,MinFixed,MaxFixed,Cacheable,ReadWrite,0,0x80000000,0xf7ffffff, 0,0x78000000)
Need one for I/O too: WORDIO(ResourceProducer,MinFixed,MaxFixed,PosDecode,EntireRange, 0,0x0D00,0xffff, 0,0xf300)
I would like to come up with a clean way for ACPI to find TOM, then submit a patch. The current way coreboot shares info with ACPI is kind of scary.
Thanks, Scott
]-- ]Tobias PGP: http://8ef7ddba.uguu.de
Scott Duplichan wrote:
The stop A5 can be easy to debug if you go through the pain of setting up a checked build with windbg. For me the first thing it reported was e820 ranges overlapping with other (ACPI) ranges. I found Windows wants no range reserved in e820 unless it is truly off limits to the OS ands its drivers. The exception is mmconf, which is often reserved in e820. An annoyance with checked build (at least win7) is the e820 range error message prints garbage. The reason is that the DbgPrint format string and arg list do not match. One is 32-bit and the other 64-bit. It will work if patched in memory before executing. Another problem is that Windows wants ACPI to report the address space available to the PCI bus. Here is how mine looks. It is hard-coded for 2MB TOM at the moment:
Finally have a win install on my notebook set up. I didn't have any disk space left on the hard disk and had to patch the xp install cd so I could install it on an external USB hard drive... Hmm, according to windbg the error is 'failed to load DDB', and the third arg points to the generated SSDT for my Processor. I'll have a look...
Tobias Diedrich wrote:
Scott Duplichan wrote:
The stop A5 can be easy to debug if you go through the pain of setting up a checked build with windbg. For me the first thing it reported was e820 ranges overlapping with other (ACPI) ranges. I found Windows wants no range reserved in e820 unless it is truly off limits to the OS ands its drivers. The exception is mmconf, which is often reserved in e820. An annoyance with checked build (at least win7) is the e820 range error message prints garbage. The reason is that the DbgPrint format string and arg list do not match. One is 32-bit and the other 64-bit. It will work if patched in memory before executing. Another problem is that Windows wants ACPI to report the address space available to the PCI bus. Here is how mine looks. It is hard-coded for 2MB TOM at the moment:
Finally have a win install on my notebook set up. I didn't have any disk space left on the hard disk and had to patch the xp install cd so I could install it on an external USB hard drive... Hmm, according to windbg the error is 'failed to load DDB', and the third arg points to the generated SSDT for my Processor. I'll have a look...
Disabling the SSDT for now there was indeed an E820 conflict with the DSDT PCI0 _CRS resources. Looks like the dsdt I copied it from was a bad example. :) I got my first successful ACPI boot of XP now.
]Tobias Diedrich wrote: ]> Scott Duplichan wrote: ]> > The stop A5 can be easy to debug if you go through the pain of ]> > setting up a checked build with windbg. For me the first thing ]> > it reported was e820 ranges overlapping with other (ACPI) ranges. ]> > I found Windows wants no range reserved in e820 unless it is ]> > truly off limits to the OS ands its drivers. The exception is ]> > mmconf, which is often reserved in e820. An annoyance with checked ]> > build (at least win7) is the e820 range error message prints ]> > garbage. The reason is that the DbgPrint format string and arg list ]> > do not match. One is 32-bit and the other 64-bit. It will work if ]> > patched in memory before executing. Another problem is that Windows ]> > wants ACPI to report the address space available to the PCI bus. ]> > Here is how mine looks. It is hard-coded for 2MB TOM at the moment: ]> ]> Finally have a win install on my notebook set up. I didn't have any ]> disk space left on the hard disk and had to patch the xp install cd ]> so I could install it on an external USB hard drive... ]> Hmm, according to windbg the error is 'failed to load DDB', and the ]> third arg points to the generated SSDT for my Processor. I'll have a ]> look... ] ]Disabling the SSDT for now there was indeed an E820 conflict with the ]DSDT PCI0 _CRS resources. Looks like the dsdt I copied it from was a ]bad example. :) ]I got my first successful ACPI boot of XP now.
That is great news, congratulations. Thanks, Scott
]-- ]Tobias PGP: http://8ef7ddba.uguu.de