34
34
#include < iostream>
35
35
#include < fstream>
36
36
#include < exception>
37
+ #include < future>
37
38
#include < uuid/uuid.h>
38
39
#include " xclbin.h"
39
40
#include " aws_dev.h"
40
41
41
-
42
+ static std::map<std::string, size_t >index_map;
42
43
/*
43
44
* Functions each plugin needs to provide
44
45
*/
@@ -59,11 +60,15 @@ int init(mpd_plugin_callbacks *cbs)
59
60
syslog (LOG_INFO, " aws: no device found" );
60
61
return ret;
61
62
}
63
+ ret = AwsDev::init (index_map);
64
+ if (ret)
65
+ return ret;
62
66
if (cbs)
63
67
{
64
68
// hook functions
65
69
cbs->mpc_cookie = NULL ;
66
70
cbs->get_remote_msd_fd = get_remote_msd_fd;
71
+ cbs->mb_notify = mb_notify;
67
72
cbs->mb_req .load_xclbin = awsLoadXclBin;
68
73
cbs->mb_req .peer_data .get_icap_data = awsGetIcap;
69
74
cbs->mb_req .peer_data .get_sensor_data = awsGetSensor;
@@ -108,6 +113,53 @@ int get_remote_msd_fd(size_t index, int* fd)
108
113
return 0 ;
109
114
}
110
115
116
+ /*
117
+ * callback function that is used to notify xocl the imagined xclmgmt
118
+ * online/offline
119
+ * Input:
120
+ * index: index of the user PF
121
+ * fd: mailbox file descriptor
122
+ * online: online or offline
123
+ * Output:
124
+ * None
125
+ * Return value:
126
+ * 0: success
127
+ * others: err code
128
+ */
129
+ int mb_notify (size_t index, int fd, bool online)
130
+ {
131
+ std::unique_ptr<sw_msg> swmsg;
132
+ struct xcl_mailbox_req *mb_req = NULL ;
133
+ struct xcl_mailbox_peer_state mb_conn = { 0 };
134
+ size_t data_len = sizeof (struct xcl_mailbox_peer_state ) + sizeof (struct xcl_mailbox_req );
135
+ pcieFunc dev (index);
136
+
137
+ std::vector<char > buf (data_len, 0 );
138
+ mb_req = reinterpret_cast <struct xcl_mailbox_req *>(buf.data ());
139
+
140
+ mb_req->req = XCL_MAILBOX_REQ_MGMT_STATE;
141
+ if (online)
142
+ mb_conn.state_flags |= XCL_MB_STATE_ONLINE;
143
+ else
144
+ mb_conn.state_flags |= XCL_MB_STATE_OFFLINE;
145
+ memcpy (mb_req->data , &mb_conn, sizeof (mb_conn));
146
+
147
+ try {
148
+ swmsg = std::make_unique<sw_msg>(mb_req, data_len, 0x1234 , XCL_MB_REQ_FLAG_REQUEST);
149
+ } catch (std::exception &e) {
150
+ std::cout << " aws mb_notify: " << e.what () << std::endl;
151
+ throw ;
152
+ }
153
+
154
+ struct queue_msg msg;
155
+ msg.localFd = fd;
156
+ msg.type = REMOTE_MSG;
157
+ msg.cb = nullptr ;
158
+ msg.data = std::move (swmsg);
159
+
160
+ return handleMsg (dev, msg);
161
+ }
162
+
111
163
/*
112
164
* callback function that is used to handle MAILBOX_REQ_LOAD_XCLBIN msg
113
165
*
@@ -280,6 +332,18 @@ int awsGetSubdev(size_t index, char *resp, size_t resp_len)
280
332
return ret;
281
333
}
282
334
335
+ /*
336
+ * Reset requires the mailbox msg return before the real reset
337
+ * happens. So we run user special reset in async thread.
338
+ */
339
+ std::future<void > nouse; // so far we don't care the return value of reset
340
+ static void awsResetDeviceAsync (size_t index)
341
+ {
342
+ AwsDev d (index, nullptr );
343
+ if (d.isGood ()) {
344
+ d.awsResetDevice ();
345
+ }
346
+ }
283
347
/*
284
348
* callback function that is used to handle MAILBOX_REQ_HOT_RESET msg
285
349
*
@@ -293,13 +357,9 @@ int awsGetSubdev(size_t index, char *resp, size_t resp_len)
293
357
*/
294
358
int awsResetDevice (size_t index, int *resp)
295
359
{
296
- int ret = -1 ;
297
- AwsDev d (index, nullptr );
298
- if (d.isGood ()) {
299
- *resp = d.awsResetDevice ();
300
- ret = 0 ;
301
- }
302
- return ret;
360
+ *resp = -ENOTSUP;
361
+ nouse = std::async (std::launch::async, &awsResetDeviceAsync, index);
362
+ return 0 ;
303
363
}
304
364
305
365
/*
@@ -391,6 +451,16 @@ int awsReadP2pBarAddr(size_t index, const xcl_mailbox_p2p_bar_addr *addr, int *r
391
451
return ret;
392
452
}
393
453
454
+ /*
455
+ * On AWS F1, fpga user PF without xclbin being loaded (cleared) has different
456
+ * device id (0x1042) than that of the user PF with xclbin being loaded (0xf010)
457
+ * Changint the device id needs pci node remove and rescan.
458
+ * fpga_pci_rescan_slot_app_pfs( mBoardNumber ) is the function used to do that.
459
+ * removal of the pf requires unload the xocl driver, within mpd it is impossible.
460
+ * So we assume the user already made the change by loading a default afi from cmdline
461
+ * with fpga-load-local-image.
462
+ * From mpd & xocl perspective, whichever device id doesn't matter.
463
+ */
394
464
int AwsDev::awsLoadXclBin (const xclBin *buffer)
395
465
{
396
466
#ifdef INTERNAL_TESTING_FOR_AWS
@@ -519,7 +589,19 @@ bool AwsDev::isGood() {
519
589
520
590
int AwsDev::awsUserProbe (xcl_mailbox_conn_resp *resp)
521
591
{
592
+ #ifndef INTERNAL_TESTING_FOR_AWS
593
+ fpga_slot_spec spec_array[16 ];
594
+ std::memset (spec_array, 0 , sizeof (fpga_slot_spec) * 16 );
595
+ if (fpga_pci_get_all_slot_specs (spec_array, 16 )) {
596
+ std::cout << " ERROR: failed at fpga_pci_get_all_slot_specs" << std::endl;
597
+ return -1 ;
598
+ }
599
+
600
+ if (spec_array[mBoardNumber ].map [FPGA_APP_PF].device_id != AWS_UserPF_DEVICE_ID)
601
+ resp->conn_flags |= XCL_MB_PEER_READY;
602
+ #else
522
603
resp->conn_flags |= XCL_MB_PEER_READY;
604
+ #endif
523
605
return 0 ;
524
606
}
525
607
@@ -580,15 +662,18 @@ AwsDev::~AwsDev()
580
662
}
581
663
}
582
664
583
- AwsDev::AwsDev (size_t index, const char *logfileName) : mBoardNumber(index)
665
+ AwsDev::AwsDev (size_t index, const char *logfileName)
584
666
{
585
667
if (logfileName != nullptr ) {
586
668
mLogStream .open (logfileName);
587
669
mLogStream << " FUNCTION, THREAD ID, ARG..." << std::endl;
588
670
mLogStream << __func__ << " , " << std::this_thread::get_id () << std::endl;
589
671
}
590
672
673
+ std::string sysfs_name = pcidev::get_dev (index, true )->sysfs_name ;
674
+ std::cout << " AwsDev: " << sysfs_name << " (index: " << index << " )" << std::endl;
591
675
#ifdef INTERNAL_TESTING_FOR_AWS
676
+ mBoardNumber = index;
592
677
char file_name_buf[128 ];
593
678
std::fill (&file_name_buf[0 ], &file_name_buf[0 ] + 128 , 0 );
594
679
std::sprintf ((char *)&file_name_buf, " /dev/awsmgmt%d" , mBoardNumber );
@@ -600,31 +685,13 @@ AwsDev::AwsDev(size_t index, const char *logfileName) : mBoardNumber(index)
600
685
601
686
#else
602
687
fpga_mgmt_init (); // aws-fpga version newer than 09/2019 need this
603
- loadDefaultAfiIfCleared () ;
688
+ mBoardNumber = index_map[sysfs_name] ;
604
689
// bar0 is mapped already. seems other 2 bars are not required.
605
690
#endif
606
691
}
607
692
608
693
// private functions
609
694
#ifndef INTERNAL_TESTING_FOR_AWS
610
- int AwsDev::loadDefaultAfiIfCleared ( void )
611
- {
612
- int array_len = 16 ;
613
- fpga_slot_spec spec_array[ array_len ];
614
- std::memset ( spec_array, mBoardNumber , sizeof (fpga_slot_spec) * array_len );
615
- fpga_pci_get_all_slot_specs ( spec_array, array_len );
616
- if ( spec_array[mBoardNumber ].map [FPGA_APP_PF].device_id == AWS_UserPF_DEVICE_ID ) {
617
- std::string agfi = DEFAULT_GLOBAL_AFI;
618
- fpga_mgmt_load_local_image ( mBoardNumber , const_cast <char *>(agfi.c_str ()) );
619
- if ( sleepUntilLoaded ( agfi ) ) {
620
- std::cout << " ERROR: Sleep until load failed." << std::endl;
621
- return -1 ;
622
- }
623
- fpga_pci_rescan_slot_app_pfs ( mBoardNumber );
624
- }
625
- return 0 ;
626
- }
627
-
628
695
int AwsDev::sleepUntilLoaded ( const std::string &afi )
629
696
{
630
697
for ( int i = 0 ; i < 20 ; i++ ) {
0 commit comments