coord.h 4.36 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
27
28
29
30
31
#ifndef COORD_H_
#define COORD_H_

#include <deque>
#include <map>
#include <iostream>

Antoine Kaufmann's avatar
Antoine Kaufmann committed
32
#include "sims/nic/corundum/debug.h"
Antoine Kaufmann's avatar
Antoine Kaufmann committed
33
34

class DMAOp;
35
struct MMIOOp;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
36
37
38

void pci_dma_issue(DMAOp *op);
void pci_msi_issue(uint8_t vec);
39
void pci_rwcomp_issue(MMIOOp *op);
Antoine Kaufmann's avatar
Antoine Kaufmann committed
40
41
42
43
44
45

class PCICoordinator {
    protected:
        struct PCIOp {
            union {
                DMAOp *dma_op;
46
                MMIOOp *mmio_op;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
47
48
                uint32_t msi_vec;
            };
49
50
51
52
53
            enum {
                OP_DMA,
                OP_MSI,
                OP_RWCOMP,
            } type;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
            bool ready;
        };

        std::deque<PCIOp *> queue;
        std::map<DMAOp *, PCIOp *> dmamap;

        void process()
        {
            PCIOp *op;
            while (!queue.empty()) {
                op = queue.front();
                if (!op->ready)
                    break;

                queue.pop_front();
69
                if (op->type == PCIOp::OP_MSI) {
Antoine Kaufmann's avatar
Antoine Kaufmann committed
70
#ifdef COORD_DEBUG
Antoine Kaufmann's avatar
Antoine Kaufmann committed
71
72
                    std::cout << main_time << " issuing msi " << op->msi_vec <<
                        std::endl;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
73
74
#endif
                    pci_msi_issue(op->msi_vec);
75
                } else if (op->type == PCIOp::OP_DMA) {
Antoine Kaufmann's avatar
Antoine Kaufmann committed
76
#ifdef COORD_DEBUG
Antoine Kaufmann's avatar
Antoine Kaufmann committed
77
78
                    std::cout << main_time << " issuing dma " << op->dma_op <<
                        std::endl;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
79
80
81
#endif
                    pci_dma_issue(op->dma_op);
                    dmamap.erase(op->dma_op);
82
83
                } else if (op->type == PCIOp::OP_RWCOMP) {
#ifdef COORD_DEBUG
Antoine Kaufmann's avatar
Antoine Kaufmann committed
84
85
                    std::cout << main_time << " issuing mmio " << op->mmio_op <<
                        std::endl;
86
87
88
89
#endif
                    pci_rwcomp_issue(op->mmio_op);
                } else {
                    throw "unknown type";
Antoine Kaufmann's avatar
Antoine Kaufmann committed
90
                }
91

Antoine Kaufmann's avatar
Antoine Kaufmann committed
92
93
94
95
96
97
98
99
                delete op;
            }
        }

    public:
        void dma_register(DMAOp *dma_op, bool ready)
        {
#ifdef COORD_DEBUG
Antoine Kaufmann's avatar
Antoine Kaufmann committed
100
101
            std::cout << main_time << " registering dma op " << dma_op << "  "
                << ready << std::endl;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
102
103
104
#endif
            PCIOp *op = new PCIOp;
            op->dma_op = dma_op;
105
            op->type = PCIOp::OP_DMA;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
106
107
108
109
110
111
112
113
114
115
116
            op->ready = ready;

            queue.push_back(op);
            dmamap[dma_op] = op;

            process();
        }

        void dma_mark_ready(DMAOp *op)
        {
#ifdef COORD_DEBUG
117
            std::cout << main_time << " readying dma op " << op <<  std::endl;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
118
119
120
121
122
123
124
125
126
#endif
            dmamap[op]->ready = true;

            process();
        }

        void msi_enqueue(uint32_t vec)
        {
#ifdef COORD_DEBUG
127
            std::cout << main_time << " enqueuing MSI " << vec <<  std::endl;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
128
129
130
#endif
            PCIOp *op = new PCIOp;
            op->msi_vec = vec;
131
132
133
134
135
136
137
138
139
140
            op->type = PCIOp::OP_MSI;
            op->ready = true;
            queue.push_back(op);

            process();
        }

        void mmio_comp_enqueue(MMIOOp *mmio_op)
        {
#ifdef COORD_DEBUG
Antoine Kaufmann's avatar
Antoine Kaufmann committed
141
142
            std::cout << main_time << " enqueuing MMIO comp " << mmio_op <<
                std::endl;
143
144
145
146
#endif
            PCIOp *op = new PCIOp;
            op->mmio_op = mmio_op;
            op->type = PCIOp::OP_RWCOMP;
Antoine Kaufmann's avatar
Antoine Kaufmann committed
147
148
149
150
151
152
153
            op->ready = true;
            queue.push_back(op);

            process();
        }
};

Antoine Kaufmann's avatar
Antoine Kaufmann committed
154
#endif  // COORD_H_