Here's an untested epia-m700 patch. VIA vx800 + C7.
Please review and feel free to clean it up.
-Bari
Index: src/mainboard/via/epia-m700/dsdt.c =================================================================== --- src/mainboard/via/epia-m700/dsdt.c (revision 0) +++ src/mainboard/via/epia-m700/dsdt.c (revision 0) @@ -0,0 +1,17 @@ +/* + * + * Intel ACPI Component Architecture + * ASL Optimizing Compiler version 20051117 [Nov 17 2005] + * Copyright (C) 2000 - 2005 Intel Corporation + * Supports ACPI Specification Revision 3.0 + * + * Compilation of "dsdt.asl" - Mon Mar 02 10:15:04 2009 + * + * C source code output + * + */ +unsigned char AmlCode_dsdt[] = +{ +0x44,0x53,0x44,0x54,0x0F,0x3C,0x00,0x00, +//remove for lincense issue +}; \ No newline at end of file Index: src/mainboard/via/epia-m700/wakeup.h =================================================================== --- src/mainboard/via/epia-m700/wakeup.h (revision 0) +++ src/mainboard/via/epia-m700/wakeup.h (revision 0) @@ -0,0 +1,31 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2009 One Laptop per Child, Association, Inc. + * + * 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 + */ +#ifndef WAKEUP_H +#define WAKEUP_H +#define WAKE_SPECIAL_AREA 0xE0000 +#define WAKE_SPECIAL_SIZE 0x1000 +#define WAKE_THUNK16_ADDR (WAKE_SPECIAL_AREA+0x200) +#define WAKE_THUNK16_GDT (WAKE_SPECIAL_AREA+0x300) +#define WAKE_THUNK16_XDTR (WAKE_SPECIAL_AREA+0x350) +#define WAKE_MEM_INFO (WAKE_SPECIAL_AREA+0x400) +#define WAKE_RECOVER1M_CODE (WAKE_SPECIAL_AREA+0x500) +#define WAKE_THUNK16_STACK (WAKE_SPECIAL_AREA+0xf00) +#endif/* WAKEUP_H */ + Index: src/mainboard/via/epia-m700/acpi_tables.c =================================================================== --- src/mainboard/via/epia-m700/acpi_tables.c (revision 0) +++ src/mainboard/via/epia-m700/acpi_tables.c (revision 0) @@ -0,0 +1,225 @@ +/* + * This file is part of the coreboot project. + * + * LinuxBIOS ACPI Table support + * written by Stefan Reinauer stepan@openbios.org + * ACPI FADT, FACS, and DSDT table support added by + * Nick Barker nick.barker9@btinternet.com, and those portions + * (C) Copyright 2004 Nick Barker + * (C) Copyright 2005 Stefan Reinauer + * (C) Copyright 2009 One Laptop per Child, Association, Inc. + * + * 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 + * + * most parts of this file copied from src\mainboard\asus\a8v-e_se\acpi_tables.c, + * acpi_is_wakeup() is from Rudolf's S3 patch and SSDT was added + */ + +#include <console/console.h> +#include <string.h> +#include <arch/acpi.h> +#include <device/device.h> +#include <device/pci_ids.h> +#include <../../../northbridge/via/vx800/vx800.h> + +extern unsigned char AmlCode_dsdt[]; +extern unsigned char AmlCode_ssdt[]; + +/* +These four macro copied from #include <arch/smp/mpspec.h>, I have to do this since "default HAVE_MP_TABLE = 0" in option.lb, +and also since mainboard/via/*.* have no Mptable.c(so that I can not set HAVE_MP_TABLE = 1) as many other mainboard. +So I have to copy these four to here. acpi_fill_madt() need this. +*/ +#define MP_IRQ_POLARITY_HIGH 0x1 +#define MP_IRQ_POLARITY_LOW 0x3 +#define MP_IRQ_TRIGGER_EDGE 0x4 +#define MP_IRQ_TRIGGER_LEVEL 0xc + + +unsigned long acpi_fill_mcfg(unsigned long current) +{ + /* NO MCFG in VX855, no pci-e*/ + return current; +} + +unsigned long acpi_create_madt_lapics(unsigned long current) +{ + device_t cpu; + int cpu_index = 0; + + for(cpu = all_devices; cpu; cpu = cpu->next) { + if ((cpu->path.type != DEVICE_PATH_APIC) || + (cpu->bus->dev->path.type != DEVICE_PATH_APIC_CLUSTER)) { + continue; + } + if (!cpu->enabled) { + continue; + } + current += acpi_create_madt_lapic((acpi_madt_lapic_t *)current, cpu_index, cpu->path.apic.apic_id); + cpu_index++; + } + return current; +} + +unsigned long acpi_create_madt_lapic_nmis(unsigned long current, u16 flags, u8 lint) +{ + device_t cpu; + int cpu_index = 0; + + for(cpu = all_devices; cpu; cpu = cpu->next) { + if ((cpu->path.type != DEVICE_PATH_APIC) || + (cpu->bus->dev->path.type != DEVICE_PATH_APIC_CLUSTER)) { + continue; + } + if (!cpu->enabled) { + continue; + } + current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *)current, cpu_index, flags, lint); + cpu_index++; + } + return current; +} + +unsigned long acpi_fill_madt(unsigned long current) +{ + unsigned int gsi_base = 0x18; + + /* Create all subtables for processors. */ + current = acpi_create_madt_lapics(current); + + /* Write SB IOAPIC. */ + current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, + VX800SB_APIC_ID, VX800SB_APIC_BASE, 0); + + /* IRQ0 -> APIC IRQ2. */ + current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) + current, 0, 0, 2, 0x0); + + /* IRQ9 ACPI active low. */ + current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) + current, 0, 9, 9, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_LOW); + + /* Create all subtables for processors. */ + current = acpi_create_madt_lapic_nmis(current, + MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, 1); + + return current; +} + +unsigned long acpi_fill_slit(unsigned long current) +{ + // Not implemented + return current; +} + +unsigned long acpi_fill_srat(unsigned long current) +{ + /* No NUMA, no SRAT */ +} + +#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) +#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) + +unsigned long write_acpi_tables(unsigned long start) +{ + unsigned long current; + acpi_rsdp_t *rsdp; + acpi_srat_t *srat; + acpi_rsdt_t *rsdt; + acpi_mcfg_t *mcfg; + acpi_hpet_t *hpet; + acpi_madt_t *madt; + acpi_fadt_t *fadt; + acpi_facs_t *facs; + acpi_header_t *dsdt; + acpi_header_t *ssdt; + + /* Align ACPI tables to 16byte */ + start = ( start + 0x0f ) & -0x10; + current = start; + + printk_info("ACPI: Writing ACPI tables at %lx...\n", start); + + /* We need at least an RSDP and an RSDT Table */ + rsdp = (acpi_rsdp_t *) current; + current += sizeof(acpi_rsdp_t); + rsdt = (acpi_rsdt_t *) current; + current += sizeof(acpi_rsdt_t); + + /* clear all table memory */ + memset((void *)start, 0, current - start); + + acpi_write_rsdp(rsdp, rsdt); + acpi_write_rsdt(rsdt); + + /* + * We explicitly add these tables later on: + */ + printk_debug("ACPI: * FACS\n"); + current = ALIGN(current, 64); + facs = (acpi_facs_t *) current; + current += sizeof(acpi_facs_t); + acpi_create_facs(facs); + + printk_debug("ACPI: * DSDT\n"); + dsdt = (acpi_header_t *) current; + current += ((acpi_header_t *)AmlCode_dsdt)->length; + memcpy((void *)dsdt,(void *)AmlCode_dsdt, ((acpi_header_t *)AmlCode_dsdt)->length); + dsdt->checksum = 0; /* don't trust intel iasl compiler to get this right. */ + dsdt->checksum = acpi_checksum(dsdt, dsdt->length); + printk_debug("ACPI: * DSDT @ %08x Length %x\n", dsdt, dsdt->length); + + printk_debug("ACPI: * FADT\n"); + fadt = (acpi_fadt_t *) current; + current += sizeof(acpi_fadt_t); + + acpi_create_fadt(fadt,facs,dsdt); + acpi_add_table(rsdt,fadt); + + /* If we want to use HPET timers Linux wants it in MADT. */ + printk_debug("ACPI: * MADT\n"); + madt = (acpi_madt_t *) current; + acpi_create_madt(madt); + current += madt->header.length; + acpi_add_table(rsdt, madt); + + /* NO MCFG in VX855, no pci-e*/ + + printk_debug("ACPI: * HPET\n"); + hpet = (acpi_mcfg_t *) current; + acpi_create_hpet(hpet); + current += hpet->header.length; + acpi_add_table(rsdt, hpet); +/* + printk_debug("ACPI: * SSDT\n"); + ssdt = (acpi_header_t *) current; + current += ((acpi_header_t *)AmlCode_ssdt)->length; + memcpy((void *)ssdt,(void *)AmlCode_ssdt, ((acpi_header_t *)AmlCode_ssdt)->length); + ssdt->checksum = 0; // don't trust intel iasl compiler to get this right + ssdt->checksum = acpi_checksum(ssdt, ssdt->length); + acpi_add_table(rsdt, ssdt); + printk_debug("ACPI: * SSDT @ %08x Length %x\n", ssdt, ssdt->length); +*/ + + printk_info("ACPI: done.\n"); + return current; +} + +extern u32 wake_vec; +extern u8 acpi_sleep_type; + +int acpi_is_wakeup(void) { + return (acpi_sleep_type == 3); +} + Index: src/mainboard/via/epia-m700/Options.lb =================================================================== --- src/mainboard/via/epia-m700/Options.lb (revision 0) +++ src/mainboard/via/epia-m700/Options.lb (revision 0) @@ -0,0 +1,158 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2009 One Laptop per Child, Association, Inc. +## +## 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 +## + +uses HAVE_MP_TABLE +uses CONFIG_CBFS +uses HAVE_PIRQ_TABLE +uses USE_FALLBACK_IMAGE +uses HAVE_FALLBACK_BOOT +uses HAVE_HARD_RESET +uses HAVE_OPTION_TABLE +uses USE_OPTION_TABLE +uses CONFIG_ROM_PAYLOAD +uses IRQ_SLOT_COUNT +uses MAINBOARD +uses MAINBOARD_VENDOR +uses MAINBOARD_PART_NUMBER +uses COREBOOT_EXTRA_VERSION +uses ARCH +uses FALLBACK_SIZE +uses STACK_SIZE +uses HEAP_SIZE +uses ROM_SIZE +uses ROM_SECTION_SIZE +uses ROM_IMAGE_SIZE +uses ROM_SECTION_SIZE +uses ROM_SECTION_OFFSET +uses CONFIG_ROM_PAYLOAD_START +uses CONFIG_COMPRESSED_PAYLOAD_NRV2B +uses CONFIG_COMPRESSED_PAYLOAD_LZMA +uses PAYLOAD_SIZE +uses _ROMBASE +uses _RAMBASE +uses XIP_ROM_SIZE +uses XIP_ROM_BASE +uses HAVE_MP_TABLE +uses HAVE_ACPI_TABLES +uses CROSS_COMPILE +uses CC +uses HOSTCC +uses OBJCOPY +uses DEFAULT_CONSOLE_LOGLEVEL +uses MAXIMUM_CONSOLE_LOGLEVEL +uses CONFIG_CONSOLE_SERIAL8250 +uses CONFIG_UDELAY_TSC +uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2 +uses CONFIG_PCI_ROM_RUN +uses CONFIG_CONSOLE_VGA +uses CONFIG_MAX_PCI_BUSES +uses TTYS0_BAUD +uses CONFIG_VIDEO_MB +uses CONFIG_IOAPIC + + + +## +## new options +## +uses USE_DCACHE_RAM +uses DCACHE_RAM_BASE +uses DCACHE_RAM_SIZE +uses CONFIG_USE_INIT +uses MAX_RAM_SLOTS +uses USB_ENABLE +uses EHCI_ENABLE +uses HPET_ENABLE +uses USB_PORTNUM +uses FULL_ROM_SIZE +uses FULL_ROM_BASE +uses PAYLOAD_IS_SEABIOS +uses VIACONFIG_TOP_SM_SIZE_MB +uses VIACONFIG_VGA_PCI_10 +uses VIACONFIG_VGA_PCI_14 + +## +## new options +## +default USE_DCACHE_RAM=1 +default DCACHE_RAM_BASE=0xffef0000 +#default DCACHE_RAM_BASE=0xffbf0000 +#default DCACHE_RAM_BASE=0xfec00000 //hpet may use this +default DCACHE_RAM_SIZE=0x2000 +default CONFIG_USE_INIT=0 +default MAX_RAM_SLOTS=2 +default USB_ENABLE=1 +default EHCI_ENABLE=1 +default HPET_ENABLE=1 +default USB_PORTNUM=2 +default FULL_ROM_SIZE = 512 * 1024 +default FULL_ROM_BASE = (0xffffffff - FULL_ROM_SIZE+ 1) +default VIACONFIG_TOP_SM_SIZE_MB=0 +#default VIACONFIG_VGA_PCI_10=0xd0000008 +#default VIACONFIG_VGA_PCI_14=0xfd000000 +default VIACONFIG_VGA_PCI_10=0xf8000008 +default VIACONFIG_VGA_PCI_14=0xfc000000 + + +default ROM_SIZE = 512 * 1024 +default CONFIG_IOAPIC = 1 + +#define framebuffer size of VX800's integrated graphics card. support 32 64 128 256 +default CONFIG_VIDEO_MB = 64 + +default CONFIG_CONSOLE_SERIAL8250 = 1 +default CONFIG_PCI_ROM_RUN = 0 +default CONFIG_CONSOLE_VGA = 0 +default HAVE_FALLBACK_BOOT = 1 +default HAVE_MP_TABLE = 0 +default CONFIG_UDELAY_TSC = 1 +default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2 = 1 +default HAVE_HARD_RESET = 0 +default HAVE_PIRQ_TABLE = 0 +default IRQ_SLOT_COUNT = 10 +default HAVE_ACPI_TABLES = 1 +default HAVE_OPTION_TABLE = 1 +default ROM_IMAGE_SIZE = 128 * 1024 +default FALLBACK_SIZE = ROM_SIZE +default USE_FALLBACK_IMAGE = 1 +default STACK_SIZE = 16 * 1024 +default HEAP_SIZE = 20 * 1024 +#default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE +default USE_OPTION_TABLE = 0 +default _RAMBASE = 0x00004000 +default CONFIG_ROM_PAYLOAD = 1 +default CROSS_COMPILE = "" +default CC = "$(CROSS_COMPILE)gcc -m32" +default HOSTCC = "gcc" + +## +## Set this to the max PCI bus number you would ever use for PCI config I/O. +## Setting this number very high will make pci_locate_device() take a long +## time when it can't find a device. +## +default CONFIG_MAX_PCI_BUSES = 3 +end + +# +# CBFS +# +# +default CONFIG_CBFS=0 +end Index: src/mainboard/via/epia-m700/DrivingClkPhaseData.c =================================================================== --- src/mainboard/via/epia-m700/DrivingClkPhaseData.c (revision 0) +++ src/mainboard/via/epia-m700/DrivingClkPhaseData.c (revision 0) @@ -0,0 +1,247 @@ + +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2009 One Laptop per Child, Association, Inc. + * + * 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 "northbridge/via/vx800/DrivingClkPhaseData.h" + +// DQS Driving +//Reg0xE0, 0xE1 +// According to #Bank to set DRAM DQS Driving +// #Bank 1 2 3 4 5 6 7 8 +static const u8 DDR2_DQSA_Driving_Table[4] = { 0xEE, 0xEE, 0xEE, 0xEE}; +static const u8 DDR2_DQSB_Driving_Table[2] = { 0xEE, 0xEE}; + +// DQ Driving +//Reg0xE2, 0xE3 +// For DDR2: According to bank to set DRAM DQ Driving +static const u8 DDR2_DQA_Driving_Table[4] = { 0xAC, 0xAC, 0xAC, 0xAC }; +static const u8 DDR2_DQB_Driving_Table[2] = { 0xCA, 0xCA }; + + +// CS Driving +//Reg0xE4, 0xE5 +// According to #Bank to set DRAM CS Driving +// DDR1 #Bank 1 2 3 4 5 6 7 8 +static const u8 DDR2_CSA_Driving_Table_x8[4] = { 0x44, 0x44, 0x44, 0x44 }; +static const u8 DDR2_CSB_Driving_Table_x8[2] = { 0x44, 0x44}; +static const u8 DDR2_CSA_Driving_Table_x16[4]= { 0x44, 0x44, 0x44, 0x44}; +static const u8 DDR2_CSB_Driving_Table_x16[2]= { 0x44, 0x44}; +// MAA Driving +//Reg0xE8, Reg0xE9 +static const u8 DDR2_MAA_Driving_Table[MA_Table][5] = + { + //Chip number, 400, 533, 667 800 ;(SRAS, SCAS, SWE)RxE8 + { 6, 0x86, 0x86, 0x86, 0x86}, // total MAA chips = 00 ~ 06 + { 18, 0x86, 0x86, 0x86, 0x86}, // total MAA chips = 06 ~ 18 + {255, 0xDB, 0xDB, 0xDB, 0xDB} // total MAA chips = 18 ~ + }; + +static const u8 DDR2_MAB_Driving_Table[MA_Table][2] = + { + // Chip number, Value ;(SRAS, SCAS, SWE)RxE9 + { 6, 0x86 }, // total MAB chips = 00 ~ 06 + { 18, 0x86 }, // total MAB chips = 06 ~ 18 + {255, 0xDB } // total MAB chips = 18 ~ + }; + +// DCLK Driving +//Reg0xE6, 0xE7 +// For DDR2: According to #Freq to set DRAM DCLK Driving +// freq 400M, 533M, 667M, 800M + +static const u8 DDR2_DCLKA_Driving_Table[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; +static const u8 DDR2_DCLKB_Driving_Table[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; + +/* +Duty cycle +Duty cycle Control for DQ/DQS/DDRCKG in ChA & ChB +D0F3RxEC/D0F3RxED/D0F3RxEE/D0F3RxEF +According to DRAM frequency to control Duty Cycle +*/ +static const u8 ChA_Duty_Control_DDR2[DUTY_CYCLE_REG_NUM][DUTY_CYCLE_FREQ_NUM] = + { + // (And NOT) DDR800 DDR667 DDR533 DDR400 + //Reg Mask Value Value Value Value + {0xEC, 0x00, 0x30, 0x30, 0x30, 0x30 }, // 1Rank + {0xEE, 0x0F, 0x40, 0x40, 0x00, 0x00 }, + {0xEF, 0xCF, 0x00, 0x30, 0x30, 0x30} + }; + +static const u8 ChB_Duty_Control_DDR2[DUTY_CYCLE_REG_NUM][DUTY_CYCLE_FREQ_NUM] = + { + // (And NOT) DDR800 DDR667 DDR533 DDR400 + //Reg Mask Value Value Value Value + {0xED, 0x00, 0x88, 0x88, 0x84, 0x88 }, // 1Rank + {0xEE, 0xF0, 0x00, 0x00, 0x00, 0x00 }, + {0xEF, 0xFC, 0x00, 0x00, 0x00, 0x00 } + }; + + +/* +DRAM Clock Phase Control for FeedBack Mode +Modify NB Reg: Rx90[7]/Rx91/Rx92/Rx93/Rx94 +Processing: + 1.Program VIA_NB3DRAM_REG90[7]=0b for FeedBack mode + 2.Program clock phase value with ChA/B DCLK enable, VIA_NB3DRAM_REG91[7:3]=00b + 3.Check ChB rank #, if 0, VIA_NB3DRAM_REG91[7]=1b, to disable ChB DCLKO + ChA DCLKO can not be disable, so always program VIA_NB3DRAM_REG91[3]=0b + */ +static const u8 DDR2_ChA_Clk_Phase_Table_1R[3][Clk_Phase_Table_DDR2_Width] = + { + // (And NOT) DDR800 DDR667 DDR533 DDR400 + //Reg Mask Value Value Value Value + {0x91, 0xF8, 0x02, 0x01, 0x00, 0x07 }, // 1Rank + {0x92, 0xF8, 0x04, 0x03, 0x03, 0x02 }, + {0x93, 0xF8, 0x06, 0x05, 0x04, 0x03 } + }; + +static const u8 DDR2_ChB_Clk_Phase_Table_1R[3][Clk_Phase_Table_DDR2_Width] = + { + // (And NOT) DDR800 DDR667 DDR533 DDR400 + //Reg Mask Value Value Value Value + {0x91, 0x0F, 0x20, 0x10, 0x00, 0x70 }, // 1Rank + {0x92, 0x0F, 0x40, 0x30, 0x30, 0x20 }, + {0x93, 0x0F, 0x60, 0x50, 0x40, 0x30 } + }; + +//vt6413c +/*static const u8 DDR2_ChA_Clk_Phase_Table_2R[3][Clk_Phase_Table_DDR2_Width] = + { + // (And NOT) DDR800 DDR667 DDR533 DDR400 + //Reg Mask Value Value Value Value + {0x91, 0xF8, 0x04, 0x03, 0x04, 0x01 }, // 1Rank + {0x92, 0xF8, 0x03, 0x06, 0x05, 0x04 }, + {0x93, 0xF8, 0x03, 0x07, 0x06, 0x05 } + };*/ + +//vt6413d +static const u8 DDR2_ChA_Clk_Phase_Table_2R[3][Clk_Phase_Table_DDR2_Width] = + { + // (And NOT) DDR800 DDR667 DDR533 DDR400 + //Reg Mask Value Value Value Value + {0x91, 0xF8, 0x02, 0x01, 0x00, 0x07}, // 1Rank + {0x92, 0xF8, 0x04, 0x03, 0x03, 0x02 }, + {0x93, 0xF8, 0x06, 0x05, 0x04, 0x03 } + }; + +/* +DRAM Write Data phase control +Modify NB Reg: Rx74/Rx75/Rx76 +*/ +//vt6413c +/*static const u8 DDR2_ChA_WrtData_Phase_Table[WrtData_REG_NUM ][WrtData_FREQ_NUM] = + { + // (And NOT) DDR800 DDR667 DDR533 DDR400 + //Reg Mask Value Value Value Value + {0x74, 0xF8, 0x03, 0x04, 0x05, 0x02 }, // 1Rank + {0x75, 0xF8, 0x03, 0x04, 0x05, 0x02 }, + {0x76, 0x00, 0x10, 0x80, 0x00, 0x07 } + };*/ + +//vt6413D +static const u8 DDR2_ChA_WrtData_Phase_Table[WrtData_REG_NUM ][WrtData_FREQ_NUM] = + { + // (And NOT) DDR800 DDR667 DDR533 DDR400 + //Reg Mask Value Value Value Value + {0x74, 0xF8, 0x01, 0x00, 0x00, 0x07 }, // 1Rank + {0x75, 0xF8, 0x01, 0x00, 0x00, 0x07 }, + {0x76, 0x10, 0x80, 0x87, 0x07, 0x06 }, + {0x8C, 0xFC, 0x03, 0x03, 0x03, 0x03 } + }; + +/*static const u8 DDR2_ChB_WrtData_Phase_Table[WrtData_REG_NUM ][WrtData_FREQ_NUM] = + { + // (And NOT) DDR800 DDR667 DDR533 DDR400 + //Reg Mask Value Value Value Value + {0x74, 0x8F, 0x30, 0x40, 0x30, 0x20 }, // 1Rank + {0x75, 0x8F, 0x30, 0x40, 0x30, 0x20 }, + {0x8A, 0x00, 0x10, 0x80, 0x07, 0x07 } + }; +*/ +/* +DQ/DQS Output Delay Control +Modify NB D0F3: RxF0/RxF1/RxF2/RxF3 +*/ +static const u8 DDR2_CHA_DQ_DQS_Delay_Table[4][DQ_DQS_Delay_Table_Width] = + { + // RxF0 RxF1 RxF2 RxF3 + { 0x00, 0x00, 0x00, 0x00 },// DDR400 + { 0x00, 0x00, 0x00, 0x00 },// DDR533 + { 0x00, 0x00, 0x00, 0x00 },// DDR667 + { 0x00, 0x00, 0x00, 0x00 }// DDR800 + }; +static const u8 DDR2_CHB_DQ_DQS_Delay_Table[4][DQ_DQS_Delay_Table_Width] = + { + // RxF4 RxF5 RxF6 RxF7 + { 0x00, 0x00, 0x00, 0x00 },// DDR400 + { 0x00, 0x00, 0x00, 0x00 },// DDR533 + { 0x00, 0x00, 0x00, 0x00 },// DDR667 + { 0x00, 0x00, 0x00, 0x00 }// DDR800 + }; + +/* +DQ/DQS input Capture Control +modify NB D0F3_Reg:Rx78/Rx79/Rx7A/Rx7B +*/ +//vt6413C +/*static const u8 DDR2_ChA_DQS_Input_Capture_Tbl[DQS_INPUT_CAPTURE_REG_NUM ][DQS_INPUT_CAPTURE_FREQ_NUM] = + { + // (And NOT) DDR800 DDR667 DDR533 DDR400 + //Reg Mask Value Value Value Value + {0x78, 0x00, 0x83, 0x8D, 0x87, 0x83 }, // 1Rank + {0x7A, 0xF0, 0x00, 0x00, 0x00, 0x00 }, + {0x7B, 0x00, 0x10, 0x30, 0x20, 0x10 } + };*/ + +//Vt6413D +static const u8 DDR2_ChA_DQS_Input_Capture_Tbl[DQS_INPUT_CAPTURE_REG_NUM ][DQS_INPUT_CAPTURE_FREQ_NUM] = + { + // (And NOT) DDR800 DDR667 DDR533 DDR400 + //Reg Mask Value Value Value Value + {0x78, 0xC0, 0x0D, 0x07, 0x03, 0x01 }, // 1Rank + {0x7A, 0xF0, 0x00, 0x00, 0x00, 0x00 }, + {0x7B, 0x00, 0x34, 0x34, 0x20, 0x10 } + }; + +static const u8 DDR2_ChB_DQS_Input_Capture_Tbl[DQS_INPUT_CAPTURE_REG_NUM ][DQS_INPUT_CAPTURE_FREQ_NUM] = + { + // (And NOT) DDR800 DDR667 DDR533 DDR400 + //Reg Mask Value Value Value Value + {0x79, 0x00, 0x89, 0x89, 0x87, 0x83 }, // 1Rank + {0x7A, 0x0F, 0x00, 0x00, 0x00, 0x00 }, + {0x8B, 0x00, 0x34, 0x34, 0x20, 0x10 } + }; + +static const u8 Fixed_DQSA_1_2_Rank_Table[4][2] = +{ +// Rx70 Rx71 + { 0x00, 0x05 }, // DDR800 + { 0x00, 0x06 }, // DDR667 + { 0x00, 0x04 }, // DDR533 + { 0x00, 0x05 } // DDR400 +}; +static const u8 Fixed_DQSA_3_4_Rank_Table[4][2] = +{ +// Rx70 Rx71 + {0x00 , 0x04}, // DDR800 + {0x00 , 0x04}, // DDR667 + {0x00 , 0x03}, // DDR533 + {0x00 , 0x04} // DDR400 +}; Index: src/mainboard/via/epia-m700/get_dsdt =================================================================== --- src/mainboard/via/epia-m700/get_dsdt (revision 0) +++ src/mainboard/via/epia-m700/get_dsdt (revision 0) @@ -0,0 +1,24 @@ +#!/bin/bash +# +# Simple script to dump the factory ACPI DSDT and convert it to C +# Needs to be run as root on some systems, and always run on the target machine + +if [ ! iasl ] +then echo "Intel ASL Compiler required to recompile DSDT table" +fi + +if [ ! -f /proc/acpi/dsdt ] +then echo "Cannot find DSDT table, check that your kernel supports and uses ACPI" +fi + +cat /proc/acpi/dsdt > dsdt +if [ ! -f dsdt ] +then echo "Failed copying DSDT, please check your permissions" +fi + +iasl -d -vr -vs dsdt +iasl -tc -vr -vs dsdt.dsl +mv dsdt.hex dsdt.c +echo "Done, cleaning up" +rm -f dsdt dsdt.dsl dsdt.aml dsdt.hex +exit Index: src/mainboard/via/epia-m700/ssdt.c =================================================================== --- src/mainboard/via/epia-m700/ssdt.c (revision 0) +++ src/mainboard/via/epia-m700/ssdt.c (revision 0) @@ -0,0 +1,17 @@ +/* + * + * Intel ACPI Component Architecture + * ASL Optimizing Compiler version 20051117 [Nov 17 2005] + * Copyright (C) 2000 - 2005 Intel Corporation + * Supports ACPI Specification Revision 3.0 + * + * Compilation of "ssdt.asl" - Tue Feb 10 17:38:20 2009 + * + * C source code output + * + */ +unsigned char AmlCode_ssdt[] = +{ + 0x53,0x53,0x44,0x54,0xA7,0x01,0x00,0x00, /* 00000000 "SSDT...." */ +// remove for lincese issue +}; Index: src/mainboard/via/epia-m700/cache_as_ram_auto.c =================================================================== --- src/mainboard/via/epia-m700/cache_as_ram_auto.c (revision 0) +++ src/mainboard/via/epia-m700/cache_as_ram_auto.c (revision 0) @@ -0,0 +1,721 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2009 One Laptop per Child, Association, Inc. + * + * 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 + * + * part of this file is from cx700 port, part of is from cn700 port, + * and acpi_is_wakeup_early_via_VX800() is part of Rudolf's S3 patch +*/ +#define ASSEMBLY 1 +#define __ROMCC__ +#define RAMINIT_SYSINFO 1 +#define CACHE_AS_RAM_ADDRESS_DEBUG 0 + +#include <stdint.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#include <arch/io.h> +#include <device/pnp_def.h> +#include <arch/romcc_io.h> +#include <arch/hlt.h> +#include "pc80/serial.c" +#include "arch/i386/lib/console.c" +#include "ram/ramtest.c" +#include "northbridge/via/vx800/vx800.h" +#include "cpu/x86/mtrr/earlymtrr.c" +#include "cpu/x86/bist.h" +#include "pc80/udelay_io.c" +#include "lib/delay.c" +#if CONFIG_USE_INIT == 0 +#include "lib/memcpy.c" +#endif +#include "cpu/x86/lapic/boot_cpu.c" + +/* this file contains the board-special SI value for raminit.c*/ +#include "mainboard/via/6413e/DrivingClkPhaseData.c" + +#include "northbridge/via/vx800/raminit.h" +#include "northbridge/via/vx800/raminit.c" +#include "cpu/x86/car/copy_and_run.c" +#include "mainboard/via/6413e/wakeup.h" + +/* this acpi_is_wakeup_early_via_VX800 is from Rudolf's patch post in maillist in 2008-9-8, + http://www.coreboot.org/pipermail/coreboot/2008-January/028787.html. +*/ + +void jason_tsc_count_car(void) +{/* + unsigned long long start; + asm volatile ("rdtsc" : "=A" (start)); + start >>= 20; + print_emerg("jason_tsc_count_car= "); + print_emerg_hex32((unsigned long) start); + print_emerg("\n");*/ +} + +int acpi_is_wakeup_early_via_vx800(void) { + device_t dev; + u16 tmp,result; + + print_debug("In acpi_is_wakeup_early_via_vx800\r\n"); + /* Power management controller */ + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VX855_LPC), 0); + + if (dev == PCI_DEV_INVALID) + die("Power management controller not found\r\n"); + + /* Set ACPI base address to I/O VX800_ACPI_IO_BASE. */ + pci_write_config16(dev, 0x88, VX800_ACPI_IO_BASE | 0x1); + + /* Enable ACPI accessm RTC signal gated with PSON. */ + pci_write_config8(dev, 0x81, 0x84); + + tmp = inw(VX800_ACPI_IO_BASE + 0x04); + result= ((tmp & (7 << 10)) >> 10) == 1 ? 3 : 0; + print_debug(" boot_mode="); + print_debug_hex16(result); + print_debug("\r\n"); + return result ; +} + +static inline int spd_read_byte(unsigned device, unsigned address) +{ + return smbus_read_byte(device, address); +} + + +/* all content of this function came from the cx700 port of coreboot. + */ +static void enable_mainboard_devices(void) +{ + device_t dev; + uint16_t values; + +#if 0 // add and close this switch, since some line cause error, some written at elsewhere (stage1 stage2), + u8 regdata; + dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_VX855_LPC), 0); + + /* Disable GP3 */ + pci_write_config8(dev, 0x98, 0x00); + + pci_write_config8(dev, 0x50, 0x80);//disable mc97 + //martin disable internal KBC Configuration + pci_write_config8(dev, 0x51, 0x2d); //internal Config is needed to decide which key can be pressed to resume from s3 + + // this cmd cause the irq0 can not be triggerd,since bit 5 was set to 0. + //pci_write_config8(dev, 0x58, 0x42); + + //these writing may + regdata=pci_read_config8(dev, 0x58); + regdata|=0x41; + pci_write_config8(dev, 0x58,regdata); + pci_write_config8(dev, 0x59, 0x80); + pci_write_config8(dev, 0x5b, 0x01); +#endif + print_debug("In enable_mainboard_devices \r\n"); + + /*--AUTHOR-NOTE-- + Enable P2P Bridge Header for External PCI BUS. +--AUTHOR-NOTE--*/ + dev = pci_locate_device(PCI_ID(0x1106, 0xa353), 0); + pci_write_config8(dev, 0x4f, 0x41); + + /* "5324" already is the default value of PCI ide device, cancel this pci write*/ + /*[william 20080124]: fix bug that can not boot ubuntu at the begnning time*/ + /* dev = 0; + dev = pci_locate_device(PCI_ID(0x1106, PCI_DEVICE_ID_VIA_VX855_IDE), 0); + values = pci_read_config16(dev, 0xBA); + values &= ~0xffff; + values |= 0x5324; + pci_write_config16(dev, 0xBA, values);*/ +} + +/* most content of this function came from the cx700 port of coreboot. + Turn on the shadow of E-seg. + */ +static void enable_shadow_ram(void) +{ + uint8_t shadowreg; + /*changed the value from 0x2a to 0x3f. "read only" may block "write"? + and maybe in C-seg "write" will be needed?*/ + pci_write_config8(PCI_DEV(0, 0, 3), 0x80, 0xff); + /* 0xf0000-0xfffff - ACPI tables */ + shadowreg = pci_read_config8(PCI_DEV(0, 0, 3), 0x83); + shadowreg |= 0x30; + pci_write_config8(PCI_DEV(0, 0, 3), 0x83, shadowreg); + /* 0xe0000-0xeffff - elfload? */ + /*in s3 resume process, wakeup.c, I use E-seg to hold the code(which can not locate in the area to be covered) that will copy 0-A-seg and F-seg from TOP-mem back to their normal location.*/ + pci_write_config8(PCI_DEV(0, 0, 3), 0x82, 0xff); + +#if 0 + /* Enable shadow ram as normal dram */ + /* 0xc0000-0xcffff - VGA BIOS */ + pci_write_config8(PCI_DEV(0, 0, 3), 0x80, 0x2a); + pci_write_config8(PCI_DEV(0, 0, 7), 0x61, 0x00); + /* 0xd0000-0xdffff - ?? */ + //pci_write_config8(PCI_DEV(0, 0, 3), 0x81, 0xff); + //pci_write_config8(PCI_DEV(0, 0, 7), 0x62, 0xff); + + /* Do it again for the vlink controller */ + shadowreg = pci_read_config8(PCI_DEV(0, 0, 7), 0x63); + shadowreg |= 0x30; + pci_write_config8(PCI_DEV(0, 0, 7), 0x63, shadowreg); +#endif +} + + +/*added this table 2008-11-28, +this table contains the value needed to be set before begin to init dram. +Note: REV_Bx should be checked for changes when porting a new board!!!!! */ +static const struct VIA_PCI_REG_INIT_TABLE mNbStage1InitTbl[]= { + //VT3409 no pcie + 0x00, 0xFF, NB_APIC_REG(0x61), 0xFF, 0x0E, // Set Exxxxxxx as pcie mmio config range + 0x00, 0xFF, NB_APIC_REG(0x60), 0xF4, 0x0B, // Support extended cfg address of pcie + //0x00, 0xFF, NB_APIC_REG(0x42), 0xF9, 0x02, // APIC Interrupt((BT_INTR)) Control + // Set ROMSIP value by software + + /*0x00, 0xFF, NB_HOST_REG(0x70), 0x77, 0x33, // 2x Host Adr Strobe/Pad Pullup Driving = 3 + 0x00, 0xFF, NB_HOST_REG(0x71), 0x77, 0x33, // 2x Host Adr Strobe/Pad Pulldown Driving = 3 + 0x00, 0xFF, NB_HOST_REG(0x72), 0x77, 0x33, // 4x Host Dat Strobe/Pad Pullup Driving = 3 + 0x00, 0xFF, NB_HOST_REG(0x73), 0x77, 0x33, // 4x Host Dat Strobe/Pad Pulldown Driving = 3 + 0x00, 0xFF, NB_HOST_REG(0x74), 0xFF, 0x21, // Memory I/F timing ctrl + 0x00, 0xFF, NB_HOST_REG(0x74), 0xFF, 0xE1, // Memory I/F timing ctrl + 0x00, 0xFF, NB_HOST_REG(0x75), 0xFF, 0x18, // AGTL+ I/O Circuit + 0x00, 0xFF, NB_HOST_REG(0x76), 0xFB, 0x0C, // AGTL+ Compensation Status + 0x00, 0xFF, NB_HOST_REG(0x78), 0xFF, 0x33, // 2X AGTL+ Auto Compensation Offset + 0x00, 0xFF, NB_HOST_REG(0x79), 0xFF, 0x33, // 4X AGTL+ Auto Compensation Offset + 0x00, 0xFF, NB_HOST_REG(0x7A), 0x3F, 0x72, // AGTL Compensation Status + 0x00, 0xFF, NB_HOST_REG(0x7A), 0x3F, 0x77, // AGTL Compensation Status + 0x00, 0xFF, NB_HOST_REG(0x7B), 0xFF, 0x44, // Input Host Address / Host Strobe Delay Control for HA Group + 0x00, 0xFF, NB_HOST_REG(0x7B), 0xFF, 0x22, // Input Host Address / Host Strobe Delay Control for HA Group + 0x00, 0xFF, NB_HOST_REG(0x7C), 0xFF, 0x00, // Output Delay Control of PAD for HA Group + 0x00, 0xFF, NB_HOST_REG(0x7D), 0xFF, 0xAA, // Host Address / Address Clock Output Delay Control (Only for P4 Bus) + 0x00, 0xFF, NB_HOST_REG(0x7E), 0xFF, 0x10, // Host Address CKG Rising / Falling Time Control (Only for P4 Bus) + 0x00, 0xFF, NB_HOST_REG(0x7E), 0xFF, 0x40, // Host Address CKG Rising / Falling Time Control (Only for P4 Bus) + 0x00, 0xFF, NB_HOST_REG(0x7F), 0xFF, 0x10, // Host Address CKG Rising / Falling Time Control (Only for P4 Bus) + 0x00, 0xFF, NB_HOST_REG(0x7F), 0xFF, 0x40, // Host Address CKG Rising / Falling Time Control (Only for P4 Bus) + 0x00, 0xFF, NB_HOST_REG(0x80), 0x3F, 0x44, // Host Data Receiving Strobe Delay Ctrl 1 + 0x00, 0xFF, NB_HOST_REG(0x81), 0xFF, 0x44, // Host Data Receiving Strobe Delay Ctrl 2 + 0x00, 0xFF, NB_HOST_REG(0x82), 0xFF, 0x00, // Output Delay of PAD for HDSTB + 0x00, 0xFF, NB_HOST_REG(0x83), 0xFF, 0x00, // Output Delay of PAD for HD + 0x00, 0xFF, NB_HOST_REG(0x84), 0xFF, 0x44, // Host Data / Strobe CKG Control (Group 0) + 0x00, 0xFF, NB_HOST_REG(0x85), 0xFF, 0x44, // Host Data / Strobe CKG Control (Group 1) + 0x00, 0xFF, NB_HOST_REG(0x86), 0xFF, 0x44, // Host Data / Strobe CKG Control (Group 2) + 0x00, 0xFF, NB_HOST_REG(0x87), 0xFF, 0x44, // Host Data / Strobe CKG Control (Group 3)*/ + + + // CPU Host Bus Control + 0x00, 0xFF, NB_HOST_REG(0x50), 0x1F, 0x08, // Request phase ctrl: Dynamic Defer Snoop Stall Count = 8 + //0x00, 0xFF, NB_HOST_REG(0x51), 0xFF, 0x7F, // CPU I/F Ctrl-1: Disable Fast DRDY and RAW + 0x00, 0xFF, NB_HOST_REG(0x51), 0xFF, 0x7C, // CPU I/F Ctrl-1: Disable Fast DRDY and RAW + 0x00, 0xFF, NB_HOST_REG(0x52), 0xCB, 0xCB, // CPU I/F Ctrl-2: Enable all for performance + //0x00, 0xFF, NB_HOST_REG(0x53), 0xFF, 0x88, // Arbitration: Host/Master Occupancy timer = 8*4 HCLK + 0x00, 0xFF, NB_HOST_REG(0x53), 0xFF, 0x44, // Arbitration: Host/Master Occupancy timer = 4*4 HCLK + 0x00, 0xFF, NB_HOST_REG(0x54), 0x1E, 0x1C, // Misc Ctrl: Enable 8QW burst Mem Access + //0x00, 0xFF, NB_HOST_REG(0x55), 0x06, 0x06, // Miscellaneous Control 2 + 0x00, 0xFF, NB_HOST_REG(0x55), 0x06, 0x04, // Miscellaneous Control 2 + 0x00, 0xFF, NB_HOST_REG(0x56), 0xF7, 0x63, // Write Policy 1 + //0x00, 0xFF, NB_HOST_REG(0x59), 0x3D, 0x01, // CPU Miscellaneous Control 1, enable Lowest-Priority IPL + //0x00, 0xFF, NB_HOST_REG(0x5c), 0xFF, 0x00, // CPU Miscellaneous Control 2 + 0x00, 0xFF, NB_HOST_REG(0x5D), 0xFF, 0xA2, // Write Policy + 0x00, 0xFF, NB_HOST_REG(0x5E), 0xFF, 0x88, // Bandwidth Timer + 0x00, 0xFF, NB_HOST_REG(0x5F), 0x46, 0x46, // CPU Misc Ctrl + // 0x00, 0xFF, NB_HOST_REG(0x90), 0xFF, 0x0B, // CPU Miscellaneous Control 3 + //0x00, 0xFF, NB_HOST_REG(0x96), 0x0B, 0x0B, // CPU Miscellaneous Control 2 + 0x00, 0xFF, NB_HOST_REG(0x96), 0x0B, 0x0A, // CPU Miscellaneous Control 2 + 0x00, 0xFF, NB_HOST_REG(0x98), 0xC1, 0x41, // CPU Miscellaneous Control 3 + 0x00, 0xFF, NB_HOST_REG(0x99), 0x0E, 0x06, // CPU Miscellaneous Control 4 + + + // Set APIC and SMRAM + 0x00, 0xFF, NB_HOST_REG(0x97), 0xFF, 0x00, // APIC Related Control + 0x00, 0xFF, NB_DRAMC_REG(0x86), 0xD6, 0x29, // SMM and APIC Decoding: enable APIC, MSI and SMRAM A-Seg + 0x00, 0xFF, 0x00, 0x00, 0x00,0x00, 0x00, 0x00 // End of the table +}; + +#define USE_VCP 1//0 means use DVP +#define USE_COM1 1 +#define USE_COM2 0 + +#define gCom1Base 0x3f8 +#define gCom2Base 0x2f8 +void EmbedComInit() +{ + u8 ByteVal; + u16 ComBase; + + //enable NB multiple function control + ByteVal = pci_read_config8(PCI_DEV(0, 0, 0), 0x4f); + ByteVal = ByteVal |0x01; + pci_write_config8(PCI_DEV(0, 0, 0), 0x4f, ByteVal); + + //VGA Enable + ByteVal = pci_read_config8(PCI_DEV(0, 0, 3), 0xA1); + ByteVal = ByteVal |0x80; + pci_write_config8(PCI_DEV(0, 0, 3), 0xA1, ByteVal); + + ByteVal = pci_read_config8(PCI_DEV(0, 0, 3), 0xA7); + ByteVal = ByteVal |0x08; + pci_write_config8(PCI_DEV(0, 0, 3), 0xA7, ByteVal); + + //Enable p2p IO/mem + ByteVal = pci_read_config8(PCI_DEV(0, 1, 0), 0x4); + ByteVal = ByteVal |0x07; + pci_write_config8(PCI_DEV(0, 1, 0), 0x4, ByteVal); + + //Turn on Graphic chip IO port port access + ByteVal = inb(0x3C3); + ByteVal = ByteVal |0x01; + outb(ByteVal,0x3C3); + + //Turn off Graphic chip Register protection + outb(0x10,0x3C4); + ByteVal = inb(0x3C5); + ByteVal = ByteVal |0x01; + outb(ByteVal,0x3C5); + + //south module pad share enable 0x3C5.78[7] + outb(0x78,0x3C4); + ByteVal = inb(0x3C5); + ByteVal = ByteVal |0x80; + outb(ByteVal,0x3C5); + + //enable UART Function multiplex with DVP or VCP pad D17F0Rx46[7,6] + ByteVal = pci_read_config8(PCI_DEV(0, 17, 0), 0x46); + //multiplex with VCP + if(USE_VCP == 1) + ByteVal = (ByteVal & 0x3F) | 0x40; + //multiplex with DVP + else + ByteVal = (ByteVal & 0x3F) | 0xC0; + pci_write_config8(PCI_DEV(0, 17, 0), 0x46, ByteVal); + + + + //enable embeded com1 and com2 D17F0RxB0[5,4] + ByteVal = pci_read_config8(PCI_DEV(0, 17, 0), 0xB0); + ByteVal = ByteVal & 0xcf; + //multiplex with VCP + if(USE_COM1==1) + ByteVal = ByteVal | 0x10; + if(USE_COM2==1) + ByteVal = ByteVal | 0x20; + pci_write_config8(PCI_DEV(0, 17, 0), 0xB0, ByteVal); + + if(USE_COM1 == 1) + ComBase = gCom1Base; + else + ComBase = gCom2Base; + +//noharddrive + + //set embeded com1 IO base = 0x3E8 + //D17F0RB4 + //ByteVal = 0xFD; + if(USE_COM1==1){ + ByteVal = (u8)((gCom1Base >> 3) |0x80); + pci_write_config8(PCI_DEV(0, 17, 0), 0xB4, ByteVal); + ByteVal = pci_read_config8(PCI_DEV(0, 17, 0), 0xb2); + ByteVal = (ByteVal&0xf0)|0x04; + pci_write_config8(PCI_DEV(0, 17, 0), 0xB2, ByteVal); + } + + //set embeded com2 IO base = 0x2E8 + //D17F0RB5 + //ByteVal = 0xDD; + if(USE_COM2==1){ + ByteVal = (u8)((gCom2Base >> 3) |0x80); + pci_write_config8(PCI_DEV(0, 17, 0), 0xB5, ByteVal); + ByteVal = pci_read_config8(PCI_DEV(0, 17, 0), 0xb2); + ByteVal = (ByteVal&0x0f)|0x30; + pci_write_config8(PCI_DEV(0, 17, 0), 0xB2, ByteVal); + } + + //no port 80 biger then 0x10 + + //disable interrupt + ByteVal = inb(ComBase + 3); + outb(ByteVal & 0x7F,ComBase + 3); + outb( 0x00,ComBase + 1); + + //set baudrate + ByteVal = inb(ComBase + 3); + outb( ByteVal | 0x80,ComBase + 3); + outb(0x01,ComBase); + outb(0x00,ComBase + 1 ); + + //set frame fromat + ByteVal = inb(ComBase + 3); + outb( ByteVal & 0x3F,ComBase + 3); + outb(0x03,ComBase + 3 ); + outb(0x00,ComBase + 2); + outb(0x00,ComBase + 4); + + //SOutput("Embeded com output\n"); + //while(1); +} + +/*cache_as_ram.inc jump to here +*/ +void amd64_main(unsigned long bist) +{ unsigned cpu_reset = 0; + u16 boot_mode; + u8 rambits; + + //device_t dev; + /* Enable multifunction for northbridge. These 4 lines(until console_init();) are the same with epia-cn port.*/ + pci_write_config8(PCI_DEV(0, 0, 0), 0x4f, 0x01); + EmbedComInit(); + //enable_vx800_serial(); + //uart_init(); + + +/* 1. D15F0 + +a) RxBAh = 71h + +b) RxBBh = 05h + +c) RxBEh = 71h + +d) RxBFh = 05h + +2. D17F0 + +a) RxA0h = 06h + +b) RxA1h = 11h + +c) RxA2h = 27h + +d) RxA3h = 32h + +e) Rx79h = 40h + +f) Rx72h = 27h + +g) Rx73h = 32h +*/ + + u8 Data8; + + jason_tsc_count_car(); + pci_write_config16(PCI_DEV(0, 0xf, 0), 0xBA, PCI_DEVICE_ID_VIA_VX855_IDE); + pci_write_config16(PCI_DEV(0, 0xf, 0), 0xBE, PCI_DEVICE_ID_VIA_VX855_IDE); + pci_write_config16(PCI_DEV(0, 0x11, 0), 0xA0, PCI_VENDOR_ID_VIA); + pci_write_config16(PCI_DEV(0, 0x11, 0), 0xA2, PCI_DEVICE_ID_VIA_VX855_LPC); + Data8=pci_read_config8(PCI_DEV(0, 0x11, 0),0x79); + Data8 &= ~0x40; + Data8 |=0x40; + pci_write_config8(PCI_DEV(0, 0x11, 0),0x79,Data8); + pci_write_config16(PCI_DEV(0, 0x11, 0), 0x72, PCI_DEVICE_ID_VIA_VX855_LPC); + + console_init();//there are to function defination of console_init(), while the src/archi386/lib is the right one. + + /* decide if this is a s3 wakeup or a normal boot*/ + boot_mode=acpi_is_wakeup_early_via_vx800(); + /* 2008-11-27 add this, to transfer "cpu restart" to "cold boot" + When this boot is not a S3 resume, and PCI registers had been written, + then this must be a cpu restart(result of os reboot cmd), so we need a real "cold boot".*/ + jason_tsc_count_car(); + if((boot_mode!=3)&&(pci_read_config8(PCI_DEV(0, 0, 3), 0x80)!=0)) + {outb(6, 0xcf9);} /*x86 cold boot I/O cmd*/ + + /* this 2 lines is the same with epia-cn port.*/ + enable_smbus(); + jason_tsc_count_car(); + //smbus_fixup(&ctrl);// this fix does help vx800!, but vx855 doesn't need this + + if (bist == 0) { + //CAR need mtrr untill mem is ok, so i disable this early_mtrr_init(); + //print_debug("doing early_mtrr\r\n"); + //early_mtrr_init(); + } + + /* Halt if there was a built-in self test failure. */ + report_bist_failure(bist); + + print_debug("Enabling mainboard devices\r\n"); + enable_mainboard_devices(); + + u8 Data; + device_t device; + /*2008-11-27 Get NB Chip revision from D0F4RxF6, revision will be used in via_pci_inittable*/ + device=PCI_DEV(0, 0, 4); + Data=pci_read_config8(device,0xf6); + print_debug("NB chip revision ="); + print_debug_hex8(Data); + print_debug("\r\n"); + /*2008-11-27, make NB ready before draminit*/ + via_pci_inittable(Data,mNbStage1InitTbl); + + /*2008-11-27 add this. + When resume from s3, draminit is skiped, so need to recovery any PCI register related to draminit. d0f3 didnt lose its Power during whole s3 time, so any register not belonging to d0f3 needs to be recovered .*/ +#if 1 + if (boot_mode==3) { + u8 i; + u8 ramregs[] = {0x43, 0x42, 0x41, 0x40}; + DRAM_SYS_ATTR DramAttr; + + print_debug("This is a S3 wakeup\r\n"); + + memset (&DramAttr, 0,sizeof (DRAM_SYS_ATTR)); + /*Step1 DRAM Detection; DDR1 or DDR2; Get SPD Data; Rank Presence;64 or 128bit; Unbuffered or registered; 1T or 2T*/ + DRAMDetect(&DramAttr); + + /*begin to get ram size, 43,42 41 40 contains the end address of last rank in ddr2-slot*/ + device=PCI_DEV(0, 0, 3); + for(rambits = 0, i = 0; i < ARRAY_SIZE(ramregs); i++) { + rambits = pci_read_config8(device, ramregs[i]); + if (rambits != 0) + break; + } + + DRAMDRDYSetting (&DramAttr); + + Data = 0x80;//this value is same with DevInit.c + pci_write_config8(PCI_DEV(0,0,4), 0xa3, Data); + pci_write_config8(PCI_DEV(0,17,7), 0x60, rambits<<2); + Data=pci_read_config8(MEMCTRL, 0x88); + pci_write_config8(PCI_DEV(0,17,7), 0xE5, Data); + + DRAMRegFinalValue(&DramAttr); //Just copy this function from draminit to here! + SetUMARam();//Just copy this function from draminit to here! + print_debug("Resume from S3, RAM init was ignored\r\n"); + } + else{ + ddr2_ram_setup(); + ram_check(0, 640 * 1024); + } +#endif + //ddr2_ram_setup(); + /*2008-11-27 this line is the same with cx700 port .*/ + enable_shadow_ram(); + + jason_tsc_count_car(); + /*2008-11-27 + For coreboot most time of S3 resume is the same as normal boot, so some memory area under 1M become dirty, + so before this happen, I need to backup the content of mem to top-mem. + I will reserve the 1M top-men in LBIO table in coreboot_table.c and recovery the content of 1M-mem in wakeup.c + */ +#if PAYLOAD_IS_SEABIOS==1 // + if(boot_mode==3){ + /* An Idea of Libo.Feng at amd.com in http://www.coreboot.org/pipermail/coreboot/2008-December/043111.html + I want move the 1M data, I have to set some MTRRs myself.*/ + /*Setting mtrr before back memoy save s3 resume time about 0.14 seconds*/ + /*!!!!!!!!Since CAR stack uses cache, and we are using cache here, we must be careful, + 1 during these mtrr code, must no function call, (after this mtrr, I think it should be ok to use function) + 2 before stack switch, no use variable that have value set before this + 3 due to 2, take care of "cpu_reset", I directlly set it to ZERO. + */ + u32 memtop=*(u32*)WAKE_MEM_INFO; + u32 memtop1=*(u32*)WAKE_MEM_INFO-0x100000; + u32 memtop2=*(u32*)WAKE_MEM_INFO-0x200000; + u32 memtop3=*(u32*)WAKE_MEM_INFO- 64*1024-0x100000; + u32 memtop4=*(u32*)WAKE_MEM_INFO- 64*1024-0x100000+0xe0000; + /* __asm__ volatile ( + "movl $0x204, %%ecx\n\t" + "xorl %%edx, %%edx\n\t" + "movl %0,%%eax\n\t" + "orl $(0 | 6), %%eax\n\t" + "wrmsr\n\t" + + "movl $0x205, %%ecx\n\t" + "xorl %%edx, %%edx\n\t" + "movl $0x100000,%%eax\n\t" + "decl %%eax\n\t" + "notl %%eax\n\t" + "orl $(0 | 0x800), %%eax\n\t" + "wrmsr\n\t" + ::"g"(memtop2) + ); + __asm__ volatile ( + "movl $0x206, %%ecx\n\t" + "xorl %%edx, %%edx\n\t" + "movl %0,%%eax\n\t" + "orl $(0 | 6), %%eax\n\t" + "wrmsr\n\t" + + "movl $0x207, %%ecx\n\t" + "xorl %%edx, %%edx\n\t" + "movl $0x100000,%%eax\n\t" + "decl %%eax\n\t" + "notl %%eax\n\t" + "orl $(0 | 0x800), %%eax\n\t" + "wrmsr\n\t" + ::"g"(memtop1) + ); + __asm__ volatile ( + "movl $0x208, %ecx\n\t" + "xorl %edx, %edx\n\t" + "movl $0,%eax\n\t" + "orl $(0 | 6), %eax\n\t" + "wrmsr\n\t" + + "movl $0x209, %ecx\n\t" + "xorl %edx, %edx\n\t" + "movl $0x100000,%eax\n\t" + "decl %eax\n\t" + "notl %eax\n\t" + "orl $(0 | 0x800), %eax\n\t" + "wrmsr\n\t" + ); + */ + // WAKE_MEM_INFO is inited in get_set_top_available_mem in tables.c + // these two memcpy not not be enabled if set the MTRR around this two lines. + /*__asm__ volatile ( + "movl $0, %%esi\n\t" + "movl %0, %%edi\n\t" + "movl $0xa0000, %%ecx\n\t" + "shrl $2, %%ecx\n\t" + "rep movsd\n\t" + ::"g"(memtop3) + ); + __asm__ volatile ( + "movl $0xe0000, %%esi\n\t" + "movl %0, %%edi\n\t" + "movl $0x20000, %%ecx\n\t" + "shrl $2, %%ecx\n\t" + "rep movsd\n\t" + ::"g"(memtop4) + );*/ + print_debug("copy memory to high memory to protect s3 wakeup vector code \r\n");//this can have function call, because no variable used before this + memcpy((unsigned char *)((*(u32*)WAKE_MEM_INFO) - 64*1024-0x100000),(unsigned char *)0,0xa0000); + memcpy((unsigned char *)((*(u32*)WAKE_MEM_INFO) - 64*1024-0x100000+0xe0000),(unsigned char *)0xe0000,0x20000); + + /* restore the MTRR previously modified. */ +/* __asm__ volatile ( + "wbinvd\n\t" + "xorl %edx, %edx\n\t" + "xorl %eax, %eax\n\t" + "movl $0x204, %ecx\n\t" + "wrmsr\n\t" + "movl $0x205, %ecx\n\t" + "wrmsr\n\t" + "movl $0x206, %ecx\n\t" + "wrmsr\n\t" + "movl $0x207, %ecx\n\t" + "wrmsr\n\t" + "movl $0x208, %ecx\n\t" + "wrmsr\n\t" + "movl $0x209, %ecx\n\t" + "wrmsr\n\t" + );*/ + } + #endif +/*2008-11-27 +the following code is copied from src\mainboard\tyan\s2735\cache_as_ram_auto.c +Only the code around CLEAR_FIRST_1M_RAM is changed. +Removed all the code around CLEAR_FIRST_1M_RAM and #include "cpu/x86/car/cache_as_ram_post.c" +the CLEAR_FIRST_1M_RAM seems to make cpu/x86/car/cache_as_ram_post.c stop at somewhere, +and cpu/x86/car/cache_as_ram_post.c do not cache my $XIP_ROM_BASE+SIZE area. + +Uuse: #include "cpu/via/car/cache_as_ram_post.c". this version post.c have some diff withx86-version +*/ +#if 1 + { + /* Check value of esp to verify if we have enough rom for stack in Cache as RAM */ + unsigned v_esp; + __asm__ volatile ( + "movl %%esp, %0\n\t" + : "=a" (v_esp) + ); +#if CONFIG_USE_INIT + printk_debug("v_esp=%08x\r\n", v_esp); +#else + print_debug("v_esp="); print_debug_hex32(v_esp); print_debug("\r\n"); +#endif + } + +#endif +#if 1 + +cpu_reset_x: +// it seems that cpu_reset is not used before this, so I just reset it, (this is because the s3 resume, setting in mtrr and copy data may destroy +//stack +cpu_reset=0; +#if CONFIG_USE_INIT + printk_debug("cpu_reset = %08x\r\n",cpu_reset); +#else + print_debug("cpu_reset = "); print_debug_hex32(cpu_reset); print_debug("\r\n"); +#endif + + if(cpu_reset == 0) { + print_debug("Clearing initial memory region: "); + } + print_debug("No cache as ram now - "); + + /* store cpu_reset to ebx */ + __asm__ volatile ( + "movl %0, %%ebx\n\t" + ::"a" (cpu_reset) + ); + + +/* Cancel these lines, CLEAR_FIRST_1M_RAM cause the cpu/x86/car/cache_as_ram_post.c stop at somewhere + + if(cpu_reset==0) { +#define CLEAR_FIRST_1M_RAM 1 +#include "cpu/via/car/cache_as_ram_post.c" + } + else { +#undef CLEAR_FIRST_1M_RAM +#include "cpu/via/car/cache_as_ram_post.c" + } +*/ +#include "cpu/via/car/cache_as_ram_post.c" +//#include "cpu/x86/car/cache_as_ram_post.c" + __asm__ volatile ( + /* set new esp */ /* before _RAMBASE */ + "subl %0, %%ebp\n\t" + "subl %0, %%esp\n\t" + ::"a"( (DCACHE_RAM_BASE + DCACHE_RAM_SIZE)- _RAMBASE) + ); + + { + unsigned new_cpu_reset; + + /* get back cpu_reset from ebx */ + __asm__ volatile ( + "movl %%ebx, %0\n\t" + :"=a" (new_cpu_reset) + ); + + /* We can not go back any more, we lost old stack data in cache as ram*/ + if(new_cpu_reset==0) { + print_debug("Use Ram as Stack now - done\r\n"); + } else + { + print_debug("Use Ram as Stack now - \r\n"); + } +#if CONFIG_USE_INIT + printk_debug("new_cpu_reset = %08x\r\n", new_cpu_reset); +#else + print_debug("new_cpu_reset = "); print_debug_hex32(new_cpu_reset); print_debug("\r\n"); +#endif + jason_tsc_count_car(); + /*copy and execute coreboot_ram */ + copy_and_run(new_cpu_reset); + /* We will not return */ + } +#endif + + + print_debug("should not be here -\r\n"); + +} Index: src/mainboard/via/epia-m700/fadt.c =================================================================== --- src/mainboard/via/epia-m700/fadt.c (revision 0) +++ src/mainboard/via/epia-m700/fadt.c (revision 0) @@ -0,0 +1,170 @@ +/* + * ACPI - create the Fixed ACPI Description Tables (FADT) + * (C) Copyright 2004 Nick Barker nick.barker9@btinternet.com + * Copyright (C) 2009 One Laptop per Child, Association, Inc. + * + * 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 <string.h> +#include <arch/acpi.h> +#include <../../../northbridge/via/vx800/vx800.h> + +void acpi_create_fadt(acpi_fadt_t *fadt,acpi_facs_t *facs,void *dsdt){ + acpi_header_t *header =& (fadt->header); + + memset((void *)fadt, 0, sizeof(acpi_fadt_t)); + memcpy(header->signature, "FACP", 4); + header->length = 244; + header->revision = 1; + memcpy(header->oem_id, "VX800 ", 6); + memcpy(header->oem_table_id, "LNXBACPI", 8); + memcpy(header->asl_compiler_id, "LXB", 8); + header->asl_compiler_revision = 0; + + fadt->firmware_ctrl = facs; + fadt->dsdt = dsdt; + fadt->preferred_pm_profile = 0; + fadt->sci_int = 0x9; + + fadt->smi_cmd = VX800_ACPI_IO_BASE+0x2F; + fadt->acpi_enable = 0xA1; + fadt->acpi_disable = 0xA0; + + /* value 42F,A1,A0, if we dont want SMI, then set them to zero. + fadt->smi_cmd = 0x0; + fadt->acpi_enable = 0x0; + fadt->acpi_disable = 0x0; + */ + + fadt->s4bios_req = 0x0; + fadt->pstate_cnt = 0x0; + + fadt->pm1a_evt_blk = VX800_ACPI_IO_BASE; + fadt->pm1b_evt_blk = 0x0; + fadt->pm1a_cnt_blk = VX800_ACPI_IO_BASE+0x4; + fadt->pm1b_cnt_blk = 0x0; + fadt->pm2_cnt_blk = 0x22;//to support cpu-c3 +// fadt->pm2_cnt_blk = 0x0; + fadt->pm_tmr_blk = VX800_ACPI_IO_BASE+0x8; + fadt->gpe0_blk = VX800_ACPI_IO_BASE+0x20; + fadt->gpe1_blk = VX800_ACPI_IO_BASE+0x50; + + fadt->pm1_evt_len = 4; + fadt->pm1_cnt_len = 2; + fadt->pm2_cnt_len = 1;//to support cpu-c3 +// fadt->pm2_cnt_len = 0; + + fadt->pm_tmr_len = 4; + fadt->gpe0_blk_len = 4; + fadt->gpe1_blk_len = 4; + fadt->gpe1_base = 0x10; + fadt->cst_cnt = 0; + + fadt->p_lvl2_lat = 0x50; //this is the coreboot source + fadt->p_lvl3_lat = 0x320;// +// fadt->p_lvl2_lat = 0x80; // +// fadt->p_lvl3_lat = 0x800;// +// fadt->p_lvl2_lat = 0x1; // +// fadt->p_lvl3_lat = 0x23; + +// fadt->p_lvl2_lat = 0x200; //disable +// fadt->p_lvl3_lat = 0x2000; + + fadt->flush_size = 0; + fadt->flush_stride = 0; + fadt->duty_offset = 0; +// fadt->duty_width = 1; + fadt->duty_width = 4; + fadt->day_alrm = 0x7d; + fadt->mon_alrm = 0x7e; + fadt->century = 0x32; + fadt->iapc_boot_arch = 0x0; + fadt->flags = 0xa5; + + 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 = facs; + fadt->x_firmware_ctl_h = 0; + fadt->x_dsdt_l = dsdt; + fadt->x_dsdt_h = 0; + + fadt->x_pm1a_evt_blk.space_id = 1; + fadt->x_pm1a_evt_blk.bit_width = 4; + fadt->x_pm1a_evt_blk.bit_offset = 0; + fadt->x_pm1a_evt_blk.resv = 0; + fadt->x_pm1a_evt_blk.addrl = VX800_ACPI_IO_BASE; + fadt->x_pm1a_evt_blk.addrh = 0x0; + + fadt->x_pm1b_evt_blk.space_id = 1; + fadt->x_pm1b_evt_blk.bit_width = 4; + 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 = 2; + fadt->x_pm1a_cnt_blk.bit_offset = 0; + fadt->x_pm1a_cnt_blk.resv = 0; + fadt->x_pm1a_cnt_blk.addrl = VX800_ACPI_IO_BASE+0x4; + fadt->x_pm1a_cnt_blk.addrh = 0x0; + + fadt->x_pm1b_cnt_blk.space_id = 1; + fadt->x_pm1b_cnt_blk.bit_width = 2; + 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.space_id = 0; + fadt->x_pm2_cnt_blk.bit_width = 0; + fadt->x_pm2_cnt_blk.bit_offset = 0; + fadt->x_pm2_cnt_blk.resv = 0; + fadt->x_pm2_cnt_blk.addrl = 0x0; + fadt->x_pm2_cnt_blk.addrh = 0x0; + + fadt->x_pm_tmr_blk.space_id = 1; + fadt->x_pm_tmr_blk.bit_width = 4; + fadt->x_pm_tmr_blk.bit_offset = 0; + fadt->x_pm_tmr_blk.resv = 0; + fadt->x_pm_tmr_blk.addrl = VX800_ACPI_IO_BASE+0x8; + fadt->x_pm_tmr_blk.addrh = 0x0; + + fadt->x_gpe0_blk.space_id = 1; + fadt->x_gpe0_blk.bit_width = 0; + fadt->x_gpe0_blk.bit_offset = 0; + fadt->x_gpe0_blk.resv = 0; + fadt->x_gpe0_blk.addrl = VX800_ACPI_IO_BASE+0x20; + 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; + + header->checksum = acpi_checksum((void *)fadt, sizeof(acpi_fadt_t)); +} Index: src/mainboard/via/epia-m700/Config.lb =================================================================== --- src/mainboard/via/epia-m700/Config.lb (revision 0) +++ src/mainboard/via/epia-m700/Config.lb (revision 0) @@ -0,0 +1,146 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2009 One Laptop per Child, Association, Inc. +## +## 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 +## + +if USE_FALLBACK_IMAGE + default ROM_SECTION_SIZE = FALLBACK_SIZE + default ROM_SECTION_OFFSET = (ROM_SIZE - FALLBACK_SIZE) +else + default ROM_SECTION_SIZE = (ROM_SIZE - FALLBACK_SIZE) + default ROM_SECTION_OFFSET = 0 +end +default PAYLOAD_SIZE = (ROM_SECTION_SIZE - ROM_IMAGE_SIZE) +default CONFIG_ROM_PAYLOAD_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1) +default _ROMBASE = (CONFIG_ROM_PAYLOAD_START + PAYLOAD_SIZE) +default XIP_ROM_SIZE = 64 * 1024 +#default XIP_ROM_SIZE = ROM_IMAGE_SIZE +#default XIP_ROM_BASE = (_ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE) +default XIP_ROM_BASE = (_ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE) + + +arch i386 end +driver mainboard.o +driver wakeup.o +if HAVE_PIRQ_TABLE object irq_tables.o end +if HAVE_MP_TABLE object mptable.o end +if HAVE_ACPI_TABLES + object fadt.o + object dsdt.o +# object ssdt.o + object acpi_tables.o +end +# these lines maybe noused +makerule ./failover.E + depends "$(MAINBOARD)/../../../arch/i386/lib/failover.c ./romcc" + action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/../../../arch/i386/lib/failover.c -o $@" +end +makerule ./failover.inc + depends "$(MAINBOARD)/../../../arch/i386/lib/failover.c ./romcc" + action "./romcc -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/../../../arch/i386/lib/failover.c -o $@" +end +if USE_DCACHE_RAM + if CONFIG_USE_INIT + makerule ./cache_as_ram_auto.o + depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h" + action "$(CC) $(DISTRO_CFLAGS) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -o $@" + end + else + makerule ./cache_as_ram_auto.inc + depends "$(MAINBOARD)/cache_as_ram_auto.c option_table.h" + action "$(CC) $(DISTRO_CFLAGS) -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/cache_as_ram_auto.c -Os -nostdinc -nostdlib -fno-builtin -Wall -c -S -o $@" + action "perl -e 's/.rodata/.rom.data/g' -pi $@" + action "perl -e 's/.text/.section .rom.text/g' -pi $@" + end + end +end +mainboardinit cpu/via/16bit/entry16.inc +ldscript /cpu/via/16bit/entry16.lds + +mainboardinit northbridge/via/vx800/romstrap.inc +ldscript /northbridge/via/vx800/romstrap.lds + +mainboardinit cpu/x86/32bit/entry32.inc +ldscript /cpu/x86/32bit/entry32.lds +if USE_FALLBACK_IMAGE + mainboardinit cpu/x86/16bit/reset16.inc + ldscript /cpu/x86/16bit/reset16.lds +else + mainboardinit cpu/x86/32bit/reset32.inc + ldscript /cpu/x86/32bit/reset32.lds +end + +#mainboardinit arch/i386/lib/cpu_reset.inc +#here cpu_reset.inc have label _cpu_reset, which is needed in failover,c, but cpu_reset.inc also has code to jump to __main() which is not included in cache_as_ram_auto_auto.c + + +mainboardinit arch/i386/lib/id.inc +ldscript /arch/i386/lib/id.lds + +if USE_DCACHE_RAM + mainboardinit cpu/via/car/cache_as_ram.inc +end + +if USE_FALLBACK_IMAGE + ldscript /arch/i386/lib/failover.lds +# failover.inc need defination in cpu_reset.inc, but we do not include cpu_reset.inc,so ... +# mainboardinit ./failover.inc +end +#mainboardinit cpu/x86/fpu/enable_fpu.inc +#mainboardinit cpu/x86/mmx/enable_mmx.inc + + +if USE_DCACHE_RAM + if CONFIG_USE_INIT + initobject cache_as_ram_auto.o + else + mainboardinit ./cache_as_ram_auto.inc + end +end + +#mainboardinit cpu/x86/mmx/disable_mmx.inc +dir /pc80 + +config chip.h + + +chip northbridge/via/vx800 # Northbridge + device pci_domain 0 on + device pci 0.0 on end # AGP Bridge + device pci 0.1 on end # Error Reporting + device pci 0.2 on end # Host Bus Control + device pci 0.3 on end # Memory Controller + device pci 0.4 on end # Power Management + device pci 0.7 on end # V-Link Controller + device pci 1.0 on end # PCI Bridge + #device pci f.0 on end # IDE/SATA + #device pci f.1 on end # IDE + #device pci 10.0 on end # USB 1.1 + #device pci 10.1 on end # USB 1.1 + #device pci 10.2 on end # USB 1.1 + #device pci 10.4 on end # USB 2.0 + #device pci 11.0 on # Southbridge LPC + #end # pci 11.0 + + end # pci domain 0 + device apic_cluster 0 on # APIC cluster + chip cpu/via/model_c7 # VIA C7 + device apic 0 on end # APIC + end + end +end # vx800 Index: src/mainboard/via/epia-m700/irq_tables.c =================================================================== --- src/mainboard/via/epia-m700/irq_tables.c (revision 0) +++ src/mainboard/via/epia-m700/irq_tables.c (revision 0) @@ -0,0 +1,58 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2009 One Laptop per Child, Association, Inc. + * + * 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 + */ + +#ifdef GETPIR +#include "pirq_routing.h" +#else +#include <arch/pirq_routing.h> +#endif + +const struct irq_routing_table intel_irq_routing_table = { + PIRQ_SIGNATURE, /* u32 signature */ + PIRQ_VERSION, /* u16 version */ + 32+16*14, /* There can be total 14 devices on the bus */ + 0x00, /* Where the interrupt router lies (bus) */ + (0x11<<3)|0x0, /* Where the interrupt router lies (dev) */ + 0xc20, /* IRQs devoted exclusively to PCI usage */ + 0x1106, /* Vendor */ + 0x8409, /* Device */ + 0, /* Crap (miniport) */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */ + 0xc6, /* u8 checksum. This has to be set to some + //0xa0?? 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,(0x01<<3)|0x0, {{0x01, 0xdeb8}, {0x00, 0xdeb8}, {0x00, 0xdeb8}, {0x00, 0x0deb8}}, 0x0, 0x0}, + {0x00,(0x08<<3)|0x0, {{0x01, 0xdeb8}, {0x01, 0xdeb8}, {0x01, 0xdeb8}, {0x01, 0x0deb8}}, 0x1, 0x0}, + {0x00,(0x0b<<3)|0x0, {{0x01, 0xdeb8}, {0x00, 0xdeb8}, {0x00, 0xdeb8}, {0x00, 0x0deb8}}, 0x0, 0x0}, + {0x00,(0x0c<<3)|0x0, {{0x01, 0xdeb8}, {0x00, 0xdeb8}, {0x00, 0xdeb8}, {0x00, 0x0deb8}}, 0x0, 0x0}, + {0x00,(0x0d<<3)|0x0, {{0x02, 0xdeb8}, {0x00, 0xdeb8}, {0x00, 0xdeb8}, {0x00, 0x0deb8}}, 0x0, 0x0}, + {0x00,(0x0e<<3)|0x0, {{0x03, 0xdeb8}, {0x00, 0xdeb8}, {0x00, 0xdeb8}, {0x00, 0x0deb8}}, 0x0, 0x0}, + {0x00,(0x0f<<3)|0x0, {{0x02, 0xdeb8}, {0x00, 0xdeb8}, {0x00, 0xdeb8}, {0x00, 0x0deb8}}, 0x0, 0x0}, + {0x00,(0x10<<3)|0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x04, 0x0deb8}}, 0x0, 0x0}, + {0x00,(0x14<<3)|0x0, {{0x02, 0xdeb8}, {0x00, 0xdeb8}, {0x00, 0xdeb8}, {0x00, 0x0deb8}}, 0x0, 0x0}, + } +}; + +inline unsigned long write_pirq_routing_table(unsigned long addr) +{ + return copy_pirq_routing_table(addr); +} Index: src/mainboard/via/epia-m700/chip.h =================================================================== --- src/mainboard/via/epia-m700/chip.h (revision 0) +++ src/mainboard/via/epia-m700/chip.h (revision 0) @@ -0,0 +1,25 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2009 One Laptop per Child, Association, Inc. + * + * 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 + */ + +extern struct chip_operations mainboard_ops; + +struct mainboard_config { + int nothing; +}; Index: src/mainboard/via/epia-m700/mainboard.c =================================================================== --- src/mainboard/via/epia-m700/mainboard.c (revision 0) +++ src/mainboard/via/epia-m700/mainboard.c (revision 0) @@ -0,0 +1,26 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) One Laptop per Child, Association, Inc. + * + * 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 <device/device.h> +#include "chip.h" + +struct chip_operations mainboard_ops = { + CHIP_NAME("epia-m700 Mainboard") +}; Index: src/mainboard/via/epia-m700/wakeup.c =================================================================== --- src/mainboard/via/epia-m700/wakeup.c (revision 0) +++ src/mainboard/via/epia-m700/wakeup.c (revision 0) @@ -0,0 +1,445 @@ +/* + * This file is part of the coreboot project. + * Copyright (C) 2008 Rudolf Marek r.marek@assembler.cz + * Copyright (C) 2009 One Laptop per Child, Association, Inc. + * + * 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 + */ + //reboot.c from linux +/*this file mostly copied from Rudolf's S3 patch, some changes in acpi_jump_wake()*/ +#include <stdint.h> +#include <string.h> +#include <arch/io.h> +#include <console/console.h> +#include <delay.h> +#include <part/init_timer.h>//for jaon_tsc_count_end +#include "wakeup.h" + + + + +int enable_a20(void); + +/* The following code and data reboots the machine by switching to real + mode and jumping to the BIOS reset entry point, as if the CPU has + really been reset. The previous version asked the keyboard + controller to pulse the CPU reset line, which is more thorough, but + doesn't work with at least one type of 486 motherboard. It is easy + to stop this code working; hence the copious comments. */ + +static unsigned long long +real_mode_gdt_entries [3] = +{ + 0x0000000000000000ULL, /* Null descriptor */ + 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */ + 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */ +}; + +struct Xgt_desc_struct { + unsigned short size; + unsigned long address __attribute__((packed)); + unsigned short pad; + } __attribute__ ((packed)); + +static struct Xgt_desc_struct +real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries }, +real_mode_idt = { 0x3ff, 0 }, +no_idt = { 0, 0 }; + + +/* This is 16-bit protected mode code to disable paging and the cache, + switch to real mode and jump to the BIOS reset code. + + The instruction that switches to real mode by writing to CR0 must be + followed immediately by a far jump instruction, which set CS to a + valid value for real mode, and flushes the prefetch queue to avoid + running instructions that have already been decoded in protected + mode. + + Clears all the flags except ET, especially PG (paging), PE + (protected-mode enable) and TS (task switch for coprocessor state + save). Flushes the TLB after paging has been disabled. Sets CD and + NW, to disable the cache on a 486, and invalidates the cache. This + is more like the state of a 486 after reset. I don't know if + something else should be done for other chips. + + More could be done here to set up the registers as if a CPU reset had + occurred; hopefully real BIOSs don't assume much. */ + + +// 0x66, 0x0d, 0x00, 0x00, 0x00, 0x60, /* orl $0x60000000,%eax */ + +static unsigned char real_mode_switch [] = +{ + 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */ + 0x24, 0xfe, /* andb $0xfe,al */ + 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */ +}; +static unsigned char jump_to_wakeup [] = +{ + 0xea, 0x00, 0x00, 0x00, 0xe0 /* ljmp $0xffff,$0x0000 */ +}; + +/* + * Switch to real mode and then execute the code + * specified by the code and length parameters. + * We assume that length will aways be less that 100! + */ +static unsigned char show31 [6] = +{ + 0xb0, 0x31, 0xe6, 0x80, 0xeb ,0xFA /* ljmp $0xffff,$0x0000 */ +}; +static unsigned char show32 [6] = +{ + 0xb0, 0x32, 0xe6, 0x80, 0xeb ,0xFA /* ljmp $0xffff,$0x0000 */ +}; +void acpi_jump_wake(u32 vector) +{ +u32 tmp; +u16 tmpvector; +u32 dwEip; +u8 Data; +struct Xgt_desc_struct * wake_thunk16_Xgt_desc; + + printk_debug("IN ACPI JUMP WAKE TO %x\n", vector); + if (enable_a20()) + die("failed to enable A20\n"); + printk_debug("IN ACPI JUMP WAKE TO 3 %x\n", vector); + + * ((u16 *) (jump_to_wakeup+3)) = (u16)(vector>>4); + printk_debug("%x %x %x %x %x\n", jump_to_wakeup[0], jump_to_wakeup[1], jump_to_wakeup[2], jump_to_wakeup[3],jump_to_wakeup[4]); + + memcpy ((void *) (WAKE_THUNK16_ADDR - sizeof (real_mode_switch) - 100), + real_mode_switch, sizeof (real_mode_switch)); + memcpy ((void *) (WAKE_THUNK16_ADDR - 100), jump_to_wakeup, sizeof(jump_to_wakeup)); + + jason_tsc_count(); + printk_emerg("file '%s', line %d\n\n", __FILE__, __LINE__); + jason_tsc_count_end(); + + + unsigned long long * real_mode_gdt_entries_at_eseg; + real_mode_gdt_entries_at_eseg=WAKE_THUNK16_GDT; //copy from real_mode_gdt_entries and change limition to 1M and data base to 0; + real_mode_gdt_entries_at_eseg [0] = 0x0000000000000000ULL; /* Null descriptor */ + real_mode_gdt_entries_at_eseg [1] = 0x000f9a000000ffffULL; /* 16-bit real-mode 1M code at 0x00000000 */ + real_mode_gdt_entries_at_eseg [2] = 0x000f93000000ffffULL; /* 16-bit real-mode 1M data at 0x00000000 */ + + wake_thunk16_Xgt_desc=WAKE_THUNK16_XDTR; + wake_thunk16_Xgt_desc[0].size=sizeof (real_mode_gdt_entries) - 1; + wake_thunk16_Xgt_desc[0].address=(long)real_mode_gdt_entries_at_eseg; + wake_thunk16_Xgt_desc[1].size=0x3ff; + wake_thunk16_Xgt_desc[1].address=0; + wake_thunk16_Xgt_desc[2].size=0; + wake_thunk16_Xgt_desc[2].address=0; + + /*added this code to get current value of EIP + */ + __asm__ volatile ( + "calll geip\n\t" + "geip: \n\t" + "popl %0\n\t" + :"=a"(dwEip) + ); + + unsigned char *dest; + unsigned char *src; + src= (unsigned char *)dwEip; + dest=WAKE_RECOVER1M_CODE; + u32 i; + for (i = 0; i < 0x200; i++) + dest[i] = src[i]; + + __asm__ __volatile__ ("ljmp $0x0010,%0"//08 error + : + : "i" ((void *) (WAKE_RECOVER1M_CODE+0x20))); + + /*added 0x20 "nop" to make sure the ljmp will not jump then halt*/ + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + asm volatile("nop"); + + + __asm__ volatile ( + /* set new esp, maybe ebp should not equal to esp?, + due to the variable in acpi_jump_wake?, anyway, this may be not a big problem. + and I didnt clear the area (ef000+-0x200) to zero. + */ + "movl %0, %%ebp\n\t" + "movl %0, %%esp\n\t" + ::"a"(WAKE_THUNK16_STACK) + ); + + + /* added this + only "src" and "dest" use the new stack, and the esp maybe also used in resumevector + */ +#if PAYLOAD_IS_SEABIOS==1 + // WAKE_MEM_INFO inited in get_set_top_available_mem in tables.c + src = (unsigned char *)((* (u32*)WAKE_MEM_INFO)- 64*1024-0x100000); + dest = 0; + for (i = 0; i < 0xa0000; i++)//if recovered 0-e0000, then when resume, before winxp turn on the desktop screen ,there is gray background which last 1sec. + dest[i] = src[i]; + /*__asm__ volatile ( + "movl %0, %%esi\n\t" + "movl $0, %%edi\n\t" + "movl $0xa0000, %%ecx\n\t" + "shrl $2, %%ecx\n\t" + "rep movsd\n\t" + ::"a"(src) + );*/ + src = (unsigned char *)((* (u32*)WAKE_MEM_INFO)- 64*1024-0x100000+0xc0000); + //dest = 0xc0000; + //for (i = 0; i < 0x20000; i++) + // dest[i] = src[i]; + /* __asm__ volatile ( + "movl %0, %%esi\n\t" + "movl $0xc0000, %%edi\n\t" + "movl $0x20000, %%ecx\n\t" + "shrl $2, %%ecx\n\t" + "rep movsd\n\t" + ::"a"(src) + );*/ + + + src = (unsigned char *)((* (u32*)WAKE_MEM_INFO)- 64*1024-0x100000+0xe0000+WAKE_SPECIAL_SIZE); + //dest = 0xf0000; + //for (i = 0; i < 0x10000; i++) + // dest[i] = src[i]; + __asm__ volatile ( + "movl %0, %%esi\n\t" + "movl %1, %%edi\n\t" + "movl %2, %%ecx\n\t" + "shrl $2, %%ecx\n\t" + "rep movsd\n\t" + ::"r"(src),"r"(0xe0000+WAKE_SPECIAL_SIZE), "r"(0x10000-WAKE_SPECIAL_SIZE) + ); + + src = (unsigned char *)((* (u32*)WAKE_MEM_INFO)- 64*1024-0x100000+0xf0000); + //dest = 0xf0000; + //for (i = 0; i < 0x10000; i++) + // dest[i] = src[i]; + __asm__ volatile ( + "movl %0, %%esi\n\t" + "movl $0xf0000, %%edi\n\t" + "movl $0x10000, %%ecx\n\t" + "shrl $2, %%ecx\n\t" + "rep movsd\n\t" + ::"a"(src) + ); + + asm volatile("wbinvd"); +#endif + /* Set up the IDT for real mode. */ + asm volatile("lidt %0"::"m" (wake_thunk16_Xgt_desc[1])); + + /* Set up a GDT from which we can load segment descriptors for real + mode. The GDT is not used in real mode; it is just needed here to + prepare the descriptors. */ + asm volatile("lgdt %0"::"m" (wake_thunk16_Xgt_desc[0])); + + /* Load the data segment registers, and thus the descriptors ready for + real mode. The base address of each segment is 0x100, 16 times the + selector value being loaded here. This is so that the segment + registers don't have to be reloaded after switching to real mode: + the values are consistent for real mode operation already. */ + + __asm__ __volatile__ ("movl $0x0010,%%eax\n" + "\tmovl %%eax,%%ds\n" + "\tmovl %%eax,%%es\n" + "\tmovl %%eax,%%fs\n" + "\tmovl %%eax,%%gs\n" + "\tmovl %%eax,%%ss" : : : "eax"); + + /* Jump to the 16-bit code that we copied earlier. It disables paging + and the cache, switches to real mode, and jumps to the BIOS reset + entry point. */ + + __asm__ __volatile__ ("ljmp $0x0008,%0" + : + : "i" ((void *) (WAKE_THUNK16_ADDR - sizeof (real_mode_switch) - 100))); +} + + +/* -*- linux-c -*- ------------------------------------------------------- * + * + * Copyright (C) 1991, 1992 Linus Torvalds + * Copyright 2007 rPath, Inc. - All Rights Reserved + * + * This file is part of the Linux kernel, and is made available under + * the terms of the GNU General Public License version 2. + * + * ----------------------------------------------------------------------- */ + +/* + * arch/i386/boot/a20.c + * + * Enable A20 gate (return -1 on failure) + */ + +//#include "boot.h" + +#define MAX_8042_LOOPS 100000 + +static int empty_8042(void) +{ + u8 status; + int loops = MAX_8042_LOOPS; + + while (loops--) { + udelay(1); + + status = inb(0x64); + if (status & 1) { + /* Read and discard input data */ + udelay(1); + (void)inb(0x60); + } else if (!(status & 2)) { + /* Buffers empty, finished! */ + return 0; + } + } + + return -1; +} + +/* Returns nonzero if the A20 line is enabled. The memory address + used as a test is the int $0x80 vector, which should be safe. */ + +#define A20_TEST_ADDR (4*0x80) +#define A20_TEST_SHORT 32 +#define A20_TEST_LONG 2097152 /* 2^21 */ + +static int a20_test(int loops) +{ + int ok = 0; + int saved, ctr; + +// set_fs(0x0000); +// set_gs(0xffff); + + saved = ctr = *((u32*) A20_TEST_ADDR); + + while (loops--) { + //wrfs32(++ctr, A20_TEST_ADDR); + + *((u32*) A20_TEST_ADDR) = ++ctr; + + udelay(1); /* Serialize and make delay constant */ + + ok = *((u32 *) A20_TEST_ADDR+0xffff0+0x10) ^ ctr; + if (ok) + break; + } + + *((u32*) A20_TEST_ADDR) = saved; + return ok; +} + +/* Quick test to see if A20 is already enabled */ +static int a20_test_short(void) +{ + return a20_test(A20_TEST_SHORT); +} + +/* Longer test that actually waits for A20 to come on line; this + is useful when dealing with the KBC or other slow external circuitry. */ +static int a20_test_long(void) +{ + return a20_test(A20_TEST_LONG); +} + +static void enable_a20_kbc(void) +{ + empty_8042(); + + outb(0xd1, 0x64); /* Command write */ + empty_8042(); + + outb(0xdf, 0x60); /* A20 on */ + empty_8042(); +} + +static void enable_a20_fast(void) +{ + u8 port_a; + + port_a = inb(0x92); /* Configuration port A */ + port_a |= 0x02; /* Enable A20 */ + port_a &= ~0x01; /* Do not reset machine */ + outb(port_a, 0x92); +} + +/* + * Actual routine to enable A20; return 0 on ok, -1 on failure + */ + +#define A20_ENABLE_LOOPS 255 /* Number of times to try */ + +int enable_a20(void) +{ + int loops = A20_ENABLE_LOOPS; + + while (loops--) { + /* First, check to see if A20 is already enabled + (legacy free, etc.) */ + if (a20_test_short()) + return 0; + + /* Try enabling A20 through the keyboard controller */ + empty_8042(); +//if (a20_test_short()) +// return 0; /* BIOS worked, but with delayed reaction */ + + enable_a20_kbc(); + if (a20_test_long()) + return 0; + + /* Finally, try enabling the "fast A20 gate" */ + enable_a20_fast(); + if (a20_test_long()) + return 0; + } + + return -1; +} Index: src/mainboard/via/epia-m700/cmos.layout =================================================================== --- src/mainboard/via/epia-m700/cmos.layout (revision 0) +++ src/mainboard/via/epia-m700/cmos.layout (revision 0) @@ -0,0 +1,74 @@ +entries + +#start-bit length config config-ID name +#0 8 r 0 seconds +#8 8 r 0 alarm_seconds +#16 8 r 0 minutes +#24 8 r 0 alarm_minutes +#32 8 r 0 hours +#40 8 r 0 alarm_hours +#48 8 r 0 day_of_week +#56 8 r 0 day_of_month +#64 8 r 0 month +#72 8 r 0 year +#80 4 r 0 rate_select +#84 3 r 0 REF_Clock +#87 1 r 0 UIP +#88 1 r 0 auto_switch_DST +#89 1 r 0 24_hour_mode +#90 1 r 0 binary_values_enable +#91 1 r 0 square-wave_out_enable +#92 1 r 0 update_finished_enable +#93 1 r 0 alarm_interrupt_enable +#94 1 r 0 periodic_interrupt_enable +#95 1 r 0 disable_clock_updates +#96 288 r 0 temporary_filler +0 384 r 0 reserved_memory +384 1 e 4 boot_option +385 1 e 4 last_boot +386 1 e 1 ECC_memory +388 4 r 0 reboot_bits +392 3 e 5 baud_rate +400 1 e 1 power_on_after_fail +412 4 e 6 debug_level +416 4 e 7 boot_first +420 4 e 7 boot_second +424 4 e 7 boot_third +428 4 h 0 boot_index +432 8 h 0 boot_countdown +1008 16 h 0 check_sum + +enumerations + +#ID value text +1 0 Disable +1 1 Enable +2 0 Enable +2 1 Disable +4 0 Fallback +4 1 Normal +5 0 115200 +5 1 57600 +5 2 38400 +5 3 19200 +5 4 9600 +5 5 4800 +5 6 2400 +5 7 1200 +6 6 Notice +6 7 Info +6 8 Debug +6 9 Spew +7 0 Network +7 1 HDD +7 2 Floppy +7 8 Fallback_Network +7 9 Fallback_HDD +7 10 Fallback_Floppy +#7 3 ROM + +checksums + +checksum 392 1007 1008 + +