summaryrefslogtreecommitdiff
path: root/ext/nomali/lib/jobslot.hh
blob: 31b178db2c956a5177e7c4351b8a9820ef7d3563 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/*
 * Copyright (c) 2014-2015 ARM Limited
 * All rights reserved
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Authors: Andreas Sandberg
 */

#ifndef _LIBNOMALIMODEL_JOBSLOT_HH
#define _LIBNOMALIMODEL_JOBSLOT_HH

#include <vector>

#include "gpublock.hh"
#include "types.hh"

namespace NoMali {

class GPU;

class JobControl;

/**
 * Midgard job slot implementation.
 *
 * A job slot is a part of a JobControl block that controls the state
 * of one out of 16 active jobs. Each slot can contain one running job
 * and a pending job.
 */
class JobSlot
    : public GPUBlock
{
  public:
    JobSlot(GPU &_gpu, JobControl &_jc, uint8_t slot_id);
    JobSlot(JobSlot &&rhs);
    virtual ~JobSlot();

    void writeReg(RegAddr idx, uint32_t value) override;

    /** Is there an active job in this job slot? */
    bool active() const;
    /** Is there a pending next job in this job slot? */
    bool activeNext() const;

  protected:
    /**
     * @{
     * @name Job Control
     */

    /**
     * Try to start the next job in the slot.
     *
     * Start the next job if the following conditions are true:
     * <ul>
     *   <li>There is no currently running job.
     *   <li>The pending command in the JSn_COMMAND_NEXT register is
     *       JSn_COMMAND_START.
     * </ul>
     *
     * When the job is started, the registers describing the next job
     * chain are moved (resetting them to zero) into the register
     * block describing the currently running job. The job is then run
     * by a call to runJob().
     */
    void tryStart();

    /**
     * Execute the job in described by the current job registers.
     */
    void runJob();

    /**
     * Report the exit status of an exiting job.
     *
     * @note The exit status must be of the class
     * Status::CLASS_NOFAULT or Status::CLASS_JOB.
     *
     * @note The fault address isn't always a fault address, it is
     * sometimes used to represent a TSC value. See the Midgard
     * architecture specification for details.
     *
     * @param status Job exit status.
     * @param fault_address Fault address to write into descriptor.
     */
    void exitJob(Status status, uint64_t fault_address);

    /** @} */

    /**
     * @{
     * @name Job slot commands
     */

    /**
     * Control command dispatcher.
     *
     * This method is called whenever there is a write to the
     * JSn_COMMAND register. The method uses a lookup table to call
     * the right command handling method.
     *
     * @param cmd Command number (see the Midgard architecture
     * specification)
     */
    void jobCommand(uint32_t cmd);

    /**
     * Command handler for No-ops.
     *
     * @param cmd Command number (see the Midgard architecture
     * specification)
     */
    void cmdNop(uint32_t cmd);
    /**
     * Command handler for job start commands.
     *
     * @note This should <i>NEVER</i> be called as the start command
     * should never be written to the JSn_COMMAND register. Jobs are
     * normally started by tryStart() whenever the state of the
     * currently running job changes or JSn_COMMAND_START is written
     * to the JSn_COMMAND_NEXT register.
     *
     * @param cmd Command number (see the Midgard architecture
     * specification)
     */
    void cmdStart(uint32_t cmd);
    /**
     * Gently stop the currently running job chain.
     *
     * @param cmd Command number (see the Midgard architecture
     * specification)
     */
    void cmdSoftStop(uint32_t cmd);
    /**
     * Force a stop of the currently running job chain.
     *
     * @param cmd Command number (see the Midgard architecture
     * specification)
     */
    void cmdHardStop(uint32_t cmd);
    /**
     * Soft stop the current job chain if the JOB_CHAIN_FLAG <i>IS
     * NOT</i> set.
     *
     * @param cmd Command number (see the Midgard architecture
     * specification)
     */
    void cmdSoftStop0(uint32_t cmd);
    /**
     * Hard stop the current job chain if the JOB_CHAIN_FLAG <i>IS
     * NOT</i> set.
     *
     * @param cmd Command number (see the Midgard architecture
     * specification)
     */
    void cmdHardStop0(uint32_t cmd);
    /**
     * Soft stop the current job chain if the JOB_CHAIN_FLAG <i>IS</i>
     * set.
     *
     * @param cmd Command number (see the Midgard architecture
     * specification)
     */
    void cmdSoftStop1(uint32_t cmd);
    /**
     * Hard stop the current job chain if the JOB_CHAIN_FLAG <i>IS</i>
     * set.
     *
     * @param cmd Command number (see the Midgard architecture
     * specification)
     */
    void cmdHardStop1(uint32_t cmd);

    /** @} */

    /** Job slot ID */
    const uint8_t id;

    /** Parent JobControl block */
    JobControl &jc;

  private:
    typedef void (JobSlot::*cmd_t)(uint32_t);

    /**
     * Mapping between command IDs and command handling methods.
     *
     * @note The order of this vector <i>MUST</i> correspond to the
     * job control command IDs in the Midgard architecture
     * specification.
     */
    static const std::vector<cmd_t> cmds;
};

}

#endif // _LIBNOMALIMODEL_JOBSLOT_HH