Ver código fonte

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 anos atrás
pai
commit
75d864432c

+ 4
- 19
src/core/main.c Ver arquivo

144
 
144
 
145
 
145
 
146
 /* Global instance of the current boot device */
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
  * initialise() - perform any C-level initialisation
153
  * initialise() - perform any C-level initialisation
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
 #if 0
219
 #if 0
235
 
220
 
236
 static int main_loop(int state)
221
 static int main_loop(int state)

+ 20
- 6
src/drivers/bus/eisa.c Ver arquivo

13
 #define DBG(...)
13
 #define DBG(...)
14
 #endif
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
  * Fill in parameters for an EISA device based on slot number
25
  * Fill in parameters for an EISA device based on slot number
18
  *
26
  *
52
  * Obtain a struct eisa * from a struct dev *
60
  * Obtain a struct eisa * from a struct dev *
53
  *
61
  *
54
  * If dev has not previously been used for an EISA device scan, blank
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
 struct eisa_device * eisa_device ( struct dev *dev ) {
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
 		memset ( eisa, 0, sizeof ( *eisa ) );
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
 	eisa->dev = dev;
72
 	eisa->dev = dev;
66
 	return eisa;
73
 	return eisa;
74
 	unsigned int i;
81
 	unsigned int i;
75
 
82
 
76
 	/* Iterate through all possible EISA slots, starting where we
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
 	for ( ; eisa->slot <= EISA_MAX_SLOT ; eisa->slot++ ) {
91
 	for ( ; eisa->slot <= EISA_MAX_SLOT ; eisa->slot++ ) {
80
 		/* If we've already used this device, skip it */
92
 		/* If we've already used this device, skip it */
81
 		if ( eisa->already_tried ) {
93
 		if ( eisa->already_tried ) {
101
 						      eisa->prod_id ) );
113
 						      eisa->prod_id ) );
102
 				if ( eisa->dev ) {
114
 				if ( eisa->dev ) {
103
 					eisa->dev->name = driver->name;
115
 					eisa->dev->name = driver->name;
116
+					eisa->dev->devid.bus_type
117
+						= ISA_BUS_TYPE;
104
 					eisa->dev->devid.vendor_id
118
 					eisa->dev->devid.vendor_id
105
 						= eisa->mfg_id;
119
 						= eisa->mfg_id;
106
 					eisa->dev->devid.device_id
120
 					eisa->dev->devid.device_id

+ 16
- 6
src/drivers/bus/mca.c Ver arquivo

19
 #define DBG(...)
19
 #define DBG(...)
20
 #endif
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
  * Fill in parameters for an MCA device based on slot number
31
  * Fill in parameters for an MCA device based on slot number
24
  *
32
  *
53
  * Obtain a struct mca * from a struct dev *
61
  * Obtain a struct mca * from a struct dev *
54
  *
62
  *
55
  * If dev has not previously been used for an MCA device scan, blank
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
 struct mca_device * mca_device ( struct dev *dev ) {
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
 		memset ( mca, 0, sizeof ( *mca ) );
70
 		memset ( mca, 0, sizeof ( *mca ) );
63
-		dev->devid.bus_type = MCA_BUS_TYPE;
71
+		mca->magic = mca_magic;
64
 	}
72
 	}
65
 	mca->dev = dev;
73
 	mca->dev = dev;
66
 	return mca;
74
 	return mca;
97
 				      id->name, driver->name, id->id );
105
 				      id->name, driver->name, id->id );
98
 				if ( mca->dev ) {
106
 				if ( mca->dev ) {
99
 					mca->dev->name = driver->name;
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
 					mca->dev->devid.device_id = id->id;
112
 					mca->dev->devid.device_id = id->id;
103
 				}
113
 				}
104
 				mca->already_tried = 1;
114
 				mca->already_tried = 1;

+ 27
- 4
src/drivers/bus/pci.c Ver arquivo

9
 #define DBG(...)
9
 #define DBG(...)
10
 #endif
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
  * Fill in parameters (vendor & device ids, class, membase etc.) for a
21
  * Fill in parameters (vendor & device ids, class, membase etc.) for a
14
  * PCI device based on bus & devfn.
22
  * PCI device based on bus & devfn.
112
  * Obtain a struct pci * from a struct dev *
120
  * Obtain a struct pci * from a struct dev *
113
  *
121
  *
114
  * If dev has not previously been used for a PCI device scan, blank
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
 struct pci_device * pci_device ( struct dev *dev ) {
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
 		memset ( pci, 0, sizeof ( *pci ) );
129
 		memset ( pci, 0, sizeof ( *pci ) );
122
-		dev->devid.bus_type = PCI_BUS_TYPE;
130
+		pci->magic = pci_magic;
123
 	}
131
 	}
124
 	pci->dev = dev;
132
 	pci->dev = dev;
125
 	return pci;
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
  * Find a PCI device matching the specified driver
151
  * Find a PCI device matching the specified driver
130
  *
152
  *
154
 		/* Fill in dev structure, if present */
176
 		/* Fill in dev structure, if present */
155
 		if ( pci->dev ) {
177
 		if ( pci->dev ) {
156
 			pci->dev->name = driver->name;
178
 			pci->dev->name = driver->name;
179
+			pci->dev->devid.bus_type = PCI_BUS_TYPE;
157
 			pci->dev->devid.vendor_id = pci->vendor;
180
 			pci->dev->devid.vendor_id = pci->vendor;
158
 			pci->dev->devid.device_id = pci->dev_id;
181
 			pci->dev->devid.device_id = pci->dev_id;
159
 		}
182
 		}

+ 14
- 13
src/include/dev.h Ver arquivo

3
 
3
 
4
 #include "stdint.h"
4
 #include "stdint.h"
5
 
5
 
6
-/* Bus types */
7
-#include "pci.h"
8
-#include "eisa.h"
9
-#include "mca.h"
10
-
11
 /* Device types */
6
 /* Device types */
12
 #include "nic.h"
7
 #include "nic.h"
13
 
8
 
18
 	uint8_t		bus_type;
13
 	uint8_t		bus_type;
19
 #define	PCI_BUS_TYPE	1
14
 #define	PCI_BUS_TYPE	1
20
 #define	ISA_BUS_TYPE	2
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
 } __attribute__ ((packed));
17
 } __attribute__ ((packed));
24
 
18
 
25
 /* Dont use sizeof, that will include the padding */
19
 /* Dont use sizeof, that will include the padding */
29
 	struct dev_operations *dev_op;
23
 	struct dev_operations *dev_op;
30
 	const char *name;
24
 	const char *name;
31
 	struct dev_id	devid;	/* device ID string (sent to DHCP server) */
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
 	/* All possible device types */
31
 	/* All possible device types */
39
 	union {
32
 	union {
40
 		struct nic	nic;
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
 struct dev_operations {
45
 struct dev_operations {
45
 	void ( *disable ) ( struct dev * );
46
 	void ( *disable ) ( struct dev * );
46
 	void ( *print_info ) ( struct dev * );
47
 	void ( *print_info ) ( struct dev * );

+ 1
- 0
src/include/eisa.h Ver arquivo

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

+ 1
- 0
src/include/mca.h Ver arquivo

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

+ 1
- 1
src/include/pci.h Ver arquivo

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

Carregando…
Cancelar
Salvar