blob: a9829a82ed18dfc681bc0a8f21cf56b8d8d549ab [file] [log] [blame]
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +00001/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2009 Carl-Daniel Hailfinger
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <stdint.h>
22#include <string.h>
23#include <stdlib.h>
24#include <fcntl.h>
25#include <sys/types.h>
26#include <sys/stat.h>
27#include <errno.h>
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000028#include "flash.h"
29
30#if defined(__FreeBSD__) || defined(__DragonFly__)
31int io_fd;
32#endif
33
Christian Ruppert0cdb0312009-05-14 18:57:26 +000034struct pci_dev *pci_dev_find_filter(struct pci_filter filter)
35{
36 struct pci_dev *temp;
37
38 for (temp = pacc->devices; temp; temp = temp->next)
39 if (pci_filter_match(&filter, temp))
40 return temp;
41
42 return NULL;
43}
44
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000045struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device)
46{
47 struct pci_dev *temp;
48 struct pci_filter filter;
49
50 pci_filter_init(NULL, &filter);
51 filter.vendor = vendor;
52 filter.device = device;
53
54 for (temp = pacc->devices; temp; temp = temp->next)
55 if (pci_filter_match(&filter, temp))
56 return temp;
57
58 return NULL;
59}
60
61struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device,
62 uint16_t card_vendor, uint16_t card_device)
63{
64 struct pci_dev *temp;
65 struct pci_filter filter;
66
67 pci_filter_init(NULL, &filter);
68 filter.vendor = vendor;
69 filter.device = device;
70
71 for (temp = pacc->devices; temp; temp = temp->next)
72 if (pci_filter_match(&filter, temp)) {
73 if ((card_vendor ==
74 pci_read_word(temp, PCI_SUBSYSTEM_VENDOR_ID))
75 && (card_device ==
76 pci_read_word(temp, PCI_SUBSYSTEM_ID)))
77 return temp;
78 }
79
80 return NULL;
81}
82
Uwe Hermanna0869322009-05-14 20:41:57 +000083void get_io_perms(void)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000084{
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000085#if defined (__sun) && (defined(__i386) || defined(__amd64))
86 if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) != 0) {
87#elif defined(__FreeBSD__) || defined (__DragonFly__)
88 if ((io_fd = open("/dev/io", O_RDWR)) < 0) {
89#else
90 if (iopl(3) != 0) {
91#endif
Uwe Hermanna0869322009-05-14 20:41:57 +000092 fprintf(stderr, "ERROR: Could not get I/O privileges (%s).\n"
93 "You need to be root.\n", strerror(errno));
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000094 exit(1);
95 }
Uwe Hermanna0869322009-05-14 20:41:57 +000096}
97
98int internal_init(void)
99{
100 int ret = 0;
101
Carl-Daniel Hailfinger3b7e75a2009-05-14 21:41:10 +0000102 get_io_perms();
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000103
104 /* Initialize PCI access for flash enables */
105 pacc = pci_alloc(); /* Get the pci_access structure */
106 /* Set all options you want -- here we stick with the defaults */
107 pci_init(pacc); /* Initialize the PCI library */
108 pci_scan_bus(pacc); /* We want to get the list of devices */
109
110 /* We look at the lbtable first to see if we need a
111 * mainboard specific flash enable sequence.
112 */
113 coreboot_init();
114
115 /* try to enable it. Failure IS an option, since not all motherboards
116 * really need this to be done, etc., etc.
117 */
118 ret = chipset_flash_enable();
119 if (ret == -2) {
120 printf("WARNING: No chipset found. Flash detection "
121 "will most likely fail.\n");
122 }
123
124 board_flash_enable(lb_vendor, lb_part);
125
126 return ret;
127}
128
129int internal_shutdown(void)
130{
131#if defined(__FreeBSD__) || defined(__DragonFly__)
132 close(io_fd);
133#endif
134
135 return 0;
136}
137
Carl-Daniel Hailfinger5820f422009-05-16 21:22:56 +0000138void internal_chip_writeb(uint8_t val, chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000139{
140 *(volatile uint8_t *) addr = val;
141}
142
Carl-Daniel Hailfinger5820f422009-05-16 21:22:56 +0000143void internal_chip_writew(uint16_t val, chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000144{
145 *(volatile uint16_t *) addr = val;
146}
147
Carl-Daniel Hailfinger5820f422009-05-16 21:22:56 +0000148void internal_chip_writel(uint32_t val, chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000149{
150 *(volatile uint32_t *) addr = val;
151}
152
Carl-Daniel Hailfinger5820f422009-05-16 21:22:56 +0000153uint8_t internal_chip_readb(const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000154{
155 return *(volatile uint8_t *) addr;
156}
157
Carl-Daniel Hailfinger5820f422009-05-16 21:22:56 +0000158uint16_t internal_chip_readw(const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000159{
160 return *(volatile uint16_t *) addr;
161}
162
Carl-Daniel Hailfinger5820f422009-05-16 21:22:56 +0000163uint32_t internal_chip_readl(const chipaddr addr)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000164{
165 return *(volatile uint32_t *) addr;
166}
167
Carl-Daniel Hailfinger9ee10772009-05-16 01:23:55 +0000168/* Little-endian fallback for drivers not supporting 16 bit accesses */
Carl-Daniel Hailfinger5820f422009-05-16 21:22:56 +0000169void fallback_chip_writew(uint16_t val, chipaddr addr)
Carl-Daniel Hailfinger9ee10772009-05-16 01:23:55 +0000170{
171 chip_writeb(val & 0xff, addr);
172 chip_writeb((val >> 8) & 0xff, addr + 1);
173}
174
175/* Little-endian fallback for drivers not supporting 16 bit accesses */
Carl-Daniel Hailfinger5820f422009-05-16 21:22:56 +0000176uint16_t fallback_chip_readw(const chipaddr addr)
Carl-Daniel Hailfinger9ee10772009-05-16 01:23:55 +0000177{
178 uint16_t val;
179 val = chip_readb(addr);
180 val |= chip_readb(addr + 1) << 8;
181 return val;
182}
183
184/* Little-endian fallback for drivers not supporting 32 bit accesses */
Carl-Daniel Hailfinger5820f422009-05-16 21:22:56 +0000185void fallback_chip_writel(uint32_t val, chipaddr addr)
Carl-Daniel Hailfinger9ee10772009-05-16 01:23:55 +0000186{
187 chip_writew(val & 0xffff, addr);
188 chip_writew((val >> 16) & 0xffff, addr + 2);
189}
190
191/* Little-endian fallback for drivers not supporting 32 bit accesses */
Carl-Daniel Hailfinger5820f422009-05-16 21:22:56 +0000192uint32_t fallback_chip_readl(const chipaddr addr)
Carl-Daniel Hailfinger9ee10772009-05-16 01:23:55 +0000193{
194 uint32_t val;
195 val = chip_readw(addr);
196 val |= chip_readw(addr + 2) << 16;
197 return val;
198}