i40e_hmc.cc 4.65 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.
 */

Antoine Kaufmann's avatar
Antoine Kaufmann committed
25
26
#include <stdlib.h>
#include <string.h>
27

Antoine Kaufmann's avatar
Antoine Kaufmann committed
28
29
30
#include <cassert>
#include <iostream>

Antoine Kaufmann's avatar
Antoine Kaufmann committed
31
#include "sims/nic/i40e_bm/i40e_base_wrapper.h"
32
#include "sims/nic/i40e_bm/i40e_bm.h"
Antoine Kaufmann's avatar
Antoine Kaufmann committed
33

34
namespace i40e {
Antoine Kaufmann's avatar
Antoine Kaufmann committed
35
36
37

extern nicbm::Runner *runner;

38
39
host_mem_cache::host_mem_cache(i40e_bm &dev_) : dev(dev_) {
  reset();
40
41
}

42
43
44
45
46
47
48
void host_mem_cache::reset() {
  for (size_t i = 0; i < MAX_SEGMENTS; i++) {
    segs[i].addr = 0;
    segs[i].pgcount = 0;
    segs[i].valid = false;
    segs[i].direct = false;
  }
Antoine Kaufmann's avatar
Antoine Kaufmann committed
49
50
}

51
52
53
54
55
56
57
58
59
60
61
void host_mem_cache::reg_updated(uint64_t addr) {
  if (addr == I40E_PFHMC_SDCMD) {
    // read/write command for descriptor
    uint32_t cmd = dev.regs.pfhmc_sdcmd;
    uint16_t idx =
        (cmd & I40E_PFHMC_SDCMD_PMSDIDX_MASK) >> I40E_PFHMC_SDCMD_PMSDIDX_SHIFT;

    uint32_t lo = dev.regs.pfhmc_sddatalow;
    uint32_t hi = dev.regs.pfhmc_sddatahigh;
    if ((cmd & I40E_PFHMC_SDCMD_PMSDWR_MASK)) {
      // write
62
#ifdef DEBUG_HMC
63
      std::cerr << "hmc: writing descriptor " << idx << std::endl;
64
#endif
65

66
67
68
69
70
71
72
73
      segs[idx].addr = ((lo & I40E_PFHMC_SDDATALOW_PMSDDATALOW_MASK) >>
                        I40E_PFHMC_SDDATALOW_PMSDDATALOW_SHIFT)
                       << 12;
      segs[idx].addr |= ((uint64_t)hi) << 32;
      segs[idx].pgcount = (lo & I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_MASK) >>
                          I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT;
      segs[idx].valid = !!(lo & I40E_PFHMC_SDDATALOW_PMSDVALID_MASK);
      segs[idx].direct = !!(lo & I40E_PFHMC_SDDATALOW_PMSDTYPE_MASK);
74

75
#ifdef DEBUG_HMC
76
77
78
79
      std::cerr << "    addr=" << segs[idx].addr
                << " pgcount=" << segs[idx].pgcount
                << " valid=" << segs[idx].valid
                << " direct=" << segs[idx].direct << std::endl;
80
#endif
81
82
    } else {
      // read
83
#ifdef DEBUG_HMC
84
      std::cerr << "hmc: reading descriptor " << idx << std::endl;
85
#endif
86

87
88
89
90
91
92
93
94
95
96
97
      dev.regs.pfhmc_sddatalow =
          ((segs[idx].addr >> 12) << I40E_PFHMC_SDDATALOW_PMSDDATALOW_SHIFT) &
          I40E_PFHMC_SDDATALOW_PMSDDATALOW_MASK;
      dev.regs.pfhmc_sddatalow |=
          (segs[idx].pgcount << I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT) &
          I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_MASK;
      if (segs[idx].valid)
        dev.regs.pfhmc_sddatalow |= I40E_PFHMC_SDDATALOW_PMSDVALID_MASK;
      if (segs[idx].direct)
        dev.regs.pfhmc_sddatalow |= I40E_PFHMC_SDDATALOW_PMSDTYPE_MASK;
      dev.regs.pfhmc_sddatahigh = segs[idx].addr >> 32;
98
    }
99
  }
100
101
}

102
void host_mem_cache::issue_mem_op(mem_op &op) {
103
  uint64_t addr = op.dma_addr_;
104
  uint16_t seg_idx = addr >> 21;
105
  uint16_t seg_idx_last = (addr + op.len_ - 1) >> 21;
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
  uint32_t dir_off = addr & ((1 << 21) - 1);
  struct segment *seg = &segs[seg_idx];

  if (seg_idx >= MAX_SEGMENTS) {
    std::cerr << "hmc issue_mem_op: seg index too high " << seg_idx
              << std::endl;
    abort();
  }

  if (!seg->valid) {
    // TODO(antoinek): errorinfo and data registers
    std::cerr << "hmc issue_mem_op: segment invalid addr=" << addr << std::endl;
    op.failed = true;
    return;
  }

  if (seg_idx != seg_idx_last) {
    std::cerr << "hmc issue_mem_op: operation crosses segs addr=" << addr
124
              << " len=" << op.len_ << std::endl;
125
126
127
128
129
130
131
132
133
    abort();
  }

  if (!seg->direct) {
    std::cerr << "hmc issue_mem_op: TODO paged ops addr=" << addr << std::endl;
    abort();
  }

  op.failed = false;
134
  op.dma_addr_ = seg->addr + dir_off;
135

136
#ifdef DEBUG_HMC
137
138
  std::cerr << "hmc issue_mem_op: hmc_addr=" << addr
            << " dma_addr=" << op.dma_addr << " len=" << op.len << std::endl;
139
#endif
140
  runner->IssueDma(op);
Antoine Kaufmann's avatar
Antoine Kaufmann committed
141
}
142
}  // namespace i40e