Linux/Kernel/PCIDynamicResourceAllocationManagement: pci-dram.h

File pci-dram.h, 11.6 KB (added by tj, 9 years ago)

Kernel header for PCI-Dynamic Resource Allocation Management

Line 
1/*
2 * PCI Dynamic Resource Allocation Management
3 *
4 * An implementation that uses all free memory address regions reported
5 * by the BIOS Int 0x15 eax=0xe820, EFI and/or ACPI facilities, does top-down or
6 * bottom-up allocation, attempts to optimise usage of the PCI I/O MEM ranges, and
7 * provides Dynamic Resource Adjustment (DRA) to allow bridges to expand/contract
8 * their resource range and auto-reconfigure devices behind the bridge.
9 *
10 * Copyright April 2008 TJ <linux@tjworld.net>
11 *
12 * See the file COPYING in the root directory of the linux kernel source
13 * for the full GPL v2 license.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License version 2 as published
17 * by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
27 */
28
29#ifndef PCIDRAM_H_
30#define PCIDRAM_H_
31
32#ifndef CONFIG_PCI_DRAM
33
34// empty implementation because PCI DRAM not built
35int pci_dram_apply_policy(void) { return 0; }
36
37#else
38
39#include <linux/kernel.h> // for abs(), loglevels, get_option
40#include <linux/types.h>  // for resource_size_t
41#include <linux/ioport.h> // for struct resource and *_resource() functions
42#include <linux/list.h> // for list_head
43
44
45/**
46 * Primary initialisation
47 * Must be called before any PCI DRAM activity
48 */
49extern int pci_dram_apply_policy(void);
50
51/**
52 * Called by bus and device scanning functions. Allows the scanning operation to
53 * perform arbitrary tasks separate from the device tree-traversal code.
54 * @device: the PCI device being scanned
55 * @data: task-specific memory structure
56 * @data-size: size of memory block at @data
57 */
58typedef int (*pci_dram_scan_device_worker)(struct pci_dev* device, void* data, resource_size_t data_size);
59
60/**
61 * Active policy flags
62 */
63extern unsigned int pci_dram_policy;
64
65/**
66 * List of memory-mapped I/O regions available for PCI MEM resource usage.
67 */
68extern struct resource* pci_dram_map;
69
70/* E.g.
71 *
72 * map-->region01-->fragment01
73 *    |          |   allocated to device
74 *    |          |->fragment02
75 *    |->region02-->fragment03
76 *    |          |   allocated to device
77 *    |          |->fragment04
78 *    |->region03
79 *
80 * In the map above the 'available' regions are:
81 * 1 fragment01
82 * 2 fragment02
83 * 3 fragment03
84 * 4 fragment04
85 * 5 region03
86 */
87
88
89// prefix for log reports
90#define PCI_DRAM_PREFIX "PCI DRAM: "
91
92// maximum value of a signed int
93#define PCI_DRAM_MAX_INT 0x7FFFFFFF
94
95// reuse existing flag but give it descriptive name
96# define PCI_DRAM_BUS IORESOURCE_AUTO
97
98/* Conditional compilation of debug logging statements
99 *
100 * This is complicated since the preprocessor needs several levels of indirection
101 * to enable the value of PCI_DRAM_DEBUG (n or y) to be converted into a number
102 * that can be tested in a conditional expression.
103 *
104 * _DBUGLOG is a simple macro that sets the function-macro parameters.
105 * __DBUGLOG()'s purpose is to force expansion of the macro CONFIG_PCI_DRAM_DEBUG to
106 * its value
107 * ___DBUGLOG() builds the final test condition which expands to a boolean true/false
108 * test.
109 *
110 * The result of all this is that the dbug_printk() macro is expanded inline in the
111 * source code as something like:
112 *
113 *  ({ if (1 == 1 && 3 <= 4) { printf("<4>" "PCI DRAM: " "Test macro %d\n", argc); } })
114 *
115 * As both if() conditions are true the compiler will include the statements.
116 *
117 * However, if one of the if() conditions is false the compiler will detect that the
118 * statements can never be executed and will drop the complete expression during
119 * optimisation. E.g:
120 *
121 *  ({ if (0 == 1 && 3 <= 4) { printf("<4>" "PCI DRAM: " "Test macro %d\n", argc); } });
122 *
123 * will become ({}) which is null.
124 */
125#define ___DBUGLOG(arg, val) (arg == val)
126#define __DBUGLOG(arg, val) ___DBUGLOG(arg, val)
127#define _DBUGLOG __DBUGLOG(CONFIG_PCI_DRAM_DEBUG, 1)
128
129/** Conditionally compiled debug logging based on CONFIGured log level and debug.
130 * Logs PCI DRAM debug messages at kernel log level KERN_WARNING (4) rather
131 * than use KERN_DEBUG (7) and rely on the kernel-wide debug setting which would
132 * cause other modules to emit unwanted debug messages too.
133 * @level: log level of this report
134 * @format: standard format specifier
135 * @args: optional variable argument list
136 */ 
137#define dbug_printk(level, format, args...) ({\
138        if (_DBUGLOG && \
139         level <= CONFIG_PCI_DRAM_LOGLEVEL) { \
140                printk(KERN_WARNING PCI_DRAM_PREFIX format, ##args); \
141        } \
142})
143
144// debug log levels
145#define DBUG_WARNING 4
146#define DBUG_NOTICE 5
147#define DBUG_INFO 6
148#define DBUG_DEBUG 7
149#define DBUG_FLAGS 8
150#define DBUG_FUNC 9
151#define DBUG_TRACE 10
152
153
154/*
155 * The list of memory-mapped I/O regions available for PCI resource usage is
156 * created by scanning the system memory map.
157 * On 'conventional' x86 that is a list of e820.map regions from last to first in the
158 * same way that e820_64.c::e820_setup_gap() and e820_32.c::e820_register_memory()
159 * do. On EFI systems that is from the results of GetMemoryMap().
160 *
161 * The allocation strategy is controlled by policy made up of bits and flags.
162 *
163 * These are the bit assignments:
164 */
165
166// marker that value wasn't CONIFGured
167#define PCI_DRAM_INVALID        0x80000000
168
169#define PCI_DRAM_REGIONS_NUM    0x000000FF
170#define PCI_DRAM_REGIONS_SORT   0x00000100
171#define PCI_DRAM_REGIONS_DIR    0x00000200
172#define PCI_DRAM_ALLOC_DIR      0x00000400
173#define PCI_DRAM_DRA_BRIDGE     0x00001000
174#define PCI_DRAM_DRA_DEVICE     0x00002000
175#define PCI_DRAM_LIMIT_4GB      0x00010000
176#define PCI_DRAM_SAFETY_NET     0x00020000
177#define PCI_DRAM_SCAN_E820      0x00100000
178#define PCI_DRAM_SCAN_ACPI      0x00200000
179
180#define PCI_DRAM_POLICY_LINUX   0x00303500 // Linux preferred
181#define PCI_DRAM_POLICY_LEGACY  0x00030401 // Linux up to 2.6.25
182#define PCI_DRAM_POLICY_WIN2003 0x00310500 // Windows XP, 2003 Server
183#define PCI_DRAM_POLICY_WIN2006 0x00303500 // Windows Vista, 2008 Server
184
185#define PCI_DRAM_POLICY_DEFAULT PCI_DRAM_POLICY_LEGACY // default setting (may change in future)
186
187/*
188 *  PCI_DRAM_REGIONS_NUM (bits 0-7) The number of regions to use:
189 *   0 = use all
190 *   1 = use 1
191 *   2-255 = use X (ignored if X > pci_dram_regions_qty)
192 *
193 *  PCI_DRAM_REGIONS_SORT (bit 8) Order regions in list
194 *  0 = no sort
195 *  1 = order largest-to-smallest
196 *
197 *  PCI_DRAM_REGIONS_DIR (bit 9) Direction to traverse the list:
198 *  0 = traverse last-to-first (smallest-to-largest)
199 *  1 = traverse first-to-last (largest-to-smallest)
200 *
201 *  PCI_DRAM_ALLOC_DIR (bit 10) direction of allocation of resources within a region:
202 *   0 = lower-to-higher addresses (bottom-up)
203 *   1 = higher-to-lower addresses (top-down)
204 *
205 *  PCI_DRAM_DRA_BRIDGE (bit 12) Dynamic Resource Allocation for Bridges
206 *   0 = no DRA for bridges
207 *   1 = use DRA for bridges
208 *
209 *  PCI_DRAM_DRA_DEVICE (bit 13) Dynamic Resource Allocation for Devices
210 *   0 = no DRA for devices
211 *   1 = use DRA for devices
212 *
213 *  PCI_DRAM_LIMIT_4GB (bit 16)
214 *   0 = allow 64-bit BARs above the 4GB boundary on 64-bit systems
215 *   1 = force 64-bit BARs to be allocated below the 4GB boundary
216 *
217 *  PCI_DRAM_SAFETY_NET (bit 17)
218 *   0 = no safety barrier
219 *   1 = allocate safety barrier
220 *  Unused range between top of RAM and bottom of PCI I/O memory mapping.
221 *  First introduced with commit f0eca9626c6becb6fc56106b2e4287c6c784af3d
222 *  from 2005-09-09 to guard against unreported shared video RAM overlapping
223 *  PCI IOMEM if IOMEM started immediately after top of RAM.
224 *
225 *  PCI_DRAM_SCAN_E820 (bit 24)
226 *   0 = don't use e820
227 *   1 = use e820 in determing free address regions
228 *
229 *  PCI_DRAM_SCAN_ACPI (bit 25)
230 *   0 = don't use ACPI
231 *   1 = do use ACPI in determining free address regions
232 *
233 * PCI_DRAM_POLICY_LINUX the preferred Linux policy
234 * PCI_DRAM_POLICY_LEGACY the Linux 2.6.25 legacy policy
235 * PCI_DRAM_POLICY_WIN2003 the Windows XP/2003 policy
236 * PCI_DRAM_POLICY_WIN2006 the Windows Vista/2008 policy
237 *
238 * The combination of these flags allows many different strategies to be choosen
239 * or experimented with. If a particular configuration causes a PCI device to
240 * have problems gaining a resource allocation below the 4GB boundary, it is
241 * relatively simple to reconfigure the policy at boot-time using
242 * easy-to-understand kernel command line parameters.
243 *
244 * On a 64-bit CPU system that can address more than 4GB (some northbridge chipsets
245 * are 32-bit and limit addressing to 4GB), devices that have 64-bit
246 * Base Address Registers (BARs) will be placed above 4GB *only* if all other
247 * devices behind the same bridge also support 64-bit BARs. If just one of the
248 * devices behind the bridge doesn't support a 64-bit BAR, all devices behind that
249 * bridge will be allocated a region below 4GB.
250 *
251 * Dynamic Resource Allocation (DRA)
252 *
253 * There are two types of DRA:
254 *  1. Bridge DRA
255 *  2. Device DRA
256 *
257 * Bridge DRA
258 * This is the broad-brush aspect of DRA. If, because of a device addition or
259 * removal, an allocated bridge resource needs to grow or shrink then it is
260 * possible that:
261 *  a) the bridge resource needs expanding
262 *  b) a gap will be created between two allocations within a region
263 *
264 * When enabled (and device drivers of all affected devices support DRA pause),
265 * bridge DRA shuffles the resource allocations so the remaining allocations
266 * within the region become contiguous once again.
267 *
268 * If Bridge DRA isn't enabled then gaps will appear.
269 *
270 * Device DRA
271 * When devices behind a bridge and therefore within a bridge's resource allocation
272 * are added or removed, the remaining devices are shuffled (if their drivers
273 * support DRA pause), within the bridge allocation so their boundaries are kept
274 * contiguous and no gaps are left between adjacent device allocations.
275 *
276 * The bridge can then optionally shrink it's allocation to give back to the system,
277 * potentially initiating a DRA bridge cascade.
278 *
279 */
280
281// verbose reporting of flag names is helpful during debugging
282#ifdef CONFIG_PCI_DRAM_DEBUG
283#define PCI_DRAM_SZ_REGIONS_NUM    "PCI_DRAM_REGIONS_NUM"
284#define PCI_DRAM_SZ_REGIONS_SORT   "PCI_DRAM_REGIONS_SORT"
285#define PCI_DRAM_SZ_REGIONS_DIR    "PCI_DRAM_REGIONS_DIR"
286#define PCI_DRAM_SZ_ALLOC_DIR      "PCI_DRAM_ALLOC_DIR"
287#define PCI_DRAM_SZ_DRA_BRIDGE     "PCI_DRAM_DRA_BRIDGE"
288#define PCI_DRAM_SZ_DRA_DEVICE     "PCI_DRAM_DRA_DEVICE"
289#define PCI_DRAM_SZ_LIMIT_4GB      "PCI_DRAM_LIMIT_4GB"
290#define PCI_DRAM_SZ_SAFETY_NET     "PCI_DRAM_SAFETY_NET"
291#define PCI_DRAM_SZ_SCAN_E820      "PCI_DRAM_SCAN_E820"
292#define PCI_DRAM_SZ_SCAN_ACPI      "PCI_DRAM_SCAN_ACPI"
293
294#define PCI_DRAM_SZ_POLICY_LINUX   "PCI_DRAM_POLICY_LINUX"
295#define PCI_DRAM_SZ_POLICY_LEGACY  "PCI_DRAM_POLICY_LEGACY"
296#define PCI_DRAM_SZ_POLICY_WIN2003 "PCI_DRAM_POLICY_WIN2003"
297#define PCI_DRAM_SZ_POLICY_WIN2006 "PCI_DRAM_POLICY_WIN2006"
298#define PCI_DRAM_SZ_POLICY_DEFAULT "PCI_DRAM_POLICY_LEGACY"
299#define PCI_DRAM_SZ_LOGLEVEL       "PCI_DRAM_LOGLEVEL"
300#define PCI_DRAM_SZ_FLAGS          "PCI_DRAM_FLAGS"
301#endif
302
303/* Convenience macro for applying the same bit-flip method to the flag DWORD
304 * Preserve existing unrelated flags; combine user flag.
305 * This works by inverting the flag mask and applying it to the existing flags
306 * then masking just the bits in the new value and adding (not AND/ORing)
307 * the values together.
308 */
309#define PCI_DRAM_BITFLIP(flags, mask, var) ({ \
310        if(var != PCI_DRAM_INVALID) \
311                flags = ((flags & ~mask) + (mask & var)); \
312})
313
314// convenience flag checker
315#define pci_dram_is_flag_set(flag) ((pci_dram_policy & flag) != 0)
316
317
318#endif /* CONFIG_PCI_DRAM */
319
320#endif /*PCIDRAM_H_*/