1/*
2 * Copyright (c) 2014-2015 ARM Limited
3 * All rights reserved
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * Authors: Andreas Sandberg
18 */
19
20#ifndef _LIBNOMALIMODEL_JOBSLOT_HH
21#define _LIBNOMALIMODEL_JOBSLOT_HH
22
23#include <vector>
24
25#include "gpublock.hh"
26#include "types.hh"
27
28namespace NoMali {
29
30class GPU;
31
32class JobControl;
33
34/**
35 * Midgard job slot implementation.
36 *
37 * A job slot is a part of a JobControl block that controls the state
38 * of one out of 16 active jobs. Each slot can contain one running job
39 * and a pending job.
40 */
41class JobSlot
42    : public GPUBlock
43{
44  public:
45    JobSlot(GPU &_gpu, JobControl &_jc, uint8_t slot_id);
46    JobSlot(JobSlot &&rhs);
47    virtual ~JobSlot();
48
49    void writeReg(RegAddr idx, uint32_t value) override;
50
51    /** Is there an active job in this job slot? */
52    bool active() const;
53    /** Is there a pending next job in this job slot? */
54    bool activeNext() const;
55
56  protected:
57    /**
58     * @{
59     * @name Job Control
60     */
61
62    /**
63     * Try to start the next job in the slot.
64     *
65     * Start the next job if the following conditions are true:
66     * <ul>
67     *   <li>There is no currently running job.
68     *   <li>The pending command in the JSn_COMMAND_NEXT register is
69     *       JSn_COMMAND_START.
70     * </ul>
71     *
72     * When the job is started, the registers describing the next job
73     * chain are moved (resetting them to zero) into the register
74     * block describing the currently running job. The job is then run
75     * by a call to runJob().
76     */
77    void tryStart();
78
79    /**
80     * Execute the job in described by the current job registers.
81     */
82    void runJob();
83
84    /**
85     * Report the exit status of an exiting job.
86     *
87     * @note The exit status must be of the class
88     * Status::CLASS_NOFAULT or Status::CLASS_JOB.
89     *
90     * @note The fault address isn't always a fault address, it is
91     * sometimes used to represent a TSC value. See the Midgard
92     * architecture specification for details.
93     *
94     * @param status Job exit status.
95     * @param fault_address Fault address to write into descriptor.
96     */
97    void exitJob(Status status, uint64_t fault_address);
98
99    /** @} */
100
101    /**
102     * @{
103     * @name Job slot commands
104     */
105
106    /**
107     * Control command dispatcher.
108     *
109     * This method is called whenever there is a write to the
110     * JSn_COMMAND register. The method uses a lookup table to call
111     * the right command handling method.
112     *
113     * @param cmd Command number (see the Midgard architecture
114     * specification)
115     */
116    void jobCommand(uint32_t cmd);
117
118    /**
119     * Command handler for No-ops.
120     *
121     * @param cmd Command number (see the Midgard architecture
122     * specification)
123     */
124    void cmdNop(uint32_t cmd);
125    /**
126     * Command handler for job start commands.
127     *
128     * @note This should <i>NEVER</i> be called as the start command
129     * should never be written to the JSn_COMMAND register. Jobs are
130     * normally started by tryStart() whenever the state of the
131     * currently running job changes or JSn_COMMAND_START is written
132     * to the JSn_COMMAND_NEXT register.
133     *
134     * @param cmd Command number (see the Midgard architecture
135     * specification)
136     */
137    void cmdStart(uint32_t cmd);
138    /**
139     * Gently stop the currently running job chain.
140     *
141     * @param cmd Command number (see the Midgard architecture
142     * specification)
143     */
144    void cmdSoftStop(uint32_t cmd);
145    /**
146     * Force a stop of the currently running job chain.
147     *
148     * @param cmd Command number (see the Midgard architecture
149     * specification)
150     */
151    void cmdHardStop(uint32_t cmd);
152    /**
153     * Soft stop the current job chain if the JOB_CHAIN_FLAG <i>IS
154     * NOT</i> set.
155     *
156     * @param cmd Command number (see the Midgard architecture
157     * specification)
158     */
159    void cmdSoftStop0(uint32_t cmd);
160    /**
161     * Hard stop the current job chain if the JOB_CHAIN_FLAG <i>IS
162     * NOT</i> set.
163     *
164     * @param cmd Command number (see the Midgard architecture
165     * specification)
166     */
167    void cmdHardStop0(uint32_t cmd);
168    /**
169     * Soft stop the current job chain if the JOB_CHAIN_FLAG <i>IS</i>
170     * set.
171     *
172     * @param cmd Command number (see the Midgard architecture
173     * specification)
174     */
175    void cmdSoftStop1(uint32_t cmd);
176    /**
177     * Hard stop the current job chain if the JOB_CHAIN_FLAG <i>IS</i>
178     * set.
179     *
180     * @param cmd Command number (see the Midgard architecture
181     * specification)
182     */
183    void cmdHardStop1(uint32_t cmd);
184
185    /** @} */
186
187    /** Job slot ID */
188    const uint8_t id;
189
190    /** Parent JobControl block */
191    JobControl &jc;
192
193  private:
194    typedef void (JobSlot::*cmd_t)(uint32_t);
195
196    /**
197     * Mapping between command IDs and command handling methods.
198     *
199     * @note The order of this vector <i>MUST</i> correspond to the
200     * job control command IDs in the Midgard architecture
201     * specification.
202     */
203    static const std::vector<cmd_t> cmds;
204};
205
206}
207
208#endif // _LIBNOMALIMODEL_JOBSLOT_HH
209