tester.c 5.57 KB
Newer Older
Antoine Kaufmann's avatar
Antoine Kaufmann committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
 * Copyright 2021 Max Planck Institute for Software Systems, and
 * National University of Singapore
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

25
26
27
#include <assert.h>
#include <fcntl.h>
#include <signal.h>
Jialin Li's avatar
Jialin Li committed
28
#include <stdio.h>
29
#include <stdlib.h>
Jialin Li's avatar
Jialin Li committed
30
#include <string.h>
31
#include <sys/mman.h>
Jialin Li's avatar
Jialin Li committed
32
33
34
35
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

36
#include <simbricks/nicif/nicif.h>
37
38
#include <simbricks/proto/pcie.h>

Jialin Li's avatar
Jialin Li committed
39
40
41
42
43
44
45
46
47
48
static uint8_t *d2h_queue;
static size_t d2h_pos;
static size_t d2h_elen;
static size_t d2h_enum;

static uint8_t *h2d_queue;
static size_t h2d_pos;
static size_t h2d_elen;
static size_t h2d_enum;

49
50
static void sigint_handler(int dummy) {
  exit(1);
Jialin Li's avatar
Jialin Li committed
51
52
}

53
54
static int uxsocket_init() {
  int cfd;
Jialin Li's avatar
Jialin Li committed
55

56
57
58
  if ((cfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
    return -1;
  }
Jialin Li's avatar
Jialin Li committed
59

60
61
62
63
  struct sockaddr_un saun;
  memset(&saun, 0, sizeof(saun));
  saun.sun_family = AF_UNIX;
  memcpy(saun.sun_path, "/tmp/cosim-pci", strlen("/tmp/cosim-pci"));
Jialin Li's avatar
Jialin Li committed
64

65
66
67
68
  if (connect(cfd, (struct sockaddr *)&saun, sizeof(saun)) == -1) {
    close(cfd);
    return -1;
  }
Jialin Li's avatar
Jialin Li committed
69

70
  return cfd;
Jialin Li's avatar
Jialin Li committed
71
72
}

73
static int queue_create(const struct SimbricksProtoPcieDevIntro di) {
74
75
76
77
78
  int fd = -1;
  if ((fd = open("/dev/shm/dummy_nic_shm", O_RDWR)) == -1) {
    perror("Failed to open shm file");
    goto error;
  }
Jialin Li's avatar
Jialin Li committed
79

80
81
82
83
84
85
  void *addr;
  if ((addr = mmap(NULL, 32 * 1024 * 1024, PROT_READ | PROT_WRITE,
                   MAP_SHARED | MAP_POPULATE, fd, 0)) == (void *)-1) {
    perror("mmap failed");
    goto error;
  }
Jialin Li's avatar
Jialin Li committed
86

87
88
89
90
  d2h_queue = (uint8_t *)addr + di.d2h_offset;
  d2h_pos = 0;
  d2h_elen = di.d2h_elen;
  d2h_enum = di.d2h_nentries;
Jialin Li's avatar
Jialin Li committed
91

92
93
94
95
  h2d_queue = (uint8_t *)addr + di.h2d_offset;
  h2d_pos = 0;
  h2d_elen = di.h2d_elen;
  h2d_enum = di.h2d_nentries;
Jialin Li's avatar
Jialin Li committed
96

97
  return 0;
Jialin Li's avatar
Jialin Li committed
98
99

error:
100
101
102
103
  if (fd > 0) {
    close(fd);
  }
  return -1;
Jialin Li's avatar
Jialin Li committed
104
105
}

106
107
108
volatile union SimbricksProtoPcieH2D *h2d_alloc() {
  volatile union SimbricksProtoPcieH2D *msg =
      (volatile union SimbricksProtoPcieH2D *)(h2d_queue + h2d_pos * h2d_elen);
Jialin Li's avatar
Jialin Li committed
109

110
111
  if ((msg->dummy.own_type & SIMBRICKS_PROTO_PCIE_H2D_OWN_MASK) !=
      SIMBRICKS_PROTO_PCIE_H2D_OWN_HOST) {
112
113
114
    fprintf(stderr, "cosim: failed to allocate h2d message\n");
    exit(1);
  }
Jialin Li's avatar
Jialin Li committed
115

116
117
  h2d_pos = (h2d_pos + 1) % h2d_enum;
  return msg;
Jialin Li's avatar
Jialin Li committed
118
119
}

120
121
volatile union SimbricksProtoPcieD2H *d2h_poll() {
  volatile union SimbricksProtoPcieD2H *msg;
Jialin Li's avatar
Jialin Li committed
122

123
124
  msg =
      (volatile union SimbricksProtoPcieD2H *)(d2h_queue + d2h_pos * d2h_elen);
125
126
  if ((msg->dummy.own_type & SIMBRICKS_PROTO_PCIE_D2H_OWN_MASK) ==
      SIMBRICKS_PROTO_PCIE_D2H_OWN_DEV) {
127
128
129
    return NULL;
  }
  return msg;
Jialin Li's avatar
Jialin Li committed
130
131
}

132
133
134
135
void d2h_done(volatile union SimbricksProtoPcieD2H *msg) {
  msg->dummy.own_type =
      (msg->dummy.own_type & SIMBRICKS_PROTO_PCIE_D2H_MSG_MASK) |
      SIMBRICKS_PROTO_PCIE_D2H_OWN_DEV;
136
  d2h_pos = (d2h_pos + 1) % d2h_enum;
Jialin Li's avatar
Jialin Li committed
137
138
}

139
static void dev_read(uint64_t offset, uint16_t len) {
140
141
  volatile union SimbricksProtoPcieH2D *h2d_msg = h2d_alloc();
  volatile struct SimbricksProtoPcieH2DRead *read = &h2d_msg->read;
142
143
144
145
  read->req_id = 0xF;
  read->offset = offset;
  read->len = len;
  read->bar = 0;
146
147
  read->own_type =
      SIMBRICKS_PROTO_PCIE_H2D_MSG_READ | SIMBRICKS_PROTO_PCIE_H2D_OWN_DEV;
148

149
  volatile union SimbricksProtoPcieD2H *d2h_msg = NULL;
150
151
152
  while (d2h_msg == NULL) {
    d2h_msg = d2h_poll();
  }
153
  volatile struct SimbricksProtoPcieD2HReadcomp *rc;
154
155
156
157
158
159
160
161
162
  rc = &d2h_msg->readcomp;
  assert(rc->req_id == 0xF);
  printf("received readcomp with data ");
  for (int i = 0; i < read->len; i++) {
    printf("%x ", ((const uint8_t *)rc->data)[i]);
  }
  printf("\n");

  d2h_done(d2h_msg);
Jialin Li's avatar
Jialin Li committed
163
164
}

165
166
int main(int argc, char *argv[]) {
  signal(SIGINT, sigint_handler);
Jialin Li's avatar
Jialin Li committed
167

168
169
170
171
172
  int cfd;
  if ((cfd = uxsocket_init()) < 0) {
    fprintf(stderr, "Failed to open unix socket\n");
    return -1;
  }
Jialin Li's avatar
Jialin Li committed
173

174
  struct SimbricksProtoPcieDevIntro di;
175
176
177
178
179
  if (recv(cfd, &di, sizeof(di), 0) != sizeof(di)) {
    perror("Failed to receive dev_intro");
    close(cfd);
    return -1;
  }
Jialin Li's avatar
Jialin Li committed
180

181
182
183
184
185
  if (queue_create(di) != 0) {
    fprintf(stderr, "Failed to create shm queues\n");
    close(cfd);
    return -1;
  }
Jialin Li's avatar
Jialin Li committed
186

187
188
  struct SimbricksProtoPcieHostIntro hi;
  hi.flags = SIMBRICKS_PROTO_PCIE_FLAGS_HI_SYNC;
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
  if (send(cfd, &hi, sizeof(hi), 0) != sizeof(hi)) {
    perror("Failed to send host_intro");
    close(cfd);
    return -1;
  }

  while (1) {
    int op_type;
    uint64_t offset;
    uint16_t len;
    printf("op type (0-read): ");
    scanf("%d", &op_type);
    printf("offset: ");
    scanf("%lx", &offset);
    printf("len: ");
    scanf("%hu", &len);
    switch (op_type) {
      case 0:
        dev_read(offset, len);
        break;
      default:
        fprintf(stderr, "Unimplemented type %u\n", op_type);
Jialin Li's avatar
Jialin Li committed
211
    }
212
  }
Jialin Li's avatar
Jialin Li committed
213

214
215
  close(cfd);
  return 0;
Jialin Li's avatar
Jialin Li committed
216
}