blob: cd2f71302eef9fa5d04fce44c5ca3bb1598ca9f9 [file] [log] [blame]
Marc Jones8ae8c882007-12-19 01:32:08 +00001/*
Stefan Reinauer7e61e452008-01-18 10:35:56 +00002 * This file is part of the coreboot project.
Marc Jones8ae8c882007-12-19 01:32:08 +00003 *
Timothy Pearson82982a12015-01-23 20:26:31 -06004 * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
Marc Jones8ae8c882007-12-19 01:32:08 +00005 * Copyright (C) 2007 Advanced Micro Devices, Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
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.
Marc Jones8ae8c882007-12-19 01:32:08 +000015 */
16
17
18#define RES_DEBUG 0
19
20static void setup_resource_map(const u32 *register_values, u32 max)
21{
22 u32 i;
Stefan Reinauer65b72ab2015-01-05 12:59:54 -080023// printk(BIOS_DEBUG, "setting up resource map....");
Marc Jones8ae8c882007-12-19 01:32:08 +000024
25 for(i = 0; i < max; i += 3) {
26 device_t dev;
27 u32 where;
28 u32 reg;
29
30 dev = register_values[i] & ~0xff;
31 where = register_values[i] & 0xff;
32 reg = pci_read_config32(dev, where);
33 reg &= register_values[i+1];
34 reg |= register_values[i+2];
35 pci_write_config32(dev, where, reg);
36 }
Stefan Reinauer65b72ab2015-01-05 12:59:54 -080037// printk(BIOS_DEBUG, "done.\n");
Marc Jones8ae8c882007-12-19 01:32:08 +000038}
39
40
Stefan Reinauer817d7542010-07-08 00:37:23 +000041void setup_resource_map_offset(const u32 *register_values, u32 max, u32 offset_pci_dev, u32 offset_io_base)
Marc Jones8ae8c882007-12-19 01:32:08 +000042{
43 u32 i;
Stefan Reinauer65b72ab2015-01-05 12:59:54 -080044// printk(BIOS_DEBUG, "setting up resource map offset....");
Marc Jones8ae8c882007-12-19 01:32:08 +000045 for(i = 0; i < max; i += 3) {
46 device_t dev;
47 u32 where;
48 unsigned long reg;
49 dev = (register_values[i] & ~0xfff) + offset_pci_dev;
50 where = register_values[i] & 0xfff;
51 reg = pci_read_config32(dev, where);
52 reg &= register_values[i+1];
53 reg |= register_values[i+2] + offset_io_base;
54 pci_write_config32(dev, where, reg);
55 }
Stefan Reinauer65b72ab2015-01-05 12:59:54 -080056// printk(BIOS_DEBUG, "done.\n");
Marc Jones8ae8c882007-12-19 01:32:08 +000057}
58
59#define RES_PCI_IO 0x10
60#define RES_PORT_IO_8 0x22
61#define RES_PORT_IO_32 0x20
62#define RES_MEM_IO 0x40
63
Stefan Reinauer817d7542010-07-08 00:37:23 +000064void setup_resource_map_x_offset(const u32 *register_values, u32 max, u32 offset_pci_dev, u32 offset_io_base)
Marc Jones8ae8c882007-12-19 01:32:08 +000065{
66 u32 i;
67
Timothy Pearson82982a12015-01-23 20:26:31 -060068 if (IS_ENABLED(RES_DEBUG))
69 printk(BIOS_DEBUG, "setting up resource map ex offset....\n");
Marc Jones8ae8c882007-12-19 01:32:08 +000070
Marc Jones8ae8c882007-12-19 01:32:08 +000071 for(i = 0; i < max; i += 4) {
Timothy Pearson82982a12015-01-23 20:26:31 -060072 if (IS_ENABLED(RES_DEBUG))
73 printk(BIOS_DEBUG, "%04x: %02x %08x <- & %08x | %08x\n",
74 i/4, register_values[i],
75 register_values[i+1] + ( (register_values[i]==RES_PCI_IO) ? offset_pci_dev : 0),
76 register_values[i+2],
77 register_values[i+3] + ( ( (register_values[i] & RES_PORT_IO_32) == RES_PORT_IO_32) ? offset_io_base : 0)
78 );
Marc Jones8ae8c882007-12-19 01:32:08 +000079 switch (register_values[i]) {
80 case RES_PCI_IO: //PCI
81 {
82 device_t dev;
83 u32 where;
84 u32 reg;
85 dev = (register_values[i+1] & ~0xfff) + offset_pci_dev;
86 where = register_values[i+1] & 0xfff;
87 reg = pci_read_config32(dev, where);
Timothy Pearson82982a12015-01-23 20:26:31 -060088 if (IS_ENABLED(RES_DEBUG))
89 printk(BIOS_SPEW, "WAS: %08x\n", reg);
Marc Jones8ae8c882007-12-19 01:32:08 +000090 reg &= register_values[i+2];
91 reg |= register_values[i+3];
92 pci_write_config32(dev, where, reg);
Timothy Pearson82982a12015-01-23 20:26:31 -060093 if (IS_ENABLED(RES_DEBUG))
94 printk(BIOS_SPEW, "NOW: %08x\n", reg);
Marc Jones8ae8c882007-12-19 01:32:08 +000095 }
96 break;
97 case RES_PORT_IO_8: // io 8
98 {
99 u32 where;
100 u32 reg;
101 where = register_values[i+1] + offset_io_base;
102 reg = inb(where);
Timothy Pearson82982a12015-01-23 20:26:31 -0600103 if (IS_ENABLED(RES_DEBUG))
104 printk(BIOS_SPEW, "WAS: %08x\n", reg);
Marc Jones8ae8c882007-12-19 01:32:08 +0000105 reg &= register_values[i+2];
106 reg |= register_values[i+3];
107 outb(reg, where);
Timothy Pearson82982a12015-01-23 20:26:31 -0600108 if (IS_ENABLED(RES_DEBUG))
109 printk(BIOS_SPEW, "NOW: %08x\n", reg);
Marc Jones8ae8c882007-12-19 01:32:08 +0000110 }
111 break;
112 case RES_PORT_IO_32: //io32
113 {
114 u32 where;
115 u32 reg;
116 where = register_values[i+1] + offset_io_base;
117 reg = inl(where);
Timothy Pearson82982a12015-01-23 20:26:31 -0600118 if (IS_ENABLED(RES_DEBUG))
119 printk(BIOS_SPEW, "WAS: %08x\n", reg);
Marc Jones8ae8c882007-12-19 01:32:08 +0000120 reg &= register_values[i+2];
121 reg |= register_values[i+3];
122 outl(reg, where);
Timothy Pearson82982a12015-01-23 20:26:31 -0600123 if (IS_ENABLED(RES_DEBUG))
124 printk(BIOS_SPEW, "NOW: %08x\n", reg);
Marc Jones8ae8c882007-12-19 01:32:08 +0000125 }
126 break;
127 } // switch
128
129
130 }
131
Timothy Pearson82982a12015-01-23 20:26:31 -0600132 if (IS_ENABLED(RES_DEBUG))
133 printk(BIOS_DEBUG, "done.\n");
Marc Jones8ae8c882007-12-19 01:32:08 +0000134}
Stefan Reinauer817d7542010-07-08 00:37:23 +0000135
136void setup_resource_map_x(const u32 *register_values, u32 max)
Marc Jones8ae8c882007-12-19 01:32:08 +0000137{
138 u32 i;
139
Timothy Pearson82982a12015-01-23 20:26:31 -0600140 if (IS_ENABLED(RES_DEBUG))
141 printk(BIOS_DEBUG, "setting up resource map ex offset....\n");
Marc Jones8ae8c882007-12-19 01:32:08 +0000142
Marc Jones8ae8c882007-12-19 01:32:08 +0000143 for(i = 0; i < max; i += 4) {
Timothy Pearson82982a12015-01-23 20:26:31 -0600144 if (IS_ENABLED(RES_DEBUG))
145 printk(BIOS_DEBUG, "%04x: %02x %08x <- & %08x | %08x\n",
146 i/4, register_values[i],register_values[i+1], register_values[i+2], register_values[i+3]);
Marc Jones8ae8c882007-12-19 01:32:08 +0000147 switch (register_values[i]) {
148 case RES_PCI_IO: //PCI
149 {
150 device_t dev;
151 u32 where;
152 u32 reg;
153 dev = register_values[i+1] & ~0xff;
154 where = register_values[i+1] & 0xff;
155 reg = pci_read_config32(dev, where);
156 reg &= register_values[i+2];
157 reg |= register_values[i+3];
158 pci_write_config32(dev, where, reg);
159 }
160 break;
161 case RES_PORT_IO_8: // io 8
162 {
163 u32 where;
164 u32 reg;
165 where = register_values[i+1];
166 reg = inb(where);
167 reg &= register_values[i+2];
168 reg |= register_values[i+3];
169 outb(reg, where);
170 }
171 break;
172 case RES_PORT_IO_32: //io32
173 {
174 u32 where;
175 u32 reg;
176 where = register_values[i+1];
177 reg = inl(where);
178 reg &= register_values[i+2];
179 reg |= register_values[i+3];
180 outl(reg, where);
181 }
182 break;
183 } // switch
184
185
186 }
187
Timothy Pearson82982a12015-01-23 20:26:31 -0600188 if (IS_ENABLED(RES_DEBUG))
189 printk(BIOS_DEBUG, "done.\n");
Marc Jones8ae8c882007-12-19 01:32:08 +0000190}
191
Stefan Reinauerc51dc442010-04-07 01:44:04 +0000192#if 0
Marc Jones8ae8c882007-12-19 01:32:08 +0000193static void setup_iob_resource_map(const u32 *register_values, u32 max)
194{
195 u32 i;
196
197 for(i = 0; i < max; i += 3) {
198 u32 where;
199 u32 reg;
200
201 where = register_values[i];
202 reg = inb(where);
203 reg &= register_values[i+1];
204 reg |= register_values[i+2];
205 outb(reg, where);
206 }
207}
208
209static void setup_io_resource_map(const u32 *register_values, u32 max)
210{
211 u32 i;
212
213 for(i = 0; i < max; i += 3) {
214 u32 where;
215 u32 reg;
216
217 where = register_values[i];
218 reg = inl(where);
219 reg &= register_values[i+1];
220 reg |= register_values[i+2];
221
222 outl(reg, where);
223 }
224}
Stefan Reinauerc51dc442010-04-07 01:44:04 +0000225#endif