Browse Source

[arbel] Perform ICM allocations according to the specification

The current method for ICM allocation exactly matches the addresses
chosen by the old Etherboot driver, but does not match the
specification.  Some ICM tables (notably the queue pair context table)
therefore end up incorrectly aligned.

Fix by performing allocations as per the specification.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 years ago
parent
commit
d84e4e0575
2 changed files with 87 additions and 44 deletions
  1. 83
    44
      src/drivers/infiniband/arbel.c
  2. 4
    0
      src/drivers/infiniband/arbel.h

+ 83
- 44
src/drivers/infiniband/arbel.c View File

@@ -1981,7 +1981,7 @@ static int arbel_start_firmware ( struct arbel *arbel ) {
1981 1981
 	arbel_cmd_enable_lam ( arbel, &lam );
1982 1982
 
1983 1983
 	/* Allocate firmware pages and map firmware area */
1984
-	fw_size = ( fw_pages * 4096 );
1984
+	fw_size = ( fw_pages * ARBEL_PAGE_SIZE );
1985 1985
 	arbel->firmware_area = umalloc ( fw_size * 2 );
1986 1986
 	if ( ! arbel->firmware_area ) {
1987 1987
 		rc = -ENOMEM;
@@ -2092,18 +2092,17 @@ static int arbel_get_limits ( struct arbel *arbel ) {
2092 2092
 }
2093 2093
 
2094 2094
 /**
2095
- * Get ICM usage
2095
+ * Align ICM table
2096 2096
  *
2097
- * @v log_num_entries	Log2 of the number of entries
2098
- * @v entry_size	Entry size
2099
- * @ret usage		Usage size in ICM
2097
+ * @v icm_offset	Current ICM offset
2098
+ * @v len		ICM table length
2099
+ * @ret icm_offset	ICM offset
2100 2100
  */
2101
-static size_t icm_usage ( unsigned int log_num_entries, size_t entry_size ) {
2102
-	size_t usage;
2101
+static size_t icm_align ( size_t icm_offset, size_t len ) {
2103 2102
 
2104
-	usage = ( ( 1 << log_num_entries ) * entry_size );
2105
-	usage = ( ( usage + 4095 ) & ~4095 );
2106
-	return usage;
2103
+	/* Round up to a multiple of the table size */
2104
+	assert ( len == ( 1UL << ( fls ( len ) - 1 ) ) );
2105
+	return ( ( icm_offset + len - 1 ) & ~( len - 1 ) );
2107 2106
 }
2108 2107
 
2109 2108
 /**
@@ -2123,6 +2122,8 @@ static int arbel_alloc_icm ( struct arbel *arbel,
2123 2122
 	size_t icm_offset = 0;
2124 2123
 	unsigned int log_num_qps, log_num_srqs, log_num_ees, log_num_cqs;
2125 2124
 	unsigned int log_num_mtts, log_num_mpts, log_num_rdbs, log_num_eqs;
2125
+	unsigned int log_num_mcs;
2126
+	size_t len;
2126 2127
 	int rc;
2127 2128
 
2128 2129
 	icm_offset = ( ( arbel->limits.reserved_uars + 1 ) << 12 );
@@ -2130,108 +2131,143 @@ static int arbel_alloc_icm ( struct arbel *arbel,
2130 2131
 	/* Queue pair contexts */
2131 2132
 	log_num_qps = fls ( arbel->limits.reserved_qps +
2132 2133
 			    ARBEL_RSVD_SPECIAL_QPS + ARBEL_MAX_QPS - 1 );
2134
+	len = ( ( 1 << log_num_qps ) * arbel->limits.qpc_entry_size );
2135
+	icm_offset = icm_align ( icm_offset, len );
2133 2136
 	MLX_FILL_2 ( init_hca, 13,
2134 2137
 		     qpc_eec_cqc_eqc_rdb_parameters.qpc_base_addr_l,
2135 2138
 		     ( icm_offset >> 7 ),
2136 2139
 		     qpc_eec_cqc_eqc_rdb_parameters.log_num_of_qp,
2137 2140
 		     log_num_qps );
2138
-	DBGC ( arbel, "Arbel %p ICM QPC base = %zx\n", arbel, icm_offset );
2139
-	icm_offset += icm_usage ( log_num_qps, arbel->limits.qpc_entry_size );
2141
+	DBGC ( arbel, "Arbel %p ICM QPC at [%zx,%zx)\n",
2142
+	       arbel, icm_offset, ( icm_offset + len ) );
2143
+	icm_offset += len;
2140 2144
 
2141 2145
 	/* Extended queue pair contexts */
2146
+	len = ( ( 1 << log_num_qps ) * arbel->limits.eqpc_entry_size );
2147
+	icm_offset = icm_align ( icm_offset, len );
2142 2148
 	MLX_FILL_1 ( init_hca, 25,
2143 2149
 		     qpc_eec_cqc_eqc_rdb_parameters.eqpc_base_addr_l,
2144 2150
 		     icm_offset );
2145
-	DBGC ( arbel, "Arbel %p ICM EQPC base = %zx\n", arbel, icm_offset );
2146
-	//	icm_offset += icm_usage ( log_num_qps, arbel->limits.eqpc_entry_size );
2147
-	icm_offset += icm_usage ( log_num_qps, arbel->limits.qpc_entry_size );	
2151
+	DBGC ( arbel, "Arbel %p ICM EQPC at [%zx,%zx)\n",
2152
+	       arbel, icm_offset, ( icm_offset + len ) );
2153
+	icm_offset += len;
2148 2154
 
2149 2155
 	/* Shared receive queue contexts */
2150 2156
 	log_num_srqs = fls ( arbel->limits.reserved_srqs - 1 );
2157
+	len = ( ( 1 << log_num_srqs ) * arbel->limits.srqc_entry_size );
2158
+	icm_offset = icm_align ( icm_offset, len );
2151 2159
 	MLX_FILL_2 ( init_hca, 19,
2152 2160
 		     qpc_eec_cqc_eqc_rdb_parameters.srqc_base_addr_l,
2153 2161
 		     ( icm_offset >> 5 ),
2154 2162
 		     qpc_eec_cqc_eqc_rdb_parameters.log_num_of_srq,
2155 2163
 		     log_num_srqs );
2156
-	DBGC ( arbel, "Arbel %p ICM SRQC base = %zx\n", arbel, icm_offset );
2157
-	icm_offset += icm_usage ( log_num_srqs, arbel->limits.srqc_entry_size );
2164
+	DBGC ( arbel, "Arbel %p ICM SRQC at [%zx,%zx)\n",
2165
+	       arbel, icm_offset, ( icm_offset + len ) );
2166
+	icm_offset += len;
2158 2167
 
2159 2168
 	/* End-to-end contexts */
2160 2169
 	log_num_ees = fls ( arbel->limits.reserved_ees - 1 );
2170
+	len = ( ( 1 << log_num_ees ) * arbel->limits.eec_entry_size );
2171
+	icm_offset = icm_align ( icm_offset, len );
2161 2172
 	MLX_FILL_2 ( init_hca, 17,
2162 2173
 		     qpc_eec_cqc_eqc_rdb_parameters.eec_base_addr_l,
2163 2174
 		     ( icm_offset >> 7 ),
2164 2175
 		     qpc_eec_cqc_eqc_rdb_parameters.log_num_of_ee,
2165 2176
 		     log_num_ees );
2166
-	DBGC ( arbel, "Arbel %p ICM EEC base = %zx\n", arbel, icm_offset );
2167
-	icm_offset += icm_usage ( log_num_ees, arbel->limits.eec_entry_size );
2177
+	DBGC ( arbel, "Arbel %p ICM EEC at [%zx,%zx)\n",
2178
+	       arbel, icm_offset, ( icm_offset + len ) );
2179
+	icm_offset += len;
2168 2180
 
2169 2181
 	/* Extended end-to-end contexts */
2182
+	len = ( ( 1 << log_num_ees ) * arbel->limits.eeec_entry_size );
2183
+	icm_offset = icm_align ( icm_offset, len );
2170 2184
 	MLX_FILL_1 ( init_hca, 29,
2171 2185
 		     qpc_eec_cqc_eqc_rdb_parameters.eeec_base_addr_l,
2172 2186
 		     icm_offset );
2173
-	DBGC ( arbel, "Arbel %p ICM EEEC base = %zx\n", arbel, icm_offset );
2174
-	icm_offset += icm_usage ( log_num_ees, arbel->limits.eeec_entry_size );
2187
+	DBGC ( arbel, "Arbel %p ICM EEEC at [%zx,%zx)\n",
2188
+	       arbel, icm_offset, ( icm_offset + len ) );
2189
+	icm_offset += len;
2175 2190
 
2176 2191
 	/* Completion queue contexts */
2177 2192
 	log_num_cqs = fls ( arbel->limits.reserved_cqs + ARBEL_MAX_CQS - 1 );
2193
+	len = ( ( 1 << log_num_cqs ) * arbel->limits.cqc_entry_size );
2194
+	icm_offset = icm_align ( icm_offset, len );
2178 2195
 	MLX_FILL_2 ( init_hca, 21,
2179 2196
 		     qpc_eec_cqc_eqc_rdb_parameters.cqc_base_addr_l,
2180 2197
 		     ( icm_offset >> 6 ),
2181 2198
 		     qpc_eec_cqc_eqc_rdb_parameters.log_num_of_cq,
2182 2199
 		     log_num_cqs );
2183
-	DBGC ( arbel, "Arbel %p ICM CQC base = %zx\n", arbel, icm_offset );
2184
-	icm_offset += icm_usage ( log_num_cqs, arbel->limits.cqc_entry_size );
2200
+	DBGC ( arbel, "Arbel %p ICM CQC at [%zx,%zx)\n",
2201
+	       arbel, icm_offset, ( icm_offset + len ) );
2202
+	icm_offset += len;
2185 2203
 
2186 2204
 	/* Memory translation table */
2187 2205
 	log_num_mtts = fls ( arbel->limits.reserved_mtts - 1 );
2206
+	len = ( ( 1 << log_num_mtts ) * arbel->limits.mtt_entry_size );
2207
+	icm_offset = icm_align ( icm_offset, len );
2188 2208
 	MLX_FILL_1 ( init_hca, 65,
2189 2209
 		     tpt_parameters.mtt_base_addr_l, icm_offset );
2190
-	DBGC ( arbel, "Arbel %p ICM MTT base = %zx\n", arbel, icm_offset );
2191
-	icm_offset += icm_usage ( log_num_mtts, arbel->limits.mtt_entry_size );
2210
+	DBGC ( arbel, "Arbel %p ICM MTT at [%zx,%zx)\n",
2211
+	       arbel, icm_offset, ( icm_offset + len ) );
2212
+	icm_offset += len;
2192 2213
 
2193 2214
 	/* Memory protection table */
2194 2215
 	log_num_mpts = fls ( arbel->limits.reserved_mrws + 1 - 1 );
2216
+	len = ( ( 1 << log_num_mpts ) * arbel->limits.mpt_entry_size );
2217
+	icm_offset = icm_align ( icm_offset, len );
2195 2218
 	MLX_FILL_1 ( init_hca, 61,
2196 2219
 		     tpt_parameters.mpt_base_adr_l, icm_offset );
2197 2220
 	MLX_FILL_1 ( init_hca, 62,
2198 2221
 		     tpt_parameters.log_mpt_sz, log_num_mpts );
2199
-	DBGC ( arbel, "Arbel %p ICM MTT base = %zx\n", arbel, icm_offset );
2200
-	icm_offset += icm_usage ( log_num_mpts, arbel->limits.mpt_entry_size );
2222
+	DBGC ( arbel, "Arbel %p ICM MTT at [%zx,%zx)\n",
2223
+	       arbel, icm_offset, ( icm_offset + len ) );
2224
+	icm_offset += len;
2201 2225
 
2202
-	/* RDMA something or other */
2226
+	/* Remote read data base table */
2203 2227
 	log_num_rdbs = fls ( arbel->limits.reserved_rdbs - 1 );
2228
+	len = ( ( 1 << log_num_rdbs ) * ARBEL_RDB_ENTRY_SIZE );
2229
+	icm_offset = icm_align ( icm_offset, len );
2204 2230
 	MLX_FILL_1 ( init_hca, 37,
2205 2231
 		     qpc_eec_cqc_eqc_rdb_parameters.rdb_base_addr_l,
2206 2232
 		     icm_offset );
2207
-	DBGC ( arbel, "Arbel %p ICM RDB base = %zx\n", arbel, icm_offset );
2208
-	icm_offset += icm_usage ( log_num_rdbs, 32 );
2233
+	DBGC ( arbel, "Arbel %p ICM RDB at [%zx,%zx)\n",
2234
+	       arbel, icm_offset, ( icm_offset + len ) );
2235
+	icm_offset += len;
2209 2236
 
2210 2237
 	/* Event queue contexts */
2211
-	log_num_eqs =  fls ( arbel->limits.reserved_eqs + ARBEL_MAX_EQS - 1 );
2238
+	log_num_eqs = fls ( arbel->limits.reserved_eqs + ARBEL_MAX_EQS - 1 );
2239
+	len = ( ( 1 << log_num_eqs ) * arbel->limits.eqc_entry_size );
2240
+	icm_offset = icm_align ( icm_offset, len );
2212 2241
 	MLX_FILL_2 ( init_hca, 33,
2213 2242
 		     qpc_eec_cqc_eqc_rdb_parameters.eqc_base_addr_l,
2214 2243
 		     ( icm_offset >> 6 ),
2215 2244
 		     qpc_eec_cqc_eqc_rdb_parameters.log_num_eq,
2216 2245
 		     log_num_eqs );
2217
-	DBGC ( arbel, "Arbel %p ICM EQ base = %zx\n", arbel, icm_offset );
2218
-	icm_offset += ( ( 1 << log_num_eqs ) * arbel->limits.eqc_entry_size );
2246
+	DBGC ( arbel, "Arbel %p ICM EQ at [%zx,%zx)\n",
2247
+	       arbel, icm_offset, ( icm_offset + len ) );
2248
+	icm_offset += len;
2219 2249
 
2220 2250
 	/* Multicast table */
2251
+	log_num_mcs = ARBEL_LOG_MULTICAST_HASH_SIZE;
2252
+	len = ( ( 1 << log_num_mcs ) * sizeof ( struct arbelprm_mgm_entry ) );
2253
+	icm_offset = icm_align ( icm_offset, len );
2221 2254
 	MLX_FILL_1 ( init_hca, 49,
2222 2255
 		     multicast_parameters.mc_base_addr_l, icm_offset );
2223 2256
 	MLX_FILL_1 ( init_hca, 52,
2224 2257
 		     multicast_parameters.log_mc_table_entry_sz,
2225 2258
 		     fls ( sizeof ( struct arbelprm_mgm_entry ) - 1 ) );
2226 2259
 	MLX_FILL_1 ( init_hca, 53,
2227
-		     multicast_parameters.mc_table_hash_sz, 8 );
2260
+		     multicast_parameters.mc_table_hash_sz,
2261
+		     ( 1 << log_num_mcs ) );
2228 2262
 	MLX_FILL_1 ( init_hca, 54,
2229
-		     multicast_parameters.log_mc_table_sz, 3 );
2230
-	DBGC ( arbel, "Arbel %p ICM MC base = %zx\n", arbel, icm_offset );
2231
-	icm_offset += ( 8 * sizeof ( struct arbelprm_mgm_entry ) );
2263
+		     multicast_parameters.log_mc_table_sz,
2264
+		     log_num_mcs /* Only one entry per hash */ );
2265
+	DBGC ( arbel, "Arbel %p ICM MC at [%zx,%zx)\n",
2266
+	       arbel, icm_offset, ( icm_offset + len ) );
2267
+	icm_offset += len;
2232 2268
 
2233
-	arbel->icm_len = icm_offset;
2234
-	arbel->icm_len = ( ( arbel->icm_len + 4095 ) & ~4095 );
2269
+	/* Round up to a whole number of pages */
2270
+	arbel->icm_len = icm_align ( icm_offset, ARBEL_PAGE_SIZE );
2235 2271
 
2236 2272
 	/* Get ICM auxiliary area size */
2237 2273
 	memset ( &icm_size, 0, sizeof ( icm_size ) );
@@ -2242,7 +2278,8 @@ static int arbel_alloc_icm ( struct arbel *arbel,
2242 2278
 		       arbel, strerror ( rc ) );
2243 2279
 		goto err_set_icm_size;
2244 2280
 	}
2245
-	arbel->icm_aux_len = ( MLX_GET ( &icm_aux_size, value ) * 4096 );
2281
+	arbel->icm_aux_len =
2282
+		( MLX_GET ( &icm_aux_size, value ) * ARBEL_PAGE_SIZE );
2246 2283
 
2247 2284
 	/* Allocate ICM data and auxiliary area */
2248 2285
 	DBGC ( arbel, "Arbel %p requires %zd kB ICM and %zd kB AUX ICM\n",
@@ -2257,7 +2294,8 @@ static int arbel_alloc_icm ( struct arbel *arbel,
2257 2294
 	/* Map ICM auxiliary area */
2258 2295
 	memset ( &map_icm_aux, 0, sizeof ( map_icm_aux ) );
2259 2296
 	MLX_FILL_2 ( &map_icm_aux, 3,
2260
-		     log2size, fls ( ( arbel->icm_aux_len / 4096 ) - 1 ),
2297
+		     log2size,
2298
+		     fls ( ( arbel->icm_aux_len / ARBEL_PAGE_SIZE ) - 1 ),
2261 2299
 		     pa_l,
2262 2300
 		     ( user_to_phys ( arbel->icm, arbel->icm_len ) >> 12 ) );
2263 2301
 	if ( ( rc = arbel_cmd_map_icm_aux ( arbel, &map_icm_aux ) ) != 0 ) {
@@ -2269,7 +2307,8 @@ static int arbel_alloc_icm ( struct arbel *arbel,
2269 2307
 	/* MAP ICM area */
2270 2308
 	memset ( &map_icm, 0, sizeof ( map_icm ) );
2271 2309
 	MLX_FILL_2 ( &map_icm, 3,
2272
-		     log2size, fls ( ( arbel->icm_len / 4096 ) - 1 ),
2310
+		     log2size,
2311
+		     fls ( ( arbel->icm_len / ARBEL_PAGE_SIZE ) - 1 ),
2273 2312
 		     pa_l, ( user_to_phys ( arbel->icm, 0 ) >> 12 ) );
2274 2313
 	if ( ( rc = arbel_cmd_map_icm ( arbel, &map_icm ) ) != 0 ) {
2275 2314
 		DBGC ( arbel, "Arbel %p could not map ICM: %s\n",
@@ -2287,7 +2326,7 @@ static int arbel_alloc_icm ( struct arbel *arbel,
2287 2326
 
2288 2327
 	return 0;
2289 2328
 
2290
-	arbel_cmd_unmap_icm ( arbel, ( arbel->icm_len / 4096 ) );
2329
+	arbel_cmd_unmap_icm ( arbel, ( arbel->icm_len / ARBEL_PAGE_SIZE ) );
2291 2330
  err_map_icm:
2292 2331
 	arbel_cmd_unmap_icm_aux ( arbel );
2293 2332
  err_map_icm_aux:
@@ -2304,7 +2343,7 @@ static int arbel_alloc_icm ( struct arbel *arbel,
2304 2343
  * @v arbel		Arbel device
2305 2344
  */
2306 2345
 static void arbel_free_icm ( struct arbel *arbel ) {
2307
-	arbel_cmd_unmap_icm ( arbel, ( arbel->icm_len / 4096 ) );
2346
+	arbel_cmd_unmap_icm ( arbel, ( arbel->icm_len / ARBEL_PAGE_SIZE ) );
2308 2347
 	arbel_cmd_unmap_icm_aux ( arbel );
2309 2348
 	ufree ( arbel->icm );
2310 2349
 	arbel->icm = UNULL;

+ 4
- 0
src/drivers/infiniband/arbel.h View File

@@ -93,6 +93,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
93 93
 
94 94
 #define ARBEL_PAGE_SIZE			4096
95 95
 
96
+#define ARBEL_RDB_ENTRY_SIZE		32
97
+
96 98
 #define ARBEL_DB_POST_SND_OFFSET	0x10
97 99
 #define ARBEL_DB_EQ_OFFSET(_eqn)	( 0x08 * (_eqn) )
98 100
 
@@ -103,6 +105,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
103 105
 
104 106
 #define ARBEL_EV_PORT_STATE_CHANGE	0x09
105 107
 
108
+#define ARBEL_LOG_MULTICAST_HASH_SIZE	3
109
+
106 110
 /*
107 111
  * Datatypes that seem to be missing from the autogenerated documentation
108 112
  *

Loading…
Cancel
Save