epia-m support

git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1655 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Ronald G. Minnich 2004-10-06 17:33:54 +00:00
parent 4fa89208a1
commit 02fa3b2743
32 changed files with 1945 additions and 405 deletions

View File

@ -3,6 +3,10 @@
* written by Stefan Reinauer <stepan@openbios.org>
* (C) 2004 SUSE LINUX AG
*/
/* ACPI FADT, FACS, and DSDT table support added by
* Nick Barker <nick.barker9@btinternet.com>, and those portions
* (C) Copyright 2004 Nick Barker
*/
#include <console/console.h>
#include <string.h>
@ -22,7 +26,15 @@
#define OEM_ID "LXBIOS"
#define ASLC "NONE"
static u8 acpi_checksum(u8 *table, u32 length)
// FIX ME - define needs declaring / setting in Config files
#define HAVE_ACPI_FADT
#ifdef HAVE_ACPI_FADT
extern unsigned char AmlCode[];
#endif
u8 acpi_checksum(u8 *table, u32 length)
{
u8 ret=0;
while (length--) {
@ -43,13 +55,15 @@ static void acpi_add_table(acpi_rsdt_t *rsdt, void *table)
for (i=0; i<8; i++) {
if(rsdt->entry[i]==0) {
rsdt->entry[i]=(u32)table;
/* fix length to stop kernel winging about invalid entries */
rsdt->header.length = sizeof(acpi_header_t) + (sizeof(u32) * (i+1));
/* fix checksum */
/* hope this won't get optimized away */
rsdt->header.checksum=0;
rsdt->header.checksum=acpi_checksum((u8 *)rsdt,
rsdt->header.length);
printk_debug("ACPI: added table %d/8\n",i+1);
printk_debug("ACPI: added table %d/8 Length now %d\n",i+1,rsdt->header.length);
return;
}
}
@ -181,6 +195,22 @@ static void acpi_create_hpet(acpi_hpet_t *hpet)
header->checksum = acpi_checksum((void *)hpet, sizeof(acpi_hpet_t));
}
static void acpi_create_facs(acpi_facs_t *facs)
{
memset( (void *)facs,0, sizeof(acpi_facs_t));
memcpy(facs->signature,"FACS",4);
facs->length = sizeof(acpi_facs_t);
facs->hardware_signature = 0;
facs->firmware_waking_vector = 0;
facs->global_lock = 0;
facs->flags = 0;
facs->x_firmware_waking_vector_l = 0;
facs->x_firmware_waking_vector_h = 0;
facs->version = 1;
}
static void acpi_write_rsdt(acpi_rsdt_t *rsdt)
{
acpi_header_t *header=&(rsdt->header);
@ -222,6 +252,9 @@ unsigned long write_acpi_tables(unsigned long start)
acpi_rsdt_t *rsdt;
acpi_hpet_t *hpet;
acpi_madt_t *madt;
acpi_fadt_t *fadt;
acpi_facs_t *facs;
acpi_header_t *dsdt;
/* Align ACPI tables to 16byte */
start = ( start + 0x0f ) & -0x10;
@ -244,7 +277,6 @@ unsigned long write_acpi_tables(unsigned long start)
/*
* We explicitly add these tables later on:
*/
#define HAVE_ACPI_HPET
#ifdef HAVE_ACPI_HPET
printk_debug("ACPI: * HPET\n");
@ -263,6 +295,35 @@ unsigned long write_acpi_tables(unsigned long start)
#endif
#ifdef HAVE_ACPI_FADT
printk_debug("ACPI: * FACS\n");
facs = (acpi_facs_t *) current;
current += sizeof(acpi_facs_t);
acpi_create_facs(facs);
dsdt = (acpi_header_t *)current;
current += ((acpi_header_t *)AmlCode)->length;
memcpy((void *)dsdt,(void *)AmlCode, ((acpi_header_t *)AmlCode)->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);
#endif
printk_info("ACPI: done.\n");
return current;
}

View File

@ -60,8 +60,13 @@ struct lb_memory *write_tables(struct mem_range *mem, unsigned long *processor_m
low_table_end = write_smp_table(low_table_end, processor_map);
/* Write ACPI tables */
low_table_end = write_acpi_tables(low_table_end);
/* write them in the rom area because DSDT can be large (8K on epia-m) which
* pushes linuxbios table out of first 4K if set up in low table area
*/
rom_table_end = write_acpi_tables(rom_table_end);
rom_table_end = (rom_table_end+1023) & ~1023;
/* Don't write anything in the traditional x86 BIOS data segment */
if (low_table_end < 0x500) {
low_table_end = 0x500;

View File

@ -7,6 +7,9 @@
* The ACPI table structs are based on the Linux kernel sources.
*
*/
/* ACPI FADT & FACS added by Nick Barker <nick.barker9@btinternet.com>
* those parts (C) 2004 Nick Barker
*/
#ifndef __ASM_ACPI_H
@ -134,7 +137,77 @@ typedef struct acpi_madt_irqoverride {
} __attribute__ ((packed)) acpi_madt_irqoverride_t;
typedef struct acpi_fadt {
struct acpi_table_header header;
u32 firmware_ctrl;
u32 dsdt;
u8 res1;
u8 preferred_pm_profile;
u16 sci_int;
u32 smi_cmd;
u8 acpi_enable;
u8 acpi_disable;
u8 s4bios_req;
u8 pstate_cnt;
u32 pm1a_evt_blk;
u32 pm1b_evt_blk;
u32 pm1a_cnt_blk;
u32 pm1b_cnt_blk;
u32 pm2_cnt_blk;
u32 pm_tmr_blk;
u32 gpe0_blk;
u32 gpe1_blk;
u8 pm1_evt_len;
u8 pm1_cnt_len;
u8 pm2_cnt_len;
u8 pm_tmr_len;
u8 gpe0_blk_len;
u8 gpe1_blk_len;
u8 gpe1_base;
u8 cst_cnt;
u16 p_lvl2_lat;
u16 p_lvl3_lat;
u16 flush_size;
u16 flush_stride;
u8 duty_offset;
u8 duty_width;
u8 day_alrm;
u8 mon_alrm;
u8 century;
u16 iapc_boot_arch;
u8 res2;
u32 flags;
struct acpi_gen_regaddr reset_reg;
u8 reset_value;
u8 res3;
u8 res4;
u8 res5;
u32 x_firmware_ctl_l;
u32 x_firmware_ctl_h;
u32 x_dsdt_l;
u32 x_dsdt_h;
struct acpi_gen_regaddr x_pm1a_evt_blk;
struct acpi_gen_regaddr x_pm1b_evt_blk;
struct acpi_gen_regaddr x_pm1a_cnt_blk;
struct acpi_gen_regaddr x_pm1b_cnt_blk;
struct acpi_gen_regaddr x_pm2_cnt_blk;
struct acpi_gen_regaddr x_pm_tmr_blk;
struct acpi_gen_regaddr x_gpe0_blk;
struct acpi_gen_regaddr x_gpe1_blk;
} __attribute__ ((packed)) acpi_fadt_t;
typedef struct acpi_facs {
char signature[4];
u32 length;
u32 hardware_signature;
u32 firmware_waking_vector;
u32 global_lock;
u32 flags;
u32 x_firmware_waking_vector_l;
u32 x_firmware_waking_vector_h;
u8 version;
u8 resv[33];
} __attribute__ ((packed)) acpi_facs_t;
unsigned long write_acpi_tables(unsigned long addr);

View File

@ -116,7 +116,7 @@ gdt:
.word 0x0000, 0x0000 /* dummy */
.byte 0x00, 0x00, 0x00, 0x00
#if defined(CONFIG_VGABIOS) && (CONFIG_VGABIOS == 1)
#if defined(CONFIG_LEGACY_VGABIOS) && (CONFIG_LEGACY_VGABIOS == 1)
// from monty:
/* 0x00009a00,0000ffffULL, 20h: 16-bit 64k code at 0x00000000 */
/* 0x00009200,0000ffffULL 28h: 16-bit 64k data at 0x00000000 */

View File

@ -481,7 +481,11 @@ define CONFIG_LEGACY_VGABIOS
export used
comment "Support for legacy VGA BIOS"
end
define VGABIOS_START
default 0
export used
comment "Base of Legacy VGA in Rom"
end
###############################################
# SMP options
###############################################

View File

@ -45,6 +45,7 @@ static unsigned int mtrr_msr[] = {
MTRRfix4K_E0000_MSR, MTRRfix4K_E8000_MSR, MTRRfix4K_F0000_MSR, MTRRfix4K_F8000_MSR,
};
static int mtrr_count = 0;
static void intel_enable_fixed_mtrr(void)
{
@ -79,6 +80,12 @@ static inline void disable_cache(void)
::"memory");
}
static inline void wbinvd(void)
{
asm volatile (
"wbinvd\n\t");
}
static inline void enable_cache(void)
{
unsigned int tmp;
@ -92,15 +99,19 @@ static inline void enable_cache(void)
}
/* setting variable mtrr, comes from linux kernel source */
/* funtion nows saves and restores state of deftype regs so that extra mtrr's can be set-up
* after the initial main memory mtrr's
*/
static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned long sizek, unsigned char type)
{
msr_t base, mask;
msr_t base, mask, def,defsave;
base.hi = basek >> 22;
base.lo = basek << 10;
//printk_debug("ADDRESS_MASK_HIGH=%#x\n", ADDRESS_MASK_HIGH);
printk_debug("Adding mtrr #%d at %08x size %x\n",reg,base.lo,sizek<<10);
if (sizek < 4*1024*1024) {
mask.hi = ADDRESS_MASK_HIGH;
mask.lo = ~((sizek << 10) -1);
@ -116,6 +127,10 @@ static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned l
// it is recommended that we disable and enable cache when we
// do this.
disable_cache();
def = defsave = rdmsr(MTRRdefType_MSR);
def.lo &= 0xf300;
wrmsr(MTRRdefType_MSR,def);
if (sizek == 0) {
msr_t zero;
zero.lo = zero.hi = 0;
@ -129,6 +144,8 @@ static void intel_set_var_mtrr(unsigned int reg, unsigned long basek, unsigned l
wrmsr (MTRRphysBase_MSR(reg), base);
wrmsr (MTRRphysMask_MSR(reg), mask);
}
wbinvd();
wrmsr(MTRRdefType_MSR,defsave);
enable_cache();
}
@ -262,7 +279,16 @@ static unsigned fixed_mtrr_index(unsigned long addrk)
}
return index;
}
// Externally visible function to add extra non system memory based mtrr's such
// as AGP mtrr's - needs to be called after setup_mtrrs
void add_var_mtrr(unsigned long range_startk, unsigned long range_sizek,
unsigned char type)
{
intel_set_var_mtrr(mtrr_count++,range_startk,range_sizek,type);
}
static unsigned int range_to_mtrr(unsigned int reg,
unsigned long range_startk, unsigned long range_sizek,
unsigned long next_range_startk)
@ -382,6 +408,7 @@ void setup_mtrrs(struct mem_range *mem)
}
/* Write the last range */
reg = range_to_mtrr(reg, range_startk, range_sizek, 0);
mtrr_count = reg;
printk_debug("DONE variable MTRRs\n");
printk_debug("Clear out the extra MTRR's\n");
/* Clear out the extra MTRR's */

View File

@ -679,6 +679,10 @@ unsigned int pci_scan_bus(struct bus *bus, unsigned min_devfn,
/* if a child provides scan_bus(), for example a bridge, scan
* buses behind that child */
for (child = bus->children; child; child = child->sibling) {
// make sure that we have an ops structure
if (!child->ops) {
continue;
}
if (!child->ops->scan_bus) {
continue;
}
@ -767,17 +771,17 @@ static void pci_level_irq(unsigned char intNum)
{
unsigned short intBits = inb(0x4d0) | (((unsigned) inb(0x4d1)) << 8);
printk_spew("%s: current ints are 0x%x\n", __FUNCTION__, intBits);
printk_debug("%s: current ints are 0x%x\n", __FUNCTION__, intBits);
intBits |= (1 << intNum);
printk_spew("%s: try to set ints 0x%x\n", __FUNCTION__, intBits);
printk_debug("%s: try to set ints 0x%x\n", __FUNCTION__, intBits);
// Write new values
outb((unsigned char) intBits, 0x4d0);
outb((unsigned char) (intBits >> 8), 0x4d1);
/* this seems like an error but is not ... */
#if 0
#if 1
if (inb(0x4d0) != (intBits & 0xf)) {
printk_err("%s: lower order bits are wrong: want 0x%x, got 0x%x\n",
__FUNCTION__, intBits &0xf, inb(0x4d0));

View File

@ -34,6 +34,7 @@
#if !defined(ASSEMBLY)
void set_var_mtrr(unsigned int reg, unsigned long base, unsigned long size, unsigned char type);
void add_var_mtrr(unsigned long basek, unsigned long sizek, unsigned char type);
#if defined(INTEL_PPRO_MTRR)
struct mem_range;
void setup_mtrrs(struct mem_range *mem);

View File

@ -23,6 +23,7 @@ uses _ROMBASE
uses XIP_ROM_SIZE
uses XIP_ROM_BASE
uses HAVE_MP_TABLE
uses HAVE_ACPI_TABLES
## ROM_SIZE is the size of boot ROM that this board will use.
default ROM_SIZE = 256*1024
@ -130,6 +131,11 @@ arch i386 end
driver mainboard.o
#object reset.o
if HAVE_ACPI_TABLES
object fadt.o
object dsdt.o
end
##
## Romcc output
##
@ -218,6 +224,14 @@ northbridge via/vt8623 "vt8623"
register "enable_keyboard" = "0"
register "enable_nvram" = "1"
end
southbridge ricoh/rl5c476 "rl5c476"
end
superio via/vt1211 "vt1211"
register "enable_com_ports" = "1"
register "enable_hwmon" = "1"
register "enable_lpt" = "1"
register "enable_fdc" = "1"
end
end
cpu p6 "cpu0"

View File

@ -49,7 +49,7 @@ static inline int spd_read_byte(unsigned device, unsigned address)
#include "northbridge/via/vt8601/raminit.c"
#include "northbridge/via/vt8623/raminit.c"
/*
#include "sdram/generic_sdram.c"
*/
@ -64,8 +64,9 @@ static void enable_mainboard_devices(void)
if (dev == PCI_DEV_INVALID) {
die("Southbridge not found!!!\n");
}
pci_write_config8(dev, 0x50, 7);
pci_write_config8(dev, 0x51, 0xff);
pci_write_config8(dev, 0x50, 0);
pci_write_config8(dev, 0x51, 0xfd);
pci_write_config8(dev, 0x94, 0xb2);
#if 0
// This early setup switches IDE into compatibility mode before PCI gets
// // a chance to assign I/Os
@ -97,9 +98,15 @@ static void enable_shadow_ram(void)
static void main(void)
{
unsigned long x;
device_t dev;
/* init_timer();*/
outb(5, 0x80);
pci_write_config8( 0xd*8,0x15,0x1c);
pci_write_config8( 0 , 0xe1, 0xdd);
outb(5, 0x80);
enable_smbus();
enable_vt8235_serial();

View File

@ -0,0 +1,155 @@
/*
* ACPI - create the Fixed ACPI Description Tables (FADT)
* (C) Copyright 2004 Nick Barker <nick.barker9@btinternet.com>
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <string.h>
#include <arch/acpi.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,"LXBIOS",6);
memcpy(header->oem_table_id,"LXBACPI ",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=5;
fadt->smi_cmd = 0;
fadt->acpi_enable = 0;
fadt->acpi_disable = 0;
fadt->s4bios_req = 0x0;
fadt->pstate_cnt = 0x0;
fadt->pm1a_evt_blk = 0x400;
fadt->pm1b_evt_blk = 0x0;
fadt->pm1a_cnt_blk = 0x404;
fadt->pm1b_cnt_blk = 0x0;
fadt->pm2_cnt_blk = 0x0;
fadt->pm_tmr_blk = 0x408;
fadt->gpe0_blk = 0x420;
fadt->gpe1_blk = 0x0;
fadt->pm1_evt_len = 4;
fadt->pm1_cnt_len = 2;
fadt->pm2_cnt_len = 0;
fadt->pm_tmr_len = 4;
fadt->gpe0_blk_len = 4;
fadt->gpe1_blk_len = 0;
fadt->gpe1_base = 0;
fadt->cst_cnt = 0;
fadt->p_lvl2_lat = 90;
fadt->p_lvl3_lat = 900;
fadt->flush_size = 0;
fadt->flush_stride = 0;
fadt->duty_offset = 0;
fadt->duty_width = 1;
fadt->day_alrm = 125;
fadt->mon_alrm = 126;
fadt->century = 50;
fadt->iapc_boot_arch = 0x1;
fadt->flags = 0x4a5;
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 = 0x400;
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 = 0x404;
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.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 = 0x408;
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 = 0x420;
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));
}

View File

@ -1,32 +1,30 @@
/* This file was generated by getpir.c, do not modify!
(but if you do, please run checkpir on it to verify)
Contains the IRQ Routing Table dumped directly from your memory , wich BIOS sets up
Documentation at : http://www.microsoft.com/hwdev/busbios/PCIIRQ.HTM
* Contains the IRQ Routing Table dumped directly from your memory, which BIOS sets up
*
* Documentation at : http://www.microsoft.com/hwdev/busbios/PCIIRQ.HTM
*/
#include <arch/pirq_routing.h>
const struct irq_routing_table intel_irq_routing_table = {
PIRQ_SIGNATURE, /* u32 signature */
PIRQ_VERSION, /* u16 version */
32+16*5, /* there can be total 5 devices on the bus */
0, /* Where the interrupt router lies (bus) */
0x88, /* Where the interrupt router lies (dev) */
0x1c20, /* IRQs devoted exclusively to PCI usage */
0x1106, /* Vendor */
0x8231, /* Device */
0, /* Crap (miniport) */
PIRQ_SIGNATURE, /* u32 signature */
PIRQ_VERSION, /* u16 version */
32+16*5, /* there can be total 5 devices on the bus */
0x00, /* Where the interrupt router lies (bus) */
(0x00<<3)|0x0, /* Where the interrupt router lies (dev) */
0xc20, /* IRQs devoted exclusively to PCI usage */
0, /* Vendor */
0, /* Device */
0, /* Crap (miniport) */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
0x5e, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */
0x68, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */
{
/* 8231 ethernet */
{0,0x90, {{0x1, 0xdeb8}, {0x2, 0xdeb8}, {0x3, 0xdeb8}, {0x4, 0xdeb8}}, 0x1, 0},
/* 8231 internal */
{0,0x88, {{0x2, 0xdeb8}, {0x3, 0xdeb8}, {0x4, 0xdeb8}, {0x1, 0xdeb8}}, 0x2, 0},
/* PCI slot */
{0,0xa0, {{0x3, 0xdeb8}, {0x4, 0xdeb8}, {0x1, 0xdeb8}, {0x2, 0xdeb8}}, 0, 0},
{0,0x50, {{0x4, 0xdeb8}, {0x3, 0xdeb8}, {0x2, 0xdeb8}, {0x1, 0xdeb8}}, 0x3, 0},
{0,0x98, {{0x4, 0xdeb8}, {0x3, 0xdeb8}, {0x2, 0xdeb8}, {0x1, 0xdeb8}}, 0x4, 0},
/* bus, dev|fn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */
{0x00,(0x14<<3)|0x0, {{0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x04, 0xdeb8}, {0x01, 0x0deb8}}, 0x1, 0x0},
{0x00,(0x13<<3)|0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x04, 0x0deb8}}, 0x2, 0x0},
{0x00,(0x0a<<3)|0x0, {{0x04, 0xdeb8}, {0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0x0deb8}}, 0x3, 0x0},
{0x00,(0x0d<<3)|0x0, {{0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x04, 0xdeb8}, {0x01, 0x0deb8}}, 0x4, 0x0},
{0x00,(0x01<<3)|0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x04, 0x0deb8}}, 0x0, 0x0},
}
};

View File

@ -9,6 +9,9 @@
#include <device/chip.h>
#include "chip.h"
void vga_enable_console();
static int
mainboard_scan_bus(device_t root, int maxbus)
{
@ -19,6 +22,56 @@ mainboard_scan_bus(device_t root, int maxbus)
return maxbus;
}
void vga_fixup(void) {
// we do this right here because:
// - all the hardware is working, and some VGA bioses seem to need
// that
// - we need page 0 below for linuxbios tables.
printk_debug("INSTALL REAL-MODE IDT\n");
setup_realmode_idt();
printk_debug("DO THE VGA BIOS\n");
do_vgabios();
post_code(0x93);
vga_enable_console();
}
void write_protect_vgabios(void)
{
device_t dev;
printk_info("write_protect_vgabios\n");
dev = dev_find_device(PCI_VENDOR_ID_VIA, 0x3123, 0);
if(dev)
pci_write_config8(dev, 0x61, 0xaa);
}
static void
enable(struct chip *chip, enum chip_pass pass)
{
struct mainboard_tyan_s4882_config *conf =
(struct mainboard_tyan_s4882_config *)chip->chip_info;
switch (pass) {
default: break;
// case CONF_PASS_PRE_CONSOLE:
// case CONF_PASS_PRE_PCI:
case CONF_PASS_POST_PCI:
// case CONF_PASS_PRE_BOOT:
// if (conf->fixup_scsi)
// onboard_scsi_fixup();
// if (conf->fixup_vga)
// vga_fixup();
printk_debug("mainboard fixup pass %d done\r\n",
pass);
break;
}
}
static struct device_operations mainboard_operations = {
.read_resources = root_dev_read_resources,
.set_resources = root_dev_set_resources,
@ -41,5 +94,6 @@ static void enumerate(struct chip *chip)
struct chip_control mainboard_via_epia_m_control = {
.enumerate = enumerate,
.name = "VIA EPIA-M mainboard ",
.enable = enable
};

View File

@ -6,15 +6,16 @@
#include <device/device.h>
#include <device/pci.h>
#include <device/hypertransport.h>
#include <device/pci_ids.h>
#include <device/chip.h>
#include <stdlib.h>
#include <string.h>
#include <bitops.h>
#include <cpu/p6/mtrr.h>
#include "chip.h"
#include "northbridge.h"
static const uint8_t ramregs[] = {0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x56, 0x57};
static const uint8_t ramregs[] = {0x5a, 0x5b, 0x5c, 0x5d };
struct mem_range *sizeram(void)
{
@ -30,8 +31,9 @@ struct mem_range *sizeram(void)
return 0;
}
mem[0].basek = 0;
mem[0].sizek = 65536;
idx = 1;
mem[0].sizek = 0xa0000 >>10; // first 640k
mem[1].basek = 0xc0000 >>10; // leave a hole for vga
idx = 2;
while(idx < sizeof(mem)/sizeof(mem[0])) {
mem[idx].basek = 0;
mem[idx].sizek = 0;
@ -53,8 +55,8 @@ struct mem_range *sizeram(void)
ramregs[i]);
}
printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*8*1024);
mem[0].sizek = rambits*8*1024;
printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*16*1024);
mem[1].sizek = rambits*16*1024 - 32768 - (0xc0000 >> 10);
#if 1
for(i = 0; i < idx; i++) {
printk_debug("mem[%d].basek = %08x mem[%d].sizek = %08x\n",
@ -78,18 +80,65 @@ static void enumerate(struct chip *chip)
* Apparently these registers govern some sort of bus master behavior.
*/
static void random_fixup() {
device_t pcidev = dev_find_slot(0, 0);
device_t pcidev0 = dev_find_slot(0, 0);
device_t pcidev1,pcidev2;
unsigned long fb;
unsigned char c;
printk_spew("VT8623 random fixup ...\n");
if (pcidev) {
pci_write_config8(pcidev, 0x70, 0xc0);
pci_write_config8(pcidev, 0x71, 0x88);
pci_write_config8(pcidev, 0x72, 0xec);
pci_write_config8(pcidev, 0x73, 0x0c);
pci_write_config8(pcidev, 0x74, 0x0e);
pci_write_config8(pcidev, 0x75, 0x81);
pci_write_config8(pcidev, 0x76, 0x52);
printk_debug("VT8623 random fixup ...\n");
if (pcidev0) {
pci_write_config8(pcidev0, 0x0d, 0x08);
pci_write_config8(pcidev0, 0x70, 0x82);
pci_write_config8(pcidev0, 0x71, 0xc8);
pci_write_config8(pcidev0, 0x72, 0x0);
pci_write_config8(pcidev0, 0x73, 0x01);
pci_write_config8(pcidev0, 0x74, 0x01);
pci_write_config8(pcidev0, 0x75, 0x08);
pci_write_config8(pcidev0, 0x76, 0x52);
pci_write_config8(pcidev0, 0x13, 0xd0);
pci_write_config8(pcidev0, 0x84, 0x80);
pci_write_config16(pcidev0,0x80, 0x610f);
pci_write_config32(pcidev0,0x88, 0x02);
}
printk_debug("VT8623 AGP random fixup ...\n");
pcidev1 = dev_find_device(PCI_VENDOR_ID_VIA,0xb091,0);
if( pcidev1) {
pci_write_config8(pcidev1,0x3e,0x0c);
pci_write_config8(pcidev1,0x40,0x83);
pci_write_config8(pcidev1,0x41,0xc5);
pci_write_config8(pcidev1,0x43,0x44);
pci_write_config8(pcidev1,0x44,0x34);
pci_write_config8(pcidev1,0x83,0x02);
}
printk_debug("VGA random fixup ...\n");
pcidev2 = dev_find_device(PCI_VENDOR_ID_VIA,0x3122,0);
if( pcidev2 ){
pci_write_config8(pcidev2,0x04,0x07);
pci_write_config8(pcidev2,0x0d,0x20);
}
// fixup GART and framebuffer addresses properly
// first set up frame buffer properly
fb = pci_read_config32(pcidev2,0x10); // base address of framebuffer
printk_debug("Frame buffer at %8x\n",fb);
c = pci_read_config8(pcidev0,0xe1) & 0xf0; // size of vga
c |= fb>>28; // upper nibble of frame buffer address
pci_write_config8(pcidev0,0xe1,c);
c = (fb>>20) | 1; // enable framebuffer
pci_write_config8(pcidev0,0xe0,c);
pci_write_config8(pcidev0,0xe2,0x42); // 'cos award does
}
static void set_vga_mtrrs(void)
{
device_t pcidev = dev_find_device(PCI_VENDOR_ID_VIA,0x3122,0);
unsigned long fb;
add_var_mtrr( 0xd0000000 >> 10, 0x08000000>>10, MTRR_TYPE_WRCOMB);
fb = pci_read_config32(pcidev,0x10); // get the fb address
add_var_mtrr( fb>>10, 8192, MTRR_TYPE_WRCOMB);
}
static void northbridge_init(struct chip *chip, enum chip_pass pass)
@ -103,10 +152,11 @@ static void northbridge_init(struct chip *chip, enum chip_pass pass)
break;
case CONF_PASS_POST_PCI:
random_fixup();
break;
case CONF_PASS_PRE_BOOT:
random_fixup();
set_vga_mtrrs();
break;
default:

View File

@ -47,16 +47,17 @@ it with the version available from LANL.
#define DIMM_CL2 0
#endif
void dimms_read(unsigned long x)
void dimm_read(unsigned long x)
{
uint8_t c;
unsigned long eax;
volatile unsigned long y;
eax = x;
for(c = 0; c < 6; c++) {
y = * (volatile unsigned long *) eax;
eax += 0x10000000;
}
y = * (volatile unsigned long *) eax;
}
void dimms_write(int x)
@ -88,7 +89,7 @@ void setnorthb(device_t north, uint8_t reg, uint8_t val)
void
dumpnorth(device_t north)
{
uint8_t r, c;
uint16_t r, c;
for(r = 0; r < 256; r += 16) {
print_debug_hex8(r);
print_debug(":");
@ -106,7 +107,7 @@ static void sdram_set_registers(const struct mem_controller *ctrl)
uint8_t c, r;
print_err("vt8623 init starting\r\n");
north = pci_locate_device(PCI_ID(0x1106, 0x8623), 0);
north = pci_locate_device(PCI_ID(0x1106, 0x3123), 0);
north = 0;
print_debug_hex32(north);
print_debug(" is the north\n");
@ -118,66 +119,57 @@ static void sdram_set_registers(const struct mem_controller *ctrl)
/* All we are doing now is setting initial known-good values that will
* be revised later as we read SPD
*/
// memory clk enable. We are not using ECC
pci_write_config8(north,0x78, 0x01);
print_debug_hex8(pci_read_config8(north, 0x78));
// dram control, see the book.
#if DIMM_PC133
pci_write_config8(north,0x68, 0x52);
#else
pci_write_config8(north,0x68, 0x42);
#endif
// dram control, see the book.
pci_write_config8(north,0x6B, 0x0c);
// Initial setting, 256MB in each bank, will be rewritten later.
pci_write_config8(north,0x5A, 0x20);
print_debug_hex8(pci_read_config8(north, 0x5a));
pci_write_config8(north,0x5B, 0x40);
pci_write_config8(north,0x5C, 0x60);
pci_write_config8(north,0x5D, 0x80);
pci_write_config8(north,0x5E, 0xA0);
pci_write_config8(north,0x5F, 0xC0);
// It seems we have to take care of these 2 registers as if
// they are bank 6 and 7.
pci_write_config8(north,0x56, 0xC0);
pci_write_config8(north,0x57, 0xC0);
pci_write_config8(north,0x75,0x08);
/* since we only support epia-m at the moment, only ddr is supported */
/* setup cpu */
pci_write_config8(north,0x50,0xc8);
pci_write_config8(north,0x51,0xde);
pci_write_config8(north,0x52,0xcf);
pci_write_config8(north,0x53,0x88);
pci_write_config8(north,0x55,0x07);
/* DRAM MA Map Type */
pci_write_config8(north,0x58,0xe0);
/* DRAM bank 0 - 3 size = 512M */
pci_write_config8(north,0x5a,0x10);
pci_write_config8(north,0x5b,0x10);
pci_write_config8(north,0x5c,0x10);
pci_write_config8(north,0x5d,0x10);
/* set DRAM timing for all banks */
pci_write_config8(north,0x64,0xe6);
/* set DRAM type to DDR */
pci_write_config8(north,0x60,0x02);
/* DRAM arbitration timer */
pci_write_config8(north,0x65,0x32);
pci_write_config8(north,0x66,0x01);
pci_write_config8(north,0x68,0x59);
/* DRAM Frequency */
pci_write_config8(north,0x54,0xe0);
pci_write_config8(north,0x69,0x2d);
/* Enable CKE */
pci_write_config8(north,0x6b,0x10);
// SDRAM in all banks
pci_write_config8(north,0x60, 0x3F);
// DRAM timing. I'm suspicious of this
// This is for all banks, 64 is 0,1. 65 is 2,3. 66 is 4,5.
// ras precharge 4T, RAS pulse 5T
// cas2 is 0xd6, cas3 is 0xe6
// we're also backing off write pulse width to 2T, so result is 0xee
#if DIMM_CL2
pci_write_config8(north,0x64, 0xd4);
pci_write_config8(north,0x65, 0xd4);
pci_write_config8(north,0x66, 0xd4);
#else // CL=3
pci_write_config8(north,0x64, 0xe4);
pci_write_config8(north,0x65, 0xe4);
pci_write_config8(north,0x66, 0xe4);
#endif
/* Disable DRAM refresh */
pci_write_config8(north,0x6a,0x0);
/* set heavy drive */
pci_write_config8(north,0x6d,0x44);
pci_write_config8(north,0x61,0xff);
// dram frequency select.
// enable 4K pages for 64M dram.
#if DIMM_PC133
pci_write_config8(north,0x69, 0x3c);
#else
pci_write_config8(north,0x69, 0xac);
#endif
/* IMPORTANT -- disable refresh counter */
// refresh counter, disabled.
pci_write_config8(north,0x6A, 0x00);
// clkenable configuration. kevinh FIXME - add precharge
pci_write_config8(north,0x6C, 0x00);
// dram read latch delay of 1 ns, MD drive 8 mA,
// high drive strength on MA[2: 13], we#, cas#, ras#
// As per Cindy Lee, set to 0x37, not 0x57
pci_write_config8(north,0x6D, 0x7f);
}
/* slot is the dram slot. Return size of side0 in lower 16-bit,
@ -291,104 +283,87 @@ static void sdram_enable(int controllers, const struct mem_controller *ctrl)
};
device_t north = 0;
uint32_t size, base, slot, ma;
/* begin to initialize*/
// I forget why we need this, but we do
dimms_write(0xa55a5aa5);
/* set NOP*/
pci_write_config8(north,0x6C, 0x01);
print_debug("NOP\r\n");
/* wait 200us*/
// You need to do the memory reference. That causes the nop cycle.
dimms_read(0);
udelay(400);
print_debug("PRECHARGE\r\n");
/* set precharge */
pci_write_config8(north,0x6C, 0x02);
print_debug("DUMMY READS\r\n");
/* dummy reads*/
dimms_read(0);
udelay(200);
print_debug("CBR\r\n");
/* set CBR*/
pci_write_config8(north,0x6C, 0x04);
/* do 8 reads and wait >100us between each - from via*/
dimms_read(0);
udelay(200);
dimms_read(0);
udelay(200);
dimms_read(0);
udelay(200);
dimms_read(0);
udelay(200);
dimms_read(0);
udelay(200);
dimms_read(0);
udelay(200);
dimms_read(0);
udelay(200);
dimms_read(0);
udelay(200);
print_debug("MRS\r\n");
/* set MRS*/
pci_write_config8(north,0x6c, 0x03);
#if DIMM_CL2
dimms_read(0x150);
#else // CL=3
dimms_read(0x1d0);
#endif
udelay(200);
print_debug("NORMAL\r\n");
/* set to normal mode */
pci_write_config8(north,0x6C, 0x08);
dimms_write(0x55aa55aa);
dimms_read(0);
udelay(200);
print_debug("set ref. rate\r\n");
// Set the refresh rate.
#if DIMM_PC133
pci_write_config8(north,0x6A, 0x86);
#else
pci_write_config8(north,0x6A, 0x65);
#endif
print_debug("enable multi-page open\r\n");
// enable multi-page open
pci_write_config8(north,0x6B, 0x0d);
base = 0;
for(slot = 0; slot < 4; slot++) {
size = spd_module_size(slot);
/* side 0 */
base += size & 0xffff;
pci_write_config8(north, ramregs[2*slot], base);
/* side 1 */
base += size >> 16;
if (base > 0xff)
base = 0xff;
pci_write_config8(north, ramregs[2*slot + 1], base);
if (!size)
continue;
/* NOP command enable */
pci_write_config8(north,0x6b,0x01);
/* Calculate the value of MA mapping type register,
* based on size of SDRAM chips. */
size = (size & 0xffff) << (3 + 3);
/* convert module size to be in Mbits */
size /= spd_num_chips(slot);
print_debug_hex16(size);
print_debug(" is the chip size\r\n");
if (size < 64)
ma = 0;
if (size < 256)
ma = 8;
else
ma = 0xe;
print_debug_hex16(ma);
print_debug(" is the MA type\r\n");
set_ma_mapping(north, slot, ma);
}
print_err("vt8623 done\r\n");
/* read a double word from any addree of the dimm */
dimm_read(0x1f000);
udelay(200);
/* All bank precharge Command Enable */
pci_write_config8(north,0x6b,0x02);
dimm_read(0x1f000);
/* MSR Enable */
pci_write_config8(north,0x6b,0x03);
dimm_read(0x2000);
dimm_read(0x800);
/* All banks precharge Command Enable */
pci_write_config8(north,0x6b,0x02);
dimm_read(0x1f200);
/* CBR Cycle Enable */
pci_write_config8(north,0x6b,0x04);
/* Read 8 times */
dimm_read(0x1f300);
udelay(100);
dimm_read(0x1f400);
udelay(100);
dimm_read(0x1f500);
udelay(100);
dimm_read(0x1f600);
udelay(100);
dimm_read(0x1f700);
udelay(100);
dimm_read(0x1f800);
udelay(100);
dimm_read(0x1f900);
udelay(100);
dimm_read(0x1fa00);
udelay(100);
/* MSR Enable */
pci_write_config8(north,0x6b,0x03);
/* 0x150 if CAS Latency 2 or 0x350 CAS Latency 2.5 */
dimm_read(0x350);
/* Normal SDRAM Mode */
pci_write_config8(north,0x6b,0x58 );
/* Set the refresh rate */
pci_write_config8(north,0x6a,0x43);
pci_write_config8(north,0x67,0x22);
/* pci */
pci_write_config8(north,0x70,0x82);
pci_write_config8(north,0x73,0x01);
pci_write_config8(north,0x76,0x50);
pci_write_config8(north,0x71,0xc8);
/* graphics aperture base */
pci_write_config8(north,0x13,0xd0);
//pci_write_config8(north,0x56,0x10);
//pci_write_config8(north,0x57,0x10);
pci_write_config8(north,0xe0,0x80);
pci_write_config8(north,0xe1,0xdf);
pci_write_config8(north,0xe2,0x42);
pci_write_config8(north,0xa8,0x04);
pci_write_config8(north,0xac,0x2f);
pci_write_config8(north,0xae,0x04);
print_err("vt8623 done\r\n");
dumpnorth(north);
}

View File

@ -3,7 +3,7 @@ uses CONFIG_LEGACY_VGABIOS
object mc146818rtc.o
object isa-dma.o
#object i8259.o CONFIG_I8259
object i8259.o
#object udelay_timer2.o CONFIG_UDELAY_TIMER2
#object beep.o CONFIG_BEEP
#object vga_load_regs.o VIDEO_CONSOLE

View File

@ -5,7 +5,7 @@
/* much better keyboard init courtesy ollie@sis.com.tw
TODO: Typematic Setting, the keyboard is too slow for me */
static void pc_keyboard_init(struct pc_keyboard *keyboard)
void pc_keyboard_init(struct pc_keyboard *keyboard)
{
volatile unsigned char regval;

View File

@ -1,8 +1,10 @@
#include <pci.h>
#include <pci_ids.h>
#include <console/console.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#undef __KERNEL__
#include <arch/io.h>
#include <printk.h>
//#include <printk.h>
#include <string.h>
#include "vgachip.h"
@ -121,6 +123,8 @@ static void real_mode_switch_call_vga(unsigned long devfn)
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
" mov $0x40, %ax \n"
" mov %ax, %ds \n"
" mov %cx, %ax \n"
" .byte 0x9a, 0x03, 0, 0, 0xc0 \n"
" movb $0x55, %al\noutb %al, $0x80\n"
@ -151,10 +155,99 @@ static void real_mode_switch_call_vga(unsigned long devfn)
__asm__ (".text\n""real_mode_switch_end:\n");
extern char real_mode_switch_end[];
/* call vga bios int 10 function 0x4f14 to enable main console
epia-m does not always autosence the main console so forcing it on is good !! */
void vga_enable_console()
{
__asm__ __volatile__ (
// paranoia -- does ecx get saved? not sure. This is
// the easiest safe thing to do.
" pushal\n"
/* save the stack */
" mov %esp, __stack\n"
/* This configures CS properly for real mode. */
" ljmp $0x28, $__vga_ec_16bit\n"
"__vga_ec_16bit: \n"
".code16 \n"
/* 16 bit code from here on... */
/* Load the segment registers w/ properly configured segment
* descriptors. They will retain these configurations (limits,
* writability, etc.) once protected mode is turned off. */
" mov $0x30, %ax \n"
" mov %ax, %ds \n"
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
" mov %ax, %ss \n"
/* Turn off protection (bit 0 in CR0) */
" movl %cr0, %eax \n"
" andl $0xFFFFFFFE, %eax \n"
" movl %eax, %cr0 \n"
/* Now really going into real mode */
" ljmp $0, $__vga_ec_real \n"
"__vga_ec_real: \n"
// put the stack at the end of page zero.
// that way we can easily share it between real and protected,
// since the 16-bit ESP at segment 0 will work for any case.
/* Setup a stack */
" mov $0x0, %ax \n"
" mov %ax, %ss \n"
" movl $0x1000, %eax \n"
" movl %eax, %esp \n"
/* debugging for RGM */
" mov $0x11, %al \n"
" outb %al, $0x80\n"
/* Dump zeros in the other segregs */
" xor %ax, %ax \n"
" mov %ax, %ds \n"
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
/* ask bios to enable main console */
/* set up for int 10 call - values found from X server bios call routines */
" movw $0x4f14,%ax \n"
" movw $0x8003,%bx \n"
" movw $1, %cx \n"
" movw $0, %dx \n"
" movw $0, %di \n"
" .byte 0xcd, 0x10 \n"
" movb $0x55, %al\noutb %al, $0x80\n"
/* if we got here, just about done.
* Need to get back to protected mode */
"movl %cr0, %eax\n"
// "andl $0x7FFAFFD1, %eax\n" /* PG,AM,WP,NE,TS,EM,MP = 0 */
// "orl $0x60000001, %eax\n" /* CD, NW, PE = 1 */
"orl $0x0000001, %eax\n" /* PE = 1 */
"movl %eax, %cr0\n"
/* Now that we are in protected mode jump to a 32 bit code segment. */
"data32 ljmp $0x10, $vga_ec_restart\n"
"vga_ec_restart:\n"
".code32\n"
" movw $0x18, %ax \n"
" mov %ax, %ds \n"
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
" mov %ax, %ss \n"
".globl vga__ec_exit\n"
"vga_ec_exit:\n"
" mov __stack, %esp\n"
" popal\n"
);
}
void
do_vgabios(void)
{
struct pci_dev *dev;
device_t dev;
unsigned long busdevfn;
unsigned int rom = 0;
unsigned char *buf;
@ -162,17 +255,17 @@ do_vgabios(void)
int i;
for (i=0x400; i<0x500; i++) {
printk_debug("%02x%c", *(unsigned char *)i,
i%16==15 ? '\n' : ' ');
//printk_debug("%02x%c", *(unsigned char *)i,
// i%16==15 ? '\n' : ' ');
*(unsigned char *) i = 0;
}
for (i=0x400; i<0x500; i++) {
/* for (i=0x400; i<0x500; i++) {
printk_debug("%02x%c", *(unsigned char *)i,
i%16==15 ? '\n' : ' ');
}
dev = pci_find_class(PCI_CLASS_DISPLAY_VGA <<8, NULL);
*/
dev = dev_find_class(PCI_CLASS_DISPLAY_VGA<<8 , 0);
if (! dev) {
printk_debug("NO VGA FOUND\n");
@ -184,7 +277,7 @@ do_vgabios(void)
// Use VGA BIOS blob at specified address
rom = VGABIOS_START;
#else
pci_read_config32(dev, PCI_ROM_ADDRESS, &rom);
rom = pci_read_config32(dev, PCI_ROM_ADDRESS);
// paranoia
rom = 0xf0000000;
pci_write_config32(dev, PCI_ROM_ADDRESS, rom|1);
@ -193,12 +286,28 @@ do_vgabios(void)
buf = (unsigned char *) rom;
if ((buf[0] == 0x55) && (buf[1] == 0xaa)) {
memcpy((void *) 0xc0000, buf, size);
#define VGABIOS_WRITE_PROTECT 1
#ifdef VGABIOS_WRITE_PROTECT
write_protect_vgabios();
#endif
for(i = 0; i < 16; i++)
printk_debug("0x%x ", buf[i]);
// check signature again
buf = (unsigned char *) 0xc0000;
if (buf[0]==0x55 && buf[1]==0xAA) {
busdevfn = (dev->bus->secondary << 8) | dev->path.u.pci.devfn;
printk_debug("bus/devfn = %#x\n", busdevfn);
real_mode_switch_call_vga(busdevfn);
//for( i = 0 ; i < 0x500; i++){
// printk_debug("%02x%c",*(unsigned char *)i,
// i%16 == 15 ? '\n':' ');
//}
} else
printk_debug("Failed to copy VGA BIOS to 0xc0000\n");
for(i = 0; i < 16; i++)
printk_debug("0x%x ", buf[i]);
// check signature here later!
busdevfn = (dev->bus->secondary << 8) | dev->devfn;
real_mode_switch_call_vga(busdevfn);
} else
printk_debug("BAD SIGNATURE 0x%x 0x%x\n", buf[0], buf[1]);
#ifndef VGABIOS_START
@ -253,6 +362,10 @@ void callbiosint(void) {
__asm__ __volatile__ (
".code16\n"
"callbiosint16:\n"
" push %ds \n"
" push %es \n"
" push %fs \n"
" push %gs \n"
// clean up the int #. To save space we put it in the lower
// byte. But the top 24 bits are junk.
"andl $0xff, %eax\n"
@ -277,8 +390,8 @@ void callbiosint(void) {
" mov %ax, %ss \n"
" call biosint \n"
// back to real mode ...
" ljmp $0x28, $__rms_16bit\n"
"__rms_16bit: \n"
" ljmp $0x28, $__rms_16bit2\n"
"__rms_16bit2: \n"
".code16 \n" /* 16 bit code from here on... */
/* Load the segment registers w/ properly configured segment
@ -297,8 +410,8 @@ void callbiosint(void) {
" movl %eax, %cr0 \n"
/* Now really going into real mode */
" ljmp $0, $__rms_real \n"
"__rms_real: \n"
" ljmp $0, $__rms_real2 \n"
"__rms_real2: \n"
/* Setup a stack */
" mov $0x0, %ax \n"
@ -311,10 +424,16 @@ void callbiosint(void) {
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
" mov $0x40, %ax \n"
" mov %ax, %ds \n"
// pop the INT # that you pushed earlier
" popl %eax\n"
" popal\n"
" iret\n"
" pop %gs \n"
" pop %fs \n"
" pop %es \n"
" pop %ds \n"
" popal\n"
" iret\n"
".code32\n"
);
}
@ -336,12 +455,26 @@ pcibios(
unsigned long *peax,
unsigned long *pflags
);
int
handleint21(
unsigned long *pedi,
unsigned long *pesi,
unsigned long *pebp,
unsigned long *pesp,
unsigned long *pebx,
unsigned long *pedx,
unsigned long *pecx,
unsigned long *peax,
unsigned long *pflags
);
extern void vga_exit(void);
int
biosint(
unsigned long intnumber,
unsigned long gsfs,
unsigned long dses,
unsigned long edi,
unsigned long esi,
unsigned long ebp,
@ -393,8 +526,12 @@ biosint(
eax = 64 * 1024;
ret = 0;
break;
case 0x15:
ret=handleint21( &edi, &esi, &ebp, &esp,
&ebx, &edx, &ecx, &eax, &flags);
break;
default:
printk_info(__FUNCTION__ ": Unsupport int #0x%x\n",
printk_info("BIOSINT: Unsupport int #0x%x\n",
intnumber);
break;
}
@ -491,7 +628,7 @@ pcibios(
unsigned short devid, vendorid, devfn;
short devindex; /* Use short to get rid of gabage in upper half of 32-bit register */
unsigned char bus;
struct pci_dev *dev;
device_t dev;
switch(func) {
case CHECK:
@ -505,7 +642,7 @@ pcibios(
vendorid = *pedx;
devindex = *pesi;
dev = 0;
while ((dev = pci_find_device(vendorid, devid, dev))) {
while ((dev = dev_find_device(vendorid, devid, dev))) {
if (devindex <= 0)
break;
devindex--;
@ -516,7 +653,7 @@ pcibios(
// busnum is an unsigned char;
// devfn is an int, so we mask it off.
busdevfn = (dev->bus->secondary << 8)
| (dev->devfn & 0xff);
| (dev->path.u.pci.devfn & 0xff);
printk_debug("0x%x: return 0x%x\n", func, busdevfn);
*pebx = busdevfn;
retval = 0;
@ -541,7 +678,7 @@ pcibios(
devfn = *pebx & 0xff;
bus = *pebx >> 8;
reg = *pedi;
dev = pci_find_slot(bus, devfn);
dev = dev_find_slot(bus, devfn);
if (! dev) {
printk_debug("0x%x: BAD DEVICE bus %d devfn 0x%x\n", func, bus, devfn);
// idiots. the pcibios guys assumed you'd never pass a bad bus/devfn!
@ -563,15 +700,15 @@ pcibios(
break;
case WRITECONFBYTE:
byte = *pecx;
write_config8(dev, reg, byte);
pci_write_config8(dev, reg, byte);
break;
case WRITECONFWORD:
word = *pecx;
write_config16(dev, reg, word);
pci_write_config16(dev, reg, word);
break;
case WRITECONFDWORD:
word = *pecx;
write_config32(dev, reg, dword);
dword = *pecx;
pci_write_config32(dev, reg, dword);
break;
}
@ -590,31 +727,46 @@ pcibios(
return retval;
}
static void vga_init(struct chip *chip, enum chip_pass pass)
{
struct pc80_vgabios_config *conf =
(struct pc80_vgabios_config *)chip->chip_info;
switch (pass) {
case CONF_PASS_PRE_BOOT:
int handleint21( unsigned long *edi, unsigned long *esi, unsigned long *ebp,
unsigned long *esp, unsigned long *ebx, unsigned long *edx,
unsigned long *ecx, unsigned long *eax, unsigned long *flags)
{
int res=-1;
switch(*eax&0xffff)
{
case 0x5f19:
break;
default:
/* nothing yet */
case 0x5f18:
*eax=0x5f;
*ebx=0x545; // MCLK = 133, 32M frame buffer, 256 M main memory
// *ebx = 0x515; // MCLK = 133, 32M frame buffer, 128 M main memory
*ecx=0x060;
res=0;
break;
case 0x5f00:
*eax = 0x8600;
break;
case 0x5f01:
*eax = 0x5f;
*ecx = (*ecx & 0xffffff00 ) | 2; // panel type = 2 = 1024 * 768
res = 0;
break;
case 0x5f02:
*eax=0x5f;
*ebx= (*ebx & 0xffff0000) | 2;
*ecx= (*ecx & 0xffff0000) | 0x401; // PAL + crt only
*edx= (*edx & 0xffff0000) | 0; // TV Layout - default
res=0;
break;
case 0x5f0f:
*eax=0x860f;
//*ebx=0;
//*ecx=0;
//*edx=0;
//res=0;
break;
}
return res;
}
static void enumerate(struct chip *chip)
{
/* don't really need to do anything */
}
struct chip_control southbridge_via_vt8231_control = {
.enumerate = enumerate,
.enable = vga_init,
.name = "Legacy VGA bios"
};

View File

@ -0,0 +1,2 @@
config chip.h
object rl5c476.o

View File

@ -0,0 +1,10 @@
#ifndef _SOUTHBRIDGE_RICOH_RL5C476
#define _SOUTHBRIDGE_RICOH_RL5C476
extern struct chip_control southbridge_ricoh_rl5c476_control;
struct southbridge_ricoh_rl5c476_config {
int num;
};
#endif /* _SOUTHBRIDGE_RL5C476 */

View File

@ -0,0 +1,255 @@
/*
* (C) Copyright 2004 Nick Barker <nick.barker9@btinternet.com>
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <arch/io.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ops.h>
#include <device/pci_ids.h>
#include <device/chip.h>
#include <console/console.h>
#include "rl5c476.h"
#include "chip.h"
static void udelay(int i){
for(; i > 0 ; i--)
inb(0x80);
}
static void
dump_south(void)
{
device_t dev0;
dev0 = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, 0);
dev0 = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, dev0);
int i,j;
for(i = 0; i < 256; i += 16) {
printk_debug("0x%x: ", i);
for(j = 0; j < 16; j++) {
printk_debug("%02x ", pci_read_config8(dev0, i+j));
}
printk_debug("\n");
}
printk_debug("Card32\n");
for(i = 0 ; i < 256 ; i+=16){
printk_debug("0x%x: ",i);
for(j = 0 ; j < 16 ; j++){
printk_debug(" %02x",*(unsigned char *)(0x80000000+i+j));
}
printk_debug("\n");
}
printk_debug("Card16\n");
for(i = 0; i < 256; i += 16) {
printk_debug("0x%x: ", i);
for(j = 0; j < 16; j++) {
printk_debug("%02x ", *(unsigned char *)(0x80000800+ i+j));
}
printk_debug("\n");
}
printk_debug("CF Config\n");
for(i = 0 ; i < 256 ; i+=16){
printk_debug("0x%x: ",i);
for(j=0 ; j < 16 ; j++){
printk_debug("%02x ",*(unsigned char *)(0x81000200 + i + j));
}
printk_debug("\n");
}
}
static void rl5c476_init(struct southbridge_rl5c476_config *conf)
{
//unsigned char enables;
device_t dev;
pc16reg_t *pc16;
int i;
printk_debug("rl5c476 init\n");
/* cardbus controller function 1 for CF Socket */
dev = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, 0);
if (!dev ){
// probably an epia-m rather than mii
printk_debug("No rl5c476 found\n");
return;
}
/* setup pci header manually because 'pci_device.c' doesn't know how to handle
* pci to cardbus bridges - (header type 2 I think)
*/
/* initialize function zero - pcmcia socket so it behaves itself */
/* FIXME - statically put control memory at 0xe0000000 for now
* one day the pci_device allocator might do this */
pci_write_config32(dev,0x10,0xe0000000);
pci_write_config8(dev,0x0d,0x20);
pci_write_config8(dev,0x19,0x02);
pci_write_config8(dev,0x1a,0x02);
pci_write_config8(dev,0x1b,0x20);
//pci_write_config8(dev,0x3c,0);
pci_write_config8(dev,0x82,0x00a0);
pci_write_config16(dev,0x04,0x07);
/* get second function - i.e. compact flash socket */
dev = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, dev);
/* FIXME - control structure statically declared at 0xe0008000 for now */
pci_write_config32(dev,0x10,0xe0008000);
pci_write_config8(dev,0x0d,0x20);
pci_write_config8(dev,0x19,0x03);
pci_write_config8(dev,0x1a,0x03);
pci_write_config8(dev,0x1b,0x20);
//pci_write_config8(dev,0x3c,0x0);
pci_write_config16(dev,0x3e,0x0780);
pci_write_config16(dev,0x82,0x00a0);
pci_write_config16(dev,0x04,0x07);
/* pick up where 16 bit card control structure is */
pc16 = (pc16reg_t *)(0xe0008800);
/* disable memory and io windows and turn off socket power */
pc16->pwctrl = 0;
/* disable irq lines */
pc16->igctrl = 0;
/* disable memory and I/O windows */
pc16->awinen = 0;
/* reset card, configure for I/O and set IRQ line */
pc16->igctrl = 0x69;
// set io window 0 for 1e8 - 1ef
pc16->iostl0 = 0xe8;
pc16->iosth0 = 1;
pc16->iospl0 = 0xef;
pc16->iosph0 = 1;
// add io offset of 8 so that CF card will decode 0x1e8 as 0x1f0 i.e. the first byte of
// a 16 byte aligned, 16 byte window etc
pc16->ioffl0 = 0x8;
pc16->ioffh0 = 0;
// set io window 1 for 3ed - 3ee
pc16->iostl1 = 0xed;
pc16->iosth1 = 3;
pc16->iospl1 = 0xee;
pc16->iosph1 = 3;
pc16->ioffl1 = 0x0;
pc16->ioffh1 = 0;
// FIXME statically declare CF config window at 0xe1000000
pc16->smstl0 = 0;
pc16->smsth0 = 0;
pc16->smspl0 = 0;
pc16->smsph0 = 0x80;
pc16->moffl0 = 0;
pc16->moffh0 = 0x40;
pc16->smpga0 = 0xe1;
// set I/O width for Auto Data width
pc16->ioctrl = 0x22;
// enable I/O window 0 and 1
pc16->awinen = 0xc1;
pc16->miscc1 = 1;
// apply power and enable outputs
pc16->pwctrl = 0xb0;
// delay could be optimised, but this works
udelay(100000);
pc16->igctrl = 0x69;
unsigned char *cptr;
cptr = (unsigned char *)(0xe1000200);
printk_debug("CF Config = %x\n",*cptr);
// FIX Me 16 bit CF always have first config byte at 0x200 into Config structure,
// but CF+ May Not according to spec - should locate through reading tuple data,
// but this will do for now !!!
// set CF to decode 16 IO bytes on any 16 byte boundary - rely on the io
// windows of the bridge set up above to map those bytes into the
// addresses for ide controller 3 (0x1e8 - 0x1ef and 0x3ed - 0x3ee)
*cptr = 0x41;
}
static void southbridge_init(struct chip *chip, enum chip_pass pass)
{
struct southbridge_rl5c476_config *conf =
(struct southbridge_rl5c476_config *)chip->chip_info;
switch (pass) {
case CONF_PASS_PRE_PCI:
//rl5c476_pci_enable(conf);
break;
case CONF_PASS_POST_PCI:
rl5c476_init(conf);
break;
case CONF_PASS_PRE_BOOT:
//dump_south();
break;
default:
/* nothing yet */
break;
}
}
static void enumerate(struct chip *chip)
{
extern struct device_operations default_pci_ops_bus;
chip_enumerate(chip);
chip->dev->ops = &default_pci_ops_bus;
}
struct chip_control southbridge_ricoh_rl5c476_control = {
.enumerate = enumerate,
.enable = southbridge_init,
.name = "RICOH RL5C476"
};

View File

@ -0,0 +1,97 @@
/*
* (C) Copyright 2004 Nick Barker <nick.barker9@btinternet.com>
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/* rl5c476 routines and defines*/
typedef unsigned char u8;
/* the 16 bit control structure for ricoh cardbus bridge */
typedef struct pc16reg {
u8 idrevs;
u8 ifstat;
u8 pwctrl;
u8 igctrl;
u8 cschg;
u8 cscint;
u8 awinen;
u8 ioctrl;
u8 iostl0;
u8 iosth0;
u8 iospl0;
u8 iosph0;
u8 iostl1;
u8 iosth1;
u8 iospl1;
u8 iosph1;
u8 smstl0;
u8 smsth0;
u8 smspl0;
u8 smsph0;
u8 moffl0;
u8 moffh0;
u8 cdgenc;
u8 resv1;
u8 smstl1;
u8 smsth1;
u8 smspl1;
u8 smsph1;
u8 moffl1;
u8 moffh1;
u8 glctrl;
u8 atctrl;
u8 smstl2;
u8 smsth2;
u8 smspl2;
u8 smsph2;
u8 moffl2;
u8 moffh2;
u8 resv2;
u8 resv3;
u8 smstl3;
u8 smsth3;
u8 smspl3;
u8 smsph3;
u8 moffl3;
u8 moffh3;
u8 resv4;
u8 miscc1;
u8 smstl4;
u8 smsth4;
u8 smspl4;
u8 smsph4;
u8 moffl4;
u8 moffh4;
u8 ioffl0;
u8 ioffh0;
u8 ioffl1;
u8 ioffh1;
u8 gpio;
u8 resv5;
u8 resv6;
u8 resv7;
u8 resv8;
u8 resv9;
u8 smpga0;
} __attribute__ ((packed)) pc16reg_t;

View File

@ -9,6 +9,8 @@
#include "vt8235.h"
#include "chip.h"
void rtc_init(int i);
void pc_keyboard_init(void);
void hard_reset(void)
@ -23,67 +25,78 @@ static void usb_on(int enable)
/* Base 8235 controller */
device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, 0);
/* USB controller 1 */
device_t dev2 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, 0);
device_t dev1 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, 0);
/* USB controller 2 */
device_t dev3 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, dev2);
device_t dev2 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, dev1);
/* USB controller 2 */
device_t dev3 = dev_find_device(PCI_VENDOR_ID_VIA,
PCI_DEVICE_ID_VIA_82C586_2, dev2);
/* enable USB1 */
if(dev2) {
if (enable) {
pci_write_config8(dev2, 0x3c, 0x05);
pci_write_config8(dev2, 0x04, 0x07);
} else {
pci_write_config8(dev2, 0x3c, 0x00);
pci_write_config8(dev2, 0x04, 0x00);
if(enable){
if(dev0) {
regval = pci_read_config8(dev0, 0x50);
regval &= ~(0x36);
pci_write_config8(dev0, 0x50, regval);
}
}
if(dev0) {
regval = pci_read_config8(dev0, 0x50);
if (enable)
regval &= ~(0x10);
else
regval |= 0x10;
pci_write_config8(dev0, 0x50, regval);
}
/* enable USB2 */
if(dev3) {
if (enable) {
pci_write_config8(dev3, 0x3c, 0x05);
pci_write_config8(dev3, 0x04, 0x07);
} else {
pci_write_config8(dev3, 0x3c, 0x00);
pci_write_config8(dev3, 0x04, 0x00);
/* enable USB1 */
if(dev1) {
pci_write_config8(dev1, 0x04, 0x07);
}
/* enable USB2 */
if(dev2) {
pci_write_config8(dev2, 0x04, 0x07);
}
/* enable USB3 */
if(dev3) {
pci_write_config8(dev3, 0x04, 0x07);
}
}else{
if(dev0) {
regval = pci_read_config8(dev0, 0x50);
regval |= 0x36;
pci_write_config8(dev0, 0x50, regval);
}
/* disable USB1 */
if(dev1) {
pci_write_config8(dev1, 0x3c, 0x00);
pci_write_config8(dev1, 0x04, 0x00);
}
/* disable USB2 */
if(dev2) {
pci_write_config8(dev2, 0x3c, 0x00);
pci_write_config8(dev2, 0x04, 0x00);
}
/* disable USB3 */
if(dev3) {
pci_write_config8(dev3, 0x3c, 0x00);
pci_write_config8(dev3, 0x04, 0x00);
}
}
if(dev0) {
regval = pci_read_config8(dev0, 0x50);
if (enable)
regval &= ~(0x20);
else
regval |= 0x20;
pci_write_config8(dev0, 0x50, regval);
}
}
static void keyboard_on(void)
{
unsigned char regval;
/* Base 8235 controller */
device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, 0);
/* kevinh/Ispiri - update entire function to use
new pci_write_config8 */
device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, \
PCI_DEVICE_ID_VIA_8235, 0);
if (dev0) {
regval = pci_read_config8(dev0, 0x51);
regval |= 0x0f;
// regval |= 0x0f;
/* !!!FIX let's try this */
regval |= 0x1d;
pci_write_config8(dev0, 0x51, regval);
}
init_pc_keyboard(0x60, 0x64, 0);
pc_keyboard_init();
}
static void nvram_on(void)
@ -152,16 +165,43 @@ static void vt8235_pci_enable(struct southbridge_via_vt8235_config *conf)
*/
void pci_assign_irqs(unsigned bus, unsigned slot, const unsigned char pIntAtoD[4]);
/* taken some liberties - changed irq structures to pins numbers so that it is easier to
* change PCI irq assignments without having to change each PCI function individually
*/
static const unsigned char southbridgeIrqs[4] = { 11, 5, 10, 12 };
static const unsigned char enetIrqs[4] = { 11, 5, 10, 12 };
static const unsigned char slotIrqs[4] = { 5, 10, 12, 11 };
/* pciIrqs contains the irqs assigned for PCI pins A-D */
/* setting will depend on motherboard as irqs can be quite scarce */
/* e.g on EPIA-MII, 16 bit CF card wants a dedicated IRQ. A 16 bit card in pcmcia socket */
/* may want another - for now only claim 3 interupts for PCI, leaving at least one spare */
/* for CF. */
/* On EPIA-M one could allocated all four irqs to different numbers since there are no cardbus */
/* devices */
static const unsigned char pciIrqs[4] = { 5 , 9 , 9, 10 };
static const unsigned char usbPins[4] = { 'A','B','C','D'};
static const unsigned char enetPins[4] = { 'A','B','C','D'};
static const unsigned char slotPins[4] = { 'B','C','D','A'};
static const unsigned char firewirePins[4] = { 'B','C','D','A'};
static const unsigned char vt8235Pins[4] = { 'A','B','C','D'};
static const unsigned char vgaPins[4] = { 'A','B','C','D'};
static const unsigned char cbPins[4] = { 'A','B','C','D'};
static const unsigned char riserPins[4] = { 'A','B','C','D'};
/*
Our IDSEL mappings are as follows
PCI slot is AD31 (device 15) (00:14.0)
Southbridge is AD28 (device 12) (00:11.0)
*/
static unsigned char *pin_to_irq(const unsigned char *pin)
{
static unsigned char Irqs[4];
int i;
for (i = 0 ; i < 4 ; i++)
Irqs[i] = pciIrqs[ pin[i] - 'A' ];
return Irqs;
}
static void pci_routing_fixup(void)
{
device_t dev;
@ -177,23 +217,47 @@ static void pci_routing_fixup(void)
PINTC = IRQ10
PINTD = IRQ12
*/
pci_write_config8(dev, 0x55, 0xb0);
pci_write_config8(dev, 0x56, 0xa5);
pci_write_config8(dev, 0x57, 0xc0);
pci_write_config8(dev, 0x55, pciIrqs[0] << 4);
pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4) );
pci_write_config8(dev, 0x57, pciIrqs[3] << 4);
}
// Standard southbridge components
printk_info("setting southbridge\n");
pci_assign_irqs(0, 0x11, southbridgeIrqs);
// firewire built into southbridge
printk_info("setting firewire\n");
pci_assign_irqs(0, 0x0d, pin_to_irq(firewirePins) );
// Standard usb components
printk_info("setting usb\n");
pci_assign_irqs(0, 0x10, pin_to_irq(usbPins) );
// VT8235 + sound hardware
printk_info("setting vt8235\n");
pci_assign_irqs(0, 0x11, pin_to_irq(vt8235Pins) );
// Ethernet built into southbridge
printk_info("setting ethernet\n");
pci_assign_irqs(0, 0x12, enetIrqs);
pci_assign_irqs(0, 0x12, pin_to_irq(enetPins) );
// VGA
printk_info("setting vga\n");
pci_assign_irqs(1, 0x00, pin_to_irq(vgaPins) );
// PCI slot
printk_info("setting pci slot\n");
pci_assign_irqs(0, 0x14, slotIrqs);
printk_info("%s: DONE\n", __FUNCTION__);
pci_assign_irqs(0, 0x14, pin_to_irq(slotPins) );
// Cardbus slot
printk_info("setting cardbus slot\n");
pci_assign_irqs(0, 0x0a, pin_to_irq(cbPins) );
// Via 2 slot riser card 2nd slot
printk_info("setting riser slot\n");
pci_assign_irqs(0, 0x13, pin_to_irq(riserPins) );
}
@ -213,13 +277,76 @@ dump_south(void)
}
}
void set_led(void)
{
// set power led to steady now that lxbios has virtually done its job
device_t dev0;
dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,0);
pci_write_config8(dev0,0x94,0xb0);
}
/* set up the power management capabilities directly into ACPI mode */
/* this avoids having to handle any System Management Interrupts (SMI's) which I can't */
/* figure out how to do !!!! */
void setup_pm(device_t dev0)
{
// Set gen config 0
pci_write_config8(dev0,0x80,0x20);
// Set ACPI base address to IO 0x4000
pci_write_config16(dev0, 0x88, 0x0401);
// set ACPI irq to 5
pci_write_config8(dev0,0x82,0x55);
// primary interupt channel
pci_write_config16(dev0,0x84,0x30f2);
// throttle / stop clock control
pci_write_config8(dev0,0x8d,0x18);
pci_write_config8(dev0,0x93,0x88);
//pci_write_config8(dev0,0x94,0xb0);
pci_write_config8(dev0,0x95,0xc0);
pci_write_config8(dev0,0x98,0);
pci_write_config8(dev0,0x99,0xea);
pci_write_config8(dev0,0xe4,0x14);
pci_write_config8(dev0,0xe5,0x08);
// Enable ACPI access (and setup like award)
pci_write_config8(dev0, 0x81, 0x84);
outw(0xffff,0x400);
outw(0xffff,0x420);
outw(0xffff,0x428);
outl(0xffffffff,0x430);
outw(0x0,0x424);
outw(0x0,0x42a);
outw(0x1,0x42c);
outl(0x0,0x434);
outl(0x01,0x438);
outb(0x0,0x442);
outl(0xffff7fff,0x448);
outw(0x001,0x404);
}
static void vt8235_init(struct southbridge_via_vt8235_config *conf)
{
unsigned char enables;
device_t dev0;
device_t dev1;
device_t devpwr;
//device_t devpwr;
//int i;
// to do: use the pcibios_find function here, instead of
// hard coding the devfn.
// done - kevinh/Ispiri
@ -243,6 +370,7 @@ static void vt8235_init(struct southbridge_via_vt8235_config *conf)
// IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI
// interrupts can be properly marked as level triggered.
enables = pci_read_config8(dev0, 0x40);
enables |= 0x45;
pci_write_config8(dev0, 0x40, enables);
// Set 0x42 to 0xf0 to match Award bios
@ -250,6 +378,17 @@ static void vt8235_init(struct southbridge_via_vt8235_config *conf)
enables |= 0xf0;
pci_write_config8(dev0, 0x42, enables);
/* Set 0x58 to 0x03 to match Award */
pci_write_config8(dev0, 0x58, 0x03);
/* Set bit 3 of 0x4f to match award (use INIT# as cpu reset) */
enables = pci_read_config8(dev0, 0x4f);
enables |= 0x08;
pci_write_config8(dev0, 0x4f, enables);
// Set bit 3 of 0x4a, to match award (dummy pci request)
enables = pci_read_config8(dev0, 0x4a);
enables |= 0x08;
@ -271,67 +410,23 @@ static void vt8235_init(struct southbridge_via_vt8235_config *conf)
}
// enable com1 and com2.
if (conf->enable_com_ports) {
enables = pci_read_config8(dev0, 0x6e);
/* 0x80 is enable com port b, 0x10 is to make it com2, 0x8
* is enable com port a as com1 kevinh/Ispiri - Old code
* thought 0x01 would make it com1, that was wrong enables =
* 0x80 | 0x10 | 0x8 ; pci_write_config8(dev0, 0x6e,
* enables); // note: this is also a redo of some port of
* assembly, but we want everything up.
*/
/* set com1 to 115 kbaud not clear how to do this yet.
* forget it; done in assembly.
*/
/* enable serial irq */
pci_write_config8(dev0,0x52,0x9);
/* dma */
pci_write_config8(dev0, 0x53, 0x00);
/* Use compatability mode - per award bios */
pci_write_config32(dev1, 0x10, 0x0);
pci_write_config32(dev1, 0x14, 0x0);
pci_write_config32(dev1, 0x18, 0x0);
pci_write_config32(dev1, 0x1c, 0x0);
}
// enable IDE, since Linux won't do it.
// First do some more things to devfn (17,0)
// note: this should already be cleared, according to the book.
enables = pci_read_config8(dev0, 0x50);
printk_debug("IDE enable in reg. 50 is 0x%x\n", enables);
enables &= ~8; // need manifest constant here!
printk_debug("set IDE reg. 50 to 0x%x\n", enables);
pci_write_config8(dev0, 0x50, enables);
// set default interrupt values (IDE)
enables = pci_read_config8(dev0, 0x4c);
printk_debug("IRQs in reg. 4c are 0x%x\n", enables & 0xf);
// clear out whatever was there.
enables &= ~0xf;
enables |= 4;
printk_debug("setting reg. 4c to 0x%x\n", enables);
pci_write_config8(dev0, 0x4c, enables);
// set up the serial port interrupts.
// com2 to 3, com1 to 4
pci_write_config8(dev0, 0x46, 0x04);
pci_write_config8(dev0, 0x47, 0x03);
pci_write_config8(dev0, 0x6e, 0x98);
//
// Power management setup
setup_pm(dev0);
//
// Set ACPI base address to IO 0x4000
//pci_write_config32(devpwr, 0x48, 0x4001);
// Enable ACPI access (and setup like award)
//pci_write_config8(devpwr, 0x41, 0x84);
// Set hardware monitor base address to IO 0x6000
//pci_write_config32(devpwr, 0x70, 0x6001);
// Enable hardware monitor (and setup like award)
//pci_write_config8(devpwr, 0x74, 0x01);
// set IO base address to 0x5000
//pci_write_config32(devpwr, 0x90, 0x5001);
// Enable SMBus
//pci_write_config8(devpwr, 0xd2, 0x01);
//
// IDE setup
//
@ -422,6 +517,8 @@ static void vt8235_init(struct southbridge_via_vt8235_config *conf)
// Start the rtc
rtc_init(0);
}
static void southbridge_init(struct chip *chip, enum chip_pass pass)
@ -436,12 +533,23 @@ static void southbridge_init(struct chip *chip, enum chip_pass pass)
break;
case CONF_PASS_POST_PCI:
/* initialise the PIC - particularly so that VGA bios init code
doesn't get nasty unknown interupt vectors when it tries to establish
its interrupts. */
setup_i8259();
vt8235_init(conf);
pci_routing_fixup();
usb_on(1);
keyboard_on();
vga_fixup();
break;
case CONF_PASS_PRE_BOOT:
dump_south();
set_led();
break;
default:

View File

@ -29,35 +29,64 @@ static void enable_smbus(void)
{
device_t dev;
unsigned char c;
int i;
/* Power management controller */
dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235), 0);
dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235), 0);
if (dev == PCI_DEV_INVALID) {
die("SMBUS controller not found\r\n");
}
}
pci_write_config8(dev, 0xd2, (0x4 << 1 ));
// set IO base address to SMBUS_IO_BASE
pci_write_config32(dev, 0x90, SMBUS_IO_BASE|1);
pci_write_config16(dev, 0xd0, SMBUS_IO_BASE);
// Enable SMBus
pci_write_config8(dev, 0xd2, (0x4 << 1)|1);
// Enable RTC
pci_write_config8(dev,0x51,0x04);
/* make it work for I/O ...
*/
pci_write_config8(dev, 4, 1);
pci_write_config16(dev, 4, 1);
/* tell the world we're alive - make power led flash during bios execution */
pci_write_config8(dev,0x94,0xb2);
/* FIX for half baud rate problem */
/* let clocks and the like settle */
/* as yet arbitrary count - 1000 is too little 5000 works */
for(i = 0 ; i < 5000 ; i++)
outb(0x80,0x80);
/* southbridge doesn't seem to like to do much untill after this delay, so set up
* the flashing power LED again */
pci_write_config8(dev,0x94,0xb2);
/* The VT1211 serial port needs 48 mhz clock, on power up it is getting
only 24 mhz, there is some mysterious device on the smbus that can
fix this...this code below does it. */
outb(0xff, SMBUS_IO_BASE+SMBHSTSTAT);
outb(0xff, SMBUS_IO_BASE+SMBHSTSTAT);
outb(0xff, SMBUS_IO_BASE+SMBHSTSTAT);
outb(0xff, SMBUS_IO_BASE+SMBHSTSTAT);
for( ;;) {
c = inb(SMBUS_IO_BASE+SMBHSTSTAT);
if ((c & 1) == 0)
break;
}
outb(0x7f, SMBUS_IO_BASE+SMBHSTDAT0);
outb(0x83, SMBUS_IO_BASE+SMBHSTCMD);
outb(CLOCK_SLAVE_ADDRESS<<1, SMBUS_IO_BASE+SMBXMITADD);
outb(CLOCK_SLAVE_ADDRESS<<1 , SMBUS_IO_BASE+SMBXMITADD);
outb(8 | I2C_TRANS_CMD, SMBUS_IO_BASE+SMBHSTCTL);
for (;;) {
c = inb(SMBUS_IO_BASE+SMBHSTSTAT);
if (c & 1 == 0)
if ((c & 1) == 0)
break;
}
}
@ -173,8 +202,9 @@ static unsigned char smbus_read_byte(unsigned char devAdr,
/* SMBUS Wait Ready */
for ( i = 0; i < 0xFFFF; i++ )
if ( ((sts = inb(SMBUS_IO_BASE)) & 0x01) == 0 )
if ( ((sts = (inb(SMBUS_IO_BASE) & 0x1f)) & 0x01) == 0 )
break;
if ((sts & ~3) != 0) {
smbus_print_error(sts);
return 0;

View File

@ -0,0 +1,2 @@
config chip.h
object vt1211.o

View File

@ -0,0 +1,19 @@
#ifndef _SUPERIO_VIA_VT1211
#define _SUPERIO_VIA_VT1211
extern struct chip_control superio_via_vt1211_control;
struct superio_via_vt1211_config {
/* PCI function enables */
/* i.e. so that pci scan bus will find them. */
/* I am putting in IDE as an example but obviously this needs
* to be more complete!
*/
/* enables of functions of devices */
int enable_com_ports;
int enable_fdc;
int enable_lpt;
int enable_hwmon;
};
#endif /* _SUPERIO_VIA_VT1211 */

View File

@ -0,0 +1,149 @@
/*
* (C) Copyright 2004 Nick Barker <nick.barker9@btinternet.com>
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/* vt1211 routines and defines*/
#include <arch/io.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ops.h>
#include <device/pci_ids.h>
#include <device/chip.h>
#include <console/console.h>
#include "vt1211.h"
#include "chip.h"
static unsigned char vt1211hwmonitorinits[]={
0x10,0x3, 0x11,0x10, 0x12,0xd, 0x13,0x7f,
0x14,0x21, 0x15,0x81, 0x16,0xbd, 0x17,0x8a,
0x18,0x0, 0x19,0x0, 0x1a,0x0, 0x1b,0x0,
0x1d,0xff, 0x1e,0x0, 0x1f,0x73, 0x20,0x67,
0x21,0xc1, 0x22,0xca, 0x23,0x74, 0x24,0xc2,
0x25,0xc7, 0x26,0xc9, 0x27,0x7f, 0x29,0x0,
0x2a,0x0, 0x2b,0xff, 0x2c,0x0, 0x2d,0xff,
0x2e,0x0, 0x2f,0xff, 0x30,0x0, 0x31,0xff,
0x32,0x0, 0x33,0xff, 0x34,0x0, 0x39,0xff,
0x3a,0x0, 0x3b,0xff, 0x3c,0xff, 0x3d,0xff,
0x3e,0x0, 0x3f,0xb0, 0x43,0xff, 0x44,0xff,
0x46,0xff, 0x47,0x50, 0x4a,0x3, 0x4b,0xc0,
0x4c,0x0, 0x4d,0x0, 0x4e,0xf, 0x5d,0x77,
0x5c,0x0, 0x5f,0x33, 0x40,0x1};
static void start_conf_pnp(int dev)
{
outb(0x87,0x2e);
outb(0x87,0x2e);
outb(7,0x2e);
outb(dev,0x2f);
}
static void write_pnp(int reg, int val)
{
outb(reg,0x2e);
outb(val,0x2f);
}
static void end_conf_pnp()
{
outb(0xaa,0x2e);
}
static void vt1211_init(struct superio_via_vt1211_config *conf)
{
int i;
// Activate the vt1211 hardware monitor
if(conf->enable_hwmon){
start_conf_pnp(0x0b);
write_pnp(0x60,0xec);
write_pnp(0x30,1);
end_conf_pnp();
// initialize vt1211 hardware monitor registers, which are at 0xECXX
for(i=0;i<sizeof(vt1211hwmonitorinits);i+=2)
outb(vt1211hwmonitorinits[i+1],0xec00+vt1211hwmonitorinits[i]);
}
if( conf->enable_fdc){
// activate FDC
start_conf_pnp(0); // fdc is device 0
write_pnp(0x60,0xfc); // io address
write_pnp(0x70,0x06); // interupt
write_pnp(0x74,0x02); // dma
write_pnp(0x30,0x01); // activate it
end_conf_pnp();
}
if( conf->enable_com_ports ){
// activate com2
start_conf_pnp(3);
write_pnp(0x60,0xbe);
write_pnp(0x70,0x3);
write_pnp(0xf0,0x02);
write_pnp(0x30,0x01);
end_conf_pnp();
}
if( conf->enable_lpt ){
// activate lpt
start_conf_pnp(1);
write_pnp(0x60,0xde);
write_pnp(0x70,0x07);
write_pnp(0x74,0x3);
write_pnp(0x30,0x01);
end_conf_pnp();
}
}
static void superio_init(struct chip *chip, enum chip_pass pass)
{
struct superio_via_vt1211_config *conf =
(struct superio_via_vt1211_config *)chip->chip_info;
switch (pass) {
case CONF_PASS_PRE_PCI:
break;
case CONF_PASS_POST_PCI:
vt1211_init(conf);
break;
case CONF_PASS_PRE_BOOT:
break;
default:
/* nothing yet */
break;
}
}
static void enumerate(struct chip *chip)
{
extern struct device_operations default_pci_ops_bus;
chip_enumerate(chip);
chip->dev->ops = &default_pci_ops_bus;
}
struct chip_control superio_via_vt1211_control = {
.enumerate = enumerate,
.enable = superio_init,
.name = "VIA vt1211"
};

View File

@ -0,0 +1,22 @@
/*
* (C) Copyright 2004 Nick Barker <nick.barker9@btinternet.com>
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/* vt1211 routines and defines*/

View File

@ -0,0 +1,107 @@
# Sample config file for EPIA-M
# This will make a target directory of ./epia-m
loadoptions
target epia-m
uses ARCH
uses CONFIG_COMPRESS
uses CONFIG_IOAPIC
uses CONFIG_ROM_STREAM
uses CONFIG_ROM_STREAM_START
uses CONFIG_UDELAY_TSC
uses CPU_FIXUP
uses FALLBACK_SIZE
uses HAVE_FALLBACK_BOOT
uses HAVE_MP_TABLE
uses HAVE_PIRQ_TABLE
uses HAVE_HARD_RESET
uses i586
uses i686
uses INTEL_PPRO_MTRR
uses HEAP_SIZE
uses IRQ_SLOT_COUNT
uses MAINBOARD_PART_NUMBER
uses MAINBOARD_VENDOR
uses CONFIG_SMP
uses CONFIG_MAX_CPUS
uses MEMORY_HOLE
uses PAYLOAD_SIZE
uses _RAMBASE
uses _ROMBASE
uses ROM_IMAGE_SIZE
uses ROM_SECTION_OFFSET
uses ROM_SECTION_SIZE
uses ROM_SIZE
uses STACK_SIZE
uses USE_FALLBACK_IMAGE
uses USE_OPTION_TABLE
uses HAVE_OPTION_TABLE
uses MAXIMUM_CONSOLE_LOGLEVEL
uses DEFAULT_CONSOLE_LOGLEVEL
uses CONFIG_CONSOLE_SERIAL8250
uses MAINBOARD
uses CONFIG_CHIP_CONFIGURE
uses XIP_ROM_SIZE
uses XIP_ROM_BASE
uses LINUXBIOS_EXTRA_VERSION
uses TTYS0_BAUD
option TTYS0_BAUD=19200
option CONFIG_CHIP_CONFIGURE=1
option MAXIMUM_CONSOLE_LOGLEVEL=7
option DEFAULT_CONSOLE_LOGLEVEL=7
option CONFIG_CONSOLE_SERIAL8250=1
option CPU_FIXUP=1
option CONFIG_UDELAY_TSC=0
option i686=1
option i586=1
option INTEL_PPRO_MTRR=1
option ROM_SIZE=256*1024
option HAVE_OPTION_TABLE=1
option CONFIG_ROM_STREAM=1
option HAVE_FALLBACK_BOOT=1
###
### Compute the location and size of where this firmware image
### (linuxBIOS plus bootloader) will live in the boot rom chip.
###
option FALLBACK_SIZE=131072
## LinuxBIOS C code runs at this location in RAM
option _RAMBASE=0x00004000
#
###
### Compute the start location and size size of
### The linuxBIOS bootloader.
###
#
# Arima hdama
romimage "normal"
option USE_FALLBACK_IMAGE=0
option ROM_IMAGE_SIZE=0x10000
option LINUXBIOS_EXTRA_VERSION=".0Normal"
mainboard via/epia-m
# payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
# payload ../../../../tg3--ide_disk.zelf
payload ../../../../../lnxieepro100.ebi
end
romimage "fallback"
option USE_FALLBACK_IMAGE=1
option ROM_IMAGE_SIZE=0x10000
option LINUXBIOS_EXTRA_VERSION=".0Fallback"
mainboard via/epia-m
# payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
# payload ../../../../tg3--ide_disk.zelf
payload ../../../../../lnxieepro100.ebi
end
buildrom ./linuxbios.rom ROM_SIZE "normal" "fallback"

View File

@ -46,32 +46,33 @@ uses CONFIG_CHIP_CONFIGURE
uses XIP_ROM_SIZE
uses XIP_ROM_BASE
uses LINUXBIOS_EXTRA_VERSION
uses TTYS0_BAUD
option TTYS0_BAUD=19200
uses HAVE_ACPI_TABLES
uses CONFIG_LEGACY_VGABIOS
uses VGABIOS_START
uses VGABIOS_START
option CONFIG_CHIP_CONFIGURE=1
option MAXIMUM_CONSOLE_LOGLEVEL=7
option DEFAULT_CONSOLE_LOGLEVEL=7
option MAXIMUM_CONSOLE_LOGLEVEL=8
option DEFAULT_CONSOLE_LOGLEVEL=8
option CONFIG_CONSOLE_SERIAL8250=1
option HAVE_ACPI_TABLES=1
option CPU_FIXUP=1
option CONFIG_UDELAY_TSC=0
option i686=1
option i586=1
option INTEL_PPRO_MTRR=1
option ROM_SIZE=256*1024
option CONFIG_LEGACY_VGABIOS=1
option HAVE_OPTION_TABLE=1
option CONFIG_ROM_STREAM=1
option HAVE_FALLBACK_BOOT=1
option VGABIOS_START=0xfffc0000
###
### Compute the location and size of where this firmware image
### (linuxBIOS plus bootloader) will live in the boot rom chip.
###
option FALLBACK_SIZE=131072
option FALLBACK_SIZE=0x18000
## LinuxBIOS C code runs at this location in RAM
option _RAMBASE=0x00004000
@ -86,22 +87,26 @@ option _RAMBASE=0x00004000
# Arima hdama
romimage "normal"
option USE_FALLBACK_IMAGE=0
option ROM_IMAGE_SIZE=0x10000
option ROM_IMAGE_SIZE=0xc000
option ROM_SECTION_OFFSET=0x10000
option ROM_SECTION_SIZE=0x18000
option LINUXBIOS_EXTRA_VERSION=".0Normal"
mainboard via/epia-m
# payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
# payload ../../../../tg3--ide_disk.zelf
payload ../../../../../lnxieepro100.ebi
# payload ../../../../../lnxieepro100.ebi
payload /filo.elf
end
romimage "fallback"
option USE_FALLBACK_IMAGE=1
option ROM_IMAGE_SIZE=0x10000
option ROM_IMAGE_SIZE=0xc000
option LINUXBIOS_EXTRA_VERSION=".0Fallback"
mainboard via/epia-m
# payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
# payload ../../../../tg3--ide_disk.zelf
payload ../../../../../lnxieepro100.ebi
# payload ../../../../../lnxieepro100.ebi
payload /filo.elf
end
buildrom ./linuxbios.rom ROM_SIZE "normal" "fallback"

View File

@ -0,0 +1,112 @@
# Sample config file for EPIA-M
# This will make a target directory of ./epia-m
loadoptions
target epia-m
uses ARCH
uses CONFIG_COMPRESS
uses CONFIG_IOAPIC
uses CONFIG_ROM_STREAM
uses CONFIG_ROM_STREAM_START
uses CONFIG_UDELAY_TSC
uses CPU_FIXUP
uses FALLBACK_SIZE
uses HAVE_FALLBACK_BOOT
uses HAVE_MP_TABLE
uses HAVE_PIRQ_TABLE
uses HAVE_HARD_RESET
uses i586
uses i686
uses INTEL_PPRO_MTRR
uses HEAP_SIZE
uses IRQ_SLOT_COUNT
uses MAINBOARD_PART_NUMBER
uses MAINBOARD_VENDOR
uses CONFIG_SMP
uses CONFIG_MAX_CPUS
uses MEMORY_HOLE
uses PAYLOAD_SIZE
uses _RAMBASE
uses _ROMBASE
uses ROM_IMAGE_SIZE
uses ROM_SECTION_OFFSET
uses ROM_SECTION_SIZE
uses ROM_SIZE
uses STACK_SIZE
uses USE_FALLBACK_IMAGE
uses USE_OPTION_TABLE
uses HAVE_OPTION_TABLE
uses MAXIMUM_CONSOLE_LOGLEVEL
uses DEFAULT_CONSOLE_LOGLEVEL
uses CONFIG_CONSOLE_SERIAL8250
uses MAINBOARD
uses CONFIG_CHIP_CONFIGURE
uses XIP_ROM_SIZE
uses XIP_ROM_BASE
uses LINUXBIOS_EXTRA_VERSION
uses HAVE_ACPI_TABLES
uses CONFIG_LEGACY_VGABIOS
uses VGABIOS_START
uses VGABIOS_START
option CONFIG_CHIP_CONFIGURE=1
option MAXIMUM_CONSOLE_LOGLEVEL=8
option DEFAULT_CONSOLE_LOGLEVEL=8
option CONFIG_CONSOLE_SERIAL8250=1
option HAVE_ACPI_TABLES=1
option CPU_FIXUP=1
option CONFIG_UDELAY_TSC=0
option i686=1
option i586=1
option INTEL_PPRO_MTRR=1
option ROM_SIZE=256*1024
option CONFIG_LEGACY_VGABIOS=1
option HAVE_OPTION_TABLE=1
option CONFIG_ROM_STREAM=1
option HAVE_FALLBACK_BOOT=1
option VGABIOS_START=0xfffc0000
###
### Compute the location and size of where this firmware image
### (linuxBIOS plus bootloader) will live in the boot rom chip.
###
option FALLBACK_SIZE=0x18000
## LinuxBIOS C code runs at this location in RAM
option _RAMBASE=0x00004000
#
###
### Compute the start location and size size of
### The linuxBIOS bootloader.
###
#
# Arima hdama
romimage "normal"
option USE_FALLBACK_IMAGE=0
option ROM_IMAGE_SIZE=0xc000
option ROM_SECTION_OFFSET=0x10000
option ROM_SECTION_SIZE=0x18000
option LINUXBIOS_EXTRA_VERSION=".0Normal"
mainboard via/epia-m
# payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
# payload ../../../../tg3--ide_disk.zelf
# payload ../../../../../lnxieepro100.ebi
payload /filo.elf
end
romimage "fallback"
option USE_FALLBACK_IMAGE=1
option ROM_IMAGE_SIZE=0xc000
option LINUXBIOS_EXTRA_VERSION=".0Fallback"
mainboard via/epia-m
# payload /usr/share/etherboot/5.1.9pre2-lnxi-lb/tg3--ide_disk.zelf
# payload ../../../../tg3--ide_disk.zelf
# payload ../../../../../lnxieepro100.ebi
payload /filo.elf
end
buildrom ./linuxbios.rom ROM_SIZE "normal" "fallback"

42
util/resetcf/resetcf.c Normal file
View File

@ -0,0 +1,42 @@
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
main(int argc, char *argv[])
{
int i;
volatile unsigned char *cp;
int fd;
void *v;
off_t nvram;
size_t length = 0x1000;
fd = open("/proc/bus/pci/00/0a.1",O_RDONLY);
lseek(fd,0x10,0);
read(fd,&nvram,sizeof(nvram));
close(fd);
//printf("Star %x\n",nvram);
if((fd = open("/dev/mem",O_RDWR)) != -1)
{
v = mmap(0, length, PROT_READ | PROT_WRITE, MAP_SHARED,fd,nvram);
fprintf(stderr, "mmap returns %p\n", v);
if ( v == (void *) -1)
{
perror("mmap");
exit(1);
}
} else {
perror("open /dev/mem");
exit(1);
}
for( i = 0x836 ; i < 0x840 ; i++){
*(unsigned char *)(v+i) = 0;
}
}