source: branches/fault_tolerance/lib/iss2/include/iss2.h @ 673

Last change on this file since 673 was 657, checked in by cfuguet, 11 years ago

TSAR FAULT TOLERANCE BRANCH

  • Introducing ISS containing the XTN_INST_PADDR_EXT CP2 index.
File size: 13.0 KB
Line 
1/* -*- c++ -*-
2 *
3 * SOCLIB_LGPL_HEADER_BEGIN
4 *
5 * This file is part of SoCLib, GNU LGPLv2.1.
6 *
7 * SoCLib is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; version 2.1 of the License.
10 *
11 * SoCLib is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with SoCLib; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 * SOCLIB_LGPL_HEADER_END
22 *
23 * Copyright (c) UPMC, Lip6
24 *         Nicolas Pouillon <nipo@ssji.net>, 2008
25 *         Alain Greiner <alain.greiner@lip6.fr>, 2008
26 *
27 * Maintainers: nipo
28 *
29 * $Id$
30 *
31 * History:
32 * - 2008-07-09
33 *   Nicolas Pouillon, Alain Greiner: Forking ISS API to an improved
34 *   one with:
35 *  - Sync / prefetch / flush / ... opcods
36 *  - Mode (user/kernel/hyperviser)
37 *  - Byte enable (unaligned memory access)
38 *  - Virtual cache control
39 *
40 * - 2007-06-15
41 *   Nicolas Pouillon, Alain Greiner: Model created
42 */
43#ifndef _SOCLIB_ISS2_H_
44#define _SOCLIB_ISS2_H_
45
46#include <inttypes.h>
47#include <signal.h>
48#include <iostream>
49
50namespace soclib { namespace common {
51
52/**
53 * Iss2 API abstract class
54 *
55 * This Iss aims to define a common simulation behaviour for any
56 * 32-bit simple-issue processor.
57 *
58 * Iss conforming to this API may be used by:
59 *  - Tlmt cache wrappers
60 *  - Caba cache wrappers
61 *  - Caba Iss wrappers (with cache access through signals)
62 *
63 * Cache wrappers at least include:
64 *  - XCacheWrapper (Simple I/D cache)
65 *  - ccXCacheWrapper (coherent I/D cache)
66 *  - VCacheWrapper (MMU-enabled I/D cache)
67 *
68 * Some instrumentation classes also implement this API and may be
69 * used between the Iss and the wrapper, including:
70 *  - GdbServer
71 *  - IssProfiler
72 *
73 * You may want to use first-generation Iss instanciating them through
74 * an IssIss2 wrapper. See soclib/lib/ississ2.
75 */
76
77class Iss2
78{
79public:
80    /** Address type from/to the Iss */
81    typedef uint32_t addr_t;
82    /** Debug register from/to the Iss */
83    typedef uint32_t debug_register_t;
84    /** Byte enable field from the Iss for data access
85     *
86     * The lower endian bit in the BE field targets the lower address
87     * byte in word.
88     *
89     * You could consider this API as Little-endian.
90     */
91    typedef uint8_t be_t;
92    /**
93     * Data type from/to the Iss
94     *
95     * The lower significant byte in data word is at the lower
96     * address.
97     *
98     * You could consider this API as Little-endian.
99     */
100    typedef uint32_t data_t;
101
102    /**
103     * Execution mode for any Instruction/Data access, checked by
104     * mode-enabled caches */
105    enum ExecMode {
106        MODE_HYPER,
107        MODE_KERNEL,
108        MODE_USER,
109    };
110
111    /** Operation type on Data cache access */
112    enum DataOperationType {
113        DATA_READ,
114        DATA_WRITE,
115        DATA_LL,
116        DATA_SC,
117        XTN_WRITE,
118        XTN_READ,
119    };
120
121    /** Exception classes, keep it simple with 4 entries ! */
122    enum ExceptionClass {
123        EXCL_FAULT,
124        EXCL_IRQ,
125        EXCL_SYSCALL,
126        EXCL_TRAP,
127    };
128
129    /** Exception cause details, expand as needed and update EXCEPTIONCAUSE_STRINGS too */
130    enum ExceptionCause {
131        EXCA_OTHER,
132        EXCA_BADADDR,
133        EXCA_ALIGN,             // non aligned access not handled
134        EXCA_PAGEFAULT,
135        EXCA_ILL,               // illegal instruction
136        EXCA_FPU,
137        EXCA_REGWINDOW,
138        EXCA_DIVBYZERO
139    };
140
141#define EXCEPTIONCAUSE_STRINGS "unknown cause", "bad address", "bad alignment", \
142        "page fault", "illegal instruction", "fpu exception", "register window", \
143        "division by zero"
144
145    enum {
146        SC_ATOMIC = 0,
147        SC_NOT_ATOMIC = 1,
148    };
149
150    /**
151     * When operation is XTN_READ or XTN_WRITE, address field must be
152     * one of these values, it determines the extended access type.
153     */
154    enum ExternalAccessType {
155        XTN_PTPR               = 0,
156        XTN_TLB_MODE           = 1,
157        XTN_ICACHE_FLUSH       = 2,
158        XTN_DCACHE_FLUSH       = 3,
159        XTN_ITLB_INVAL         = 4,
160        XTN_DTLB_INVAL         = 5,
161        XTN_ICACHE_INVAL       = 6,
162        XTN_DCACHE_INVAL       = 7,
163        XTN_ICACHE_PREFETCH    = 8,
164        XTN_DCACHE_PREFETCH    = 9,
165        XTN_SYNC               = 10,
166        XTN_INS_ERROR_TYPE     = 11,
167        XTN_DATA_ERROR_TYPE    = 12,
168        XTN_INS_BAD_VADDR      = 13,
169        XTN_DATA_BAD_VADDR     = 14,
170        XTN_MMU_PARAMS         = 15,
171        XTN_MMU_RELEASE        = 16,
172        XTN_MMU_WORD_LO        = 17,
173        XTN_MMU_WORD_HI        = 18,
174        XTN_MMU_ICACHE_PA_INV  = 19,
175        XTN_MMU_DCACHE_PA_INV  = 20,
176        XTN_MMU_LL_RESET       = 21,
177        XTN_MMU_DOUBLE_LL      = 22,
178        XTN_MMU_DOUBLE_SC      = 23,
179        XTN_DATA_PADDR_EXT     = 24,
180        XTN_INST_PADDR_EXT     = 25,
181    };
182
183    /**
184     * Instruction request, only significant if `valid' is asserted.
185     *
186     * addr must be 4-byte aligned.
187     */
188    struct InstructionRequest {
189        bool valid;
190        addr_t addr;
191        enum ExecMode mode;
192
193        void print( std::ostream &o ) const;
194
195        friend std::ostream &operator << (std::ostream &o, const struct InstructionRequest &ir)
196        {
197            ir.print(o);
198            return o;
199        }
200
201        inline bool operator==( const struct InstructionRequest &oreq )
202        {
203            return
204                valid == oreq.valid &&
205                addr == oreq.addr &&
206                mode == oreq.mode;
207        }
208    };
209#define ISS_IREQ_INITIALIZER {false, 0, ::soclib::common::Iss2::MODE_HYPER}
210
211    /**
212     * Data request, only significant if `valid' is asserted.
213     *
214     * addr must be 4-byte aligned.
215     * wdata is only significant for be-masked bytes.
216     * wdata[7:0] is at [addr], masked by be[0]
217     * wdata[15:8] is at [addr+1], masked by be[1]
218     * wdata[23:16] is at [addr+2], masked by be[2]
219     * wdata[31:24] is at [addr+3], masked by be[3]
220     *
221     * When type is XTN_READ or XTN_WRITE, addr must be an opcod of
222     * enum ExternalAccessType.  For extended access types needing an
223     * address, address is passed through the wdata field.
224     */
225    struct DataRequest {
226        bool valid;
227        addr_t addr;
228        data_t wdata;
229        enum DataOperationType type;
230        be_t be;
231        enum ExecMode mode;
232
233        void print( std::ostream &o ) const;
234
235        friend std::ostream &operator << (std::ostream &o, const struct DataRequest &ir)
236        {
237            ir.print(o);
238            return o;
239        }
240
241        inline bool operator==( const struct DataRequest &oreq )
242        {
243            return
244                valid == oreq.valid &&
245                addr == oreq.addr &&
246                wdata == oreq.wdata &&
247                type == oreq.type &&
248                be == oreq.be &&
249                mode == oreq.mode;
250        }
251    };
252#define ISS_DREQ_INITIALIZER {false, 0, 0, ::soclib::common::Iss2::DATA_READ, 0, ::soclib::common::Iss2::MODE_HYPER}
253
254    /**
255     * Instruction response.
256     *
257     * Valid is asserted when query has beed satisfied, if no request
258     * is pending, valid is not asserted.
259     *
260     * instruction is only valid if no error is signaled.
261     */
262    struct InstructionResponse {
263        bool valid;
264        bool error;
265        data_t instruction;
266
267        void print( std::ostream &o ) const;
268
269        friend std::ostream &operator << (std::ostream &o, const struct InstructionResponse &ir)
270        {
271            ir.print(o);
272            return o;
273        }
274    };
275#define ISS_IRSP_INITIALIZER {false, false, 0}
276
277    /**
278     * Data response.
279     *
280     * Valid is asserted when query has beed satisfied, if no request
281     * is pending, valid is not asserted.
282     *
283     * data is only valid if no error is signaled.
284     *
285     * Read data is aligned with the same semantics than the wdata
286     * field in struct DataRequest. Only bytes asserted in the BE
287     * field upon request are meaningful, others have an undefined
288     * value, they may be non-zero.
289     */
290    struct DataResponse {
291        bool valid;
292        bool error;
293        data_t rdata;
294
295        void print( std::ostream &o ) const;
296
297        friend std::ostream &operator << (std::ostream &o, const struct DataResponse &ir)
298        {
299            ir.print(o);
300            return o;
301        }
302    };
303#define ISS_DRSP_INITIALIZER {false, false, 0}
304
305protected:
306
307    /**
308     * Cpu ID
309     */
310    const uint32_t m_ident;
311    /**
312     * Iss instance name
313     */
314    const std::string m_name;
315    /**
316     * debug mask
317     */
318    uint m_debug_mask;
319
320public:
321    virtual ~Iss2() {}
322
323    /**
324     * Name accessor
325     */
326    inline const std::string & name() const
327    {
328        return m_name;
329    }
330
331    Iss2( const std::string &name, uint32_t ident )
332        : m_ident(ident),
333          m_name(name)
334    {
335    }
336
337    // ISS2 <-> Wrapper API
338
339    /**
340     * Reset operation, Iss must behave like the processor receiving a reset cycle.
341     */
342    virtual void reset() = 0;
343
344    /**
345     * Tell the Iss to execute *at most* ncycle cycles, knowing the
346     * value of all the irq lines. Each irq is a bit in the
347     * irq_bit_field word.
348     *
349     * Iss must return the number of cycles it actually executed. This
350     * is at least 1, at most ncycle.
351     */
352    virtual uint32_t executeNCycles(
353        uint32_t ncycle,
354        const struct InstructionResponse &,
355        const struct DataResponse &,
356        uint32_t irq_bit_field ) = 0;
357
358    /**
359     * This function is used to translate a virtual address to
360     * physical address Return false if address not mapped.
361     */
362    virtual bool virtualToPhys(addr_t &addr) const
363    {
364        return true;
365    }
366
367    /**
368     * Iss must populate the request fields.
369     */
370    virtual void getRequests( struct InstructionRequest &,
371                              struct DataRequest & ) const = 0;
372
373    /**
374     * The cache received an imprecise write error condition, this
375     * signalling is asynchronous.
376     */
377    virtual void setWriteBerr() = 0;
378
379    struct CacheInfo
380    {
381        bool has_mmu;
382        size_t icache_line_size;
383        size_t icache_assoc;
384        size_t icache_n_lines;
385        size_t dcache_line_size;
386        size_t dcache_assoc;
387        size_t dcache_n_lines;
388    };
389
390    /**
391     * Inform the Iss about the cache
392     */
393    virtual void setCacheInfo( const struct CacheInfo &info )
394    {
395    }
396
397    /*
398     * Debugger API
399     */
400
401    /**
402     * Iss must return the count of registers known to GDB. This must
403     * follow GDB protocol for this architecture.
404     */
405    virtual unsigned int debugGetRegisterCount() const = 0;
406    /**
407     * Accessor for an Iss register, register number meaning is
408     * defined in GDB protocol for this architecture.
409     */
410    virtual debug_register_t debugGetRegisterValue(unsigned int reg) const = 0;
411    /**
412     * Accessor for an Iss register, register number meaning is
413     * defined in GDB protocol for this architecture. Special virtual
414     * register ids defined by debugSpecialRegisters enum can be used
415     * to get additionnal information on current processor state.
416     */
417    virtual void debugSetRegisterValue(unsigned int reg, debug_register_t value) = 0;
418    /**
419     * Get the size for a given register. This is defined in GDB
420     * protocol for this architecture.
421     */
422    virtual size_t debugGetRegisterSize(unsigned int reg) const = 0;
423
424    enum debugCpuEndianness {
425        ISS_LITTLE_ENDIAN,
426        ISS_BIG_ENDIAN,
427    };
428
429    enum debugSpecialRegisters {
430        /** is non-zero if processor is currently executing user code */
431        ISS_DEBUG_REG_IS_USERMODE               = 100000,
432        /** is non-zero if processor can react on irqs */
433        ISS_DEBUG_REG_IS_INTERRUPTIBLE          = 100001,
434        /** give number of bytes which can be legitimately accessed below stack pointer */
435        ISS_DEBUG_REG_STACK_REDZONE_SIZE        = 100002,
436    };
437
438    /** Dump processor state (optional) */
439    virtual void dump() const
440    {
441    }
442
443    /** set debug mask */
444    inline void set_debug_mask(uint v) {
445        m_debug_mask = v;
446    }
447
448protected:
449   
450    /**
451     * On exception condition, an Iss should call this method to let
452     * the debugger inform the monitoring entity. If return value is
453     * true, Iss must not jump to exception handler and continue with
454     * execution. This permits implementation of software breakpoints.
455     */
456    virtual bool debugExceptionBypassed( ExceptionClass cl, ExceptionCause ca  = EXCA_OTHER )
457    {
458        return false;
459    }
460
461};
462
463const char *mode_str(Iss2::ExecMode mode);
464const char *type_str(Iss2::DataOperationType type);
465const char *xtn_str(Iss2::ExternalAccessType type);
466
467}}
468
469#endif // _SOCLIB_ISS2_H_
470
471// Local Variables:
472// tab-width: 4
473// c-basic-offset: 4
474// c-file-offsets:((innamespace . 0)(inline-open . 0))
475// indent-tabs-mode: nil
476// End:
477
478// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Note: See TracBrowser for help on using the repository browser.