Преглед изворни кода

Use the magic of common symbols to allow struct dev to effectively grow at

link time to accommodate whatever bus objects are included.
tags/v0.9.3
Michael Brown пре 19 година
родитељ
комит
75d864432c
8 измењених фајлова са 84 додато и 49 уклоњено
  1. 4
    19
      src/core/main.c
  2. 20
    6
      src/drivers/bus/eisa.c
  3. 16
    6
      src/drivers/bus/mca.c
  4. 27
    4
      src/drivers/bus/pci.c
  5. 14
    13
      src/include/dev.h
  6. 1
    0
      src/include/eisa.h
  7. 1
    0
      src/include/mca.h
  8. 1
    1
      src/include/pci.h

+ 4
- 19
src/core/main.c Прегледај датотеку

@@ -144,7 +144,10 @@ static int initialized;
144 144
 
145 145
 
146 146
 /* Global instance of the current boot device */
147
-struct dev dev;
147
+DEV_BUS(struct {}, dev_bus);
148
+struct dev dev = {
149
+	.bus = &dev_bus,
150
+};
148 151
 
149 152
 /**************************************************************************
150 153
  * initialise() - perform any C-level initialisation
@@ -213,24 +216,6 @@ void exit(int status)
213 216
 }
214 217
 
215 218
 
216
-/*
217
- * Set PCI device to use.
218
- *
219
- * This routine can be called by e.g. the ROM prefix to specify that
220
- * the first device to be tried should be the device on which the ROM
221
- * was physically located.
222
- *
223
- * Note that this is deliberately in main.c rather than pci.c, because
224
- * this function should generalise to other bus types (e.g. ISAPnP),
225
- * and we don't want to end up dragging in pci.o unnecessarily.
226
- */
227
-void set_pci_device ( uint16_t busdevfn ) {
228
-	dev.devid.bus_type = PCI_BUS_TYPE;
229
-	dev.pci.busdevfn = busdevfn;
230
-	dev.pci.already_tried = 0;
231
-}
232
-
233
-
234 219
 #if 0
235 220
 
236 221
 static int main_loop(int state)

+ 20
- 6
src/drivers/bus/eisa.c Прегледај датотеку

@@ -13,6 +13,14 @@
13 13
 #define DBG(...)
14 14
 #endif
15 15
 
16
+/*
17
+ * Ensure that there is sufficient space in the shared dev_bus
18
+ * structure for a struct pci_device.
19
+ *
20
+ */
21
+DEV_BUS( struct eisa_device, eisa_dev );
22
+static char eisa_magic[0]; /* guaranteed unique symbol */
23
+
16 24
 /*
17 25
  * Fill in parameters for an EISA device based on slot number
18 26
  *
@@ -52,15 +60,14 @@ static int fill_eisa_device ( struct eisa_device *eisa ) {
52 60
  * Obtain a struct eisa * from a struct dev *
53 61
  *
54 62
  * If dev has not previously been used for an EISA device scan, blank
55
- * out dev.eisa
63
+ * out struct eisa
56 64
  */
57 65
 struct eisa_device * eisa_device ( struct dev *dev ) {
58
-	struct eisa_device *eisa = &dev->eisa;
66
+	struct eisa_device *eisa = dev->bus;;
59 67
 
60
-	if ( dev->devid.bus_type != EISA_BUS_TYPE ) {
68
+	if ( eisa->magic != eisa_magic ) {
61 69
 		memset ( eisa, 0, sizeof ( *eisa ) );
62
-		dev->devid.bus_type = EISA_BUS_TYPE;
63
-		eisa->slot = EISA_MIN_SLOT;
70
+		eisa->magic = eisa_magic;
64 71
 	}
65 72
 	eisa->dev = dev;
66 73
 	return eisa;
@@ -74,8 +81,13 @@ int find_eisa_device ( struct eisa_device *eisa, struct eisa_driver *driver ) {
74 81
 	unsigned int i;
75 82
 
76 83
 	/* Iterate through all possible EISA slots, starting where we
77
-	 * left off/
84
+	 * left off.  If eisa->slot is zero (which it will be if we
85
+	 * have a zeroed structure), start from slot EISA_MIN_SLOT,
86
+	 * since slot 0 doesn't exist.
78 87
 	 */
88
+	if ( ! eisa->slot ) {
89
+		eisa->slot = EISA_MIN_SLOT;
90
+	}
79 91
 	for ( ; eisa->slot <= EISA_MAX_SLOT ; eisa->slot++ ) {
80 92
 		/* If we've already used this device, skip it */
81 93
 		if ( eisa->already_tried ) {
@@ -101,6 +113,8 @@ int find_eisa_device ( struct eisa_device *eisa, struct eisa_driver *driver ) {
101 113
 						      eisa->prod_id ) );
102 114
 				if ( eisa->dev ) {
103 115
 					eisa->dev->name = driver->name;
116
+					eisa->dev->devid.bus_type
117
+						= ISA_BUS_TYPE;
104 118
 					eisa->dev->devid.vendor_id
105 119
 						= eisa->mfg_id;
106 120
 					eisa->dev->devid.device_id

+ 16
- 6
src/drivers/bus/mca.c Прегледај датотеку

@@ -19,6 +19,14 @@
19 19
 #define DBG(...)
20 20
 #endif
21 21
 
22
+/*
23
+ * Ensure that there is sufficient space in the shared dev_bus
24
+ * structure for a struct pci_device.
25
+ *
26
+ */
27
+DEV_BUS( struct mca_device, mca_dev );
28
+static char mca_magic[0]; /* guaranteed unique symbol */
29
+
22 30
 /*
23 31
  * Fill in parameters for an MCA device based on slot number
24 32
  *
@@ -53,14 +61,14 @@ static int fill_mca_device ( struct mca_device *mca ) {
53 61
  * Obtain a struct mca * from a struct dev *
54 62
  *
55 63
  * If dev has not previously been used for an MCA device scan, blank
56
- * out dev.mca
64
+ * out struct mca
57 65
  */
58 66
 struct mca_device * mca_device ( struct dev *dev ) {
59
-	struct mca_device *mca = &dev->mca;
67
+	struct mca_device *mca = dev->bus;
60 68
 
61
-	if ( dev->devid.bus_type != MCA_BUS_TYPE ) {
69
+	if ( mca->magic != mca_magic ) {
62 70
 		memset ( mca, 0, sizeof ( *mca ) );
63
-		dev->devid.bus_type = MCA_BUS_TYPE;
71
+		mca->magic = mca_magic;
64 72
 	}
65 73
 	mca->dev = dev;
66 74
 	return mca;
@@ -97,8 +105,10 @@ int find_mca_device ( struct mca_device *mca, struct mca_driver *driver ) {
97 105
 				      id->name, driver->name, id->id );
98 106
 				if ( mca->dev ) {
99 107
 					mca->dev->name = driver->name;
100
-					mca->dev->devid.vendor_id =
101
-						GENERIC_MCA_VENDOR;
108
+					mca->dev->devid.bus_type
109
+						= MCA_BUS_TYPE;
110
+					mca->dev->devid.vendor_id
111
+						= GENERIC_MCA_VENDOR;
102 112
 					mca->dev->devid.device_id = id->id;
103 113
 				}
104 114
 				mca->already_tried = 1;

+ 27
- 4
src/drivers/bus/pci.c Прегледај датотеку

@@ -9,6 +9,14 @@
9 9
 #define DBG(...)
10 10
 #endif
11 11
 
12
+/*
13
+ * Ensure that there is sufficient space in the shared dev_bus
14
+ * structure for a struct pci_device.
15
+ *
16
+ */
17
+DEV_BUS( struct pci_device, pci_dev );
18
+static char pci_magic[0]; /* guaranteed unique symbol */
19
+
12 20
 /*
13 21
  * Fill in parameters (vendor & device ids, class, membase etc.) for a
14 22
  * PCI device based on bus & devfn.
@@ -112,19 +120,33 @@ void adjust_pci_device ( struct pci_device *pci ) {
112 120
  * Obtain a struct pci * from a struct dev *
113 121
  *
114 122
  * If dev has not previously been used for a PCI device scan, blank
115
- * out dev.pci
123
+ * out struct pci
116 124
  */
117 125
 struct pci_device * pci_device ( struct dev *dev ) {
118
-	struct pci_device *pci = &dev->pci;
126
+	struct pci_device *pci = dev->bus;
119 127
 
120
-	if ( dev->devid.bus_type != PCI_BUS_TYPE ) {
128
+	if ( pci->magic != pci_magic ) {
121 129
 		memset ( pci, 0, sizeof ( *pci ) );
122
-		dev->devid.bus_type = PCI_BUS_TYPE;
130
+		pci->magic = pci_magic;
123 131
 	}
124 132
 	pci->dev = dev;
125 133
 	return pci;
126 134
 }
127 135
 
136
+/*
137
+ * Set PCI device to use.
138
+ *
139
+ * This routine can be called by e.g. the ROM prefix to specify that
140
+ * the first device to be tried should be the device on which the ROM
141
+ * was physically located.
142
+ *
143
+ */
144
+void set_pci_device ( uint16_t busdevfn ) {
145
+	pci_dev.magic = pci_magic;
146
+	pci_dev.busdevfn = busdevfn;
147
+	pci_dev.already_tried = 0;
148
+}
149
+
128 150
 /*
129 151
  * Find a PCI device matching the specified driver
130 152
  *
@@ -154,6 +176,7 @@ int find_pci_device ( struct pci_device *pci,
154 176
 		/* Fill in dev structure, if present */
155 177
 		if ( pci->dev ) {
156 178
 			pci->dev->name = driver->name;
179
+			pci->dev->devid.bus_type = PCI_BUS_TYPE;
157 180
 			pci->dev->devid.vendor_id = pci->vendor;
158 181
 			pci->dev->devid.device_id = pci->dev_id;
159 182
 		}

+ 14
- 13
src/include/dev.h Прегледај датотеку

@@ -3,11 +3,6 @@
3 3
 
4 4
 #include "stdint.h"
5 5
 
6
-/* Bus types */
7
-#include "pci.h"
8
-#include "eisa.h"
9
-#include "mca.h"
10
-
11 6
 /* Device types */
12 7
 #include "nic.h"
13 8
 
@@ -18,8 +13,7 @@ struct dev_id {
18 13
 	uint8_t		bus_type;
19 14
 #define	PCI_BUS_TYPE	1
20 15
 #define	ISA_BUS_TYPE	2
21
-#define EISA_BUS_TYPE	3
22
-#define MCA_BUS_TYPE	4
16
+#define MCA_BUS_TYPE	3
23 17
 } __attribute__ ((packed));
24 18
 
25 19
 /* Dont use sizeof, that will include the padding */
@@ -29,18 +23,25 @@ struct dev {
29 23
 	struct dev_operations *dev_op;
30 24
 	const char *name;
31 25
 	struct dev_id	devid;	/* device ID string (sent to DHCP server) */
32
-	/* All possible bus types */
33
-	union {
34
-		struct pci_device	pci;
35
-		struct eisa_device	eisa;
36
-		struct mca_device	mca;
37
-	};
26
+	/* Pointer to bus information for device.  Whatever sets up
27
+	 * the struct dev must make sure that this points to a buffer
28
+	 * large enough for the required struct <bus>_device.
29
+	 */
30
+	void *bus;
38 31
 	/* All possible device types */
39 32
 	union {
40 33
 		struct nic	nic;
41 34
 	};
42 35
 };
43 36
 
37
+/*
38
+ * Macro to help create a common symbol with enough space for any
39
+ * struct <bus>_device.
40
+ *
41
+ * Use as e.g. DEV_BUS(struct pci_device);
42
+ */
43
+#define DEV_BUS(datatype,symbol) datatype symbol __asm__ ( "_dev_bus" );
44
+
44 45
 struct dev_operations {
45 46
 	void ( *disable ) ( struct dev * );
46 47
 	void ( *print_info ) ( struct dev * );

+ 1
- 0
src/include/eisa.h Прегледај датотеку

@@ -27,6 +27,7 @@
27 27
  */
28 28
 struct dev;
29 29
 struct eisa_device {
30
+	char *magic; /* must be first */
30 31
 	struct dev *dev;
31 32
 	unsigned int slot;
32 33
 	uint16_t ioaddr;

+ 1
- 0
src/include/mca.h Прегледај датотеку

@@ -28,6 +28,7 @@
28 28
  */
29 29
 struct dev;
30 30
 struct mca_device {
31
+	char *magic; /* must be first */
31 32
 	struct dev *dev;
32 33
 	unsigned int slot;
33 34
 	unsigned char pos[8];

+ 1
- 1
src/include/pci.h Прегледај датотеку

@@ -232,13 +232,13 @@
232 232
 #define PCI_MSI_ADDRESS_HI	8	/* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
233 233
 #define PCI_MSI_DATA_32		8	/* 16 bits of data for 32-bit devices */
234 234
 #define PCI_MSI_DATA_64		12	/* 16 bits of data for 64-bit devices */
235
-
236 235
 /*
237 236
  * A physical PCI device
238 237
  *
239 238
  */
240 239
 struct dev;
241 240
 struct pci_device {
241
+	char *			magic; /* must be first */
242 242
 	struct dev *		dev;
243 243
 	uint32_t		membase;	/* BAR 1 */
244 244
 	uint32_t		ioaddr;		/* first IO BAR */

Loading…
Откажи
Сачувај