blob: 38475f387476b0a219fa8791b1339c37cced353b [file] [log] [blame]
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
* Copyright (C) 2007 Advanced Micro Devices, 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.
*/
#include <inttypes.h>
#include <console/console.h>
#include <device/pci_ops.h>
#include <northbridge/amd/amdfam10/raminit.h>
#include <northbridge/amd/amdfam10/amdfam10.h>
#define RES_DEBUG 0
void setup_resource_map(const u32 *register_values, u32 max)
{
u32 i;
for (i = 0; i < max; i += 3) {
pci_devfn_t dev;
u32 where;
u32 reg;
dev = register_values[i] & ~0xfff;
where = register_values[i] & 0xfff;
reg = pci_read_config32(dev, where);
reg &= register_values[i+1];
reg |= register_values[i+2];
pci_write_config32(dev, where, reg);
}
}
void setup_resource_map_offset(const u32 *register_values, u32 max, u32 offset_pci_dev, u32 offset_io_base)
{
u32 i;
for (i = 0; i < max; i += 3) {
pci_devfn_t dev;
u32 where;
unsigned long reg;
dev = (register_values[i] & ~0xfff) + offset_pci_dev;
where = register_values[i] & 0xfff;
reg = pci_read_config32(dev, where);
reg &= register_values[i+1];
reg |= register_values[i+2] + offset_io_base;
pci_write_config32(dev, where, reg);
}
}
void setup_resource_map_x_offset(const u32 *register_values, u32 max, u32 offset_pci_dev, u32 offset_io_base)
{
u32 i;
if (IS_ENABLED(RES_DEBUG))
printk(BIOS_DEBUG, "setting up resource map ex offset....\n");
for (i = 0; i < max; i += 4) {
if (IS_ENABLED(RES_DEBUG))
printk(BIOS_DEBUG, "%04x: %02x %08x <- & %08x | %08x\n",
i/4, register_values[i],
register_values[i+1] + ((register_values[i]==RES_PCI_IO) ? offset_pci_dev : 0),
register_values[i+2],
register_values[i+3] + (((register_values[i] & RES_PORT_IO_32) == RES_PORT_IO_32) ? offset_io_base : 0)
);
switch (register_values[i]) {
case RES_PCI_IO: //PCI
{
pci_devfn_t dev;
u32 where;
u32 reg;
dev = (register_values[i+1] & ~0xfff) + offset_pci_dev;
where = register_values[i+1] & 0xfff;
reg = pci_read_config32(dev, where);
if (IS_ENABLED(RES_DEBUG))
printk(BIOS_SPEW, "WAS: %08x\n", reg);
reg &= register_values[i+2];
reg |= register_values[i+3];
pci_write_config32(dev, where, reg);
if (IS_ENABLED(RES_DEBUG))
printk(BIOS_SPEW, "NOW: %08x\n", reg);
}
break;
case RES_PORT_IO_8: // io 8
{
u32 where;
u32 reg;
where = register_values[i+1] + offset_io_base;
reg = inb(where);
if (IS_ENABLED(RES_DEBUG))
printk(BIOS_SPEW, "WAS: %08x\n", reg);
reg &= register_values[i+2];
reg |= register_values[i+3];
outb(reg, where);
if (IS_ENABLED(RES_DEBUG))
printk(BIOS_SPEW, "NOW: %08x\n", reg);
}
break;
case RES_PORT_IO_32: //io32
{
u32 where;
u32 reg;
where = register_values[i+1] + offset_io_base;
reg = inl(where);
if (IS_ENABLED(RES_DEBUG))
printk(BIOS_SPEW, "WAS: %08x\n", reg);
reg &= register_values[i+2];
reg |= register_values[i+3];
outl(reg, where);
if (IS_ENABLED(RES_DEBUG))
printk(BIOS_SPEW, "NOW: %08x\n", reg);
}
break;
}
}
if (IS_ENABLED(RES_DEBUG))
printk(BIOS_DEBUG, "done.\n");
}
void setup_resource_map_x(const u32 *register_values, u32 max)
{
u32 i;
if (IS_ENABLED(RES_DEBUG))
printk(BIOS_DEBUG, "setting up resource map ex offset....\n");
for (i = 0; i < max; i += 4) {
if (IS_ENABLED(RES_DEBUG))
printk(BIOS_DEBUG, "%04x: %02x %08x <- & %08x | %08x\n",
i/4, register_values[i],register_values[i+1], register_values[i+2], register_values[i+3]);
switch (register_values[i]) {
case RES_PCI_IO: //PCI
{
pci_devfn_t dev;
u32 where;
u32 reg;
dev = register_values[i+1] & ~0xfff;
where = register_values[i+1] & 0xfff;
reg = pci_read_config32(dev, where);
reg &= register_values[i+2];
reg |= register_values[i+3];
pci_write_config32(dev, where, reg);
}
break;
case RES_PORT_IO_8: // io 8
{
u32 where;
u32 reg;
where = register_values[i+1];
reg = inb(where);
reg &= register_values[i+2];
reg |= register_values[i+3];
outb(reg, where);
}
break;
case RES_PORT_IO_32: //io32
{
u32 where;
u32 reg;
where = register_values[i+1];
reg = inl(where);
reg &= register_values[i+2];
reg |= register_values[i+3];
outl(reg, where);
}
break;
}
}
if (IS_ENABLED(RES_DEBUG))
printk(BIOS_DEBUG, "done.\n");
}