on 15/05/2008 05:32 Carl-Daniel Hailfinger said the following:
Hi Andriy,
On 14.05.2008 22:30, Andriy Gapon wrote:
First of all, I have a very rough (and ugly!) patch that makes flashrom
work on FreeBSD. I tried it for reading BIOS image and it worked.
Can you mail the patch to the list? We want flashrom to be
cross-platform and will try to merge the patch or at least a variant of it.
The diff is attached.
But it is really very ugly and hackish.
The most noisy change is that outb has different order of arguments on
Linux and FreeBSD.
I have an old system with MP2-BX-X, please see some description here:
http://www.geocities.com/SiliconValley/3686/delta_mp2.html
It is based on 440BX chipset.
Visually I was able to identify that BIOS flash chip is SST39SF020, but
flashrom didn't initially recognize it.
Some debugging showed that it has JEDEC ids 0x25 for vendor and 0xE5 for
device. Very unusual. So I decided to let you know.
The JEDEC vendor ID 0x25 can mean any of the following companies:
- Tristar
- Zarlink/Mitel
- Chameleon systems
- Kingmax Semiconductor
- Phyworks
- Power-One
None of the companies above are in the BIOS flash market AFAICS.
Probably this is just a strange reading of real flash contents at ID
offsets.
The data that flashrom read are very similar to the data in vendor
provided bios .bin. There are differences in a chunk of about 12k size,
I guess this is where bios stored some config data.
Can you hexdump the first 8 bytes of the bios.bin you read back from
your chip?
Here it is (16 bytes):
00000000 25 e5 2d 6c 68 35 2d 52 16 00 00 9e 1f 00 00 02
It does include -lh5- signature. I was even able to split it into
several chunks on that signature, decompress the chunks and even
disassemble some pieces. Interestingly enough this BIOS contains
original.tm1 file in addition to original.tmp and the former seems to be
a trailer of the latter.
Hmm, I see that 25 e5 is present here. So it might mean that my ported
code didn't properly enable flash chip communication?
--
Andriy Gapon
Index: flash.h
===================================================================
--- flash.h (revision 3225)
+++ flash.h (working copy)
@@ -286,13 +286,14 @@
void myusec_delay(int time);
void myusec_calibrate_delay();
+#if 0
/* PCI handling for board/chipset_enable */
struct pci_access *pacc;
struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device);
struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device,
uint16_t card_vendor, uint16_t card_device);
+#endif
-
/* board_enable.c */
int board_flash_enable(const char *vendor, const char *part);
void print_supported_boards(void);
Index: spi.c
===================================================================
--- spi.c (revision 3225)
+++ spi.c (working copy)
@@ -23,11 +23,13 @@
*/
#include <stdio.h>
-#include <pci/pci.h>
#include <stdint.h>
#include <string.h>
#include "flash.h"
+#include <machine/cpufunc.h>
+#define lin_outb(x, y) outb((y), (x))
+
#define ITE_SUPERIO_PORT1 0x2e
#define ITE_SUPERIO_PORT2 0x4e
@@ -102,14 +104,14 @@
/* Generic Super I/O helper functions */
uint8_t regval(uint16_t port, uint8_t reg)
{
- outb(reg, port);
+ lin_outb(reg, port);
return inb(port + 1);
}
void regwrite(uint16_t port, uint8_t reg, uint8_t val)
{
- outb(reg, port);
- outb(val, port + 1);
+ lin_outb(reg, port);
+ lin_outb(val, port + 1);
}
/* Helper functions for most recent ITE IT87xx Super I/O chips */
@@ -117,13 +119,13 @@
#define CHIP_ID_BYTE2_REG 0x21
static void enter_conf_mode_ite(uint16_t port)
{
- outb(0x87, port);
- outb(0x01, port);
- outb(0x55, port);
+ lin_outb(0x87, port);
+ lin_outb(0x01, port);
+ lin_outb(0x55, port);
if (port == ITE_SUPERIO_PORT1)
- outb(0x55, port);
+ lin_outb(0x55, port);
else
- outb(0xaa, port);
+ lin_outb(0xaa, port);
}
static void exit_conf_mode_ite(uint16_t port)
@@ -194,27 +199,27 @@
}
switch (writecnt) {
case 1:
- outb(writearr[0], port + 1);
+ lin_outb(writearr[0], port + 1);
writeenc = 0x0;
break;
case 2:
- outb(writearr[0], port + 1);
- outb(writearr[1], port + 7);
+ lin_outb(writearr[0], port + 1);
+ lin_outb(writearr[1], port + 7);
writeenc = 0x1;
break;
case 4:
- outb(writearr[0], port + 1);
- outb(writearr[1], port + 4);
- outb(writearr[2], port + 3);
- outb(writearr[3], port + 2);
+ lin_outb(writearr[0], port + 1);
+ lin_outb(writearr[1], port + 4);
+ lin_outb(writearr[2], port + 3);
+ lin_outb(writearr[3], port + 2);
writeenc = 0x2;
break;
case 5:
- outb(writearr[0], port + 1);
- outb(writearr[1], port + 4);
- outb(writearr[2], port + 3);
- outb(writearr[3], port + 2);
- outb(writearr[4], port + 7);
+ lin_outb(writearr[0], port + 1);
+ lin_outb(writearr[1], port + 4);
+ lin_outb(writearr[2], port + 3);
+ lin_outb(writearr[3], port + 2);
+ lin_outb(writearr[4], port + 7);
writeenc = 0x3;
break;
default:
@@ -226,7 +231,7 @@
* Note:
* We can't use writecnt directly, but have to use a strange encoding.
*/
- outb(((0x4 + (fast_spi ? 1 : 0)) << 4) | ((readcnt & 0x3) << 2) | (writeenc), port);
+ lin_outb(((0x4 + (fast_spi ? 1 : 0)) << 4) | ((readcnt & 0x3) << 2) | (writeenc), port);
if (readcnt > 0) {
do {
@@ -454,12 +459,12 @@
int i;
generic_spi_write_enable();
- outb(0x06 , it8716f_flashport + 1);
- outb(((2 + (fast_spi ? 1 : 0)) << 4), it8716f_flashport);
+ lin_outb(0x06 , it8716f_flashport + 1);
+ lin_outb(((2 + (fast_spi ? 1 : 0)) << 4), it8716f_flashport);
for (i = 0; i < 256; i++) {
bios[256 * block + i] = buf[256 * block + i];
}
- outb(0, it8716f_flashport);
+ lin_outb(0, it8716f_flashport);
/* Wait until the Write-In-Progress bit is cleared.
* This usually takes 1-10 ms, so wait in 1 ms steps.
*/
@@ -529,7 +534,7 @@
myusec_delay(10);
}
/* resume normal ops... */
- outb(0x20, it8716f_flashport);
+ lin_outb(0x20, it8716f_flashport);
return 0;
}
Index: Makefile
===================================================================
--- Makefile (revision 3225)
+++ Makefile (working copy)
@@ -11,12 +11,12 @@
INSTALL = /usr/bin/install
PREFIX = /usr/local
#CFLAGS = -O2 -g -Wall -Werror
-CFLAGS = -Os -Wall -Werror -DDISABLE_DOC # -DTS5300
+CFLAGS = -Os -Wall -DDISABLE_DOC # -DTS5300
OS_ARCH = $(shell uname)
ifeq ($(OS_ARCH), SunOS)
-LDFLAGS = -lpci -lz
+LDFLAGS = -lz
else
-LDFLAGS = -lpci -lz -static
+LDFLAGS = -lz -static
STRIP_ARGS = -s
endif
Index: chipset_enable.c
===================================================================
--- chipset_enable.c (revision 3225)
+++ chipset_enable.c (working copy)
@@ -26,15 +26,154 @@
#define _LARGEFILE64_SOURCE
#include <stdio.h>
-#include <pci/pci.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
+#include <string.h>
#include "flash.h"
+#include <sys/ioctl.h>
+#include <sys/pciio.h>
+#include <machine/cpufunc.h>
+
+#define lin_outb(x, y) outb((y), (x))
+#define pci_dev pcisel
+static int pcifd;
+
+static struct pcisel * pci_dev_find(uint16_t vendor, uint16_t device)
+{
+ struct pci_conf match;
+ struct pci_match_conf pattern;
+ struct pci_conf_io confio;
+ struct pcisel * ret;
+ int rc;
+
+ memset(&match, 0, sizeof(match));
+ memset(&pattern, 0, sizeof(pattern));
+ memset(&confio, 0, sizeof(confio));
+
+ pattern.pc_vendor = vendor;
+ pattern.pc_device = device;
+ pattern.flags = PCI_GETCONF_MATCH_VENDOR | PCI_GETCONF_MATCH_DEVICE;
+
+ confio.pat_buf_len = sizeof(pattern);
+ confio.num_patterns = 1;
+ confio.patterns = &pattern;
+ confio.match_buf_len = sizeof(match);
+ confio.matches = &match;
+
+ rc = ioctl(pcifd, PCIOCGETCONF, &confio);
+ if (rc != 0)
+ return NULL;
+
+ if (confio.status == PCI_GETCONF_ERROR)
+ return NULL;
+
+ if (confio.num_matches != 1)
+ return NULL;
+
+ ret = (struct pcisel *)malloc(sizeof(*ret));
+ *ret = match.pc_sel;
+
+ printf("pci_dev_find success:\n");
+ printf("pc_domain = %#x, pc_bus = %#x, pc_dev = %#x, pc_func = %#x\n", ret->pc_domain, ret->pc_bus, ret->pc_dev, ret->pc_func);
+ return ret;
+}
+
+static uint8_t pci_read_byte(struct pcisel *dev, uint8_t reg)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 1;
+ io.pi_data = 0;
+
+ if (ioctl(pcifd, PCIOCREAD, &io) < 0)
+ printf("pci_read_byte failed\n");
+
+ return io.pi_data;
+}
+
+static uint16_t pci_read_word(struct pcisel *dev, uint8_t reg)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 2;
+ io.pi_data = 0;
+
+ if (ioctl(pcifd, PCIOCREAD, &io) < 0)
+ printf("pci_read_word failed\n");
+
+ return io.pi_data;
+}
+
+static uint32_t pci_read_long(struct pcisel *dev, uint8_t reg)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 4;
+ io.pi_data = 0;
+
+ if (ioctl(pcifd, PCIOCREAD, &io) < 0)
+ printf("pci_read_long failed\n");
+
+ return io.pi_data;
+}
+
+static void pci_write_byte(struct pcisel *dev, uint8_t reg, uint8_t val)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 1;
+ io.pi_data = val;
+
+ if (ioctl(pcifd, PCIOCWRITE, &io) < 0)
+ printf("pci_write_byte failed\n");
+
+ return;
+}
+
+static void pci_write_word(struct pcisel *dev, uint8_t reg, uint16_t val)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 2;
+ io.pi_data = val;
+
+ if (ioctl(pcifd, PCIOCWRITE, &io) < 0)
+ printf("pci_write_word failed\n");
+
+ return;
+}
+
+static void pci_write_long(struct pcisel *dev, uint8_t reg, uint32_t val)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 4;
+ io.pi_data = val;
+
+ ioctl(pcifd, PCIOCWRITE, &io);
+ if (ioctl(pcifd, PCIOCWRITE, &io) < 0)
+ printf("pci_write_long failed\n");
+
+ return;
+}
+
static int enable_flash_ali_m1533(struct pci_dev *dev, const char *name)
{
uint8_t tmp;
@@ -65,37 +204,37 @@
/* The same thing on SiS 950 Super I/O side... */
/* First probe for Super I/O on config port 0x2e. */
- outb(0x87, 0x2e);
- outb(0x01, 0x2e);
- outb(0x55, 0x2e);
- outb(0x55, 0x2e);
+ lin_outb(0x87, 0x2e);
+ lin_outb(0x01, 0x2e);
+ lin_outb(0x55, 0x2e);
+ lin_outb(0x55, 0x2e);
if (inb(0x2f) != 0x87) {
/* If that failed, try config port 0x4e. */
- outb(0x87, 0x4e);
- outb(0x01, 0x4e);
- outb(0x55, 0x4e);
- outb(0xaa, 0x4e);
+ lin_outb(0x87, 0x4e);
+ lin_outb(0x01, 0x4e);
+ lin_outb(0x55, 0x4e);
+ lin_outb(0xaa, 0x4e);
if (inb(0x4f) != 0x87) {
printf("Can not access SiS 950\n");
return -1;
}
- outb(0x24, 0x4e);
+ lin_outb(0x24, 0x4e);
b = inb(0x4f) | 0xfc;
- outb(0x24, 0x4e);
- outb(b, 0x4f);
- outb(0x02, 0x4e);
- outb(0x02, 0x4f);
+ lin_outb(0x24, 0x4e);
+ lin_outb(b, 0x4f);
+ lin_outb(0x02, 0x4e);
+ lin_outb(0x02, 0x4f);
}
- outb(0x24, 0x2e);
+ lin_outb(0x24, 0x2e);
printf("2f is %#x\n", inb(0x2f));
b = inb(0x2f) | 0xfc;
- outb(0x24, 0x2e);
- outb(b, 0x2f);
+ lin_outb(0x24, 0x2e);
+ lin_outb(b, 0x2f);
- outb(0x02, 0x2e);
- outb(0x02, 0x2f);
+ lin_outb(0x02, 0x2e);
+ lin_outb(0x02, 0x2f);
return 0;
}
@@ -309,8 +448,8 @@
return -1;
}
- if (lseek64(fd_msr, (off64_t) MSR_RCONF_DEFAULT, SEEK_SET) == -1) {
- perror("lseek64");
+ if (lseek(fd_msr, (off_t) MSR_RCONF_DEFAULT, SEEK_SET) == -1) {
+ perror("lseek");
printf("Cannot operate on MSR. Did you run 'modprobe msr'?\n");
close(fd_msr);
return -1;
@@ -324,8 +463,8 @@
if (buf[7] != 0x22) {
buf[7] &= 0xfb;
- if (lseek64(fd_msr, (off64_t) MSR_RCONF_DEFAULT, SEEK_SET) == -1) {
- perror("lseek64");
+ if (lseek(fd_msr, (off_t) MSR_RCONF_DEFAULT, SEEK_SET) == -1) {
+ perror("lseek");
close(fd_msr);
return -1;
}
@@ -337,8 +476,8 @@
}
}
- if (lseek64(fd_msr, (off64_t) MSR_NORF_CTL, SEEK_SET) == -1) {
- perror("lseek64");
+ if (lseek(fd_msr, (off_t) MSR_NORF_CTL, SEEK_SET) == -1) {
+ perror("lseek");
close(fd_msr);
return -1;
}
@@ -352,8 +491,8 @@
/* Raise WE_CS3 bit. */
buf[0] |= 0x08;
- if (lseek64(fd_msr, (off64_t) MSR_NORF_CTL, SEEK_SET) == -1) {
- perror("lseek64");
+ if (lseek(fd_msr, (off_t) MSR_NORF_CTL, SEEK_SET) == -1) {
+ perror("lseek");
close(fd_msr);
return -1;
}
@@ -461,7 +600,7 @@
return 0;
}
-
+#if 0
/* ATI Technologies Inc IXP SB400 PCI-ISA Bridge (rev 80) */
static int enable_flash_sb400(struct pci_dev *dev, const char *name)
{
@@ -497,16 +636,16 @@
/* Now become a bit silly. */
tmp = inb(0xc6f);
- outb(tmp, 0xeb);
- outb(tmp, 0xeb);
+ lin_outb(tmp, 0xeb);
+ lin_outb(tmp, 0xeb);
tmp |= 0x40;
- outb(tmp, 0xc6f);
- outb(tmp, 0xeb);
- outb(tmp, 0xeb);
+ lin_outb(tmp, 0xc6f);
+ lin_outb(tmp, 0xeb);
+ lin_outb(tmp, 0xeb);
return 0;
}
-
+#endif
static int enable_flash_mcp55(struct pci_dev *dev, const char *name)
{
uint8_t old, new, byte;
@@ -618,7 +757,7 @@
{0x10de, 0x0365, "NVIDIA MCP55", enable_flash_mcp55}, /* LPC */
{0x10de, 0x0366, "NVIDIA MCP55", enable_flash_mcp55}, /* LPC */
{0x10de, 0x0367, "NVIDIA MCP55", enable_flash_mcp55}, /* Pro */
- {0x1002, 0x4377, "ATI SB400", enable_flash_sb400},
+/* {0x1002, 0x4377, "ATI SB400", enable_flash_sb400},*/
{0x1166, 0x0205, "Broadcom HT-1000", enable_flash_ht1000},
};
@@ -639,6 +778,12 @@
int ret = -2; /* Nothing! */
int i;
+ pcifd = open("/dev/pci", O_RDWR);
+ if (pcifd < 0) {
+ perror("/dev/pci");
+ return ret;
+ }
+
/* Now let's try to find the chipset we have... */
for (i = 0; i < ARRAY_SIZE(enables); i++) {
dev = pci_dev_find(enables[i].vendor, enables[i].device);
Index: flashrom.c
===================================================================
--- flashrom.c (revision 3225)
+++ flashrom.c (working copy)
@@ -30,7 +30,6 @@
#include <string.h>
#include <stdlib.h>
#include <getopt.h>
-#include <pci/pci.h>
/* for iopl */
#if defined (__sun) && (defined(__i386) || defined(__amd64))
#include <strings.h>
@@ -40,44 +39,155 @@
#endif
#include "flash.h"
-char *chip_to_probe = NULL;
-struct pci_access *pacc; /* For board and chipset_enable */
-int exclude_start_page, exclude_end_page;
-int force = 0, verbose = 0;
-int fd_mem;
-struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device)
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/pciio.h>
+#include <machine/cpufunc.h>
+
+#define lin_outb(x, y) outb((y), (x))
+#define pci_dev pcisel
+static int pcifd;
+
+static struct pcisel * pci_dev_find(uint16_t vendor, uint16_t device)
{
- struct pci_dev *temp;
- struct pci_filter filter;
+ struct pci_conf match;
+ struct pci_match_conf pattern;
+ struct pci_conf_io confio;
+ struct pcisel * ret;
+ int rc;
- pci_filter_init(NULL, &filter);
- filter.vendor = vendor;
- filter.device = device;
+ memset(&match, 0, sizeof(match));
+ memset(&pattern, 0, sizeof(pattern));
+ memset(&confio, 0, sizeof(confio));
- for (temp = pacc->devices; temp; temp = temp->next)
- if (pci_filter_match(&filter, temp))
- return temp;
+ pattern.pc_vendor = vendor;
+ pattern.pc_device = device;
+ pattern.flags = PCI_GETCONF_MATCH_VENDOR | PCI_GETCONF_MATCH_DEVICE;
- return NULL;
+ confio.pat_buf_len = sizeof(pattern);
+ confio.num_patterns = 1;
+ confio.patterns = &pattern;
+ confio.match_buf_len = sizeof(match);
+ confio.matches = &match;
+
+ rc = ioctl(pcifd, PCIOCGETCONF, &confio);
+ if (rc != 0)
+ return NULL;
+
+ if (confio.status == PCI_GETCONF_ERROR)
+ return NULL;
+
+ if (confio.num_matches != 1)
+ return NULL;
+
+ ret = (struct pcisel *)malloc(sizeof(*ret));
+ *ret = match.pc_sel;
+ return ret;
}
+static uint8_t pci_read_byte(struct pcisel *dev, uint8_t reg)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 1;
+ io.pi_data = 0;
+
+ ioctl(pcifd, PCIOCREAD, &io);
+
+ return io.pi_data;
+}
+
+static uint16_t pci_read_word(struct pcisel *dev, uint8_t reg)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 2;
+ io.pi_data = 0;
+
+ ioctl(pcifd, PCIOCREAD, &io);
+
+ return io.pi_data;
+}
+
+static uint32_t pci_read_long(struct pcisel *dev, uint8_t reg)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 4;
+ io.pi_data = 0;
+
+ ioctl(pcifd, PCIOCREAD, &io);
+
+ return io.pi_data;
+}
+
+static void pci_write_byte(struct pcisel *dev, uint8_t reg, uint8_t val)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 1;
+ io.pi_data = val;
+
+ ioctl(pcifd, PCIOCWRITE, &io);
+
+ return;
+}
+
+static void pci_write_word(struct pcisel *dev, uint16_t reg, uint16_t val)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 2;
+ io.pi_data = val;
+
+ ioctl(pcifd, PCIOCWRITE, &io);
+
+ return;
+}
+
+static void pci_write_long(struct pcisel *dev, uint32_t reg, uint32_t val)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 4;
+ io.pi_data = val;
+
+ ioctl(pcifd, PCIOCWRITE, &io);
+
+ return;
+}
+
+char *chip_to_probe = NULL;
+struct pci_access *pacc; /* For board and chipset_enable */
+int exclude_start_page, exclude_end_page;
+int force = 0, verbose = 0;
+int fd_mem;
+
struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device,
uint16_t card_vendor, uint16_t card_device)
{
struct pci_dev *temp;
- struct pci_filter filter;
+ temp = pci_dev_find(vendor, device);
- pci_filter_init(NULL, &filter);
- filter.vendor = vendor;
- filter.device = device;
+ if (temp == NULL)
+ return NULL;
- for (temp = pacc->devices; temp; temp = temp->next)
- if (pci_filter_match(&filter, temp)) {
- if ((card_vendor == pci_read_word(temp, 0x2C)) &&
- (card_device == pci_read_word(temp, 0x2E)))
- return temp;
- }
+ if ((card_vendor == pci_read_word(temp, 0x2C)) &&
+ (card_device == pci_read_word(temp, 0x2E)))
+ return temp;
return NULL;
}
@@ -246,6 +356,7 @@
int option_index = 0;
int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0;
int ret = 0;
+ int iofd;
static struct option long_options[] = {
{"read", 0, 0, 'r'},
@@ -358,22 +469,17 @@
if (optind < argc)
filename = argv[optind++];
- /* First get full io access */
-#if defined (__sun) && (defined(__i386) || defined(__amd64))
- if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) != 0) {
-#else
- if (iopl(3) != 0) {
-#endif
- fprintf(stderr, "ERROR: iopl failed: "%s"\n",
- strerror(errno));
- exit(1);
- }
- /* Initialize PCI access for flash enables */
- pacc = pci_alloc(); /* Get the pci_access structure */
- /* Set all options you want -- here we stick with the defaults */
- pci_init(pacc); /* Initialize the PCI library */
- pci_scan_bus(pacc); /* We want to get the list of devices */
+ iofd = open("/dev/io", O_RDWR);
+ if (iofd < 0) {
+ perror("/dev/io");
+ exit(1);
+ }
+ pcifd = open("/dev/pci", O_RDWR);
+ if (pcifd < 0) {
+ perror("/dev/pci");
+ exit(1);
+ }
/* Open the memory device. A lot of functions need it */
if ((fd_mem = open(MEM_DEV, O_RDWR)) < 0) {
Index: board_enable.c
===================================================================
--- board_enable.c (revision 3225)
+++ board_enable.c (working copy)
@@ -25,48 +25,176 @@
*/
#include <stdio.h>
-#include <pci/pci.h>
#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include "flash.h"
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/pciio.h>
+#include <machine/cpufunc.h>
+
+#define lin_outb(x, y) outb((y), (x))
+#define pci_dev pcisel
+static int pcifd;
+
+static struct pcisel * pci_dev_find(uint16_t vendor, uint16_t device)
+{
+ struct pci_conf match;
+ struct pci_match_conf pattern;
+ struct pci_conf_io confio;
+ struct pcisel * ret;
+ int rc;
+
+ memset(&match, 0, sizeof(match));
+ memset(&pattern, 0, sizeof(pattern));
+ memset(&confio, 0, sizeof(confio));
+
+ pattern.pc_vendor = vendor;
+ pattern.pc_device = device;
+ pattern.flags = PCI_GETCONF_MATCH_VENDOR | PCI_GETCONF_MATCH_DEVICE;
+
+ confio.pat_buf_len = sizeof(pattern);
+ confio.num_patterns = 1;
+ confio.patterns = &pattern;
+ confio.match_buf_len = sizeof(match);
+ confio.matches = &match;
+
+ rc = ioctl(pcifd, PCIOCGETCONF, &confio);
+ if (rc != 0)
+ return NULL;
+
+ if (confio.status == PCI_GETCONF_ERROR)
+ return NULL;
+
+ if (confio.num_matches != 1)
+ return NULL;
+
+ ret = (struct pcisel *)malloc(sizeof(*ret));
+ *ret = match.pc_sel;
+ return ret;
+}
+
+static uint8_t pci_read_byte(struct pcisel *dev, uint8_t reg)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 1;
+ io.pi_data = 0;
+
+ ioctl(pcifd, PCIOCREAD, &io);
+
+ return io.pi_data;
+}
+
+static uint16_t pci_read_word(struct pcisel *dev, uint8_t reg)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 2;
+ io.pi_data = 0;
+
+ ioctl(pcifd, PCIOCREAD, &io);
+
+ return io.pi_data;
+}
+
+static uint32_t pci_read_long(struct pcisel *dev, uint8_t reg)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 4;
+ io.pi_data = 0;
+
+ ioctl(pcifd, PCIOCREAD, &io);
+
+ return io.pi_data;
+}
+
+static void pci_write_byte(struct pcisel *dev, uint8_t reg, uint8_t val)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 1;
+ io.pi_data = val;
+
+ ioctl(pcifd, PCIOCWRITE, &io);
+
+ return;
+}
+
+static void pci_write_word(struct pcisel *dev, uint16_t reg, uint16_t val)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 2;
+ io.pi_data = val;
+
+ ioctl(pcifd, PCIOCWRITE, &io);
+
+ return;
+}
+
+static void pci_write_long(struct pcisel *dev, uint32_t reg, uint32_t val)
+{
+ struct pci_io io;
+
+ io.pi_sel = *dev;
+ io.pi_reg = reg;
+ io.pi_width = 4;
+ io.pi_data = val;
+
+ ioctl(pcifd, PCIOCWRITE, &io);
+
+ return;
+}
/*
* Helper functions for many Winbond Super I/Os of the W836xx range.
*/
/* Enter extended functions */
static void w836xx_ext_enter(uint16_t port)
{
- outb(0x87, port);
- outb(0x87, port);
+ lin_outb(0x87, port);
+ lin_outb(0x87, port);
}
/* Leave extended functions */
static void w836xx_ext_leave(uint16_t port)
{
- outb(0xAA, port);
+ lin_outb(0xAA, port);
}
/* General functions for reading/writing Winbond Super I/Os. */
static unsigned char wbsio_read(uint16_t index, uint8_t reg)
{
- outb(reg, index);
+ lin_outb(reg, index);
return inb(index + 1);
}
static void wbsio_write(uint16_t index, uint8_t reg, uint8_t data)
{
- outb(reg, index);
- outb(data, index + 1);
+ lin_outb(reg, index);
+ lin_outb(data, index + 1);
}
static void wbsio_mask(uint16_t index, uint8_t reg, uint8_t data, uint8_t mask)
{
uint8_t tmp;
- outb(reg, index);
+ lin_outb(reg, index);
tmp = inb(index + 1) & ~mask;
- outb(tmp | (data & mask), index + 1);
+ lin_outb(tmp | (data & mask), index + 1);
}
/**
@@ -174,7 +302,7 @@
/* Enable GPIO15 which is connected to write protect. */
val = inb(base + 0x4D);
val |= 0x80;
- outb(val, base + 0x4D);
+ lin_outb(val, base + 0x4D);
return 0;
}
@@ -249,13 +377,13 @@
#define ASUSP5A_LOOP 5000
- outb(0x00, 0xE807);
- outb(0xEF, 0xE803);
+ lin_outb(0x00, 0xE807);
+ lin_outb(0xEF, 0xE803);
- outb(0xFF, 0xE800);
+ lin_outb(0xFF, 0xE800);
for (i = 0; i < ASUSP5A_LOOP; i++) {
- outb(0xE1, 0xFF);
+ lin_outb(0xE1, 0xFF);
if (inb(0xE800) & 0x04)
break;
}
@@ -265,10 +393,10 @@
return -1;
}
- outb(0x20, 0xE801);
- outb(0x20, 0xE1);
+ lin_outb(0x20, 0xE801);
+ lin_outb(0x20, 0xE1);
- outb(0xFF, 0xE802);
+ lin_outb(0xFF, 0xE802);
for (i = 0; i < ASUSP5A_LOOP; i++) {
tmp = inb(0xE800);
@@ -284,18 +412,18 @@
tmp = inb(0xE804);
tmp &= ~0x02;
- outb(0x00, 0xE807);
- outb(0xEE, 0xE803);
+ lin_outb(0x00, 0xE807);
+ lin_outb(0xEE, 0xE803);
- outb(tmp, 0xE804);
+ lin_outb(tmp, 0xE804);
- outb(0xFF, 0xE800);
- outb(0xE1, 0xFF);
+ lin_outb(0xFF, 0xE800);
+ lin_outb(0xE1, 0xFF);
- outb(0x20, 0xE801);
- outb(0x20, 0xE1);
+ lin_outb(0x20, 0xE801);
+ lin_outb(0x20, 0xE1);
- outb(0xFF, 0xE802);
+ lin_outb(0xFF, 0xE802);
for (i = 0; i < ASUSP5A_LOOP; i++) {
tmp = inb(0xE800);
@@ -316,9 +444,9 @@
uint8_t byte;
/* Set GPIO lines in the Broadcom HT-1000 southbridge. */
- outb(0x45, 0xcd6);
+ lin_outb(0x45, 0xcd6);
byte = inb(0xcd7);
- outb(byte | 0x20, 0xcd7);
+ lin_outb(byte | 0x20, 0xcd7);
return 0;
}
@@ -332,12 +460,12 @@
/* Raise GPIO22. */
tmp = inb(0x4036);
- outb(tmp, 0xEB);
+ lin_outb(tmp, 0xEB);
tmp |= 0x40;
- outb(tmp, 0x4036);
- outb(tmp, 0xEB);
+ lin_outb(tmp, 0x4036);
+ lin_outb(tmp, 0xEB);
return 0;
}
@@ -363,7 +491,7 @@
val = inb(port);
val |= 0x80; /* Top Block Lock -- pin 8 of PLCC32 */
val |= 0x40; /* Lower Blocks Lock -- pin 7 of PLCC32 */
- outb(val, port);
+ lin_outb(val, port);
return 0;
}
@@ -645,6 +773,12 @@
struct board_pciid_enable *board = NULL;
int ret = 0;
+ pcifd = open("/dev/pci", O_RDWR);
+ if (pcifd < 0) {
+ perror("/dev/pci");
+ return -1;
+ }
+
if (part)
board = board_match_coreboot_name(vendor, part);