All,
i started a port of coreboot to my Thinkpad X60 last week.
Things implemented right now:
Serial I/O over X6 ultrabase. The X60 itself doesn't have a serial interface, so the first thing i've done was to buy a Docking station.
CPU + Chipset initialization. There still one thing to discuss: The X60s has a L2300 CPU, which has (AFAIK) a Socket 479 M, but the coreboot code doesn't know model_6ex for socket_479M. so i added model_6ex and speedsteep to the subdirs in src/cpu/intel/socket_mPGA479M/Makefile.inc. Another thing: socket_479M has it's own CAR code, which doesn't work on my CPU. Removed the extra include and using the common intel CAR code works.
And most important: Linux boots with the DSDT extracted from the Vendor BIOS. Without ACPI, interrupt routing is currently broken. Have not tried windows. I did not add the disassembled IBM/Lenovo DSDT, as i'm not sure if this violates any Copyright. (And we want to replace it by our own ACPI code anyways)
Things not working:
- Dual Channel DRAM:
The X60 has one DIMM per Channel, but coreboot expects the SPD Addresses for Dual Channel on 0x50/0x52, but the Thinkpad has it wired to 0x50/0x51.
- Power Management (of course :) )
Needs reverse engineering of the Embedded Controller interface. This is the next thing on my TODO List. I wrote a LPC Bus Support Package for my Tektronix Logic Analyzer, so i'm able to capture all LPC traffic. I will add dumps to the coreboot Wiki.
- Trackpoint
Needs probably some magic enable command to EC.
I'm adding the current version as diff to this email, in case anybody wants to play with the code. Not sure if "it boot's Linux' is enough to go into the coreboot SVN.
Yet another important thing:
I've modified my X60 in a way that i can switch between the original BIOS Flash (SPI, MX25L1605D) and the Artecgroup USB Dongle (which is connected via LPC) with the Wireless RFKILL switch. So i have not tried booting the Notebook via SPI, as i don't want to erase my original BIOS (still required for reverse engineering ;) )
I expect it to boot via SPI, but haven't tried it. So be careful when flashing your Thinkpad :D
Regards,
Sven
Dear Sven,
Am Montag, den 10.01.2011, 09:43 +0100 schrieb Sven Schnelle:
i started a port of coreboot to my Thinkpad X60 last week.
great to hear that.
[…]
I'm adding the current version as diff to this email, in case anybody wants to play with the code. Not sure if "it boot's Linux' is enough to go into the coreboot SVN.
It at least needs your Signed-off-by line [1].
Maybe you could also publish your Git tree on your server.
[…]
Thanks and I wish you success,
Paul
[1] http://www.coreboot.org/Development_Guidelines#Sign-off_Procedure
Paul Menzel paulepanter@users.sourceforge.net writes:
I'm adding the current version as diff to this email, in case anybody wants to play with the code. Not sure if "it boot's Linux' is enough to go into the coreboot SVN.
It at least needs your Signed-off-by line [1].
Sorry, missed that. Trying again.
Maybe you could also publish your Git tree on your server.
You may clone the tree with:
git clone git://git.stackframe.org/coreboot. Development Tree is 'X60'.
gitweb lives at http://git.stackframe.org/?p=coreboot;a=summary
Regards,
Sven.
commit 7d3a1ebf3de5746d3dec8f47e74458c15018c694 Author: Sven Schnelle svens@stackframe.org Date: Mon Jan 10 13:23:59 2011 +0100
Initial bits for X60 support
Signed-off-by: Sven Schnelle svens@stackframe.org
diff --git a/src/cpu/intel/socket_mPGA479M/Makefile.inc b/src/cpu/intel/socket_mPGA479M/Makefile.inc index 260d1c8..83e6049 100644 --- a/src/cpu/intel/socket_mPGA479M/Makefile.inc +++ b/src/cpu/intel/socket_mPGA479M/Makefile.inc @@ -1,6 +1,7 @@ ramstage-y += socket_mPGA479M.c subdirs-y += ../model_69x subdirs-y += ../model_6dx +subdirs-y += ../model_6ex subdirs-y += ../model_f2x subdirs-y += ../../x86/tsc subdirs-y += ../../x86/mtrr @@ -9,5 +10,5 @@ subdirs-y += ../../x86/cache subdirs-y += ../../x86/smm subdirs-y += ../microcode subdirs-y += ../hyperthreading +subdirs-y += ../speedstep
-cpu_incs += $(src)/cpu/intel/car/cache_as_ram.inc diff --git a/src/mainboard/Kconfig b/src/mainboard/Kconfig index cbee0a0..e86c310 100644 --- a/src/mainboard/Kconfig +++ b/src/mainboard/Kconfig @@ -54,6 +54,8 @@ config VENDOR_IBASE bool "iBase" config VENDOR_IBM bool "IBM" +config VENDOR_LENOVO + bool "Lenovo" config VENDOR_IEI bool "IEI" config VENDOR_INTEL @@ -147,6 +149,7 @@ source "src/mainboard/iwill/Kconfig" source "src/mainboard/jetway/Kconfig" source "src/mainboard/kontron/Kconfig" source "src/mainboard/lanner/Kconfig" +source "src/mainboard/lenovo/Kconfig" source "src/mainboard/lippert/Kconfig" source "src/mainboard/mitac/Kconfig" source "src/mainboard/msi/Kconfig" diff --git a/src/mainboard/lenovo/Kconfig b/src/mainboard/lenovo/Kconfig new file mode 100644 index 0000000..580c4a8 --- /dev/null +++ b/src/mainboard/lenovo/Kconfig @@ -0,0 +1,17 @@ +if VENDOR_LENOVO + +choice + prompt "Mainboard model" + +config BOARD_LENOVO_X60 + bool "Thinkpad X60" + +endchoice + +source "src/mainboard/lenovo/x60/Kconfig" + +config MAINBOARD_VENDOR + string + default "Lenovo" + +endif # VENDOR_LENOVO diff --git a/src/mainboard/lenovo/x60/Kconfig b/src/mainboard/lenovo/x60/Kconfig new file mode 100644 index 0000000..c71f8a5 --- /dev/null +++ b/src/mainboard/lenovo/x60/Kconfig @@ -0,0 +1,53 @@ +if BOARD_LENOVO_X60 + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + select ARCH_X86 + select CPU_INTEL_CORE + select CPU_INTEL_SOCKET_MPGA479M + select NORTHBRIDGE_INTEL_I945GM + select SOUTHBRIDGE_INTEL_I82801GX + select BOARD_HAS_FADT + select HAVE_OPTION_TABLE + select HAVE_PIRQ_TABLE + select HAVE_MP_TABLE + select MMCONF_SUPPORT + select HAVE_SMI_HANDLER + select HAVE_ACPI_TABLES +# select HAVE_ACPI_RESUME + select BOARD_ROMSIZE_KB_1024 + select CHANNEL_XOR_RANDOMIZATION + +config MAINBOARD_DIR + string + default lenovo/x60 + +config DCACHE_RAM_BASE + hex + default 0xffdf8000 + +config DCACHE_RAM_SIZE + hex + default 0x8000 + +config MAINBOARD_PART_NUMBER + string + default "X60" + +config MMCONF_BASE_ADDRESS + hex + default 0xf0000000 + +config IRQ_SLOT_COUNT + int + default 18 + +config MAX_CPUS + int + default 2 + +config MAX_PHYSICAL_CPUS + int + default 1 + +endif diff --git a/src/mainboard/lenovo/x60/Makefile.inc b/src/mainboard/lenovo/x60/Makefile.inc new file mode 100644 index 0000000..10f00a0 --- /dev/null +++ b/src/mainboard/lenovo/x60/Makefile.inc @@ -0,0 +1,20 @@ +## +## This file is part of the coreboot project. +## +## Copyright (c) 2011 Sven Schnelle svens@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 +## + +smm-$(CONFIG_HAVE_SMI_HANDLER) += mainboard_smi.c diff --git a/src/mainboard/lenovo/x60/acpi_tables.c b/src/mainboard/lenovo/x60/acpi_tables.c new file mode 100644 index 0000000..0a34673 --- /dev/null +++ b/src/mainboard/lenovo/x60/acpi_tables.c @@ -0,0 +1,364 @@ +/* + * 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 + */ + +#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 "dmi.h" + +extern const unsigned char AmlCode[]; +#if CONFIG_HAVE_ACPI_SLIC +unsigned long acpi_create_slic(unsigned long current); +#endif + +#define OLD_ACPI 0 +#if OLD_ACPI +static void acpi_create_gnvs(global_nvs_t *gnvs) +{ + memset (gnvs, 0, sizeof(global_nvs_t)); + + gnvs->LIDS = 1; + gnvs->PWRS = 1; + + gnvs->ACTT = 0x37; + gnvs->PSVT = 0x4f; + + gnvs->TC1V = 0x00; + gnvs->TC2V = 0x0a; + gnvs->TSPV = 0x02; + + gnvs->CRTT = 0x77; + + gnvs->B0SC = 0x54; + gnvs->APIC = 0x01; + gnvs->MPEN = 0x01; + + gnvs->PPCM = 0x02; + gnvs->PCP0 = 0xbf; + gnvs->PCP1 = 0xbf; + + gnvs->CMAP = 0x01; + gnvs->CMBP = 0x01; + gnvs->LT0 = 0x01; + gnvs->FDCP = 0x01; + gnvs->CMCP = 0x01; + gnvs->CMDP = 0x01; + gnvs->P2M = 0x02; + + gnvs->IGDS = 0x01; + + gnvs->CADL = 0x09; + gnvs->PADL = 0x09; + + gnvs->NDID = 3; + gnvs->DID1 = 0x80000100; + gnvs->DID2 = 0x80000240; + gnvs->DID3 = 0x80000410; + gnvs->DID4 = 0x80000410; + gnvs->DID5 = 0x00000005; + + gnvs->ALAF = 0x64; + gnvs->LLOW = 0x2c; + gnvs->LHIH = 0x01; + + // tolud = pci_read_config32(dev_find_slot(0, PCI_DEVFN(2, 0)), 0x5c); + // oemb->topm = tolud; +} +#endif + +#include "southbridge/intel/i82801gx/nvs.h" +static void acpi_create_gnvs(global_nvs_t *gnvs) +{ + memset((void *)gnvs, 0, sizeof(*gnvs)); + gnvs->apic = 1; + gnvs->mpen = 1; /* Enable Multi Processing */ + + /* Enable both COM ports */ + gnvs->cmap = 0x01; + gnvs->cmbp = 0x01; + + /* 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; +} + +static void acpi_create_intel_hpet(acpi_hpet_t * hpet) +{ +#define HPET_ADDR 0xfed00000ULL + acpi_header_t *header = &(hpet->header); + acpi_addr_t *addr = &(hpet->addr); + + memset((void *) hpet, 0, sizeof(acpi_hpet_t)); + + /* fill out header fields */ + memcpy(header->signature, "HPET", 4); + memcpy(header->oem_id, OEM_ID, 6); + memcpy(header->oem_table_id, "COREBOOT", 8); + memcpy(header->asl_compiler_id, ASLC, 4); + + header->length = sizeof(acpi_hpet_t); + header->revision = 1; + + /* fill out HPET address */ + addr->space_id = 0; /* Memory */ + addr->bit_width = 64; + addr->bit_offset = 0; + addr->addrl = HPET_ADDR & 0xffffffff; + addr->addrh = HPET_ADDR >> 32; + + hpet->id = 0x8086a201; /* Intel */ + hpet->number = 0x00; + hpet->min_tick = 0x0080; + + header->checksum = + acpi_checksum((void *) hpet, sizeof(acpi_hpet_t)); +} + +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, + 2, IO_APIC_ADDR, 0); + + /* 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); + + /* INT_SRC_OVR */ + current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) + current, 0, 0, 2, MP_IRQ_POLARITY_HIGH | MP_IRQ_TRIGGER_EDGE); + current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) + current, 0, 9, 9, MP_IRQ_POLARITY_HIGH | MP_IRQ_TRIGGER_LEVEL); + + + 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 = ((current + 0x0f) & -0x10) +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_intel_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 + * 0x00000020 - 0x0000019c Low MP Table (XXX conflict?) + * 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? (conflict with low tables:) + * 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; // 0x92 bytes + 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, "COREBOOT"); + current += ssdt->length; + acpi_add_table(rsdp, ssdt); + ALIGN_CURRENT; + + printk(BIOS_DEBUG, "current = %lx\n", current); + + printk(BIOS_DEBUG, "ACPI: * DMI (Linux workaround)\n"); + memcpy((void *)0xfff80, dmi_table, DMI_TABLE_SIZE); +#if CONFIG_WRITE_HIGH_TABLES == 1 + memcpy((void *)current, dmi_table, DMI_TABLE_SIZE); + current += DMI_TABLE_SIZE; + ALIGN_CURRENT; +#endif + + printk(BIOS_INFO, "ACPI: done.\n"); + + return current; +} diff --git a/src/mainboard/lenovo/x60/chip.h b/src/mainboard/lenovo/x60/chip.h new file mode 100644 index 0000000..70f9bb4 --- /dev/null +++ b/src/mainboard/lenovo/x60/chip.h @@ -0,0 +1,21 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2011 Sven Schnelle svens@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 + */ + +extern struct chip_operations mainboard_ops; +struct mainboard_config {}; diff --git a/src/mainboard/lenovo/x60/cmos.layout b/src/mainboard/lenovo/x60/cmos.layout new file mode 100644 index 0000000..4dc9112 --- /dev/null +++ b/src/mainboard/lenovo/x60/cmos.layout @@ -0,0 +1,145 @@ +# +# 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 +# + +# ----------------------------------------------------------------- +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: cpu +400 1 e 2 hyper_threading +#401 7 r 0 unused + +# coreboot config options: southbridge +408 1 e 1 nmi +#409 2 e 7 power_on_after_fail +#411 5 r 0 unused + +# coreboot config options: bootloader +416 512 s 0 boot_devices +928 8 h 0 boot_default +#936 48 r 0 unused + +# coreboot config options: check sums +984 16 h 0 check_sum +#1000 24 r 0 amd_reserved + +# ram initialization internal data +1024 8 r 0 C0WL0REOST +1032 8 r 0 C1WL0REOST +1040 8 r 0 RCVENMT +1048 4 r 0 C0DRT1 +1052 4 r 0 C1DRT1 + +# ----------------------------------------------------------------- + +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 + +# ----------------------------------------------------------------- +checksums + +checksum 392 983 984 + + diff --git a/src/mainboard/lenovo/x60/devicetree.cb b/src/mainboard/lenovo/x60/devicetree.cb new file mode 100644 index 0000000..fdd1a88 --- /dev/null +++ b/src/mainboard/lenovo/x60/devicetree.cb @@ -0,0 +1,79 @@ +## +## This file is part of the coreboot project. +## +## Copyright (c) 2011 Sven Schnelle svens@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/i945 + + device lapic_cluster 0 on + chip cpu/intel/socket_MPGA479M + device lapic 0 on end + end + end + + device pci_domain 0 on + device pci 00.0 on end # host bridge + device pci 02.0 on end # vga controller + device pci 02.1 on end # display controller + chip southbridge/intel/i82801gx + register "pirqa_routing" = "0x8b" + register "pirqb_routing" = "0x8b" + register "pirqc_routing" = "0x8b" + register "pirqd_routing" = "0x8b" + register "pirqe_routing" = "0x8b" + register "pirqf_routing" = "0x8b" + register "pirqg_routing" = "0x8b" + register "pirqh_routing" = "0x8b" + + register "sata_ahci" = "0x0" + + register "gpi13_routing" = "2" + register "gpi12_routing" = "2" + register "gpi8_routing" = "2" + + device pci 1b.0 on end # Audio Controller + device pci 1c.0 on end # Ethernet + device pci 1c.1 on end # Atheros WLAN + device pci 1d.0 on end # USB UHCI + device pci 1d.1 on end # USB UHCI + device pci 1d.2 on end # USB UHCI + device pci 1d.3 on end # USB UHCI + device pci 1d.7 on end # USB2 EHCI + device pci 1f.0 on # PCI-LPC bridge + chip superio/lenovo/x60_ec +# device pnp 2e.5 on # Keyboard+Mouse +# io 0x60 = 0x60 +# io 0x62 = 0x64 +# irq 0x70 = 1 +# irq 0x72 = 12 +# end +# end +# chip superio/lenovo/pmh7 +# device pnp ff.1 on # dummy address +# end + end + end + device pci 1f.1 off end # IDE + device pci 1f.2 on end # SATA + device pci 1f.3 on end # SMBus + end + chip southbridge/ricoh/rl5c476 + end + end +end diff --git a/src/mainboard/lenovo/x60/dmi.h b/src/mainboard/lenovo/x60/dmi.h new file mode 100644 index 0000000..96b5873 --- /dev/null +++ b/src/mainboard/lenovo/x60/dmi.h @@ -0,0 +1,29 @@ +/* + * 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 + */ + +#define DMI_TABLE_SIZE 0x55 + +static u8 dmi_table[DMI_TABLE_SIZE] = { + 0x5f, 0x53, 0x4d, 0x5f, 0x29, 0x1f, 0x02, 0x03, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5f, 0x44, 0x4d, 0x49, 0x5f, 0x61, 0x35, 0x00, 0xa0, 0xff, 0x0f, 0x00, 0x01, 0x00, 0x23, 0x00, + 0x00, 0x14, 0x00, 0x00, 0x01, 0x02, 0x00, 0xe0, 0x03, 0x07, 0x90, 0xde, 0xcb, 0x7f, 0x00, 0x00, + 0x00, 0x00, 0x37, 0x01, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x20, + 0x47, 0x6d, 0x62, 0x48, 0x00, 0x32, 0x2e, 0x30, 0x00, 0x30, 0x33, 0x2f, 0x31, 0x33, 0x2f, 0x32, + 0x30, 0x30, 0x38, 0x00, 0x00 +}; diff --git a/src/mainboard/lenovo/x60/dsdt.asl b/src/mainboard/lenovo/x60/dsdt.asl new file mode 100644 index 0000000..e69de29 diff --git a/src/mainboard/lenovo/x60/fadt.c b/src/mainboard/lenovo/x60/fadt.c new file mode 100644 index 0000000..e45db8a --- /dev/null +++ b/src/mainboard/lenovo/x60/fadt.c @@ -0,0 +1,164 @@ +/* + * 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> + +/* 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. + */ +#define APM_CNT 0xb2 +#define CST_CONTROL 0x85 +#define PST_CONTROL 0x80 +#define ACPI_DISABLE 0x1e +#define ACPI_ENABLE 0xe1 +#define GNVS_UPDATE 0xea + +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, "CORE ", 6); + memcpy(header->oem_table_id, "COREBOOT", 8); + memcpy(header->asl_compiler_id, "CORE", 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 = ACPI_ENABLE; + fadt->acpi_disable = ACPI_DISABLE; + fadt->s4bios_req = 0x0; + fadt->pstate_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 + 0x20; + fadt->pm_tmr_blk = pmbase + 0x8; + fadt->gpe0_blk = pmbase + 0x28; + 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 = 8; + fadt->gpe1_blk_len = 0; + fadt->gpe1_base = 0; + fadt->cst_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 = 16; + 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 + 0x20; + 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 = 64; + fadt->x_gpe0_blk.bit_offset = 0; + fadt->x_gpe0_blk.resv = 0; + fadt->x_gpe0_blk.addrl = pmbase + 0x28; + 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/lenovo/x60/irq_tables.c b/src/mainboard/lenovo/x60/irq_tables.c new file mode 100644 index 0000000..ce0bc4f --- /dev/null +++ b/src/mainboard/lenovo/x60/irq_tables.c @@ -0,0 +1,61 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 Sven Schnelle svens@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; 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 + */ + +#include <arch/pirq_routing.h> + +const struct irq_routing_table intel_irq_routing_table = { + PIRQ_SIGNATURE, /* u32 signature */ + PIRQ_VERSION, /* u16 version */ + 32 + 16 * 15, /* Max. number of devices on the bus */ + 0x00, /* Interrupt router bus */ + (0x1f << 3) | 0x0, /* Interrupt router dev */ + 0, /* IRQs devoted exclusively to PCI usage */ + 0x8086, /* Vendor */ + 0x122e, /* Device */ + 0, /* Miniport */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ + 0xf5, /* Checksum (has to be set to some value that + * would give 0 after the sum of all bytes + * for this structure (including checksum). + */ + { + /* bus, dev | fn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */ + {0x00, (0x1b << 3) | 0x0, {{0x00, 0xdef8}, {0x61, 0x1cf8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x0, 0x0}, + {0x00, (0x1c << 3) | 0x0, {{0x68, 0x1cf8}, {0x69, 0x1cf8}, {0x6a, 0x1cf8}, {0x6b, 0x1cf8}}, 0x0, 0x0}, + {0x00, (0x1d << 3) | 0x0, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x63, 0x1cf8}}, 0x0, 0x0}, + {0x00, (0x1f << 3) | 0x0, {{0x6b, 0x1cf8}, {0x60, 0x1cf8}, {0x60, 0x1cf8}, {0x00, 0xdef8}}, 0x0, 0x0}, + {0x02, (0x00 << 3) | 0x0, {{0x68, 0x1cf8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x0, 0x0}, + {0x03, (0x00 << 3) | 0x0, {{0x69, 0x1cf8}, {0x6a, 0x1cf8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x1, 0x0}, + {0x03, (0x1f << 3) | 0x0, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x0, 0x0}, + {0x04, (0x00 << 3) | 0x0, {{0x6a, 0x1cf8}, {0x6b, 0x1cf8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x2, 0x0}, + {0x04, (0x1f << 3) | 0x0, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x0, 0x0}, + {0x0c, (0x00 << 3) | 0x0, {{0x6b, 0x1cf8}, {0x68, 0x1cf8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x3, 0x0}, + {0x0c, (0x1f << 3) | 0x0, {{0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x0, 0x0}, + {0x15, (0x00 << 3) | 0x0, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x00, 0xdef8}}, 0x0, 0x0}, + {0x00, (0x00 << 3) | 0x0, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x62, 0x1cf8}, {0x63, 0x1cf8}}, 0x0, 0x0}, + {0x00, (0x02 << 3) | 0x0, {{0x60, 0x1cf8}, {0x00, 0x1cf8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x0, 0x0}, + {0x00, (0x01 << 3) | 0x0, {{0x60, 0x1cf8}, {0x61, 0x1cf8}, {0x00, 0xdef8}, {0x00, 0xdef8}}, 0x0, 0x0}, + } +}; + +unsigned long write_pirq_routing_table(unsigned long addr) +{ + return copy_pirq_routing_table(addr); +} diff --git a/src/mainboard/lenovo/x60/mainboard.c b/src/mainboard/lenovo/x60/mainboard.c new file mode 100644 index 0000000..73cd8fa --- /dev/null +++ b/src/mainboard/lenovo/x60/mainboard.c @@ -0,0 +1,92 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2011 Sven Schnelle svens@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 <console/console.h> +#include <device/device.h> +#include <arch/io.h> +#include <boot/tables.h> +#include <delay.h> +#ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL +#include <x86emu/x86emu.h> +#endif +#include <arch/coreboot_tables.h> +#include "chip.h" +#include <device/pci_def.h> +#include <device/pci_ops.h> +#include <arch/io.h> + +static void pmh7_register_set_bit(int reg, int bit) +{ + char val; + + outb(reg, 0x15ec); + val = inb(0x15ee); + outb(reg, 0x15ec); + outb(val | (1 << bit), 0x15ee); +} + +static void backlight_enable(void) +{ + pmh7_register_set_bit(0x50, 5); +} + +#if CONFIG_PCI_OPTION_ROM_RUN_YABEL +static int int15_handler(void) +{ + u8 display_id; + + printk(BIOS_DEBUG, "%s: AX=%04x BX=%04x CX=%04x DX=%04x\n", + __func__, M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, M.x86.R_DX); + + switch (M.x86.R_AX) { + default: + /* Interrupt was not handled */ + return 0; + } + + /* Interrupt handled */ + return 1; +} + +static void int15_install(void) +{ + typedef int (* yabel_handleIntFunc)(void); + extern yabel_handleIntFunc yabel_intFuncArray[256]; + yabel_intFuncArray[0x15] = int15_handler; +} +#endif + + +static void mainboard_enable(device_t dev) +{ + backlight_enable(); + +#if CONFIG_PCI_OPTION_ROM_RUN_YABEL + /* Install custom int15 handler for VGA OPROM */ + int15_install(); +#endif +} + +struct chip_operations mainboard_ops = { + CHIP_NAME("Lenovo Thinkpad X60") + .enable_dev = mainboard_enable, +}; + diff --git a/src/mainboard/lenovo/x60/mainboard_smi.c b/src/mainboard/lenovo/x60/mainboard_smi.c new file mode 100644 index 0000000..6736ace --- /dev/null +++ b/src/mainboard/lenovo/x60/mainboard_smi.c @@ -0,0 +1,53 @@ +/* + * 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 <arch/romcc_io.h> +#include <console/console.h> +#include <cpu/x86/smm.h> +#include "southbridge/intel/i82801gx/nvs.h" + +/* The southbridge SMI handler checks whether gnvs has a + * valid pointer before calling the trap handler + */ +extern global_nvs_t *gnvs; + +int mainboard_io_trap_handler(int smif) +{ + switch (smif) { + case 0x99: + printk(BIOS_DEBUG, "Sample\n"); + //gnvs->smif = 0; + break; + default: + return 0; + } + + /* On success, the IO Trap Handler returns 0 + * On failure, the IO Trap Handler returns a value != 0 + * + * For now, we force the return value to 0 and log all traps to + * see what's going on. + */ + //gnvs->smif = 0; + return 1; +} + diff --git a/src/mainboard/lenovo/x60/mptable.c b/src/mainboard/lenovo/x60/mptable.c new file mode 100644 index 0000000..8cf4a09 --- /dev/null +++ b/src/mainboard/lenovo/x60/mptable.c @@ -0,0 +1,84 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2011 Sven Schnelle svens@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 + */ + +/* generated by MPTable, version 2.0.15*/ +/* as modified by RGM for coreboot */ +#include <console/console.h> +#include <arch/smp/mpspec.h> +#include <arch/ioapic.h> +#include <device/pci.h> +#include <string.h> +#include <stdint.h> + +static void *smp_write_config_table(void *v) +{ + struct mp_config_table *mc; + + mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN); + + mptable_init(mc, LAPIC_ADDR); + + smp_write_processors(mc); + + +/*Bus: Bus ID Type*/ +/* smp_write_bus(mc, 0, "PCI "); + smp_write_bus(mc, 2, "PCI "); + smp_write_bus(mc, 3, "PCI "); + smp_write_bus(mc, 21, "PCI "); + smp_write_bus(mc, 22, "ISA ");*/ +/*I/O APICs: APIC ID Version State Address*/ + smp_write_ioapic(mc, 2, 0x20, IO_APIC_ADDR); + /* TODO: If you have multiple IOAPICs, add them here. */ +/*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# +*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0x0, 0x2, 0x0); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0x1, 0x2, 0x1); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0x0, 0x2, 0x2); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0x3, 0x2, 0x3); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0x4, 0x2, 0x4); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0x5, 0x2, 0x5); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0x6, 0x2, 0x6); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0x7, 0x2, 0x7); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0x8, 0x2, 0x8); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0x9, 0x2, 0x9); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0xa, 0x2, 0xa); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0xb, 0x2, 0xb); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0xc, 0x2, 0xc); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0xd, 0x2, 0xd); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0xe, 0x2, 0xe); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0xf, 0x2, 0xf); +/*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/ + smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0x0, MP_APIC_ALL, 0x0); + smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x16, 0x0, MP_APIC_ALL, 0x1); + + mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length); + mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length); + printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n", + mc, smp_next_mpe_entry(mc)); + return smp_next_mpe_entry(mc); +} + +unsigned long write_smp_table(unsigned long addr) +{ + void *v; + v = smp_write_floating_table(addr); + return (unsigned long)smp_write_config_table(v); +} diff --git a/src/mainboard/lenovo/x60/romstage.c b/src/mainboard/lenovo/x60/romstage.c new file mode 100644 index 0000000..cb58881 --- /dev/null +++ b/src/mainboard/lenovo/x60/romstage.c @@ -0,0 +1,386 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2011 Sven Schnelle svens@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 <stdint.h> +#include <string.h> +#include <arch/io.h> +#include <arch/romcc_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 <usbdebug.h> +#include <cpu/x86/bist.h> +#include "northbridge/intel/i945/i945.h" +#include "northbridge/intel/i945/raminit.h" +#include "southbridge/intel/i82801gx/i82801gx.h" + +void setup_ich7_gpios(void) +{ + printk(BIOS_DEBUG, " GPIOS..."); + + outl(0x1f40f7c2, DEFAULT_GPIOBASE + 0x00); /* GPIO_USE_SEL */ + outl(0xe0e8ffc3, DEFAULT_GPIOBASE + 0x04); /* GP_IO_SEL */ + outl(0xfbf6ddfd, DEFAULT_GPIOBASE + 0x0c); /* GP_LVL */ + /* Output Control Registers */ + outl(0x00040000, DEFAULT_GPIOBASE + 0x18); /* GPO_BLINK */ + /* Input Control Registers */ + outl(0x000039ff, DEFAULT_GPIOBASE + 0x2c); /* GPI_INV */ + outl(0x000100f2, DEFAULT_GPIOBASE + 0x30); /* GPIO_USE_SEL2 */ + outl(0x000000f0, DEFAULT_GPIOBASE + 0x34); /* GP_IO_SEL2 */ + outl(0x00030043, DEFAULT_GPIOBASE + 0x38); /* GP_LVL */ + +} + +static void ich7_enable_lpc(void) +{ + // Enable Serial IRQ + pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x64, 0xd0); + // decode range + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x80, 0x0210); + // decode range + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x82, 0x1f0d); + + /* range 0x1600 - 0x167f */ + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x84, 0x1601); + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x86, 0x007c); + + /* range 0x15e0 - 0x10ef */ + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x88, 0x15e1); + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x8a, 0x000c); + + /* range 0x1680 - 0x169f */ + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x8c, 0x1681); + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x8e, 0x001c); + +} + +static void pnp_write_register(device_t dev, int reg, int val) +{ + unsigned int port = dev >> 8; + outb(reg, port); + outb(val, port+1); +} + +static void dock_write_register(int reg, int value) +{ + outb(reg, 0x164e); + outb(value, 0x164f); + /* original software reads the chip id after every + I/O operation. Not sure if they are doing it for + some code switching depending on hardware or just + to have a delay after every operation. + + Do it the same way for now, we may remove it later + if it isn't needed + */ + outb(0x20, 0x164e); + inb(0x164f); +} + +static void dock_dlpc_init(void) +{ + /* Select DLPC module */ + dock_write_register(0x07, 0x19); + /* DLPC Base Address 0x164c */ + dock_write_register(0x60, 0x16); + dock_write_register(0x61, 0x4c); + /* Activate DLPC */ + dock_write_register(0x30, 0x01); + outb(0x07, 0x164c); + + while(!(inb(0x164c) & 8)) + udelay(100 * 100); +} + +static void dock_gpio_set_mode(int port, int mode) +{ + dock_write_register(0xf0, port); + dock_write_register(0xf1, mode); + +} + +static void dock_gpio_init(void) +{ + /* Select GPIO module */ + dock_write_register(0x07, 0x07); + /* GPIO Base Address 0x1680 */ + dock_write_register(0x60, 0x16); + dock_write_register(0x61, 0x80); + + /* Activate GPIO */ + dock_write_register(0x30, 0x01); + + dock_gpio_set_mode(0x00, 3); + dock_gpio_set_mode(0x01, 3); + dock_gpio_set_mode(0x02, 0); + dock_gpio_set_mode(0x03, 3); + dock_gpio_set_mode(0x04, 4); + dock_gpio_set_mode(0x20, 4); + dock_gpio_set_mode(0x21, 4); + dock_gpio_set_mode(0x23, 4); +} + +static void connect_dock(void) +{ + /* Enable 14.318MHz CLK on CLKIN */ + dock_write_register(0x29, 0x00); + dock_write_register(0x29, 0xa0); + dock_gpio_init(); + /* Assert D_PLTRST# */ + outb(0xfe, 0x1680); + dock_dlpc_init(); + /* Deassert D_PLTRST# */ + outb(0xff, 0x1680); +} + +static void early_superio_config(void) +{ + device_t dev; + + dev=PNP_DEV(0x2e, 0x00); + pnp_write_register(dev, 0x29, 0x06); + + /* Enable COM1 */ + pnp_write_register(dev, 0x07, 0x03); + pnp_write_register(dev, 0x60, 0x03); + pnp_write_register(dev, 0x61, 0xf8); + pnp_write_register(dev, 0x30, 0x01); +} + +static void rcba_config(void) +{ + /* Set up virtual channel 0 */ + RCBA32(0x0014) = 0x80000001; + RCBA32(0x001c) = 0x03128010; + + /* Device 1f interrupt pin register */ + RCBA32(0x3100) = 0x00001230; + RCBA32(0x3108) = 0x40004321; + + /* PCIe Interrupts */ + RCBA32(0x310c) = 0x00004321; + /* HD Audio Interrupt */ + RCBA32(0x3110) = 0x00000002; + + /* dev irq route register */ + RCBA16(0x3140) = 0x1007; + RCBA16(0x3142) = 0x0076; + RCBA16(0x3144) = 0x3210; + RCBA16(0x3146) = 0x7654; + RCBA16(0x3148) = 0x0010; + + /* Enable IOAPIC */ + RCBA8(0x31ff) = 0x03; + + /* Enable upper 128bytes of CMOS */ +// RCBA32(0x3400) = (1 << 2); + + /* Disable unused devices */ + RCBA32(0x3418) = FD_PCIE6 | FD_PCIE5 | FD_INTLAN | FD_ACMOD | FD_ACAUD; + RCBA32(0x3418) |= (1 << 0); // Required. +} + +static void early_ich7_init(void) +{ + uint8_t reg8; + uint32_t reg32; + + // program secondary mlt XXX byte? + pci_write_config8(PCI_DEV(0, 0x1e, 0), 0x1b, 0x20); + + // reset rtc power status + reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa4); + reg8 &= ~(1 << 2); + pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa4, reg8); + + // usb transient disconnect + reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xad); + reg8 |= (3 << 0); + pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xad, reg8); + + reg32 = pci_read_config32(PCI_DEV(0, 0x1d, 7), 0xfc); + reg32 |= (1 << 29) | (1 << 17); + pci_write_config32(PCI_DEV(0, 0x1d, 7), 0xfc, reg32); + + reg32 = pci_read_config32(PCI_DEV(0, 0x1d, 7), 0xdc); + reg32 |= (1 << 31) | (1 << 27); + pci_write_config32(PCI_DEV(0, 0x1d, 7), 0xdc, reg32); + + RCBA32(0x0088) = 0x0011d000; + RCBA16(0x01fc) = 0x060f; + RCBA32(0x01f4) = 0x86000040; + RCBA32(0x0214) = 0x10030549; + RCBA32(0x0218) = 0x00020504; + RCBA8(0x0220) = 0xc5; + reg32 = RCBA32(0x3410); + reg32 |= (1 << 6); + RCBA32(0x3410) = reg32; + reg32 = RCBA32(0x3430); + reg32 &= ~(3 << 0); + reg32 |= (1 << 0); + RCBA32(0x3430) = reg32; + RCBA32(0x3418) |= (1 << 0); + RCBA16(0x0200) = 0x2008; + RCBA8(0x2027) = 0x0d; + RCBA16(0x3e08) |= (1 << 7); + RCBA16(0x3e48) |= (1 << 7); + RCBA32(0x3e0e) |= (1 << 7); + RCBA32(0x3e4e) |= (1 << 7); + + // next step only on ich7m b0 and later: + reg32 = RCBA32(0x2034); + reg32 &= ~(0x0f << 16); + reg32 |= (5 << 16); + RCBA32(0x2034) = reg32; +} + +#include <cbmem.h> + +void main(unsigned long bist) +{ + u32 reg32; + int boot_mode = 0; + + if (bist == 0) + enable_lapic(); + + /* Force PCIRST# */ + pci_write_config16(PCI_DEV(0, 0x1e, 0), BCTRL, SBR); + udelay(200 * 1000); + pci_write_config16(PCI_DEV(0, 0x1e, 0), BCTRL, 0); + + ich7_enable_lpc(); + + connect_dock(); + + early_superio_config(); + /* Set up the console */ + uart_init(); + + +#if CONFIG_USBDEBUG + i82801gx_enable_usbdebug(1); + early_usbdebug_init(); +#endif + + console_init(); + + /* Halt if there was a built in self test failure */ + report_bist_failure(bist); + + if (MCHBAR16(SSKPD) == 0xCAFE) { + printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n"); + outb(0x6, 0xcf9); + while (1) asm("hlt"); + } + + /* Perform some early chipset initialization required + * before RAM initialization can work + */ + i945_early_initialization(); + + /* Read PM1_CNT */ + reg32 = inl(DEFAULT_PMBASE + 0x04); + printk(BIOS_DEBUG, "PM1_CNT: %08x\n", reg32); + if (((reg32 >> 10) & 7) == 5) { +#if CONFIG_HAVE_ACPI_RESUME + printk(BIOS_DEBUG, "Resume from S3 detected.\n"); + boot_mode = 2; + /* Clear SLP_TYPE. This will break stage2 but + * we care for that when we get there. + */ + outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04); + +#else + printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n"); +#endif + } + + /* Enable SPD ROMs and DDR-II DRAM */ + enable_smbus(); + +#if CONFIG_DEFAULT_CONSOLE_LOGLEVEL > 8 + dump_spd_registers(); +#endif + + sdram_initialize(boot_mode); + + /* Perform some initialization that must run before stage2 */ + early_ich7_init(); + + /* This should probably go away. Until now it is required + * and mainboard specific + */ + rcba_config(); + + /* Chipset Errata! */ + fixup_i945_errata(); + + /* Initialize the internal PCIe links before we go into stage2 */ + i945_late_initialization(); + +#if !CONFIG_HAVE_ACPI_RESUME +#if CONFIG_DEFAULT_CONSOLE_LOGLEVEL > 8 +#if CONFIG_DEBUG_RAM_SETUP + sdram_dump_mchbar_registers(); + + { + /* This will not work if TSEG is in place! */ + u32 tom = pci_read_config32(PCI_DEV(0,2,0), 0x5c); + + printk(BIOS_DEBUG, "TOM: 0x%08x\n", tom); + ram_check(0x00000000, 0x000a0000); + ram_check(0x00100000, tom); + } +#endif +#endif +#endif + + MCHBAR16(SSKPD) = 0xCAFE; + +#if CONFIG_HAVE_ACPI_RESUME + /* Start address of high memory tables */ + unsigned long high_ram_base = get_top_of_ram() - HIGH_MEMORY_SIZE; + + /* 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 ((boot_mode == 2) && cbmem_reinit((u64)high_ram_base)) { + void *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); + } +#endif + /* Set legacy Brightness control to full brightness */ + pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, 0xff); +}
Nice, a ThinkPad patch! :) Many have wanted that.
Sven Schnelle wrote:
commit 7d3a1ebf3de5746d3dec8f47e74458c15018c694 Author: Sven Schnelle svens@stackframe.org Date: Mon Jan 10 13:23:59 2011 +0100
Initial bits for X60 support Signed-off-by: Sven Schnelle <svens@stackframe.org>
Well the commit is quite a lot more than initial bits for support. :)
Could you split this up in a few more commits? E.g. one that adds the CPU model to the socket, one for speedstep (maybe combine them if appropriate) and then the one that adds the new board?
Also, in particular for the patch that adds the new board, it is quite beneficial to use svn cp to copy files and *then* modify them for the new boards - that way the history is kept and the patch is much easier to look at. I am not sure how well git svn supports these operations. Maybe it does, but I haven't tried it.
//Peter
Hi Peter,
Peter Stuge peter@stuge.se writes:
Nice, a ThinkPad patch! :) Many have wanted that.
Sven Schnelle wrote:
commit 7d3a1ebf3de5746d3dec8f47e74458c15018c694 Author: Sven Schnelle svens@stackframe.org Date: Mon Jan 10 13:23:59 2011 +0100
Initial bits for X60 support Signed-off-by: Sven Schnelle <svens@stackframe.org>
Well the commit is quite a lot more than initial bits for support. :)
Could you split this up in a few more commits? E.g. one that adds the CPU model to the socket, one for speedstep (maybe combine them if appropriate) and then the one that adds the new board?
Hmm, i would first really appreciate comments from People who know the CAR code if the modification is correct. I don't know the code well enough to tell for sure.
But it should be not that big problem to split up the patches.
Also, in particular for the patch that adds the new board, it is quite beneficial to use svn cp to copy files and *then* modify them for the new boards - that way the history is kept and the patch is much easier to look at. I am not sure how well git svn supports these operations. Maybe it does, but I haven't tried it.
Hmm, so i should 'svn cp' files like romstage.c, mainboard.c, etc? Is the history really helpful if the target is different?
Regards,
Sven.
* Peter Stuge peter@stuge.se [110110 21:34]:
Nice, a ThinkPad patch! :) Many have wanted that.
Sven Schnelle wrote:
commit 7d3a1ebf3de5746d3dec8f47e74458c15018c694 Author: Sven Schnelle svens@stackframe.org Date: Mon Jan 10 13:23:59 2011 +0100
Initial bits for X60 support Signed-off-by: Sven Schnelle <svens@stackframe.org>
Well the commit is quite a lot more than initial bits for support. :)
Could you split this up in a few more commits? E.g. one that adds the CPU model to the socket, one for speedstep (maybe combine them if appropriate) and then the one that adds the new board?
Not sure we want to use that socket as it is the container for all the old CPUs. Sure it isn't a mFCPGA478 'cause that's what Merom/Yonah usually use.
Stefan
Hi Stefan,
Stefan Reinauer stepan@coreboot.org writes:
Not sure we want to use that socket as it is the container for all the old CPUs. Sure it isn't a mFCPGA478 'cause that's what Merom/Yonah usually use.
Intel Spec Finder (http://ark.intel.com/Product.aspx?id=27228) says it's 'PBGA479' which is soldered directly to the Board, so mPGA479M looked like the best fit. But the mFCPGA478 works without modifications, so we may use that.
I have no problem changing the code to 478, i'm just not sure what the right Socket is.
Regards,
Sven
Peter Stuge peter@stuge.se writes:
Could you split this up in a few more commits? E.g. one that adds the CPU model to the socket, one for speedstep (maybe combine them if appropriate) and then the one that adds the new board?
After Stephans comment about the Socket 478 vs 479 socket, i've changed it to Socket 478, so there's only one big mainboard patch left.
Also, in particular for the patch that adds the new board, it is quite beneficial to use svn cp to copy files and *then* modify them for the new boards - that way the history is kept and the patch is much easier to look at. I am not sure how well git svn supports these operations. Maybe it does, but I haven't tried it.
ok, i did this before the svn diff:
svn cp ../../getac/p470/ec.c . svn cp ../../getac/p470/ec.h . svn cp ../../getac/p470/romstage.c . svn cp ../../getac/p470/mainboard.c . svn cp ../../getac/p470/dmi.h . svn cp ../../getac/p470/acpi_tables.c . svn cp ../../getac/p470/chip.h . svn cp ../../getac/p470/cmos.layout . svn cp ../../getac/p470/devicetree.cb . svn cp ../../getac/p470/dsdt.asl . svn cp ../../getac/p470/fadt.c . svn cp ../../getac/p470/mainboard_smi.c .
Signed-off-by: Sven Schnelle svens@stackframe.org
Index: src/mainboard/Kconfig =================================================================== --- src/mainboard/Kconfig (revision 6252) +++ src/mainboard/Kconfig (working copy) @@ -54,6 +54,8 @@ bool "iBase" config VENDOR_IBM bool "IBM" +config VENDOR_LENOVO + bool "Lenovo" config VENDOR_IEI bool "IEI" config VENDOR_INTEL @@ -147,6 +149,7 @@ source "src/mainboard/jetway/Kconfig" source "src/mainboard/kontron/Kconfig" source "src/mainboard/lanner/Kconfig" +source "src/mainboard/lenovo/Kconfig" source "src/mainboard/lippert/Kconfig" source "src/mainboard/mitac/Kconfig" source "src/mainboard/msi/Kconfig" Index: src/mainboard/lenovo/Kconfig =================================================================== --- src/mainboard/lenovo/Kconfig (revision 0) +++ src/mainboard/lenovo/Kconfig (revision 0) @@ -0,0 +1,17 @@ +if VENDOR_LENOVO + +choice + prompt "Mainboard model" + +config BOARD_LENOVO_X60 + bool "Thinkpad X60" + +endchoice + +source "src/mainboard/lenovo/x60/Kconfig" + +config MAINBOARD_VENDOR + string + default "Lenovo" + +endif # VENDOR_LENOVO Index: src/mainboard/lenovo/x60/dmi.h =================================================================== --- src/mainboard/lenovo/x60/dmi.h (revision 0) +++ src/mainboard/lenovo/x60/dmi.h (working copy) @@ -3,10 +3,9 @@ * * 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 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 @@ -15,13 +14,12 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#define DMI_TABLE_SIZE 0x55
-static const u8 dmi_table[DMI_TABLE_SIZE] = { +static u8 dmi_table[DMI_TABLE_SIZE] = { 0x5f, 0x53, 0x4d, 0x5f, 0x29, 0x1f, 0x02, 0x03, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x44, 0x4d, 0x49, 0x5f, 0x61, 0x35, 0x00, 0xa0, 0xff, 0x0f, 0x00, 0x01, 0x00, 0x23, 0x00, 0x00, 0x14, 0x00, 0x00, 0x01, 0x02, 0x00, 0xe0, 0x03, 0x07, 0x90, 0xde, 0xcb, 0x7f, 0x00, 0x00, Index: src/mainboard/lenovo/x60/fadt.c =================================================================== --- src/mainboard/lenovo/x60/fadt.c (revision 0) +++ src/mainboard/lenovo/x60/fadt.c (working copy) @@ -1,7 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2007-2009 coresystems GmbH + * 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 @@ -41,24 +41,24 @@
memset((void *) fadt, 0, sizeof(acpi_fadt_t)); memcpy(header->signature, "FACP", 4); - header->length = sizeof(acpi_fadt_t); - header->revision = 3; + header->length = sizeof(acpi_fadt_t); + header->revision = 3; memcpy(header->oem_id, "CORE ", 6); memcpy(header->oem_table_id, "COREBOOT", 8); memcpy(header->asl_compiler_id, "CORE", 4); - header->asl_compiler_revision = 1; + 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 = ACPI_ENABLE; + fadt->acpi_disable = ACPI_DISABLE; + fadt->s4bios_req = 0x0; + fadt->pstate_cnt = PST_CONTROL;
- fadt->sci_int = 0x9; - fadt->smi_cmd = APM_CNT; - fadt->acpi_enable = ACPI_ENABLE; - fadt->acpi_disable = ACPI_DISABLE; - fadt->s4bios_req = 0x0; // S4 command disabled - fadt->pstate_cnt = PST_CONTROL; - fadt->pm1a_evt_blk = pmbase; fadt->pm1b_evt_blk = 0x0; fadt->pm1a_cnt_blk = pmbase + 0x4; @@ -75,89 +75,89 @@ fadt->gpe0_blk_len = 8; fadt->gpe1_blk_len = 0; fadt->gpe1_base = 0; - fadt->cst_cnt = CST_CONTROL; + fadt->cst_cnt = CST_CONTROL; fadt->p_lvl2_lat = 1; - fadt->p_lvl3_lat = 85; - fadt->flush_size = 1024; - fadt->flush_stride = 16; + 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 = 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->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_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->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_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 = 1; - 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_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 = 16; - 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_pm1a_cnt_blk.space_id = 1; + fadt->x_pm1a_cnt_blk.bit_width = 16; + 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 = 1; - 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_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 + 0x20; - fadt->x_pm2_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 + 0x20; + 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_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 = 64; - fadt->x_gpe0_blk.bit_offset = 0; - fadt->x_gpe0_blk.resv = 0; - fadt->x_gpe0_blk.addrl = pmbase + 0x28; - fadt->x_gpe0_blk.addrh = 0x0; + fadt->x_gpe0_blk.space_id = 1; + fadt->x_gpe0_blk.bit_width = 64; + fadt->x_gpe0_blk.bit_offset = 0; + fadt->x_gpe0_blk.resv = 0; + fadt->x_gpe0_blk.addrl = pmbase + 0x28; + fadt->x_gpe0_blk.addrh = 0x0;
- fadt->x_gpe1_blk.space_id = 1; - 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; + 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); Index: src/mainboard/lenovo/x60/romstage.c =================================================================== --- src/mainboard/lenovo/x60/romstage.c (revision 0) +++ src/mainboard/lenovo/x60/romstage.c (working copy) @@ -1,8 +1,8 @@ /* * This file is part of the coreboot project. - * - * Copyright (C) 2007-2009 coresystems GmbH * + * Copyright (c) 2011 Sven Schnelle svens@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 @@ -27,9 +27,9 @@ #include <device/pnp_def.h> #include <cpu/x86/lapic.h> #include <lib.h> -#include <usbdebug.h> #include <pc80/mc146818rtc.h> #include <console/console.h> +#include <usbdebug.h> #include <cpu/x86/bist.h> #include "northbridge/intel/i945/i945.h" #include "northbridge/intel/i945/raminit.h" @@ -37,46 +37,19 @@
void setup_ich7_gpios(void) { - u32 gpios; + printk(BIOS_DEBUG, " GPIOS...");
- printk(BIOS_DEBUG, " GPIOS..."); - /* General Registers */ - outl(0x1f28f7c2, DEFAULT_GPIOBASE + 0x00); /* GPIO_USE_SEL */ - outl(0xe0e809c3, DEFAULT_GPIOBASE + 0x04); /* GP_IO_SEL */ - // Power On value is eede1fbf, we set: (TODO explain why) - // -- [21] = 1 - // -- [20] = 0 - // -- [18] = 0 - // -- [17] = 0 - // -- [13] = 1 - // -- [05] = 0 - // -- [04] = 0 - // -- [03] = 0 - // -- [02] = 0 - // We should probably do this explicitly bitwise, see below. - outl(0xeee83f83, DEFAULT_GPIOBASE + 0x0c); /* GP_LVL */ + outl(0x1f40f7c2, DEFAULT_GPIOBASE + 0x00); /* GPIO_USE_SEL */ + outl(0xe0e8ffc3, DEFAULT_GPIOBASE + 0x04); /* GP_IO_SEL */ + outl(0xfbf6ddfd, DEFAULT_GPIOBASE + 0x0c); /* GP_LVL */ /* Output Control Registers */ - outl(0x00000000, DEFAULT_GPIOBASE + 0x18); /* GPO_BLINK */ + outl(0x00040000, DEFAULT_GPIOBASE + 0x18); /* GPO_BLINK */ /* Input Control Registers */ - outl(0x00000180, DEFAULT_GPIOBASE + 0x2c); /* GPI_INV */ - outl(0x000000e6, DEFAULT_GPIOBASE + 0x30); /* GPIO_USE_SEL2 */ - outl(0x000000d0, DEFAULT_GPIOBASE + 0x34); /* GP_IO_SEL2 */ - outl(0x00000034, DEFAULT_GPIOBASE + 0x38); /* GP_LVL2 */ + outl(0x000039ff, DEFAULT_GPIOBASE + 0x2c); /* GPI_INV */ + outl(0x000100f2, DEFAULT_GPIOBASE + 0x30); /* GPIO_USE_SEL2 */ + outl(0x000000f0, DEFAULT_GPIOBASE + 0x34); /* GP_IO_SEL2 */ + outl(0x00030043, DEFAULT_GPIOBASE + 0x38); /* GP_LVL */
- printk(BIOS_SPEW, "\n Initializing drive bay...\n"); - gpios = inl(DEFAULT_GPIOBASE + 0x38); // GPIO Level 2 - gpios |= (1 << 0); // GPIO33 = ODD - gpios |= (1 << 1); // GPIO34 = IDE_RST# - outl(gpios, DEFAULT_GPIOBASE + 0x38); /* GP_LVL2 */ - - gpios = inl(DEFAULT_GPIOBASE + 0x0c); // GPIO Level - gpios &= ~(1 << 13); // ?? - outl(gpios, DEFAULT_GPIOBASE + 0x0c); /* GP_LVL */ - - printk(BIOS_SPEW, "\n Initializing Ethernet NIC...\n"); - gpios = inl(DEFAULT_GPIOBASE + 0x0c); // GPIO Level - gpios &= ~(1 << 24); // Enable LAN Power - outl(gpios, DEFAULT_GPIOBASE + 0x0c); /* GP_LVL */ }
static void ich7_enable_lpc(void) @@ -84,126 +57,148 @@ // Enable Serial IRQ pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x64, 0xd0); // decode range - pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x80, 0x0007); + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x80, 0x0210); // decode range - pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x82, 0x3f0f); - // Enable 0x02e0 - 0x2ff - pci_write_config32(PCI_DEV(0, 0x1f, 0), 0x84, 0x001c02e1); - // Enable 0x600 - 0x6ff - pci_write_config32(PCI_DEV(0, 0x1f, 0), 0x88, 0x00fc0601); - // Enable 0x68 - 0x6f - pci_write_config32(PCI_DEV(0, 0x1f, 0), 0x8c, 0x00040069); + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x82, 0x1f0d); + + /* range 0x1600 - 0x167f */ + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x84, 0x1601); + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x86, 0x007c); + + /* range 0x15e0 - 0x10ef */ + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x88, 0x15e1); + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x8a, 0x000c); + + /* range 0x1680 - 0x169f */ + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x8c, 0x1681); + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x8e, 0x001c); + }
-/* This box has two superios, so enabling serial becomes slightly excessive. - * We disable a lot of stuff to make sure that there are no conflicts between - * the two. Also set up the GPIOs from the beginning. This is the "no schematic - * but safe anyways" method. - */ -static void pnp_enter_ext_func_mode(device_t dev) +static void pnp_write_register(device_t dev, int reg, int val) { unsigned int port = dev >> 8; - outb(0x55, port); + outb(reg, port); + outb(val, port+1); }
-static void pnp_exit_ext_func_mode(device_t dev) +static void dock_write_register(int reg, int value) { - unsigned int port = dev >> 8; - outb(0xaa, port); + outb(reg, 0x164e); + outb(value, 0x164f); + /* original software reads the chip id after every + I/O operation. Not sure if they are doing it for + some code switching depending on hardware or just + to have a delay after every operation. + + Do it the same way for now, we may remove it later + if it isn't needed + */ + outb(0x20, 0x164e); + inb(0x164f); }
-static void pnp_write_register(device_t dev, int reg, int val) +static void dock_dlpc_init(void) { - unsigned int port = dev >> 8; - outb(reg, port); - outb(val, port+1); + /* Select DLPC module */ + dock_write_register(0x07, 0x19); + /* DLPC Base Address 0x164c */ + dock_write_register(0x60, 0x16); + dock_write_register(0x61, 0x4c); + /* Activate DLPC */ + dock_write_register(0x30, 0x01); + outb(0x07, 0x164c); + + while(!(inb(0x164c) & 8)) + udelay(100 * 100); }
-static void early_superio_config(void) +static void dock_gpio_set_mode(int port, int mode) { - device_t dev; + dock_write_register(0xf0, port); + dock_write_register(0xf1, mode);
- dev=PNP_DEV(0x4e, 0x00); +}
- pnp_enter_ext_func_mode(dev); - pnp_write_register(dev, 0x02, 0x0e); // UART power - pnp_write_register(dev, 0x1b, (0x3e8 >> 2)); // UART3 base - pnp_write_register(dev, 0x1c, (0x2e8 >> 2)); // UART4 base - pnp_write_register(dev, 0x1d, (5 << 4) | 11); // UART3,4 IRQ - pnp_write_register(dev, 0x1e, 1); // no 32khz clock - pnp_write_register(dev, 0x24, (0x3f8 >> 2)); // UART1 base - pnp_write_register(dev, 0x28, (4 << 4) | 0); // UART1,2 IRQ - pnp_write_register(dev, 0x2c, 0); // DMA0 FIR - pnp_write_register(dev, 0x30, (0x600 >> 4)); // Runtime Register Block Base +static void dock_gpio_init(void) +{ + /* Select GPIO module */ + dock_write_register(0x07, 0x07); + /* GPIO Base Address 0x1680 */ + dock_write_register(0x60, 0x16); + dock_write_register(0x61, 0x80);
- pnp_write_register(dev, 0x31, 0xce); // GPIO1 DIR - pnp_write_register(dev, 0x32, 0x00); // GPIO1 POL - pnp_write_register(dev, 0x33, 0x0f); // GPIO2 DIR - pnp_write_register(dev, 0x34, 0x00); // GPIO2 POL - pnp_write_register(dev, 0x35, 0xa8); // GPIO3 DIR - pnp_write_register(dev, 0x36, 0x00); // GPIO3 POL - pnp_write_register(dev, 0x37, 0xa8); // GPIO4 DIR - pnp_write_register(dev, 0x38, 0x00); // GPIO4 POL + /* Activate GPIO */ + dock_write_register(0x30, 0x01);
- pnp_write_register(dev, 0x39, 0x00); // GPIO1 OUT - pnp_write_register(dev, 0x40, 0x80); // GPIO2/MISC OUT - pnp_write_register(dev, 0x41, 0x00); // GPIO5 OUT - pnp_write_register(dev, 0x42, 0xa8); // GPIO5 DIR - pnp_write_register(dev, 0x43, 0x00); // GPIO5 POL - pnp_write_register(dev, 0x44, 0x00); // GPIO ALT1 - pnp_write_register(dev, 0x45, 0x50); // GPIO ALT2 - pnp_write_register(dev, 0x46, 0x00); // GPIO ALT3 + dock_gpio_set_mode(0x00, 3); + dock_gpio_set_mode(0x01, 3); + dock_gpio_set_mode(0x02, 0); + dock_gpio_set_mode(0x03, 3); + dock_gpio_set_mode(0x04, 4); + dock_gpio_set_mode(0x20, 4); + dock_gpio_set_mode(0x21, 4); + dock_gpio_set_mode(0x23, 4); +}
- pnp_write_register(dev, 0x48, 0x55); // GPIO ALT5 - pnp_write_register(dev, 0x49, 0x55); // GPIO ALT6 - pnp_write_register(dev, 0x4a, 0x55); // GPIO ALT7 - pnp_write_register(dev, 0x4b, 0x55); // GPIO ALT8 - pnp_write_register(dev, 0x4c, 0x55); // GPIO ALT9 - pnp_write_register(dev, 0x4d, 0x55); // GPIO ALT10 +static void connect_dock(void) +{ + /* Enable 14.318MHz CLK on CLKIN */ + dock_write_register(0x29, 0x00); + dock_write_register(0x29, 0xa0); + dock_gpio_init(); + /* Assert D_PLTRST# */ + outb(0xfe, 0x1680); + dock_dlpc_init(); + /* Deassert D_PLTRST# */ + outb(0xff, 0x1680); +}
- pnp_exit_ext_func_mode(dev); +static void early_superio_config(void) +{ + device_t dev; + + dev=PNP_DEV(0x2e, 0x00); + pnp_write_register(dev, 0x29, 0x06); + + /* Enable COM1 */ + pnp_write_register(dev, 0x07, 0x03); + pnp_write_register(dev, 0x60, 0x03); + pnp_write_register(dev, 0x61, 0xf8); + pnp_write_register(dev, 0x30, 0x01); }
static void rcba_config(void) { /* Set up virtual channel 0 */ - //RCBA32(0x0014) = 0x80000001; - //RCBA32(0x001c) = 0x03128010; + RCBA32(0x0014) = 0x80000001; + RCBA32(0x001c) = 0x03128010;
/* Device 1f interrupt pin register */ - RCBA32(0x3100) = 0x00042220; - /* Device 1d interrupt pin register */ - RCBA32(0x310c) = 0x00214321; + RCBA32(0x3100) = 0x00001230; + RCBA32(0x3108) = 0x40004321;
+ /* PCIe Interrupts */ + RCBA32(0x310c) = 0x00004321; + /* HD Audio Interrupt */ + RCBA32(0x3110) = 0x00000002; + /* dev irq route register */ - RCBA16(0x3140) = 0x0232; - RCBA16(0x3142) = 0x3246; - RCBA16(0x3144) = 0x0237; - RCBA16(0x3146) = 0x3201; - RCBA16(0x3148) = 0x3216; + RCBA16(0x3140) = 0x1007; + RCBA16(0x3142) = 0x0076; + RCBA16(0x3144) = 0x3210; + RCBA16(0x3146) = 0x7654; + RCBA16(0x3148) = 0x0010;
/* Enable IOAPIC */ RCBA8(0x31ff) = 0x03;
/* Enable upper 128bytes of CMOS */ - RCBA32(0x3400) = (1 << 2); +// RCBA32(0x3400) = (1 << 2);
/* Disable unused devices */ - RCBA32(0x3418) = FD_PCIE6 | FD_PCIE5 | FD_INTLAN | FD_ACMOD | FD_ACAUD | FD_PATA; + RCBA32(0x3418) = FD_PCIE6 | FD_PCIE5 | FD_INTLAN | FD_ACMOD | FD_ACAUD; RCBA32(0x3418) |= (1 << 0); // Required. - - /* Enable PCIe Root Port Clock Gate */ - // RCBA32(0x341c) = 0x00000001; - - - /* This should probably go into the ACPI enable trap */ - /* Set up I/O Trap #0 for 0xfe00 (SMIC) */ - RCBA32(0x1e84) = 0x00020001; - RCBA32(0x1e80) = 0x0000fe01; - - /* Set up I/O Trap #3 for 0x800-0x80c (Trap) */ - RCBA32(0x1e9c) = 0x000200f0; - RCBA32(0x1e98) = 0x000c0801; }
static void early_ich7_init(void) @@ -270,23 +265,25 @@ if (bist == 0) enable_lapic();
-#if 0 /* Force PCIRST# */ pci_write_config16(PCI_DEV(0, 0x1e, 0), BCTRL, SBR); udelay(200 * 1000); pci_write_config16(PCI_DEV(0, 0x1e, 0), BCTRL, 0); -#endif
ich7_enable_lpc(); + + connect_dock(); + early_superio_config(); - /* Set up the console */ uart_init();
+ #if CONFIG_USBDEBUG i82801gx_enable_usbdebug(1); early_usbdebug_init(); #endif + console_init();
/* Halt if there was a built in self test failure */ @@ -322,7 +319,7 @@
/* Enable SPD ROMs and DDR-II DRAM */ enable_smbus(); - + #if CONFIG_DEFAULT_CONSOLE_LOGLEVEL > 8 dump_spd_registers(); #endif @@ -332,8 +329,8 @@ /* Perform some initialization that must run before stage2 */ early_ich7_init();
- /* This should probably go away. Until now it is required - * and mainboard specific + /* This should probably go away. Until now it is required + * and mainboard specific */ rcba_config();
@@ -343,8 +340,8 @@ /* Initialize the internal PCIe links before we go into stage2 */ i945_late_initialization();
-#if CONFIG_HAVE_ACPI_RESUME == 0 - /* When doing resume, we must not overwrite RAM */ +#if !CONFIG_HAVE_ACPI_RESUME +#if CONFIG_DEFAULT_CONSOLE_LOGLEVEL > 8 #if CONFIG_DEBUG_RAM_SETUP sdram_dump_mchbar_registers();
@@ -358,6 +355,8 @@ } #endif #endif +#endif + MCHBAR16(SSKPD) = 0xCAFE;
#if CONFIG_HAVE_ACPI_RESUME @@ -375,11 +374,13 @@ * memory completely, but that's a wonderful clean up task for another * day. */ - if (resume_backup_memory) + 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); } #endif + /* Set legacy Brightness control to full brightness */ + pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, 0xff); } Index: src/mainboard/lenovo/x60/devicetree.cb =================================================================== --- src/mainboard/lenovo/x60/devicetree.cb (revision 0) +++ src/mainboard/lenovo/x60/devicetree.cb (working copy) @@ -1,8 +1,8 @@ ## ## This file is part of the coreboot project. -## -## Copyright (C) 2007-2009 coresystems GmbH ## +## Copyright (c) 2011 Sven Schnelle svens@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 @@ -22,123 +22,60 @@ chip northbridge/intel/i945
device lapic_cluster 0 on - chip cpu/intel/socket_mFCPGA478 + chip cpu/intel/socket_MFCPGA478 device lapic 0 on end end end
- device pci_domain 0 on + device pci_domain 0 on device pci 00.0 on end # host bridge - # autodetect: - #device pci 01.0 off end # i945 PCIe root port - #device pci 02.0 on end # vga controller - #device pci 02.1 on end # display controller - + device pci 02.0 on end # vga controller + device pci 02.1 on end # display controller chip southbridge/intel/i82801gx - register "pirqa_routing" = "0x0a" - register "pirqb_routing" = "0x0a" - register "pirqc_routing" = "0x0a" - register "pirqd_routing" = "0x0a" - register "pirqe_routing" = "0x80" - register "pirqf_routing" = "0x80" - register "pirqg_routing" = "0x0a" - register "pirqh_routing" = "0x0a" + register "pirqa_routing" = "0x8b" + register "pirqb_routing" = "0x8b" + register "pirqc_routing" = "0x8b" + register "pirqd_routing" = "0x8b" + register "pirqe_routing" = "0x8b" + register "pirqf_routing" = "0x8b" + register "pirqg_routing" = "0x8b" + register "pirqh_routing" = "0x8b"
- # 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 "gpi8_routing" = "1" # EXTSMI low active - register "gpi7_routing" = "2" # ECSCI low active + register "sata_ahci" = "0x0"
- # GPE0 Enables - register "gpe0_en" = "0x00800106" - register "alt_gp_smi_en" = "0x0100" + register "gpi13_routing" = "2" + register "gpi12_routing" = "2" + register "gpi8_routing" = "2"
- register "ide_legacy_combined" = "0x1" - register "ide_enable_primary" = "0x1" - register "ide_enable_secondary" = "0x0" - register "sata_ahci" = "0x0" + register "gpe0_en" = "0x11000006"
- device pci 1b.0 on end # High Definition Audio - device pci 1c.0 on end # PCIe port 1 - device pci 1c.1 on end # PCIe port 2 - device pci 1c.2 on end # PCIe port 3 - device pci 1c.3 on end # PCIe port 4 - #device pci 1c.4 off end # PCIe port 5 - #device pci 1c.5 off end # PCIe port 6 - device pci 1d.0 on end # USB UHCI - device pci 1d.1 on end # USB UHCI - device pci 1d.2 on end # USB UHCI - device pci 1d.3 on end # USB UHCI - device pci 1d.7 on end # USB2 EHCI - device pci 1e.0 on - chip southbridge/ti/pcixx12 - + device pci 1b.0 on end # Audio Controller + device pci 1c.0 on end # Ethernet + device pci 1c.1 on end # Atheros WLAN + device pci 1d.0 on end # USB UHCI + device pci 1d.1 on end # USB UHCI + device pci 1d.2 on end # USB UHCI + device pci 1d.3 on end # USB UHCI + device pci 1d.7 on end # USB2 EHCI + device pci 1f.0 on # PCI-LPC bridge + chip superio/lenovo/x60_ec +# device pnp 2e.5 on # Keyboard+Mouse +# io 0x60 = 0x60 +# io 0x62 = 0x64 +# irq 0x70 = 1 +# irq 0x72 = 12 +# end +# end +# chip superio/lenovo/pmh7 +# device pnp ff.1 on # dummy address +# end end - end # PCI bridge - #device pci 1e.2 off end # AC'97 Audio - #device pci 1e.3 off end # AC'97 Modem - device pci 1f.0 on # LPC bridge - chip superio/smsc/fdc37n972 - device pnp 2e.0 off # Floppy - end - device pnp 2e.1 off # ACPI PM - end - # 2e.2 does not exist - device pnp 2e.3 off # Parallel port - end - device pnp 2e.4 on # COM1 - io 0x60 = 0x3f8 - irq 0x70 = 4 - end - device pnp 2e.5 off - end - #device pnp 2e.6 on # RTC - # io 0x60 = 0x70 - # io 0x62 = 0x74 - #end - device pnp 2e.7 off # Keyboard - end - device pnp 2e.8 off # EC - io 0x60 = 0x62 - end - #device pnp 2e.9 on # Mailbox - #end - end - chip superio/smsc/sio10n268 - device pnp 4e.0 off # Floppy - end - device pnp 4e.1 off # Parport - end - #device pnp 4e.2 on # COM3 - # io 0x60 = 0x3e8 - # irq 0x70 = 11 - #end - #device pnp 4e.3 on # COM4 - # io 0x60 = 0x2e8 - # irq 0x70 = 10 - #end - device pnp 4e.5 on # Keyboard - io 0x60 = 0x60 - io 0x62 = 0x64 - end - device pnp 4e.7 off # GPIO1, GAME, MIDI - end - device pnp 4e.8 off # GPIO2 - end - device pnp 4e.9 off # GPIO3/4 - end - device pnp 4e.a off # ACPI - end - device pnp 4e.b off # HWM - end - end - end - device pci 1f.1 on end # IDE + device pci 1f.1 off end # IDE device pci 1f.2 on end # SATA device pci 1f.3 on end # SMBus - end - end + end + chip southbridge/ricoh/rl5c476 + end + end end Index: src/mainboard/lenovo/x60/mainboard_smi.c =================================================================== --- src/mainboard/lenovo/x60/mainboard_smi.c (revision 0) +++ src/mainboard/lenovo/x60/mainboard_smi.c (working copy) @@ -23,181 +23,31 @@ #include <arch/romcc_io.h> #include <console/console.h> #include <cpu/x86/smm.h> -#include "southbridge/intel/i82801gx/i82801gx.h" #include "southbridge/intel/i82801gx/nvs.h" -#include "northbridge/intel/i945/udelay.c" -#include "ec.c"
-#define MAX_LCD_BRIGHTNESS 0xd8 - -/* The southbridge SMI handler checks whether gnvs has a +/* The southbridge SMI handler checks whether gnvs has a * valid pointer before calling the trap handler */ extern global_nvs_t *gnvs;
int mainboard_io_trap_handler(int smif) { - u8 reg8; - u32 reg32; - switch (smif) { - case 0x2b: - printk(BIOS_DEBUG, "CPU power state switch\n"); - // TODO, move to CPU handler? + case 0x99: + printk(BIOS_DEBUG, "Sample\n"); + //gnvs->smif = 0; break; - case 0x3d: - printk(BIOS_DEBUG, "Enable C-State SMM coordination\n"); - // TODO, move to CPU handler? - break; - case 0x46: - printk(BIOS_DEBUG, "S3 DTS SMI (completely re-enable DTS)\n"); - // TODO, move to CPU handler? - break; - case 0x47: - printk(BIOS_DEBUG, "S4 DTS SMI (Update NVS DTS temperature)\n"); - // TODO, move to CPU handler? - break; - case 0xc0: - printk(BIOS_DEBUG, "Disable RF\n"); - // TODO - break; - case 0xd0: - printk(BIOS_DEBUG, "ACBS LAN Power on\n"); - // TODO - break; - case 0xd1: - printk(BIOS_DEBUG, "ACBS LAN Power off\n"); - // TODO - break; - case 0xd2: - printk(BIOS_DEBUG, "Check AC status\n"); - // TODO - break; - case 0xd3: - printk(BIOS_DEBUG, "Enable Bluetooth\n"); - // TODO - break; - case 0xd4: - printk(BIOS_DEBUG, "Disable Bluetooth\n"); - // TODO - break; - case 0xd5: - printk(BIOS_DEBUG, "Set Brightness\n"); - reg8 = gnvs->brtl; - printk(BIOS_DEBUG, "brtl: %x\n", reg8); - ec_write(0x17, reg8); - break; - case 0xd6: - printk(BIOS_DEBUG, "Get Brightness\n"); - reg8 = ec_read(0x17); - printk(BIOS_DEBUG, "brtl: %x\n", reg8); - gnvs->brtl = reg8; - break; - case 0xd7: - printk(BIOS_DEBUG, "Get ECO mode status\n"); - // TODO - break; - case 0xd8: - printk(BIOS_DEBUG, "Get sunlight readable status\n"); - // TODO - break; - case 0xd9: - printk(BIOS_DEBUG, "Get docking connection\n"); - // TODO - break; - case 0xda: - printk(BIOS_DEBUG, "Power off docking\n"); - // TODO - break; - case 0xdc: - printk(BIOS_DEBUG, "EC: Turn on LED on ECO enable\n"); - // TODO - break; - case 0xdd: - printk(BIOS_DEBUG, "EC: Turn off LED on ECO disable\n"); - // TODO - break; - case 0xde: - printk(BIOS_DEBUG, "LAN power off\n"); - reg32 = inl(DEFAULT_GPIOBASE + GP_LVL); - reg32 |= (1 << 24); // Disable LAN Power - outl(reg32, DEFAULT_GPIOBASE + GP_LVL); - break; - case 0xdf: - printk(BIOS_DEBUG, "RF enable\n"); - // TODO - break; - case 0xe0: - printk(BIOS_DEBUG, "Get RTC wake flag\n"); - // TODO - break; - case 0xe1: - printk(BIOS_DEBUG, "Hotkey function\n"); - // TODO - break; - case 0xe3: - printk(BIOS_DEBUG, "ECO disable\n"); - // TODO - break; default: return 0; }
- /* gnvs->smif: - * On success, the IO Trap Handler returns 0 - * On failure, the IO Trap Handler returns a value != 0 + /* On success, the IO Trap Handler returns 0 + * On failure, the IO Trap Handler returns a value != 0 + * + * For now, we force the return value to 0 and log all traps to + * see what's going on. */ - gnvs->smif = 0; + //gnvs->smif = 0; return 1; }
-static void mainboard_smi_hotkey(u8 hotkey) -{ - u8 reg8; - - switch (hotkey) { - case 0x3b: break; // Fn+F1 - case 0x3c: break; // Fn+F2 - case 0x3d: break; // Fn+F3 - case 0x3e: break; // Fn+F4 - case 0x3f: break; // Fn+F5 - case 0x40: // Fn+F6 (Decrease Display Brightness) - reg8 = ec_read(0x17); - reg8 = (reg8 > 8) ? (reg8 - 8) : 0; - ec_write(0x17, reg8); - return; - case 0x41: // Fn+F7 (Increase Display Brightness) - reg8 = ec_read(0x17); - reg8 += 8; - reg8 = (reg8 >= MAX_LCD_BRIGHTNESS) ? MAX_LCD_BRIGHTNESS : reg8; - ec_write(0x17, reg8); - return; - case 0x42: break; // Fn+F8 - case 0x43: break; // Fn+F9 - case 0x44: break; // Fn+F10 - case 0x57: break; // Fn+F11 - case 0x58: break; // Fn+F12 - } - printk(BIOS_DEBUG, "EC hotkey: %02x\n", hotkey); -} - -void mainboard_smi_gpi(u16 gpi_sts) -{ - u8 source, hotkey; - send_ec_oem_command(0x5c); - source = recv_ec_oem_data(); - - switch (source) { - case 0: - // Some kind of ACK? - break; - case 1: - send_ec_oem_command(0x59); - hotkey = recv_ec_oem_data(); - mainboard_smi_hotkey(hotkey); - break; - default: - printk(BIOS_DEBUG, "EC SMI source: %02x\n", source); - } -} - Index: src/mainboard/lenovo/x60/acpi_tables.c =================================================================== --- src/mainboard/lenovo/x60/acpi_tables.c (revision 0) +++ src/mainboard/lenovo/x60/acpi_tables.c (working copy) @@ -1,8 +1,8 @@ /* * This file is part of the coreboot project. - * - * Copyright (C) 2007-2010 coresystems GmbH * + * 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 @@ -19,11 +19,11 @@ * MA 02110-1301 USA */
-#include <types.h> #include <string.h> #include <console/console.h> -#include <arch/acpi.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> @@ -31,25 +31,82 @@ #include <device/pci_ids.h> #include "dmi.h"
-extern unsigned char AmlCode[]; +extern const unsigned char AmlCode[]; +#if CONFIG_HAVE_ACPI_SLIC +unsigned long acpi_create_slic(unsigned long current); +#endif
-#include "southbridge/intel/i82801gx/nvs.h" +#define OLD_ACPI 0 +#if OLD_ACPI +static void acpi_create_gnvs(global_nvs_t *gnvs) +{ + memset (gnvs, 0, sizeof(global_nvs_t));
+ gnvs->LIDS = 1; + gnvs->PWRS = 1; + + gnvs->ACTT = 0x37; + gnvs->PSVT = 0x4f; + + gnvs->TC1V = 0x00; + gnvs->TC2V = 0x0a; + gnvs->TSPV = 0x02; + + gnvs->CRTT = 0x77; + + gnvs->B0SC = 0x54; + gnvs->APIC = 0x01; + gnvs->MPEN = 0x01; + + gnvs->PPCM = 0x02; + gnvs->PCP0 = 0xbf; + gnvs->PCP1 = 0xbf; + + gnvs->CMAP = 0x01; + gnvs->CMBP = 0x01; + gnvs->LT0 = 0x01; + gnvs->FDCP = 0x01; + gnvs->CMCP = 0x01; + gnvs->CMDP = 0x01; + gnvs->P2M = 0x02; + + gnvs->IGDS = 0x01; + + gnvs->CADL = 0x09; + gnvs->PADL = 0x09; + + gnvs->NDID = 3; + gnvs->DID1 = 0x80000100; + gnvs->DID2 = 0x80000240; + gnvs->DID3 = 0x80000410; + gnvs->DID4 = 0x80000410; + gnvs->DID5 = 0x00000005; + + gnvs->ALAF = 0x64; + gnvs->LLOW = 0x2c; + gnvs->LHIH = 0x01; + + // tolud = pci_read_config32(dev_find_slot(0, PCI_DEVFN(2, 0)), 0x5c); + // oemb->topm = tolud; +} +#endif + +#include "southbridge/intel/i82801gx/nvs.h" static void acpi_create_gnvs(global_nvs_t *gnvs) { memset((void *)gnvs, 0, sizeof(*gnvs)); gnvs->apic = 1; gnvs->mpen = 1; /* Enable Multi Processing */
- /* Enable COM port(s) */ + /* Enable both COM ports */ gnvs->cmap = 0x01; - gnvs->cmbp = 0x00; + gnvs->cmbp = 0x01;
- /* IGD Displays */ - gnvs->ndid = 2; + /* IGD Displays */ + gnvs->ndid = 3; gnvs->did[0] = 0x80000100; - gnvs->did[1] = 0x80000410; - gnvs->did[2] = 0x80000320; + gnvs->did[1] = 0x80000240; + gnvs->did[2] = 0x80000410; gnvs->did[3] = 0x80000410; gnvs->did[4] = 0x00000005; } @@ -65,7 +122,7 @@ /* fill out header fields */ memcpy(header->signature, "HPET", 4); memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); + memcpy(header->oem_table_id, "COREBOOT", 8); memcpy(header->asl_compiler_id, ASLC, 4);
header->length = sizeof(acpi_hpet_t); @@ -86,52 +143,6 @@ acpi_checksum((void *) hpet, sizeof(acpi_hpet_t)); }
-static long acpi_create_ecdt(acpi_ecdt_t * ecdt) -{ - /* Attention: Make sure these match the values from - * the DSDT's ec.asl - */ - static const char ec_id[] = "\_SB.PCI0.LPCB.EC0"; - int ecdt_len = sizeof(acpi_ecdt_t) + strlen(ec_id) + 1; - - acpi_header_t *header = &(ecdt->header); - - memset((void *) ecdt, 0, ecdt_len); - - /* fill out header fields */ - memcpy(header->signature, "ECDT", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = ecdt_len; - header->revision = 1; - - /* Location of the two EC registers */ - ecdt->ec_control.space_id = ACPI_ADDRESS_SPACE_IO; - ecdt->ec_control.bit_width = 8; - ecdt->ec_control.bit_offset = 0; - ecdt->ec_control.addrl = 0x66; - ecdt->ec_control.addrh = 0; - - ecdt->ec_data.space_id = ACPI_ADDRESS_SPACE_IO; /* Memory */ - ecdt->ec_data.bit_width = 8; - ecdt->ec_data.bit_offset = 0; - ecdt->ec_data.addrl = 0x62; - ecdt->ec_data.addrh = 0; - - ecdt->uid = 1; // Must match _UID of the EC0 node. - - ecdt->gpe_bit = 23; // SCI interrupt within GPEx_STS - - strncpy((char *)ecdt->ec_id, ec_id, strlen(ec_id)); - - header->checksum = - acpi_checksum((void *) ecdt, ecdt_len); - - return header->length; -} - unsigned long acpi_fill_madt(unsigned long current) { /* Local APICs */ @@ -141,17 +152,21 @@ current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 2, IO_APIC_ADDR, 0);
+ /* 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); + /* INT_SRC_OVR */ current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) - current, 0, 0, 2, 0); + current, 0, 0, 2, MP_IRQ_POLARITY_HIGH | MP_IRQ_TRIGGER_EDGE); current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) - current, 0, 9, 9, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_HIGH); + 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, 0x0005, 0x01); - current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *) - current, 1, 0x0005, 0x01);
return current; } @@ -194,10 +209,8 @@ #endif acpi_header_t *ssdt; acpi_header_t *dsdt; - acpi_header_t *ecdt; + void *gnvs;
- void *gnvs, *smi1; - current = start;
/* Align ACPI tables to 16byte */ @@ -261,13 +274,14 @@ current += dsdt->length; memcpy(dsdt, &AmlCode, dsdt->length);
- /* Fix up global NVS region for SMI handler. The GNVS region lives + /* 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 + * 0x00000020 - 0x0000019c Low MP Table (XXX conflict?) * 0x00000400 - 0x000004ff BDA (somewhat unused) - * 0x00000500 - 0x00000518 coreboot table forwarder - * 0x00000600 - 0x00000??? realmode trampoline + * 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 @@ -301,22 +315,8 @@ current += 0x100; ALIGN_CURRENT;
- for (i=0; i < dsdt->length; i++) { - if (*(u32*)(((u32)dsdt) + i) == 0xC0DEDEAD) { - printk(BIOS_DEBUG, "ACPI: Patching up SMI1 area in DSDT at offset 0x%04x -> 0x%08x\n", i, (u32)current); - *(u32*)(((u32)dsdt) + i) = current; // 0x100 bytes - break; - } - } - - /* Keep pointer around */ - smi1 = (void *)current; - - current += 0x100; - ALIGN_CURRENT; - /* And tell SMI about it */ - smm_setup_structures(gnvs, NULL, smi1); + smm_setup_structures(gnvs, NULL, NULL);
/* We patched up the DSDT, so we need to recalculate the checksum */ dsdt->checksum = 0; @@ -325,12 +325,6 @@ printk(BIOS_DEBUG, "ACPI: * DSDT @ %p Length %x\n", dsdt, dsdt->length);
- printk(BIOS_DEBUG, "ACPI: * ECDT\n"); - ecdt = (acpi_header_t *)current; - current += acpi_create_ecdt((acpi_ecdt_t *)current); - ALIGN_CURRENT; - acpi_add_table(rsdp, ecdt); - #if CONFIG_HAVE_ACPI_SLIC printk(BIOS_DEBUG, "ACPI: * SLIC\n"); slic = (acpi_header_t *)current; @@ -349,7 +343,7 @@
printk(BIOS_DEBUG, "ACPI: * SSDT\n"); ssdt = (acpi_header_t *)current; - acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR); + acpi_create_ssdt_generator(ssdt, "COREBOOT"); current += ssdt->length; acpi_add_table(rsdp, ssdt); ALIGN_CURRENT; @@ -365,5 +359,6 @@ #endif
printk(BIOS_INFO, "ACPI: done.\n"); + return current; } Index: src/mainboard/lenovo/x60/chip.h =================================================================== --- src/mainboard/lenovo/x60/chip.h (revision 0) +++ src/mainboard/lenovo/x60/chip.h (working copy) @@ -1,13 +1,12 @@ /* * 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. + * Copyright (c) 2011 Sven Schnelle svens@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 @@ -15,8 +14,7 @@ * * 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 + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
extern struct chip_operations mainboard_ops; Index: src/mainboard/lenovo/x60/acpi/i945_pci_irqs.asl =================================================================== --- src/mainboard/lenovo/x60/acpi/i945_pci_irqs.asl (revision 0) +++ src/mainboard/lenovo/x60/acpi/i945_pci_irqs.asl (working copy) @@ -1,7 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2011 Sven Schnelle svens@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 @@ -19,7 +19,7 @@ * MA 02110-1301 USA */
-/* This is board specific information: IRQ routing for the +/* This is board specific information: IRQ routing for the * i945 */
@@ -29,59 +29,37 @@ { If (PICM) { Return (Package() { - // PCIe Graphics 0:1.0 - Package() { 0x0001ffff, 0, 0, 16 }, - // Onboard graphics (IGD) 0:2.0 - Package() { 0x0002ffff, 0, 0, 16 }, - // Network - Package() { 0x0007ffff, 0, 0, 16 }, - // High Definition Audio 0:1b.0 - Package() { 0x001bffff, 0, 0, 22 }, - // PCIe Root Ports 0:1c.x - Package() { 0x001cffff, 0, 0, 17 }, - Package() { 0x001cffff, 1, 0, 16 }, - Package() { 0x001cffff, 2, 0, 18 }, - Package() { 0x001cffff, 3, 0, 19 }, - // USB and EHCI 0:1d.x - Package() { 0x001dffff, 0, 0, 23 }, - Package() { 0x001dffff, 1, 0, 19 }, - Package() { 0x001dffff, 2, 0, 18 }, - Package() { 0x001dffff, 3, 0, 16 }, - // AC97 0:1e.2, 0:1e.3 - Package() { 0x001effff, 0, 0, 22 }, - Package() { 0x001effff, 1, 0, 20 }, - // LPC device 0:1f.0 - Package() { 0x001fffff, 0, 0, 18 }, - Package() { 0x001fffff, 1, 0, 19 }, - Package() { 0x001fffff, 3, 0, 16 } + Package() { 0x0001ffff, 0, 0, 0x10 }, + Package() { 0x0002ffff, 0, 0, 0x10 }, + Package() { 0x001bffff, 1, 0, 0x11 }, + Package() { 0x001cffff, 0, 0, 0x14 }, + Package() { 0x001cffff, 1, 0, 0x15 }, + Package() { 0x001cffff, 2, 0, 0x16 }, + Package() { 0x001cffff, 3, 0, 0x17 }, + Package() { 0x001dffff, 0, 0, 0x10 }, + Package() { 0x001dffff, 1, 0, 0x11 }, + Package() { 0x001dffff, 2, 0, 0x12 }, + Package() { 0x001dffff, 3, 0, 0x13 }, + Package() { 0x001fffff, 0, 0, 0x17 }, + Package() { 0x001fffff, 1, 0, 0x10 }, + Package() { 0x001fffff, 2, 0, 0x10 } }) } Else { Return (Package() { - // PCIe Graphics 0:1.0 Package() { 0x0001ffff, 0, _SB.PCI0.LPCB.LNKA, 0 }, - // Onboard graphics (IGD) 0:2.0 Package() { 0x0002ffff, 0, _SB.PCI0.LPCB.LNKA, 0 }, - // Network 0:7.0 - Package() { 0x0007ffff, 0, _SB.PCI0.LPCB.LNKA, 0 }, - // High Definition Audio 0:1b.0 - Package() { 0x001bffff, 0, _SB.PCI0.LPCB.LNKG, 0 }, - // PCIe Root Ports 0:1c.x - Package() { 0x001cffff, 0, _SB.PCI0.LPCB.LNKB, 0 }, - Package() { 0x001cffff, 1, _SB.PCI0.LPCB.LNKA, 0 }, - Package() { 0x001cffff, 2, _SB.PCI0.LPCB.LNKC, 0 }, - Package() { 0x001cffff, 3, _SB.PCI0.LPCB.LNKD, 0 }, - // USB and EHCI 0:1d.x - Package() { 0x001dffff, 0, _SB.PCI0.LPCB.LNKH, 0 }, - Package() { 0x001dffff, 1, _SB.PCI0.LPCB.LNKD, 0 }, + Package() { 0x001bffff, 1, _SB.PCI0.LPCB.LNKB, 0 }, + Package() { 0x001cffff, 0, _SB.PCI0.LPCB.LNKE, 0 }, + Package() { 0x001cffff, 1, _SB.PCI0.LPCB.LNKF, 0 }, + Package() { 0x001cffff, 2, _SB.PCI0.LPCB.LNKG, 0 }, + Package() { 0x001cffff, 3, _SB.PCI0.LPCB.LNKH, 0 }, + Package() { 0x001dffff, 0, _SB.PCI0.LPCB.LNKA, 0 }, + Package() { 0x001dffff, 1, _SB.PCI0.LPCB.LNKB, 0 }, Package() { 0x001dffff, 2, _SB.PCI0.LPCB.LNKC, 0 }, - Package() { 0x001dffff, 3, _SB.PCI0.LPCB.LNKA, 0 }, - // AC97 0:1e.2, 0:1e.3 - Package() { 0x001effff, 0, _SB.PCI0.LPCB.LNKG, 0 }, - Package() { 0x001effff, 1, _SB.PCI0.LPCB.LNKE, 0 }, - // LPC device 0:1f.0 - Package() { 0x001fffff, 0, _SB.PCI0.LPCB.LNKC, 0 }, - Package() { 0x001fffff, 1, _SB.PCI0.LPCB.LNKD, 0 }, - Package() { 0x001fffff, 3, _SB.PCI0.LPCB.LNKA, 0 } + Package() { 0x001dffff, 3, _SB.PCI0.LPCB.LNKD, 0 }, + Package() { 0x001fffff, 0, _SB.PCI0.LPCB.LNKH, 0 }, + Package() { 0x001fffff, 1, _SB.PCI0.LPCB.LNKA, 0 }, + Package() { 0x001fffff, 2, _SB.PCI0.LPCB.LNKA, 0 } }) } } Index: src/mainboard/lenovo/x60/acpi/ich7_pci_irqs.asl =================================================================== --- src/mainboard/lenovo/x60/acpi/ich7_pci_irqs.asl (revision 0) +++ src/mainboard/lenovo/x60/acpi/ich7_pci_irqs.asl (working copy) @@ -19,23 +19,23 @@ * MA 02110-1301 USA */
-/* This is board specific information: IRQ routing for the +/* This is board specific information: IRQ routing for the * 0:1e.0 PCI bridge of the ICH7 */
-If (PICM) { - Return (Package() { - Package() { 0x0005ffff, 0, 0, 16}, - Package() { 0x0005ffff, 1, 0, 17}, - Package() { 0x0005ffff, 2, 0, 18}, - Package() { 0x0005ffff, 4, 0, 19} // ?? 4 ?? - }) -} Else { - Return (Package() { - Package() { 0x0005ffff, 0, _SB.PCI0.LPCB.LNKA, 0}, - Package() { 0x0005ffff, 1, _SB.PCI0.LPCB.LNKB, 0}, - Package() { 0x0005ffff, 2, _SB.PCI0.LPCB.LNKC, 0}, - Package() { 0x0005ffff, 4, _SB.PCI0.LPCB.LNKD, 0}, // Really 4?? - }) -} +// If (PICM) { +// Return (Package() { +// Package() { 0x0005ffff, 0, 0, 16}, +// Package() { 0x0005ffff, 1, 0, 17}, +// Package() { 0x0005ffff, 2, 0, 18}, +// Package() { 0x0005ffff, 4, 0, 19} // ?? 4 ?? +// }) +// } Else { +// Return (Package() { +// Package() { 0x0005ffff, 0, _SB.PCI0.LPCB.LNKA, 0}, +// Package() { 0x0005ffff, 1, _SB.PCI0.LPCB.LNKB, 0}, +// Package() { 0x0005ffff, 2, _SB.PCI0.LPCB.LNKC, 0}, +// Package() { 0x0005ffff, 4, _SB.PCI0.LPCB.LNKD, 0}, // Really 4?? +// }) +// }
Index: src/mainboard/lenovo/x60/acpi/platform.asl =================================================================== --- src/mainboard/lenovo/x60/acpi/platform.asl (revision 0) +++ src/mainboard/lenovo/x60/acpi/platform.asl (working copy) @@ -75,7 +75,7 @@ TRAP(0xed) Sleep(1000)
- Store(0, _SB.ACFG) + //Store(0, _SB.ACFG)
// Are we going to S3? If (LEqual(Arg0, 3)) { @@ -140,7 +140,7 @@
// Are we coming from S4? If (LEqual(Arg0, 4)) { - Notify(SLPB, 0x02) + //Notify(SLPB, 0x02) If (DTSE) { TRAP(0x47) } @@ -201,8 +201,8 @@ }
// Notify the Batteries - Notify(_SB.BAT0, 0x80) // Execute BAT0 _BST - Notify(_SB.BAT1, 0x80) // Execute BAT1 _BST +// Notify(_SB.BAT0, 0x80) // Execute BAT0 _BST +// Notify(_SB.BAT1, 0x80) // Execute BAT1 _BST }
// Hardcoded for now.. Index: src/mainboard/lenovo/x60/acpi/superio.asl =================================================================== --- src/mainboard/lenovo/x60/acpi/superio.asl (revision 0) +++ src/mainboard/lenovo/x60/acpi/superio.asl (working copy) @@ -1,677 +0,0 @@ -/* - * 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 - */ - -/* SMSC SIO10N268 */ - -Device (SIO1) -{ - Name (_HID, EISAID("PNP0A05")) - Name (_UID, 1) - - OperationRegion(SIOR, SystemIO, 0x4e, 0x02) - Field (SIOR, ByteAcc, Nolock, Preserve) - { - INDX, 8, - DATA, 8 - } - - Mutex (SIOM, 0x00) - - Method (READ, 3) - { - Acquire (SIOM, 0xffff) - If (LEqual(Arg0, 0)) { - Store (0x55, INDX) - Store (Arg1, INDX) - Store (DATA, Local1) - Store (0xaa, INDX) - } - And (Local1, Arg2, Local1) - Release(SIOM) - Return(Local1) - } - - Method (WRIT, 3) - { - Acquire (SIOM, 0xffff) - If (LEqual(Arg0, 0)) { - Store (0x55, INDX) - Store (Arg1, INDX) - Store (Arg2, DATA) - Store (0xaa, INDX) - } - Release(SIOM) - } - - Device (UAR1) - { - Name(_HID, EISAID("PNP0501")) - Name(_UID, 1) - Name(_DDN, "COM1") - Name(_PRW, Package() { 0x08, 0x03 }) - - /* Device Status */ - Method (_STA, 0) - { - Acquire (SIOM, 0xffff) - - // Is the hardware enabled? - Store (READ(0, 0x24, 0xff), Local0) - If (LEqual(Local0, 0)) { - Return (0xd) - } Else { - // Power Enabled? - Store (READ(0, 0x02, 0x08), Local0) - If (LEqual(Local0, 0)) { - Return (0x0d) - } Else { - Return (0x0f) - } - } - } - - /* Device Disable */ - Method (_DIS, 0) - { - WRIT(0, 0x24, 0x00) - - Store(READ(0, 0x28, 0x0f), Local0) - WRIT(0, 0x28, Local0) - - Store(READ(0, 0x02, 0xff), Local0) - Not(0x08, Local1) - And(Local0, Local1, Local0) - WRIT(0, 0x02, Local0) - } - - /* Possible Resource Settings */ - Name(_PRS, ResourceTemplate() { - StartDependentFn(0, 1) { - IO(Decode16, 0x3f8, 0x3f8, 0x8, 0x8) - IRQNoFlags() { 4 } - } EndDependentFn() - }) - - /* Current Resource Settings */ - Method(_CRS, 0) - { - Name(NONE, ResourceTemplate() { - IO(Decode16, 0x000, 0x000, 0x0, 0x1) - IRQNoFlags() { } - }) - - Name(RSRC, ResourceTemplate() { - IO(Decode16, 0x3f8, 0x3f8, 0x8, 0x8, _IOA) - IRQNoFlags(_IRA) { 4 } - }) - - And (_STA(), 0x02, Local0) - If (LEqual(Local0, 0)) { - Return(NONE) - } - - CreateByteField(RSRC, - _SB.PCI0.LPCB.SIO1.UAR1._CRS._IOA._MIN, IOLO) - CreateByteField(RSRC, 0x03, IOHI) // Why? - CreateByteField(RSRC, - _SB.PCI0.LPCB.SIO1.UAR1._CRS._IOA._MAX, IORL) - CreateByteField(RSRC, 0x05, IORH) // Why? - CreateByteField(RSRC, - _SB.PCI0.LPCB.SIO1.UAR1._CRS._IRA._INT, IRQL) - - Store (READ(0, 0x24, 0xff), Local0) - And (Local0, 0xc0, Local1) - ShiftRight(Local1, 0x06, Local1) - ShiftLeft(Local0, 0x02, Local0) - Store(Local0, IOLO) - Store(Local1, IOHI) - Store(IOLO, IORL) - Store(IOHI, IORH) - - /* Interrupt */ - Store(READ(0, 0x28, 0xf0), Local0) - ShiftRight(Local0, 4, Local0) - ShiftLeft(1, Local0, IRQL) - Return(RSRC) - } - - /* Set Resource Settings */ - Method(_SRS, 1) - { - CreateByteField(Arg0, 0x02, IOLO) - CreateByteField(Arg0, 0x03, IOHI) - CreateByteField(Arg0, 0x09, IRQL) - - WRIT(0, 0x24, 0) - FindSetRightBit(IRQL, Local0) - Decrement(Local0) - ShiftLeft(Local0, 4, Local0) - - Store(READ(0, 0x28, 0x0f), Local1) - Or(Local0, Local1, Local0) - WRIT(0, 0x28, Local0) - - Store(IOLO, Local0) - ShiftRight(Local0, 2, Local0) - And(Local0, 0xfe, Local0) - - Store(IOHI, Local1) - ShiftLeft(Local1, 6, Local1) - Or (Local0, Local1, Local0) - WRIT(0, 0x24, Local0) - - Store(READ(0, 0x02, 0xff), Local0) - Or(Local0, 0x08, Local0) - WRIT(0, 0x02, Local0) - - Store(READ(0, 0x07, 0xff), Local0) - Not(0x40, Local1) - And (Local0, Local1, Local0) - WRIT(0, 0x07, Local0) - } - - - /* D0 state - Line drivers are on */ - Method (_PS0, 0) - { - Store(READ(0, 0x02, 0xff), Local0) - Or(Local0, 0x08, Local0) - WRIT(0, 0x02, Local0) - - Store (READ(0, 0x07, 0xff), Local0) - Not(0x40, Local1) - And(Local0, Local1, Local0) - WRIT(0, 0x07, Local0) - } - - /* D3 State - Line drivers are off */ - Method(_PS3, 0) - { - Store(READ(0, 0x02, 0xff), Local0) - Not(0x08, Local1) - And(Local0, Local1, Local0) - WRIT(0, 0x02, Local0) - } - } - - Device (UAR2) - { - Name(_HID, EISAID("PNP0501")) - Name(_UID, 2) - Name(_DDN, "COM2") - Name(_PRW, Package() { 0x08, 0x03 }) - - /* Device Status */ - Method (_STA, 0) - { - /* IRDA? */ - Store(READ(0, 0x0c, 0x38), Local0) - If (LNotEqual(Local0, Zero)) { - Return (0) - } - - // Is the hardware enabled? - Store (READ(0, 0x25, 0xff), Local0) - If (LEqual(Local0, 0)) { - Return (0xd) - } Else { - // Power Enabled? - Store (READ(0, 0x02, 0x80), Local0) - If (LEqual(Local0, 0)) { - Return (0x0d) - } Else { - Return (0x0f) - } - } - } - - /* Device Disable */ - Method (_DIS, 0) - { - WRIT(0, 0x25, 0x00) - - Store(READ(0, 0x28, 0xf0), Local0) - WRIT(0, 0x28, Local0) - - Store(READ(0, 0x02, 0xff), Local0) - Not(0x80, Local1) - And(Local0, Local1, Local0) - WRIT(0, 0x02, Local0) - } - - /* Possible Resource Settings */ - Name(_PRS, ResourceTemplate() { - StartDependentFn(0, 1) { - IO(Decode16, 0x2f8, 0x2f8, 0x8, 0x8) - IRQNoFlags() { 3 } - } EndDependentFn() - }) - - /* Current Resource Settings */ - Method(_CRS, 0) - { - Name(NONE, ResourceTemplate() { - IO(Decode16, 0x000, 0x000, 0x0, 0x1) - IRQNoFlags() { } - }) - - Name(RSRC, ResourceTemplate() { - IO(Decode16, 0x2f8, 0x2f8, 0x8, 0x8, _IOB) - IRQNoFlags(_IRB) { 3 } - }) - - And (_STA(), 0x02, Local0) - If (LEqual(Local0, 0)) { - Return(NONE) - } - - CreateByteField(RSRC, - _SB.PCI0.LPCB.SIO1.UAR2._CRS._IOB._MIN, IOLO) - CreateByteField(RSRC, 0x03, IOHI) - CreateByteField(RSRC, - _SB.PCI0.LPCB.SIO1.UAR2._CRS._IOB._MAX, IORL) - CreateByteField(RSRC, 0x05, IORH) - CreateByteField(RSRC, - _SB.PCI0.LPCB.SIO1.UAR2._CRS._IRB._INT, IRQL) - - Store (READ(0, 0x25, 0xff), Local0) - And (Local0, 0xc0, Local1) - ShiftRight(Local1, 0x06, Local1) - ShiftLeft(Local0, 0x02, Local0) - Store(Local0, IOLO) - Store(Local1, IOHI) - Store(IOLO, IORL) - Store(IOHI, IORH) - - /* Interrupt */ - Store(READ(0, 0x28, 0x0f), Local0) - ShiftRight(Local0, 4, Local0) - ShiftLeft(1, Local0, IRQL) - Return(RSRC) - } - - /* Set Resource Settings */ - Method(_SRS, 1) - { - CreateByteField(Arg0, 0x02, IOLO) - CreateByteField(Arg0, 0x03, IOHI) - CreateByteField(Arg0, 0x09, IRQL) - - WRIT(0, 0x25, 0) - FindSetRightBit(IRQL, Local0) - Decrement(Local0) - - Store(READ(0, 0x28, 0xf0), Local1) - Or(Local0, Local1, Local0) - WRIT(0, 0x28, Local0) - - Store(IOLO, Local0) - ShiftRight(Local0, 2, Local0) - And(Local0, 0xfe, Local0) - - Store(IOHI, Local1) - ShiftLeft(Local1, 6, Local1) - Or (Local0, Local1, Local0) - WRIT(0, 0x25, Local0) - - Store(READ(0, 0x0c, 0xff), Local0) - Not(0x38, Local1) - And(Local0, Local1, Local0) - WRIT(0, 0x0c, Local0) - - Store(READ(0, 0x02, 0xff), Local0) - Or(Local0, 0x80, Local0) - WRIT(0, 0x02, Local0) - - Store(READ(0, 0x07, 0xff), Local0) - Not(0x20, Local1) - And (Local0, Local1, Local0) - WRIT(0, 0x07, Local0) - } - - /* D0 state - Line drivers are on */ - Method (_PS0, 0) - { - Store(READ(0, 0x02, 0xff), Local0) - Or(Local0, 0x80, Local0) - WRIT(0, 0x02, Local0) - - Store (READ(0, 0x07, 0xff), Local0) - Not(0x20, Local1) - And(Local0, Local1, Local0) - WRIT(0, 0x07, Local0) - } - - /* D3 State - Line drivers are off */ - Method(_PS3, 0) - { - Store(READ(0, 0x02, 0xff), Local0) - Not(0x80, Local1) - And(Local0, Local1, Local0) - WRIT(0, 0x02, Local0) - } - } - - Device (UAR3) - { - Name(_HID, EISAID("PNP0501")) - Name(_UID, 3) - Name(_DDN, "COM3") - Name(_PRW, Package() { 0x08, 0x03 }) - - /* Device Status */ - Method (_STA, 0) - { - Acquire (SIOM, 0xffff) - - // Is the hardware enabled? - Store (READ(0, 0x1b, 0xff), Local0) - If (LEqual(Local0, 0)) { - Return (0xd) - } Else { - // Power Enabled? - Store (READ(0, 0x02, 0x02), Local0) - If (LEqual(Local0, 0)) { - Return (0x0d) - } Else { - Return (0x0f) - } - } - } - - /* Device Disable */ - Method (_DIS, 0) - { - WRIT(0, 0x1b, 0x00) - - Store(READ(0, 0x1d, 0x0f), Local0) - WRIT(0, 0x1d, Local0) - - Store(READ(0, 0x02, 0xff), Local0) - Not(0x02, Local1) - And(Local0, Local1, Local0) - WRIT(0, 0x02, Local0) - } - - /* Possible Resource Settings */ - Name(_PRS, ResourceTemplate() { - StartDependentFn(0, 1) { - IO(Decode16, 0x3e8, 0x3e8, 0x8, 0x8) - IRQNoFlags() { 5 } - } EndDependentFn() - }) - - /* Current Resource Settings */ - Method(_CRS, 0) - { - Name(NONE, ResourceTemplate() { - IO(Decode16, 0x000, 0x000, 0x0, 0x1) - IRQNoFlags() { } - }) - - Name(RSRC, ResourceTemplate() { - IO(Decode16, 0x3e8, 0x3e8, 0x8, 0x8, _IOA) - IRQNoFlags(_IRA) { 5 } - }) - - And (_STA(), 0x02, Local0) - If (LEqual(Local0, 0)) { - Return(NONE) - } - - CreateByteField(RSRC, - _SB.PCI0.LPCB.SIO1.UAR3._CRS._IOA._MIN, IOLO) - CreateByteField(RSRC, 0x03, IOHI) // Why? - CreateByteField(RSRC, - _SB.PCI0.LPCB.SIO1.UAR3._CRS._IOA._MAX, IORL) - CreateByteField(RSRC, 0x05, IORH) // Why? - CreateByteField(RSRC, - _SB.PCI0.LPCB.SIO1.UAR3._CRS._IRA._INT, IRQL) - - Store (READ(0, 0x1b, 0xff), Local0) - And (Local0, 0xc0, Local1) - ShiftRight(Local1, 0x06, Local1) - ShiftLeft(Local0, 0x02, Local0) - Store(Local0, IOLO) - Store(Local1, IOHI) - Store(IOLO, IORL) - Store(IOHI, IORH) - - /* Interrupt */ - Store(READ(0, 0x1d, 0xf0), Local0) - ShiftRight(Local0, 4, Local0) - ShiftLeft(1, Local0, IRQL) - Return(RSRC) - } - - /* Set Resource Settings */ - Method(_SRS, 1) - { - CreateByteField(Arg0, 0x02, IOLO) - CreateByteField(Arg0, 0x03, IOHI) - CreateByteField(Arg0, 0x09, IRQL) - - WRIT(0, 0x1b, 0) - FindSetRightBit(IRQL, Local0) - Decrement(Local0) - ShiftLeft(Local0, 4, Local0) - - Store(READ(0, 0x1d, 0x0f), Local1) - Or(Local0, Local1, Local0) - WRIT(0, 0x1d, Local0) - - Store(IOLO, Local0) - ShiftRight(Local0, 2, Local0) - And(Local0, 0xfe, Local0) - - Store(IOHI, Local1) - ShiftLeft(Local1, 6, Local1) - Or (Local0, Local1, Local0) - WRIT(0, 0x1b, Local0) - - Store(READ(0, 0x02, 0xff), Local0) - Or(Local0, 0x02, Local0) - WRIT(0, 0x02, Local0) - - Store(READ(0, 0x07, 0xff), Local0) - Not(0x04, Local1) - And (Local0, Local1, Local0) - WRIT(0, 0x07, Local0) - } - - - /* D0 state - Line drivers are on */ - Method (_PS0, 0) - { - Store(READ(0, 0x02, 0xff), Local0) - Or(Local0, 0x02, Local0) - WRIT(0, 0x02, Local0) - - Store (READ(0, 0x07, 0xff), Local0) - Not(0x04, Local1) - And(Local0, Local1, Local0) - WRIT(0, 0x07, Local0) - } - - /* D3 State - Line drivers are off */ - Method(_PS3, 0) - { - Store(READ(0, 0x02, 0xff), Local0) - Not(0x02, Local1) - And(Local0, Local1, Local0) - WRIT(0, 0x02, Local0) - } - } - - - Device (UAR4) - { - Name(_HID, EISAID("PNP0501")) - Name(_UID, 4) - Name(_DDN, "COM4") - Name(_PRW, Package() { 0x08, 0x03 }) - - /* Device Status */ - Method (_STA, 0) - { - Acquire (SIOM, 0xffff) - - // Is the hardware enabled? - Store (READ(0, 0x1c, 0xff), Local0) - If (LEqual(Local0, 0)) { - Return (0xd) - } Else { - // Power Enabled? - Store (READ(0, 0x02, 0x04), Local0) - If (LEqual(Local0, 0)) { - Return (0x0d) - } Else { - Return (0x0f) - } - } - } - - /* Device Disable */ - Method (_DIS, 0) - { - WRIT(0, 0x1c, 0x00) - - Store(READ(0, 0x1d, 0x0f), Local0) - WRIT(0, 0x1d, Local0) - - Store(READ(0, 0x02, 0xff), Local0) - Not(0x04, Local1) - And(Local0, Local1, Local0) - WRIT(0, 0x02, Local0) - } - - /* Possible Resource Settings */ - Name(_PRS, ResourceTemplate() { - StartDependentFn(0, 1) { - IO(Decode16, 0x2e8, 0x2e8, 0x8, 0x8) - IRQNoFlags() { 11 } - } EndDependentFn() - }) - - /* Current Resource Settings */ - Method(_CRS, 0) - { - Name(NONE, ResourceTemplate() { - IO(Decode16, 0x000, 0x000, 0x0, 0x1) - IRQNoFlags() { } - }) - - Name(RSRC, ResourceTemplate() { - IO(Decode16, 0x2e8, 0x2e8, 0x8, 0x8, _IOA) - IRQNoFlags(_IRA) { 11 } - }) - - And (_STA(), 0x02, Local0) - If (LEqual(Local0, 0)) { - Return(NONE) - } - - CreateByteField(RSRC, - _SB.PCI0.LPCB.SIO1.UAR4._CRS._IOA._MIN, IOLO) - CreateByteField(RSRC, 0x03, IOHI) // Why? - CreateByteField(RSRC, - _SB.PCI0.LPCB.SIO1.UAR4._CRS._IOA._MAX, IORL) - CreateByteField(RSRC, 0x05, IORH) // Why? - CreateByteField(RSRC, - _SB.PCI0.LPCB.SIO1.UAR4._CRS._IRA._INT, IRQL) - - Store (READ(0, 0x1c, 0xff), Local0) - And (Local0, 0xc0, Local1) - ShiftRight(Local1, 0x06, Local1) - ShiftLeft(Local0, 0x02, Local0) - Store(Local0, IOLO) - Store(Local1, IOHI) - Store(IOLO, IORL) - Store(IOHI, IORH) - - /* Interrupt */ - Store(READ(0, 0x1d, 0xf0), Local0) - ShiftRight(Local0, 4, Local0) - ShiftLeft(1, Local0, IRQL) - Return(RSRC) - } - - /* Set Resource Settings */ - Method(_SRS, 1) - { - CreateByteField(Arg0, 0x02, IOLO) - CreateByteField(Arg0, 0x03, IOHI) - CreateByteField(Arg0, 0x09, IRQL) - - WRIT(0, 0x1c, 0) - FindSetRightBit(IRQL, Local0) - Decrement(Local0) - ShiftLeft(Local0, 4, Local0) - - Store(READ(0, 0x1d, 0x0f), Local1) - Or(Local0, Local1, Local0) - WRIT(0, 0x1d, Local0) - - Store(IOLO, Local0) - ShiftRight(Local0, 2, Local0) - And(Local0, 0xfe, Local0) - - Store(IOHI, Local1) - ShiftLeft(Local1, 6, Local1) - Or (Local0, Local1, Local0) - WRIT(0, 0x1c, Local0) - - Store(READ(0, 0x02, 0xff), Local0) - Or(Local0, 0x04, Local0) - WRIT(0, 0x02, Local0) - - Store(READ(0, 0x07, 0xff), Local0) - Not(0x08, Local1) - And (Local0, Local1, Local0) - WRIT(0, 0x07, Local0) - } - - - /* D0 state - Line drivers are on */ - Method (_PS0, 0) - { - Store(READ(0, 0x02, 0xff), Local0) - Or(Local0, 0x04, Local0) - WRIT(0, 0x02, Local0) - - Store (READ(0, 0x07, 0xff), Local0) - Not(0x08, Local1) - And(Local0, Local1, Local0) - WRIT(0, 0x07, Local0) - } - - /* D3 State - Line drivers are off */ - Method(_PS3, 0) - { - Store(READ(0, 0x02, 0xff), Local0) - Not(0x04, Local1) - And(Local0, Local1, Local0) - WRIT(0, 0x02, Local0) - } - } - -} - Index: src/mainboard/lenovo/x60/acpi/video.asl =================================================================== --- src/mainboard/lenovo/x60/acpi/video.asl (revision 0) +++ src/mainboard/lenovo/x60/acpi/video.asl (working copy) @@ -1,45 +0,0 @@ -/* - * 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 - */ - -// Brightness write -Method (BRTW, 1, Serialized) -{ - // TODO -} - -// Hot Key Display Switch -Method (HKDS, 1, Serialized) -{ - // TODO -} - -// Lid Switch Display Switch -Method (LSDS, 1, Serialized) -{ - // TODO -} - -// Brightness Notification -Method(BRTN,1,Serialized) -{ - // TODO (no displays defined yet) -} - Index: src/mainboard/lenovo/x60/acpi/ec.asl =================================================================== --- src/mainboard/lenovo/x60/acpi/ec.asl (revision 0) +++ src/mainboard/lenovo/x60/acpi/ec.asl (working copy) @@ -1,7 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (c) 2011 Sven Schnelle svens@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 @@ -19,657 +19,259 @@ * MA 02110-1301 USA */
-Device(EC0) +OperationRegion (POST, SystemIO, 0x80, 1) +Field (POST, ByteAcc, Lock, Preserve) { + DBG0, 8 +} + + +Device(EC) +{ Name (_HID, EISAID("PNP0C09")) - Name (_UID, 1) + Name (_UID, 0)
- Name (_GPE, 23) // GPI07 / GPE23 -> Runtime SCI + Name (_GPE, 28) + Mutex (ECLK, 0)
- OperationRegion(ERAM, EmbeddedControl, 0x00, 0x37) + OperationRegion(ERAM, EmbeddedControl, 0x00, 0x100) Field (ERAM, ByteAcc, NoLock, Preserve) { - MODE, 1, // Thermal Policy (Quiet/Perform) - FAN, 1, // Fan Power (On/Off) - LIDS, 1, // LID Status (0=Open/1=Close) - LSW0, 1, // LCD Power Switch + Offset (0x05), + HSPA, 1, + Offset (0x0C), + LEDS, 8, /* LED state */ + Offset (0x38), + B0ST, 4, /* Battery 0 state */ + , 1, + B0CH, 1, /* Battery 0 charging */ + B0DI, 1, /* Battery 0 discharging */ + , 1, + B1ST, 4, /* Battery 1 state */ + , 1, + B1CH, 1, /* Battery 1 charging, + B1DI, 1, /* Battery 1 discharging, + Offset (0x3B), + , 1, + KBLT, 1, /* Keyboard Light */ + Offset (0x46), + , 1, + , 1, + , 1, + , 1, + HPAC, 1, + Offset (0x81), + PAGE, 8 /* Information Page Selector */ + }
- BTYP, 1, // Battery Type (0=LiIon/1=NiMh) - MWKE, 1, // Enable Wakeup from RI - ADP, 1, // AC Adapter (0=Offline/1=Online) - BAT, 1, // Battery (0=Not Present/1=Present) - SLPT, 3, // Set Sleep Type on SLP enter (1=S1...4=S4) - CHRG, 1, // 0=Battery not charging/1=Battery charging - RI_W, 1, // Wake-up event source is RI - KB_W, 1, // Wake-up event source is keyboard - BATW, 1, // Wake-up event source is Battery Low - PMEW, 1, // Wake-up event source is PME - - // Battery 0 Registers - // Battery Life = BRC0/BPR0 - // Battery percentage = BRC0/BFC0 * 100 - BDC0, 16, // Designed Capacity - BFC0, 16, // Last Full Charge Capacity - BDV0, 16, // Design Voltage - BPR0, 16, // Battery Present Rate - BRC0, 16, // Battery Remaining Capacity - BPV0, 16, // Battery Present Voltage - - Offset(0x11), - CTMP, 8, // CPU Temperature - Offset(0x15), - CTRO, 8, // EC throttling on trip point - CRTT, 8, // Critical Shut-down Temperature - Offset(0x17), - BKLL, 8, // Backlight Level - - // Battery 2 Registers - Offset(0x20), - , 4, - BTY2, 1, // Battery Type (0=LiIon/1=NiMh) - , 2, - BAT2, 1, // Battery (0=Not Present/1=Present) - , 3, - CRG2, 1, // 0=Battery not charging/1=Battery charging - Offset(0x22), - BDC2, 16, // Designed Capacity - BFC2, 16, // Last Full Charge Capacity - BDV2, 16, // Design Voltage - BPR2, 16, // Battery Present Rate - BRC2, 16, // Battery Remaining Capacity - BPV2, 16, // Battery Present Voltage - BTP2, 16, // Trip Point - - PBMO, 2, // PBMO power control method - ECO, 1, // ECO on/off status - SUN, 1, // Sunlight Readable - RF, 1, // RF Enable/Disable status - DOCK, 1, // Dock In/Out status - CBAT, 1, // Car Battery status - APPS, 1, // OSD utility status - Offset(0x33), - ODDS, 1 - } - - Method (_CRS, 0) + /* PAGE == 0x00 */ + Field (ERAM, ByteAcc, NoLock, Preserve) { - Name (ECMD, ResourceTemplate() - { - IO (Decode16, 0x62, 0x62, 1, 1) - IO (Decode16, 0x66, 0x66, 1, 1) - }) - - Return (ECMD) + Offset(0xa0), + BARC, 16, /* Battery remaining capacity */ + BAFC, 16, /* Battery full charge capacity */ + Offset(0xa8), + BAPR, 16, /* Battery present rate */ + BAVO, 16, /* Battery Voltage */ }
- // EC Query methods, called upon SCI interrupts. - Method (_Q01, 0) + /* PAGE == 0x01 */ + Field (ERAM, ByteAcc, NoLock, Preserve) { - Notify (_PR.CPU0, 0x80) - If(ADP) { - Store(1, _SB.AC.ACST) - TRAP(0xe3) - Store(1, PWRS) - TRAP(0x2b) - } Else { - Store(0, _SB.AC.ACST) - Notify(_SB.AC, 0x80) - Notify(_SB.BAT0, 0x80) - Store(0, PWRS) - TRAP(0x2b) - } - - PNOT() + Offset(0xa0), + , 15, + BAMA, 1, }
- Method (_Q02, 0) + /* PAGE == 0x02 */ + Field (ERAM, ByteAcc, NoLock, Preserve) { - If(BAT) { - Notify(_SB.BAT0, 0x00) - Notify(_SB.AC, 0x80) - } Else { - Notify(_SB.AC, 0x80) - Notify(_SB.BAT0, 0x01) - } - - PNOT() + Offset(0xa0), + BADC, 16, /* Design Capacity */ + BADV, 16, /* Design voltage */ + , 16, + , 16, + , 16, + BASN, 16, }
- Method (_Q05, 0) + /* PAGE == 0x04: Battery type */ + Field (ERAM, ByteAcc, NoLock, Preserve) { - Notify(SLPB, 0x80) - PNOT() + Offset(0xa0), + BATY, 32 }
- Method (_Q07, 0) - { - TRAP(0xe0)
- If (LEqual(RTCF, 0x00)) { - Notify(LID0, 0x80) - } else { - TRAP(0xc1) - } - } - - Method (_Q09, 0) + /* PAGE == 0x05: Battery OEM information */ + Field (ERAM, ByteAcc, NoLock, Preserve) { - Notify(BAT0, 0x80) - Notify(BAT1, 0x80) + Offset(0xa0), + BAOE, 128 }
- Method (_Q0A, 0) + /* PAGE == 0x06: Battery name */ + Field (ERAM, ByteAcc, NoLock, Preserve) { - Notify(_TZ.THRM, 0x80) + Offset(0xa0), + BANA, 128 } - - Method (_Q20, 0) - { - Notify(_SB.ECO, 0x81) - }
- Method (_Q21, 0) + Method (_CRS, 0) { - Notify(_SB.ECO, 0x82) + Name (ECMD, ResourceTemplate() + { + IO (Decode16, 0x62, 0x62, 1, 1) + IO (Decode16, 0x66, 0x66, 1, 1) + }) + Return (ECMD) }
- Method (_Q22, 0) + Method (LED, 1, NotSerialized) { - Notify(_SB.ECO, 0x83) + Store(Arg0, LEDS) }
- Method (_Q23, 0) + Method (_INI, 0, NotSerialized) { - Notify(_SB.ECO, 0x84) + Store(0x00, HSPA) // Enable ACPI Interrupts + LED(0xc1) }
- Method (_Q24, 0) + Device(AC) { - Store(0x3f, HOTK) - If(IGDS) { - HKDS(10) - } Else { - TRAP(0xE1) - } - Notify (_SB.ECO, 0x85) - } + Name(_HID, "ACPI0003") + Name(_UID, 0x00) + Name(_PCL, Package(0x01) { _SB } )
- Method (_Q25, 0) - { - Store(0x40, HOTK) - TRAP(0xe1) - Notify(_SB.ECO, 0x86) - } - - Method (_Q26, 0) - { - Store(0x41, HOTK) - TRAP(0xe1) - Notify(_SB.ECO, 0x87) - } - - Method (_Q27, 0) - { - Notify(_SB.ECO, 0x88) - } - - Method (_Q28, 0) - { - Notify(_SB.ECO, 0x89) - } - - Method (_Q29, 0) - { - Notify(_SB.ECO, 0x8a) - } - - Method (_Q2A, 0) - { - Store(0x57, HOTK) - TRAP(0xe1) - Notify(_SB.ECO, 0x8b) - } - - Method (_Q2B, 0) - { - Notify(SLPB, 0x80) - Notify(_SB.ECO, 0x8c) - } - - Method (_Q2C, 0) - { - Store(0x59, HOTK) - TRAP(0xe1) - } - - Method (_Q38, 0) - { - // IDE TODO - } - - Method (_Q39, 0) - { - // SATA TODO - } - - Method (_Q3A, 0) - { - Store(1, BRTL) - Notify(_SB.ECO, 0x93) - } - - Method (_Q3B, 0) - { - Store(0, BRTL) - Notify(_SB.ECO, 0x93) - } - - Method (_Q3C, 0) - { - Store(1, SUN) - Notify(_SB.ECO, 0x92) - } - - Method (_Q3D, 0) - { - Store(0, SUN) - Notify(_SB.ECO, 0x92) - } - - /* Enable RF device */ - Method (_Q3E, 0) - { - TRAP(0xdf) - } - - /* Disable RF device */ - Method (_Q3F, 0) - { - TRAP(0xc0) - } - - /* ACBS LAN Power On */ - Method (_Q40, 0) - { - TRAP(0xd0) - Sleep(500) - Notify(RP04, 0) - } - - /* ACBS LAN Power Off */ - Method (_Q41, 0) - { - TRAP(0xd1) - } - - Method (_Q42, 0) - { - TRAP(0xf3) - } - - Method (_Q43, 0) - { - TRAP(0xf4) - } - - Method (_Q48, 0) - { - TRAP(0xd2) // Check AC Status - Store (1, ODDS) - Notify(_SB.ECO, 0x90) - } - - Method (_Q49, 0) - { - TRAP(0xd2) // Check AC Status - Store (0, ODDS) - Notify(_SB.ECO, 0x90) - } - - - Method (_Q4C, 0) - { - Notify(_SB.ECO, 0x94) - } - - Method (_Q4D, 0) - { - Notify(_SB.ECO, 0x95) - } - - Method (_Q4E, 0) - { - // PATA TODO - } - - Method (_Q4F, 0) - { - TRAP(0xf9) - Notify(_SB.ECO, 0x95) - } - - Method (_Q5C, 0) - { - // Store(2, IGPS) - Notify(_SB.ECO, 0x94) - } - - Method (_Q70, 0) - { - Notify(_SB.ECO, 0x96) - } - - Method (_Q71, 0) - { - Notify(_SB.ECO, 0x97) - } - - // TODO Scope _SB devices for AC power, LID, Power button -} - -Scope(_SB) -{ - /* This device is used by the GETAC P470 Windows drivers. */ - - Device (ECO) - { - Name(_HID, "MTC0303") // MTC0303 BIOS Service Provider - Method (GDPD, 0, Serialized) + Method(_PSR, 0, NotSerialized) { - // Set flag byte to zero - Store (0, Local0) - - If (And(BRTL, 0x01)) { - Or(Local0, 0x01, Local0) - } - - If (And(BRTL, 0x02)) { - Or(Local0, 0x04, Local0) - } - - If (And(BRTL, 0x04)) { - Or(Local0, 0x02, Local0) - } - - If (And(BRTL, 0x30)) { - Or(Local0, 0x10, Local0) - } - - If (And(BRTL, 0x40)) { - Or(Local0, 0x40, Local0) - } - - Return (Local0) + return (HPAC) }
- Method (GDPC, 0, Serialized) + Method(_STA, 0, NotSerialized) { - Store (0, Local0) - - If (And(BRTL, 0x10)) { - Or(Local0, 0x04, Local0) - } - - If (And( BRTL, 0x20)) { - Or(Local0, 0x01, Local0) - } - - If (And(BRTL, 0x40)) { - Or(Local0, 0x02, Local0) - } - - Return (Local0) + Return (0x0f) } + }
- /* Set Brightness Level */ - Method(SBLL, 1, Serialized) - { - Store (Arg0, BRTL) - TRAP(0xd5) // See mainboard_smi.c - Return (0) - } + Device (BAT0) + { + Name (_HID, EisaId ("PNP0C0A")) + Name (_UID, 0x00) + Name (_PCL, Package () { _SB })
- /* Get Brightness Level */ - Method(GBLL, 0, Serialized) - { - TRAP(0xd6) // See mainboard_smi.c - Return (BRTL) - } + 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 + })
- /* Get Brightness Level Medium? */ - Method(GBLM, 0, Serialized) + Method (_BIF, 0, NotSerialized) { - Store(0x3f, BRTL) - // XXX don't we have to set the brightness? - Return(BRTL) - } + Acquire(ECLK, 0xffff) + Store(0x01, PAGE) /* Battery 0 static information */ + Xor(BAMA, 1, Index(BATS, 0)) + Store(BAMA, Local0) + Store(0, PAGE) + Store(BAFC, Local2) + Store(2, PAGE) + Store(BADC, Local1)
- /* ??? */ - Method(SUTE, 1, Serialized) - { - If (And(Arg0, 0x01)) { - TRAP(0xf5) - } Else { - TRAP(0xf6) + if (Local0) + { + Multiply (Local1, 10, Local1) + Multiply (Local2, 10, Local2) } - Return (0) - }
- /* ??? */ - Method(GECO, 0, Serialized) - { - TRAP(0xd7) - Return (ODDS) - } + Store(Local1, Index(BATS, 1)) // Design Capacity + Store(Local2, Index(BATS, 2)) // Last full charge capacity + Store(BADV, Index(BATS, 4)) // Design Voltage + Divide (Local2, 20, Local0, Index(BATS, 5)) // Warning capacity
- /* ??? */ - Method(GBSL, 0, Serialized) - { - TRAP(0xd8) - Return (BRTL) - } - - /* ??? Get LED/Device Enable Status */ - Method(GRFD, 0, Serialized) - { - /* Let coreboot update the flags */ - TRAP(0xe5) - - Store (0, Local0) - If(And(RFDV, 0x01)) { - Or(Local0, 0x01, Local0) + 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) } - If(And(RFDV, 0x02)) { - Or(Local0, 0x02, Local0) - } - If(And(RFDV, 0x02)) { - Or(Local0, 0x02, Local0) - } - If(And(RFDV, 0x04)) { - Or(Local0, 0x04, Local0) - } - If(And(RFDV, 0x08)) { - Or(Local0, 0x08, Local0) - } - If(And(GP16, 0x01)) { // GDIS - Or(Local0, 0x10, Local0) - } - If(And(GP13, 0x01)) { // WIFI Led (WLED) - Or(Local0, 0x20, Local0) - } - If(And(BTEN, 0x01)) { // BlueTooth Enable - Or(Local0, 0x40, Local0) - } - If(And(GP11, 0x01)) { // GPS Enable - Or(Local0, 0x80, Local0) - } + Store (SERN, Index (BATS, 10)) // Serial Number
- Return (Local0) + Store(4, PAGE) + Name (TYPE, Buffer() { 0, 0, 0, 0, 0 }) + Store(BATY, TYPE) + Store(TYPE, Index (BATS, 11)) // Battery type + Store(5, PAGE) + Store(BAOE, Index (BATS, 12)) // OEM information + Store(6, PAGE) + Store(BANA, Index (BATS, 9)) // Model number + Release(ECLK) + Return (BATS) }
- /* Set RFD */ - Method(SRFD, 1, Serialized) + Name (BATI, Package () { - If (And(Arg0, 0x01)) { - Store (1, GP15) // GLED - Store (1, GP16) // GDIS - } Else { - Store (0, GP15) - Store (0, GP16) - } + 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 + })
- /* WIFI */ - If (And(Arg0, 0x02)) { - Store (1, GP13) // WLED - Store (1, GP26) // WLAN - } Else { - Store (0, GP13) - Store (0, GP26) - } - - /* Bluetooth */ - If (And(Arg0, 0x04)) { - Store (1, GP14) // BLED - Store (1, BTEN) - } Else { - Store (0, GP14) // BLED - Store (0, BTEN) - } - Return (0) - } - - /* Get DKD */ - Method(GDKD, 0, Serialized) + Method (_BST, 0, NotSerialized) { - TRAP(0xd9) - Return (BRTL) - } + Store(0, Local0) + Store(1, PAGE) + Store(BAMA, Local1) + Store(0, PAGE) /* Battery 0 dynamic information */
- /* Set DKD */ - Method(SDKD, 1, Serialized) - { - TRAP(0xda) - Return (0) - } - - /* Set IGD (Graphics) */ - Method(SIGD, 1, Serialized) - { - If (And(Arg0, 0x01)) { - TRAP(0xf7) - } Else { - TRAP(0xf8) + /* set charge/discharge bits */ + if (B0CH) + { + Or(2, Local0, Local0) + Store(BAPR, Index(BATI, 0x01)) } - Return (0) - }
- /* SMI-C? Set Mic? */ - Method (SMIC, 1, Serialized) - { - If (And(Arg0, 0x01)) { - TRAP(0xeb) - } Else { - TRAP(0xec) + if (B0DI) + { + Or(1, Local0, Local0) + Store(BAPR, Local1) + Subtract(0x10000, Local1, Local1) + Store(Local1, Index(BATI, 0x01)) } - Return (0) - }
- /* ??? */ - Method(GTSD, 0, Serialized) - { - Return (GP20) // TSDT - } + Store(Local0, Index(BATI, 0x00))
- /* Not even decent function names anymore? */ - Method(S024, 1, Serialized) - { - If (And(Arg0, 0x01)) { - TRAP(0xf1) - } Else { - TRAP(0xf2) + if (Local1) { + Multiply (BARC, 10, Index(BATI, 2)) + } else { + Store(BARC, Index(BATI, 2)) } - Return (0) + Store(BAVO, Index(BATI, 3)) + Return (BATI) }
- /* Get CVD */ - Method(GCVD, 0, Serialized) + Method (_STA, 0, NotSerialized) { - TRAP(0xf9) - Return (BRTL) + Return (0x1f) } + }
- /* ??? Something with PATA */ - Method(S025, 1, Serialized) - { - If(And(Arg0, 0x01)) { - TRAP(0xfc) - - Store (1, GP33) // CREN - Sleep(1500) - - Store (1, GP34) // CRRS - Sleep(500) - - Notify(^^PCI0.PATA, 0) - Notify(^^PCI0.PATA.PRID, 0) - } Else { - TRAP(0xfb) - Sleep(1500) - Store(0, GP33) // CREN - Sleep(1500) - Notify(^^PCI0.PATA, 0) - Notify(^^PCI0.PATA.PRID, 0) - Notify(^^PCI0.PATA.PRID.DSK1, 1) - Notify(^^PCI0.PATA.PRID.DSK0, 1) - } - Return (0) - } - - /* ??? */ - Method(G021, 0, Serialized) - { - TRAP(0xfe) - If (LEqual(ACIN, 0)) { - TRAP(0xfa) - TRAP(0xfd) - If (LEqual(ODDS, 1)) { - TRAP(0xfb) - Notify(^^PCI0.PATA, 0) - Notify(^^PCI0.PATA.PRID.DSK1, 1) - Notify(^^PCI0.PATA.PRID.DSK0, 1) - Sleep (1500) - Store (0, GP33) // CREN - Sleep (1500) - Notify(^^PCI0.PATA, 0) - Notify(^^PCI0.PATA.PRID.DSK1, 1) - Notify(^^PCI0.PATA.PRID.DSK0, 1) - Return (0) - } - } - /* All Else Cases */ - Notify(ECO, 0xb1) - Return (1) - } - - /* Get RFS */ - Method(GRFS, 0, Serialized) - { - TRAP(0xff) - Return(BRTL) - } - - /* ??? */ - Method(S00B, 1, Serialized) - { - If (And(Arg0, 1)) { - TRAP(0xdc) - } Else { - TRAP(0xdd) - } - Return (0) - } - - - - } } + Index: src/mainboard/lenovo/x60/acpi/gpe.asl =================================================================== --- src/mainboard/lenovo/x60/acpi/gpe.asl (revision 0) +++ src/mainboard/lenovo/x60/acpi/gpe.asl (working copy) @@ -1,104 +0,0 @@ -/* - * 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 - */ - -Scope (_GPE) -{ - /* The event numbers correspond to the bit numbers in the - * GPE0_EN register PMBASE + 0x2C. - */ - - // Hot Plug - Method (_L01, 0) - { - // TODO - } - - // Software GPE - Method (_L02, 0) - { - Store (0, GPEC) - } - - // USB1 - Method (_L03, 0) - { - Notify (_SB.PCI0.USB1, 2) - } - - // USB2 - Method (_L04, 0) - { - Notify (_SB.PCI0.USB2, 2) - } - - // AC97 - Method (_L05, 0) - { - Notify (_SB.PCI0.MODM, 2) - Notify (_SB.PCI0.HDEF, 2) - } - - // _L06 TCOSCI - - // SMBus (Reserved!) - Method (_L07, 0) - { - Store (0x20, _SB.PCI0.SBUS.HSTS) - } - - // COM1/COM2 (RI) - Method (_L08, 0) - { - // Don't care - } - - // PCIe - Method (_L09, 0) - { - // TODO - } - - // _L0A BatLow / Quick Resume - - // PME - Method (_L0B, 0) - { - Notify (_SB.PCI0.PCIB.LANR, 0x02) - } - - // USB3 - Method (_L0C, 0) - { - Notify(_SB.PCI0.USB3, 2) - } - - // PME B0 - Method (_L0D, 0) - { - Notify(_SB.PCI0.EHC1, 2) - } - - // USB4 - Method (_L0E, 0) - { - Notify(_SB.PCI0.USB4, 2) - } -} Index: src/mainboard/lenovo/x60/acpi/mainboard.asl =================================================================== --- src/mainboard/lenovo/x60/acpi/mainboard.asl (revision 0) +++ src/mainboard/lenovo/x60/acpi/mainboard.asl (working copy) @@ -1,48 +0,0 @@ -/* - * 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 - */ - -Device (LID0) -{ - Name(_HID, EisaId("PNP0C0D")) - Method(_LID, 0) - { - If(_SB.PCI0.LPCB.EC0.LIDS) { - Return (0) - } Else { - Return (1) - } - } -} - -Device (SLPB) -{ - Name(_HID, EisaId("PNP0C0E")) -} - -Device (PWRB) -{ - Name(_HID, EisaId("PNP0C0C")) - - // Wake - Name(_PRW, Package(){0x1d, 0x04}) -} - -#include "acpi/battery.asl" Index: src/mainboard/lenovo/x60/acpi/thermal.asl =================================================================== --- src/mainboard/lenovo/x60/acpi/thermal.asl (revision 0) +++ src/mainboard/lenovo/x60/acpi/thermal.asl (working copy) @@ -1,106 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007-2010 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 - */ - -// Thermal Zone - -Scope (_TZ) -{ - ThermalZone (THRM) - { - // TODO These could/should be read from the - // GNVS area, so they can be controlled by - // coreboot - Name(TC1V, 0x00) - Name(TC2V, 0x0a) - Name(TSPV, 0x32) - - - // Convert from °C to 1/10 Kelvin - Method(DEGR, 1, NotSerialized) - { - Store(Arg0, Local0) - // 10ths of degrees - Multiply(Local0, 10, Local0) - // 0°C is 273.15 K, we need to round it. - Add(Local0, 2732, Local0) - Return(Local0) - } - - // At which temperature should the OS start - // active cooling? - Method (_AC0, 0, Serialized) - { - Return (0xf5c) // Value for Rocky - } - - // Critical shutdown temperature - Method (_CRT, 0, Serialized) - { - Store(_SB.PCI0.LPCB.EC0.CRTT, Local0) - Store(DEGR(Local0), Local0) - Return(Local0) - } - - // CPU throttling start temperature - Method (_PSV, 0, Serialized) - { - Store(_SB.PCI0.LPCB.EC0.CTRO, Local0) - Store(DEGR(Local0), Local0) - Return(Local0) - } - - // Get DTS Temperature - Method (_TMP, 0, Serialized) - { - Store(_SB.PCI0.LPCB.EC0.CTMP, Local0) - Store(DEGR(Local0), Local0) - Return(Local0) - } - - // Processors used for active cooling - Method (_PSL, 0, Serialized) - { - If (MPEN) { - Return (Package() {_PR.CPU0, _PR.CPU1}) - } - Return (Package() {_PR.CPU0}) - } - - // TC1 value for passive cooling - Method (_TC1, 0, Serialized) - { - Return (TC1V) - } - - // TC2 value for passive cooling - Method (_TC2, 0, Serialized) - { - Return (TC2V) - } - - // Sampling period for passive cooling - Method (_TSP, 0, Serialized) - { - Return (TSPV) - } - } -} - Index: src/mainboard/lenovo/x60/dsdt.asl =================================================================== --- src/mainboard/lenovo/x60/dsdt.asl (revision 0) +++ src/mainboard/lenovo/x60/dsdt.asl (working copy) @@ -25,7 +25,7 @@ DefinitionBlock( "dsdt.aml", "DSDT", - 0x02, // DSDT revision: ACPI v2.0 + 0x03, // DSDT revision: ACPI v2.0 "COREv4", // OEM id "COREBOOT", // OEM table id 0x20090419 // OEM revision @@ -42,7 +42,7 @@
// mainboard specific devices #include "acpi/mainboard.asl" - + // Thermal Zone #include "acpi/thermal.asl"
Index: src/mainboard/lenovo/x60/mainboard.c =================================================================== --- src/mainboard/lenovo/x60/mainboard.c (revision 0) +++ src/mainboard/lenovo/x60/mainboard.c (working copy) @@ -1,7 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (c) 2011 Sven Schnelle svens@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 @@ -21,85 +21,94 @@
#include <console/console.h> #include <device/device.h> -#include <device/pci_def.h> #include <arch/io.h> #include <boot/tables.h> #include <delay.h> +//#ifdef CONFIG_PCI_OPTION_ROM_RUN_YABEL +//#include <x86emu/x86emu.h> +//#endif +#include <arch/coreboot_tables.h> #include "chip.h" -#include "hda_verb.h" +#include <device/pci_def.h> +#include <device/pci_ops.h> +#include <arch/io.h>
#include "ec.c"
-#define MAX_LCD_BRIGHTNESS 0xd8 - -static void ec_enable(void) +static void pmh7_register_set_bit(int reg, int bit) { - u16 keymap; - /* Enable Hotkey SCI */ + char val;
- /* Fn key map; F1 = [0] ... F12 = [11] */ - keymap = 0x5f1; - send_ec_oem_command(0x45); - send_ec_oem_data(0x09); // SCI - // send_ec_oem_data(0x08); // SMI# - send_ec_oem_data(keymap >> 8); - send_ec_oem_data(keymap & 0xff); + outb(reg, 0x15ec); + val = inb(0x15ee); + outb(reg, 0x15ec); + outb(val | (1 << bit), 0x15ee); +}
- /* Enable Backlight */ - ec_write(0x17, MAX_LCD_BRIGHTNESS); - - /* Notify EC system is in ACPI mode */ - send_ec_oem_command(0x5e); - send_ec_oem_data(0xea); - send_ec_oem_data(0x0c); - send_ec_oem_data(0x01); +static void backlight_enable(void) +{ + pmh7_register_set_bit(0x50, 5); }
-static void pcie_limit_power(void) +#if CONFIG_PCI_OPTION_ROM_RUN_YABEL +static int int15_handler(void) { -#if 0 - // This piece of code needs further debugging as it crashes the - // machine. It should set the slot numbers and enable power - // limitation for the PCIe slots. + u8 display_id;
- device_t dev; - - dev = dev_find_slot(0, PCI_DEVFN(28,0)); - if (dev) pci_write_config32(dev, 0x54, 0x0010a0e0); + printk(BIOS_DEBUG, "%s: AX=%04x BX=%04x CX=%04x DX=%04x\n", + __func__, M.x86.R_AX, M.x86.R_BX, M.x86.R_CX, M.x86.R_DX);
- dev = dev_find_slot(0, PCI_DEVFN(28,1)); - if (dev) pci_write_config32(dev, 0x54, 0x0018a0e0); + switch (M.x86.R_AX) { + default: + /* Interrupt was not handled */ + return 0; + }
- dev = dev_find_slot(0, PCI_DEVFN(28,2)); - if (dev) pci_write_config32(dev, 0x54, 0x0020a0e0); - - dev = dev_find_slot(0, PCI_DEVFN(28,3)); - if (dev) pci_write_config32(dev, 0x54, 0x0028a0e0); -#endif + /* Interrupt handled */ + return 1; }
-static void verb_setup(void) +static void int15_install(void) { - cim_verb_data = mainboard_cim_verb_data; - cim_verb_data_size = sizeof(mainboard_cim_verb_data); + typedef int (* yabel_handleIntFunc)(void); + extern yabel_handleIntFunc yabel_intFuncArray[256]; + yabel_intFuncArray[0x15] = int15_handler; } +#endif
-static void mainboard_init(device_t dev) +static void trackpoint_enable(void) { - ec_enable(); + ec_write(0x0b, 0x03); }
-// mainboard_enable is executed as first thing after -// enumerate_buses(). Is there no mainboard_init()? -static void mainboard_enable(device_t dev) +static void mainboard_enable(device_t dev) { - dev->ops->init = mainboard_init; - pcie_limit_power(); - verb_setup(); + backlight_enable(); + trackpoint_enable(); + + /* enable ACPI events */ + ec_write(0x00, 0xa6); + ec_write(0x01, 0x05); + + ec_write(0x02, 0xa0); + ec_write(0x03, 0x05); + + /* Unknown, but required for hotkeys + Maybe a mask for enabled keys? */ + + ec_write(0x12, 0xff); + ec_write(0x13, 0xff); + ec_write(0x14, 0xf4); + ec_write(0x15, 0x3c); + +#if CONFIG_PCI_OPTION_ROM_RUN_YABEL + /* Install custom int15 handler for VGA OPROM */ + int15_install(); +#endif }
struct chip_operations mainboard_ops = { - CHIP_NAME("Getac P470 Rugged Notebook") + CHIP_NAME("Lenovo Thinkpad X60") .enable_dev = mainboard_enable, };