mb/via/epia-m700: Remove board
Platforms with LATE_CBMEM_INIT were agreed to be removed with 4.7 release late 2017. Change-Id: I34f9bffcced5ccdd8691994b78fffed057021d0e Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: https://review.coreboot.org/26676 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
@@ -1,27 +0,0 @@
|
|||||||
if BOARD_VIA_EPIA_M700
|
|
||||||
|
|
||||||
config BOARD_SPECIFIC_OPTIONS # dummy
|
|
||||||
def_bool y
|
|
||||||
select CPU_VIA_C7
|
|
||||||
select NORTHBRIDGE_VIA_VX800
|
|
||||||
select SUPERIO_WINBOND_W83697HF
|
|
||||||
select HAVE_PIRQ_TABLE
|
|
||||||
# Note: For ACPI, you need to use the 'get_dsdt' script and uncomment
|
|
||||||
# the "select HAVE_ACPI_TABLES" line below.
|
|
||||||
# select HAVE_ACPI_TABLES
|
|
||||||
select HAVE_OPTION_TABLE
|
|
||||||
select BOARD_ROMSIZE_KB_512
|
|
||||||
|
|
||||||
config MAINBOARD_DIR
|
|
||||||
string
|
|
||||||
default via/epia-m700
|
|
||||||
|
|
||||||
config MAINBOARD_PART_NUMBER
|
|
||||||
string
|
|
||||||
default "EPIA-M700"
|
|
||||||
|
|
||||||
config IRQ_SLOT_COUNT
|
|
||||||
int
|
|
||||||
default 13
|
|
||||||
|
|
||||||
endif # BOARD_VIA_EPIA_M700
|
|
@@ -1,2 +0,0 @@
|
|||||||
config BOARD_VIA_EPIA_M700
|
|
||||||
bool "EPIA-M700"
|
|
@@ -1,96 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Most parts of this file copied from 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 u32 wake_vec;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* These four macros are copied from <arch/smp/mpspec.h>, I have to do this
|
|
||||||
* since the "CONFIG_GENERATE_MP_TABLE = 0", and also since
|
|
||||||
* mainboard/via/... have no mptable.c (so that I can not set
|
|
||||||
* "CONFIG_GENERATE_MP_TABLE = 1" as many other mainboards.
|
|
||||||
* So I have to copy these four to here. acpi_fill_madt() needs 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_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_CPU_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)
|
|
||||||
{
|
|
||||||
/* 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;
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
Category: mini
|
|
||||||
Board URL: http://www.viaembedded.com/en/products/boards/670/1/EPIA-M700_%28EOL%29.html
|
|
||||||
ROM package: SOIC8
|
|
||||||
ROM protocol: SPI
|
|
||||||
ROM socketed: n
|
|
||||||
Flashrom support: y
|
|
||||||
Release year: 2008
|
|
@@ -1,28 +0,0 @@
|
|||||||
entries
|
|
||||||
|
|
||||||
0 384 r 0 reserved_memory
|
|
||||||
384 1 e 4 boot_option
|
|
||||||
388 4 h 0 reboot_counter
|
|
||||||
#392 3 r 0 unused
|
|
||||||
400 1 e 1 power_on_after_fail
|
|
||||||
412 4 e 6 debug_level
|
|
||||||
456 1 e 1 ECC_memory
|
|
||||||
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
|
|
||||||
6 5 Notice
|
|
||||||
6 6 Info
|
|
||||||
6 7 Debug
|
|
||||||
6 8 Spew
|
|
||||||
|
|
||||||
checksums
|
|
||||||
|
|
||||||
checksum 392 1007 1008
|
|
@@ -1,24 +0,0 @@
|
|||||||
chip northbridge/via/vx800 # Northbridge
|
|
||||||
device 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
|
|
||||||
end
|
|
||||||
device cpu_cluster 0 on # APIC cluster
|
|
||||||
chip cpu/via/c7 # VIA C7
|
|
||||||
device lapic 0 on end # APIC
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@@ -1,233 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "northbridge/via/vx800/driving_clk_phase_data.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't be disabled, 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 */
|
|
||||||
#if 0
|
|
||||||
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 },
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
#if 0
|
|
||||||
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 },
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* 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},
|
|
||||||
};
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
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 },
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 */
|
|
||||||
#if 0
|
|
||||||
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 }
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
};
|
|
@@ -1,167 +0,0 @@
|
|||||||
/*
|
|
||||||
* ACPI - create the Fixed ACPI Description Tables (FADT)
|
|
||||||
*
|
|
||||||
* Copyright (C) 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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 = 3;
|
|
||||||
memcpy(header->oem_id, OEM_ID, 6);
|
|
||||||
memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
|
|
||||||
memcpy(header->asl_compiler_id, ASLC, 4);
|
|
||||||
header->asl_compiler_revision = 0;
|
|
||||||
|
|
||||||
fadt->firmware_ctrl = (u32)facs;
|
|
||||||
fadt->dsdt = (u32)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 don't 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 = (u32)facs;
|
|
||||||
fadt->x_firmware_ctl_h = 0;
|
|
||||||
fadt->x_dsdt_l = (u32)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));
|
|
||||||
}
|
|
@@ -1,39 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
##
|
|
||||||
## 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.
|
|
||||||
##
|
|
||||||
|
|
||||||
# Simple script to dump the factory ACPI DSDT and convert it to C.
|
|
||||||
# Must 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
|
|
@@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <arch/pirq_routing.h>
|
|
||||||
|
|
||||||
static const struct irq_routing_table intel_irq_routing_table = {
|
|
||||||
PIRQ_SIGNATURE, /* u32 signature */
|
|
||||||
PIRQ_VERSION, /* u16 version */
|
|
||||||
32 + 16 * CONFIG_IRQ_SLOT_COUNT,/* Max. number of devices on the bus */
|
|
||||||
0x00, /* Where the interrupt router lies (bus) */
|
|
||||||
(0x11 << 3) | 0x0, /* Where the interrupt router lies (dev) */
|
|
||||||
0xca0, /* IRQs devoted exclusively to PCI usage */
|
|
||||||
0x1106, /* Vendor */
|
|
||||||
0x596, /* Device */
|
|
||||||
0, /* Miniport */
|
|
||||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* u8 rfu[11] */
|
|
||||||
0xdb, /* Checksum. 0xa0? */
|
|
||||||
{
|
|
||||||
/* bus, dev | fn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */
|
|
||||||
{0x00, (0x02 << 3) | 0x0, {{0x09, 0xdeb8}, {0x09, 0xdeb8}, {0x09, 0xdeb8}, {0x09, 0xdeb8}}, 0x1, 0x0},
|
|
||||||
{0x00, (0x03 << 3) | 0x0, {{0x09, 0xdeb8}, {0x09, 0xdeb8}, {0x09, 0xdeb8}, {0x09, 0xdeb8}}, 0x2, 0x0},
|
|
||||||
{0x00, (0x03 << 3) | 0x1, {{0x09, 0xdeb8}, {0x09, 0xdeb8}, {0x09, 0xdeb8}, {0x09, 0xdeb8}}, 0x3, 0x0},
|
|
||||||
{0x04, (0x04 << 3) | 0x0, {{0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x05, 0xdeb8}, {0x01, 0xdeb8}}, 0x4, 0x0},
|
|
||||||
{0x04, (0x0e << 3) | 0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x05, 0xdeb8}}, 0x5, 0x0},
|
|
||||||
{0x00, (0x11 << 3) | 0x0, {{0x00, 0xdeb8}, {0x00, 0xdeb8}, {0x03, 0xdeb8}, {0x05, 0xdeb8}}, 0x0, 0x0},
|
|
||||||
{0x00, (0x0f << 3) | 0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x05, 0xdeb8}}, 0x0, 0x0},
|
|
||||||
{0x00, (0x01 << 3) | 0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x05, 0xdeb8}}, 0x0, 0x0},
|
|
||||||
{0x00, (0x10 << 3) | 0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x05, 0xdeb8}}, 0x0, 0x0},
|
|
||||||
{0x00, (0x02 << 3) | 0x0, {{0x09, 0xdeb8}, {0x09, 0xdeb8}, {0x09, 0xdeb8}, {0x09, 0xdeb8}}, 0x0, 0x0},
|
|
||||||
{0x00, (0x03 << 3) | 0x0, {{0x09, 0xdeb8}, {0x09, 0xdeb8}, {0x09, 0xdeb8}, {0x09, 0xdeb8}}, 0x0, 0x0},
|
|
||||||
{0x00, (0x03 << 3) | 0x1, {{0x09, 0xdeb8}, {0x09, 0xdeb8}, {0x09, 0xdeb8}, {0x09, 0xdeb8}}, 0x0, 0x0},
|
|
||||||
{0x00, (0x14 << 3) | 0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x05, 0xdeb8}}, 0x0, 0x0},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline unsigned long write_pirq_routing_table(unsigned long addr)
|
|
||||||
{
|
|
||||||
return copy_pirq_routing_table(addr, &intel_irq_routing_table);
|
|
||||||
}
|
|
@@ -1,656 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 PAYLOAD_IS_SEABIOS 0
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <device/pci_def.h>
|
|
||||||
#include <device/pci_ids.h>
|
|
||||||
#include <arch/acpi.h>
|
|
||||||
#include <arch/io.h>
|
|
||||||
#include <device/pnp_def.h>
|
|
||||||
#include <console/console.h>
|
|
||||||
#include <lib.h>
|
|
||||||
#include <northbridge/via/vx800/vx800.h>
|
|
||||||
#include <cpu/x86/bist.h>
|
|
||||||
#include <delay.h>
|
|
||||||
#include <string.h>
|
|
||||||
/* This file contains the board-special SI value for raminit.c. */
|
|
||||||
#include "driving_clk_phase_data.c"
|
|
||||||
#include <northbridge/via/vx800/raminit.h>
|
|
||||||
#include "northbridge/via/vx800/raminit.c"
|
|
||||||
#include "wakeup.h"
|
|
||||||
#include <superio/winbond/common/winbond.h>
|
|
||||||
#include <superio/winbond/w83697hf/w83697hf.h>
|
|
||||||
|
|
||||||
#define SERIAL_DEV PNP_DEV(0x2e, W83697HF_SP1)
|
|
||||||
#define SUPERIO_DEV PNP_DEV(0x2e, 0)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This acpi_is_wakeup_early_via_VX800 is from Rudolf's patch on the list:
|
|
||||||
* https://www.coreboot.org/pipermail/coreboot/2008-January/028787.html.
|
|
||||||
*/
|
|
||||||
static int acpi_is_wakeup_early_via_vx800(void)
|
|
||||||
{
|
|
||||||
pci_devfn_t dev;
|
|
||||||
u16 tmp, result;
|
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "In acpi_is_wakeup_early_via_vx800\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\n");
|
|
||||||
|
|
||||||
/* Set ACPI base address to I/O VX800_ACPI_IO_BASE. */
|
|
||||||
pci_write_config16(dev, 0x88, VX800_ACPI_IO_BASE | 0x1);
|
|
||||||
|
|
||||||
/* Enable ACPI access 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;
|
|
||||||
printk(BIOS_DEBUG, " boot_mode=%04x\n", result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* All content of this function came from the cx700 port of coreboot. */
|
|
||||||
static void enable_mainboard_devices(void)
|
|
||||||
{
|
|
||||||
pci_devfn_t dev;
|
|
||||||
#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.
|
|
||||||
*
|
|
||||||
* Internal Config is needed to decide which key can be pressed to
|
|
||||||
* resume from s3.
|
|
||||||
*/
|
|
||||||
pci_write_config8(dev, 0x51, 0x2d);
|
|
||||||
|
|
||||||
/* This causes irq0 can not be triggerd, since bit 5 was set to 0. */
|
|
||||||
/* pci_write_config8(dev, 0x58, 0x42); */
|
|
||||||
|
|
||||||
/* These writing may... TODO */
|
|
||||||
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
|
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "In enable_mainboard_devices\n");
|
|
||||||
|
|
||||||
/* Enable P2P Bridge Header for external PCI bus. */
|
|
||||||
dev = pci_locate_device(PCI_ID(0x1106, 0xa353), 0);
|
|
||||||
pci_write_config8(dev, 0x4f, 0x41);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "5324" already is the default value of the PCI IDE device, cancel
|
|
||||||
* this PCI write.
|
|
||||||
*
|
|
||||||
* [william 20080124]: Fix bug that can not boot Ubuntu at the
|
|
||||||
* beginning time.
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
dev = 0;
|
|
||||||
dev = pci_locate_device(PCI_ID(0x1106, PCI_DEVICE_ID_VIA_VX855_IDE), 0);
|
|
||||||
|
|
||||||
uint16_t values;
|
|
||||||
values = pci_read_config16(dev, 0xBA);
|
|
||||||
values &= ~0xffff;
|
|
||||||
values |= 0x5324;
|
|
||||||
pci_write_config16(dev, 0xBA, values);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 PCI-E */
|
|
||||||
{ 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
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void EmbedComInit(void)
|
|
||||||
{
|
|
||||||
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 I/O 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);
|
|
||||||
if (USE_VCP == 1)
|
|
||||||
ByteVal = (ByteVal & 0x3F) | 0x40; /* Multiplex with VCP. */
|
|
||||||
else
|
|
||||||
ByteVal = (ByteVal & 0x3F) | 0xC0; /* Multiplex with DVP. */
|
|
||||||
pci_write_config8(PCI_DEV(0, 17, 0), 0x46, ByteVal);
|
|
||||||
|
|
||||||
/* Enable embedded 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 embedded COM1 I/O 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 embedded COM2 I/O 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 BAUD rate. */
|
|
||||||
ByteVal = inb(ComBase + 3);
|
|
||||||
outb(ByteVal | 0x80, ComBase + 3);
|
|
||||||
outb(0x01, ComBase);
|
|
||||||
outb(0x00, ComBase + 1);
|
|
||||||
|
|
||||||
/* Set frame format. */
|
|
||||||
ByteVal = inb(ComBase + 3);
|
|
||||||
outb(ByteVal & 0x3F, ComBase + 3);
|
|
||||||
outb(0x03, ComBase + 3);
|
|
||||||
outb(0x00, ComBase + 2);
|
|
||||||
outb(0x00, ComBase + 4);
|
|
||||||
|
|
||||||
/* SOutput("Embedded COM output\n"); */
|
|
||||||
/* while (1); */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* cache_as_ram.inc jumps to here. */
|
|
||||||
void main(unsigned long bist)
|
|
||||||
{
|
|
||||||
u16 boot_mode;
|
|
||||||
u8 rambits, Data8, Data;
|
|
||||||
pci_devfn_t device;
|
|
||||||
/* 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(); */
|
|
||||||
winbond_set_clksel_48(SUPERIO_DEV);
|
|
||||||
winbond_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
|
|
||||||
/* enable_vx800_serial(); */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* There are two function definitions of console_init(), while the
|
|
||||||
* src/arch/x86/lib is the right one.
|
|
||||||
*/
|
|
||||||
console_init();
|
|
||||||
|
|
||||||
/* 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".
|
|
||||||
*/
|
|
||||||
if ((boot_mode != 3)
|
|
||||||
&& (pci_read_config8(PCI_DEV(0, 0, 3), 0x80) != 0)) {
|
|
||||||
outb(6, 0xcf9);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* x86 cold boot I/O cmd. */
|
|
||||||
/* These 2 lines are the same with epia-cn port. */
|
|
||||||
enable_smbus();
|
|
||||||
|
|
||||||
/* This fix does help vx800!, but vx855 doesn't need this. */
|
|
||||||
/* smbus_fixup(ctrl.channel0, ARRAY_SIZE(ctrl.channel0)); */
|
|
||||||
|
|
||||||
/* Halt if there was a built-in self test failure. */
|
|
||||||
report_bist_failure(bist);
|
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "Enabling mainboard devices\n");
|
|
||||||
enable_mainboard_devices();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
printk(BIOS_DEBUG, "NB chip revision = %02x\n", Data);
|
|
||||||
|
|
||||||
/* Make NB ready before DRAM init. */
|
|
||||||
via_pci_inittable(Data, mNbStage1InitTbl);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* When resume from s3, DRAM init is skipped, so need to recovery
|
|
||||||
* any PCI register related to DRAM init. d0f3 didn't 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;
|
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "This is an S3 wakeup\n");
|
|
||||||
|
|
||||||
memset(&DramAttr, 0, sizeof(DRAM_SYS_ATTR));
|
|
||||||
/*
|
|
||||||
* Step 1: 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);
|
|
||||||
|
|
||||||
/* Just copy this function from draminit to here! */
|
|
||||||
DRAMRegFinalValue(&DramAttr);
|
|
||||||
|
|
||||||
/* Just copy this function from draminit to here! */
|
|
||||||
SetUMARam();
|
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "Resume from S3, RAM init was ignored\n");
|
|
||||||
} else {
|
|
||||||
ddr2_ram_setup();
|
|
||||||
ram_check(0, 640 * 1024);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ddr2_ram_setup(); */
|
|
||||||
/* This line is the same with cx700 port. */
|
|
||||||
enable_shadow_ram();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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
|
|
||||||
* https://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 memory 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 this 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;
|
|
||||||
#if 0
|
|
||||||
__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"
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
__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)
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
/* This can have function call, because no variable used before this. */
|
|
||||||
printk(BIOS_DEBUG, "Copy memory to high memory to protect s3 wakeup vector code\n");
|
|
||||||
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. */
|
|
||||||
#if 0
|
|
||||||
__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
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
@@ -1,448 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* FIXME This code should be dropped and instead the generic resume code
|
|
||||||
* should be used.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Parts of this code is taken from reboot.c from Linux. */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file mostly copied from Rudolf's S3 patch, some changes in
|
|
||||||
* acpi_jump_wake().
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <compiler.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <arch/io.h>
|
|
||||||
#include <console/console.h>
|
|
||||||
#include <delay.h>
|
|
||||||
#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 __packed;
|
|
||||||
unsigned short pad;
|
|
||||||
} __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 */
|
|
||||||
};
|
|
||||||
|
|
||||||
void acpi_jump_wake(u32 vector)
|
|
||||||
{
|
|
||||||
u32 dwEip;
|
|
||||||
struct Xgt_desc_struct *wake_thunk16_Xgt_desc;
|
|
||||||
|
|
||||||
printk(BIOS_DEBUG, "IN ACPI JUMP WAKE TO %x\n", vector);
|
|
||||||
if (enable_a20())
|
|
||||||
die("failed to enable A20\n");
|
|
||||||
printk(BIOS_DEBUG, "IN ACPI JUMP WAKE TO 3 %x\n", vector);
|
|
||||||
|
|
||||||
*((u16 *) (jump_to_wakeup + 3)) = (u16) (vector >> 4);
|
|
||||||
printk(BIOS_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(BIOS_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 = (void *)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 = (void *)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, *src;
|
|
||||||
src = (unsigned char *)dwEip;
|
|
||||||
dest = (void *)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 didn't clear the area (ef000+-0x200) to zero.
|
|
||||||
*/
|
|
||||||
"movl %0, %%ebp\n\t"
|
|
||||||
"movl %0, %%esp\n\t"::"a" (WAKE_THUNK16_STACK)
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If recovered 0-e0000, then when resume, before WinXP turn on the
|
|
||||||
* desktop screen, there is gray background which last 1sec.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < 0xa0000; i++)
|
|
||||||
dest[i] = src[i];
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
__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)
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
src = (unsigned char *)((*(u32 *) WAKE_MEM_INFO) - 64 * 1024
|
|
||||||
- 0x100000 + 0xc0000);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
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)
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
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/x86/boot/a20.c
|
|
||||||
*
|
|
||||||
* Enable A20 gate (return -1 on failure)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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;
|
|
||||||
|
|
||||||
saved = ctr = *((u32 *) A20_TEST_ADDR);
|
|
||||||
|
|
||||||
while (loops--) {
|
|
||||||
|
|
||||||
*((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;
|
|
||||||
}
|
|
@@ -1,29 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#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
|
|
Reference in New Issue
Block a user