blob: f10d0d513dd3198781822dae849380e44c52ba8d [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>
28#include <pci/pci.h>
29#include "flash.h"
30
31#if defined(__FreeBSD__) || defined(__DragonFly__)
32int io_fd;
33#endif
34
35struct pci_access *pacc; /* For board and chipset_enable */
36
Christian Ruppert0cdb0312009-05-14 18:57:26 +000037struct pci_dev *pci_dev_find_filter(struct pci_filter filter)
38{
39 struct pci_dev *temp;
40
41 for (temp = pacc->devices; temp; temp = temp->next)
42 if (pci_filter_match(&filter, temp))
43 return temp;
44
45 return NULL;
46}
47
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000048struct pci_dev *pci_dev_find(uint16_t vendor, uint16_t device)
49{
50 struct pci_dev *temp;
51 struct pci_filter filter;
52
53 pci_filter_init(NULL, &filter);
54 filter.vendor = vendor;
55 filter.device = device;
56
57 for (temp = pacc->devices; temp; temp = temp->next)
58 if (pci_filter_match(&filter, temp))
59 return temp;
60
61 return NULL;
62}
63
64struct pci_dev *pci_card_find(uint16_t vendor, uint16_t device,
65 uint16_t card_vendor, uint16_t card_device)
66{
67 struct pci_dev *temp;
68 struct pci_filter filter;
69
70 pci_filter_init(NULL, &filter);
71 filter.vendor = vendor;
72 filter.device = device;
73
74 for (temp = pacc->devices; temp; temp = temp->next)
75 if (pci_filter_match(&filter, temp)) {
76 if ((card_vendor ==
77 pci_read_word(temp, PCI_SUBSYSTEM_VENDOR_ID))
78 && (card_device ==
79 pci_read_word(temp, PCI_SUBSYSTEM_ID)))
80 return temp;
81 }
82
83 return NULL;
84}
85
Uwe Hermanna0869322009-05-14 20:41:57 +000086void get_io_perms(void)
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000087{
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000088#if defined (__sun) && (defined(__i386) || defined(__amd64))
89 if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) != 0) {
90#elif defined(__FreeBSD__) || defined (__DragonFly__)
91 if ((io_fd = open("/dev/io", O_RDWR)) < 0) {
92#else
93 if (iopl(3) != 0) {
94#endif
Uwe Hermanna0869322009-05-14 20:41:57 +000095 fprintf(stderr, "ERROR: Could not get I/O privileges (%s).\n"
96 "You need to be root.\n", strerror(errno));
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +000097 exit(1);
98 }
Uwe Hermanna0869322009-05-14 20:41:57 +000099}
100
101int internal_init(void)
102{
103 int ret = 0;
104
Carl-Daniel Hailfinger3b7e75a2009-05-14 21:41:10 +0000105 get_io_perms();
Carl-Daniel Hailfinger702218d2009-05-08 17:43:22 +0000106
107 /* Initialize PCI access for flash enables */
108 pacc = pci_alloc(); /* Get the pci_access structure */
109 /* Set all options you want -- here we stick with the defaults */
110 pci_init(pacc); /* Initialize the PCI library */
111 pci_scan_bus(pacc); /* We want to get the list of devices */
112
113 /* We look at the lbtable first to see if we need a
114 * mainboard specific flash enable sequence.
115 */
116 coreboot_init();
117
118 /* try to enable it. Failure IS an option, since not all motherboards
119 * really need this to be done, etc., etc.
120 */
121 ret = chipset_flash_enable();
122 if (ret == -2) {
123 printf("WARNING: No chipset found. Flash detection "
124 "will most likely fail.\n");
125 }
126
127 board_flash_enable(lb_vendor, lb_part);
128
129 return ret;
130}
131
132int internal_shutdown(void)
133{
134#if defined(__FreeBSD__) || defined(__DragonFly__)
135 close(io_fd);
136#endif
137
138 return 0;
139}
140
141void internal_chip_writeb(uint8_t val, volatile void *addr)
142{
143 *(volatile uint8_t *) addr = val;
144}
145
146void internal_chip_writew(uint16_t val, volatile void *addr)
147{
148 *(volatile uint16_t *) addr = val;
149}
150
151void internal_chip_writel(uint32_t val, volatile void *addr)
152{
153 *(volatile uint32_t *) addr = val;
154}
155
156uint8_t internal_chip_readb(const volatile void *addr)
157{
158 return *(volatile uint8_t *) addr;
159}
160
161uint16_t internal_chip_readw(const volatile void *addr)
162{
163 return *(volatile uint16_t *) addr;
164}
165
166uint32_t internal_chip_readl(const volatile void *addr)
167{
168 return *(volatile uint32_t *) addr;
169}
170
Carl-Daniel Hailfinger9ee10772009-05-16 01:23:55 +0000171/* Little-endian fallback for drivers not supporting 16 bit accesses */
172void fallback_chip_writew(uint16_t val, volatile void *addr)
173{
174 chip_writeb(val & 0xff, addr);
175 chip_writeb((val >> 8) & 0xff, addr + 1);
176}
177
178/* Little-endian fallback for drivers not supporting 16 bit accesses */
179uint16_t fallback_chip_readw(const volatile void *addr)
180{
181 uint16_t val;
182 val = chip_readb(addr);
183 val |= chip_readb(addr + 1) << 8;
184 return val;
185}
186
187/* Little-endian fallback for drivers not supporting 32 bit accesses */
188void fallback_chip_writel(uint32_t val, volatile void *addr)
189{
190 chip_writew(val & 0xffff, addr);
191 chip_writew((val >> 16) & 0xffff, addr + 2);
192}
193
194/* Little-endian fallback for drivers not supporting 32 bit accesses */
195uint32_t fallback_chip_readl(const volatile void *addr)
196{
197 uint32_t val;
198 val = chip_readw(addr);
199 val |= chip_readw(addr + 2) << 16;
200 return val;
201}