bmv2
Designing your own switch target with bmv2
debugger.h
1 /* Copyright 2013-present Barefoot Networks, Inc.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 /*
17  * Antonin Bas (antonin@barefootnetworks.com)
18  *
19  */
20 
21 #ifndef BM_BM_SIM_DEBUGGER_H_
22 #define BM_BM_SIM_DEBUGGER_H_
23 
24 #include <bm/config.h>
25 
26 #include <limits>
27 #include <memory>
28 #include <string>
29 
30 namespace bm {
31 
32 using device_id_t = uint64_t;
33 using s_device_id_t = device_id_t;
34 
35 /* This whole code if for a proof of concept and is temporary */
36 
37 // forward declaration
38 class DebuggerIface;
39 
40 // TODO(antonin)
41 // temprorary: experimenting with debugger
42 #define DBG_CTR_PARSER (1 << 24)
43 #define DBG_CTR_PARSE_STATE (2 << 24)
44 #define DBG_CTR_CONTROL (3 << 24)
45 #define DBG_CTR_TABLE (4 << 24)
46 #define DBG_CTR_CONDITION (5 << 24)
47 #define DBG_CTR_ACTION (6 << 24)
48 #define DBG_CTR_DEPARSER (7 << 24)
49 
50 #define DBG_CTR_EXIT(x) (x | (0x80 << 24))
51 
52 class Debugger {
53  public:
54  static constexpr uint64_t FIELD_COND =
55  std::numeric_limits<uint64_t>::max() - 1;
56 
57  static constexpr uint64_t FIELD_ACTION =
58  std::numeric_limits<uint64_t>::max() - 2;
59 
60  struct PacketId {
61  uint64_t packet_id;
62  uint64_t copy_id;
63 
64  bool operator==(const PacketId& other) const {
65  return packet_id == other.packet_id && copy_id == other.copy_id;
66  }
67 
68  bool operator!=(const PacketId& other) const {
69  return !(*this == other);
70  }
71 
72  static PacketId make(uint64_t packet_id, uint64_t copy_id) {
73  return {packet_id, copy_id};
74  }
75  };
76 
77  static void init_debugger(const std::string &addr, device_id_t device_id);
78 
79  static DebuggerIface *get() {
80  return debugger;
81  }
82 
83  // returns an empty string if debugger wasn't initialized
84  static std::string get_addr();
85 
86  static DebuggerIface *debugger;
87 
88  static constexpr PacketId dummy_PacketId{0u, 0u};
89 
90  private:
91  static bool is_init;
92 };
93 
94 class DebuggerIface {
95  public:
96  using PacketId = Debugger::PacketId;
97 
98  void notify_update(const PacketId &packet_id,
99  uint64_t id, const char *bytes, int nbits) {
100  notify_update_(packet_id, id, bytes, nbits);
101  }
102 
103  void notify_update(const PacketId &packet_id,
104  uint64_t id, uint32_t v) {
105  notify_update_(packet_id, id, v);
106  }
107 
108  void notify_ctr(const PacketId &packet_id, uint32_t ctr) {
109  notify_ctr_(packet_id, ctr);
110  }
111 
112  void packet_in(const PacketId &packet_id, int port) {
113  packet_in_(packet_id, port);
114  }
115 
116  void packet_out(const PacketId &packet_id, int port) {
117  packet_out_(packet_id, port);
118  }
119 
120  void config_change() {
121  config_change_();
122  }
123 
124  std::string get_addr() const {
125  return get_addr_();
126  }
127 
128  protected:
129  ~DebuggerIface() { }
130 
131  private:
132  virtual void notify_update_(const PacketId &packet_id, uint64_t id,
133  const char *bytes, int nbits) = 0;
134 
135  virtual void notify_update_(const PacketId &packet_id, uint64_t id,
136  uint32_t v) = 0;
137 
138  virtual void notify_ctr_(const PacketId &packet_id, uint32_t ctr) = 0;
139 
140  virtual void packet_in_(const PacketId &packet_id, int port) = 0;
141 
142  virtual void packet_out_(const PacketId &packet_id, int port) = 0;
143 
144  virtual void config_change_() = 0;
145 
146  virtual std::string get_addr_() const = 0;
147 };
148 
149 #ifdef BM_DEBUG_ON
150 #define DEBUGGER_NOTIFY_UPDATE(packet_id, id, bytes, nbits) \
151  Debugger::get()->notify_update(packet_id, id, bytes, nbits);
152 #define DEBUGGER_NOTIFY_UPDATE_V(packet_id, id, v) \
153  Debugger::get()->notify_update(packet_id, id, v);
154 #define DEBUGGER_NOTIFY_CTR(packet_id, ctr) \
155  Debugger::get()->notify_ctr(packet_id, ctr);
156 #define DEBUGGER_PACKET_IN(packet_id, port) \
157  Debugger::get()->packet_in(packet_id, port);
158 #define DEBUGGER_PACKET_OUT(packet_id, port) \
159  Debugger::get()->packet_out(packet_id, port);
160 #else
161 #define DEBUGGER_NOTIFY_UPDATE(packet_id, id, bytes, nbits)
162 #define DEBUGGER_NOTIFY_UPDATE_V(packet_id, id, v)
163 #define DEBUGGER_NOTIFY_CTR(packet_id, ctr)
164 #define DEBUGGER_PACKET_IN(packet_id, port)
165 #define DEBUGGER_PACKET_OUT(packet_id, port)
166 #endif
167 
168 } // namespace bm
169 
170 #endif // BM_BM_SIM_DEBUGGER_H_