mail.coreboot.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
List overview
Download
coreboot-gerrit
February 2014
----- 2024 -----
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
coreboot-gerrit@coreboot.org
1 participants
1135 discussions
Start a n
N
ew thread
Patch set updated for coreboot: fb19827 intel/nehalem: Use non-powercycle reset.
by Vladimir Serbinenko
22 Feb '14
22 Feb '14
Vladimir Serbinenko (phcoder(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at
http://review.coreboot.org/5266
-gerrit commit fb198278daa46fd54ba259c5808408851b942267 Author: Vladimir Serbinenko <phcoder(a)gmail.com> Date: Wed Feb 19 22:08:51 2014 +0100 intel/nehalem: Use non-powercycle reset. Change-Id: Ibc2421a50e272a580461e4eacec6cfcd38654fe8 Signed-off-by: Vladimir Serbinenko <phcoder(a)gmail.com> --- src/northbridge/intel/nehalem/raminit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/northbridge/intel/nehalem/raminit.c b/src/northbridge/intel/nehalem/raminit.c index c967e39..46a15a9 100644 --- a/src/northbridge/intel/nehalem/raminit.c +++ b/src/northbridge/intel/nehalem/raminit.c @@ -3804,7 +3804,7 @@ void chipset_init(const int s3resume) if ((x2ca8 & 1) || (x2ca8 == 8 && !s3resume)) { printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n"); write_mchbar8(0x2ca8, 0); - outb(0xe, 0xcf9); + outb(0x6, 0xcf9); #if REAL while (1) { asm volatile ("hlt");
1
0
0
0
Patch set updated for coreboot: e514887 intel/nehalem: Fix soft reset detection.
by Vladimir Serbinenko
22 Feb '14
22 Feb '14
Vladimir Serbinenko (phcoder(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at
http://review.coreboot.org/5267
-gerrit commit e51488708cddcd528280e7c3454a58aa9b1ed2f1 Author: Vladimir Serbinenko <phcoder(a)gmail.com> Date: Wed Feb 19 22:09:33 2014 +0100 intel/nehalem: Fix soft reset detection. Change-Id: I4575cddc35dc8309372beafec441d194bc145242 Signed-off-by: Vladimir Serbinenko <phcoder(a)gmail.com> --- src/northbridge/intel/nehalem/raminit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/northbridge/intel/nehalem/raminit.c b/src/northbridge/intel/nehalem/raminit.c index 46a15a9..978ffbf 100644 --- a/src/northbridge/intel/nehalem/raminit.c +++ b/src/northbridge/intel/nehalem/raminit.c @@ -4970,7 +4970,7 @@ void raminit(const int s3resume, const u8 *spd_addrmap) pcie_write_config8(SOUTHBRIDGE, GEN_PMCON_2, pcie_read_config8(SOUTHBRIDGE, GEN_PMCON_2) & ~0x80); udelay(10000); - write_mchbar16(0x2ca8, 0x0); + write_mchbar16(0x2ca8, 0x8); #if REAL udelay(1000);
1
0
0
0
Patch set updated for coreboot: c8ce328 nehalem/raminit: Don't touch clock generator in raminit.
by Vladimir Serbinenko
22 Feb '14
22 Feb '14
Vladimir Serbinenko (phcoder(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at
http://review.coreboot.org/5265
-gerrit commit c8ce3287869f7c613c121803c61ba88b6c1676bc Author: Vladimir Serbinenko <phcoder(a)gmail.com> Date: Wed Feb 19 22:07:12 2014 +0100 nehalem/raminit: Don't touch clock generator in raminit. Clock generator is mobo-specific. Don't touch it in raminit. Change-Id: Ie114696b7fb13b8daee8dd1393d43bc609e149b3 Signed-off-by: Vladimir Serbinenko <phcoder(a)gmail.com> --- src/mainboard/lenovo/x201/romstage.c | 16 ++++++++++++++ src/northbridge/intel/nehalem/raminit.c | 37 ++++++++++++--------------------- src/northbridge/intel/nehalem/raminit.h | 1 + 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/mainboard/lenovo/x201/romstage.c b/src/mainboard/lenovo/x201/romstage.c index 07687b8..0e70f80 100644 --- a/src/mainboard/lenovo/x201/romstage.c +++ b/src/mainboard/lenovo/x201/romstage.c @@ -203,6 +203,18 @@ static inline u16 read_acpi16(u32 addr) return inw(DEFAULT_PMBASE | addr); } +static void +set_fsb_frequency(void) +{ + u8 block[5]; + u16 fsbfreq = 62879; + smbus_block_read(0x69, 0, 5, block); + block[0] = fsbfreq; + block[1] = fsbfreq >> 8; + + smbus_block_write(0x69, 0, 5, block); +} + void main(unsigned long bist) { u32 reg32; @@ -287,6 +299,10 @@ void main(unsigned long bist) timestamp_add_now(TS_BEFORE_INITRAM); + chipset_init(s3resume); + + set_fsb_frequency(); + raminit(s3resume, spd_addrmap); timestamp_add_now(TS_AFTER_INITRAM); diff --git a/src/northbridge/intel/nehalem/raminit.c b/src/northbridge/intel/nehalem/raminit.c index c5fe8ba..c967e39 100644 --- a/src/northbridge/intel/nehalem/raminit.c +++ b/src/northbridge/intel/nehalem/raminit.c @@ -3796,28 +3796,11 @@ static void dmi_setup(void) } #endif -#if REAL -static void -set_fsb_frequency (void) -{ - u8 block[5]; - u16 fsbfreq = 62879; - smbus_block_read(0x69, 0, 5, block); - block[0] = fsbfreq; - block[1] = fsbfreq >> 8; - - smbus_block_write(0x69, 0, 5, block); -} -#endif - -void raminit(const int s3resume, const u8 *spd_addrmap) +void chipset_init(const int s3resume) { - unsigned channel, slot, lane, rank; - int i; - struct raminfo info; u8 x2ca8; - gav(x2ca8 = read_mchbar8(0x2ca8)); + x2ca8 = read_mchbar8(0x2ca8); if ((x2ca8 & 1) || (x2ca8 == 8 && !s3resume)) { printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n"); write_mchbar8(0x2ca8, 0); @@ -3879,12 +3862,18 @@ void raminit(const int s3resume, const u8 *spd_addrmap) pcie_write_config16(NORTHBRIDGE, D0F0_GGC, 0xb50); gav(read32(DEFAULT_RCBA | 0x3428)); write32(DEFAULT_RCBA | 0x3428, 0x1d); +} -#if !REAL - pre_raminit_5(s3resume); -#else - set_fsb_frequency(); -#endif +void raminit(const int s3resume, const u8 *spd_addrmap) +{ + unsigned channel, slot, lane, rank; + int i; + struct raminfo info; + u8 x2ca8; + u16 deven; + + x2ca8 = read_mchbar8(0x2ca8); + deven = pcie_read_config16(NORTHBRIDGE, D0F0_DEVEN); memset(&info, 0x5a, sizeof(info)); diff --git a/src/northbridge/intel/nehalem/raminit.h b/src/northbridge/intel/nehalem/raminit.h index 91f0dea..0485694 100644 --- a/src/northbridge/intel/nehalem/raminit.h +++ b/src/northbridge/intel/nehalem/raminit.h @@ -22,6 +22,7 @@ #include "nehalem.h" +void chipset_init(const int s3resume); /* spd_addrmap is array of 4 elements: Channel 0 Slot 0 Channel 0 Slot 1
1
0
0
0
Patch set updated for coreboot: fb3312b gma: Add EDID retrieving functions.
by Vladimir Serbinenko
22 Feb '14
22 Feb '14
Vladimir Serbinenko (phcoder(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at
http://review.coreboot.org/5278
-gerrit commit fb3312b055499fbc9e2b00cfe8dad1af96a9ca75 Author: Vladimir Serbinenko <phcoder(a)gmail.com> Date: Fri Feb 21 07:21:00 2014 +0100 gma: Add EDID retrieving functions. Change-Id: I64f2fcc5ad52d6a0188d02b28769001ada718c4f Signed-off-by: Vladimir Serbinenko <phcoder(a)gmail.com> --- src/drivers/intel/Makefile.inc | 2 +- src/drivers/intel/gma/Kconfig | 4 ++ src/drivers/intel/gma/Makefile.inc | 2 +- src/drivers/intel/gma/edid.c | 78 ++++++++++++++++++++++++++++++++++++++ src/drivers/intel/gma/edid.h | 2 + 5 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/drivers/intel/Makefile.inc b/src/drivers/intel/Makefile.inc index 82d5449..eb8617c 100644 --- a/src/drivers/intel/Makefile.inc +++ b/src/drivers/intel/Makefile.inc @@ -1 +1 @@ -subdirs-$(CONFIG_INTEL_DP) += gma +subdirs-y += gma diff --git a/src/drivers/intel/gma/Kconfig b/src/drivers/intel/gma/Kconfig index 073f708..e26c297 100644 --- a/src/drivers/intel/gma/Kconfig +++ b/src/drivers/intel/gma/Kconfig @@ -28,3 +28,7 @@ config INTEL_DDI default n help helper functions for intel DDI operations + +config INTEL_EDID + bool + default n diff --git a/src/drivers/intel/gma/Makefile.inc b/src/drivers/intel/gma/Makefile.inc index 0c3f45a..bea597e 100644 --- a/src/drivers/intel/gma/Makefile.inc +++ b/src/drivers/intel/gma/Makefile.inc @@ -19,4 +19,4 @@ ramstage-$(CONFIG_INTEL_DP) += intel_dp.c drm_dp_helper.c ramstage-$(CONFIG_INTEL_DDI) += intel_ddi.c - +ramstage-$(CONFIG_INTEL_EDID) += edid.c diff --git a/src/drivers/intel/gma/edid.c b/src/drivers/intel/gma/edid.c new file mode 100644 index 0000000..0066b6a --- /dev/null +++ b/src/drivers/intel/gma/edid.c @@ -0,0 +1,78 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Vladimir Serbinenko <phcoder(a)gmail.com> + * + * 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, or (at your option) + * any later verion 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 <arch/io.h> +#include <console/console.h> +#include <delay.h> + +#include "i915_reg.h" +#include "edid.h" + +static void +wait_rdy(u32 mmio) +{ + unsigned try = 100; + + while (try--) { + if (read32(mmio + PCH_GMBUS2) & (1 << 11)) + return; + udelay(10); + } +} + +void +intel_gmbus_read_edid(u32 mmio, u8 bus, u8 slave, u8 *edid) +{ + int i; + + wait_rdy(mmio); + /* 100 KHz, hold 0ns, */ + write32(mmio + PCH_GMBUS0, bus); + wait_rdy(mmio); + /* Ensure index bits are disabled. */ + write32(mmio + PCH_GMBUS5, 0); + write32(mmio + PCH_GMBUS1, 0x46000000 | (slave << 1)); + wait_rdy(mmio); + /* Ensure index bits are disabled. */ + write32(mmio + PCH_GMBUS5, 0); + write32(mmio + PCH_GMBUS1, 0x4a800001 | (slave << 1)); + for (i = 0; i < 128 / 4; i++) { + u32 reg32; + wait_rdy(mmio); + reg32 = read32(mmio + PCH_GMBUS3); + edid[4 * i] = reg32 & 0xff; + edid[4 * i + 1] = (reg32 >> 8) & 0xff; + edid[4 * i + 2] = (reg32 >> 16) & 0xff; + edid[4 * i + 3] = (reg32 >> 24) & 0xff; + } + wait_rdy(mmio); + write32(mmio + PCH_GMBUS1, 0x4a800000 | (slave << 1)); + wait_rdy(mmio); + write32(mmio + PCH_GMBUS0, 0x48000000); + write32(mmio + PCH_GMBUS2, 0x00008000); + + printk (BIOS_INFO, "EDID:\n"); + for (i = 0; i < 128; i++) { + printk (BIOS_INFO, "%02x ", edid[i]); + if ((i & 0xf) == 0xf) + printk (BIOS_INFO, "\n"); + } +} diff --git a/src/drivers/intel/gma/edid.h b/src/drivers/intel/gma/edid.h new file mode 100644 index 0000000..1d91f70 --- /dev/null +++ b/src/drivers/intel/gma/edid.h @@ -0,0 +1,2 @@ +void +intel_gmbus_read_edid(u32 mmio, u8 bus, u8 slave, u8 *edid);
1
0
0
0
Patch set updated for coreboot: 2d8256a NOTFORMERGE: Fix for SeaBIOS
by Vladimir Serbinenko
22 Feb '14
22 Feb '14
Vladimir Serbinenko (phcoder(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at
http://review.coreboot.org/5279
-gerrit commit 2d8256aa485f03d31c6de18a52d768fa60788b3d Author: Vladimir Serbinenko <phcoder(a)gmail.com> Date: Thu Feb 20 17:50:33 2014 +0100 NOTFORMERGE: Fix for SeaBIOS Change-Id: Ib2ea3742b831178ee6dba8be73e8d7fa96952327 Signed-off-by: Vladimir Serbinenko <phcoder(a)gmail.com> --- src/southbridge/intel/bd82x6x/usb_ehci.c | 1 + src/southbridge/intel/ibexpeak/usb_ehci.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/southbridge/intel/bd82x6x/usb_ehci.c b/src/southbridge/intel/bd82x6x/usb_ehci.c index 78f92d9..4162562 100644 --- a/src/southbridge/intel/bd82x6x/usb_ehci.c +++ b/src/southbridge/intel/bd82x6x/usb_ehci.c @@ -38,6 +38,7 @@ static void usb_ehci_init(struct device *dev) printk(BIOS_DEBUG, "EHCI: Setting up controller.. "); reg32 = pci_read_config32(dev, PCI_COMMAND); reg32 |= PCI_COMMAND_MASTER; + reg32 |= PCI_COMMAND_MEMORY; //reg32 |= PCI_COMMAND_SERR; pci_write_config32(dev, PCI_COMMAND, reg32); diff --git a/src/southbridge/intel/ibexpeak/usb_ehci.c b/src/southbridge/intel/ibexpeak/usb_ehci.c index 7dc7b03..4d1183d 100644 --- a/src/southbridge/intel/ibexpeak/usb_ehci.c +++ b/src/southbridge/intel/ibexpeak/usb_ehci.c @@ -47,6 +47,7 @@ static void usb_ehci_init(struct device *dev) reg32 = pci_read_config32(dev, PCI_COMMAND); reg32 |= PCI_COMMAND_MASTER; + reg32 |= PCI_COMMAND_MEMORY; //reg32 |= PCI_COMMAND_SERR; pci_write_config32(dev, PCI_COMMAND, reg32);
1
0
0
0
Patch set updated for coreboot: 645e131 nehalem: Replace video init.
by Vladimir Serbinenko
22 Feb '14
22 Feb '14
Vladimir Serbinenko (phcoder(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at
http://review.coreboot.org/5270
-gerrit commit 645e1316c1a18a3f036294852fcf79db30d819ef Author: Vladimir Serbinenko <phcoder(a)gmail.com> Date: Wed Feb 19 22:18:08 2014 +0100 nehalem: Replace video init. Old video init just replayed the sequence. This one actually computes the values. Change-Id: Ic1fe7a2e90dc2cc36ac0d8bcea5cfabc583f09a3 Signed-off-by: Vladimir Serbinenko <phcoder(a)gmail.com> --- src/drivers/intel/gma/i915_reg.h | 5 + src/mainboard/lenovo/x201/devicetree.cb | 4 + src/northbridge/intel/nehalem/Kconfig | 1 + src/northbridge/intel/nehalem/chip.h | 5 + src/northbridge/intel/nehalem/fake_vbios.c | 1819 ---------------------------- src/northbridge/intel/nehalem/gma.c | 411 ++++++- 6 files changed, 414 insertions(+), 1831 deletions(-) diff --git a/src/drivers/intel/gma/i915_reg.h b/src/drivers/intel/gma/i915_reg.h index 8c08d9f..61b909d 100644 --- a/src/drivers/intel/gma/i915_reg.h +++ b/src/drivers/intel/gma/i915_reg.h @@ -4049,6 +4049,11 @@ #define PCH_LVDS 0xe1180 #define LVDS_DETECTED (1 << 1) +#define LVDS_BORDER_ENABLE (1 << 15) +#define LVDS_PORT_ENABLE (1 << 31) +#define LVDS_CLOCK_A_POWERUP_ALL (3 << 8) +#define LVDS_CLOCK_B_POWERUP_ALL (3 << 4) +#define LVDS_CLOCK_BOTH_POWERUP_ALL (3 << 2) /* vlv has 2 sets of panel control regs. */ #define PIPEA_PP_STATUS 0x61200 diff --git a/src/mainboard/lenovo/x201/devicetree.cb b/src/mainboard/lenovo/x201/devicetree.cb index 6c5229b..9053f89 100644 --- a/src/mainboard/lenovo/x201/devicetree.cb +++ b/src/mainboard/lenovo/x201/devicetree.cb @@ -35,6 +35,10 @@ chip northbridge/intel/nehalem register "gpu_panel_power_backlight_off_delay" = "2500" register "gpu_cpu_backlight" = "0x58d" register "gpu_pch_backlight" = "0x061a061a" + register "gpu_use_spread_spectrum_clock" = "1" + register "gpu_lvds_dual_channel" = "0" + register "gpu_link_frequency_270_mhz" = "1" + register "gpu_lvds_num_lanes" = "4" chip ec/lenovo/pmh7 device pnp ff.1 on # dummy diff --git a/src/northbridge/intel/nehalem/Kconfig b/src/northbridge/intel/nehalem/Kconfig index 69d0eee..4cbaf22 100644 --- a/src/northbridge/intel/nehalem/Kconfig +++ b/src/northbridge/intel/nehalem/Kconfig @@ -23,6 +23,7 @@ config NORTHBRIDGE_INTEL_NEHALEM select MMCONF_SUPPORT select MMCONF_SUPPORT_DEFAULT select VGA + select INTEL_EDID if NORTHBRIDGE_INTEL_NEHALEM diff --git a/src/northbridge/intel/nehalem/chip.h b/src/northbridge/intel/nehalem/chip.h index 3164035..95f8b5f 100644 --- a/src/northbridge/intel/nehalem/chip.h +++ b/src/northbridge/intel/nehalem/chip.h @@ -38,5 +38,10 @@ struct northbridge_intel_nehalem_config { u32 gpu_cpu_backlight; /* CPU Backlight PWM value */ u32 gpu_pch_backlight; /* PCH Backlight PWM value */ + + int gpu_use_spread_spectrum_clock; + int gpu_lvds_dual_channel; + int gpu_link_frequency_270_mhz; + int gpu_lvds_num_lanes; }; diff --git a/src/northbridge/intel/nehalem/fake_vbios.c b/src/northbridge/intel/nehalem/fake_vbios.c deleted file mode 100644 index 5daf5ff..0000000 --- a/src/northbridge/intel/nehalem/fake_vbios.c +++ /dev/null @@ -1,1819 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2013 Vladimir Serbinenko. - * - * 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 - */ - -/* This is a replay-based init for nehalem video. */ - -outb(0x23, 0x03c2); // Device I/O <-- -outb(0x02, 0x03da); // Device I/O <-- -inb(0x03c2); // Device I/O --> 10 -outb(0x01, 0x03da); // Device I/O <-- -inb(0x03c2); // Device I/O --> 10 -outl(0x00070080, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x00070180, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x00071180, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x00041000, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00002900 -outl(0x8000298e, 0x1044); // Device I/O -outl(0x0007019c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0007119c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x00000000, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> ffffffff -outl(0x00000000, 0x1044); // Device I/O -outl(0x00000000, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> ffffffff -outl(0x00000000, 0x1044); // Device I/O -outl(0x00000000, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> ffffffff -outl(0x00000000, 0x1044); // Device I/O -outl(0x00000000, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> ffffffff -outl(0x00000000, 0x1044); // Device I/O -outl(0x00000000, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> ffffffff -outl(0x00000000, 0x1044); // Device I/O -outl(0x000fc008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 2c010757 -outl(0x2c010000, 0x1044); // Device I/O -outl(0x000fc020, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 2c010757 -outl(0x2c010000, 0x1044); // Device I/O -outl(0x000fc038, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 2c010757 -outl(0x2c010000, 0x1044); // Device I/O -outl(0x000fc050, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 2c010757 -outl(0x2c010000, 0x1044); // Device I/O -outl(0x000fc408, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 2c010757 -outl(0x2c010000, 0x1044); // Device I/O -outl(0x000fc420, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 2c010757 -outl(0x2c010000, 0x1044); // Device I/O -outl(0x000fc438, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 2c010757 -outl(0x2c010000, 0x1044); // Device I/O -outl(0x000fc450, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 2c010757 -outl(0x2c010000, 0x1044); // Device I/O -outw(0x0018, 0x03ce); // Device I/O -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x01000001, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f048, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x03030000, 0x1044); // Device I/O -outl(0x0004f050, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f054, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000001, 0x1044); // Device I/O -outl(0x0004f058, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x03030000, 0x1044); // Device I/O -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x03030000, 0x1044); // Device I/O -outl(0x00042004, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x02000000, 0x1044); // Device I/O -outl(0x000fd034, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 39cfffe0 -outl(0x8421ffe0, 0x1044); // Device I/O -int i; -for (i = 0; i < 0x1fff; i++) { - outl(0x00000001 | (i << 2), 0x1040); // Device I/O - outl(0xc2000001 | (i << 12), 0x1044); // Device I/O -} - -outw(0x0302, 0x03c4); // Device I/O -outw(0x0003, 0x03c4); // Device I/O -outw(0x0204, 0x03c4); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outw(0x0300, 0x03c4); // Device I/O -outb(0x67, 0x03c2); // Device I/O <-- -outb(0x11, 0x03d4); // Device I/O <-- -inw(0x03d4); // Device I/O --> 0x0011 -outw(0x0011, 0x03d4); // Device I/O -outw(0x5f00, 0x03d4); // Device I/O -outw(0x4f01, 0x03d4); // Device I/O -outw(0x5002, 0x03d4); // Device I/O -outw(0x8203, 0x03d4); // Device I/O -outw(0x5504, 0x03d4); // Device I/O -outw(0x8105, 0x03d4); // Device I/O -outw(0xbf06, 0x03d4); // Device I/O -outw(0x1f07, 0x03d4); // Device I/O -outw(0x0008, 0x03d4); // Device I/O -outw(0x4f09, 0x03d4); // Device I/O -outw(0x0d0a, 0x03d4); // Device I/O -outw(0x0e0b, 0x03d4); // Device I/O -outw(0x000c, 0x03d4); // Device I/O -outw(0x000d, 0x03d4); // Device I/O -outw(0x000e, 0x03d4); // Device I/O -outw(0x000f, 0x03d4); // Device I/O -outw(0x9c10, 0x03d4); // Device I/O -outw(0x8e11, 0x03d4); // Device I/O -outw(0x8f12, 0x03d4); // Device I/O -outw(0x2813, 0x03d4); // Device I/O -outw(0x1f14, 0x03d4); // Device I/O -outw(0x9615, 0x03d4); // Device I/O -outw(0xb916, 0x03d4); // Device I/O -outw(0xa317, 0x03d4); // Device I/O -outw(0xff18, 0x03d4); // Device I/O -inb(0x03da); // Device I/O --> 31 -inb(0x03ba); // Device I/O --> ff -inb(0x03da); // Device I/O --> 21 -inb(0x03ba); // Device I/O --> ff -inb(0x03da); // Device I/O --> 01 -inb(0x03ba); // Device I/O --> ff -outw(0x0000, 0x03ce); // Device I/O -outw(0x0001, 0x03ce); // Device I/O -outw(0x0002, 0x03ce); // Device I/O -outw(0x0003, 0x03ce); // Device I/O -outw(0x0004, 0x03ce); // Device I/O -outw(0x1005, 0x03ce); // Device I/O -outw(0x0e06, 0x03ce); // Device I/O -outw(0x0007, 0x03ce); // Device I/O -outw(0xff08, 0x03ce); // Device I/O -outl(0x000e1100, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000e1100, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x000e1100, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00010000, 0x1044); // Device I/O -outl(0x000e1100, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00010000 -outl(0x000e1100, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00010000 -outl(0x000e1100, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000e1100, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x000e1100, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f054, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000001 -outl(0x0004f054, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000001 -outl(0x00000001, 0x1044); // Device I/O -outl(0x000e4200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0000001c -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00050000 -outl(0x8004003e, 0x1044); // Device I/O -outl(0x000e4214, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x80060002, 0x1044); // Device I/O -outl(0x000e4218, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x01000000, 0x1044); // Device I/O -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 5144003e -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 5144003e -outl(0x5344003e, 0x1044); // Device I/O -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0144003e -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0144003e -outl(0x8074003e, 0x1044); // Device I/O -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 5144003e -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 5144003e -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 5144003e -outl(0x5344003e, 0x1044); // Device I/O -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0144003e -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0144003e -outl(0x8074003e, 0x1044); // Device I/O -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 5144003e -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 5144003e -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 5144003e -outl(0x5344003e, 0x1044); // Device I/O -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0144003e -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0144003e -outl(0x8074003e, 0x1044); // Device I/O -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 5144003e -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 5144003e -outl(0x000e4210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 5144003e -outl(0x5344003e, 0x1044); // Device I/O -outl(0x000e4f00, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0100038e -outl(0x0100030c, 0x1044); // Device I/O -outl(0x000e4f04, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00b8338e -outl(0x00b8230c, 0x1044); // Device I/O -outl(0x000e4f08, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0178838e -outl(0x06f8930c, 0x1044); // Device I/O -outl(0x000e4f0c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 09f8e38e -outl(0x09f8e38e, 0x1044); // Device I/O -outl(0x000e4f10, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00b8038e -outl(0x00b8030c, 0x1044); // Device I/O -outl(0x000e4f14, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0978838e -outl(0x0b78830c, 0x1044); // Device I/O -outl(0x000e4f18, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 09f8b38e -outl(0x0ff8d3cf, 0x1044); // Device I/O -outl(0x000e4f1c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0178038e -outl(0x01e8030c, 0x1044); // Device I/O -outl(0x000e4f20, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 09f8638e -outl(0x0ff863cf, 0x1044); // Device I/O -outl(0x000e4f24, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 09f8038e -outl(0x0ff803cf, 0x1044); // Device I/O -outl(0x000c4030, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00001000, 0x1044); // Device I/O -outl(0x000c4000, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000c4030, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00001000 -outl(0x00001000, 0x1044); // Device I/O -outl(0x000e1150, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0000001c -outl(0x000e1150, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0000001c -outl(0x0000089c, 0x1044); // Device I/O -outl(0x000fcc00, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01773f30 -outl(0x01986f00, 0x1044); // Device I/O -outl(0x000fcc0c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01773f30 -outl(0x01986f00, 0x1044); // Device I/O -outl(0x000fcc18, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01773f30 -outl(0x01986f00, 0x1044); // Device I/O -outl(0x000fcc24, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01773f30 -outl(0x01986f00, 0x1044); // Device I/O -outl(0x000c4000, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000e1180, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 40000002 -inb(0x03d4); // Device I/O --> 18 -inb(0x03d6); // Device I/O --> ff -inb(0x03d0); // Device I/O --> ff -inb(0x03ce); // Device I/O --> 08 -inb(0x03d2); // Device I/O --> ff -inb(0x03c4); // Device I/O --> 00 -inb(0x03c7); // Device I/O --> 00 -inb(0x03c8); // Device I/O --> 00 -outb(0x01, 0x03c4); // Device I/O <-- -inw(0x03c4); // Device I/O --> 0x2001 -outw(0x2001, 0x03c4); // Device I/O -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000800 -outl(0x000c5100, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000003, 0x1044); // Device I/O -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008800 -outl(0x000c5120, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x000c5104, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x460000a0, 0x1044); // Device I/O -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0000ca00 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0000ca00 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0000ca00 -outl(0x000c5120, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x000c5104, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 060000a0 -outl(0x4a8000a1, 0x1044); // Device I/O -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a08 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a08 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> ffffff00 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a0c -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a0c -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00ffffff -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a10 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a10 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 4011ae30 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a14 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a14 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a18 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a18 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03011300 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a1c -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a1c -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 78101a80 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a20 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a20 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 9795baea -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a24 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a24 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 278c5559 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a28 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a28 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00545021 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a2c -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a2c -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01010000 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a30 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a30 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01010101 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a34 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a34 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01010101 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a38 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a38 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01010101 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a3c -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a3c -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 1b120101 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a40 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a40 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 20508000 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a44 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a44 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 20183014 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a48 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a48 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> a3050044 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a4c -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a4c -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 1f000010 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a50 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a50 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 80001693 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a54 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a54 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 30142050 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a58 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a58 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00442018 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a5c -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a5c -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0010a305 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a60 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a60 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00001f00 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a64 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a64 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 81000f00 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a68 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a68 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0a813c0a -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a6c -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a6c -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00091632 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a70 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a70 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01f0e430 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a74 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a74 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> fe000000 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a78 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a78 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 31504c00 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a7c -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008a7c -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 58573132 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008800 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008800 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 4c542d33 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008800 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008800 -outl(0x000c510c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> ac003143 -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008000 -outl(0x000c5104, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 028000a1 -outl(0x480000a0, 0x1044); // Device I/O -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008000 -outl(0x000c5100, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000003 -outl(0x48000000, 0x1044); // Device I/O -outl(0x000c5108, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008000 -outl(0x00008000, 0x1044); // Device I/O -outb(0x01, 0x03c4); // Device I/O <-- -inw(0x03c4); // Device I/O --> 0x2001 -outw(0x0001, 0x03c4); // Device I/O -outb(0x18, 0x03d4); // Device I/O <-- -outb(0xff, 0x03d6); // Device I/O <-- -outb(0xff, 0x03d0); // Device I/O <-- -outb(0x08, 0x03ce); // Device I/O <-- -outb(0xff, 0x03d2); // Device I/O <-- -outb(0x00, 0x03c4); // Device I/O <-- -outb(0x00, 0x03c8); // Device I/O <-- -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000e1180, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 40000002 -outl(0x00000300, 0x1044); // Device I/O -outl(0x000c7208, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00fa09c4, 0x1044); // Device I/O -outl(0x000c720c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00fa09c4, 0x1044); // Device I/O -outl(0x000c7210, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00186904 -outl(0x00186903, 0x1044); // Device I/O -outl(0x00048250, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x80000000, 0x1044); // Device I/O -outl(0x00048254, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x061a061a, 0x1044); // Device I/O -outl(0x000c8254, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x061a061a, 0x1044); // Device I/O -outl(0x000c8250, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x000c8250, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x80000000, 0x1044); // Device I/O -outl(0x000c7204, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000c4000, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f054, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000001 -outl(0x0000020d, 0x1044); // Device I/O -outl(0x0004f054, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0000020d -outl(0x0004f050, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f050, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f054, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0000020d -outl(0x0000020d, 0x1044); // Device I/O -outl(0x0004f050, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0xc0000000, 0x1044); // Device I/O -outl(0x0004f054, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0000020d -outl(0x0004f054, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 0000020d -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000400, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000400 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000400 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outb(0xff, 0x03c6); // Device I/O <-- -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x03300000, 0x1044); // Device I/O -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03300000 -outl(0x30300000, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 30300000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 30300000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 30300000 -outl(0x0004f048, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 30300000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 30300000 -outl(0x30030000, 0x1044); // Device I/O -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 30030000 -outl(0x03030000, 0x1044); // Device I/O - -vga_textmode_init(); - -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000001 -outl(0x01000008, 0x1044); // Device I/O -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x03030000, 0x1044); // Device I/O -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x03030000, 0x1044); // Device I/O -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00070080, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000700c0, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outb(0x01, 0x03c4); // Device I/O <-- -inw(0x03c4); // Device I/O --> 0x0001 -outw(0x2001, 0x03c4); // Device I/O -outl(0x00041000, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 8000298e -outl(0x00041000, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 8000298e -outl(0x8000298e, 0x1044); // Device I/O -outl(0x00070180, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00071180, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00068070, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00068080, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00068074, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000400, 0x1044); // Device I/O -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000400 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000400 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00041000, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 8000298e -outl(0x8020298e, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outw(0x0010, 0x03ce); // Device I/O -outw(0x0011, 0x03ce); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outw(0x0100, 0x03c4); // Device I/O -outw(0x2001, 0x03c4); // Device I/O -outw(0x0302, 0x03c4); // Device I/O -outw(0x0003, 0x03c4); // Device I/O -outw(0x0204, 0x03c4); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outw(0x0300, 0x03c4); // Device I/O -outb(0x67, 0x03c2); // Device I/O <-- -outb(0x11, 0x03d4); // Device I/O <-- -inw(0x03d4); // Device I/O --> 0x8e11 -outw(0x0e11, 0x03d4); // Device I/O -outw(0x5f00, 0x03d4); // Device I/O -outw(0x4f01, 0x03d4); // Device I/O -outw(0x5002, 0x03d4); // Device I/O -outw(0x8203, 0x03d4); // Device I/O -outw(0x5504, 0x03d4); // Device I/O -outw(0x8105, 0x03d4); // Device I/O -outw(0xbf06, 0x03d4); // Device I/O -outw(0x1f07, 0x03d4); // Device I/O -outw(0x0008, 0x03d4); // Device I/O -outw(0x4f09, 0x03d4); // Device I/O -outw(0x0d0a, 0x03d4); // Device I/O -outw(0x0e0b, 0x03d4); // Device I/O -outw(0x000c, 0x03d4); // Device I/O -outw(0x000d, 0x03d4); // Device I/O -outw(0x000e, 0x03d4); // Device I/O -outw(0x000f, 0x03d4); // Device I/O -outw(0x9c10, 0x03d4); // Device I/O -outw(0x8e11, 0x03d4); // Device I/O -outw(0x8f12, 0x03d4); // Device I/O -outw(0x2813, 0x03d4); // Device I/O -outw(0x1f14, 0x03d4); // Device I/O -outw(0x9615, 0x03d4); // Device I/O -outw(0xb916, 0x03d4); // Device I/O -outw(0xa317, 0x03d4); // Device I/O -outw(0xff18, 0x03d4); // Device I/O -inb(0x03da); // Device I/O --> 01 -inb(0x03ba); // Device I/O --> ff -inb(0x03da); // Device I/O --> 21 -inb(0x03ba); // Device I/O --> ff -inb(0x03da); // Device I/O --> 01 -inb(0x03ba); // Device I/O --> ff -outw(0x0000, 0x03ce); // Device I/O -outw(0x0001, 0x03ce); // Device I/O -outw(0x0002, 0x03ce); // Device I/O -outw(0x0003, 0x03ce); // Device I/O -outw(0x0004, 0x03ce); // Device I/O -outw(0x1005, 0x03ce); // Device I/O -outw(0x0e06, 0x03ce); // Device I/O -outw(0x0007, 0x03ce); // Device I/O -outw(0xff08, 0x03ce); // Device I/O -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outb(0xff, 0x03c6); // Device I/O <-- -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -vga_textmode_init(); -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outb(0x01, 0x03c4); // Device I/O <-- -inw(0x03c4); // Device I/O --> 0x2001 -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f050, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> c0000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outb(0x01, 0x03c4); // Device I/O <-- -inw(0x03c4); // Device I/O --> 0x2001 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outb(0x06, 0x03ce); // Device I/O <-- -inw(0x03ce); // Device I/O --> 0x0e06 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outb(0x01, 0x03c4); // Device I/O <-- -inw(0x03c4); // Device I/O --> 0x2001 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00041000, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 8020298e -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000e1180, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000302 -outl(0x00008302, 0x1044); // Device I/O -outl(0x00048250, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 80000000 -outl(0x80000000, 0x1044); // Device I/O -outl(0x000e1180, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008302 -outl(0x000e1180, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008302 -outl(0x000e1180, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008302 -outl(0x000c6200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00001000, 0x1044); // Device I/O -outl(0x000c6200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00001000 -outl(0x00001002, 0x1044); // Device I/O -outl(0x000c7204, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000c7204, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0xabcd0000, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f00c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000c6040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00030d07 -outl(0x00021005, 0x1044); // Device I/O -outl(0x000c6014, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 04800080 -outl(0x88046004, 0x1044); // Device I/O -outl(0x000c6014, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 88046004 -outl(0x88046004, 0x1044); // Device I/O -outl(0x000c7204, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> abcd0000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000e1180, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008302 -outl(0x00008302, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00060000, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x057f04ff, 0x1044); // Device I/O -outl(0x00060004, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x057f04ff, 0x1044); // Device I/O -outl(0x00060008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x05370517, 0x1044); // Device I/O -outl(0x0006000c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0333031f, 0x1044); // Device I/O -outl(0x00060010, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0333031f, 0x1044); // Device I/O -outl(0x00060014, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x03270323, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outb(0x01, 0x03c4); // Device I/O <-- -inw(0x03c4); // Device I/O --> 0x2001 -outl(0x0006001c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x02cf018f, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00070008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f050, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> c0000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outb(0x01, 0x03c4); // Device I/O <-- -inw(0x03c4); // Device I/O --> 0x2001 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outb(0x06, 0x03ce); // Device I/O <-- -inw(0x03ce); // Device I/O --> 0x0e06 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outb(0x01, 0x03c4); // Device I/O <-- -inw(0x03c4); // Device I/O --> 0x2001 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0006001c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 02cf018f -outl(0x027f018f, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00068080, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x80800000, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00068070, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00068074, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x05000320, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00070008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00070008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00060030, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x7e127ae1, 0x1044); // Device I/O -outl(0x00060034, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00800000, 0x1044); // Device I/O -outl(0x00060040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00020da7, 0x1044); // Device I/O -outl(0x00060044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00080000, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000f000c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000040 -outl(0x00002040, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000f000c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00002040 -outl(0x00002050, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00060100, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00044000 -outl(0x00044000, 0x1044); // Device I/O -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00070008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000040, 0x1044); // Device I/O -outl(0x000f0008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000040, 0x1044); // Device I/O -outl(0x000f000c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00002050 -outl(0x00022050, 0x1044); // Device I/O -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00070008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000040 -outl(0x00000050, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00070008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000050 -outl(0x80000050, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x00041000, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 8020298e -outl(0x0020298e, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000080, 0x1044); // Device I/O -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000f0018, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 000007ff -outl(0x000000ff, 0x1044); // Device I/O -outl(0x000f1018, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 000007ff -outl(0x000000ff, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000f000c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00022050 -outl(0x001a2050, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00060100, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00044000 -outl(0x001c4000, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00060100, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 001c4000 -outl(0x801c4000, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000f000c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 001a2050 -outl(0x801a2050, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00060100, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 801c4000 -outl(0x801c4000, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000f000c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 801a2050 -outl(0x801a2050, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000f0014, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000100 -outl(0x000f0014, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000100 -outl(0x00000100, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00060100, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 801c4000 -outl(0x901c4000, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000f000c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 801a2050 -outl(0x901a2050, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000f0014, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000600 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000e0000, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x057f04ff, 0x1044); // Device I/O -outl(0x000e0004, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x057f04ff, 0x1044); // Device I/O -outl(0x000e0008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x05370517, 0x1044); // Device I/O -outl(0x000e000c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0333031f, 0x1044); // Device I/O -outl(0x000e0010, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0333031f, 0x1044); // Device I/O -outl(0x000e0014, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x03270323, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00060100, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 901c4000 -outl(0xb01c4000, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000f000c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 901a2050 -outl(0xb01a2050, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000f0008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000040 -outl(0x80000040, 0x1044); // Device I/O -outl(0x000e1180, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00008302 -outl(0x80008302, 0x1044); // Device I/O -outl(0x000c7204, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0xabcd0000, 0x1044); // Device I/O -outl(0x000c7204, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> abcd0000 -outl(0xabcd0002, 0x1044); // Device I/O -outl(0x000c7204, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> abcd0002 -outl(0xabcd0003, 0x1044); // Device I/O -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d000000a -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d000000a -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d000000a -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d000000a -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d000000a -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d000000a -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d000000a -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d000000a -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d000000a -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d000000a -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d000000a -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d000000a -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> d0000009 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> c0000008 -outl(0x000c7200, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> c0000008 -outl(0x000c7204, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> abcd0003 -outl(0x00000003, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f040, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 01000008 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000400, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000400 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000400 -outl(0x00000000, 0x1044); // Device I/O -outl(0x0004f044, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x0004f04c, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 03030000 -outl(0x000c4030, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00001000 -outl(0x000c4030, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00001000 -outl(0x00001000, 0x1044); // Device I/O -outl(0x000c4008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x000c4008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x000c4008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00044008, 0x1040); // Device I/O -inl(0x1044); // Device I/O --> 00000000 -outl(0x00000000, 0x1044); // Device I/O diff --git a/src/northbridge/intel/nehalem/gma.c b/src/northbridge/intel/nehalem/gma.c index 2f13a6b..74e67fc 100644 --- a/src/northbridge/intel/nehalem/gma.c +++ b/src/northbridge/intel/nehalem/gma.c @@ -28,6 +28,11 @@ #include <device/pci_ops.h> #include <cpu/x86/msr.h> #include <cpu/x86/mtrr.h> +#include <drivers/intel/gma/edid.h> +#include <drivers/intel/gma/i915.h> +#include <pc80/vga.h> +#include <pc80/vga_io.h> + #include "chip.h" #include "nehalem.h" @@ -545,16 +550,6 @@ static void gma_pm_init_pre_vbios(struct device *dev) gtt_write(0x6c024, reg32); } -#include <pc80/vga.h> -#include <pc80/vga_io.h> - -#if CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT -static void fake_vbios(void) -{ -#include "fake_vbios.c" -} -#endif - static void gma_pm_init_post_vbios(struct device *dev) { struct northbridge_intel_nehalem_config *conf = dev->chip_info; @@ -620,6 +615,388 @@ static void gma_pm_init_post_vbios(struct device *dev) } } +#if IS_ENABLED(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) + +static void train_link(u32 mmio) +{ + write32(mmio + 0x000f000c, 0x00002040); + mdelay(1); + write32(mmio + 0x000f000c, 0x00002050); + write32(mmio + 0x00060100, 0x00044000); + mdelay(1); + write32(mmio + 0x00070008, 0x00000040); + write32(mmio + 0x000f0008, 0x00000040); + write32(mmio + 0x000f000c, 0x00022050); + write32(mmio + 0x00070008, 0x00000050); + write32(mmio + 0x00070008, 0x80000050); + write32(mmio + 0x00041000, 0x0020298e); + + /* Clear interrupts. */ + write32(mmio + DEIIR, 0xffffffff); + + write32(mmio + 0x000f0018, 0x000000ff); + write32(mmio + 0x000f1018, 0x000000ff); + write32(mmio + 0x000f000c, 0x001a2050); + write32(mmio + 0x00060100, 0x001c4000); + write32(mmio + 0x00060100, 0x801c4000); + write32(mmio + 0x000f000c, 0x801a2050); + write32(mmio + 0x00060100, 0x801c4000); + write32(mmio + 0x000f000c, 0x801a2050); + mdelay(1); + + read32(mmio + 0x000f0014); // = 0x00000100 + write32(mmio + 0x000f0014, 0x00000100); + write32(mmio + 0x00060100, 0x901c4000); + write32(mmio + 0x000f000c, 0x901a2050); + mdelay(1); + read32(mmio + 0x000f0014); // = 0x00000600 +} + +static void power_port(u32 mmio) +{ + read32(mmio + 0x000e1100); // = 0x00000000 + write32(mmio + 0x000e1100, 0x00000000); + write32(mmio + 0x000e1100, 0x00010000); + read32(mmio + 0x000e1100); // = 0x00010000 + read32(mmio + 0x000e1100); // = 0x00010000 + read32(mmio + 0x000e1100); // = 0x00000000 + write32(mmio + 0x000e1100, 0x00000000); + read32(mmio + 0x000e1100); // = 0x00000000 + read32(mmio + 0x000e4200); // = 0x0000001c + write32(mmio + 0x000e4210, 0x8004003e); + write32(mmio + 0x000e4214, 0x80060002); + write32(mmio + 0x000e4218, 0x01000000); + read32(mmio + 0x000e4210); // = 0x5144003e + write32(mmio + 0x000e4210, 0x5344003e); + read32(mmio + 0x000e4210); // = 0x0144003e + write32(mmio + 0x000e4210, 0x8074003e); + read32(mmio + 0x000e4210); // = 0x5144003e + read32(mmio + 0x000e4210); // = 0x5144003e + write32(mmio + 0x000e4210, 0x5344003e); + read32(mmio + 0x000e4210); // = 0x0144003e + write32(mmio + 0x000e4210, 0x8074003e); + read32(mmio + 0x000e4210); // = 0x5144003e + read32(mmio + 0x000e4210); // = 0x5144003e + write32(mmio + 0x000e4210, 0x5344003e); + read32(mmio + 0x000e4210); // = 0x0144003e + write32(mmio + 0x000e4210, 0x8074003e); + read32(mmio + 0x000e4210); // = 0x5144003e + read32(mmio + 0x000e4210); // = 0x5144003e + write32(mmio + 0x000e4210, 0x5344003e); + write32(mmio + 0x000e4f00, 0x0100030c); + write32(mmio + 0x000e4f04, 0x00b8230c); + write32(mmio + 0x000e4f08, 0x06f8930c); + write32(mmio + 0x000e4f0c, 0x09f8e38e); + write32(mmio + 0x000e4f10, 0x00b8030c); + write32(mmio + 0x000e4f14, 0x0b78830c); + write32(mmio + 0x000e4f18, 0x0ff8d3cf); + write32(mmio + 0x000e4f1c, 0x01e8030c); + write32(mmio + 0x000e4f20, 0x0ff863cf); + write32(mmio + 0x000e4f24, 0x0ff803cf); + write32(mmio + 0x000c4030, 0x00001000); + read32(mmio + 0x000c4000); // = 0x00000000 + write32(mmio + 0x000c4030, 0x00001000); + read32(mmio + 0x000e1150); // = 0x0000001c + write32(mmio + 0x000e1150, 0x0000089c); + write32(mmio + 0x000fcc00, 0x01986f00); + write32(mmio + 0x000fcc0c, 0x01986f00); + write32(mmio + 0x000fcc18, 0x01986f00); + write32(mmio + 0x000fcc24, 0x01986f00); + read32(mmio + 0x000c4000); // = 0x00000000 + read32(mmio + 0x000e1180); // = 0x40000002 +} + +static void intel_gma_init(const struct northbridge_intel_nehalem_config *info, + u32 mmio, u32 physbase, u32 gttbase) +{ + int i; + u8 edid_data[128]; + struct edid edid; + u32 hactive, vactive, right_border, bottom_border; + int hpolarity, vpolarity; + u32 vsync, hsync, vblank, hblank, hfront_porch, vfront_porch; + u32 candp1, candn; + u32 best_delta = 0xffffffff; + u32 target_frequency; + u32 pixel_p1 = 1; + u32 pixel_n = 1; + u32 pixel_m1 = 1; + u32 pixel_m2 = 1; + u32 link_frequency = info->gpu_link_frequency_270_mhz ? 270000 : 162000; + u32 data_m1; + u32 data_n1 = 0x00800000; + u32 link_m1; + u32 link_n1 = 0x00080000; + + write32(mmio + 0x00070080, 0x00000000); + write32(mmio + 0x00070180, 0x00000000); + write32(mmio + 0x00071180, 0x00000000); + write32(mmio + 0x00041000, 0x8000298e); + write32(mmio + 0x0007019c, 0x00000000); + write32(mmio + 0x0007119c, 0x00000000); + write32(mmio + 0x000fc008, 0x2c010000); + write32(mmio + 0x000fc020, 0x2c010000); + write32(mmio + 0x000fc038, 0x2c010000); + write32(mmio + 0x000fc050, 0x2c010000); + write32(mmio + 0x000fc408, 0x2c010000); + write32(mmio + 0x000fc420, 0x2c010000); + write32(mmio + 0x000fc438, 0x2c010000); + write32(mmio + 0x000fc450, 0x2c010000); + vga_gr_write(0x18, 0); + write32(mmio + 0x00042004, 0x02000000); + write32(mmio + 0x000fd034, 0x8421ffe0); + + /* Setup GTT. */ + for (i = 0; i < 0x1fff; i++) + write32(gttbase + (i << 2), physbase | (i << 12) | 1); + + vga_misc_write(0x67); + + const u8 cr[] = { 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, + 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, + 0xff + }; + vga_cr_write(0x11, 0); + + for (i = 0; i <= 0x18; i++) + vga_cr_write(i, cr[i]); + + power_port(mmio); + + intel_gmbus_read_edid(mmio, 3, 0x50, edid_data); + decode_edid(edid_data, + sizeof(edid_data), &edid); + + /* Disable screen memory to prevent garbage from appearing. */ + vga_sr_write(1, vga_sr_read(1) | 0x20); + + vga_textmode_init(); + + hactive = edid.x_resolution; + vactive = edid.y_resolution; + right_border = edid.hborder; + bottom_border = edid.vborder; + hpolarity = (edid.phsync == '-'); + vpolarity = (edid.pvsync == '-'); + vsync = edid.vspw; + hsync = edid.hspw; + vblank = edid.vbl; + hblank = edid.hbl; + hfront_porch = edid.hso; + vfront_porch = edid.vso; + + target_frequency = info->gpu_lvds_dual_channel ? edid.pixel_clock + : (2 * edid.pixel_clock); + + /* Find suitable divisors. */ + for (candp1 = 1; candp1 <= 8; candp1++) { + for (candn = 5; candn <= 10; candn++) { + u32 cur_frequency; + u32 m; /* 77 - 131. */ + u32 denom; /* 35 - 560. */ + u32 current_delta; + + denom = candn * candp1 * 7; + /* Doesnt overflow for up to + 5000000 kHz = 5 GHz. */ + m = (target_frequency * denom + 60000) / 120000; + + if (m < 77 || m > 131) + continue; + + cur_frequency = (120000 * m) / denom; + if (target_frequency > cur_frequency) + current_delta = target_frequency - cur_frequency; + else + current_delta = cur_frequency - target_frequency; + + + if (best_delta > current_delta) { + best_delta = current_delta; + pixel_n = candn; + pixel_p1 = candp1; + pixel_m2 = ((m + 3) % 5) + 7; + pixel_m1 = (m - pixel_m2) / 5; + } + } + } + + if (best_delta == 0xffffffff) { + printk (BIOS_ERR, "Couldn't find GFX clock divisors\n"); + return; + } + + link_m1 = ((uint64_t)link_n1 * edid.pixel_clock) / link_frequency; + data_m1 = ((uint64_t)data_n1 * 18 * edid.pixel_clock) + / (link_frequency * 8 * (info->gpu_lvds_num_lanes ? : 4)); + + printk(BIOS_INFO, "bringing up panel at resolution %d x %d\n", + hactive, vactive); + printk(BIOS_DEBUG, "Borders %d x %d\n", + right_border, bottom_border); + printk(BIOS_DEBUG, "Blank %d x %d\n", + hblank, vblank); + printk(BIOS_DEBUG, "Sync %d x %d\n", + hsync, vsync); + printk(BIOS_DEBUG, "Front porch %d x %d\n", + hfront_porch, vfront_porch); + printk(BIOS_DEBUG, (info->gpu_use_spread_spectrum_clock + ? "Spread spectrum clock\n" : "DREF clock\n")); + printk(BIOS_DEBUG, + info->gpu_lvds_dual_channel ? "Dual channel\n" : "Single channel\n"); + printk(BIOS_DEBUG, "Polarities %d, %d\n", + hpolarity, vpolarity); + printk(BIOS_DEBUG, "Data M1=%d, N1=%d\n", + data_m1, data_n1); + printk(BIOS_DEBUG, "Link frequency %d kHz\n", + link_frequency); + printk(BIOS_DEBUG, "Link M1=%d, N1=%d\n", + link_m1, link_n1); + printk(BIOS_DEBUG, "Pixel N=%d, M1=%d, M2=%d, P1=%d\n", + pixel_n, pixel_m1, pixel_m2, pixel_p1); + printk(BIOS_DEBUG, "Pixel clock %d kHz\n", + 120000 * (5 * pixel_m1 + pixel_m2) / pixel_n + / (pixel_p1 * 7)); + + write32(mmio + PCH_LVDS, + (hpolarity << 20) | (vpolarity << 21) + | (info->gpu_lvds_dual_channel ? LVDS_CLOCK_B_POWERUP_ALL + | LVDS_CLOCK_BOTH_POWERUP_ALL : 0) + | LVDS_BORDER_ENABLE | LVDS_CLOCK_A_POWERUP_ALL + | LVDS_DETECTED); + write32(mmio + BLC_PWM_CPU_CTL2, (1 << 31)); + write32(mmio + PCH_DREF_CONTROL, (info->gpu_use_spread_spectrum_clock + ? 0x1002 : 0x400)); + mdelay(1); + write32(mmio + PCH_PP_CONTROL, PANEL_UNLOCK_REGS + | (read32(mmio + PCH_PP_CONTROL) & ~PANEL_UNLOCK_MASK)); + write32(mmio + _PCH_FP0(0), + ((pixel_n - 2) << 16) + | ((pixel_m1 - 2) << 8) | pixel_m2); + write32(mmio + _PCH_DPLL(0), + DPLL_VCO_ENABLE | DPLLB_MODE_LVDS + | (info->gpu_lvds_dual_channel ? DPLLB_LVDS_P2_CLOCK_DIV_7 + : DPLLB_LVDS_P2_CLOCK_DIV_14) + | (0x10000 << (pixel_p1 - 1)) + | ((info->gpu_use_spread_spectrum_clock ? 3 : 0) << 13) + | (0x1 << (pixel_p1 - 1))); + mdelay(1); + write32(mmio + _PCH_DPLL(0), + DPLL_VCO_ENABLE | DPLLB_MODE_LVDS + | (info->gpu_lvds_dual_channel ? DPLLB_LVDS_P2_CLOCK_DIV_7 + : DPLLB_LVDS_P2_CLOCK_DIV_14) + | (0x10000 << (pixel_p1 - 1)) + | ((info->gpu_use_spread_spectrum_clock ? 3 : 0) << 13) + | (0x1 << (pixel_p1 - 1))); + /* Re-lock the registers. */ + write32(mmio + PCH_PP_CONTROL, + (read32(mmio + PCH_PP_CONTROL) & ~PANEL_UNLOCK_MASK)); + + write32(mmio + PCH_LVDS, + (hpolarity << 20) | (vpolarity << 21) + | (info->gpu_lvds_dual_channel ? LVDS_CLOCK_B_POWERUP_ALL + | LVDS_CLOCK_BOTH_POWERUP_ALL : 0) + | LVDS_BORDER_ENABLE | LVDS_CLOCK_A_POWERUP_ALL + | LVDS_DETECTED); + + write32(mmio + HTOTAL(0), + ((hactive + right_border + hblank - 1) << 16) + | (hactive - 1)); + write32(mmio + HBLANK(0), + ((hactive + right_border + hblank - 1) << 16) + | (hactive + right_border - 1)); + write32(mmio + HSYNC(0), + ((hactive + right_border + hfront_porch + hsync - 1) << 16) + | (hactive + right_border + hfront_porch - 1)); + + write32(mmio + VTOTAL(0), ((vactive + bottom_border + vblank - 1) << 16) + | (vactive - 1)); + write32(mmio + VBLANK(0), ((vactive + bottom_border + vblank - 1) << 16) + | (vactive + bottom_border - 1)); + write32(mmio + VSYNC(0), + (vactive + bottom_border + vfront_porch + vsync - 1) + | (vactive + bottom_border + vfront_porch - 1)); + + write32(mmio + PIPESRC(0), 0x02cf018f); + write32(mmio + PIPECONF(0), PIPECONF_DISABLE); + + write32(mmio + 0x6001c,0x27f018f); // 02cf018f + write32(mmio + 0x68080,0x80800000); // 00000000 + + write32(mmio + PF_WIN_SZ(0), vactive | (hactive << 16)); + read32(mmio + 0x00070008); + read32(mmio + 0x00070008); + + mdelay(1); + + write32(mmio + PIPE_DATA_M1(0), 0x7e000000 | data_m1); + write32(mmio + PIPE_DATA_N1(0), data_n1); + write32(mmio + PIPE_LINK_M1(0), link_m1); + write32(mmio + PIPE_LINK_N1(0), link_n1); + + train_link(mmio); + + write32(mmio + TRANS_HTOTAL(0), + ((hactive + right_border + hblank - 1) << 16) + | (hactive - 1)); + write32(mmio + TRANS_HBLANK(0), + ((hactive + right_border + hblank - 1) << 16) + | (hactive + right_border - 1)); + write32(mmio + TRANS_HSYNC(0), + ((hactive + right_border + hfront_porch + hsync - 1) << 16) + | (hactive + right_border + hfront_porch - 1)); + + write32(mmio + TRANS_VTOTAL(0), + ((vactive + bottom_border + vblank - 1) << 16) + | (vactive - 1)); + write32(mmio + TRANS_VBLANK(0), + ((vactive + bottom_border + vblank - 1) << 16) + | (vactive + bottom_border - 1)); + write32(mmio + TRANS_VSYNC(0), + (vactive + bottom_border + vfront_porch + vsync - 1) + | (vactive + bottom_border + vfront_porch - 1)); + + write32(mmio + 0x00060100, 0xb01c4000); + write32(mmio + 0x000f000c, 0xb01a2050); + mdelay(1); + write32(mmio + 0x000f0008, 0x80000040); + write32(mmio + PCH_LVDS, + LVDS_PORT_ENABLE + | (hpolarity << 20) | (vpolarity << 21) + | (info->gpu_lvds_dual_channel ? LVDS_CLOCK_B_POWERUP_ALL + | LVDS_CLOCK_BOTH_POWERUP_ALL : 0) + | LVDS_BORDER_ENABLE | LVDS_CLOCK_A_POWERUP_ALL + | LVDS_DETECTED); + + write32(mmio + PCH_PP_CONTROL, PANEL_UNLOCK_REGS | PANEL_POWER_OFF); + write32(mmio + PCH_PP_CONTROL, PANEL_UNLOCK_REGS | PANEL_POWER_RESET); + mdelay(1); + write32(mmio + PCH_PP_CONTROL, PANEL_UNLOCK_REGS + | PANEL_POWER_ON | PANEL_POWER_RESET); + + printk (BIOS_DEBUG, "waiting for panel powerup\n"); + while (1) { + u32 reg32; + reg32 = read32(mmio + PCH_PP_STATUS); + if (((reg32 >> 28) & 3) == 0) + break; + } + printk (BIOS_DEBUG, "panel powered up\n"); + + write32(mmio + PCH_PP_CONTROL, PANEL_POWER_ON | PANEL_POWER_RESET); + + /* Enable screen memory. */ + vga_sr_write(1, vga_sr_read(1) & ~0x20); + + /* Clear interrupts. */ + write32(mmio + DEIIR, 0xffffffff); + write32(mmio + SDEIIR, 0xffffffff); +} + +#endif + + static void gma_func0_init(struct device *dev) { u32 reg32; @@ -636,8 +1013,18 @@ static void gma_func0_init(struct device *dev) /* PCI Init, will run VBIOS */ pci_dev_init(dev); #else - printk(BIOS_SPEW, "Initializing VGA without OPROM.\n"); - fake_vbios(); + u32 physbase, gttbase; + struct northbridge_intel_nehalem_config *conf = dev->chip_info; + + physbase = pci_read_config32(dev, 0x5c) & ~0xf; + gttbase = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0, 0)), + D0F0_GTT_BASE); + + if (gtt_res && gtt_res->base && physbase && gttbase) { + printk(BIOS_SPEW, "Initializing VGA without OPROM. MMIO 0x%llx\n", + gtt_res->base); + intel_gma_init(conf, gtt_res->base, physbase, gttbase); + } #endif /* Linux relies on VBT for panel info. */
1
0
0
0
Patch set updated for coreboot: 95dda18 bd82x6x, ibexpeak, lynxpoint: Unify SPI.
by Vladimir Serbinenko
22 Feb '14
22 Feb '14
Vladimir Serbinenko (phcoder(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at
http://review.coreboot.org/5254
-gerrit commit 95dda186ed9f463e8545f0ffd32769a0219e1db3 Author: Vladimir Serbinenko <phcoder(a)gmail.com> Date: Sun Feb 16 17:13:19 2014 +0100 bd82x6x, ibexpeak, lynxpoint: Unify SPI. SPI registers didnt change since ICH8. No need to have separate files for them. Unify. Change-Id: I4e2ac3221b419c007e135c9ee615fc3b84424cbc Signed-off-by: Vladimir Serbinenko <phcoder(a)gmail.com> --- src/southbridge/intel/bd82x6x/Makefile.inc | 4 +- src/southbridge/intel/bd82x6x/spi.c | 1066 ----------------------- src/southbridge/intel/common/spi.c | 986 ++++++++++++++++++++++ src/southbridge/intel/fsp_bd82x6x/Makefile.inc | 4 +- src/southbridge/intel/fsp_bd82x6x/spi.c | 751 ----------------- src/southbridge/intel/ibexpeak/Makefile.inc | 4 +- src/southbridge/intel/ibexpeak/spi.c | 1067 ------------------------ src/southbridge/intel/lynxpoint/Makefile.inc | 4 +- src/southbridge/intel/lynxpoint/spi.c | 657 --------------- 9 files changed, 994 insertions(+), 3549 deletions(-) diff --git a/src/southbridge/intel/bd82x6x/Makefile.inc b/src/southbridge/intel/bd82x6x/Makefile.inc index 8abc56a..16a53cc 100644 --- a/src/southbridge/intel/bd82x6x/Makefile.inc +++ b/src/southbridge/intel/bd82x6x/Makefile.inc @@ -39,8 +39,8 @@ ramstage-y += reset.c ramstage-y += watchdog.c ramstage-$(CONFIG_ELOG) += elog.c -ramstage-y += spi.c -smm-$(CONFIG_SPI_FLASH_SMM) += spi.c +ramstage-y += ../spi.c +smm-$(CONFIG_SPI_FLASH_SMM) += ../spi.c ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c me.c me_8.x.c finalize.c pch.c diff --git a/src/southbridge/intel/bd82x6x/spi.c b/src/southbridge/intel/bd82x6x/spi.c deleted file mode 100644 index 1f2511e..0000000 --- a/src/southbridge/intel/bd82x6x/spi.c +++ /dev/null @@ -1,1066 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * Copyright (C) 2009, 2010 Carl-Daniel Hailfinger - * Copyright (C) 2011 Stefan Tauner - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* This file is derived from the flashrom project. */ -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <delay.h> -#include <arch/io.h> -#include <console/console.h> -#include <device/pci_ids.h> -#include <device/pci.h> -#include <spi_flash.h> - -#include <spi-generic.h> -#include "pch.h" - -#define min(a, b) ((a)<(b)?(a):(b)) - -#define HSFC_FCYCLE_OFF 1 /* 1-2: FLASH Cycle */ -#define HSFC_FCYCLE (0x3 << HSFC_FCYCLE_OFF) -#define HSFC_FDBC_OFF 8 /* 8-13: Flash Data Byte Count */ -#define HSFC_FDBC (0x3f << HSFC_FDBC_OFF) - - -#ifdef __SMM__ -#include <arch/pci_mmio_cfg.h> -#define pci_read_config_byte(dev, reg, targ)\ - *(targ) = pci_read_config8(dev, reg) -#define pci_read_config_word(dev, reg, targ)\ - *(targ) = pci_read_config16(dev, reg) -#define pci_read_config_dword(dev, reg, targ)\ - *(targ) = pci_read_config32(dev, reg) -#define pci_write_config_byte(dev, reg, val)\ - pci_write_config8(dev, reg, val) -#define pci_write_config_word(dev, reg, val)\ - pci_write_config16(dev, reg, val) -#define pci_write_config_dword(dev, reg, val)\ - pci_write_config32(dev, reg, val) -#else /* !__SMM__ */ -#include <device/device.h> -#include <device/pci.h> -#define pci_read_config_byte(dev, reg, targ)\ - *(targ) = pci_read_config8(dev, reg) -#define pci_read_config_word(dev, reg, targ)\ - *(targ) = pci_read_config16(dev, reg) -#define pci_read_config_dword(dev, reg, targ)\ - *(targ) = pci_read_config32(dev, reg) -#define pci_write_config_byte(dev, reg, val)\ - pci_write_config8(dev, reg, val) -#define pci_write_config_word(dev, reg, val)\ - pci_write_config16(dev, reg, val) -#define pci_write_config_dword(dev, reg, val)\ - pci_write_config32(dev, reg, val) -#endif /* !__SMM__ */ - -static int spi_is_multichip(void); -static struct spi_flash *spi_flash_hwseq(struct spi_slave *spi); - -typedef struct spi_slave ich_spi_slave; - -static int ichspi_lock = 0; - -typedef struct ich7_spi_regs { - uint16_t spis; - uint16_t spic; - uint32_t spia; - uint64_t spid[8]; - uint64_t _pad; - uint32_t bbar; - uint16_t preop; - uint16_t optype; - uint8_t opmenu[8]; -} __attribute__((packed)) ich7_spi_regs; - -typedef struct ich9_spi_regs { - uint32_t bfpr; - uint16_t hsfs; - uint16_t hsfc; - uint32_t faddr; - uint32_t _reserved0; - uint32_t fdata[16]; - uint32_t frap; - uint32_t freg[5]; - uint32_t _reserved1[3]; - uint32_t pr[5]; - uint32_t _reserved2[2]; - uint8_t ssfs; - uint8_t ssfc[3]; - uint16_t preop; - uint16_t optype; - uint8_t opmenu[8]; - uint32_t bbar; - uint8_t _reserved3[12]; - uint32_t fdoc; - uint32_t fdod; - uint8_t _reserved4[8]; - uint32_t afc; - uint32_t lvscc; - uint32_t uvscc; - uint8_t _reserved5[4]; - uint32_t fpb; - uint8_t _reserved6[28]; - uint32_t srdl; - uint32_t srdc; - uint32_t srd; -} __attribute__((packed)) ich9_spi_regs; - -typedef struct ich_spi_controller { - int locked; - int revision; - uint32_t flmap0; - uint32_t hsfs; - - ich9_spi_regs *ich9_spi; - uint8_t *opmenu; - int menubytes; - uint16_t *preop; - uint16_t *optype; - uint32_t *addr; - uint8_t *data; - unsigned databytes; - uint8_t *status; - uint16_t *control; - uint32_t *bbar; -} ich_spi_controller; - -static ich_spi_controller cntlr; - -enum { - SPIS_SCIP = 0x0001, - SPIS_GRANT = 0x0002, - SPIS_CDS = 0x0004, - SPIS_FCERR = 0x0008, - SSFS_AEL = 0x0010, - SPIS_LOCK = 0x8000, - SPIS_RESERVED_MASK = 0x7ff0, - SSFS_RESERVED_MASK = 0x7fe2 -}; - -enum { - SPIC_SCGO = 0x000002, - SPIC_ACS = 0x000004, - SPIC_SPOP = 0x000008, - SPIC_DBC = 0x003f00, - SPIC_DS = 0x004000, - SPIC_SME = 0x008000, - SSFC_SCF_MASK = 0x070000, - SSFC_RESERVED = 0xf80000 -}; - -enum { - HSFS_FDONE = 0x0001, - HSFS_FCERR = 0x0002, - HSFS_AEL = 0x0004, - HSFS_BERASE_MASK = 0x0018, - HSFS_BERASE_SHIFT = 3, - HSFS_SCIP = 0x0020, - HSFS_FDOPSS = 0x2000, - HSFS_FDV = 0x4000, - HSFS_FLOCKDN = 0x8000 -}; - -enum { - HSFC_FGO = 0x0001, - HSFC_FCYCLE_MASK = 0x0006, - HSFC_FCYCLE_SHIFT = 1, - HSFC_FDBC_MASK = 0x3f00, - HSFC_FDBC_SHIFT = 8, - HSFC_FSMIE = 0x8000 -}; - -enum { - SPI_OPCODE_TYPE_READ_NO_ADDRESS = 0, - SPI_OPCODE_TYPE_WRITE_NO_ADDRESS = 1, - SPI_OPCODE_TYPE_READ_WITH_ADDRESS = 2, - SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3 -}; - -#if CONFIG_DEBUG_SPI_FLASH - -static u8 readb_(const void *addr) -{ - u8 v = read8((unsigned long)addr); - printk(BIOS_DEBUG, "read %2.2x from %4.4x\n", - v, ((unsigned) addr & 0xffff) - 0xf020); - return v; -} - -static u16 readw_(const void *addr) -{ - u16 v = read16((unsigned long)addr); - printk(BIOS_DEBUG, "read %4.4x from %4.4x\n", - v, ((unsigned) addr & 0xffff) - 0xf020); - return v; -} - -static u32 readl_(const void *addr) -{ - u32 v = read32((unsigned long)addr); - printk(BIOS_DEBUG, "read %8.8x from %4.4x\n", - v, ((unsigned) addr & 0xffff) - 0xf020); - return v; -} - -static void writeb_(u8 b, const void *addr) -{ - write8((unsigned long)addr, b); - printk(BIOS_DEBUG, "wrote %2.2x to %4.4x\n", - b, ((unsigned) addr & 0xffff) - 0xf020); -} - -static void writew_(u16 b, const void *addr) -{ - write16((unsigned long)addr, b); - printk(BIOS_DEBUG, "wrote %4.4x to %4.4x\n", - b, ((unsigned) addr & 0xffff) - 0xf020); -} - -static void writel_(u32 b, const void *addr) -{ - write32((unsigned long)addr, b); - printk(BIOS_DEBUG, "wrote %8.8x to %4.4x\n", - b, ((unsigned) addr & 0xffff) - 0xf020); -} - -#else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled vvv NOT enabled */ - -#define readb_(a) read8((uint32_t)a) -#define readw_(a) read16((uint32_t)a) -#define readl_(a) read32((uint32_t)a) -#define writeb_(val, addr) write8((uint32_t)addr, val) -#define writew_(val, addr) write16((uint32_t)addr, val) -#define writel_(val, addr) write32((uint32_t)addr, val) - -#endif /* CONFIG_DEBUG_SPI_FLASH ^^^ NOT enabled */ - -static void write_reg(const void *value, void *dest, uint32_t size) -{ - const uint8_t *bvalue = value; - uint8_t *bdest = dest; - - while (size >= 4) { - writel_(*(const uint32_t *)bvalue, bdest); - bdest += 4; bvalue += 4; size -= 4; - } - while (size) { - writeb_(*bvalue, bdest); - bdest++; bvalue++; size--; - } -} - -static void read_reg(const void *src, void *value, uint32_t size) -{ - const uint8_t *bsrc = src; - uint8_t *bvalue = value; - - while (size >= 4) { - *(uint32_t *)bvalue = readl_(bsrc); - bsrc += 4; bvalue += 4; size -= 4; - } - while (size) { - *bvalue = readb_(bsrc); - bsrc++; bvalue++; size--; - } -} - -static void ich_set_bbar(uint32_t minaddr) -{ - const uint32_t bbar_mask = 0x00ffff00; - uint32_t ichspi_bbar; - - minaddr &= bbar_mask; - ichspi_bbar = readl_(cntlr.bbar) & ~bbar_mask; - ichspi_bbar |= minaddr; - writel_(ichspi_bbar, cntlr.bbar); -} - -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - printk(BIOS_DEBUG, "spi_cs_is_valid used but not implemented\n"); - return 0; -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - ich_spi_slave *slave = malloc(sizeof(*slave)); - - if (!slave) { - printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n"); - return NULL; - } - - memset(slave, 0, sizeof(*slave)); - - slave->bus = bus; - slave->cs = cs; - if (cntlr.revision == 9) { - slave->force_programmer_specific = spi_is_multichip (); - slave->programmer_specific_probe = spi_flash_hwseq; - } - return slave; -} - -/* - * Check if this device ID matches one of supported Intel PCH devices. - * - * Return the ICH version if there is a match, or zero otherwise. - */ -static inline int get_ich_version(uint16_t device_id) -{ - if (device_id == PCI_DEVICE_ID_INTEL_TGP_LPC) - return 7; - - if ((device_id >= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN && - device_id <= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX) || - (device_id >= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN && - device_id <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX)) - return 9; - - return 0; -} - -void spi_init(void) -{ - int ich_version = 0; - - uint8_t *rcrb; /* Root Complex Register Block */ - uint32_t rcba; /* Root Complex Base Address */ - uint8_t bios_cntl; - device_t dev; - uint32_t ids; - uint16_t vendor_id, device_id; - -#ifdef __SMM__ - dev = PCI_DEV(0, 31, 0); -#else - dev = dev_find_slot(0, PCI_DEVFN(31, 0)); -#endif - pci_read_config_dword(dev, 0, &ids); - vendor_id = ids; - device_id = (ids >> 16); - - if (vendor_id != PCI_VENDOR_ID_INTEL) { - printk(BIOS_DEBUG, "ICH SPI: No ICH found.\n"); - return; - } - - ich_version = get_ich_version(device_id); - - if (!ich_version) { - printk(BIOS_DEBUG, "ICH SPI: No known ICH found.\n"); - return; - } - - pci_read_config_dword(dev, 0xf0, &rcba); - /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable. */ - rcrb = (uint8_t *)(rcba & 0xffffc000); - cntlr.revision = ich_version; - switch (ich_version) { - case 7: - { - const uint16_t ich7_spibar_offset = 0x3020; - ich7_spi_regs *ich7_spi = - (ich7_spi_regs *)(rcrb + ich7_spibar_offset); - - ichspi_lock = readw_(&ich7_spi->spis) & SPIS_LOCK; - cntlr.opmenu = ich7_spi->opmenu; - cntlr.menubytes = sizeof(ich7_spi->opmenu); - cntlr.optype = &ich7_spi->optype; - cntlr.addr = &ich7_spi->spia; - cntlr.data = (uint8_t *)ich7_spi->spid; - cntlr.databytes = sizeof(ich7_spi->spid); - cntlr.status = (uint8_t *)&ich7_spi->spis; - cntlr.control = &ich7_spi->spic; - cntlr.bbar = &ich7_spi->bbar; - cntlr.preop = &ich7_spi->preop; - break; - } - case 9: - { - const uint16_t ich9_spibar_offset = 0x3800; - ich9_spi_regs *ich9_spi = - (ich9_spi_regs *)(rcrb + ich9_spibar_offset); - uint16_t hsfs; - cntlr.ich9_spi = ich9_spi; - hsfs = readw_(&ich9_spi->hsfs); - ichspi_lock = hsfs & HSFS_FLOCKDN; - cntlr.hsfs = hsfs; - cntlr.opmenu = ich9_spi->opmenu; - cntlr.menubytes = sizeof(ich9_spi->opmenu); - cntlr.optype = &ich9_spi->optype; - cntlr.addr = &ich9_spi->faddr; - cntlr.data = (uint8_t *)ich9_spi->fdata; - cntlr.databytes = sizeof(ich9_spi->fdata); - cntlr.status = &ich9_spi->ssfs; - cntlr.control = (uint16_t *)ich9_spi->ssfc; - cntlr.bbar = &ich9_spi->bbar; - cntlr.preop = &ich9_spi->preop; - - if (cntlr.hsfs & HSFS_FDV) - { - writel_ (4, &ich9_spi->fdoc); - cntlr.flmap0 = readl_(&ich9_spi->fdod); - } - break; - } - default: - printk(BIOS_DEBUG, "ICH SPI: Unrecognized ICH version %d.\n", ich_version); - } - - ich_set_bbar(0); - - /* Disable the BIOS write protect so write commands are allowed. */ - pci_read_config_byte(dev, 0xdc, &bios_cntl); - switch (ich_version) { - case 9: - /* Deassert SMM BIOS Write Protect Disable. */ - bios_cntl &= ~(1 << 5); - break; - - default: - break; - } - pci_write_config_byte(dev, 0xdc, bios_cntl | 0x1); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - -void spi_cs_activate(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - -void spi_cs_deactivate(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - -typedef struct spi_transaction { - const uint8_t *out; - uint32_t bytesout; - uint8_t *in; - uint32_t bytesin; - uint8_t type; - uint8_t opcode; - uint32_t offset; -} spi_transaction; - -static inline void spi_use_out(spi_transaction *trans, unsigned bytes) -{ - trans->out += bytes; - trans->bytesout -= bytes; -} - -static inline void spi_use_in(spi_transaction *trans, unsigned bytes) -{ - trans->in += bytes; - trans->bytesin -= bytes; -} - -static void spi_setup_type(spi_transaction *trans) -{ - trans->type = 0xFF; - - /* Try to guess spi type from read/write sizes. */ - if (trans->bytesin == 0) { - if (trans->bytesout > 4) - /* - * If bytesin = 0 and bytesout > 4, we presume this is - * a write data operation, which is accompanied by an - * address. - */ - trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS; - else - trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS; - return; - } - - if (trans->bytesout == 1) { /* and bytesin is > 0 */ - trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS; - return; - } - - if (trans->bytesout == 4) { /* and bytesin is > 0 */ - trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; - } - - /* Fast read command is called with 5 bytes instead of 4 */ - if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) { - trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; - --trans->bytesout; - } -} - -static int spi_setup_opcode(spi_transaction *trans) -{ - uint16_t optypes; - uint8_t opmenu[cntlr.menubytes]; - - trans->opcode = trans->out[0]; - spi_use_out(trans, 1); - if (!ichspi_lock) { - /* The lock is off, so just use index 0. */ - writeb_(trans->opcode, cntlr.opmenu); - optypes = readw_(cntlr.optype); - optypes = (optypes & 0xfffc) | (trans->type & 0x3); - writew_(optypes, cntlr.optype); - return 0; - } else { - /* The lock is on. See if what we need is on the menu. */ - uint8_t optype; - uint16_t opcode_index; - - /* Write Enable is handled as atomic prefix */ - if (trans->opcode == SPI_OPCODE_WREN) - return 0; - - read_reg(cntlr.opmenu, opmenu, sizeof(opmenu)); - for (opcode_index = 0; opcode_index < cntlr.menubytes; - opcode_index++) { - if (opmenu[opcode_index] == trans->opcode) - break; - } - - if (opcode_index == cntlr.menubytes) { - printk(BIOS_DEBUG, "ICH SPI: Opcode %x not found\n", - trans->opcode); - return -1; - } - - optypes = readw_(cntlr.optype); - optype = (optypes >> (opcode_index * 2)) & 0x3; - if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS && - optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS && - trans->bytesout >= 3) { - /* We guessed wrong earlier. Fix it up. */ - trans->type = optype; - } - if (optype != trans->type) { - printk(BIOS_DEBUG, "ICH SPI: Transaction doesn't fit type %d\n", - optype); - return -1; - } - return opcode_index; - } -} - -static int spi_setup_offset(spi_transaction *trans) -{ - /* Separate the SPI address and data. */ - switch (trans->type) { - case SPI_OPCODE_TYPE_READ_NO_ADDRESS: - case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS: - return 0; - case SPI_OPCODE_TYPE_READ_WITH_ADDRESS: - case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS: - trans->offset = ((uint32_t)trans->out[0] << 16) | - ((uint32_t)trans->out[1] << 8) | - ((uint32_t)trans->out[2] << 0); - spi_use_out(trans, 3); - return 1; - default: - printk(BIOS_DEBUG, "Unrecognized SPI transaction type %#x\n", trans->type); - return -1; - } -} - -/* - * Wait for up to 60ms til status register bit(s) turn 1 (in case wait_til_set - * below is True) or 0. In case the wait was for the bit(s) to set - write - * those bits back, which would cause resetting them. - * - * Return the last read status value on success or -1 on failure. - */ -static int ich_status_poll(u16 bitmask, int wait_til_set) -{ - int timeout = 6000; /* This will result in 60 ms */ - u16 status = 0; - - while (timeout--) { - status = readw_(cntlr.status); - if (wait_til_set ^ ((status & bitmask) == 0)) { - if (wait_til_set) - writew_((status & bitmask), cntlr.status); - return status; - } - udelay(10); - } - - printk(BIOS_DEBUG, "ICH SPI: SCIP timeout, read %x, expected %x\n", - status, bitmask); - return -1; -} - -static int spi_is_multichip (void) -{ - if (cntlr.revision != 9) - return 0; - if (!(cntlr.hsfs & HSFS_FDV)) - return 0; - return !!((cntlr.flmap0 >> 8) & 3); -} - -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bitsout, void *din, unsigned int bitsin) -{ - uint16_t control; - int16_t opcode_index; - int with_address; - int status; - - spi_transaction trans = { - dout, bitsout / 8, - din, bitsin / 8, - 0xff, 0xff, 0 - }; - - /* There has to always at least be an opcode. */ - if (!bitsout || !dout) { - printk(BIOS_DEBUG, "ICH SPI: No opcode for transfer\n"); - return -1; - } - /* Make sure if we read something we have a place to put it. */ - if (bitsin != 0 && !din) { - printk(BIOS_DEBUG, "ICH SPI: Read but no target buffer\n"); - return -1; - } - /* Right now we don't support writing partial bytes. */ - if (bitsout % 8 || bitsin % 8) { - printk(BIOS_DEBUG, "ICH SPI: Accessing partial bytes not supported\n"); - return -1; - } - - if (ich_status_poll(SPIS_SCIP, 0) == -1) - return -1; - - writew_(SPIS_CDS | SPIS_FCERR, cntlr.status); - - spi_setup_type(&trans); - if ((opcode_index = spi_setup_opcode(&trans)) < 0) - return -1; - if ((with_address = spi_setup_offset(&trans)) < 0) - return -1; - - if (trans.opcode == SPI_OPCODE_WREN) { - /* - * Treat Write Enable as Atomic Pre-Op if possible - * in order to prevent the Management Engine from - * issuing a transaction between WREN and DATA. - */ - if (!ichspi_lock) - writew_(trans.opcode, cntlr.preop); - return 0; - } - - /* Preset control fields */ - control = SPIC_SCGO | ((opcode_index & 0x07) << 4); - - /* Issue atomic preop cycle if needed */ - if (readw_(cntlr.preop)) - control |= SPIC_ACS; - - if (!trans.bytesout && !trans.bytesin) { - /* SPI addresses are 24 bit only */ - if (with_address) - writel_(trans.offset & 0x00FFFFFF, cntlr.addr); - - /* - * This is a 'no data' command (like Write Enable), its - * bitesout size was 1, decremented to zero while executing - * spi_setup_opcode() above. Tell the chip to send the - * command. - */ - writew_(control, cntlr.control); - - /* wait for the result */ - status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); - if (status == -1) - return -1; - - if (status & SPIS_FCERR) { - printk(BIOS_DEBUG, "ICH SPI: Command transaction error\n"); - return -1; - } - - return 0; - } - - /* - * Check if this is a write command attempting to transfer more bytes - * than the controller can handle. Iterations for writes are not - * supported here because each SPI write command needs to be preceded - * and followed by other SPI commands, and this sequence is controlled - * by the SPI chip driver. - */ - if (trans.bytesout > cntlr.databytes) { - printk(BIOS_DEBUG, "ICH SPI: Too much to write. Does your SPI chip driver use" - " CONTROLLER_PAGE_LIMIT?\n"); - return -1; - } - - /* - * Read or write up to databytes bytes at a time until everything has - * been sent. - */ - while (trans.bytesout || trans.bytesin) { - uint32_t data_length; - - /* SPI addresses are 24 bit only */ - writel_(trans.offset & 0x00FFFFFF, cntlr.addr); - - if (trans.bytesout) - data_length = min(trans.bytesout, cntlr.databytes); - else - data_length = min(trans.bytesin, cntlr.databytes); - - /* Program data into FDATA0 to N */ - if (trans.bytesout) { - write_reg(trans.out, cntlr.data, data_length); - spi_use_out(&trans, data_length); - if (with_address) - trans.offset += data_length; - } - - /* Add proper control fields' values */ - control &= ~((cntlr.databytes - 1) << 8); - control |= SPIC_DS; - control |= (data_length - 1) << 8; - - /* write it */ - writew_(control, cntlr.control); - - /* Wait for Cycle Done Status or Flash Cycle Error. */ - status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); - if (status == -1) - return -1; - - if (status & SPIS_FCERR) { - printk(BIOS_DEBUG, "ICH SPI: Data transaction error\n"); - return -1; - } - - if (trans.bytesin) { - read_reg(cntlr.data, trans.in, data_length); - spi_use_in(&trans, data_length); - if (with_address) - trans.offset += data_length; - } - } - - /* Clear atomic preop now that xfer is done */ - writew_(0, cntlr.preop); - - return 0; -} - -/* Sets FLA in FADDR to (addr & 0x01FFFFFF) without touching other bits. */ -static void ich_hwseq_set_addr(uint32_t addr) -{ - uint32_t addr_old = readl_(&cntlr.ich9_spi->faddr) & ~0x01FFFFFF; - writel_((addr & 0x01FFFFFF) | addr_old, &cntlr.ich9_spi->faddr); -} - -/* Polls for Cycle Done Status, Flash Cycle Error or timeout in 8 us intervals. - Resets all error flags in HSFS. - Returns 0 if the cycle completes successfully without errors within - timeout us, 1 on errors. */ -static int ich_hwseq_wait_for_cycle_complete(unsigned int timeout, - unsigned int len) -{ - uint16_t hsfs; - uint32_t addr; - - timeout /= 8; /* scale timeout duration to counter */ - while ((((hsfs = readw_(&cntlr.ich9_spi->hsfs)) & - (HSFS_FDONE | HSFS_FCERR)) == 0) && - --timeout) { - udelay(8); - } - writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); - - if (!timeout) { - uint16_t hsfc; - addr = readl_(&cntlr.ich9_spi->faddr) & 0x01FFFFFF; - hsfc = readw_(&cntlr.ich9_spi->hsfc); - printk(BIOS_ERR, "Transaction timeout between offset 0x%08x and " - "0x%08x (= 0x%08x + %d) HSFC=%x HSFS=%x!\n", - addr, addr + len - 1, addr, len - 1, - hsfc, hsfs); - return 1; - } - - if (hsfs & HSFS_FCERR) { - uint16_t hsfc; - addr = readl_(&cntlr.ich9_spi->faddr) & 0x01FFFFFF; - hsfc = readw_(&cntlr.ich9_spi->hsfc); - printk(BIOS_ERR, "Transaction error between offset 0x%08x and " - "0x%08x (= 0x%08x + %d) HSFC=%x HSFS=%x!\n", - addr, addr + len - 1, addr, len - 1, - hsfc, hsfs); - return 1; - } - return 0; -} - - -static int ich_hwseq_erase(struct spi_flash *flash, u32 offset, size_t len) -{ - u32 start, end, erase_size; - int ret; - uint16_t hsfc; - uint16_t timeout = 1000 * 60; - - erase_size = flash->sector_size; - if (offset % erase_size || len % erase_size) { - printk(BIOS_ERR, "SF: Erase offset/length not multiple of erase size\n"); - return -1; - } - - flash->spi->rw = SPI_WRITE_FLAG; - ret = spi_claim_bus(flash->spi); - if (ret) { - printk(BIOS_ERR, "SF: Unable to claim SPI bus\n"); - return ret; - } - - start = offset; - end = start + len; - - while (offset < end) { - /* make sure FDONE, FCERR, AEL are cleared by writing 1 to them */ - writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); - - ich_hwseq_set_addr(offset); - - offset += erase_size; - - hsfc = readw_(&cntlr.ich9_spi->hsfc); - hsfc &= ~HSFC_FCYCLE; /* clear operation */ - hsfc |= (0x3 << HSFC_FCYCLE_OFF); /* set erase operation */ - hsfc |= HSFC_FGO; /* start */ - writew_(hsfc, &cntlr.ich9_spi->hsfc); - if (ich_hwseq_wait_for_cycle_complete(timeout, len)) - { - printk(BIOS_ERR, "SF: Erase failed at %x\n", offset - erase_size); - ret = -1; - goto out; - } - } - - printk(BIOS_DEBUG, "SF: Successfully erased %zu bytes @ %#x\n", len, start); - -out: - spi_release_bus(flash->spi); - return ret; -} - -static void ich_read_data(uint8_t *data, int len) -{ - int i; - uint32_t temp32 = 0; - - for (i = 0; i < len; i++) { - if ((i % 4) == 0) - temp32 = readl_(cntlr.data + i); - - data[i] = (temp32 >> ((i % 4) * 8)) & 0xff; - } -} - -static int ich_hwseq_read(struct spi_flash *flash, - u32 addr, size_t len, void *buf) -{ - uint16_t hsfc; - uint16_t timeout = 100 * 60; - uint8_t block_len; - - if (addr + len > flash->size) { - printk (BIOS_ERR, - "Attempt to read %x-%x which is out of chip\n", - (unsigned) addr, - (unsigned) addr+(unsigned) len); - return -1; - } - - /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ - writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); - - while (len > 0) { - block_len = min(len, cntlr.databytes); - if (block_len > (~addr & 0xff)) - block_len = (~addr & 0xff) + 1; - ich_hwseq_set_addr(addr); - hsfc = readw_(&cntlr.ich9_spi->hsfc); - hsfc &= ~HSFC_FCYCLE; /* set read operation */ - hsfc &= ~HSFC_FDBC; /* clear byte count */ - /* set byte count */ - hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); - hsfc |= HSFC_FGO; /* start */ - writew_(hsfc, &cntlr.ich9_spi->hsfc); - - if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) - return 1; - ich_read_data(buf, block_len); - addr += block_len; - buf += block_len; - len -= block_len; - } - return 0; -} - -/* Fill len bytes from the data array into the fdata/spid registers. - * - * Note that using len > flash->pgm->spi.max_data_write will trash the registers - * following the data registers. - */ -static void ich_fill_data(const uint8_t *data, int len) -{ - uint32_t temp32 = 0; - int i; - - if (len <= 0) - return; - - for (i = 0; i < len; i++) { - if ((i % 4) == 0) - temp32 = 0; - - temp32 |= ((uint32_t) data[i]) << ((i % 4) * 8); - - if ((i % 4) == 3) /* 32 bits are full, write them to regs. */ - writel_(temp32, cntlr.data + (i - (i % 4))); - } - i--; - if ((i % 4) != 3) /* Write remaining data to regs. */ - writel_(temp32, cntlr.data + (i - (i % 4))); -} - -static int ich_hwseq_write(struct spi_flash *flash, - u32 addr, size_t len, const void *buf) -{ - uint16_t hsfc; - uint16_t timeout = 100 * 60; - uint8_t block_len; - uint32_t start = addr; - - if (addr + len > flash->size) { - printk (BIOS_ERR, - "Attempt to write 0x%x-0x%x which is out of chip\n", - (unsigned)addr, (unsigned) (addr+len)); - return -1; - } - - /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ - writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); - - while (len > 0) { - block_len = min(len, cntlr.databytes); - if (block_len > (~addr & 0xff)) - block_len = (~addr & 0xff) + 1; - - ich_hwseq_set_addr(addr); - - ich_fill_data(buf, block_len); - hsfc = readw_(&cntlr.ich9_spi->hsfc); - hsfc &= ~HSFC_FCYCLE; /* clear operation */ - hsfc |= (0x2 << HSFC_FCYCLE_OFF); /* set write operation */ - hsfc &= ~HSFC_FDBC; /* clear byte count */ - /* set byte count */ - hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); - hsfc |= HSFC_FGO; /* start */ - writew_(hsfc, &cntlr.ich9_spi->hsfc); - - if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) - { - printk (BIOS_ERR, "SF: write failure at %x\n", - addr); - return -1; - } - addr += block_len; - buf += block_len; - len -= block_len; - } - printk(BIOS_DEBUG, "SF: Successfully written %u bytes @ %#x\n", - (unsigned) (addr - start), start); - return 0; -} - - -static struct spi_flash *spi_flash_hwseq(struct spi_slave *spi) -{ - struct spi_flash *flash = NULL; - uint32_t flcomp; - - flash = malloc(sizeof(*flash)); - if (!flash) { - printk(BIOS_WARNING, "SF: Failed to allocate memory\n"); - return NULL; - } - - flash->spi = spi; - flash->name = "Opaque HW-sequencing"; - - flash->write = ich_hwseq_write; - flash->erase = ich_hwseq_erase; - flash->read = ich_hwseq_read; - ich_hwseq_set_addr (0); - switch ((cntlr.hsfs >> 3) & 3) - { - case 0: - flash->sector_size = 256; - break; - case 1: - flash->sector_size = 4096; - break; - case 2: - flash->sector_size = 8192; - break; - case 3: - flash->sector_size = 65536; - break; - } - - writel_ (0x1000, &cntlr.ich9_spi->fdoc); - flcomp = readl_(&cntlr.ich9_spi->fdod); - - flash->size = 1 << (19 + (flcomp & 7)); - - if ((cntlr.hsfs & HSFS_FDV) && ((cntlr.flmap0 >> 8) & 3)) - flash->size += 1 << (19 + ((flcomp >> 3) & 7)); - printk (BIOS_DEBUG, "flash size 0x%x bytes\n", flash->size); - - return flash; -} diff --git a/src/southbridge/intel/common/spi.c b/src/southbridge/intel/common/spi.c new file mode 100644 index 0000000..b323dbb --- /dev/null +++ b/src/southbridge/intel/common/spi.c @@ -0,0 +1,986 @@ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * Copyright (C) 2009, 2010 Carl-Daniel Hailfinger + * Copyright (C) 2011 Stefan Tauner + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* This file is derived from the flashrom project. */ +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <delay.h> +#include <arch/io.h> +#include <console/console.h> +#include <device/pci_ids.h> +#include <device/pci.h> +#include <spi_flash.h> + +#include <spi-generic.h> + +#define min(a, b) ((a)<(b)?(a):(b)) + +#define HSFC_FCYCLE_OFF 1 /* 1-2: FLASH Cycle */ +#define HSFC_FCYCLE (0x3 << HSFC_FCYCLE_OFF) +#define HSFC_FDBC_OFF 8 /* 8-13: Flash Data Byte Count */ +#define HSFC_FDBC (0x3f << HSFC_FDBC_OFF) + + +#ifdef __SMM__ +#include <arch/pci_mmio_cfg.h> +#define pci_read_config_byte(dev, reg, targ)\ + *(targ) = pci_read_config8(dev, reg) +#define pci_read_config_word(dev, reg, targ)\ + *(targ) = pci_read_config16(dev, reg) +#define pci_read_config_dword(dev, reg, targ)\ + *(targ) = pci_read_config32(dev, reg) +#define pci_write_config_byte(dev, reg, val)\ + pci_write_config8(dev, reg, val) +#define pci_write_config_word(dev, reg, val)\ + pci_write_config16(dev, reg, val) +#define pci_write_config_dword(dev, reg, val)\ + pci_write_config32(dev, reg, val) +#else /* !__SMM__ */ +#include <device/device.h> +#include <device/pci.h> +#define pci_read_config_byte(dev, reg, targ)\ + *(targ) = pci_read_config8(dev, reg) +#define pci_read_config_word(dev, reg, targ)\ + *(targ) = pci_read_config16(dev, reg) +#define pci_read_config_dword(dev, reg, targ)\ + *(targ) = pci_read_config32(dev, reg) +#define pci_write_config_byte(dev, reg, val)\ + pci_write_config8(dev, reg, val) +#define pci_write_config_word(dev, reg, val)\ + pci_write_config16(dev, reg, val) +#define pci_write_config_dword(dev, reg, val)\ + pci_write_config32(dev, reg, val) +#endif /* !__SMM__ */ + +static int spi_is_multichip(void); +static struct spi_flash *spi_flash_hwseq(struct spi_slave *spi); + +typedef struct spi_slave ich_spi_slave; + +static int ichspi_lock = 0; + +typedef struct ich7_spi_regs { + uint16_t spis; + uint16_t spic; + uint32_t spia; + uint64_t spid[8]; + uint64_t _pad; + uint32_t bbar; + uint16_t preop; + uint16_t optype; + uint8_t opmenu[8]; +} __attribute__((packed)) ich7_spi_regs; + +typedef struct ich9_spi_regs { + uint32_t bfpr; + uint16_t hsfs; + uint16_t hsfc; + uint32_t faddr; + uint32_t _reserved0; + uint32_t fdata[16]; + uint32_t frap; + uint32_t freg[5]; + uint32_t _reserved1[3]; + uint32_t pr[5]; + uint32_t _reserved2[2]; + uint8_t ssfs; + uint8_t ssfc[3]; + uint16_t preop; + uint16_t optype; + uint8_t opmenu[8]; + uint32_t bbar; + uint8_t _reserved3[12]; + uint32_t fdoc; + uint32_t fdod; + uint8_t _reserved4[8]; + uint32_t afc; + uint32_t lvscc; + uint32_t uvscc; + uint8_t _reserved5[4]; + uint32_t fpb; + uint8_t _reserved6[28]; + uint32_t srdl; + uint32_t srdc; + uint32_t srd; +} __attribute__((packed)) ich9_spi_regs; + +typedef struct ich_spi_controller { + int locked; + uint32_t flmap0; + uint32_t hsfs; + + ich9_spi_regs *ich9_spi; + uint8_t *opmenu; + int menubytes; + uint16_t *preop; + uint16_t *optype; + uint32_t *addr; + uint8_t *data; + unsigned databytes; + uint8_t *status; + uint16_t *control; + uint32_t *bbar; +} ich_spi_controller; + +static ich_spi_controller cntlr; + +enum { + SPIS_SCIP = 0x0001, + SPIS_GRANT = 0x0002, + SPIS_CDS = 0x0004, + SPIS_FCERR = 0x0008, + SSFS_AEL = 0x0010, + SPIS_LOCK = 0x8000, + SPIS_RESERVED_MASK = 0x7ff0, + SSFS_RESERVED_MASK = 0x7fe2 +}; + +enum { + SPIC_SCGO = 0x000002, + SPIC_ACS = 0x000004, + SPIC_SPOP = 0x000008, + SPIC_DBC = 0x003f00, + SPIC_DS = 0x004000, + SPIC_SME = 0x008000, + SSFC_SCF_MASK = 0x070000, + SSFC_RESERVED = 0xf80000 +}; + +enum { + HSFS_FDONE = 0x0001, + HSFS_FCERR = 0x0002, + HSFS_AEL = 0x0004, + HSFS_BERASE_MASK = 0x0018, + HSFS_BERASE_SHIFT = 3, + HSFS_SCIP = 0x0020, + HSFS_FDOPSS = 0x2000, + HSFS_FDV = 0x4000, + HSFS_FLOCKDN = 0x8000 +}; + +enum { + HSFC_FGO = 0x0001, + HSFC_FCYCLE_MASK = 0x0006, + HSFC_FCYCLE_SHIFT = 1, + HSFC_FDBC_MASK = 0x3f00, + HSFC_FDBC_SHIFT = 8, + HSFC_FSMIE = 0x8000 +}; + +enum { + SPI_OPCODE_TYPE_READ_NO_ADDRESS = 0, + SPI_OPCODE_TYPE_WRITE_NO_ADDRESS = 1, + SPI_OPCODE_TYPE_READ_WITH_ADDRESS = 2, + SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3 +}; + +#if CONFIG_DEBUG_SPI_FLASH + +static u8 readb_(const void *addr) +{ + u8 v = read8((unsigned long)addr); + printk(BIOS_DEBUG, "read %2.2x from %4.4x\n", + v, ((unsigned) addr & 0xffff) - 0xf020); + return v; +} + +static u16 readw_(const void *addr) +{ + u16 v = read16((unsigned long)addr); + printk(BIOS_DEBUG, "read %4.4x from %4.4x\n", + v, ((unsigned) addr & 0xffff) - 0xf020); + return v; +} + +static u32 readl_(const void *addr) +{ + u32 v = read32((unsigned long)addr); + printk(BIOS_DEBUG, "read %8.8x from %4.4x\n", + v, ((unsigned) addr & 0xffff) - 0xf020); + return v; +} + +static void writeb_(u8 b, const void *addr) +{ + write8((unsigned long)addr, b); + printk(BIOS_DEBUG, "wrote %2.2x to %4.4x\n", + b, ((unsigned) addr & 0xffff) - 0xf020); +} + +static void writew_(u16 b, const void *addr) +{ + write16((unsigned long)addr, b); + printk(BIOS_DEBUG, "wrote %4.4x to %4.4x\n", + b, ((unsigned) addr & 0xffff) - 0xf020); +} + +static void writel_(u32 b, const void *addr) +{ + write32((unsigned long)addr, b); + printk(BIOS_DEBUG, "wrote %8.8x to %4.4x\n", + b, ((unsigned) addr & 0xffff) - 0xf020); +} + +#else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled vvv NOT enabled */ + +#define readb_(a) read8((uint32_t)a) +#define readw_(a) read16((uint32_t)a) +#define readl_(a) read32((uint32_t)a) +#define writeb_(val, addr) write8((uint32_t)addr, val) +#define writew_(val, addr) write16((uint32_t)addr, val) +#define writel_(val, addr) write32((uint32_t)addr, val) + +#endif /* CONFIG_DEBUG_SPI_FLASH ^^^ NOT enabled */ + +static void write_reg(const void *value, void *dest, uint32_t size) +{ + const uint8_t *bvalue = value; + uint8_t *bdest = dest; + + while (size >= 4) { + writel_(*(const uint32_t *)bvalue, bdest); + bdest += 4; bvalue += 4; size -= 4; + } + while (size) { + writeb_(*bvalue, bdest); + bdest++; bvalue++; size--; + } +} + +static void read_reg(const void *src, void *value, uint32_t size) +{ + const uint8_t *bsrc = src; + uint8_t *bvalue = value; + + while (size >= 4) { + *(uint32_t *)bvalue = readl_(bsrc); + bsrc += 4; bvalue += 4; size -= 4; + } + while (size) { + *bvalue = readb_(bsrc); + bsrc++; bvalue++; size--; + } +} + +static void ich_set_bbar(uint32_t minaddr) +{ + const uint32_t bbar_mask = 0x00ffff00; + uint32_t ichspi_bbar; + + minaddr &= bbar_mask; + ichspi_bbar = readl_(cntlr.bbar) & ~bbar_mask; + ichspi_bbar |= minaddr; + writel_(ichspi_bbar, cntlr.bbar); +} + +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + printk(BIOS_DEBUG, "spi_cs_is_valid used but not implemented\n"); + return 0; +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + ich_spi_slave *slave = malloc(sizeof(*slave)); + + if (!slave) { + printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n"); + return NULL; + } + + memset(slave, 0, sizeof(*slave)); + + slave->bus = bus; + slave->cs = cs; + slave->force_programmer_specific = spi_is_multichip (); + slave->programmer_specific_probe = spi_flash_hwseq; + return slave; +} + +void spi_init(void) +{ + uint8_t *rcrb; /* Root Complex Register Block */ + uint32_t rcba; /* Root Complex Base Address */ + uint8_t bios_cntl; + device_t dev; + ich9_spi_regs *ich9_spi; + uint16_t hsfs; + +#ifdef __SMM__ + dev = PCI_DEV(0, 31, 0); +#else + dev = dev_find_slot(0, PCI_DEVFN(31, 0)); +#endif + + pci_read_config_dword(dev, 0xf0, &rcba); + /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable. */ + rcrb = (uint8_t *)(rcba & 0xffffc000); + ich9_spi = (ich9_spi_regs *)(rcrb + 0x3800); + cntlr.ich9_spi = ich9_spi; + hsfs = readw_(&ich9_spi->hsfs); + ichspi_lock = hsfs & HSFS_FLOCKDN; + cntlr.hsfs = hsfs; + cntlr.opmenu = ich9_spi->opmenu; + cntlr.menubytes = sizeof(ich9_spi->opmenu); + cntlr.optype = &ich9_spi->optype; + cntlr.addr = &ich9_spi->faddr; + cntlr.data = (uint8_t *)ich9_spi->fdata; + cntlr.databytes = sizeof(ich9_spi->fdata); + cntlr.status = &ich9_spi->ssfs; + cntlr.control = (uint16_t *)ich9_spi->ssfc; + cntlr.bbar = &ich9_spi->bbar; + cntlr.preop = &ich9_spi->preop; + + if (cntlr.hsfs & HSFS_FDV) + { + writel_ (4, &ich9_spi->fdoc); + cntlr.flmap0 = readl_(&ich9_spi->fdod); + } + + ich_set_bbar(0); + + /* Disable the BIOS write protect so write commands are allowed. */ + pci_read_config_byte(dev, 0xdc, &bios_cntl); + /* Deassert SMM BIOS Write Protect Disable. */ + bios_cntl &= ~(1 << 5); + pci_write_config_byte(dev, 0xdc, bios_cntl | 0x1); +} + +int spi_claim_bus(struct spi_slave *slave) +{ + /* Handled by ICH automatically. */ + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ + /* Handled by ICH automatically. */ +} + +void spi_cs_activate(struct spi_slave *slave) +{ + /* Handled by ICH automatically. */ +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ + /* Handled by ICH automatically. */ +} + +typedef struct spi_transaction { + const uint8_t *out; + uint32_t bytesout; + uint8_t *in; + uint32_t bytesin; + uint8_t type; + uint8_t opcode; + uint32_t offset; +} spi_transaction; + +static inline void spi_use_out(spi_transaction *trans, unsigned bytes) +{ + trans->out += bytes; + trans->bytesout -= bytes; +} + +static inline void spi_use_in(spi_transaction *trans, unsigned bytes) +{ + trans->in += bytes; + trans->bytesin -= bytes; +} + +static void spi_setup_type(spi_transaction *trans) +{ + trans->type = 0xFF; + + /* Try to guess spi type from read/write sizes. */ + if (trans->bytesin == 0) { + if (trans->bytesout > 4) + /* + * If bytesin = 0 and bytesout > 4, we presume this is + * a write data operation, which is accompanied by an + * address. + */ + trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS; + else + trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS; + return; + } + + if (trans->bytesout == 1) { /* and bytesin is > 0 */ + trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS; + return; + } + + if (trans->bytesout == 4) { /* and bytesin is > 0 */ + trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; + } + + /* Fast read command is called with 5 bytes instead of 4 */ + if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) { + trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; + --trans->bytesout; + } +} + +static int spi_setup_opcode(spi_transaction *trans) +{ + uint16_t optypes; + uint8_t opmenu[cntlr.menubytes]; + + trans->opcode = trans->out[0]; + spi_use_out(trans, 1); + if (!ichspi_lock) { + /* The lock is off, so just use index 0. */ + writeb_(trans->opcode, cntlr.opmenu); + optypes = readw_(cntlr.optype); + optypes = (optypes & 0xfffc) | (trans->type & 0x3); + writew_(optypes, cntlr.optype); + return 0; + } else { + /* The lock is on. See if what we need is on the menu. */ + uint8_t optype; + uint16_t opcode_index; + + /* Write Enable is handled as atomic prefix */ + if (trans->opcode == SPI_OPCODE_WREN) + return 0; + + read_reg(cntlr.opmenu, opmenu, sizeof(opmenu)); + for (opcode_index = 0; opcode_index < cntlr.menubytes; + opcode_index++) { + if (opmenu[opcode_index] == trans->opcode) + break; + } + + if (opcode_index == cntlr.menubytes) { + printk(BIOS_DEBUG, "ICH SPI: Opcode %x not found\n", + trans->opcode); + return -1; + } + + optypes = readw_(cntlr.optype); + optype = (optypes >> (opcode_index * 2)) & 0x3; + if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS && + optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS && + trans->bytesout >= 3) { + /* We guessed wrong earlier. Fix it up. */ + trans->type = optype; + } + if (optype != trans->type) { + printk(BIOS_DEBUG, "ICH SPI: Transaction doesn't fit type %d\n", + optype); + return -1; + } + return opcode_index; + } +} + +static int spi_setup_offset(spi_transaction *trans) +{ + /* Separate the SPI address and data. */ + switch (trans->type) { + case SPI_OPCODE_TYPE_READ_NO_ADDRESS: + case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS: + return 0; + case SPI_OPCODE_TYPE_READ_WITH_ADDRESS: + case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS: + trans->offset = ((uint32_t)trans->out[0] << 16) | + ((uint32_t)trans->out[1] << 8) | + ((uint32_t)trans->out[2] << 0); + spi_use_out(trans, 3); + return 1; + default: + printk(BIOS_DEBUG, "Unrecognized SPI transaction type %#x\n", trans->type); + return -1; + } +} + +/* + * Wait for up to 60ms til status register bit(s) turn 1 (in case wait_til_set + * below is True) or 0. In case the wait was for the bit(s) to set - write + * those bits back, which would cause resetting them. + * + * Return the last read status value on success or -1 on failure. + */ +static int ich_status_poll(u16 bitmask, int wait_til_set) +{ + int timeout = 6000; /* This will result in 60 ms */ + u16 status = 0; + + while (timeout--) { + status = readw_(cntlr.status); + if (wait_til_set ^ ((status & bitmask) == 0)) { + if (wait_til_set) + writew_((status & bitmask), cntlr.status); + return status; + } + udelay(10); + } + + printk(BIOS_DEBUG, "ICH SPI: SCIP timeout, read %x, expected %x\n", + status, bitmask); + return -1; +} + +static int spi_is_multichip (void) +{ + if (!(cntlr.hsfs & HSFS_FDV)) + return 0; + return !!((cntlr.flmap0 >> 8) & 3); +} + +int spi_xfer(struct spi_slave *slave, const void *dout, + unsigned int bitsout, void *din, unsigned int bitsin) +{ + uint16_t control; + int16_t opcode_index; + int with_address; + int status; + + spi_transaction trans = { + dout, bitsout / 8, + din, bitsin / 8, + 0xff, 0xff, 0 + }; + + /* There has to always at least be an opcode. */ + if (!bitsout || !dout) { + printk(BIOS_DEBUG, "ICH SPI: No opcode for transfer\n"); + return -1; + } + /* Make sure if we read something we have a place to put it. */ + if (bitsin != 0 && !din) { + printk(BIOS_DEBUG, "ICH SPI: Read but no target buffer\n"); + return -1; + } + /* Right now we don't support writing partial bytes. */ + if (bitsout % 8 || bitsin % 8) { + printk(BIOS_DEBUG, "ICH SPI: Accessing partial bytes not supported\n"); + return -1; + } + + if (ich_status_poll(SPIS_SCIP, 0) == -1) + return -1; + + writew_(SPIS_CDS | SPIS_FCERR, cntlr.status); + + spi_setup_type(&trans); + if ((opcode_index = spi_setup_opcode(&trans)) < 0) + return -1; + if ((with_address = spi_setup_offset(&trans)) < 0) + return -1; + + if (trans.opcode == SPI_OPCODE_WREN) { + /* + * Treat Write Enable as Atomic Pre-Op if possible + * in order to prevent the Management Engine from + * issuing a transaction between WREN and DATA. + */ + if (!ichspi_lock) + writew_(trans.opcode, cntlr.preop); + return 0; + } + + /* Preset control fields */ + control = SPIC_SCGO | ((opcode_index & 0x07) << 4); + + /* Issue atomic preop cycle if needed */ + if (readw_(cntlr.preop)) + control |= SPIC_ACS; + + if (!trans.bytesout && !trans.bytesin) { + /* SPI addresses are 24 bit only */ + if (with_address) + writel_(trans.offset & 0x00FFFFFF, cntlr.addr); + + /* + * This is a 'no data' command (like Write Enable), its + * bitesout size was 1, decremented to zero while executing + * spi_setup_opcode() above. Tell the chip to send the + * command. + */ + writew_(control, cntlr.control); + + /* wait for the result */ + status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); + if (status == -1) + return -1; + + if (status & SPIS_FCERR) { + printk(BIOS_DEBUG, "ICH SPI: Command transaction error\n"); + return -1; + } + + return 0; + } + + /* + * Check if this is a write command attempting to transfer more bytes + * than the controller can handle. Iterations for writes are not + * supported here because each SPI write command needs to be preceded + * and followed by other SPI commands, and this sequence is controlled + * by the SPI chip driver. + */ + if (trans.bytesout > cntlr.databytes) { + printk(BIOS_DEBUG, "ICH SPI: Too much to write. Does your SPI chip driver use" + " CONTROLLER_PAGE_LIMIT?\n"); + return -1; + } + + /* + * Read or write up to databytes bytes at a time until everything has + * been sent. + */ + while (trans.bytesout || trans.bytesin) { + uint32_t data_length; + + /* SPI addresses are 24 bit only */ + writel_(trans.offset & 0x00FFFFFF, cntlr.addr); + + if (trans.bytesout) + data_length = min(trans.bytesout, cntlr.databytes); + else + data_length = min(trans.bytesin, cntlr.databytes); + + /* Program data into FDATA0 to N */ + if (trans.bytesout) { + write_reg(trans.out, cntlr.data, data_length); + spi_use_out(&trans, data_length); + if (with_address) + trans.offset += data_length; + } + + /* Add proper control fields' values */ + control &= ~((cntlr.databytes - 1) << 8); + control |= SPIC_DS; + control |= (data_length - 1) << 8; + + /* write it */ + writew_(control, cntlr.control); + + /* Wait for Cycle Done Status or Flash Cycle Error. */ + status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); + if (status == -1) + return -1; + + if (status & SPIS_FCERR) { + printk(BIOS_DEBUG, "ICH SPI: Data transaction error\n"); + return -1; + } + + if (trans.bytesin) { + read_reg(cntlr.data, trans.in, data_length); + spi_use_in(&trans, data_length); + if (with_address) + trans.offset += data_length; + } + } + + /* Clear atomic preop now that xfer is done */ + writew_(0, cntlr.preop); + + return 0; +} + +/* Sets FLA in FADDR to (addr & 0x01FFFFFF) without touching other bits. */ +static void ich_hwseq_set_addr(uint32_t addr) +{ + uint32_t addr_old = readl_(&cntlr.ich9_spi->faddr) & ~0x01FFFFFF; + writel_((addr & 0x01FFFFFF) | addr_old, &cntlr.ich9_spi->faddr); +} + +/* Polls for Cycle Done Status, Flash Cycle Error or timeout in 8 us intervals. + Resets all error flags in HSFS. + Returns 0 if the cycle completes successfully without errors within + timeout us, 1 on errors. */ +static int ich_hwseq_wait_for_cycle_complete(unsigned int timeout, + unsigned int len) +{ + uint16_t hsfs; + uint32_t addr; + + timeout /= 8; /* scale timeout duration to counter */ + while ((((hsfs = readw_(&cntlr.ich9_spi->hsfs)) & + (HSFS_FDONE | HSFS_FCERR)) == 0) && + --timeout) { + udelay(8); + } + writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); + + if (!timeout) { + uint16_t hsfc; + addr = readl_(&cntlr.ich9_spi->faddr) & 0x01FFFFFF; + hsfc = readw_(&cntlr.ich9_spi->hsfc); + printk(BIOS_ERR, "Transaction timeout between offset 0x%08x and " + "0x%08x (= 0x%08x + %d) HSFC=%x HSFS=%x!\n", + addr, addr + len - 1, addr, len - 1, + hsfc, hsfs); + return 1; + } + + if (hsfs & HSFS_FCERR) { + uint16_t hsfc; + addr = readl_(&cntlr.ich9_spi->faddr) & 0x01FFFFFF; + hsfc = readw_(&cntlr.ich9_spi->hsfc); + printk(BIOS_ERR, "Transaction error between offset 0x%08x and " + "0x%08x (= 0x%08x + %d) HSFC=%x HSFS=%x!\n", + addr, addr + len - 1, addr, len - 1, + hsfc, hsfs); + return 1; + } + return 0; +} + + +static int ich_hwseq_erase(struct spi_flash *flash, u32 offset, size_t len) +{ + u32 start, end, erase_size; + int ret; + uint16_t hsfc; + uint16_t timeout = 1000 * 60; + + erase_size = flash->sector_size; + if (offset % erase_size || len % erase_size) { + printk(BIOS_ERR, "SF: Erase offset/length not multiple of erase size\n"); + return -1; + } + + flash->spi->rw = SPI_WRITE_FLAG; + ret = spi_claim_bus(flash->spi); + if (ret) { + printk(BIOS_ERR, "SF: Unable to claim SPI bus\n"); + return ret; + } + + start = offset; + end = start + len; + + while (offset < end) { + /* make sure FDONE, FCERR, AEL are cleared by writing 1 to them */ + writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); + + ich_hwseq_set_addr(offset); + + offset += erase_size; + + hsfc = readw_(&cntlr.ich9_spi->hsfc); + hsfc &= ~HSFC_FCYCLE; /* clear operation */ + hsfc |= (0x3 << HSFC_FCYCLE_OFF); /* set erase operation */ + hsfc |= HSFC_FGO; /* start */ + writew_(hsfc, &cntlr.ich9_spi->hsfc); + if (ich_hwseq_wait_for_cycle_complete(timeout, len)) + { + printk(BIOS_ERR, "SF: Erase failed at %x\n", offset - erase_size); + ret = -1; + goto out; + } + } + + printk(BIOS_DEBUG, "SF: Successfully erased %zu bytes @ %#x\n", len, start); + +out: + spi_release_bus(flash->spi); + return ret; +} + +static void ich_read_data(uint8_t *data, int len) +{ + int i; + uint32_t temp32 = 0; + + for (i = 0; i < len; i++) { + if ((i % 4) == 0) + temp32 = readl_(cntlr.data + i); + + data[i] = (temp32 >> ((i % 4) * 8)) & 0xff; + } +} + +static int ich_hwseq_read(struct spi_flash *flash, + u32 addr, size_t len, void *buf) +{ + uint16_t hsfc; + uint16_t timeout = 100 * 60; + uint8_t block_len; + + if (addr + len > flash->size) { + printk (BIOS_ERR, + "Attempt to read %x-%x which is out of chip\n", + (unsigned) addr, + (unsigned) addr+(unsigned) len); + return -1; + } + + /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ + writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); + + while (len > 0) { + block_len = min(len, cntlr.databytes); + if (block_len > (~addr & 0xff)) + block_len = (~addr & 0xff) + 1; + ich_hwseq_set_addr(addr); + hsfc = readw_(&cntlr.ich9_spi->hsfc); + hsfc &= ~HSFC_FCYCLE; /* set read operation */ + hsfc &= ~HSFC_FDBC; /* clear byte count */ + /* set byte count */ + hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); + hsfc |= HSFC_FGO; /* start */ + writew_(hsfc, &cntlr.ich9_spi->hsfc); + + if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) + return 1; + ich_read_data(buf, block_len); + addr += block_len; + buf += block_len; + len -= block_len; + } + return 0; +} + +/* Fill len bytes from the data array into the fdata/spid registers. + * + * Note that using len > flash->pgm->spi.max_data_write will trash the registers + * following the data registers. + */ +static void ich_fill_data(const uint8_t *data, int len) +{ + uint32_t temp32 = 0; + int i; + + if (len <= 0) + return; + + for (i = 0; i < len; i++) { + if ((i % 4) == 0) + temp32 = 0; + + temp32 |= ((uint32_t) data[i]) << ((i % 4) * 8); + + if ((i % 4) == 3) /* 32 bits are full, write them to regs. */ + writel_(temp32, cntlr.data + (i - (i % 4))); + } + i--; + if ((i % 4) != 3) /* Write remaining data to regs. */ + writel_(temp32, cntlr.data + (i - (i % 4))); +} + +static int ich_hwseq_write(struct spi_flash *flash, + u32 addr, size_t len, const void *buf) +{ + uint16_t hsfc; + uint16_t timeout = 100 * 60; + uint8_t block_len; + uint32_t start = addr; + + if (addr + len > flash->size) { + printk (BIOS_ERR, + "Attempt to write 0x%x-0x%x which is out of chip\n", + (unsigned)addr, (unsigned) (addr+len)); + return -1; + } + + /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ + writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); + + while (len > 0) { + block_len = min(len, cntlr.databytes); + if (block_len > (~addr & 0xff)) + block_len = (~addr & 0xff) + 1; + + ich_hwseq_set_addr(addr); + + ich_fill_data(buf, block_len); + hsfc = readw_(&cntlr.ich9_spi->hsfc); + hsfc &= ~HSFC_FCYCLE; /* clear operation */ + hsfc |= (0x2 << HSFC_FCYCLE_OFF); /* set write operation */ + hsfc &= ~HSFC_FDBC; /* clear byte count */ + /* set byte count */ + hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); + hsfc |= HSFC_FGO; /* start */ + writew_(hsfc, &cntlr.ich9_spi->hsfc); + + if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) + { + printk (BIOS_ERR, "SF: write failure at %x\n", + addr); + return -1; + } + addr += block_len; + buf += block_len; + len -= block_len; + } + printk(BIOS_DEBUG, "SF: Successfully written %u bytes @ %#x\n", + (unsigned) (addr - start), start); + return 0; +} + + +static struct spi_flash *spi_flash_hwseq(struct spi_slave *spi) +{ + struct spi_flash *flash = NULL; + uint32_t flcomp; + + flash = malloc(sizeof(*flash)); + if (!flash) { + printk(BIOS_WARNING, "SF: Failed to allocate memory\n"); + return NULL; + } + + flash->spi = spi; + flash->name = "Opaque HW-sequencing"; + + flash->write = ich_hwseq_write; + flash->erase = ich_hwseq_erase; + flash->read = ich_hwseq_read; + ich_hwseq_set_addr (0); + switch ((cntlr.hsfs >> 3) & 3) + { + case 0: + flash->sector_size = 256; + break; + case 1: + flash->sector_size = 4096; + break; + case 2: + flash->sector_size = 8192; + break; + case 3: + flash->sector_size = 65536; + break; + } + + writel_ (0x1000, &cntlr.ich9_spi->fdoc); + flcomp = readl_(&cntlr.ich9_spi->fdod); + + flash->size = 1 << (19 + (flcomp & 7)); + + if ((cntlr.hsfs & HSFS_FDV) && ((cntlr.flmap0 >> 8) & 3)) + flash->size += 1 << (19 + ((flcomp >> 3) & 7)); + printk (BIOS_DEBUG, "flash size 0x%x bytes\n", flash->size); + + return flash; +} diff --git a/src/southbridge/intel/fsp_bd82x6x/Makefile.inc b/src/southbridge/intel/fsp_bd82x6x/Makefile.inc index dac1241..19c66a9 100644 --- a/src/southbridge/intel/fsp_bd82x6x/Makefile.inc +++ b/src/southbridge/intel/fsp_bd82x6x/Makefile.inc @@ -36,8 +36,8 @@ ramstage-y += reset.c ramstage-y += watchdog.c ramstage-$(CONFIG_ELOG) += elog.c -ramstage-y += spi.c -smm-$(CONFIG_SPI_FLASH_SMM) += spi.c +ramstage-y += ../spi.c +smm-$(CONFIG_SPI_FLASH_SMM) += ../spi.c ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c me.c me_8.x.c finalize.c diff --git a/src/southbridge/intel/fsp_bd82x6x/spi.c b/src/southbridge/intel/fsp_bd82x6x/spi.c deleted file mode 100644 index 887463a..0000000 --- a/src/southbridge/intel/fsp_bd82x6x/spi.c +++ /dev/null @@ -1,751 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* This file is derived from the flashrom project. */ -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <delay.h> -#include <arch/io.h> -#include <console/console.h> -#include <device/pci_ids.h> - -#include <spi-generic.h> - -static int ich_status_poll(u16 bitmask, int wait_til_set); - -#define min(a, b) ((a)<(b)?(a):(b)) - -#ifdef __SMM__ -#include <arch/pci_mmio_cfg.h> -#define pci_read_config_byte(dev, reg, targ)\ - *(targ) = pci_read_config8(dev, reg) -#define pci_read_config_word(dev, reg, targ)\ - *(targ) = pci_read_config16(dev, reg) -#define pci_read_config_dword(dev, reg, targ)\ - *(targ) = pci_read_config32(dev, reg) -#define pci_write_config_byte(dev, reg, val)\ - pci_write_config8(dev, reg, val) -#define pci_write_config_word(dev, reg, val)\ - pci_write_config16(dev, reg, val) -#define pci_write_config_dword(dev, reg, val)\ - pci_write_config32(dev, reg, val) -#else /* !__SMM__ */ -#include <device/device.h> -#include <device/pci.h> -#define pci_read_config_byte(dev, reg, targ)\ - *(targ) = pci_read_config8(dev, reg) -#define pci_read_config_word(dev, reg, targ)\ - *(targ) = pci_read_config16(dev, reg) -#define pci_read_config_dword(dev, reg, targ)\ - *(targ) = pci_read_config32(dev, reg) -#define pci_write_config_byte(dev, reg, val)\ - pci_write_config8(dev, reg, val) -#define pci_write_config_word(dev, reg, val)\ - pci_write_config16(dev, reg, val) -#define pci_write_config_dword(dev, reg, val)\ - pci_write_config32(dev, reg, val) -#endif /* !__SMM__ */ - -typedef struct spi_slave ich_spi_slave; - -static int ichspi_lock = 0; - -typedef struct ich7_spi_regs { - uint16_t spis; - uint16_t spic; - uint32_t spia; - uint64_t spid[8]; - uint64_t _pad; - uint32_t bbar; - uint16_t preop; - uint16_t optype; - uint8_t opmenu[8]; -} __attribute__((packed)) ich7_spi_regs; - -typedef struct ich9_spi_regs { - uint32_t bfpr; // 0 - uint16_t hsfs; // 4 - uint16_t hsfc; // 6 - uint32_t faddr; // 8 - uint32_t _reserved0; // 0xC - uint32_t fdata[16]; // 0x10 - uint32_t frap; // 0x50 - uint32_t freg[5]; // 0x54 - uint32_t _reserved1[3]; // 0x67 - uint32_t pr[5]; // 0x74 - uint32_t _reserved2[2]; // 0x88 - uint8_t ssfs; // 0x90 - uint8_t ssfc[3]; // 0x91 - uint16_t preop; // 0x94 - uint16_t optype; // 0x96 - uint8_t opmenu[8]; // 0x98 - uint32_t bbar; // 0xB0 - uint8_t _reserved3[12]; - uint32_t fdoc; - uint32_t fdod; - uint8_t _reserved4[8]; - uint32_t afc; - uint32_t lvscc; - uint32_t uvscc; - uint8_t _reserved5[4]; - uint32_t fpb; - uint8_t _reserved6[28]; - uint32_t srdl; - uint32_t srdc; - uint32_t srd; -} __attribute__((packed)) ich9_spi_regs; - -typedef struct ich_spi_controller { - int locked; - - uint8_t *opmenu; - int menubytes; - uint16_t *preop; - uint16_t *optype; - uint32_t *addr; - uint8_t *data; - unsigned databytes; - uint8_t *status; - uint16_t *control; - uint32_t *bbar; -} ich_spi_controller; - -static ich_spi_controller cntlr; - -enum { - SPIS_SCIP = 0x0001, - SPIS_GRANT = 0x0002, - SPIS_CDS = 0x0004, - SPIS_FCERR = 0x0008, - SSFS_AEL = 0x0010, - SPIS_LOCK = 0x8000, - SPIS_RESERVED_MASK = 0x7ff0, - SSFS_RESERVED_MASK = 0x7fe2 -}; - -enum { - SPIC_SCGO = 0x000002, - SPIC_ACS = 0x000004, - SPIC_SPOP = 0x000008, - SPIC_DBC = 0x003f00, - SPIC_DS = 0x004000, - SPIC_SME = 0x008000, - SSFC_SCF_MASK = 0x070000, - SSFC_RESERVED = 0xf80000 -}; - -enum { - HSFS_FDONE = 0x0001, - HSFS_FCERR = 0x0002, - HSFS_AEL = 0x0004, - HSFS_BERASE_MASK = 0x0018, - HSFS_BERASE_SHIFT = 3, - HSFS_SCIP = 0x0020, - HSFS_FDOPSS = 0x2000, - HSFS_FDV = 0x4000, - HSFS_FLOCKDN = 0x8000 -}; - -enum { - HSFC_FGO = 0x0001, - HSFC_FCYCLE_MASK = 0x0006, - HSFC_FCYCLE_SHIFT = 1, - HSFC_FDBC_MASK = 0x3f00, - HSFC_FDBC_SHIFT = 8, - HSFC_FSMIE = 0x8000 -}; - -enum { - SPI_OPCODE_TYPE_READ_NO_ADDRESS = 0, - SPI_OPCODE_TYPE_WRITE_NO_ADDRESS = 1, - SPI_OPCODE_TYPE_READ_WITH_ADDRESS = 2, - SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3, -}; - -#if CONFIG_DEBUG_SPI_FLASH - -static u8 readb_(const void *addr) -{ - u8 v = read8((unsigned long)addr); - printk(BIOS_DEBUG, "read %02x from %p\n", - v, addr); - return v; -} - -static u16 readw_(const void *addr) -{ - u16 v = read16((unsigned long)addr); - printk(BIOS_DEBUG, "read %04x from %p\n", - v, addr); - return v; -} - -static u32 readl_(const void *addr) -{ - u32 v = read32((unsigned long)addr); - printk(BIOS_DEBUG, "read %08x from %p\n", - v, addr); - return v; -} - -static void writeb_(u8 b, const void *addr) -{ - write8((unsigned long)addr, b); - printk(BIOS_DEBUG, "wrote %02x to %p\n", - b, addr); -} - -static void writew_(u16 b, const void *addr) -{ - write16((unsigned long)addr, b); - printk(BIOS_DEBUG, "wrote %04x to %p\n", - b, addr); -} - -static void writel_(u32 b, const void *addr) -{ - write32((unsigned long)addr, b); - printk(BIOS_DEBUG, "wrote %08x to %p\n", - b, addr); -} - -#else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled vvv NOT enabled */ - -#define readb_(a) read8((uint32_t)a) -#define readw_(a) read16((uint32_t)a) -#define readl_(a) read32((uint32_t)a) -#define writeb_(val, addr) write8((uint32_t)addr, val) -#define writew_(val, addr) write16((uint32_t)addr, val) -#define writel_(val, addr) write32((uint32_t)addr, val) - -#endif /* CONFIG_DEBUG_SPI_FLASH ^^^ NOT enabled */ - -static void write_reg(const void *value, void *dest, uint32_t size) -{ - const uint8_t *bvalue = value; - uint8_t *bdest = dest; - - while (size >= 4) { - writel_(*(const uint32_t *)bvalue, bdest); - bdest += 4; bvalue += 4; size -= 4; - } - while (size) { - writeb_(*bvalue, bdest); - bdest++; bvalue++; size--; - } -} - -static void read_reg(const void *src, void *value, uint32_t size) -{ - const uint8_t *bsrc = src; - uint8_t *bvalue = value; - - while (size >= 4) { - *(uint32_t *)bvalue = readl_(bsrc); - bsrc += 4; bvalue += 4; size -= 4; - } - while (size) { - *bvalue = readb_(bsrc); - bsrc++; bvalue++; size--; - } -} - -static void ich_set_bbar(uint32_t minaddr) -{ - const uint32_t bbar_mask = 0x00ffff00; - uint32_t ichspi_bbar; - - minaddr &= bbar_mask; - ichspi_bbar = readl_(cntlr.bbar) & ~bbar_mask; - ichspi_bbar |= minaddr; - writel_(ichspi_bbar, cntlr.bbar); -} - -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - printk(BIOS_DEBUG, "spi_cs_is_valid used but not implemented\n"); - return 0; -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - ich_spi_slave *slave = malloc(sizeof(*slave)); - - if (!slave) { - printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n"); - return NULL; - } - - memset(slave, 0, sizeof(*slave)); - - slave->bus = bus; - slave->cs = cs; - return slave; -} - -/* - * Check if this device ID matches one of supported Intel PCH devices. - * - * Return the ICH version if there is a match, or zero otherwise. - */ -static inline int get_ich_version(uint16_t device_id) -{ - if (device_id == PCI_DEVICE_ID_INTEL_TGP_LPC) - return 7; - - if ((device_id >= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN && - device_id <= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX) || - (device_id >= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN && - device_id <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX)) - return 9; - - return 0; -} - -void spi_init(void) -{ - int ich_version = 0; - - uint8_t *rcrb; /* Root Complex Register Block */ - uint32_t rcba; /* Root Complex Base Address */ - uint8_t bios_cntl; - device_t dev; - uint32_t ids; - uint16_t vendor_id, device_id; - -#ifdef __SMM__ - dev = PCI_DEV(0, 31, 0); -#else - dev = dev_find_slot(0, PCI_DEVFN(31, 0)); -#endif - pci_read_config_dword(dev, 0, &ids); - vendor_id = ids; - device_id = (ids >> 16); - - if (vendor_id != PCI_VENDOR_ID_INTEL) { - printk(BIOS_DEBUG, "ICH SPI: No ICH found.\n"); - return; - } - - ich_version = get_ich_version(device_id); - - if (!ich_version) { - printk(BIOS_DEBUG, "ICH SPI: No known ICH found.\n"); - return; - } - - pci_read_config_dword(dev, 0xf0, &rcba); - /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable. */ - rcrb = (uint8_t *)(rcba & 0xffffc000); - switch (ich_version) { - case 7: - { - const uint16_t ich7_spibar_offset = 0x3020; - ich7_spi_regs *ich7_spi = - (ich7_spi_regs *)(rcrb + ich7_spibar_offset); - - ichspi_lock = readw_(&ich7_spi->spis) & SPIS_LOCK; - cntlr.opmenu = ich7_spi->opmenu; - cntlr.menubytes = sizeof(ich7_spi->opmenu); - cntlr.optype = &ich7_spi->optype; - cntlr.addr = &ich7_spi->spia; - cntlr.data = (uint8_t *)ich7_spi->spid; - cntlr.databytes = sizeof(ich7_spi->spid); - cntlr.status = (uint8_t *)&ich7_spi->spis; - cntlr.control = &ich7_spi->spic; - cntlr.bbar = &ich7_spi->bbar; - cntlr.preop = &ich7_spi->preop; - break; - } - case 9: - { - const uint16_t ich9_spibar_offset = 0x3800; - ich9_spi_regs *ich9_spi = - (ich9_spi_regs *)(rcrb + ich9_spibar_offset); - ichspi_lock = readw_(&ich9_spi->hsfs) & HSFS_FLOCKDN; - cntlr.opmenu = ich9_spi->opmenu; - cntlr.menubytes = sizeof(ich9_spi->opmenu); - cntlr.optype = &ich9_spi->optype; - cntlr.addr = &ich9_spi->faddr; - cntlr.data = (uint8_t *)ich9_spi->fdata; - cntlr.databytes = sizeof(ich9_spi->fdata); - cntlr.status = &ich9_spi->ssfs; - cntlr.control = (uint16_t *)ich9_spi->ssfc; - cntlr.bbar = &ich9_spi->bbar; - cntlr.preop = &ich9_spi->preop; - break; - } - default: - printk(BIOS_DEBUG, "ICH SPI: Unrecognized ICH version %d.\n", ich_version); - } - - ich_set_bbar(0); - - /* Disable the BIOS write protect so write commands are allowed. */ - pci_read_config_byte(dev, 0xdc, &bios_cntl); - switch (ich_version) { - case 9: - /* Deassert SMM BIOS Write Protect Disable. */ - bios_cntl &= ~(1 << 5); - break; - - default: - break; - } - pci_write_config_byte(dev, 0xdc, bios_cntl | 0x1); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - -void spi_cs_activate(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - -void spi_cs_deactivate(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - -typedef struct spi_transaction { - const uint8_t *out; - uint32_t bytesout; - uint8_t *in; - uint32_t bytesin; - uint8_t type; - uint8_t opcode; - uint32_t offset; -} spi_transaction; - -static inline void spi_use_out(spi_transaction *trans, unsigned bytes) -{ - trans->out += bytes; - trans->bytesout -= bytes; -} - -static inline void spi_use_in(spi_transaction *trans, unsigned bytes) -{ - trans->in += bytes; - trans->bytesin -= bytes; -} - -static void spi_setup_type(spi_transaction *trans) -{ - trans->type = 0xFF; - - /* Try to guess spi type from read/write sizes. */ - if (trans->bytesin == 0) { - if (trans->bytesout >= 4) - /* - * If bytesin = 0 and bytesout > 4, we presume this is - * a write data operation, which is accompanied by an - * address. - */ - trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS; - else - trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS; - return; - } - - if (trans->bytesout == 1) { /* and bytesin is > 0 */ - trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS; - return; - } - - if (trans->bytesout == 4) { /* and bytesin is > 0 */ - trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; - } - - /* Fast read command is called with 5 bytes instead of 4 */ - if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) { - trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; - --trans->bytesout; - } -} - -static int spi_setup_opcode(spi_transaction *trans) -{ - uint16_t optypes; - uint8_t opmenu[cntlr.menubytes]; - - trans->opcode = trans->out[0]; - - /* Write Enable is handled as atomic prefix */ - if (trans->opcode == SPI_OPCODE_WREN) - return 0; - - spi_use_out(trans, 1); - if (!ichspi_lock) { - /* The lock is off, so just use index 0. */ - writeb_(trans->opcode, cntlr.opmenu); - optypes = readw_(cntlr.optype); - optypes = (optypes & 0xfffc) | (trans->type & 0x3); - writew_(optypes, cntlr.optype); - return 0; - } else { - /* The lock is on. See if what we need is on the menu. */ - uint8_t optype; - uint16_t opcode_index; - - read_reg(cntlr.opmenu, opmenu, sizeof(opmenu)); - for (opcode_index = 0; opcode_index < cntlr.menubytes; - opcode_index++) { - if (opmenu[opcode_index] == trans->opcode) - break; - } - - if (opcode_index == cntlr.menubytes) { - printk(BIOS_DEBUG, "ICH SPI: Opcode %x not found\n", - trans->opcode); - return -1; - } - - optypes = readw_(cntlr.optype); - optype = (optypes >> (opcode_index * 2)) & 0x3; - if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS && - optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS && - trans->bytesout >= 3) { - /* We guessed wrong earlier. Fix it up. */ - trans->type = optype; - } - if (optype != trans->type) { - printk(BIOS_DEBUG, "ICH SPI: Transaction doesn't fit type %d\n", - optype); - return -1; - } - return opcode_index; - } -} - -static int spi_setup_offset(spi_transaction *trans) -{ - /* Separate the SPI address and data. */ - switch (trans->type) { - case SPI_OPCODE_TYPE_READ_NO_ADDRESS: - case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS: - return 0; - case SPI_OPCODE_TYPE_READ_WITH_ADDRESS: - case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS: - trans->offset = ((uint32_t)trans->out[0] << 16) | - ((uint32_t)trans->out[1] << 8) | - ((uint32_t)trans->out[2] << 0); - spi_use_out(trans, 3); - return 1; - default: - printk(BIOS_DEBUG, "Unrecognized SPI transaction type %#x\n", trans->type); - return -1; - } -} - -/* - * Wait for up to 60ms til status register bit(s) turn 1 (in case wait_til_set - * below is True) or 0. In case the wait was for the bit(s) to set - write - * those bits back, which would cause resetting them. - * - * Return the last read status value on success or -1 on failure. - */ -static int ich_status_poll(u16 bitmask, int wait_til_set) -{ - int timeout = 6000; /* This will result in 60 ms */ - u16 status = 0; - - while (timeout--) { - status = readb_(cntlr.status); - if (wait_til_set ^ ((status & bitmask) == 0)) { - if (wait_til_set) - writeb_((status & bitmask), cntlr.status); - return status; - } - udelay(10); - } - - printk(BIOS_DEBUG, "ICH SPI: SCIP timeout, read %x, expected %x\n", - status, bitmask); - return -1; -} - -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bitsout, void *din, unsigned int bitsin) -{ - uint16_t control; - int16_t opcode_index; - int with_address; - int status; - - spi_transaction trans = { - dout, bitsout / 8, - din, bitsin / 8, - 0xff, 0xff, 0 - }; - - /* There has to always at least be an opcode. */ - if (!bitsout || !dout) { - printk(BIOS_DEBUG, "ICH SPI: No opcode for transfer\n"); - return -1; - } - /* Make sure if we read something we have a place to put it. */ - if (bitsin != 0 && !din) { - printk(BIOS_DEBUG, "ICH SPI: Read but no target buffer\n"); - return -1; - } - /* Right now we don't support writing partial bytes. */ - if (bitsout % 8 || bitsin % 8) { - printk(BIOS_DEBUG, "ICH SPI: Accessing partial bytes not supported\n"); - return -1; - } - - if (ich_status_poll(SPIS_SCIP, 0) == -1) - return -1; - - writew_(SPIS_CDS | SPIS_FCERR, cntlr.status); - - spi_setup_type(&trans); - if ((opcode_index = spi_setup_opcode(&trans)) < 0) - return -1; - if ((with_address = spi_setup_offset(&trans)) < 0) - return -1; - - if (trans.opcode == SPI_OPCODE_WREN) { - /* - * Treat Write Enable as Atomic Pre-Op if possible - * in order to prevent the Management Engine from - * issuing a transaction between WREN and DATA. - */ - if (!ichspi_lock) - writew_(trans.opcode, cntlr.preop); - - return 0; - } - - /* Preset control fields */ - control = SPIC_SCGO | ((opcode_index & 0x07) << 4); - - /* Issue atomic preop cycle if needed */ - if (readw_(cntlr.preop)) - control |= SPIC_ACS; - - if (!trans.bytesout && !trans.bytesin) { - /* SPI addresses are 24 bit only */ - if (with_address) - writel_(trans.offset & 0x00FFFFFF, cntlr.addr); - - /* - * This is a 'no data' command (like Write Enable), its - * bitesout size was 1, decremented to zero while executing - * spi_setup_opcode() above. Tell the chip to send the - * command. - */ - writew_(control, cntlr.control); - - /* wait for the result */ - status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); - if (status == -1) - return -1; - - if (status & SPIS_FCERR) { - printk(BIOS_DEBUG, "ICH SPI: Command transaction error\n"); - return -1; - } - - goto spi_xfer_exit; - } - - /* - * Check if this is a write command attempting to transfer more bytes - * than the controller can handle. Iterations for writes are not - * supported here because each SPI write command needs to be preceded - * and followed by other SPI commands, and this sequence is controlled - * by the SPI chip driver. - */ - if (trans.bytesout > cntlr.databytes) { - printk(BIOS_DEBUG, "ICH SPI: Too much to write. Does your SPI chip driver use" - " CONTROLLER_PAGE_LIMIT?\n"); - return -1; - } - - /* - * Read or write up to databytes bytes at a time until everything has - * been sent. - */ - while (trans.bytesout || trans.bytesin) { - uint32_t data_length; - - /* SPI addresses are 24 bit only */ - if (with_address) - writel_(trans.offset & 0x00FFFFFF, cntlr.addr); - - if (trans.bytesout) - data_length = min(trans.bytesout, cntlr.databytes); - else - data_length = min(trans.bytesin, cntlr.databytes); - - /* Program data into FDATA0 to N */ - if (trans.bytesout) { - write_reg(trans.out, cntlr.data, data_length); - spi_use_out(&trans, data_length); - if (with_address) - trans.offset += data_length; - } - - /* Add proper control fields' values */ - control &= ~((cntlr.databytes - 1) << 8); - control |= SPIC_DS; - control |= (data_length - 1) << 8; - - /* write it */ - writew_(control, cntlr.control); - - /* Wait for Cycle Done Status or Flash Cycle Error. */ - status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); - if (status == -1) - return -1; - - if (status & SPIS_FCERR) { - printk(BIOS_DEBUG, "ICH SPI: Data transaction error\n"); - return -1; - } - - if (trans.bytesin) { - read_reg(cntlr.data, trans.in, data_length + 1); - spi_use_in(&trans, data_length); - if (with_address) - trans.offset += data_length; - } - } - -spi_xfer_exit: - /* Clear atomic preop now that xfer is done */ - writew_(0, cntlr.preop); - - return 0; -} diff --git a/src/southbridge/intel/ibexpeak/Makefile.inc b/src/southbridge/intel/ibexpeak/Makefile.inc index e7f7d99a..da9f34a 100644 --- a/src/southbridge/intel/ibexpeak/Makefile.inc +++ b/src/southbridge/intel/ibexpeak/Makefile.inc @@ -39,8 +39,8 @@ ramstage-y += ../bd82x6x/reset.c ramstage-y += ../bd82x6x/watchdog.c ramstage-$(CONFIG_ELOG) += ../bd82x6x/elog.c -ramstage-y += spi.c -smm-$(CONFIG_SPI_FLASH_SMM) += spi.c +ramstage-y += ../common/spi.c +smm-$(CONFIG_SPI_FLASH_SMM) += ../common/spi.c ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c me.c ../bd82x6x/me_8.x.c ../bd82x6x/finalize.c ../bd82x6x/pch.c diff --git a/src/southbridge/intel/ibexpeak/spi.c b/src/southbridge/intel/ibexpeak/spi.c deleted file mode 100644 index 7080fe1..0000000 --- a/src/southbridge/intel/ibexpeak/spi.c +++ /dev/null @@ -1,1067 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * Copyright (C) 2009, 2010 Carl-Daniel Hailfinger - * Copyright (C) 2011 Stefan Tauner - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* This file is derived from the flashrom project. */ -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <delay.h> -#include <arch/io.h> -#include <console/console.h> -#include <device/pci_ids.h> -#include <device/pci.h> -#include <spi_flash.h> - -#include <spi-generic.h> -#include "pch.h" - -#define min(a, b) ((a)<(b)?(a):(b)) - -#define HSFC_FCYCLE_OFF 1 /* 1-2: FLASH Cycle */ -#define HSFC_FCYCLE (0x3 << HSFC_FCYCLE_OFF) -#define HSFC_FDBC_OFF 8 /* 8-13: Flash Data Byte Count */ -#define HSFC_FDBC (0x3f << HSFC_FDBC_OFF) - - -#ifdef __SMM__ -#include <arch/pci_mmio_cfg.h> -#define pci_read_config_byte(dev, reg, targ)\ - *(targ) = pci_read_config8(dev, reg) -#define pci_read_config_word(dev, reg, targ)\ - *(targ) = pci_read_config16(dev, reg) -#define pci_read_config_dword(dev, reg, targ)\ - *(targ) = pci_read_config32(dev, reg) -#define pci_write_config_byte(dev, reg, val)\ - pci_write_config8(dev, reg, val) -#define pci_write_config_word(dev, reg, val)\ - pci_write_config16(dev, reg, val) -#define pci_write_config_dword(dev, reg, val)\ - pci_write_config32(dev, reg, val) -#else /* !__SMM__ */ -#include <device/device.h> -#include <device/pci.h> -#define pci_read_config_byte(dev, reg, targ)\ - *(targ) = pci_read_config8(dev, reg) -#define pci_read_config_word(dev, reg, targ)\ - *(targ) = pci_read_config16(dev, reg) -#define pci_read_config_dword(dev, reg, targ)\ - *(targ) = pci_read_config32(dev, reg) -#define pci_write_config_byte(dev, reg, val)\ - pci_write_config8(dev, reg, val) -#define pci_write_config_word(dev, reg, val)\ - pci_write_config16(dev, reg, val) -#define pci_write_config_dword(dev, reg, val)\ - pci_write_config32(dev, reg, val) -#endif /* !__SMM__ */ - -static int spi_is_multichip(void); -static struct spi_flash *spi_flash_hwseq(struct spi_slave *spi); - -typedef struct spi_slave ich_spi_slave; - -static int ichspi_lock = 0; - -typedef struct ich7_spi_regs { - uint16_t spis; - uint16_t spic; - uint32_t spia; - uint64_t spid[8]; - uint64_t _pad; - uint32_t bbar; - uint16_t preop; - uint16_t optype; - uint8_t opmenu[8]; -} __attribute__((packed)) ich7_spi_regs; - -typedef struct ich9_spi_regs { - uint32_t bfpr; - uint16_t hsfs; - uint16_t hsfc; - uint32_t faddr; - uint32_t _reserved0; - uint32_t fdata[16]; - uint32_t frap; - uint32_t freg[5]; - uint32_t _reserved1[3]; - uint32_t pr[5]; - uint32_t _reserved2[2]; - uint8_t ssfs; - uint8_t ssfc[3]; - uint16_t preop; - uint16_t optype; - uint8_t opmenu[8]; - uint32_t bbar; - uint8_t _reserved3[12]; - uint32_t fdoc; - uint32_t fdod; - uint8_t _reserved4[8]; - uint32_t afc; - uint32_t lvscc; - uint32_t uvscc; - uint8_t _reserved5[4]; - uint32_t fpb; - uint8_t _reserved6[28]; - uint32_t srdl; - uint32_t srdc; - uint32_t srd; -} __attribute__((packed)) ich9_spi_regs; - -typedef struct ich_spi_controller { - int locked; - int revision; - uint32_t flmap0; - uint32_t hsfs; - - ich9_spi_regs *ich9_spi; - uint8_t *opmenu; - int menubytes; - uint16_t *preop; - uint16_t *optype; - uint32_t *addr; - uint8_t *data; - unsigned databytes; - uint8_t *status; - uint16_t *control; - uint32_t *bbar; -} ich_spi_controller; - -static ich_spi_controller cntlr; - -enum { - SPIS_SCIP = 0x0001, - SPIS_GRANT = 0x0002, - SPIS_CDS = 0x0004, - SPIS_FCERR = 0x0008, - SSFS_AEL = 0x0010, - SPIS_LOCK = 0x8000, - SPIS_RESERVED_MASK = 0x7ff0, - SSFS_RESERVED_MASK = 0x7fe2 -}; - -enum { - SPIC_SCGO = 0x000002, - SPIC_ACS = 0x000004, - SPIC_SPOP = 0x000008, - SPIC_DBC = 0x003f00, - SPIC_DS = 0x004000, - SPIC_SME = 0x008000, - SSFC_SCF_MASK = 0x070000, - SSFC_RESERVED = 0xf80000 -}; - -enum { - HSFS_FDONE = 0x0001, - HSFS_FCERR = 0x0002, - HSFS_AEL = 0x0004, - HSFS_BERASE_MASK = 0x0018, - HSFS_BERASE_SHIFT = 3, - HSFS_SCIP = 0x0020, - HSFS_FDOPSS = 0x2000, - HSFS_FDV = 0x4000, - HSFS_FLOCKDN = 0x8000 -}; - -enum { - HSFC_FGO = 0x0001, - HSFC_FCYCLE_MASK = 0x0006, - HSFC_FCYCLE_SHIFT = 1, - HSFC_FDBC_MASK = 0x3f00, - HSFC_FDBC_SHIFT = 8, - HSFC_FSMIE = 0x8000 -}; - -enum { - SPI_OPCODE_TYPE_READ_NO_ADDRESS = 0, - SPI_OPCODE_TYPE_WRITE_NO_ADDRESS = 1, - SPI_OPCODE_TYPE_READ_WITH_ADDRESS = 2, - SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3 -}; - -#if CONFIG_DEBUG_SPI_FLASH - -static u8 readb_(const void *addr) -{ - u8 v = read8((unsigned long)addr); - printk(BIOS_DEBUG, "read %2.2x from %4.4x\n", - v, ((unsigned) addr & 0xffff) - 0xf020); - return v; -} - -static u16 readw_(const void *addr) -{ - u16 v = read16((unsigned long)addr); - printk(BIOS_DEBUG, "read %4.4x from %4.4x\n", - v, ((unsigned) addr & 0xffff) - 0xf020); - return v; -} - -static u32 readl_(const void *addr) -{ - u32 v = read32((unsigned long)addr); - printk(BIOS_DEBUG, "read %8.8x from %4.4x\n", - v, ((unsigned) addr & 0xffff) - 0xf020); - return v; -} - -static void writeb_(u8 b, const void *addr) -{ - write8((unsigned long)addr, b); - printk(BIOS_DEBUG, "wrote %2.2x to %4.4x\n", - b, ((unsigned) addr & 0xffff) - 0xf020); -} - -static void writew_(u16 b, const void *addr) -{ - write16((unsigned long)addr, b); - printk(BIOS_DEBUG, "wrote %4.4x to %4.4x\n", - b, ((unsigned) addr & 0xffff) - 0xf020); -} - -static void writel_(u32 b, const void *addr) -{ - write32((unsigned long)addr, b); - printk(BIOS_DEBUG, "wrote %8.8x to %4.4x\n", - b, ((unsigned) addr & 0xffff) - 0xf020); -} - -#else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled vvv NOT enabled */ - -#define readb_(a) read8((uint32_t)a) -#define readw_(a) read16((uint32_t)a) -#define readl_(a) read32((uint32_t)a) -#define writeb_(val, addr) write8((uint32_t)addr, val) -#define writew_(val, addr) write16((uint32_t)addr, val) -#define writel_(val, addr) write32((uint32_t)addr, val) - -#endif /* CONFIG_DEBUG_SPI_FLASH ^^^ NOT enabled */ - -static void write_reg(const void *value, void *dest, uint32_t size) -{ - const uint8_t *bvalue = value; - uint8_t *bdest = dest; - - while (size >= 4) { - writel_(*(const uint32_t *)bvalue, bdest); - bdest += 4; bvalue += 4; size -= 4; - } - while (size) { - writeb_(*bvalue, bdest); - bdest++; bvalue++; size--; - } -} - -static void read_reg(const void *src, void *value, uint32_t size) -{ - const uint8_t *bsrc = src; - uint8_t *bvalue = value; - - while (size >= 4) { - *(uint32_t *)bvalue = readl_(bsrc); - bsrc += 4; bvalue += 4; size -= 4; - } - while (size) { - *bvalue = readb_(bsrc); - bsrc++; bvalue++; size--; - } -} - -static void ich_set_bbar(uint32_t minaddr) -{ - const uint32_t bbar_mask = 0x00ffff00; - uint32_t ichspi_bbar; - - minaddr &= bbar_mask; - ichspi_bbar = readl_(cntlr.bbar) & ~bbar_mask; - ichspi_bbar |= minaddr; - writel_(ichspi_bbar, cntlr.bbar); -} - -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - printk(BIOS_DEBUG, "spi_cs_is_valid used but not implemented\n"); - return 0; -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - ich_spi_slave *slave = malloc(sizeof(*slave)); - - if (!slave) { - printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n"); - return NULL; - } - - memset(slave, 0, sizeof(*slave)); - - slave->bus = bus; - slave->cs = cs; - if (cntlr.revision == 9) { - slave->force_programmer_specific = spi_is_multichip (); - slave->programmer_specific_probe = spi_flash_hwseq; - } - return slave; -} - -/* - * Check if this device ID matches one of supported Intel PCH devices. - * - * Return the ICH version if there is a match, or zero otherwise. - */ -static inline int get_ich_version(uint16_t device_id) -{ - if (device_id == PCI_DEVICE_ID_INTEL_TGP_LPC) - return 7; - - if ((device_id >= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN && - device_id <= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX) || - (device_id >= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN && - device_id <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX) - || device_id == 0x3b07) - return 9; - - return 0; -} - -void spi_init(void) -{ - int ich_version = 0; - - uint8_t *rcrb; /* Root Complex Register Block */ - uint32_t rcba; /* Root Complex Base Address */ - uint8_t bios_cntl; - device_t dev; - uint32_t ids; - uint16_t vendor_id, device_id; - -#ifdef __SMM__ - dev = PCI_DEV(0, 31, 0); -#else - dev = dev_find_slot(0, PCI_DEVFN(31, 0)); -#endif - pci_read_config_dword(dev, 0, &ids); - vendor_id = ids; - device_id = (ids >> 16); - - if (vendor_id != PCI_VENDOR_ID_INTEL) { - printk(BIOS_DEBUG, "ICH SPI: No ICH found.\n"); - return; - } - - ich_version = get_ich_version(device_id); - - if (!ich_version) { - printk(BIOS_DEBUG, "ICH SPI: No known ICH found.\n"); - return; - } - - pci_read_config_dword(dev, 0xf0, &rcba); - /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable. */ - rcrb = (uint8_t *)(rcba & 0xffffc000); - cntlr.revision = ich_version; - switch (ich_version) { - case 7: - { - const uint16_t ich7_spibar_offset = 0x3020; - ich7_spi_regs *ich7_spi = - (ich7_spi_regs *)(rcrb + ich7_spibar_offset); - - ichspi_lock = readw_(&ich7_spi->spis) & SPIS_LOCK; - cntlr.opmenu = ich7_spi->opmenu; - cntlr.menubytes = sizeof(ich7_spi->opmenu); - cntlr.optype = &ich7_spi->optype; - cntlr.addr = &ich7_spi->spia; - cntlr.data = (uint8_t *)ich7_spi->spid; - cntlr.databytes = sizeof(ich7_spi->spid); - cntlr.status = (uint8_t *)&ich7_spi->spis; - cntlr.control = &ich7_spi->spic; - cntlr.bbar = &ich7_spi->bbar; - cntlr.preop = &ich7_spi->preop; - break; - } - case 9: - { - const uint16_t ich9_spibar_offset = 0x3800; - ich9_spi_regs *ich9_spi = - (ich9_spi_regs *)(rcrb + ich9_spibar_offset); - uint16_t hsfs; - cntlr.ich9_spi = ich9_spi; - hsfs = readw_(&ich9_spi->hsfs); - ichspi_lock = hsfs & HSFS_FLOCKDN; - cntlr.hsfs = hsfs; - cntlr.opmenu = ich9_spi->opmenu; - cntlr.menubytes = sizeof(ich9_spi->opmenu); - cntlr.optype = &ich9_spi->optype; - cntlr.addr = &ich9_spi->faddr; - cntlr.data = (uint8_t *)ich9_spi->fdata; - cntlr.databytes = sizeof(ich9_spi->fdata); - cntlr.status = &ich9_spi->ssfs; - cntlr.control = (uint16_t *)ich9_spi->ssfc; - cntlr.bbar = &ich9_spi->bbar; - cntlr.preop = &ich9_spi->preop; - - if (cntlr.hsfs & HSFS_FDV) - { - writel_ (4, &ich9_spi->fdoc); - cntlr.flmap0 = readl_(&ich9_spi->fdod); - } - break; - } - default: - printk(BIOS_DEBUG, "ICH SPI: Unrecognized ICH version %d.\n", ich_version); - } - - ich_set_bbar(0); - - /* Disable the BIOS write protect so write commands are allowed. */ - pci_read_config_byte(dev, 0xdc, &bios_cntl); - switch (ich_version) { - case 9: - /* Deassert SMM BIOS Write Protect Disable. */ - bios_cntl &= ~(1 << 5); - break; - - default: - break; - } - pci_write_config_byte(dev, 0xdc, bios_cntl | 0x1); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - -void spi_cs_activate(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - -void spi_cs_deactivate(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - -typedef struct spi_transaction { - const uint8_t *out; - uint32_t bytesout; - uint8_t *in; - uint32_t bytesin; - uint8_t type; - uint8_t opcode; - uint32_t offset; -} spi_transaction; - -static inline void spi_use_out(spi_transaction *trans, unsigned bytes) -{ - trans->out += bytes; - trans->bytesout -= bytes; -} - -static inline void spi_use_in(spi_transaction *trans, unsigned bytes) -{ - trans->in += bytes; - trans->bytesin -= bytes; -} - -static void spi_setup_type(spi_transaction *trans) -{ - trans->type = 0xFF; - - /* Try to guess spi type from read/write sizes. */ - if (trans->bytesin == 0) { - if (trans->bytesout > 4) - /* - * If bytesin = 0 and bytesout > 4, we presume this is - * a write data operation, which is accompanied by an - * address. - */ - trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS; - else - trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS; - return; - } - - if (trans->bytesout == 1) { /* and bytesin is > 0 */ - trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS; - return; - } - - if (trans->bytesout == 4) { /* and bytesin is > 0 */ - trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; - } - - /* Fast read command is called with 5 bytes instead of 4 */ - if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) { - trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; - --trans->bytesout; - } -} - -static int spi_setup_opcode(spi_transaction *trans) -{ - uint16_t optypes; - uint8_t opmenu[cntlr.menubytes]; - - trans->opcode = trans->out[0]; - spi_use_out(trans, 1); - if (!ichspi_lock) { - /* The lock is off, so just use index 0. */ - writeb_(trans->opcode, cntlr.opmenu); - optypes = readw_(cntlr.optype); - optypes = (optypes & 0xfffc) | (trans->type & 0x3); - writew_(optypes, cntlr.optype); - return 0; - } else { - /* The lock is on. See if what we need is on the menu. */ - uint8_t optype; - uint16_t opcode_index; - - /* Write Enable is handled as atomic prefix */ - if (trans->opcode == SPI_OPCODE_WREN) - return 0; - - read_reg(cntlr.opmenu, opmenu, sizeof(opmenu)); - for (opcode_index = 0; opcode_index < cntlr.menubytes; - opcode_index++) { - if (opmenu[opcode_index] == trans->opcode) - break; - } - - if (opcode_index == cntlr.menubytes) { - printk(BIOS_DEBUG, "ICH SPI: Opcode %x not found\n", - trans->opcode); - return -1; - } - - optypes = readw_(cntlr.optype); - optype = (optypes >> (opcode_index * 2)) & 0x3; - if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS && - optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS && - trans->bytesout >= 3) { - /* We guessed wrong earlier. Fix it up. */ - trans->type = optype; - } - if (optype != trans->type) { - printk(BIOS_DEBUG, "ICH SPI: Transaction doesn't fit type %d\n", - optype); - return -1; - } - return opcode_index; - } -} - -static int spi_setup_offset(spi_transaction *trans) -{ - /* Separate the SPI address and data. */ - switch (trans->type) { - case SPI_OPCODE_TYPE_READ_NO_ADDRESS: - case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS: - return 0; - case SPI_OPCODE_TYPE_READ_WITH_ADDRESS: - case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS: - trans->offset = ((uint32_t)trans->out[0] << 16) | - ((uint32_t)trans->out[1] << 8) | - ((uint32_t)trans->out[2] << 0); - spi_use_out(trans, 3); - return 1; - default: - printk(BIOS_DEBUG, "Unrecognized SPI transaction type %#x\n", trans->type); - return -1; - } -} - -/* - * Wait for up to 60ms til status register bit(s) turn 1 (in case wait_til_set - * below is True) or 0. In case the wait was for the bit(s) to set - write - * those bits back, which would cause resetting them. - * - * Return the last read status value on success or -1 on failure. - */ -static int ich_status_poll(u16 bitmask, int wait_til_set) -{ - int timeout = 6000; /* This will result in 60 ms */ - u16 status = 0; - - while (timeout--) { - status = readw_(cntlr.status); - if (wait_til_set ^ ((status & bitmask) == 0)) { - if (wait_til_set) - writew_((status & bitmask), cntlr.status); - return status; - } - udelay(10); - } - - printk(BIOS_DEBUG, "ICH SPI: SCIP timeout, read %x, expected %x\n", - status, bitmask); - return -1; -} - -static int spi_is_multichip (void) -{ - if (cntlr.revision != 9) - return 0; - if (!(cntlr.hsfs & HSFS_FDV)) - return 0; - return !!((cntlr.flmap0 >> 8) & 3); -} - -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bitsout, void *din, unsigned int bitsin) -{ - uint16_t control; - int16_t opcode_index; - int with_address; - int status; - - spi_transaction trans = { - dout, bitsout / 8, - din, bitsin / 8, - 0xff, 0xff, 0 - }; - - /* There has to always at least be an opcode. */ - if (!bitsout || !dout) { - printk(BIOS_DEBUG, "ICH SPI: No opcode for transfer\n"); - return -1; - } - /* Make sure if we read something we have a place to put it. */ - if (bitsin != 0 && !din) { - printk(BIOS_DEBUG, "ICH SPI: Read but no target buffer\n"); - return -1; - } - /* Right now we don't support writing partial bytes. */ - if (bitsout % 8 || bitsin % 8) { - printk(BIOS_DEBUG, "ICH SPI: Accessing partial bytes not supported\n"); - return -1; - } - - if (ich_status_poll(SPIS_SCIP, 0) == -1) - return -1; - - writew_(SPIS_CDS | SPIS_FCERR, cntlr.status); - - spi_setup_type(&trans); - if ((opcode_index = spi_setup_opcode(&trans)) < 0) - return -1; - if ((with_address = spi_setup_offset(&trans)) < 0) - return -1; - - if (trans.opcode == SPI_OPCODE_WREN) { - /* - * Treat Write Enable as Atomic Pre-Op if possible - * in order to prevent the Management Engine from - * issuing a transaction between WREN and DATA. - */ - if (!ichspi_lock) - writew_(trans.opcode, cntlr.preop); - return 0; - } - - /* Preset control fields */ - control = SPIC_SCGO | ((opcode_index & 0x07) << 4); - - /* Issue atomic preop cycle if needed */ - if (readw_(cntlr.preop)) - control |= SPIC_ACS; - - if (!trans.bytesout && !trans.bytesin) { - /* SPI addresses are 24 bit only */ - if (with_address) - writel_(trans.offset & 0x00FFFFFF, cntlr.addr); - - /* - * This is a 'no data' command (like Write Enable), its - * bitesout size was 1, decremented to zero while executing - * spi_setup_opcode() above. Tell the chip to send the - * command. - */ - writew_(control, cntlr.control); - - /* wait for the result */ - status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); - if (status == -1) - return -1; - - if (status & SPIS_FCERR) { - printk(BIOS_DEBUG, "ICH SPI: Command transaction error\n"); - return -1; - } - - return 0; - } - - /* - * Check if this is a write command attempting to transfer more bytes - * than the controller can handle. Iterations for writes are not - * supported here because each SPI write command needs to be preceded - * and followed by other SPI commands, and this sequence is controlled - * by the SPI chip driver. - */ - if (trans.bytesout > cntlr.databytes) { - printk(BIOS_DEBUG, "ICH SPI: Too much to write. Does your SPI chip driver use" - " CONTROLLER_PAGE_LIMIT?\n"); - return -1; - } - - /* - * Read or write up to databytes bytes at a time until everything has - * been sent. - */ - while (trans.bytesout || trans.bytesin) { - uint32_t data_length; - - /* SPI addresses are 24 bit only */ - writel_(trans.offset & 0x00FFFFFF, cntlr.addr); - - if (trans.bytesout) - data_length = min(trans.bytesout, cntlr.databytes); - else - data_length = min(trans.bytesin, cntlr.databytes); - - /* Program data into FDATA0 to N */ - if (trans.bytesout) { - write_reg(trans.out, cntlr.data, data_length); - spi_use_out(&trans, data_length); - if (with_address) - trans.offset += data_length; - } - - /* Add proper control fields' values */ - control &= ~((cntlr.databytes - 1) << 8); - control |= SPIC_DS; - control |= (data_length - 1) << 8; - - /* write it */ - writew_(control, cntlr.control); - - /* Wait for Cycle Done Status or Flash Cycle Error. */ - status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); - if (status == -1) - return -1; - - if (status & SPIS_FCERR) { - printk(BIOS_DEBUG, "ICH SPI: Data transaction error\n"); - return -1; - } - - if (trans.bytesin) { - read_reg(cntlr.data, trans.in, data_length); - spi_use_in(&trans, data_length); - if (with_address) - trans.offset += data_length; - } - } - - /* Clear atomic preop now that xfer is done */ - writew_(0, cntlr.preop); - - return 0; -} - -/* Sets FLA in FADDR to (addr & 0x01FFFFFF) without touching other bits. */ -static void ich_hwseq_set_addr(uint32_t addr) -{ - uint32_t addr_old = readl_(&cntlr.ich9_spi->faddr) & ~0x01FFFFFF; - writel_((addr & 0x01FFFFFF) | addr_old, &cntlr.ich9_spi->faddr); -} - -/* Polls for Cycle Done Status, Flash Cycle Error or timeout in 8 us intervals. - Resets all error flags in HSFS. - Returns 0 if the cycle completes successfully without errors within - timeout us, 1 on errors. */ -static int ich_hwseq_wait_for_cycle_complete(unsigned int timeout, - unsigned int len) -{ - uint16_t hsfs; - uint32_t addr; - - timeout /= 8; /* scale timeout duration to counter */ - while ((((hsfs = readw_(&cntlr.ich9_spi->hsfs)) & - (HSFS_FDONE | HSFS_FCERR)) == 0) && - --timeout) { - udelay(8); - } - writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); - - if (!timeout) { - uint16_t hsfc; - addr = readl_(&cntlr.ich9_spi->faddr) & 0x01FFFFFF; - hsfc = readw_(&cntlr.ich9_spi->hsfc); - printk(BIOS_ERR, "Transaction timeout between offset 0x%08x and " - "0x%08x (= 0x%08x + %d) HSFC=%x HSFS=%x!\n", - addr, addr + len - 1, addr, len - 1, - hsfc, hsfs); - return 1; - } - - if (hsfs & HSFS_FCERR) { - uint16_t hsfc; - addr = readl_(&cntlr.ich9_spi->faddr) & 0x01FFFFFF; - hsfc = readw_(&cntlr.ich9_spi->hsfc); - printk(BIOS_ERR, "Transaction error between offset 0x%08x and " - "0x%08x (= 0x%08x + %d) HSFC=%x HSFS=%x!\n", - addr, addr + len - 1, addr, len - 1, - hsfc, hsfs); - return 1; - } - return 0; -} - - -static int ich_hwseq_erase(struct spi_flash *flash, u32 offset, size_t len) -{ - u32 start, end, erase_size; - int ret; - uint16_t hsfc; - uint16_t timeout = 1000 * 60; - - erase_size = flash->sector_size; - if (offset % erase_size || len % erase_size) { - printk(BIOS_ERR, "SF: Erase offset/length not multiple of erase size\n"); - return -1; - } - - flash->spi->rw = SPI_WRITE_FLAG; - ret = spi_claim_bus(flash->spi); - if (ret) { - printk(BIOS_ERR, "SF: Unable to claim SPI bus\n"); - return ret; - } - - start = offset; - end = start + len; - - while (offset < end) { - /* make sure FDONE, FCERR, AEL are cleared by writing 1 to them */ - writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); - - ich_hwseq_set_addr(offset); - - offset += erase_size; - - hsfc = readw_(&cntlr.ich9_spi->hsfc); - hsfc &= ~HSFC_FCYCLE; /* clear operation */ - hsfc |= (0x3 << HSFC_FCYCLE_OFF); /* set erase operation */ - hsfc |= HSFC_FGO; /* start */ - writew_(hsfc, &cntlr.ich9_spi->hsfc); - if (ich_hwseq_wait_for_cycle_complete(timeout, len)) - { - printk(BIOS_ERR, "SF: Erase failed at %x\n", offset - erase_size); - ret = -1; - goto out; - } - } - - printk(BIOS_DEBUG, "SF: Successfully erased %zu bytes @ %#x\n", len, start); - -out: - spi_release_bus(flash->spi); - return ret; -} - -static void ich_read_data(uint8_t *data, int len) -{ - int i; - uint32_t temp32 = 0; - - for (i = 0; i < len; i++) { - if ((i % 4) == 0) - temp32 = readl_(cntlr.data + i); - - data[i] = (temp32 >> ((i % 4) * 8)) & 0xff; - } -} - -static int ich_hwseq_read(struct spi_flash *flash, - u32 addr, size_t len, void *buf) -{ - uint16_t hsfc; - uint16_t timeout = 100 * 60; - uint8_t block_len; - - if (addr + len > flash->size) { - printk (BIOS_ERR, - "Attempt to read %x-%x which is out of chip\n", - (unsigned) addr, - (unsigned) addr+(unsigned) len); - return -1; - } - - /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ - writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); - - while (len > 0) { - block_len = min(len, cntlr.databytes); - if (block_len > (~addr & 0xff)) - block_len = (~addr & 0xff) + 1; - ich_hwseq_set_addr(addr); - hsfc = readw_(&cntlr.ich9_spi->hsfc); - hsfc &= ~HSFC_FCYCLE; /* set read operation */ - hsfc &= ~HSFC_FDBC; /* clear byte count */ - /* set byte count */ - hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); - hsfc |= HSFC_FGO; /* start */ - writew_(hsfc, &cntlr.ich9_spi->hsfc); - - if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) - return 1; - ich_read_data(buf, block_len); - addr += block_len; - buf += block_len; - len -= block_len; - } - return 0; -} - -/* Fill len bytes from the data array into the fdata/spid registers. - * - * Note that using len > flash->pgm->spi.max_data_write will trash the registers - * following the data registers. - */ -static void ich_fill_data(const uint8_t *data, int len) -{ - uint32_t temp32 = 0; - int i; - - if (len <= 0) - return; - - for (i = 0; i < len; i++) { - if ((i % 4) == 0) - temp32 = 0; - - temp32 |= ((uint32_t) data[i]) << ((i % 4) * 8); - - if ((i % 4) == 3) /* 32 bits are full, write them to regs. */ - writel_(temp32, cntlr.data + (i - (i % 4))); - } - i--; - if ((i % 4) != 3) /* Write remaining data to regs. */ - writel_(temp32, cntlr.data + (i - (i % 4))); -} - -static int ich_hwseq_write(struct spi_flash *flash, - u32 addr, size_t len, const void *buf) -{ - uint16_t hsfc; - uint16_t timeout = 100 * 60; - uint8_t block_len; - uint32_t start = addr; - - if (addr + len > flash->size) { - printk (BIOS_ERR, - "Attempt to write 0x%x-0x%x which is out of chip\n", - (unsigned)addr, (unsigned) (addr+len)); - return -1; - } - - /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ - writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); - - while (len > 0) { - block_len = min(len, cntlr.databytes); - if (block_len > (~addr & 0xff)) - block_len = (~addr & 0xff) + 1; - - ich_hwseq_set_addr(addr); - - ich_fill_data(buf, block_len); - hsfc = readw_(&cntlr.ich9_spi->hsfc); - hsfc &= ~HSFC_FCYCLE; /* clear operation */ - hsfc |= (0x2 << HSFC_FCYCLE_OFF); /* set write operation */ - hsfc &= ~HSFC_FDBC; /* clear byte count */ - /* set byte count */ - hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); - hsfc |= HSFC_FGO; /* start */ - writew_(hsfc, &cntlr.ich9_spi->hsfc); - - if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) - { - printk (BIOS_ERR, "SF: write failure at %x\n", - addr); - return -1; - } - addr += block_len; - buf += block_len; - len -= block_len; - } - printk(BIOS_DEBUG, "SF: Successfully written %u bytes @ %#x\n", - (unsigned) (addr - start), start); - return 0; -} - - -static struct spi_flash *spi_flash_hwseq(struct spi_slave *spi) -{ - struct spi_flash *flash = NULL; - uint32_t flcomp; - - flash = malloc(sizeof(*flash)); - if (!flash) { - printk(BIOS_WARNING, "SF: Failed to allocate memory\n"); - return NULL; - } - - flash->spi = spi; - flash->name = "Opaque HW-sequencing"; - - flash->write = ich_hwseq_write; - flash->erase = ich_hwseq_erase; - flash->read = ich_hwseq_read; - ich_hwseq_set_addr (0); - switch ((cntlr.hsfs >> 3) & 3) - { - case 0: - flash->sector_size = 256; - break; - case 1: - flash->sector_size = 4096; - break; - case 2: - flash->sector_size = 8192; - break; - case 3: - flash->sector_size = 65536; - break; - } - - writel_ (0x1000, &cntlr.ich9_spi->fdoc); - flcomp = readl_(&cntlr.ich9_spi->fdod); - - flash->size = 1 << (19 + (flcomp & 7)); - - if ((cntlr.hsfs & HSFS_FDV) && ((cntlr.flmap0 >> 8) & 3)) - flash->size += 1 << (19 + ((flcomp >> 3) & 7)); - printk (BIOS_DEBUG, "flash size 0x%x bytes\n", flash->size); - - return flash; -} diff --git a/src/southbridge/intel/lynxpoint/Makefile.inc b/src/southbridge/intel/lynxpoint/Makefile.inc index 7be2d03..d635b22 100644 --- a/src/southbridge/intel/lynxpoint/Makefile.inc +++ b/src/southbridge/intel/lynxpoint/Makefile.inc @@ -44,8 +44,8 @@ ramstage-y += acpi.c ramstage-$(CONFIG_ALT_CBFS_LOAD_PAYLOAD) += spi_loading.c ramstage-$(CONFIG_ELOG) += elog.c -ramstage-y += spi.c -smm-$(CONFIG_SPI_FLASH_SMM) += spi.c +ramstage-y += ../spi.c +smm-$(CONFIG_SPI_FLASH_SMM) += ../spi.c ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c pmutil.c smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c me_9.x.c finalize.c pch.c diff --git a/src/southbridge/intel/lynxpoint/spi.c b/src/southbridge/intel/lynxpoint/spi.c deleted file mode 100644 index 5501efc..0000000 --- a/src/southbridge/intel/lynxpoint/spi.c +++ /dev/null @@ -1,657 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* This file is derived from the flashrom project. */ -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <delay.h> -#include <arch/io.h> -#include <console/console.h> -#include <device/pci_ids.h> - -#include <spi-generic.h> - -#define min(a, b) ((a)<(b)?(a):(b)) - -#ifdef __SMM__ -#define pci_read_config_byte(dev, reg, targ)\ - *(targ) = pci_read_config8(dev, reg) -#define pci_read_config_word(dev, reg, targ)\ - *(targ) = pci_read_config16(dev, reg) -#define pci_read_config_dword(dev, reg, targ)\ - *(targ) = pci_read_config32(dev, reg) -#define pci_write_config_byte(dev, reg, val)\ - pci_write_config8(dev, reg, val) -#define pci_write_config_word(dev, reg, val)\ - pci_write_config16(dev, reg, val) -#define pci_write_config_dword(dev, reg, val)\ - pci_write_config32(dev, reg, val) -#else /* !__SMM__ */ -#include <device/device.h> -#include <device/pci.h> -#define pci_read_config_byte(dev, reg, targ)\ - *(targ) = pci_read_config8(dev, reg) -#define pci_read_config_word(dev, reg, targ)\ - *(targ) = pci_read_config16(dev, reg) -#define pci_read_config_dword(dev, reg, targ)\ - *(targ) = pci_read_config32(dev, reg) -#define pci_write_config_byte(dev, reg, val)\ - pci_write_config8(dev, reg, val) -#define pci_write_config_word(dev, reg, val)\ - pci_write_config16(dev, reg, val) -#define pci_write_config_dword(dev, reg, val)\ - pci_write_config32(dev, reg, val) -#endif /* !__SMM__ */ - -typedef struct spi_slave ich_spi_slave; - -static int ichspi_lock = 0; - -typedef struct ich9_spi_regs { - uint32_t bfpr; - uint16_t hsfs; - uint16_t hsfc; - uint32_t faddr; - uint32_t _reserved0; - uint32_t fdata[16]; - uint32_t frap; - uint32_t freg[5]; - uint32_t _reserved1[3]; - uint32_t pr[5]; - uint32_t _reserved2[2]; - uint8_t ssfs; - uint8_t ssfc[3]; - uint16_t preop; - uint16_t optype; - uint8_t opmenu[8]; - uint32_t bbar; - uint8_t _reserved3[12]; - uint32_t fdoc; - uint32_t fdod; - uint8_t _reserved4[8]; - uint32_t afc; - uint32_t lvscc; - uint32_t uvscc; - uint8_t _reserved5[4]; - uint32_t fpb; - uint8_t _reserved6[28]; - uint32_t srdl; - uint32_t srdc; - uint32_t srd; -} __attribute__((packed)) ich9_spi_regs; - -typedef struct ich_spi_controller { - int locked; - - uint8_t *opmenu; - int menubytes; - uint16_t *preop; - uint16_t *optype; - uint32_t *addr; - uint8_t *data; - unsigned databytes; - uint8_t *status; - uint16_t *control; - uint32_t *bbar; -} ich_spi_controller; - -static ich_spi_controller cntlr; - -enum { - SPIS_SCIP = 0x0001, - SPIS_GRANT = 0x0002, - SPIS_CDS = 0x0004, - SPIS_FCERR = 0x0008, - SSFS_AEL = 0x0010, - SPIS_LOCK = 0x8000, - SPIS_RESERVED_MASK = 0x7ff0, - SSFS_RESERVED_MASK = 0x7fe2 -}; - -enum { - SPIC_SCGO = 0x000002, - SPIC_ACS = 0x000004, - SPIC_SPOP = 0x000008, - SPIC_DBC = 0x003f00, - SPIC_DS = 0x004000, - SPIC_SME = 0x008000, - SSFC_SCF_MASK = 0x070000, - SSFC_RESERVED = 0xf80000 -}; - -enum { - HSFS_FDONE = 0x0001, - HSFS_FCERR = 0x0002, - HSFS_AEL = 0x0004, - HSFS_BERASE_MASK = 0x0018, - HSFS_BERASE_SHIFT = 3, - HSFS_SCIP = 0x0020, - HSFS_FDOPSS = 0x2000, - HSFS_FDV = 0x4000, - HSFS_FLOCKDN = 0x8000 -}; - -enum { - HSFC_FGO = 0x0001, - HSFC_FCYCLE_MASK = 0x0006, - HSFC_FCYCLE_SHIFT = 1, - HSFC_FDBC_MASK = 0x3f00, - HSFC_FDBC_SHIFT = 8, - HSFC_FSMIE = 0x8000 -}; - -enum { - SPI_OPCODE_TYPE_READ_NO_ADDRESS = 0, - SPI_OPCODE_TYPE_WRITE_NO_ADDRESS = 1, - SPI_OPCODE_TYPE_READ_WITH_ADDRESS = 2, - SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3 -}; - -#if CONFIG_DEBUG_SPI_FLASH - -static u8 readb_(const void *addr) -{ - u8 v = read8((unsigned long)addr); - printk(BIOS_DEBUG, "read %2.2x from %4.4x\n", - v, ((unsigned) addr & 0xffff) - 0xf020); - return v; -} - -static u16 readw_(const void *addr) -{ - u16 v = read16((unsigned long)addr); - printk(BIOS_DEBUG, "read %4.4x from %4.4x\n", - v, ((unsigned) addr & 0xffff) - 0xf020); - return v; -} - -static u32 readl_(const void *addr) -{ - u32 v = read32((unsigned long)addr); - printk(BIOS_DEBUG, "read %8.8x from %4.4x\n", - v, ((unsigned) addr & 0xffff) - 0xf020); - return v; -} - -static void writeb_(u8 b, const void *addr) -{ - write8((unsigned long)addr, b); - printk(BIOS_DEBUG, "wrote %2.2x to %4.4x\n", - b, ((unsigned) addr & 0xffff) - 0xf020); -} - -static void writew_(u16 b, const void *addr) -{ - write16((unsigned long)addr, b); - printk(BIOS_DEBUG, "wrote %4.4x to %4.4x\n", - b, ((unsigned) addr & 0xffff) - 0xf020); -} - -static void writel_(u32 b, const void *addr) -{ - write32((unsigned long)addr, b); - printk(BIOS_DEBUG, "wrote %8.8x to %4.4x\n", - b, ((unsigned) addr & 0xffff) - 0xf020); -} - -#else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled vvv NOT enabled */ - -#define readb_(a) read8((uint32_t)a) -#define readw_(a) read16((uint32_t)a) -#define readl_(a) read32((uint32_t)a) -#define writeb_(val, addr) write8((uint32_t)addr, val) -#define writew_(val, addr) write16((uint32_t)addr, val) -#define writel_(val, addr) write32((uint32_t)addr, val) - -#endif /* CONFIG_DEBUG_SPI_FLASH ^^^ NOT enabled */ - -static void write_reg(const void *value, void *dest, uint32_t size) -{ - const uint8_t *bvalue = value; - uint8_t *bdest = dest; - - while (size >= 4) { - writel_(*(const uint32_t *)bvalue, bdest); - bdest += 4; bvalue += 4; size -= 4; - } - while (size) { - writeb_(*bvalue, bdest); - bdest++; bvalue++; size--; - } -} - -static void read_reg(const void *src, void *value, uint32_t size) -{ - const uint8_t *bsrc = src; - uint8_t *bvalue = value; - - while (size >= 4) { - *(uint32_t *)bvalue = readl_(bsrc); - bsrc += 4; bvalue += 4; size -= 4; - } - while (size) { - *bvalue = readb_(bsrc); - bsrc++; bvalue++; size--; - } -} - -static void ich_set_bbar(uint32_t minaddr) -{ - const uint32_t bbar_mask = 0x00ffff00; - uint32_t ichspi_bbar; - - minaddr &= bbar_mask; - ichspi_bbar = readl_(cntlr.bbar) & ~bbar_mask; - ichspi_bbar |= minaddr; - writel_(ichspi_bbar, cntlr.bbar); -} - -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - printk(BIOS_DEBUG, "spi_cs_is_valid used but not implemented\n"); - return 0; -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - ich_spi_slave *slave = malloc(sizeof(*slave)); - - if (!slave) { - printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n"); - return NULL; - } - - memset(slave, 0, sizeof(*slave)); - - slave->bus = bus; - slave->cs = cs; - return slave; -} - -void spi_init(void) -{ - uint8_t *rcrb; /* Root Complex Register Block */ - uint32_t rcba; /* Root Complex Base Address */ - uint8_t bios_cntl; - device_t dev; - ich9_spi_regs *ich9_spi; - -#ifdef __SMM__ - dev = PCI_DEV(0, 31, 0); -#else - dev = dev_find_slot(0, PCI_DEVFN(31, 0)); -#endif - - pci_read_config_dword(dev, 0xf0, &rcba); - /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable. */ - rcrb = (uint8_t *)(rcba & 0xffffc000); - ich9_spi = (ich9_spi_regs *)(rcrb + 0x3800); - ichspi_lock = readw_(&ich9_spi->hsfs) & HSFS_FLOCKDN; - cntlr.opmenu = ich9_spi->opmenu; - cntlr.menubytes = sizeof(ich9_spi->opmenu); - cntlr.optype = &ich9_spi->optype; - cntlr.addr = &ich9_spi->faddr; - cntlr.data = (uint8_t *)ich9_spi->fdata; - cntlr.databytes = sizeof(ich9_spi->fdata); - cntlr.status = &ich9_spi->ssfs; - cntlr.control = (uint16_t *)ich9_spi->ssfc; - cntlr.bbar = &ich9_spi->bbar; - cntlr.preop = &ich9_spi->preop; - ich_set_bbar(0); - - /* Disable the BIOS write protect so write commands are allowed. */ - pci_read_config_byte(dev, 0xdc, &bios_cntl); - bios_cntl &= ~(1 << 5); - pci_write_config_byte(dev, 0xdc, bios_cntl | 0x1); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - -void spi_cs_activate(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - -void spi_cs_deactivate(struct spi_slave *slave) -{ - /* Handled by ICH automatically. */ -} - -typedef struct spi_transaction { - const uint8_t *out; - uint32_t bytesout; - uint8_t *in; - uint32_t bytesin; - uint8_t type; - uint8_t opcode; - uint32_t offset; -} spi_transaction; - -static inline void spi_use_out(spi_transaction *trans, unsigned bytes) -{ - trans->out += bytes; - trans->bytesout -= bytes; -} - -static inline void spi_use_in(spi_transaction *trans, unsigned bytes) -{ - trans->in += bytes; - trans->bytesin -= bytes; -} - -static void spi_setup_type(spi_transaction *trans) -{ - trans->type = 0xFF; - - /* Try to guess spi type from read/write sizes. */ - if (trans->bytesin == 0) { - if (trans->bytesout > 4) - /* - * If bytesin = 0 and bytesout > 4, we presume this is - * a write data operation, which is accompanied by an - * address. - */ - trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS; - else - trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS; - return; - } - - if (trans->bytesout == 1) { /* and bytesin is > 0 */ - trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS; - return; - } - - if (trans->bytesout == 4) { /* and bytesin is > 0 */ - trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; - } - - /* Fast read command is called with 5 bytes instead of 4 */ - if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) { - trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; - --trans->bytesout; - } -} - -static int spi_setup_opcode(spi_transaction *trans) -{ - uint16_t optypes; - uint8_t opmenu[cntlr.menubytes]; - - trans->opcode = trans->out[0]; - spi_use_out(trans, 1); - if (!ichspi_lock) { - /* The lock is off, so just use index 0. */ - writeb_(trans->opcode, cntlr.opmenu); - optypes = readw_(cntlr.optype); - optypes = (optypes & 0xfffc) | (trans->type & 0x3); - writew_(optypes, cntlr.optype); - return 0; - } else { - /* The lock is on. See if what we need is on the menu. */ - uint8_t optype; - uint16_t opcode_index; - - /* Write Enable is handled as atomic prefix */ - if (trans->opcode == SPI_OPCODE_WREN) - return 0; - - read_reg(cntlr.opmenu, opmenu, sizeof(opmenu)); - for (opcode_index = 0; opcode_index < cntlr.menubytes; - opcode_index++) { - if (opmenu[opcode_index] == trans->opcode) - break; - } - - if (opcode_index == cntlr.menubytes) { - printk(BIOS_DEBUG, "ICH SPI: Opcode %x not found\n", - trans->opcode); - return -1; - } - - optypes = readw_(cntlr.optype); - optype = (optypes >> (opcode_index * 2)) & 0x3; - if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS && - optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS && - trans->bytesout >= 3) { - /* We guessed wrong earlier. Fix it up. */ - trans->type = optype; - } - if (optype != trans->type) { - printk(BIOS_DEBUG, "ICH SPI: Transaction doesn't fit type %d\n", - optype); - return -1; - } - return opcode_index; - } -} - -static int spi_setup_offset(spi_transaction *trans) -{ - /* Separate the SPI address and data. */ - switch (trans->type) { - case SPI_OPCODE_TYPE_READ_NO_ADDRESS: - case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS: - return 0; - case SPI_OPCODE_TYPE_READ_WITH_ADDRESS: - case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS: - trans->offset = ((uint32_t)trans->out[0] << 16) | - ((uint32_t)trans->out[1] << 8) | - ((uint32_t)trans->out[2] << 0); - spi_use_out(trans, 3); - return 1; - default: - printk(BIOS_DEBUG, "Unrecognized SPI transaction type %#x\n", trans->type); - return -1; - } -} - -/* - * Wait for up to 60ms til status register bit(s) turn 1 (in case wait_til_set - * below is True) or 0. In case the wait was for the bit(s) to set - write - * those bits back, which would cause resetting them. - * - * Return the last read status value on success or -1 on failure. - */ -static int ich_status_poll(u16 bitmask, int wait_til_set) -{ - int timeout = 6000; /* This will result in 60 ms */ - u16 status = 0; - - while (timeout--) { - status = readw_(cntlr.status); - if (wait_til_set ^ ((status & bitmask) == 0)) { - if (wait_til_set) - writew_((status & bitmask), cntlr.status); - return status; - } - udelay(10); - } - - printk(BIOS_DEBUG, "ICH SPI: SCIP timeout, read %x, expected %x\n", - status, bitmask); - return -1; -} - -int spi_xfer(struct spi_slave *slave, const void *dout, - unsigned int bitsout, void *din, unsigned int bitsin) -{ - uint16_t control; - int16_t opcode_index; - int with_address; - int status; - - spi_transaction trans = { - dout, bitsout / 8, - din, bitsin / 8, - 0xff, 0xff, 0 - }; - - /* There has to always at least be an opcode. */ - if (!bitsout || !dout) { - printk(BIOS_DEBUG, "ICH SPI: No opcode for transfer\n"); - return -1; - } - /* Make sure if we read something we have a place to put it. */ - if (bitsin != 0 && !din) { - printk(BIOS_DEBUG, "ICH SPI: Read but no target buffer\n"); - return -1; - } - /* Right now we don't support writing partial bytes. */ - if (bitsout % 8 || bitsin % 8) { - printk(BIOS_DEBUG, "ICH SPI: Accessing partial bytes not supported\n"); - return -1; - } - - if (ich_status_poll(SPIS_SCIP, 0) == -1) - return -1; - - writew_(SPIS_CDS | SPIS_FCERR, cntlr.status); - - spi_setup_type(&trans); - if ((opcode_index = spi_setup_opcode(&trans)) < 0) - return -1; - if ((with_address = spi_setup_offset(&trans)) < 0) - return -1; - - if (trans.opcode == SPI_OPCODE_WREN) { - /* - * Treat Write Enable as Atomic Pre-Op if possible - * in order to prevent the Management Engine from - * issuing a transaction between WREN and DATA. - */ - if (!ichspi_lock) - writew_(trans.opcode, cntlr.preop); - return 0; - } - - /* Preset control fields */ - control = SPIC_SCGO | ((opcode_index & 0x07) << 4); - - /* Issue atomic preop cycle if needed */ - if (readw_(cntlr.preop)) - control |= SPIC_ACS; - - if (!trans.bytesout && !trans.bytesin) { - /* SPI addresses are 24 bit only */ - if (with_address) - writel_(trans.offset & 0x00FFFFFF, cntlr.addr); - - /* - * This is a 'no data' command (like Write Enable), its - * bitesout size was 1, decremented to zero while executing - * spi_setup_opcode() above. Tell the chip to send the - * command. - */ - writew_(control, cntlr.control); - - /* wait for the result */ - status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); - if (status == -1) - return -1; - - if (status & SPIS_FCERR) { - printk(BIOS_DEBUG, "ICH SPI: Command transaction error\n"); - return -1; - } - - return 0; - } - - /* - * Check if this is a write command attempting to transfer more bytes - * than the controller can handle. Iterations for writes are not - * supported here because each SPI write command needs to be preceded - * and followed by other SPI commands, and this sequence is controlled - * by the SPI chip driver. - */ - if (trans.bytesout > cntlr.databytes) { - printk(BIOS_DEBUG, "ICH SPI: Too much to write. Does your SPI chip driver use" - " CONTROLLER_PAGE_LIMIT?\n"); - return -1; - } - - /* - * Read or write up to databytes bytes at a time until everything has - * been sent. - */ - while (trans.bytesout || trans.bytesin) { - uint32_t data_length; - - /* SPI addresses are 24 bit only */ - writel_(trans.offset & 0x00FFFFFF, cntlr.addr); - - if (trans.bytesout) - data_length = min(trans.bytesout, cntlr.databytes); - else - data_length = min(trans.bytesin, cntlr.databytes); - - /* Program data into FDATA0 to N */ - if (trans.bytesout) { - write_reg(trans.out, cntlr.data, data_length); - spi_use_out(&trans, data_length); - if (with_address) - trans.offset += data_length; - } - - /* Add proper control fields' values */ - control &= ~((cntlr.databytes - 1) << 8); - control |= SPIC_DS; - control |= (data_length - 1) << 8; - - /* write it */ - writew_(control, cntlr.control); - - /* Wait for Cycle Done Status or Flash Cycle Error. */ - status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); - if (status == -1) - return -1; - - if (status & SPIS_FCERR) { - printk(BIOS_DEBUG, "ICH SPI: Data transaction error\n"); - return -1; - } - - if (trans.bytesin) { - read_reg(cntlr.data, trans.in, data_length); - spi_use_in(&trans, data_length); - if (with_address) - trans.offset += data_length; - } - } - - /* Clear atomic preop now that xfer is done */ - writew_(0, cntlr.preop); - - return 0; -}
1
0
0
0
Patch set updated for coreboot: 5205fa0 New port Packard Bell LM85.
by Vladimir Serbinenko
22 Feb '14
22 Feb '14
Vladimir Serbinenko (phcoder(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at
http://review.coreboot.org/5271
-gerrit commit 5205fa0240b619bf156a287fcd1f51860945620a Author: Vladimir Serbinenko <phcoder(a)gmail.com> Date: Wed Feb 19 22:20:14 2014 +0100 New port Packard Bell LM85. Change-Id: I8c1548470c605d06825fe35579879e806bf33542 Signed-off-by: Vladimir Serbinenko <phcoder(a)gmail.com> --- src/mainboard/Kconfig | 3 + src/mainboard/packardbell/Kconfig | 19 ++ src/mainboard/packardbell/ms2290/Kconfig | 58 ++++ src/mainboard/packardbell/ms2290/Makefile.inc | 21 ++ src/mainboard/packardbell/ms2290/acpi/ac.asl | 50 ++++ src/mainboard/packardbell/ms2290/acpi/battery.asl | 155 ++++++++++ src/mainboard/packardbell/ms2290/acpi/ec.asl | 136 +++++++++ src/mainboard/packardbell/ms2290/acpi/gpe.asl | 25 ++ .../packardbell/ms2290/acpi/mainboard.asl | 0 .../packardbell/ms2290/acpi/nehalem_pci_irqs.asl | 86 ++++++ src/mainboard/packardbell/ms2290/acpi/platform.asl | 147 +++++++++ src/mainboard/packardbell/ms2290/acpi/superio.asl | 1 + src/mainboard/packardbell/ms2290/acpi/thermal.asl | 48 +++ src/mainboard/packardbell/ms2290/acpi/video.asl | 115 +++++++ src/mainboard/packardbell/ms2290/acpi_tables.c | 283 +++++++++++++++++ src/mainboard/packardbell/ms2290/board_info.txt | 6 + src/mainboard/packardbell/ms2290/cmos.default | 7 + src/mainboard/packardbell/ms2290/cmos.layout | 131 ++++++++ src/mainboard/packardbell/ms2290/devicetree.cb | 104 +++++++ src/mainboard/packardbell/ms2290/dsdt.asl | 91 ++++++ src/mainboard/packardbell/ms2290/fadt.c | 160 ++++++++++ src/mainboard/packardbell/ms2290/gma.c | 272 +++++++++++++++++ src/mainboard/packardbell/ms2290/hda_verb.h | 90 ++++++ src/mainboard/packardbell/ms2290/mainboard.c | 178 +++++++++++ src/mainboard/packardbell/ms2290/romstage.c | 333 +++++++++++++++++++++ src/mainboard/packardbell/ms2290/smi.h | 0 src/mainboard/packardbell/ms2290/smihandler.c | 113 +++++++ 27 files changed, 2632 insertions(+) diff --git a/src/mainboard/Kconfig b/src/mainboard/Kconfig index d823b22..0e6f96b 100644 --- a/src/mainboard/Kconfig +++ b/src/mainboard/Kconfig @@ -106,6 +106,8 @@ config VENDOR_NOKIA bool "Nokia" config VENDOR_NVIDIA bool "NVIDIA" +config VENDOR_PACKARDBELL + bool "Packard Bell" config VENDOR_PCENGINES bool "PC Engines" config VENDOR_RCA @@ -196,6 +198,7 @@ source "src/mainboard/nec/Kconfig" source "src/mainboard/newisys/Kconfig" source "src/mainboard/nokia/Kconfig" source "src/mainboard/nvidia/Kconfig" +source "src/mainboard/packardbell/Kconfig" source "src/mainboard/pcengines/Kconfig" source "src/mainboard/rca/Kconfig" source "src/mainboard/roda/Kconfig" diff --git a/src/mainboard/packardbell/Kconfig b/src/mainboard/packardbell/Kconfig new file mode 100644 index 0000000..d0712ae --- /dev/null +++ b/src/mainboard/packardbell/Kconfig @@ -0,0 +1,19 @@ +if VENDOR_PACKARDBELL + +choice + prompt "Mainboard model" + +config BOARD_PACKARDBELL_MS2290 + bool "EasyNote LM85 (MS2290)" + help + EasyNote LM85 laptop + +endchoice + +source "src/mainboard/packardbell/ms2290/Kconfig" + +config MAINBOARD_VENDOR + string + default "Packard Bell" + +endif # VENDOR_PACKARDBELL diff --git a/src/mainboard/packardbell/ms2290/Kconfig b/src/mainboard/packardbell/ms2290/Kconfig new file mode 100644 index 0000000..a458700 --- /dev/null +++ b/src/mainboard/packardbell/ms2290/Kconfig @@ -0,0 +1,58 @@ +if BOARD_PACKARDBELL_MS2290 + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select ARCH_X86 + select NORTHBRIDGE_INTEL_NEHALEM + select SOUTHBRIDGE_INTEL_IBEXPEAK + select HAVE_OPTION_TABLE + select HAVE_CMOS_DEFAULT + select GFXUMA + select BOARD_ROMSIZE_KB_4096 + select HAVE_ACPI_TABLES + select HAVE_ACPI_RESUME + select EARLY_CBMEM_INIT + select MAINBOARD_HAS_NATIVE_VGA_INIT + select EC_ACPI + +config MAINBOARD_DIR + string + default packardbell/ms2290 + +config MAINBOARD_PART_NUMBER + string + default "EasyNote LM85" + +config MAINBOARD_VERSION + string + default "V1.20" + +config MAINBOARD_VENDOR + string + default "Packard Bell" + +config MMCONF_BASE_ADDRESS + hex + default 0xe0000000 + +config IRQ_SLOT_COUNT + int + default 18 + +config USBDEBUG_HCD_INDEX + int + default 2 + +config DRAM_RESET_GATE_GPIO + int + default 60 + +config MAX_CPUS + int + default 4 + +config CPU_ADDR_BITS + int + default 36 + +endif diff --git a/src/mainboard/packardbell/ms2290/Makefile.inc b/src/mainboard/packardbell/ms2290/Makefile.inc new file mode 100644 index 0000000..a9db8d8 --- /dev/null +++ b/src/mainboard/packardbell/ms2290/Makefile.inc @@ -0,0 +1,21 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2007-2008 coresystems GmbH +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c +ramstage-y += gma.c diff --git a/src/mainboard/packardbell/ms2290/acpi/ac.asl b/src/mainboard/packardbell/ms2290/acpi/ac.asl new file mode 100644 index 0000000..2ef1598 --- /dev/null +++ b/src/mainboard/packardbell/ms2290/acpi/ac.asl @@ -0,0 +1,50 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2011 Sven Schnelle <svens(a)stackframe.org> + * + * 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 + */ + +Device(AC) +{ + Name(_HID, "ACPI0003") + Name(_UID, 0x00) + Name(_PCL, Package() { \_SB } ) + + Method(_PSR, 0, NotSerialized) + { + return (HPAC) + } + + Method(_STA, 0, NotSerialized) + { + Return (0x0f) + } +} + +/* AC status change */ +Method(_Q50, 0, NotSerialized) +{ + Notify (AC, 0x80) +} + +/* AC status change */ +Method(_Q51, 0, NotSerialized) +{ + Notify (AC, 0x80) +} + diff --git a/src/mainboard/packardbell/ms2290/acpi/battery.asl b/src/mainboard/packardbell/ms2290/acpi/battery.asl new file mode 100644 index 0000000..1ca2cf1 --- /dev/null +++ b/src/mainboard/packardbell/ms2290/acpi/battery.asl @@ -0,0 +1,155 @@ +/* Arg0: Battery + * Arg1: Battery Status Package + * Arg2: charging + * Arg3: discharging + */ +Method(BSTA, 4, NotSerialized) +{ + Acquire(ECLK, 0xffff) + Store(0, Local0) + + Store(0, PAGE) + + Store(BAPR, Local2) + + if (Arg2) // charging + { + Or(2, Local0, Local0) + + If (LGreaterEqual (Local2, 0x8000)) { + Store(0, Local2) + } + } + + if (Arg3) // discharging + { + Or(1, Local0, Local0) + Subtract(0x10000, Local2, Local2) + } + + Store(Local0, Index(Arg1, 0x00)) + + Store(0, PAGE) + Store(BARC, Index(Arg1, 2)) + Store(Local2, Index(Arg1, 1)) + + Store(0, PAGE) + Store(BAVO, Index(Arg1, 3)) + Release(ECLK) + Return (Arg1) +} + +Method(BINF, 2, NotSerialized) +{ + Acquire(ECLK, 0xffff) + Store(0, PAGE) + Store(BAFC, Local2) + Store(1, PAGE) + Store(BADC, Local1) + + Store(Local1, Index(Arg0, 1)) // Design Capacity + Store(Local2, Index(Arg0, 2)) // Last full charge capacity + Store(1, PAGE) + Store(BADV, Index(Arg0, 4)) // Design Voltage + Divide (Local2, 20, Local0, Index(Arg0, 5)) // Warning capacity + + Store(1, PAGE) + Store (BASN, Local0) + Name (SERN, Buffer (0x06) { " " }) + Store (4, Local1) + While (Local0) + { + Divide (Local0, 0x0A, Local2, Local0) + Add (Local2, 48, Index (SERN, Local1)) + Decrement (Local1) + } + Store (SERN, Index (Arg0, 10)) // Serial Number + + Name (TYPE, Buffer() { 0, 0, 0, 0, 0 }) + Store(4, PAGE) + Store(BATY, TYPE) + Store(TYPE, Index (Arg0, 11)) // Battery type + Store(5, PAGE) + Store(BAOE, Index (Arg0, 12)) // OEM information + Store(2, PAGE) + Store(BANA, Index (Arg0, 9)) // Model number + Release(ECLK) + Return (Arg0) +} + +Device (BAT0) +{ + Name (_HID, EisaId ("PNP0C0A")) + Name (_UID, 0x00) + Name (_PCL, Package () { \_SB }) + + Name (BATS, Package () + { + 0x00, // 0: PowerUnit: Report in mWh + 0xFFFFFFFF, // 1: Design cap + 0xFFFFFFFF, // 2: Last full charge cap + 0x01, // 3: Battery Technology + 10800, // 4: Design Voltage (mV) + 0x00, // 5: Warning design capacity + 200, // 6: Low design capacity + 1, // 7: granularity1 + 1, // 8: granularity2 + "", // 9: Model number + "", // A: Serial number + "", // B: Battery Type + "" // C: OEM information + }) + + Method (_BIF, 0, NotSerialized) + { + Return (BINF(BATS, 0)) + } + + Name (BATI, Package () + { + 0, // Battery State + // Bit 0 - discharge + // Bit 1 - charge + // Bit 2 - critical state + 0, // Battery present Rate + 0, // Battery remaining capacity + 0 // Battery present voltage + }) + + Method (_BST, 0, NotSerialized) + { + if (B0PR) { + Return (BSTA(0, BATI, B0CH, B0DI)) + } else { + Return (BATS) + } + } + + Method (_STA, 0, NotSerialized) + { + if (B0PR) { + Return (0x1f) + } else { + Return (0x0f) + } + } +} + +/* Battery attach/detach */ +Method(_Q40, 0, NotSerialized) +{ + Notify(BAT0, 0x81) +} +Method(_Q41, 0, NotSerialized) +{ + Notify(BAT0, 0x81) +} + +Method(_Q48, 0, NotSerialized) +{ + Notify(BAT0, 0x80) +} +Method(_Q4C, 0, NotSerialized) +{ + Notify(BAT0, 0x80) +} diff --git a/src/mainboard/packardbell/ms2290/acpi/ec.asl b/src/mainboard/packardbell/ms2290/acpi/ec.asl new file mode 100644 index 0000000..3735f20 --- /dev/null +++ b/src/mainboard/packardbell/ms2290/acpi/ec.asl @@ -0,0 +1,136 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2011 Sven Schnelle <svens(a)stackframe.org> + * + * 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 + */ + +Device(EC) +{ + Name (_HID, EISAID("PNP0C09")) + Name (_UID, 0) + + Name (_GPE, 0x17) + Mutex (ECLK, 0) + + OperationRegion(ERAM, EmbeddedControl, 0x00, 0x100) + Field (ERAM, ByteAcc, NoLock, Preserve) + { + Offset (0x8), + PAGE, 8, /* Information Page Selector */ + Offset (0x70), + , 1, + LIDS, 1, + , 3, + HPAC, 1, + Offset (0x88), + B0PR, 1, /* Battery 0 present */ + B0CH, 1, /* Battery 0 charging */ + B0DI, 1, /* Battery 0 discharging */ + Offset (0xA8), + TMP0, 8, + TMP1, 8, + } + + Device(LID) + { + Name(_HID, "PNP0C0D") + Method(_LID, 0, NotSerialized) + { + return (LIDS) + } + } + + Method(_Q52, 0, NotSerialized) + { + Notify(LID, 0x80) + } + + Method(_Q53, 0, NotSerialized) + { + Notify(^LID, 0x80) + } + + /* PAGE = 0 */ + Field (ERAM, ByteAcc, NoLock, Preserve) + { + Offset (0xe0), + BARC, 16, /* Battery remaining capacity */ + BAFC, 16, /* Battery full charge capacity */ + , 16, + BAPR, 16, /* Battery present rate */ + BAVO, 16, /* Battery Voltage */ + } + + /* PAGE = 1 */ + Field (ERAM, ByteAcc, NoLock, Preserve) + { + Offset (0xe0), + BADC, 16, /* Design Capacity */ + BADV, 16, /* Design voltage */ + BASN, 16 + } + + /* PAGE = 2 */ + Field (ERAM, ByteAcc, NoLock, Preserve) + { + Offset (0xe0), + BANA, 128, /* Battery name */ + } + + /* PAGE = 4 */ + Field (ERAM, ByteAcc, NoLock, Preserve) + { + Offset (0xe0), + BATY, 128, /* Battery type */ + } + + /* PAGE = 5 */ + Field (ERAM, ByteAcc, NoLock, Preserve) + { + Offset (0xe0), + BAOE, 128, /* Battery OEM info */ + } + + Method (_CRS, 0) + { + Name (ECMD, ResourceTemplate() + { + IO (Decode16, 0x62, 0x62, 1, 1) + IO (Decode16, 0x66, 0x66, 1, 1) + }) + Return (ECMD) + } + Method (_INI, 0, NotSerialized) + { + } + + /* Decrease brightness. */ + Method(_Q1D, 0, NotSerialized) + { + \_SB.PCI0.GFX0.LCD0.DECB() + } + /* Increase brightness. */ + Method(_Q1C, 0, NotSerialized) + { + \_SB.PCI0.GFX0.LCD0.INCB() + } + +#include "battery.asl" +#include "ac.asl" +#include "thermal.asl" +} diff --git a/src/mainboard/packardbell/ms2290/acpi/gpe.asl b/src/mainboard/packardbell/ms2290/acpi/gpe.asl new file mode 100644 index 0000000..30fb365 --- /dev/null +++ b/src/mainboard/packardbell/ms2290/acpi/gpe.asl @@ -0,0 +1,25 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2011 Sven Schnelle <svens(a)stackframe.org> + * + * 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 "smi.h" +Scope (\_GPE) +{ +} diff --git a/src/mainboard/packardbell/ms2290/acpi/mainboard.asl b/src/mainboard/packardbell/ms2290/acpi/mainboard.asl new file mode 100644 index 0000000..e69de29 diff --git a/src/mainboard/packardbell/ms2290/acpi/nehalem_pci_irqs.asl b/src/mainboard/packardbell/ms2290/acpi/nehalem_pci_irqs.asl new file mode 100644 index 0000000..1f782c8 --- /dev/null +++ b/src/mainboard/packardbell/ms2290/acpi/nehalem_pci_irqs.asl @@ -0,0 +1,86 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Vladimir Serbinenko + * + * 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 + */ + +/* This is board specific information: IRQ routing. + */ + + +// PCI Interrupt Routing +Method(_PRT) +{ + If (PICM) { + Return (Package() { + Package() { 0x0001ffff, 0, 0, 0x10 }, + Package() { 0x0002ffff, 0, 0, 0x10 }, // VGA + Package() { 0x0003ffff, 0, 0, 0x10 }, + Package() { 0x0016ffff, 0, 0, 0x10 }, // ME + Package() { 0x0016ffff, 1, 0, 0x11 }, // ME + Package() { 0x0016ffff, 2, 0, 0x12 }, // ME + Package() { 0x0016ffff, 3, 0, 0x13 }, // ME + Package() { 0x0019ffff, 0, 0, 0x14 }, // Ethernet + Package() { 0x001affff, 0, 0, 0x14 }, // USB + Package() { 0x001affff, 1, 0, 0x15 }, // USB + Package() { 0x001affff, 2, 0, 0x16 }, // USB + Package() { 0x001affff, 3, 0, 0x17 }, // USB + Package() { 0x001bffff, 1, 0, 0x11 }, // Audio + Package() { 0x001cffff, 0, 0, 0x10 }, // PCI bridge + Package() { 0x001cffff, 1, 0, 0x11 }, // PCI bridge + Package() { 0x001cffff, 2, 0, 0x12 }, // PCI bridge + Package() { 0x001cffff, 3, 0, 0x13 }, // PCI bridge + Package() { 0x001dffff, 0, 0, 0x10 }, // USB + Package() { 0x001dffff, 1, 0, 0x11 }, // USB + Package() { 0x001dffff, 2, 0, 0x12 }, // USB + Package() { 0x001dffff, 3, 0, 0x13 }, // USB + Package() { 0x001fffff, 0, 0, 0x17 }, // LPC + Package() { 0x001fffff, 1, 0, 0x10 }, // IDE + Package() { 0x001fffff, 2, 0, 0x11 }, // SATA + Package() { 0x001fffff, 3, 0, 0x13 } // SMBUS + }) + } Else { + Return (Package() { + Package() { 0x0001ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, + Package() { 0x0002ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, // VGA + Package() { 0x0003ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, + Package() { 0x0016ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, // ME + Package() { 0x0016ffff, 1, \_SB.PCI0.LPCB.LNKB, 0 }, // ME + Package() { 0x0016ffff, 2, \_SB.PCI0.LPCB.LNKC, 0 }, // ME + Package() { 0x0016ffff, 3, \_SB.PCI0.LPCB.LNKD, 0 }, // ME + Package() { 0x0019ffff, 0, \_SB.PCI0.LPCB.LNKE, 0 }, // Ethernet + Package() { 0x001affff, 0, \_SB.PCI0.LPCB.LNKE, 0 }, // USB + Package() { 0x001affff, 1, \_SB.PCI0.LPCB.LNKF, 0 }, // USB + Package() { 0x001affff, 2, \_SB.PCI0.LPCB.LNKG, 0 }, // USB + Package() { 0x001affff, 3, \_SB.PCI0.LPCB.LNKH, 0 }, // USB + Package() { 0x001bffff, 1, \_SB.PCI0.LPCB.LNKB, 0 }, // Audio + Package() { 0x001cffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, // PCI + Package() { 0x001cffff, 1, \_SB.PCI0.LPCB.LNKB, 0 }, // PCI + Package() { 0x001cffff, 2, \_SB.PCI0.LPCB.LNKC, 0 }, // PCI + Package() { 0x001cffff, 3, \_SB.PCI0.LPCB.LNKD, 0 }, // PCI + Package() { 0x001dffff, 0, \_SB.PCI0.LPCB.LNKA, 0 }, // USB + Package() { 0x001dffff, 1, \_SB.PCI0.LPCB.LNKB, 0 }, // USB + Package() { 0x001dffff, 2, \_SB.PCI0.LPCB.LNKC, 0 }, // USB + Package() { 0x001dffff, 3, \_SB.PCI0.LPCB.LNKD, 0 }, // USB + Package() { 0x001fffff, 0, \_SB.PCI0.LPCB.LNKH, 0 }, // LPC + Package() { 0x001fffff, 1, \_SB.PCI0.LPCB.LNKA, 0 }, // IDE + Package() { 0x001fffff, 2, \_SB.PCI0.LPCB.LNKB, 0 }, // SATA + Package() { 0x001fffff, 3, \_SB.PCI0.LPCB.LNKD, 0 } // SMBus + }) + } +} diff --git a/src/mainboard/packardbell/ms2290/acpi/platform.asl b/src/mainboard/packardbell/ms2290/acpi/platform.asl new file mode 100644 index 0000000..3ca9dc5 --- /dev/null +++ b/src/mainboard/packardbell/ms2290/acpi/platform.asl @@ -0,0 +1,147 @@ +/* + * This file is part of the coreboot project. + * + * 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 + */ + +/* These come from the dynamically created CPU SSDT */ +External(PDC0) +External(PDC1) + +/* The APM port can be used for generating software SMIs */ + +OperationRegion (APMP, SystemIO, 0xb2, 2) +Field (APMP, ByteAcc, NoLock, Preserve) +{ + APMC, 8, /* APM command */ + APMS, 8 /* APM status */ +} + +/* SMI I/O Trap */ +Method(TRAP, 1, Serialized) +{ + Store (Arg0, SMIF) /* SMI Function */ + Store (0, TRP0) /* Generate trap */ + Return (SMIF) /* Return value of SMI handler */ +} + +/* 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, PICM) +} + +/* The _PTS method (Prepare To Sleep) is called before the OS is + * entering a sleep state. The sleep state number is passed in Arg0 + */ + +Method(_PTS,1) +{ +} + +/* The _WAK method is called on system wakeup */ + +Method(_WAK,1) +{ + /* Not implemented. */ + Return(Package(){0,0}) +} + +/* System Bus */ + +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) + { + /* The DTS data in NVS is probably not up to date. + * Update temperature values and make sure AP thermal + * interrupts can happen + */ + + /* TRAP(71) */ /* TODO */ + + /* 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)) { + 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 2001.1")) { + Store (2001, OSYS) + } + + If (_OSI("Windows 2001.1 SP1")) { + Store (2001, OSYS) + } + + If (_OSI("Windows 2006")) { + Store (2006, OSYS) + } + + If (_OSI("Windows 2006.1")) { + Store (2006, OSYS) + } + + If (_OSI("Windows 2006 SP1")) { + Store (2006, OSYS) + } + + If (_OSI("Windows 2009")) { + Store (2009, OSYS) + } + + If (_OSI("Windows 2012")) { + Store (2012, OSYS) + } + } + } +} + diff --git a/src/mainboard/packardbell/ms2290/acpi/superio.asl b/src/mainboard/packardbell/ms2290/acpi/superio.asl new file mode 100644 index 0000000..a2657f1 --- /dev/null +++ b/src/mainboard/packardbell/ms2290/acpi/superio.asl @@ -0,0 +1 @@ +#include "../../../../drivers/pc80/ps2_controller.asl" diff --git a/src/mainboard/packardbell/ms2290/acpi/thermal.asl b/src/mainboard/packardbell/ms2290/acpi/thermal.asl new file mode 100644 index 0000000..735171b --- /dev/null +++ b/src/mainboard/packardbell/ms2290/acpi/thermal.asl @@ -0,0 +1,48 @@ +Scope(\_TZ) +{ + Name (MEBT, 0) + + Method(C2K, 1, NotSerialized) + { + Multiply(Arg0, 10, Local0) + Add (Local0, 2732, Local0) + if (LLessEqual(Local0, 2732)) { + Return (3000) + } + + if (LGreater(Local0, 4012)) { + Return (3000) + } + Return (Local0) + } + + ThermalZone(THM0) + { + Method(_CRT, 0, NotSerialized) { + Return (C2K(127)) + } + Method(_TMP) { + /* Avoid tripping alarm if ME isn't booted at all yet */ + If (LAnd (LNot (MEBT), LEqual (\_SB.PCI0.LPCB.EC.TMP0, 128))) { + Return (C2K(40)) + } + Store (1, MEBT) + Return (C2K(\_SB.PCI0.LPCB.EC.TMP0)) + } + } + + ThermalZone(THM1) + { + Method(_CRT, 0, NotSerialized) { + Return (C2K(99)) + } + + Method(_PSV, 0, NotSerialized) { + Return (C2K(94)) + } + + Method(_TMP) { + Return (C2K(\_SB.PCI0.LPCB.EC.TMP1)) + } + } +} diff --git a/src/mainboard/packardbell/ms2290/acpi/video.asl b/src/mainboard/packardbell/ms2290/acpi/video.asl new file mode 100644 index 0000000..12a268b --- /dev/null +++ b/src/mainboard/packardbell/ms2290/acpi/video.asl @@ -0,0 +1,115 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2011 Sven Schnelle <svens(a)stackframe.org> + * Copyright (c) 2013 Vladimir Serbinenko + * + * 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 "smi.h" + +Scope (\_SB.PCI0.GFX0) +{ + Device (LCD0) + { + Name (_ADR, 0x0400) + Name (BRCT, 0) + + Name (BRIG, Package (0x12) + { + 0x61, + 0x61, + 0x2, + 0x4, + 0x5, + 0x7, + 0x9, + 0xb, + 0xd, + 0x11, + 0x14, + 0x17, + 0x1c, + 0x20, + 0x27, + 0x31, + 0x41, + 0x61, + }) + + Method (_BCL, 0, NotSerialized) + { + Store (1, BRCT) + Return (BRIG) + } + + Method (_BCM, 1, NotSerialized) + { + Store (ShiftLeft (Arg0, 4), ^^BCLV) + Store (0x80000000, ^^CR1) + Store (0x061a061a, ^^CR2) + } + Method (_BQC, 0, NotSerialized) + { + Store (^^BCLV, Local0) + ShiftRight (Local0, 4, Local0) + Return (Local0) + } + + Method(BRID, 1, NotSerialized) + { + Store (Match (BRIG, MEQ, Arg0, MTR, Zero, 2), Local0) + If (LEqual (Local0, Ones)) + { + Return (0x11) + } + Return (Local0) + } + + /* Using Notify is the right way. But Windows doesn't handle + it well. So use both method in a way to avoid double action. + */ + Method (DECB, 0, NotSerialized) + { + If (BRCT) + { + Notify (LCD0, 0x87) + } Else { + Store (BRID (_BQC ()), Local0) + If (LNotEqual (Local0, 2)) + { + Decrement (Local0) + } + _BCM (DerefOf (Index (BRIG, Local0))) + } + } + Method (INCB, 0, NotSerialized) + { + If (BRCT) + { + Notify (LCD0, 0x86) + } Else { + Store (BRID (_BQC ()), Local0) + If (LNotEqual (Local0, 0x11)) + { + Increment (Local0) + } + _BCM (DerefOf (Index (BRIG, Local0))) + } + } + } +} diff --git a/src/mainboard/packardbell/ms2290/acpi_tables.c b/src/mainboard/packardbell/ms2290/acpi_tables.c new file mode 100644 index 0000000..165de0d --- /dev/null +++ b/src/mainboard/packardbell/ms2290/acpi_tables.c @@ -0,0 +1,283 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2013 Vladimir Serbinenko <phcoder(a)gmail.com> + * + * 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 <console/console.h> +#include <arch/io.h> +#include <arch/ioapic.h> +#include <arch/acpi.h> +#include <arch/acpigen.h> +#include <arch/smp/mpspec.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include "southbridge/intel/ibexpeak/nvs.h" + +extern const unsigned char AmlCode[]; +#if CONFIG_HAVE_ACPI_SLIC +unsigned long acpi_create_slic(unsigned long current); +#endif + +static void acpi_create_gnvs(global_nvs_t * gnvs) +{ + memset((void *)gnvs, 0, sizeof(*gnvs)); + gnvs->apic = 1; + gnvs->mpen = 1; /* Enable Multi Processing */ + gnvs->pcnt = dev_count_cpu(); + + /* IGD Displays */ + gnvs->ndid = 3; + gnvs->did[0] = 0x80000100; + gnvs->did[1] = 0x80000240; + gnvs->did[2] = 0x80000410; + gnvs->did[3] = 0x80000410; + gnvs->did[4] = 0x00000005; +} + +unsigned long acpi_fill_madt(unsigned long current) +{ + /* Local APICs */ + current = acpi_create_madt_lapics(current); + + /* IOAPIC */ + current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, + 1, IO_APIC_ADDR, 0); + + /* INT_SRC_OVR */ + current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) + current, 0, 0, 2, + MP_IRQ_POLARITY_DEFAULT | + MP_IRQ_TRIGGER_DEFAULT); + current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) + current, 0, 9, 9, + MP_IRQ_POLARITY_HIGH | + MP_IRQ_TRIGGER_LEVEL); + + /* LAPIC_NMI */ + current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *) + current, 0, + MP_IRQ_POLARITY_HIGH | + MP_IRQ_TRIGGER_EDGE, 0x01); + current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *) + current, 1, MP_IRQ_POLARITY_HIGH | + MP_IRQ_TRIGGER_EDGE, 0x01); + current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *) + current, 2, MP_IRQ_POLARITY_HIGH | + MP_IRQ_TRIGGER_EDGE, 0x01); + current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *) + current, 3, MP_IRQ_POLARITY_HIGH | + MP_IRQ_TRIGGER_EDGE, 0x01); + return current; +} + +unsigned long acpi_fill_ssdt_generator(unsigned long current, + const char *oem_table_id) +{ + generate_cpu_entries(); + return (unsigned long)(acpigen_get_current()); +} + +unsigned long acpi_fill_slit(unsigned long current) +{ + /* Not implemented */ + return current; +} + +unsigned long acpi_fill_srat(unsigned long current) +{ + /* No NUMA, no SRAT */ + return current; +} + +void smm_setup_structures(void *gnvs, void *tcg, void *smi1); + +#define ALIGN_CURRENT current = (ALIGN(current, 16)) +unsigned long write_acpi_tables(unsigned long start) +{ + unsigned long current; + int i; + acpi_rsdp_t *rsdp; + acpi_rsdt_t *rsdt; + acpi_xsdt_t *xsdt; + acpi_hpet_t *hpet; + acpi_madt_t *madt; + acpi_mcfg_t *mcfg; + acpi_fadt_t *fadt; + acpi_facs_t *facs; +#if CONFIG_HAVE_ACPI_SLIC + acpi_header_t *slic; +#endif + acpi_header_t *ssdt; + acpi_header_t *dsdt; + void *gnvs; + + current = start; + + /* Align ACPI tables to 16byte */ + ALIGN_CURRENT; + + 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); + ALIGN_CURRENT; + rsdt = (acpi_rsdt_t *) current; + current += sizeof(acpi_rsdt_t); + ALIGN_CURRENT; + xsdt = (acpi_xsdt_t *) current; + current += sizeof(acpi_xsdt_t); + ALIGN_CURRENT; + + /* clear all table memory */ + memset((void *)start, 0, current - start); + + acpi_write_rsdp(rsdp, rsdt, xsdt); + acpi_write_rsdt(rsdt); + acpi_write_xsdt(xsdt); + + /* + * We explicitly add these tables later on: + */ + printk(BIOS_DEBUG, "ACPI: * HPET\n"); + + hpet = (acpi_hpet_t *) current; + current += sizeof(acpi_hpet_t); + ALIGN_CURRENT; + 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; + ALIGN_CURRENT; + acpi_add_table(rsdp, madt); + + printk(BIOS_DEBUG, "ACPI: * MCFG\n"); + mcfg = (acpi_mcfg_t *) current; + acpi_create_mcfg(mcfg); + current += mcfg->header.length; + ALIGN_CURRENT; + acpi_add_table(rsdp, mcfg); + + printk(BIOS_DEBUG, "ACPI: * FACS\n"); + facs = (acpi_facs_t *) current; + current += sizeof(acpi_facs_t); + ALIGN_CURRENT; + acpi_create_facs(facs); + + dsdt = (acpi_header_t *) current; + memcpy(dsdt, &AmlCode, sizeof(acpi_header_t)); + current += dsdt->length; + memcpy(dsdt, &AmlCode, dsdt->length); + + /* Fix up global NVS region for SMI handler. The GNVS region lives + * in the (high) table area. The low memory map looks like this: + * + * 0x00000000 - 0x000003ff Real Mode IVT + * 0x00000400 - 0x000004ff BDA (somewhat unused) + * 0x00000500 - 0x0000052f Moved GDT + * 0x00000530 - 0x00000b64 coreboot table + * 0x0007c000 - 0x0007dfff OS boot sector (unused?) + * 0x0007e000 - 0x0007ffff free to use (so no good for acpi+smi) + * 0x00080000 - 0x0009fbff usable ram + * 0x0009fc00 - 0x0009ffff EBDA (unused?) + * 0x000a0000 - 0x000bffff VGA memory + * 0x000c0000 - 0x000cffff VGA option rom + * 0x000d0000 - 0x000dffff free for other option roms? + * 0x000e0000 - 0x000fffff SeaBIOS? (if payload is SeaBIOS it + overwrites those tables when + loading but uses tables at the RAM + end to put the tables again in suitable + place) + * 0x000f0000 - 0x000f03ff PIRQ table + * 0x000f0400 - 0x000f66?? ACPI tables + * 0x000f66?? - 0x000f???? DMI tables + */ + + ALIGN_CURRENT; + + /* Pack GNVS into the ACPI table area */ + for (i = 0; i < dsdt->length; i++) { + if (*(u32 *) (((u32) dsdt) + i) == 0xC0DEBABE) { + printk(BIOS_DEBUG, + "ACPI: Patching up global NVS in DSDT at offset 0x%04x -> 0x%08x\n", + i, (u32) current); + *(u32 *) (((u32) dsdt) + i) = current; + break; + } + } + + /* And fill it */ + acpi_create_gnvs((global_nvs_t *) current); + + /* Keep pointer around */ + gnvs = (void *)current; + + current += 0x100; + ALIGN_CURRENT; + + /* And tell SMI about it */ + smm_setup_structures(gnvs, NULL, NULL); + + /* We patched up the DSDT, so we need to recalculate the checksum */ + dsdt->checksum = 0; + dsdt->checksum = acpi_checksum((void *)dsdt, dsdt->length); + + printk(BIOS_DEBUG, "ACPI: * DSDT @ %p Length %x\n", dsdt, + dsdt->length); + +#if CONFIG_HAVE_ACPI_SLIC + printk(BIOS_DEBUG, "ACPI: * SLIC\n"); + slic = (acpi_header_t *) current; + current += acpi_create_slic(current); + ALIGN_CURRENT; + acpi_add_table(rsdp, slic); +#endif + + printk(BIOS_DEBUG, "ACPI: * FADT\n"); + fadt = (acpi_fadt_t *) current; + current += sizeof(acpi_fadt_t); + ALIGN_CURRENT; + + acpi_create_fadt(fadt, facs, dsdt); + acpi_add_table(rsdp, fadt); + + printk(BIOS_DEBUG, "ACPI: * SSDT\n"); + ssdt = (acpi_header_t *) current; + acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR); + current += ssdt->length; + acpi_add_table(rsdp, ssdt); + ALIGN_CURRENT; + + printk(BIOS_DEBUG, "current = %lx\n", current); + printk(BIOS_INFO, "ACPI: done.\n"); + + /* Enable Dummy DCC ON# for DVI */ + printk(BIOS_DEBUG, "Laptop handling...\n"); + outb(inb(0x60f) & ~(1 << 5), 0x60f); + + return current; +} diff --git a/src/mainboard/packardbell/ms2290/board_info.txt b/src/mainboard/packardbell/ms2290/board_info.txt new file mode 100644 index 0000000..7df53c3 --- /dev/null +++ b/src/mainboard/packardbell/ms2290/board_info.txt @@ -0,0 +1,6 @@ +Board name: EasyNote LM85 (MS2290) +Category: laptop +ROM package: SOIC-8 +ROM protocol: SPI +ROM socketed: n +Flashrom support: n diff --git a/src/mainboard/packardbell/ms2290/cmos.default b/src/mainboard/packardbell/ms2290/cmos.default new file mode 100644 index 0000000..5820bfa --- /dev/null +++ b/src/mainboard/packardbell/ms2290/cmos.default @@ -0,0 +1,7 @@ +boot_option=Fallback +last_boot=Fallback +baud_rate=115200 +debug_level=Spew +power_on_after_fail=Enable +nmi=Enable +sata_mode=AHCI diff --git a/src/mainboard/packardbell/ms2290/cmos.layout b/src/mainboard/packardbell/ms2290/cmos.layout new file mode 100644 index 0000000..0f753b2 --- /dev/null +++ b/src/mainboard/packardbell/ms2290/cmos.layout @@ -0,0 +1,131 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2007-2008 coresystems GmbH +## Copyright (C) 2013 Vladimir Serbinenko +## +## 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 +## + +# ----------------------------------------------------------------- +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 +# ----------------------------------------------------------------- +# Status Register A +#80 4 r 0 rate_select +#84 3 r 0 REF_Clock +#87 1 r 0 UIP +# ----------------------------------------------------------------- +# Status Register B +#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 +# ----------------------------------------------------------------- +# Status Register C +#96 4 r 0 status_c_rsvd +#100 1 r 0 uf_flag +#101 1 r 0 af_flag +#102 1 r 0 pf_flag +#103 1 r 0 irqf_flag +# ----------------------------------------------------------------- +# Status Register D +#104 7 r 0 status_d_rsvd +#111 1 r 0 valid_cmos_ram +# ----------------------------------------------------------------- +# Diagnostic Status Register +#112 8 r 0 diag_rsvd1 + +# ----------------------------------------------------------------- +0 120 r 0 reserved_memory +#120 264 r 0 unused + +# ----------------------------------------------------------------- +# RTC_BOOT_BYTE (coreboot hardcoded) +384 1 e 4 boot_option +385 1 e 4 last_boot +388 4 r 0 reboot_bits +#390 2 r 0 unused? + +# ----------------------------------------------------------------- +# coreboot config options: console +392 3 e 5 baud_rate +395 4 e 6 debug_level +#399 1 r 0 unused + +# coreboot config options: southbridge +408 1 e 1 nmi +409 2 e 7 power_on_after_fail +411 1 e 9 sata_mode + +# coreboot config options: check sums +984 16 h 0 check_sum +#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 1 Emergency +6 2 Alert +6 3 Critical +6 4 Error +6 5 Warning +6 6 Notice +6 7 Info +6 8 Debug +6 9 Spew +7 0 Disable +7 1 Enable +7 2 Keep +8 0 Secondary +8 1 Primary +9 0 AHCI +9 1 Compatible +# ----------------------------------------------------------------- +checksums + +checksum 392 415 984 + + diff --git a/src/mainboard/packardbell/ms2290/devicetree.cb b/src/mainboard/packardbell/ms2290/devicetree.cb new file mode 100644 index 0000000..a57a2c1 --- /dev/null +++ b/src/mainboard/packardbell/ms2290/devicetree.cb @@ -0,0 +1,104 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2007-2009 coresystems GmbH +## Copyright (C) 2011 Sven Schnelle <svens(a)stackframe.org> +## +## 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 +## + +chip northbridge/intel/nehalem + + register "gpu_dp_b_hotplug" = "0x04" + register "gpu_dp_c_hotplug" = "0x04" + register "gpu_dp_d_hotplug" = "0x04" + + # Enable Panel as LVDS and configure power delays + register "gpu_panel_port_select" = "0" # LVDS + register "gpu_panel_power_cycle_delay" = "6" + register "gpu_panel_power_up_delay" = "300" + register "gpu_panel_power_down_delay" = "300" + register "gpu_panel_power_backlight_on_delay" = "3000" + register "gpu_panel_power_backlight_off_delay" = "3000" + register "gpu_cpu_backlight" = "0x58d" + register "gpu_pch_backlight" = "0x061a061a" + register "gpu_use_spread_spectrum_clock" = "0" + register "gpu_lvds_dual_channel" = "1" + register "gpu_link_frequency_270_mhz" = "1" + register "gpu_lvds_num_lanes" = "4" + + device cpu_cluster 0 on + chip cpu/intel/model_2065x + device lapic 0 on end + end + end + + device domain 0 on + device pci 00.0 on # Host bridge + subsystemid 0x1025 0x0379 + end + device pci 02.0 on # VGA controller + subsystemid 0x1025 0x0379 + end + chip southbridge/intel/ibexpeak + register "pirqa_routing" = "0x0b" + register "pirqb_routing" = "0x0b" + register "pirqc_routing" = "0x0b" + register "pirqd_routing" = "0x0b" + register "pirqe_routing" = "0x0b" + register "pirqf_routing" = "0x0b" + register "pirqg_routing" = "0x0b" + register "pirqh_routing" = "0x0b" + + # GPI routing + # 0 No effect (default) + # 1 SMI# (if corresponding ALT_GPI_SMI_EN bit is also set) + # 2 SCI (if corresponding GPIO_EN bit is also set) + register "gpi7_routing" = "2" + register "gpi8_routing" = "2" + + register "sata_port_map" = "0x11" + + register "gpe0_en" = "0x01800046" + register "alt_gp_smi_en" = "0x0000" + register "gen1_dec" = "0x040069" + + device pci 1a.0 on # USB2 EHCI + subsystemid 0x1025 0x0379 + end + + device pci 1b.0 on # Audio Controller + subsystemid 0x1025 0x0379 + end + + device pci 1c.0 on end # PCIe Port #1 + device pci 1c.1 on end # PCIe Port #1 + + device pci 1d.0 on # USB2 EHCI + subsystemid 0x1025 0x0379 + end + device pci 1f.0 on # PCI-LPC bridge + subsystemid 0x1025 0x0379 + end + device pci 1f.2 on # IDE/SATA + subsystemid 0x1025 0x0379 + end + device pci 1f.3 on # SMBUS + subsystemid 0x1025 0x0379 + end + end + end +end diff --git a/src/mainboard/packardbell/ms2290/dsdt.asl b/src/mainboard/packardbell/ms2290/dsdt.asl new file mode 100644 index 0000000..85542bf --- /dev/null +++ b/src/mainboard/packardbell/ms2290/dsdt.asl @@ -0,0 +1,91 @@ +/* + * This file is part of the coreboot project. + * + * 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 + */ + +DefinitionBlock( + "dsdt.aml", + "DSDT", + 0x03, /* DSDT revision: ACPI v3.0 */ + "COREv4", /* OEM id */ + "COREBOOT", /* OEM table id */ + 0x20140108 /* OEM revision */ +) +{ + /* Some generic macros */ + #include "acpi/platform.asl" + + /* global NVS and variables */ + #include <southbridge/intel/bd82x6x/acpi/globalnvs.asl> + + /* General Purpose Events */ + #include "acpi/gpe.asl" + + /* mainboard specific devices */ + #include "acpi/mainboard.asl" + + #include <cpu/intel/model_206ax/acpi/cpu.asl> + + Scope (\_SB) { + Device (PCI0) + { + #include <northbridge/intel/nehalem/acpi/nehalem.asl> + #include <southbridge/intel/bd82x6x/acpi/pch.asl> + } + Device (UNCR) + { + Name (_BBN, 0xFF) + Name (_ADR, 0x00) + Name (RID, 0x00) + Name (_HID, EisaId ("PNP0A03")) + Name (_CRS, ResourceTemplate () + { + WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode, + 0x0000, /* Granularity */ + 0x00FF, /* Range Minimum */ + 0x00FF, /* Range Maximum */ + 0x0000, /* Translation Offset */ + 0x0001, /* Length */ + ,, ) + }) + Device (SAD) + { + Name (_ADR, 0x01) + Name (RID, 0x00) + OperationRegion (SADC, PCI_Config, 0x00, 0x0100) + Field (SADC, DWordAcc, NoLock, Preserve) + { + Offset (0x40), + PAM0, 8, + PAM1, 8, + PAM2, 8, + PAM3, 8, + PAM4, 8, + PAM5, 8, + PAM6, 8 + } + } + } + } + + #include "acpi/video.asl" + + /* Chipset specific sleep states */ + #include <southbridge/intel/i82801gx/acpi/sleepstates.asl> +} diff --git a/src/mainboard/packardbell/ms2290/fadt.c b/src/mainboard/packardbell/ms2290/fadt.c new file mode 100644 index 0000000..0639026 --- /dev/null +++ b/src/mainboard/packardbell/ms2290/fadt.c @@ -0,0 +1,160 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2008 coresystems GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <string.h> +#include <device/pci.h> +#include <arch/acpi.h> +#include <cpu/x86/smm.h> + +/* FIXME: This needs to go into a separate .h file + * to be included by the ich7 smi handler, ich7 smi init + * code and the mainboard fadt. + */ + +void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt) +{ + acpi_header_t *header = &(fadt->header); + u16 pmbase = + pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f, 0)), + 0x40) & 0xfffe; + + memset((void *)fadt, 0, sizeof(acpi_fadt_t)); + memcpy(header->signature, "FACP", 4); + header->length = sizeof(acpi_fadt_t); + header->revision = 3; + memcpy(header->oem_id, OEM_ID, 6); + memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); + memcpy(header->asl_compiler_id, ASLC, 4); + header->asl_compiler_revision = 0; + + fadt->firmware_ctrl = (unsigned long)facs; + fadt->dsdt = (unsigned long)dsdt; + fadt->model = 0x00; + fadt->preferred_pm_profile = PM_MOBILE; + fadt->sci_int = 0x9; + fadt->smi_cmd = APM_CNT; + fadt->acpi_enable = APM_CNT_ACPI_ENABLE; + fadt->acpi_disable = APM_CNT_ACPI_DISABLE; + fadt->s4bios_req = 0x0; + fadt->pstate_cnt = APM_CNT_PST_CONTROL; + + fadt->pm1a_evt_blk = pmbase; + fadt->pm1b_evt_blk = 0x0; + fadt->pm1a_cnt_blk = pmbase + 0x4; + fadt->pm1b_cnt_blk = 0x0; + fadt->pm2_cnt_blk = pmbase + 0x50; + fadt->pm_tmr_blk = pmbase + 0x8; + fadt->gpe0_blk = pmbase + 0x20; + fadt->gpe1_blk = 0; + + fadt->pm1_evt_len = 4; + fadt->pm1_cnt_len = 2; + fadt->pm2_cnt_len = 1; + fadt->pm_tmr_len = 4; + fadt->gpe0_blk_len = 0x10; + fadt->gpe1_blk_len = 0; + fadt->gpe1_base = 0; + fadt->cst_cnt = APM_CNT_CST_CONTROL; + fadt->p_lvl2_lat = 1; + fadt->p_lvl3_lat = 0x23; + fadt->flush_size = 0; + fadt->flush_stride = 0; + fadt->duty_offset = 1; + fadt->duty_width = 3; + fadt->day_alrm = 0xd; + fadt->mon_alrm = 0x00; + fadt->century = 0x32; + fadt->iapc_boot_arch = 0x00; + fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED | + ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_S4_RTC_WAKE | + ACPI_FADT_DOCKING_SUPPORTED; + + fadt->reset_reg.space_id = 0; + fadt->reset_reg.bit_width = 0; + fadt->reset_reg.bit_offset = 0; + fadt->reset_reg.resv = 0; + fadt->reset_reg.addrl = 0x0; + fadt->reset_reg.addrh = 0x0; + + fadt->reset_value = 0; + fadt->x_firmware_ctl_l = (unsigned long)facs; + fadt->x_firmware_ctl_h = 0; + fadt->x_dsdt_l = (unsigned long)dsdt; + fadt->x_dsdt_h = 0; + + fadt->x_pm1a_evt_blk.space_id = 1; + fadt->x_pm1a_evt_blk.bit_width = 32; + fadt->x_pm1a_evt_blk.bit_offset = 0; + fadt->x_pm1a_evt_blk.resv = 0; + fadt->x_pm1a_evt_blk.addrl = pmbase; + fadt->x_pm1a_evt_blk.addrh = 0x0; + + fadt->x_pm1b_evt_blk.space_id = 0; + fadt->x_pm1b_evt_blk.bit_width = 0; + fadt->x_pm1b_evt_blk.bit_offset = 0; + fadt->x_pm1b_evt_blk.resv = 0; + fadt->x_pm1b_evt_blk.addrl = 0x0; + fadt->x_pm1b_evt_blk.addrh = 0x0; + + fadt->x_pm1a_cnt_blk.space_id = 1; + fadt->x_pm1a_cnt_blk.bit_width = 32; + fadt->x_pm1a_cnt_blk.bit_offset = 0; + fadt->x_pm1a_cnt_blk.resv = 0; + fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4; + fadt->x_pm1a_cnt_blk.addrh = 0x0; + + fadt->x_pm1b_cnt_blk.space_id = 0; + fadt->x_pm1b_cnt_blk.bit_width = 0; + fadt->x_pm1b_cnt_blk.bit_offset = 0; + fadt->x_pm1b_cnt_blk.resv = 0; + fadt->x_pm1b_cnt_blk.addrl = 0x0; + fadt->x_pm1b_cnt_blk.addrh = 0x0; + + fadt->x_pm2_cnt_blk.space_id = 1; + fadt->x_pm2_cnt_blk.bit_width = 8; + fadt->x_pm2_cnt_blk.bit_offset = 0; + fadt->x_pm2_cnt_blk.resv = 0; + fadt->x_pm2_cnt_blk.addrl = pmbase + 0x50; + fadt->x_pm2_cnt_blk.addrh = 0x0; + + fadt->x_pm_tmr_blk.space_id = 1; + fadt->x_pm_tmr_blk.bit_width = 32; + fadt->x_pm_tmr_blk.bit_offset = 0; + fadt->x_pm_tmr_blk.resv = 0; + fadt->x_pm_tmr_blk.addrl = pmbase + 0x8; + fadt->x_pm_tmr_blk.addrh = 0x0; + + fadt->x_gpe0_blk.space_id = 1; + fadt->x_gpe0_blk.bit_width = 128; + fadt->x_gpe0_blk.bit_offset = 0; + fadt->x_gpe0_blk.resv = 0; + fadt->x_gpe0_blk.addrl = pmbase + 0x20; + fadt->x_gpe0_blk.addrh = 0x0; + + fadt->x_gpe1_blk.space_id = 0; + fadt->x_gpe1_blk.bit_width = 0; + fadt->x_gpe1_blk.bit_offset = 0; + fadt->x_gpe1_blk.resv = 0; + fadt->x_gpe1_blk.addrl = 0x0; + fadt->x_gpe1_blk.addrh = 0x0; + + header->checksum = acpi_checksum((void *)fadt, header->length); +} diff --git a/src/mainboard/packardbell/ms2290/gma.c b/src/mainboard/packardbell/ms2290/gma.c new file mode 100644 index 0000000..540d858 --- /dev/null +++ b/src/mainboard/packardbell/ms2290/gma.c @@ -0,0 +1,272 @@ +#include <arch/io.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> + +#include "northbridge/intel/nehalem/nehalem.h" + +/* This array contains the information on flat panel. When using native + graphics init coreboot copies it to where VGA Option ROM would be so + that OS can find it and able to use internal display. This contains no + executable code and is just information on the panel. + */ + +unsigned char fake_vbt[] = { +0x24, 0x56, 0x42, 0x54, 0x20, 0x49, 0x52, 0x4f, 0x4e, 0x4c, 0x41, 0x4b, 0x45, 0x2d, 0x4d, 0x4f, +0x42, 0x49, 0x4c, 0x45, 0x64, 0x00, 0x30, 0x00, 0xc3, 0x10, 0xa4, 0x00, 0x30, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x42, 0x49, 0x4f, 0x53, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x20, +0x9b, 0x00, 0x16, 0x00, 0x93, 0x10, 0xfe, 0xea, 0x00, 0x00, 0x64, 0x01, 0x01, 0x0f, 0x0d, 0x31, +0x39, 0x39, 0x34, 0x49, 0x6e, 0x74, 0x65, 0x6c, 0x28, 0x52, 0x29, 0x49, 0x72, 0x6f, 0x6e, 0x6c, +0x61, 0x6b, 0x65, 0x20, 0x4d, 0x6f, 0x62, 0x69, 0x6c, 0x65, 0x20, 0x50, 0x43, 0x49, 0x20, 0x41, +0x63, 0x63, 0x65, 0x6c, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x53, 0x56, 0x47, 0x41, 0x20, +0x42, 0x49, 0x4f, 0x53, 0x0d, 0x0a, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x20, 0x4e, 0x75, 0x6d, 0x62, +0x65, 0x72, 0x3a, 0x20, 0x69, 0x6c, 0x6d, 0x31, 0x39, 0x39, 0x34, 0x31, 0x2e, 0x6a, 0x76, 0x37, +0x20, 0x50, 0x43, 0x20, 0x31, 0x34, 0x2e, 0x33, 0x34, 0x20, 0x20, 0x30, 0x35, 0x2f, 0x32, 0x36, +0x2f, 0x32, 0x30, 0x31, 0x30, 0x20, 0x20, 0x31, 0x39, 0x3a, 0x32, 0x32, 0x3a, 0x30, 0x33, 0x0d, +0x0a, 0x44, 0x45, 0x43, 0x4f, 0x4d, 0x50, 0x49, 0x4c, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x20, 0x4f, +0x52, 0x20, 0x44, 0x49, 0x53, 0x41, 0x53, 0x53, 0x45, 0x4d, 0x42, 0x4c, 0x59, 0x20, 0x50, 0x52, +0x4f, 0x48, 0x49, 0x42, 0x49, 0x54, 0x45, 0x44, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, +0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, 0x32, 0x30, 0x30, 0x30, +0x2d, 0x32, 0x30, 0x30, 0x33, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x6c, 0x20, 0x43, 0x6f, 0x72, 0x70, +0x2e, 0x20, 0x41, 0x6c, 0x6c, 0x20, 0x52, 0x69, 0x67, 0x68, 0x74, 0x73, 0x20, 0x52, 0x65, 0x73, +0x65, 0x72, 0x76, 0x65, 0x64, 0x2e, 0x0d, 0x0a, 0x0d, 0x0a, 0x00, 0x00, 0xc0, 0x03, 0x08, 0x04, +0x01, 0x00, 0x00, 0x01, 0x05, 0x00, 0x07, 0x01, 0x00, 0x01, 0x01, 0xfe, 0x20, 0x00, 0x01, 0x01, +0x08, 0x08, 0x04, 0x04, 0x09, 0x08, 0x0c, 0x08, 0x05, 0x04, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0d, +0x01, 0x02, 0x04, 0x00, 0x00, 0x21, 0x08, 0x00, 0x22, 0x10, 0x00, 0x4c, 0x46, 0x50, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xc0, 0xd1, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xd2, 0x60, 0x00, 0x20, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xe4, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x05, +0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, +0x00, 0x00, 0x04, 0x1c, 0x00, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x40, 0x42, 0x44, 0x46, +0x48, 0x4a, 0x4c, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x80, 0x81, 0x82, 0x83, 0x84, 0x1a, +0x00, 0xfe, 0xac, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, +0x01, 0x00, 0x00, 0x00, 0x0e, 0x01, 0x20, 0x00, 0xf4, 0x07, 0x1e, 0x00, 0x8e, 0x04, 0x28, 0x00, +0xbb, 0x04, 0x02, 0x00, 0xc5, 0x04, 0x38, 0x00, 0x06, 0x05, 0xc8, 0x00, 0x54, 0x07, 0x30, 0x00, +0x87, 0x07, 0x18, 0x00, 0xa2, 0x07, 0x18, 0x00, 0xbd, 0x07, 0x18, 0x00, 0xc0, 0x08, 0x08, 0x00, +0x04, 0x09, 0x12, 0x00, 0x16, 0x09, 0x12, 0x00, 0x28, 0x09, 0x12, 0x00, 0x3a, 0x09, 0x12, 0x00, +0x4f, 0x09, 0x0a, 0x00, 0x59, 0x09, 0x0a, 0x00, 0x63, 0x09, 0x0a, 0x00, 0x6d, 0x09, 0x0a, 0x00, +0x7a, 0x09, 0x0a, 0x00, 0x84, 0x09, 0x0a, 0x00, 0x8e, 0x09, 0x0a, 0x00, 0x98, 0x09, 0x0a, 0x00, +0xaa, 0x09, 0x0a, 0x00, 0xb4, 0x09, 0x0a, 0x00, 0xbe, 0x09, 0x0a, 0x00, 0xc8, 0x09, 0x0a, 0x00, +0xd2, 0x09, 0x0a, 0x00, 0xdc, 0x09, 0x0a, 0x00, 0xe6, 0x09, 0x0a, 0x00, 0xf0, 0x09, 0x0a, 0x00, +0xfa, 0x09, 0x0a, 0x00, 0x04, 0x0a, 0x0a, 0x00, 0x0e, 0x0a, 0x0a, 0x00, 0x18, 0x0a, 0x0a, 0x00, +0x22, 0x0a, 0x0a, 0x00, 0x2c, 0x0a, 0x0a, 0x00, 0x36, 0x0a, 0x0a, 0x00, 0x40, 0x0a, 0x0a, 0x00, +0x06, 0xa5, 0x01, 0xfc, 0xff, 0x02, 0x14, 0x60, 0x0c, 0x00, 0x80, 0x00, 0x80, 0x04, 0x40, 0x60, +0x0c, 0x00, 0x07, 0x0d, 0x03, 0x00, 0x44, 0x60, 0x0c, 0x00, 0x07, 0x0d, 0x03, 0x00, 0x18, 0x60, +0x0c, 0x00, 0x80, 0x00, 0x80, 0x04, 0x48, 0x60, 0x0c, 0x00, 0x07, 0x0d, 0x03, 0x00, 0x4c, 0x60, +0x0c, 0x00, 0x07, 0x0d, 0x03, 0x00, 0x80, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, +0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, +0x04, 0x00, 0x00, 0x00, 0x00, 0x80, 0x9c, 0x01, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x11, +0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x7f, 0x02, 0x1f, 0x03, 0x04, 0x00, +0x06, 0x00, 0x87, 0x02, 0x17, 0x03, 0x08, 0x00, 0x06, 0x00, 0x8f, 0x02, 0xef, 0x02, 0x0c, 0x00, +0x06, 0x00, 0xdf, 0x01, 0x0c, 0x02, 0x10, 0x00, 0x06, 0x00, 0xe7, 0x01, 0x04, 0x02, 0x14, 0x00, +0x06, 0x00, 0xe9, 0x01, 0xeb, 0x01, 0x1c, 0x00, 0x06, 0x00, 0xdf, 0x01, 0x7f, 0x02, 0x00, 0x10, +0x06, 0x00, 0x7f, 0x02, 0x1f, 0x03, 0x04, 0x10, 0x06, 0x00, 0x87, 0x02, 0x17, 0x03, 0x08, 0x10, +0x06, 0x00, 0x8f, 0x02, 0xef, 0x02, 0x0c, 0x10, 0x06, 0x00, 0xdf, 0x01, 0x0c, 0x02, 0x10, 0x10, +0x06, 0x00, 0xe7, 0x01, 0x04, 0x02, 0x14, 0x10, 0x06, 0x00, 0xe9, 0x01, 0xeb, 0x01, 0x1c, 0x10, +0x06, 0x00, 0xdf, 0x01, 0x7f, 0x02, 0x00, 0x00, 0x0e, 0x00, 0x7f, 0x02, 0x1f, 0x03, 0x04, 0x00, +0x0e, 0x00, 0x87, 0x02, 0x17, 0x03, 0x08, 0x00, 0x0e, 0x00, 0x8f, 0x02, 0xef, 0x02, 0x0c, 0x00, +0x0e, 0x00, 0xdf, 0x01, 0x0c, 0x02, 0x10, 0x00, 0x0e, 0x00, 0xe7, 0x01, 0x04, 0x02, 0x14, 0x00, +0x0e, 0x00, 0xe9, 0x01, 0xeb, 0x01, 0x00, 0x10, 0x0e, 0x00, 0x7f, 0x02, 0x1f, 0x03, 0x04, 0x10, +0x0e, 0x00, 0x87, 0x02, 0x17, 0x03, 0x08, 0x10, 0x0e, 0x00, 0x8f, 0x02, 0xef, 0x02, 0x0c, 0x10, +0x0e, 0x00, 0xdf, 0x01, 0x0c, 0x02, 0x10, 0x10, 0x0e, 0x00, 0xe7, 0x01, 0x04, 0x02, 0x14, 0x10, +0x0e, 0x00, 0xe9, 0x01, 0xeb, 0x01, 0x00, 0x50, 0x04, 0x00, 0x22, 0x06, 0x24, 0xc2, 0x08, 0x00, +0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, +0x04, 0x00, 0x8e, 0x29, 0x00, 0x80, 0x00, 0x11, 0x0e, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x40, +0x06, 0x00, 0x18, 0x00, 0x00, 0x00, 0x40, 0x11, 0x0e, 0x00, 0x18, 0x00, 0x00, 0x00, 0x50, 0x11, +0x0e, 0x00, 0x18, 0x00, 0x00, 0x00, 0x60, 0x11, 0x0e, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x07, 0x07, 0x00, 0xfe, 0xff, 0xce, 0x18, 0x00, +0xff, 0xff, 0x08, 0x3d, 0x00, 0xfc, 0xff, 0x02, 0x40, 0xf0, 0x04, 0x00, 0x01, 0x00, 0x00, 0x01, +0x44, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, +0x4c, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x03, 0x03, 0x50, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, +0x54, 0xf0, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x58, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, +0xff, 0xff, 0x0a, 0xcb, 0x00, 0x0a, 0x80, 0x02, 0xe0, 0x01, 0xff, 0xff, 0xff, 0xda, 0xff, 0xff, +0x20, 0x03, 0x58, 0x02, 0xff, 0x03, 0xfe, 0x07, 0xff, 0xff, 0x00, 0x04, 0x00, 0x03, 0xff, 0x1b, +0xfe, 0x07, 0xff, 0xff, 0x80, 0x04, 0x60, 0x03, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0x00, 0x05, +0x58, 0x02, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0x00, 0x05, 0xd0, 0x02, 0xff, 0x1b, 0xff, 0xbf, +0xff, 0xff, 0x00, 0x05, 0x00, 0x03, 0xff, 0x9b, 0xff, 0xbf, 0xff, 0xff, 0x00, 0x05, 0xc0, 0x03, +0xff, 0x9b, 0xff, 0x07, 0xff, 0xff, 0x00, 0x05, 0x00, 0x04, 0xff, 0x1b, 0xfe, 0x07, 0xff, 0xff, +0x56, 0x05, 0x00, 0x03, 0xff, 0x9b, 0xff, 0x07, 0xff, 0xff, 0x40, 0x06, 0x84, 0x03, 0xff, 0x1b, +0xfe, 0x07, 0xff, 0xff, 0x40, 0x06, 0xb0, 0x04, 0xff, 0x1b, 0xfe, 0x07, 0xff, 0xff, 0x00, 0x07, +0x40, 0x05, 0xff, 0xff, 0xff, 0x07, 0xff, 0xff, 0x40, 0x07, 0x70, 0x05, 0xff, 0xff, 0xff, 0x07, +0xff, 0xff, 0x80, 0x07, 0x38, 0x04, 0xff, 0x1b, 0xff, 0x07, 0xff, 0xff, 0x80, 0x07, 0xb0, 0x04, +0xff, 0xdb, 0xff, 0x07, 0xff, 0xff, 0x80, 0x07, 0xa0, 0x05, 0xff, 0x9b, 0xff, 0x07, 0xff, 0xff, +0x00, 0x08, 0x00, 0x06, 0xff, 0xdb, 0xff, 0x07, 0xff, 0xff, 0x78, 0x05, 0x1a, 0x04, 0xff, 0x9b, +0xff, 0x07, 0xff, 0xff, 0x90, 0x06, 0xb1, 0x03, 0xff, 0x1b, 0xff, 0x07, 0xff, 0xff, 0x00, 0x00, +0x0b, 0xc7, 0x00, 0x21, 0x40, 0x00, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x09, 0x06, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x72, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x03, 0x20, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x11, 0x00, 0x4e, 0x56, 0x05, +0x00, 0x03, 0x10, 0x3c, 0x84, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x01, 0x0d, 0x03, +0x00, 0x78, 0x01, 0x0a, 0x0e, 0x09, 0x00, 0x01, 0xc5, 0x06, 0x5a, 0x00, 0x21, 0x07, 0x2d, 0x00, +0x0f, 0x8b, 0x00, 0x09, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, +0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x84, +0x00, 0x10, 0x00, 0x03, 0x01, 0x08, 0x00, 0x04, 0x08, 0x00, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, +0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x01, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x08, 0x00, +0x02, 0x00, 0x00, 0x01, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, +0x00, 0x03, 0x01, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x01, 0x04, +0x00, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x01, 0x00, 0x00, +0x01, 0x08, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x01, 0x04, 0x00, 0x04, 0x00, 0x00, 0x04, +0x08, 0x00, 0x00, 0x00, 0x00, 0x11, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x12, 0x0c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, +0x20, 0x00, 0x0f, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x14, 0x9e, 0x00, 0x06, 0x1a, 0x03, 0x99, 0x00, 0x05, 0x20, 0x03, 0x07, 0x3c, 0xa9, +0x20, 0x00, 0x90, 0x51, 0x20, 0x1c, 0x30, 0x08, 0x88, 0x93, 0x00, 0x00, 0x20, 0x53, 0x00, 0x00, +0x00, 0x01, 0x99, 0xa0, 0x05, 0x84, 0x03, 0x07, 0x3c, 0xab, 0x22, 0xa0, 0xa0, 0x50, 0x84, 0x1a, +0x30, 0x30, 0x20, 0x36, 0x00, 0x2f, 0xbe, 0x10, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x07, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x3c, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, +0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x16, 0x4b, 0x00, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x84, 0x0e, 0x00, 0x00, 0x4c, 0x46, 0x50, +0x5f, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x46, 0x50, 0x5f, 0x50, 0x61, +0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x46, 0x50, 0x5f, 0x50, 0x61, 0x6e, 0x65, 0x6c, +0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x46, 0x50, 0x5f, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, +0x65, 0x17, 0x48, 0x00, 0x64, 0x19, 0x00, 0x40, 0x41, 0x00, 0x26, 0x30, 0x18, 0x88, 0x36, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x2a, 0x00, 0x98, 0x51, 0x00, 0x30, 0x40, 0x30, 0x70, +0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xa8, 0x2f, 0x78, 0xe0, 0x51, 0x1a, 0x26, 0x40, +0x58, 0x98, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x48, 0x3f, 0x40, 0x30, 0x62, 0xb0, +0x32, 0x40, 0x40, 0xc0, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x18, 0x28, 0x00, 0x36, +0x7f, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x36, 0x7f, 0x05, 0x00, 0x02, 0x00, 0x00, +0x00, 0x00, 0x0c, 0x36, 0x7f, 0x01, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x36, 0x7f, 0x06, +0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x19, 0x28, 0x00, 0x19, 0x00, 0xfa, 0x00, 0xfa, 0x00, +0x19, 0x00, 0x90, 0x01, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0xc8, 0x00, 0x40, 0x00, +0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x2c, 0x01, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, +0x2c, 0x01, 0x1a, 0x02, 0x00, 0x00, 0x00, 0x1b, 0xc8, 0x00, 0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, +0xf4, 0x01, 0x88, 0x13, 0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, 0xd0, 0x07, +0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, 0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, +0x88, 0x13, 0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, 0xd0, 0x07, 0x0a, 0x00, +0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, 0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, +0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, 0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, +0xf4, 0x01, 0x88, 0x13, 0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, 0xd0, 0x07, +0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, 0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, +0x88, 0x13, 0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, 0xd0, 0x07, 0x0a, 0x00, +0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, 0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, +0xd0, 0x07, 0x0a, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x88, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x28, 0x18, 0x00, 0x02, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x94, 0x00, +0x03, 0x27, 0x0b, 0x20, 0x4d, 0x0b, 0x12, 0x5f, 0x0b, 0x0a, 0x69, 0x0b, 0x20, 0x8f, 0x0b, 0x12, +0xa1, 0x0b, 0x0a, 0xab, 0x0b, 0x20, 0xd1, 0x0b, 0x12, 0xe3, 0x0b, 0x0a, 0xed, 0x0b, 0x20, 0x13, +0x0c, 0x12, 0x25, 0x0c, 0x0a, 0x2f, 0x0c, 0x20, 0x55, 0x0c, 0x12, 0x67, 0x0c, 0x0a, 0x71, 0x0c, +0x20, 0x97, 0x0c, 0x12, 0xa9, 0x0c, 0x0a, 0xb3, 0x0c, 0x20, 0xd9, 0x0c, 0x12, 0xeb, 0x0c, 0x0a, +0xf5, 0x0c, 0x20, 0x1b, 0x0d, 0x12, 0x2d, 0x0d, 0x0a, 0x37, 0x0d, 0x20, 0x5d, 0x0d, 0x12, 0x6f, +0x0d, 0x0a, 0x79, 0x0d, 0x20, 0x9f, 0x0d, 0x12, 0xb1, 0x0d, 0x0a, 0xbb, 0x0d, 0x20, 0xe1, 0x0d, +0x12, 0xf3, 0x0d, 0x0a, 0xfd, 0x0d, 0x20, 0x23, 0x0e, 0x12, 0x35, 0x0e, 0x0a, 0x3f, 0x0e, 0x20, +0x65, 0x0e, 0x12, 0x77, 0x0e, 0x0a, 0x81, 0x0e, 0x20, 0xa7, 0x0e, 0x12, 0xb9, 0x0e, 0x0a, 0xc3, +0x0e, 0x20, 0xe9, 0x0e, 0x12, 0xfb, 0x0e, 0x0a, 0x05, 0x0f, 0x20, 0x2b, 0x0f, 0x12, 0x3d, 0x0f, +0x0a, 0x47, 0x0f, 0x0d, 0x2a, 0xf0, 0x04, 0x80, 0x02, 0xe0, 0x01, 0x80, 0x11, 0x0e, 0x00, 0x00, +0x03, 0x00, 0x00, 0x08, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0x58, 0x02, 0x0c, 0x72, 0x0c, 0x00, 0xd0, +0x07, 0xf4, 0x01, 0x10, 0x72, 0x0c, 0x00, 0x05, 0x0f, 0x27, 0x00, 0xff, 0xff, 0xd6, 0x09, 0x80, +0x90, 0x20, 0xe0, 0x1d, 0x10, 0x08, 0x60, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x36, +0x7f, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x20, 0x03, 0x58, 0x02, 0x80, 0x11, 0x0e, +0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0x58, 0x02, 0x0c, 0x72, 0x0c, +0x00, 0xd0, 0x07, 0xf4, 0x01, 0x10, 0x72, 0x0c, 0x00, 0x05, 0x0f, 0x27, 0x00, 0xff, 0xff, 0xa0, +0x0f, 0x20, 0x00, 0x31, 0x58, 0x1c, 0x20, 0x28, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x1e, 0x36, 0x7f, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x40, 0x06, 0x84, 0x03, 0x80, +0x11, 0x0e, 0x00, 0x3c, 0x03, 0x30, 0x00, 0x08, 0x72, 0x0c, 0x00, 0xb8, 0x0b, 0x2c, 0x01, 0x0c, +0x72, 0x0c, 0x00, 0xb8, 0x0b, 0x2c, 0x01, 0x10, 0x72, 0x0c, 0x00, 0x06, 0x0f, 0x27, 0x00, 0xff, +0xff, 0x2f, 0x26, 0x40, 0xb8, 0x60, 0x84, 0x0c, 0x30, 0x30, 0x30, 0x23, 0x00, 0x7e, 0xd7, 0x10, +0x00, 0x00, 0x19, 0x30, 0xe4, 0x89, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x05, 0x00, +0x04, 0x80, 0x11, 0x0e, 0x00, 0x3c, 0x03, 0x00, 0x00, 0x08, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0x58, +0x02, 0x0c, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x10, 0x72, 0x0c, 0x00, 0x05, 0x0f, 0x27, +0x00, 0xff, 0xff, 0x30, 0x2a, 0x00, 0x98, 0x51, 0x00, 0x30, 0x40, 0x30, 0x70, 0x13, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x1e, 0x36, 0x7f, 0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x78, +0x05, 0x1a, 0x04, 0x80, 0x11, 0x0e, 0x00, 0x3c, 0x03, 0x00, 0x00, 0x08, 0x72, 0x0c, 0x00, 0xd0, +0x07, 0x58, 0x02, 0x0c, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x10, 0x72, 0x0c, 0x00, 0x05, +0x0f, 0x27, 0x00, 0xff, 0xff, 0x30, 0x2a, 0x78, 0x20, 0x51, 0x1a, 0x10, 0x40, 0x10, 0x70, 0x13, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x36, 0x7f, 0x01, 0x90, 0x05, 0x00, 0x00, 0x00, 0x00, +0x0c, 0x78, 0x05, 0x1a, 0x04, 0x80, 0x11, 0x0e, 0x00, 0x3c, 0x03, 0x00, 0x00, 0x08, 0x72, 0x0c, +0x00, 0xd0, 0x07, 0x58, 0x02, 0x0c, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x10, 0x72, 0x0c, +0x00, 0x05, 0x0f, 0x27, 0x00, 0xff, 0xff, 0xa8, 0x2f, 0x78, 0xe0, 0x51, 0x1a, 0x26, 0x40, 0x58, +0x98, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x36, 0x7f, 0x01, 0x90, 0x06, 0x00, 0x00, +0x00, 0x00, 0x0c, 0x40, 0x06, 0xb0, 0x04, 0x80, 0x11, 0x0e, 0x00, 0x3c, 0x03, 0x00, 0x00, 0x08, +0x72, 0x0c, 0x00, 0xd0, 0x07, 0x58, 0x02, 0x0c, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x10, +0x72, 0x0c, 0x00, 0x05, 0x0f, 0x27, 0x00, 0xff, 0xff, 0x48, 0x3f, 0x40, 0x30, 0x62, 0xb0, 0x32, +0x40, 0x40, 0xc0, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x36, 0x7f, 0x06, 0x00, 0x07, +0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x05, 0x00, 0x03, 0x80, 0x11, 0x0e, 0x00, 0x00, 0x03, 0x00, +0x00, 0x08, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0x58, 0x02, 0x0c, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0xf4, +0x01, 0x10, 0x72, 0x0c, 0x00, 0x05, 0x0f, 0x27, 0x00, 0xff, 0xff, 0xa9, 0x1a, 0x00, 0xa0, 0x50, +0x00, 0x0a, 0x30, 0x30, 0x20, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x36, 0x7f, 0x03, +0x90, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x90, 0x06, 0x1a, 0x04, 0x80, 0x11, 0x0e, 0x00, 0x3c, +0x03, 0x00, 0x00, 0x08, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0x58, 0x02, 0x0c, 0x72, 0x0c, 0x00, 0xd0, +0x07, 0xf4, 0x01, 0x10, 0x72, 0x0c, 0x00, 0x05, 0x0f, 0x27, 0x00, 0xff, 0xff, 0x7c, 0x2e, 0x90, +0xa0, 0x60, 0x1a, 0x1e, 0x40, 0x30, 0x20, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x36, +0x7f, 0x04, 0x90, 0x09, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x80, 0x07, 0xb0, 0x04, 0x80, 0x11, 0x0e, +0x00, 0x3c, 0x03, 0x00, 0x00, 0x08, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0x58, 0x02, 0x0c, 0x72, 0x0c, +0x00, 0xd0, 0x07, 0xf4, 0x01, 0x10, 0x72, 0x0c, 0x00, 0x05, 0x0f, 0x27, 0x00, 0xff, 0xff, 0x28, +0x3c, 0x80, 0xa0, 0x70, 0xb0, 0x23, 0x40, 0x30, 0x20, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x1e, 0x36, 0x7f, 0x05, 0x90, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x03, 0x80, +0x11, 0x0e, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0x58, 0x02, 0x0c, +0x72, 0x0c, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x10, 0x72, 0x0c, 0x00, 0x05, 0x0f, 0x27, 0x00, 0xff, +0xff, 0x64, 0x19, 0x00, 0x40, 0x41, 0x00, 0x26, 0x30, 0x18, 0x88, 0x36, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x1e, 0x36, 0x7f, 0x03, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x04, 0x00, +0x03, 0x80, 0x11, 0x0e, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0x58, +0x02, 0x0c, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x10, 0x72, 0x0c, 0x00, 0x05, 0x0f, 0x27, +0x00, 0xff, 0xff, 0x64, 0x19, 0x00, 0x40, 0x41, 0x00, 0x26, 0x30, 0x18, 0x88, 0x36, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x1e, 0x36, 0x7f, 0x03, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, +0x04, 0x00, 0x03, 0x80, 0x11, 0x0e, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0x72, 0x0c, 0x00, 0xd0, +0x07, 0x58, 0x02, 0x0c, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x10, 0x72, 0x0c, 0x00, 0x05, +0x0f, 0x27, 0x00, 0xff, 0xff, 0x64, 0x19, 0x00, 0x40, 0x41, 0x00, 0x26, 0x30, 0x18, 0x88, 0x36, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x36, 0x7f, 0x03, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, +0x0c, 0x00, 0x05, 0x20, 0x03, 0x80, 0x11, 0x0e, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, 0x72, 0x0c, +0x00, 0xd0, 0x07, 0x58, 0x02, 0x0c, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x10, 0x72, 0x0c, +0x00, 0x05, 0x0f, 0x27, 0x00, 0xff, 0xff, 0xea, 0x1a, 0x00, 0xa0, 0x50, 0x20, 0x17, 0x30, 0x0c, +0x30, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x36, 0x7f, 0x03, 0x90, 0x0e, 0x00, 0x00, +0x00, 0x00, 0x0c, 0x00, 0x05, 0x58, 0x02, 0x80, 0x11, 0x0e, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08, +0x72, 0x0c, 0x00, 0xd0, 0x07, 0x58, 0x02, 0x0c, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0xf4, 0x01, 0x10, +0x72, 0x0c, 0x00, 0x05, 0x0f, 0x27, 0x00, 0xff, 0xff, 0x06, 0x18, 0x00, 0x70, 0x51, 0x58, 0x15, +0x20, 0x38, 0x80, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x36, 0x7f, 0x03, 0x00, 0x0f, +0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x06, 0x80, 0x11, 0x0e, 0x00, 0x3c, 0x03, 0x00, +0x00, 0x08, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0x58, 0x02, 0x0c, 0x72, 0x0c, 0x00, 0xd0, 0x07, 0xf4, +0x01, 0x10, 0x72, 0x0c, 0x00, 0x05, 0x0f, 0x27, 0x00, 0xff, 0xff, 0x29, 0x40, 0x00, 0x60, 0x80, +0x00, 0x13, 0x60, 0x10, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x36, 0x7f, 0x03, +0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x4c, 0x46, 0x50, 0x5f, 0x50, 0x61, 0x6e, 0x65, 0x6c, +0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x46, 0x50, 0x5f, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, +0x65, 0x4c, 0x46, 0x50, 0x5f, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x46, +0x50, 0x5f, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x46, 0x50, 0x5f, 0x50, +0x61, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x46, 0x50, 0x5f, 0x50, 0x61, 0x6e, 0x65, +0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x46, 0x50, 0x5f, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x4e, 0x61, +0x6d, 0x65, 0x4c, 0x46, 0x50, 0x5f, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x4c, +0x46, 0x50, 0x5f, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x46, 0x50, 0x5f, +0x50, 0x61, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x46, 0x50, 0x5f, 0x50, 0x61, 0x6e +}; diff --git a/src/mainboard/packardbell/ms2290/hda_verb.h b/src/mainboard/packardbell/ms2290/hda_verb.h new file mode 100644 index 0000000..1e3ccc4 --- /dev/null +++ b/src/mainboard/packardbell/ms2290/hda_verb.h @@ -0,0 +1,90 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Vladimir Serbinenko. + * + * 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, + * 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 + */ + +static const u32 mainboard_cim_verb_data[] = { + /* coreboot specific header */ + 0x10ec0272, /* Codec Vendor / Device ID: Realtek ALC272X */ + 0x10250379, /* Subsystem ID */ + 0x00000006, /* Number of 4 dword sets */ + + /* NID 0x01: Subsystem ID. */ + 0x00172079, + 0x00172103, + 0x00172225, + 0x00172310, + + /* NID 0x14. */ + 0x01471C10, + 0x01471D01, + 0x01471E13, + 0x01471F99, + + /* NID 0x18. */ + 0x01871C30, + 0x01871D18, + 0x01871EA1, + 0x01871F03, + + /* NID 0x19. */ + 0x01971C20, + 0x01971D09, + 0x01971EA3, + 0x01971F99, + + /* NID 0x1D. */ + 0x01D71C2D, + 0x01D71D99, + 0x01D71E17, + 0x01D71F40, + + /* NID 0x21. */ + 0x02171C1F, + 0x02171D10, + 0x02171E21, + 0x02171F03, + + 0x80862804, /* Codec Vendor / Device ID: Intel Ibexpeak HDMI. */ + 0x80860101, /* Subsystem ID */ + 0x00000004, /* Number of 4 dword sets */ + + /* NID 0x01, HDA Codec Subsystem ID Verb Table: 0x17aa21b5 */ + 0x30172001, + 0x30172101, + 0x30172286, + 0x30172380, + + /* NID 0x04. */ + 0x30471C10, + 0x30471D00, + 0x30471E56, + 0x30471F18, + + /* NID 0x05. */ + 0x30571C20, + 0x30571D00, + 0x30571E56, + 0x30571F58, + + /* NID 0x06. */ + 0x30671C30, + 0x30671D00, + 0x30671E56, + 0x30671F58, +}; diff --git a/src/mainboard/packardbell/ms2290/mainboard.c b/src/mainboard/packardbell/ms2290/mainboard.c new file mode 100644 index 0000000..86f7c90 --- /dev/null +++ b/src/mainboard/packardbell/ms2290/mainboard.c @@ -0,0 +1,178 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2011 Sven Schnelle <svens(a)stackframe.org> + * Copyright (C) 2013 Vladimir Serbinenko <phcoder(a)gmail.com> + * + * 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 <arch/io.h> +#include <delay.h> +#include <device/pci_def.h> +#include <device/pci_ops.h> +#include <device/pci_ids.h> +#include <arch/io.h> +#include <northbridge/intel/nehalem/nehalem.h> +#include <southbridge/intel/bd82x6x/pch.h> +#include <ec/acpi/ec.h> + +#include <pc80/mc146818rtc.h> +#include "hda_verb.h" +#include <arch/x86/include/arch/acpigen.h> +#if CONFIG_PCI_OPTION_ROM_RUN_YABEL || CONFIG_PCI_OPTION_ROM_RUN_REALMODE +#include <x86emu/regs.h> +#include <arch/interrupt.h> +#endif +#include <pc80/keyboard.h> +#include <cpu/x86/lapic.h> +#include <device/pci.h> +#include <smbios.h> + +static acpi_cstate_t cst_entries[] = { + {1, 1, 1000, {0x7f, 1, 2, {0}, 1, 0}}, + {2, 1, 500, {0x01, 8, 0, {0}, DEFAULT_PMBASE + LV2, 0}}, + {2, 17, 250, {0x01, 8, 0, {0}, DEFAULT_PMBASE + LV3, 0}}, +}; + +int get_cst_entries(acpi_cstate_t ** entries) +{ + *entries = cst_entries; + return ARRAY_SIZE(cst_entries); +} + +#if CONFIG_PCI_OPTION_ROM_RUN_YABEL || CONFIG_PCI_OPTION_ROM_RUN_REALMODE + +static int int15_handler(void) +{ + switch ((X86_EAX & 0xffff)) { + /* Get boot display. */ + case 0x5f35: + X86_EAX = 0x5f; + /* The flags are: + 1 - VGA + 4 - DisplayPort + 8 - LCD + */ + X86_ECX = 0x8; + + return 1; + case 0x5f40: + X86_EAX = 0x5f; + X86_ECX = 0x2; + return 1; + default: + printk(BIOS_WARNING, "Unknown INT15 function %04x!\n", + X86_EAX & 0xffff); + return 0; + } +} +#endif + +/* Audio Setup */ + +extern const u32 *cim_verb_data; +extern u32 cim_verb_data_size; + +static void verb_setup(void) +{ + cim_verb_data = mainboard_cim_verb_data; + cim_verb_data_size = sizeof(mainboard_cim_verb_data); +} + +static void mainboard_enable(device_t dev) +{ + u16 pmbase; + + printk(BIOS_SPEW, "starting SPI configuration\n"); + + /* Configure SPI. */ + RCBA32(0x3800) = 0x07ff0500; + RCBA32(0x3804) = 0x3f046008; + RCBA32(0x3808) = 0x0058efc0; + RCBA32(0x384c) = 0x92000000; + RCBA32(0x3850) = 0x00000a0b; + RCBA32(0x3858) = 0x07ff0500; + RCBA32(0x385c) = 0x04ff0003; + RCBA32(0x3860) = 0x00020001; + RCBA32(0x3864) = 0x00000fff; + RCBA32(0x3874) = 0; + RCBA32(0x3890) = 0xf8400000; + RCBA32(0x3894) = 0x143b5006; + RCBA32(0x3898) = 0x05200302; + RCBA32(0x389c) = 0x0601209f; + RCBA32(0x38b0) = 0x00000004; + RCBA32(0x38b4) = 0x03040002; + RCBA32(0x38c0) = 0x00000007; + RCBA32(0x38c8) = 0x00002005; + RCBA32(0x38c4) = 0x00802005; + RCBA32(0x3804) = 0x3f04e008; + + printk(BIOS_SPEW, "SPI configured\n"); + + int i; + unsigned char dmp[256] = { + 0x00, 0x20, 0x00, 0x00, 0x00, 0x02, 0x89, 0xe4, 0x30, 0x00, 0x40, 0x14, 0x00, 0x00, 0x00, 0x11, + 0x03, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0xf4, 0x01, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x62, 0x01, 0x04, 0x00, 0x08, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, + 0x42, 0x07, 0x09, 0x09, 0xf0, 0x00, 0x00, 0xf0, 0xa9, 0x00, 0x00, 0x06, 0x00, 0x00, 0xff, 0x00, + 0x00, 0x01, 0x00, 0x04, 0xff, 0xff, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0b, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x28, 0x1b, 0x21, 0x00, 0x2c, 0x3b, 0x13, 0x00, + 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x55, 0x5a, 0x57, 0x5c, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, + 0x52, 0x10, 0x52, 0x10, 0x64, 0x00, 0x00, 0x00, 0x74, 0x30, 0x00, 0x60, 0x00, 0x00, 0xaf, 0x0b, + 0x30, 0x45, 0x2e, 0x30, 0x38, 0x41, 0x43, 0x2e, 0x30, 0x31, 0x2e, 0x31, 0x36, 0x20, 0x00, 0x00, + }; + + for (i = 0; i < 256; i++) + ec_write (i, dmp[i]); + + pmbase = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x1f, 0)), + PMBASE) & 0xff80; + + printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", pmbase); + + outl(0, pmbase + SMI_EN); + + enable_lapic(); + pci_write_config32(dev_find_slot(0, PCI_DEVFN(0x1f, 0)), GPIO_BASE, + DEFAULT_GPIOBASE | 1); + pci_write_config8(dev_find_slot(0, PCI_DEVFN(0x1f, 0)), GPIO_CNTL, + 0x10); + +#if CONFIG_PCI_OPTION_ROM_RUN_YABEL || CONFIG_PCI_OPTION_ROM_RUN_REALMODE + /* Install custom int15 handler for VGA OPROM */ + mainboard_interrupt_handlers(0x15, &int15_handler); +#endif + + /* This sneaked in here, because EasyNote has no SuperIO chip. + */ + pc_keyboard_init(0); + verb_setup(); +} + +struct chip_operations mainboard_ops = { + .enable_dev = mainboard_enable, +}; diff --git a/src/mainboard/packardbell/ms2290/romstage.c b/src/mainboard/packardbell/ms2290/romstage.c new file mode 100644 index 0000000..6a18dd6 --- /dev/null +++ b/src/mainboard/packardbell/ms2290/romstage.c @@ -0,0 +1,333 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2011 Sven Schnelle <svens(a)stackframe.org> + * Copyright (C) 2013 Vladimir Serbinenko <phcoder(a)gmail.com> + * + * 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 + */ + +/* __PRE_RAM__ means: use "unsigned" for device, not a struct. */ + +#include <stdint.h> +#include <string.h> +#include <arch/io.h> +#include <device/pci_def.h> +#include <device/pnp_def.h> +#include <cpu/x86/lapic.h> +#include <lib.h> +#include <pc80/mc146818rtc.h> +#include <console/console.h> +#include <cpu/x86/bist.h> +#include <ec/acpi/ec.h> +#include <delay.h> +#include <timestamp.h> +#include <cbmem.h> + +#include "arch/early_variables.h" +#include "southbridge/intel/ibexpeak/pch.h" +#include "northbridge/intel/nehalem/nehalem.h" + +#include "northbridge/intel/nehalem/raminit.h" +#include "southbridge/intel/ibexpeak/me.h" + +static void pch_enable_lpc(void) +{ + /* Enable EC, PS/2 Keyboard/Mouse */ + pci_write_config16(PCH_LPC_DEV, LPC_EN, + CNF2_LPC_EN | CNF1_LPC_EN | MC_LPC_EN | KBC_LPC_EN | + COMA_LPC_EN); + + pci_write_config32(PCH_LPC_DEV, LPC_GEN1_DEC, (0x68 & ~3) | 0x00040001); + + pci_write_config16(PCH_LPC_DEV, LPC_IO_DEC, 0x10); + + pci_write_config32(PCH_LPC_DEV, 0xd0, 0x0); + pci_write_config32(PCH_LPC_DEV, 0xdc, 0x8); + + pci_write_config8(PCH_LPC_DEV, GEN_PMCON_3, + (pci_read_config8(PCH_LPC_DEV, GEN_PMCON_3) & ~2) | 1); + + pci_write_config32(PCH_LPC_DEV, ETR3, + pci_read_config32(PCH_LPC_DEV, ETR3) & ~ETR3_CF9GR); +} + +static void rcba_config(void) +{ + static const u32 rcba_dump3[] = { + /* 30fc */ 0x00000000, + /* 3100 */ 0x04341200, 0x00000000, 0x40043214, 0x00014321, + /* 3110 */ 0x00000002, 0x30003214, 0x00000001, 0x00000002, + /* 3120 */ 0x00000000, 0x00002321, 0x00000000, 0x00000000, + /* 3130 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3140 */ 0x00003107, 0x76543210, 0x00000010, 0x00007654, + /* 3150 */ 0x00000004, 0x00000000, 0x00000000, 0x00003210, + /* 3160 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3170 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3180 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3190 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 31a0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 31b0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 31c0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 31d0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 31e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 31f0 */ 0x00000000, 0x00000000, 0x00000000, 0x03000000, + /* 3200 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3210 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3220 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3230 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3240 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3250 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3260 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3270 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3280 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3290 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 32a0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 32b0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 32c0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 32d0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 32e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 32f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3300 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3310 */ 0x02060100, 0x0000000f, 0x01020000, 0x80000000, + /* 3320 */ 0x00000000, 0x04000000, 0x00000000, 0x00000000, + /* 3330 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3340 */ 0x000fffff, 0x00000000, 0x00000000, 0x00000000, + /* 3350 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3360 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3370 */ 0x00000000, 0x00000000, 0x7f8fdfff, 0x00000000, + /* 3380 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3390 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 33a0 */ 0x00003900, 0x00000000, 0x00000000, 0x00000000, + /* 33b0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 33c0 */ 0x00010000, 0x00000000, 0x00000000, 0x0001004b, + /* 33d0 */ 0x06000008, 0x00010000, 0x00000000, 0x00000000, + /* 33e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 33f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3400 */ 0x0000001c, 0x00000080, 0x00000000, 0x00000000, + /* 3410 */ 0x00000c61, 0x00000000, 0x16fc1fe1, 0xbf4f001f, + /* 3420 */ 0x00000000, 0x00060010, 0x0000001d, 0x00000000, + /* 3430 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3440 */ 0xdeaddeed, 0x00000000, 0x00000000, 0x00000000, + /* 3450 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3460 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3470 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3480 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3490 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 34a0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 34b0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 34c0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 34d0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 34e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 34f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3500 */ 0x20000557, 0x2000055f, 0x2000074b, 0x2000074b, + /* 3510 */ 0x20000557, 0x2000014b, 0x2000074b, 0x2000074b, + /* 3520 */ 0x2000074b, 0x2000074b, 0x2000055f, 0x2000055f, + /* 3530 */ 0x20000557, 0x2000055f, 0x00000000, 0x00000000, + /* 3540 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3550 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3560 */ 0x00000001, 0x000026a3, 0x00040002, 0x01000052, + /* 3570 */ 0x02000772, 0x16000f8f, 0x1800ff4f, 0x0001d630, + /* 3580 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3590 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 35a0 */ 0xfc000201, 0x3c000201, 0x00000000, 0x00000000, + /* 35b0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 35c0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 35d0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 35e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 35f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3600 */ 0x0a001f00, 0x00000000, 0x00000000, 0x00000001, + /* 3610 */ 0x00010000, 0x00000000, 0x00000000, 0x00000000, + /* 3600 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3610 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3620 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3630 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3640 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3650 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3660 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3670 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3680 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3690 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 36a0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 36b0 */ 0x00000000, 0x089c0018, 0x00000000, 0x00000000, + /* 36c0 */ 0x11111111, 0x00000000, 0x00000000, 0x00000000, + /* 36d0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 36e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 36f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000, + /* 3710 */ 0x00000000, 0x4e564d49, 0x00000000, 0x00000000, + }; + unsigned i; + for (i = 0; i < sizeof(rcba_dump3) / 4; i++) { + RCBA32(4 * i + 0x30fc) = rcba_dump3[i]; + (void)RCBA32(4 * i + 0x30fc); + } +} + +static inline void write_acpi32(u32 addr, u32 val) +{ + outl(val, DEFAULT_PMBASE | addr); +} + +static inline void write_acpi16(u32 addr, u16 val) +{ + outw(val, DEFAULT_PMBASE | addr); +} + +static inline u32 read_acpi32(u32 addr) +{ + return inl(DEFAULT_PMBASE | addr); +} + +static inline u16 read_acpi16(u32 addr) +{ + return inw(DEFAULT_PMBASE | addr); +} + +void main(unsigned long bist) +{ + u32 reg32; + int s3resume = 0; + const u8 spd_addrmap[4] = { 0x50, 0, 0x52, 0 }; + + timestamp_init(rdtsc ()); + + /* SERR pin is confused on reset. Clear NMI. */ + outb(4, 0x61); + outb(0, 0x61); + + timestamp_add_now(TS_START_ROMSTAGE); + + if (bist == 0) + enable_lapic(); + + nehalem_early_initialization(NEHALEM_MOBILE); + + pch_enable_lpc(); + + /* Enable GPIOs */ + pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE | 1); + pci_write_config8(PCH_LPC_DEV, GPIO_CNTL, 0x10); + outl (0x796bd9c3, DEFAULT_GPIOBASE); + outl (0x86fec7c2, DEFAULT_GPIOBASE + 4); + outl (0xe4e8d7fe, DEFAULT_GPIOBASE + 0xc); + outl (0, DEFAULT_GPIOBASE + 0x18); + outl (0x00004182, DEFAULT_GPIOBASE + 0x2c); + outl (0x123360f8, DEFAULT_GPIOBASE + 0x30); + outl (0x1f47bfa8, DEFAULT_GPIOBASE + 0x34); + outl (0xfffe7fb6, DEFAULT_GPIOBASE + 0x38); + + + /* This should probably go away. Until now it is required + * and mainboard specific + */ + rcba_config(); + + console_init(); + + /* Halt if there was a built in self test failure */ + report_bist_failure(bist); + + /* Read PM1_CNT */ + reg32 = inl(DEFAULT_PMBASE + 0x04); + printk(BIOS_DEBUG, "PM1_CNT: %08x\n", reg32); + if (((reg32 >> 10) & 7) == 5) { + u8 reg8; + reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa2); + printk(BIOS_DEBUG, "a2: %02x\n", reg8); + if (!(reg8 & 0x20)) { + outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04); + printk(BIOS_DEBUG, "Bad resume from S3 detected.\n"); + } else { + printk(BIOS_DEBUG, "Resume from S3 detected.\n"); + s3resume = 1; + } + } + + /* Enable SMBUS. */ + enable_smbus(); + + write_acpi16(0x2, 0x0); + write_acpi32(0x28, 0x0); + write_acpi32(0x2c, 0x0); + if (!s3resume) { + read_acpi32(0x4); + read_acpi32(0x20); + read_acpi32(0x34); + write_acpi16(0x0, 0x900); + write_acpi32(0x20, 0xffff7ffe); + write_acpi32(0x34, 0x56974); + pci_write_config8(PCH_LPC_DEV, GEN_PMCON_3, + pci_read_config8(PCH_LPC_DEV, GEN_PMCON_3) | 2); + } + + early_thermal_init(); + + timestamp_add_now(TS_BEFORE_INITRAM); + + chipset_init(s3resume); + raminit(s3resume, spd_addrmap); + + timestamp_add_now(TS_AFTER_INITRAM); + + intel_early_me_status(); + + if (s3resume) { + /* Clear SLP_TYPE. This will break stage2 but + * we care for that when we get there. + */ + reg32 = inl(DEFAULT_PMBASE + 0x04); + outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04); + } + +#if CONFIG_HAVE_ACPI_RESUME + /* If there is no high memory area, we didn't boot before, so + * this is not a resume. In that case we just create the cbmem toc. + */ + if (s3resume) { + void *resume_backup_memory; + + /* For non-S3-resume, CBMEM is inited in raminit code. */ + if (cbmem_recovery(1)) { + printk(BIOS_ERR, "Failed S3 resume.\n"); + ram_check(0x100000, 0x200000); + + /* Failed S3 resume, reset to come up cleanly */ + outb(0xe, 0xcf9); + hlt(); + } + + resume_backup_memory = cbmem_find(CBMEM_ID_RESUME); + + /* copy 1MB - 64K to high tables ram_base to prevent memory corruption + * through stage 2. We could keep stuff like stack and heap in high tables + * memory completely, but that's a wonderful clean up task for another + * day. + */ + if (resume_backup_memory) + memcpy(resume_backup_memory, (void *)CONFIG_RAMBASE, + HIGH_MEMORY_SAVE); + + /* Magic for S3 resume */ + pci_write_config32(PCI_DEV(0, 0x00, 0), SKPAD, 0xcafed00d); + } else { + pci_write_config32(PCI_DEV(0, 0x00, 0), SKPAD, 0xcafebabe); + quick_ram_check(); + } +#endif + + timestamp_add_now(TS_END_ROMSTAGE); +} diff --git a/src/mainboard/packardbell/ms2290/smi.h b/src/mainboard/packardbell/ms2290/smi.h new file mode 100644 index 0000000..e69de29 diff --git a/src/mainboard/packardbell/ms2290/smihandler.c b/src/mainboard/packardbell/ms2290/smihandler.c new file mode 100644 index 0000000..5051efd --- /dev/null +++ b/src/mainboard/packardbell/ms2290/smihandler.c @@ -0,0 +1,113 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-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 + */ + +#include <arch/io.h> +#include <console/console.h> +#include <cpu/x86/smm.h> +#include "southbridge/intel/ibexpeak/nvs.h" +#include "southbridge/intel/ibexpeak/pch.h" +#include "southbridge/intel/ibexpeak/me.h" +#include <northbridge/intel/sandybridge/sandybridge.h> +#include <cpu/intel/model_2065x/model_2065x.h> +#include <ec/acpi/ec.h> +#include <pc80/mc146818rtc.h> +#include <delay.h> +#include "smi.h" + +/* The southbridge SMI handler checks whether gnvs has a + * valid pointer before calling the trap handler + */ +extern global_nvs_t *gnvs; + +static void mainboard_smm_init(void) +{ + printk(BIOS_DEBUG, "initializing SMI\n"); +} + +int mainboard_io_trap_handler(int smif) +{ + static int smm_initialized; + + if (!smm_initialized) { + mainboard_smm_init(); + smm_initialized = 1; + } + + switch (smif) { + + default: + return 0; + } + + /* On success, the IO Trap Handler returns 1 + * On failure, the IO Trap Handler returns a value != 1 */ + return 1; +} + +void mainboard_smi_gpi(u32 gpi_sts) +{ +} + +static int mainboard_finalized = 0; + +int mainboard_smi_apmc(u8 data) +{ + u16 pmbase = pci_read_config16(PCI_DEV(0, 0x1f, 0), 0x40) & 0xfffc; + u8 tmp; + + printk(BIOS_DEBUG, "%s: pmbase %04X, data %02X\n", __func__, pmbase, + data); + + if (!pmbase) + return 0; + + switch (data) { + case APM_CNT_FINALIZE: + printk(BIOS_DEBUG, "APMC: FINALIZE\n"); + if (mainboard_finalized) { + printk(BIOS_DEBUG, "APMC#: Already finalized\n"); + return 0; + } + + intel_me_finalize_smm(); + intel_pch_finalize_smm(); + intel_sandybridge_finalize_smm(); + intel_model_2065x_finalize_smm(); + + mainboard_finalized = 1; + break; + case APM_CNT_ACPI_ENABLE: + tmp = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xbb); + tmp &= ~0x03; + tmp |= 0x02; + pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xbb, tmp); + break; + case APM_CNT_ACPI_DISABLE: + tmp = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xbb); + tmp &= ~0x03; + tmp |= 0x01; + pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xbb, tmp); + break; + default: + break; + } + return 0; +}
1
0
0
0
Patch set updated for coreboot: a33dbbd nehalem: Remove SSKPD.
by Vladimir Serbinenko
22 Feb '14
22 Feb '14
Vladimir Serbinenko (phcoder(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at
http://review.coreboot.org/5268
-gerrit commit a33dbbd8de91e2c947491d01343048fff546840a Author: Vladimir Serbinenko <phcoder(a)gmail.com> Date: Wed Feb 19 22:10:03 2014 +0100 nehalem: Remove SSKPD. Not really used and conflicts with SSKPD from i915_regs.h Change-Id: I1462457f656310df99e78aee8cbfe0206f6e2a1e Signed-off-by: Vladimir Serbinenko <phcoder(a)gmail.com> --- src/northbridge/intel/nehalem/nehalem.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/northbridge/intel/nehalem/nehalem.h b/src/northbridge/intel/nehalem/nehalem.h index e79a343..60cafdf 100644 --- a/src/northbridge/intel/nehalem/nehalem.h +++ b/src/northbridge/intel/nehalem/nehalem.h @@ -504,7 +504,6 @@ void init_iommu(void); #define MCHBAR32(x) *((volatile u32 *)(DEFAULT_MCHBAR + x)) #define MCHBAR32_OR(x, or) MCHBAR32(x) = (MCHBAR32(x) | (or)) -#define SSKPD 0x5d14 /* 16bit (scratchpad) */ #define BIOS_RESET_CPL 0x5da8 /* 8bit */ /*
1
0
0
0
Patch set updated for coreboot: fc63923 intel/nehalem: Use non-powercycle reset.
by Vladimir Serbinenko
22 Feb '14
22 Feb '14
Vladimir Serbinenko (phcoder(a)gmail.com) just uploaded a new patch set to gerrit, which you can find at
http://review.coreboot.org/5266
-gerrit commit fc639231461382972403e30c489cc17ffd033c62 Author: Vladimir Serbinenko <phcoder(a)gmail.com> Date: Wed Feb 19 22:08:51 2014 +0100 intel/nehalem: Use non-powercycle reset. Change-Id: Ibc2421a50e272a580461e4eacec6cfcd38654fe8 Signed-off-by: Vladimir Serbinenko <phcoder(a)gmail.com> --- src/northbridge/intel/nehalem/raminit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/northbridge/intel/nehalem/raminit.c b/src/northbridge/intel/nehalem/raminit.c index c967e39..46a15a9 100644 --- a/src/northbridge/intel/nehalem/raminit.c +++ b/src/northbridge/intel/nehalem/raminit.c @@ -3804,7 +3804,7 @@ void chipset_init(const int s3resume) if ((x2ca8 & 1) || (x2ca8 == 8 && !s3resume)) { printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n"); write_mchbar8(0x2ca8, 0); - outb(0xe, 0xcf9); + outb(0x6, 0xcf9); #if REAL while (1) { asm volatile ("hlt");
1
0
0
0
← Newer
1
...
28
29
30
31
32
33
34
...
114
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
Results per page:
10
25
50
100
200