Pārlūkot izejas kodu

[settings] Expose PCI configuration space via settings mechanism

Allow values to be read from PCI configuration space using the syntax

  ${pci/<busdevfn>.<offset>.<length>}

where <busdevfn> is the bus:dev.fn address of the PCI device
(expressed as a single integer, as returned by ${net0/busloc}),
<offset> is the offset within PCI configuration space, and <length> is
the length within PCI configuration space.

Values are returned in reverse byte order, since PCI configuration
space is little-endian by definition.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 11 gadus atpakaļ
vecāks
revīzija
dbfa13ff2c

+ 3
- 0
src/config/config.c Parādīt failu

@@ -298,6 +298,9 @@ REQUIRE_OBJECT ( efi_bofm );
298 298
 /*
299 299
  * Drag in relevant settings sources
300 300
  */
301
+#ifdef PCI_SETTINGS
302
+REQUIRE_OBJECT ( pci_settings );
303
+#endif
301 304
 #ifdef VMWARE_SETTINGS
302 305
 REQUIRE_OBJECT ( guestinfo );
303 306
 #endif

+ 1
- 0
src/config/settings.h Parādīt failu

@@ -9,6 +9,7 @@
9 9
 
10 10
 FILE_LICENCE ( GPL2_OR_LATER );
11 11
 
12
+#define	PCI_SETTINGS	/* PCI device settings */
12 13
 //#define	VMWARE_SETTINGS	/* VMware GuestInfo settings */
13 14
 
14 15
 #include <config/local/settings.h>

+ 124
- 0
src/drivers/bus/pci_settings.c Parādīt failu

@@ -0,0 +1,124 @@
1
+/*
2
+ * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17
+ * 02110-1301, USA.
18
+ */
19
+
20
+FILE_LICENCE ( GPL2_OR_LATER );
21
+
22
+#include <stdio.h>
23
+#include <errno.h>
24
+#include <ipxe/pci.h>
25
+#include <ipxe/settings.h>
26
+#include <ipxe/init.h>
27
+
28
+/** @file
29
+ *
30
+ * PCI device settings
31
+ *
32
+ */
33
+
34
+/** PCI device settings scope */
35
+static struct settings_scope pci_settings_scope;
36
+
37
+/**
38
+ * Check applicability of PCI device setting
39
+ *
40
+ * @v settings		Settings block
41
+ * @v setting		Setting
42
+ * @ret applies		Setting applies within this settings block
43
+ */
44
+static int pci_settings_applies ( struct settings *settings __unused,
45
+				  struct setting *setting ) {
46
+
47
+	return ( setting->scope == &pci_settings_scope );
48
+}
49
+
50
+/**
51
+ * Fetch value of PCI device setting
52
+ *
53
+ * @v settings		Settings block
54
+ * @v setting		Setting to fetch
55
+ * @v data		Buffer to fill with setting data
56
+ * @v len		Length of buffer
57
+ * @ret len		Length of setting data, or negative error
58
+ */
59
+static int pci_settings_fetch ( struct settings *settings __unused,
60
+				struct setting *setting,
61
+				void *data, size_t len ) {
62
+	struct pci_device pci;
63
+	unsigned int tag_busdevfn;
64
+	unsigned int tag_offset;
65
+	unsigned int tag_len;
66
+	unsigned int i;
67
+
68
+	/* Extract busdevfn, offset, and length from tag */
69
+	tag_busdevfn = ( ( setting->tag >> 16 ) & 0xffff );
70
+	tag_offset = ( ( setting->tag >> 8 ) & 0xff );
71
+	tag_len = ( ( setting->tag >> 0 ) & 0xff );
72
+
73
+	/* Locate PCI device */
74
+	memset ( &pci, 0, sizeof ( pci ) );
75
+	pci_init ( &pci, tag_busdevfn );
76
+	DBG ( PCI_FMT " reading %#02x+%#x\n", PCI_ARGS ( &pci ),
77
+	      tag_offset, tag_len );
78
+
79
+	/* Read data one byte at a time, in reverse order (since PCI
80
+	 * is little-endian and iPXE settings are essentially
81
+	 * big-endian).
82
+	 */
83
+	tag_offset += tag_len;
84
+	for ( i = 0 ; ( ( i < tag_len ) && ( i < len ) ); i++ ) {
85
+		pci_read_config_byte ( &pci, --tag_offset, data++ );
86
+	}
87
+
88
+	/* Set type to ":hexraw" if not already specified */
89
+	if ( ! setting->type )
90
+		setting->type = &setting_type_hexraw;
91
+
92
+	return tag_len;
93
+}
94
+
95
+/** PCI device settings operations */
96
+static struct settings_operations pci_settings_operations = {
97
+	.applies = pci_settings_applies,
98
+	.fetch = pci_settings_fetch,
99
+};
100
+
101
+/** PCI device settings */
102
+static struct settings pci_settings = {
103
+	.refcnt = NULL,
104
+	.siblings = LIST_HEAD_INIT ( pci_settings.siblings ),
105
+	.children = LIST_HEAD_INIT ( pci_settings.children ),
106
+	.op = &pci_settings_operations,
107
+	.default_scope = &pci_settings_scope,
108
+};
109
+
110
+/** Initialise PCI device settings */
111
+static void pci_settings_init ( void ) {
112
+	int rc;
113
+
114
+	if ( ( rc = register_settings ( &pci_settings, NULL, "pci" ) ) != 0 ) {
115
+		DBG ( "PCI could not register settings: %s\n",
116
+		      strerror ( rc ) );
117
+		return;
118
+	}
119
+}
120
+
121
+/** PCI device settings initialiser */
122
+struct init_fn pci_settings_init_fn __init_fn ( INIT_NORMAL ) = {
123
+	.initialise = pci_settings_init,
124
+};

+ 1
- 0
src/include/ipxe/errfile.h Parādīt failu

@@ -276,6 +276,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
276 276
 #define ERRFILE_efi_timer	      ( ERRFILE_OTHER | 0x003a0000 )
277 277
 #define ERRFILE_efi_umalloc	      ( ERRFILE_OTHER | 0x003b0000 )
278 278
 #define ERRFILE_linux_pci	      ( ERRFILE_OTHER | 0x003c0000 )
279
+#define ERRFILE_pci_settings	      ( ERRFILE_OTHER | 0x003d0000 )
279 280
 
280 281
 /** @} */
281 282
 

Notiek ielāde…
Atcelt
Saglabāt