/* * This file is part of the coreboot project. * * Copyright (C) 2009 One Laptop per Child, Association, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef ARCH_I386_PCI_RAWOPS_H # define ARCH_I386_PCI_RAWOPS_H 1 #include #define PCI_RAWDEV(SEGBUS, DEV, FN) ( \ (((SEGBUS) & 0xFFF) << 20) | \ (((DEV) & 0x1F) << 15) | \ (((FN) & 0x07) << 12)) struct VIA_PCI_REG_INIT_TABLE { u8 ChipRevisionStart; u8 ChipRevisionEnd; u8 Bus; u8 Device; u8 Function; u32 Register; u8 Mask; u8 Value; }; typedef unsigned device_t_raw; /* pci and pci_mmio need to have different ways to have dev */ /* FIXME: We need to make the coreboot to run at 64bit mode, So when read/write memory above 4G, * We don't need to set %fs, and %gs anymore * Before that We need to use %gs, and leave %fs to other RAM access */ uint8_t pci_io_rawread_config8(device_t_raw dev, unsigned where) { unsigned addr; #if PCI_IO_CFG_EXT == 0 addr = (dev>>4) | where; #else addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16); //seg == 0 #endif outl(0x80000000 | (addr & ~3), 0xCF8); return inb(0xCFC + (addr & 3)); } #if MMCONF_SUPPORT uint8_t pci_mmio_rawread_config8(device_t_raw dev, unsigned where) { unsigned addr; addr = dev | where; return read8x(addr); } #endif uint8_t pci_rawread_config8(device_t_raw dev, unsigned where) { #if MMCONF_SUPPORT return pci_mmio_rawread_config8(dev, where); #else return pci_io_rawread_config8(dev, where); #endif } uint16_t pci_io_rawread_config16(device_t_raw dev, unsigned where) { unsigned addr; #if PCI_IO_CFG_EXT == 0 addr = (dev>>4) | where; #else addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16); #endif outl(0x80000000 | (addr & ~3), 0xCF8); return inw(0xCFC + (addr & 2)); } #if MMCONF_SUPPORT uint16_t pci_mmio_rawread_config16(device_t_raw dev, unsigned where) { unsigned addr; addr = dev | where; return read16x(addr); } #endif uint16_t pci_rawread_config16(device_t_raw dev, unsigned where) { #if MMCONF_SUPPORT return pci_mmio_rawread_config16(dev, where); #else return pci_io_rawread_config16(dev, where); #endif } uint32_t pci_io_rawread_config32(device_t_raw dev, unsigned where) { unsigned addr; #if PCI_IO_CFG_EXT == 0 addr = (dev>>4) | where; #else addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16); #endif outl(0x80000000 | (addr & ~3), 0xCF8); return inl(0xCFC); } #if MMCONF_SUPPORT uint32_t pci_mmio_rawread_config32(device_t_raw dev, unsigned where) { unsigned addr; addr = dev | where; return read32x(addr); } #endif uint32_t pci_rawread_config32(device_t_raw dev, unsigned where) { #if MMCONF_SUPPORT return pci_mmio_rawread_config32(dev, where); #else return pci_io_rawread_config32(dev, where); #endif } void pci_io_rawwrite_config8(device_t_raw dev, unsigned where, uint8_t value) { unsigned addr; #if PCI_IO_CFG_EXT == 0 addr = (dev>>4) | where; #else addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16); #endif outl(0x80000000 | (addr & ~3), 0xCF8); outb(value, 0xCFC + (addr & 3)); } #if MMCONF_SUPPORT void pci_mmio_rawwrite_config8(device_t_raw dev, unsigned where, uint8_t value) { unsigned addr; addr = dev | where; write8x(addr, value); } #endif void pci_rawwrite_config8(device_t_raw dev, unsigned where, uint8_t value) { #if MMCONF_SUPPORT pci_mmio_rawwrite_config8(dev, where, value); #else pci_io_rawwrite_config8(dev, where, value); #endif } void pci_io_rawwrite_config16(device_t_raw dev, unsigned where, uint16_t value) { unsigned addr; #if PCI_IO_CFG_EXT == 0 addr = (dev>>4) | where; #else addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16); #endif outl(0x80000000 | (addr & ~3), 0xCF8); outw(value, 0xCFC + (addr & 2)); } #if MMCONF_SUPPORT void pci_mmio_rawwrite_config16(device_t_raw dev, unsigned where, uint16_t value) { unsigned addr; addr = dev | where; write16x(addr, value); } #endif void pci_rawwrite_config16(device_t_raw dev, unsigned where, uint16_t value) { #if MMCONF_SUPPORT pci_mmio_rawwrite_config16(dev, where, value); #else pci_io_rawwrite_config16(dev, where, value); #endif } void pci_io_rawwrite_config32(device_t_raw dev, unsigned where, uint32_t value) { unsigned addr; #if PCI_IO_CFG_EXT == 0 addr = (dev>>4) | where; #else addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16); #endif outl(0x80000000 | (addr & ~3), 0xCF8); outl(value, 0xCFC); } #if MMCONF_SUPPORT void pci_mmio_rawwrite_config32(device_t_raw dev, unsigned where, uint32_t value) { unsigned addr; addr = dev | where; write32x(addr, value); } #endif void pci_rawwrite_config32(device_t_raw dev, unsigned where, uint32_t value) { #if MMCONF_SUPPORT pci_mmio_rawwrite_config32(dev, where, value); #else pci_io_rawwrite_config32(dev, where, value); #endif } void pci_rawmodify_config8(device_t_raw dev, unsigned where, u8 orval,u8 mask) { u8 data=pci_rawread_config8(dev,where); data&=(~mask); data|=orval; pci_rawwrite_config8(dev,where,data); } void pci_rawmodify_config16(device_t_raw dev, unsigned where, uint16_t orval,uint16_t mask) { uint16_t data=pci_rawread_config16(dev,where); data&=(~mask); data|=orval; pci_rawwrite_config16(dev,where,data); } void pci_rawmodify_config32(device_t_raw dev, unsigned where, uint32_t orval,uint32_t mask) { uint32_t data=pci_rawread_config32(dev,where); data&=(~mask); data|=orval; pci_rawwrite_config32(dev,where,data); } void io_rawmodify_config8(u16 where, uint8_t orval,uint8_t mask) { u8 data=inb(where); data&=(~mask); data|=orval; outb(data,where); } void via_pci_inittable(u8 chipversion,struct VIA_PCI_REG_INIT_TABLE* initdata) { u8 i=0; device_t_raw devbxdxfx; for(i=0;;i++) { if((initdata[i].Mask==0)&&(initdata[i].Value==0)&&(initdata[i].Bus==0)&&(initdata[i].ChipRevisionEnd==0xff)&&(initdata[i].ChipRevisionStart==0)&&(initdata[i].Device==0)&&(initdata[i].Function==0)&&(initdata[i].Register==0)) break; if((chipversion>=initdata[i].ChipRevisionStart)&&(chipversion<=initdata[i].ChipRevisionEnd)){ devbxdxfx=PCI_RAWDEV(initdata[i].Bus,initdata[i].Device,initdata[i].Function); pci_rawmodify_config8(devbxdxfx, initdata[i].Register,initdata[i].Value,initdata[i].Mask); } } } #endif