@@ -204,254 +204,3 @@ def gen_simulation(self, selfp):
204
204
else :
205
205
self .callback (rx_dword )
206
206
self .insert_cont ()
207
-
208
-
209
- # Transport Layer model
210
- def print_transport (s ):
211
- print_with_prefix (s , "[TRN]: " )
212
-
213
-
214
- def get_field_data (field , packet ):
215
- return (packet [field .byte // 4 ] >> field .offset ) & (2 ** field .width - 1 )
216
-
217
-
218
- class FIS :
219
- def __init__ (self , packet , description , direction = "H2D" ):
220
- self .packet = packet
221
- self .description = description
222
- self .direction = direction
223
- self .decode ()
224
-
225
- def decode (self ):
226
- for k , v in self .description .items ():
227
- setattr (self , k , get_field_data (v , self .packet ))
228
-
229
- def encode (self ):
230
- for k , v in self .description .items ():
231
- self .packet [v .byte // 4 ] |= (getattr (self , k ) << v .offset )
232
-
233
- def __repr__ (self ):
234
- if self .direction == "H2D" :
235
- r = ">>>>>>>>\n "
236
- else :
237
- r = "<<<<<<<<\n "
238
- for k in sorted (self .description .keys ()):
239
- r += k + " : 0x{:x}" .format (getattr (self , k )) + "\n "
240
- return r
241
-
242
-
243
- class FIS_REG_H2D (FIS ):
244
- def __init__ (self , packet = [0 ]* fis_reg_h2d_header .length ):
245
- FIS .__init__ (self , packet , fis_reg_h2d_header .fields )
246
- self .type = fis_types ["REG_H2D" ]
247
- self .direction = "H2D"
248
-
249
- def __repr__ (self ):
250
- r = "FIS_REG_H2D\n "
251
- r += FIS .__repr__ (self )
252
- return r
253
-
254
-
255
- class FIS_REG_D2H (FIS ):
256
- def __init__ (self , packet = [0 ]* fis_reg_d2h_header .length ):
257
- FIS .__init__ (self , packet , fis_reg_d2h_header .fields )
258
- self .type = fis_types ["REG_D2H" ]
259
- self .direction = "D2H"
260
-
261
- def __repr__ (self ):
262
- r = "FIS_REG_D2H\n "
263
- r += FIS .__repr__ (self )
264
- return r
265
-
266
-
267
- class FIS_DMA_ACTIVATE_D2H (FIS ):
268
- def __init__ (self , packet = [0 ]* fis_dma_activate_d2h_header .length ):
269
- FIS .__init__ (self , packet , fis_dma_activate_d2h_header .fields )
270
- self .type = fis_types ["DMA_ACTIVATE_D2H" ]
271
- self .direction = "D2H"
272
-
273
- def __repr__ (self ):
274
- r = "FIS_DMA_ACTIVATE_D2H\n "
275
- r += FIS .__repr__ (self )
276
- return r
277
-
278
-
279
- class FIS_DATA (FIS ):
280
- def __init__ (self , packet = [0 ], direction = "H2D" ):
281
- FIS .__init__ (self , packet , fis_data_header .fields , direction )
282
- self .type = fis_types ["DATA" ]
283
-
284
- def __repr__ (self ):
285
- r = "FIS_DATA\n "
286
- r += FIS .__repr__ (self )
287
- for data in self .packet [1 :]:
288
- r += "{:08x}\n " .format (data )
289
- return r
290
-
291
-
292
- class FIS_UNKNOWN (FIS ):
293
- def __init__ (self , packet = [0 ], direction = "H2D" ):
294
- FIS .__init__ (self , packet , {}, direction )
295
-
296
- def __repr__ (self ):
297
- r = "UNKNOWN\n "
298
- if self .direction == "H2D" :
299
- r += ">>>>>>>>\n "
300
- else :
301
- r += "<<<<<<<<\n "
302
- for dword in self .packet :
303
- r += "{:08x}\n " .format (dword )
304
- return r
305
-
306
-
307
- class TransportLayer (Module ):
308
- def __init__ (self , link , debug = False , loopback = False ):
309
- self .link = link
310
- self .debug = debug
311
- self .loopback = loopback
312
- self .link .set_transport_callback (self .callback )
313
-
314
- def set_command_callback (self , callback ):
315
- self .command_callback = callback
316
-
317
- def send (self , fis ):
318
- fis .encode ()
319
- packet = LinkTXPacket (fis .packet )
320
- self .link .tx_packets .append (packet )
321
- if self .debug and not self .loopback :
322
- print_transport (fis )
323
-
324
- def callback (self , packet ):
325
- fis_type = packet [0 ] & 0xff
326
- if fis_type == fis_types ["REG_H2D" ]:
327
- fis = FIS_REG_H2D (packet )
328
- elif fis_type == fis_types ["REG_D2H" ]:
329
- fis = FIS_REG_D2H (packet )
330
- elif fis_type == fis_types ["DMA_ACTIVATE_D2H" ]:
331
- fis = FIS_DMA_ACTIVATE_D2H (packet )
332
- elif fis_type == fis_types ["DATA" ]:
333
- fis = FIS_DATA (packet , direction = "H2D" )
334
- else :
335
- fis = FIS_UNKNOWN (packet , direction = "H2D" )
336
- if self .debug :
337
- print_transport (fis )
338
- if self .loopback :
339
- self .send (fis )
340
- else :
341
- self .command_callback (fis )
342
-
343
-
344
- # Command Layer model
345
- class CommandLayer (Module ):
346
- def __init__ (self , transport ):
347
- self .transport = transport
348
- self .transport .set_command_callback (self .callback )
349
-
350
- self .hdd = None
351
-
352
- def set_hdd (self , hdd ):
353
- self .hdd = hdd
354
-
355
- def callback (self , fis ):
356
- resp = None
357
- if isinstance (fis , FIS_REG_H2D ):
358
- if fis .command == regs ["WRITE_DMA_EXT" ]:
359
- resp = self .hdd .write_dma_callback (fis )
360
- elif fis .command == regs ["READ_DMA_EXT" ]:
361
- resp = self .hdd .read_dma_callback (fis )
362
- elif isinstance (fis , FIS_DATA ):
363
- resp = self .hdd .data_callback (fis )
364
-
365
- if resp is not None :
366
- for packet in resp :
367
- self .transport .send (packet )
368
-
369
-
370
- # HDD model
371
- def print_hdd (s ):
372
- print_with_prefix (s , "[HDD]: " )
373
-
374
-
375
- class HDDMemRegion :
376
- def __init__ (self , base , count , sector_size ):
377
- self .base = base
378
- self .count = count
379
- self .data = [0 ]* (count * sector_size // 4 )
380
-
381
-
382
- class HDD (Module ):
383
- def __init__ (self ,
384
- link_debug = False , link_random_level = 0 ,
385
- transport_debug = False , transport_loopback = False ,
386
- hdd_debug = False ,
387
- ):
388
- self .submodules .phy = PHYLayer ()
389
- self .submodules .link = LinkLayer (self .phy , link_debug , link_random_level )
390
- self .submodules .transport = TransportLayer (self .link , transport_debug , transport_loopback )
391
- self .submodules .command = CommandLayer (self .transport )
392
-
393
- self .command .set_hdd (self )
394
-
395
- self .debug = hdd_debug
396
- self .mem = None
397
- self .wr_sector = 0
398
- self .wr_end_sector = 0
399
- self .rd_sector = 0
400
- self .rx_end_sector = 0
401
-
402
- def malloc (self , sector , count ):
403
- if self .debug :
404
- s = "Allocating {n} sectors: {s} to {e}" .format (n = count , s = sector , e = sector + count - 1 )
405
- s += " ({} KB)" .format (count * logical_sector_size // 1024 )
406
- print_hdd (s )
407
- self .mem = HDDMemRegion (sector , count , logical_sector_size )
408
-
409
- def write (self , sector , data ):
410
- n = math .ceil (dwords2sectors (len (data )))
411
- if self .debug :
412
- if n == 1 :
413
- s = "{}" .format (sector )
414
- else :
415
- s = "{s} to {e}" .format (s = sector , e = sector + n - 1 )
416
- print_hdd ("Writing sector " + s )
417
- for i in range (len (data )):
418
- offset = sectors2dwords (sector )
419
- self .mem .data [offset + i ] = data [i ]
420
-
421
- def read (self , sector , count ):
422
- if self .debug :
423
- if count == 1 :
424
- s = "{}" .format (sector )
425
- else :
426
- s = "{s} to {e}" .format (s = sector , e = sector + count - 1 )
427
- print_hdd ("Reading sector " + s )
428
- data = []
429
- for i in range (sectors2dwords (count )):
430
- data .append (self .mem .data [sectors2dwords (sector )+ i ])
431
- return data
432
-
433
- def write_dma_callback (self , fis ):
434
- self .wr_sector = fis .lba_lsb + (fis .lba_msb << 32 )
435
- self .wr_end_sector = self .wr_sector + fis .count
436
- return [FIS_DMA_ACTIVATE_D2H ()]
437
-
438
- def read_dma_callback (self , fis ):
439
- self .rd_sector = fis .lba_lsb + (fis .lba_msb << 32 )
440
- self .rd_end_sector = self .rd_sector + fis .count
441
- packets = []
442
- while self .rd_sector != self .rd_end_sector :
443
- count = min (self .rd_end_sector - self .rd_sector , (fis_max_dwords * 4 )// logical_sector_size )
444
- packet = self .read (self .rd_sector , count )
445
- packet .insert (0 , 0 )
446
- packets .append (FIS_DATA (packet , direction = "D2H" ))
447
- self .rd_sector += count
448
- packets .append (FIS_REG_D2H ())
449
- return packets
450
-
451
- def data_callback (self , fis ):
452
- self .write (self .wr_sector , fis .packet [1 :])
453
- self .wr_sector += dwords2sectors (len (fis .packet [1 :]))
454
- if self .wr_sector == self .wr_end_sector :
455
- return [FIS_REG_D2H ()]
456
- else :
457
- return [FIS_DMA_ACTIVATE_D2H ()]
0 commit comments