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

Last change on this file since 685 was 685, checked in by cfuguet, 10 years ago

Merging trunk modifications into fault-tolerance branch

File size: 13.1 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        XTN_DEBUG_MASK         = 30,
183    };
184
185    /**
186     * Instruction request, only significant if `valid' is asserted.
187     *
188     * addr must be 4-byte aligned.
189     */
190    struct InstructionRequest {
191        bool valid;
192        addr_t addr;
193        enum ExecMode mode;
194
195        void print( std::ostream &o ) const;
196
197        friend std::ostream &operator << (std::ostream &o, const struct InstructionRequest &ir)
198        {
199            ir.print(o);
200            return o;
201        }
202
203        inline bool operator==( const struct InstructionRequest &oreq )
204        {
205            return
206                valid == oreq.valid &&
207                addr == oreq.addr &&
208                mode == oreq.mode;
209        }
210    };
211#define ISS_IREQ_INITIALIZER {false, 0, ::soclib::common::Iss2::MODE_HYPER}
212
213    /**
214     * Data request, only significant if `valid' is asserted.
215     *
216     * addr must be 4-byte aligned.
217     * wdata is only significant for be-masked bytes.
218     * wdata[7:0] is at [addr], masked by be[0]
219     * wdata[15:8] is at [addr+1], masked by be[1]
220     * wdata[23:16] is at [addr+2], masked by be[2]
221     * wdata[31:24] is at [addr+3], masked by be[3]
222     *
223     * When type is XTN_READ or XTN_WRITE, addr must be an opcod of
224     * enum ExternalAccessType.  For extended access types needing an
225     * address, address is passed through the wdata field.
226     */
227    struct DataRequest {
228        bool valid;
229        addr_t addr;
230        data_t wdata;
231        enum DataOperationType type;
232        be_t be;
233        enum ExecMode mode;
234
235        void print( std::ostream &o ) const;
236
237        friend std::ostream &operator << (std::ostream &o, const struct DataRequest &ir)
238        {
239            ir.print(o);
240            return o;
241        }
242
243        inline bool operator==( const struct DataRequest &oreq )
244        {
245            return
246                valid == oreq.valid &&
247                addr == oreq.addr &&
248                wdata == oreq.wdata &&
249                type == oreq.type &&
250                be == oreq.be &&
251                mode == oreq.mode;
252        }
253    };
254#define ISS_DREQ_INITIALIZER {false, 0, 0, ::soclib::common::Iss2::DATA_READ, 0, ::soclib::common::Iss2::MODE_HYPER}
255
256    /**
257     * Instruction response.
258     *
259     * Valid is asserted when query has beed satisfied, if no request
260     * is pending, valid is not asserted.
261     *
262     * instruction is only valid if no error is signaled.
263     */
264    struct InstructionResponse {
265        bool valid;
266        bool error;
267        data_t instruction;
268
269        void print( std::ostream &o ) const;
270
271        friend std::ostream &operator << (std::ostream &o, const struct InstructionResponse &ir)
272        {
273            ir.print(o);
274            return o;
275        }
276    };
277#define ISS_IRSP_INITIALIZER {false, false, 0}
278
279    /**
280     * Data response.
281     *
282     * Valid is asserted when query has beed satisfied, if no request
283     * is pending, valid is not asserted.
284     *
285     * data is only valid if no error is signaled.
286     *
287     * Read data is aligned with the same semantics than the wdata
288     * field in struct DataRequest. Only bytes asserted in the BE
289     * field upon request are meaningful, others have an undefined
290     * value, they may be non-zero.
291     */
292    struct DataResponse {
293        bool valid;
294        bool error;
295        data_t rdata;
296
297        void print( std::ostream &o ) const;
298
299        friend std::ostream &operator << (std::ostream &o, const struct DataResponse &ir)
300        {
301            ir.print(o);
302            return o;
303        }
304    };
305#define ISS_DRSP_INITIALIZER {false, false, 0}
306
307protected:
308
309    /**
310     * Cpu ID
311     */
312    const uint32_t m_ident;
313    /**
314     * Iss instance name
315     */
316    const std::string m_name;
317    /**
318     * debug mask
319     */
320    uint m_debug_mask;
321
322public:
323    virtual ~Iss2() {}
324
325    /**
326     * Name accessor
327     */
328    inline const std::string & name() const
329    {
330        return m_name;
331    }
332
333    Iss2( const std::string &name, uint32_t ident )
334        : m_ident(ident),
335          m_name(name)
336    {
337    }
338
339    // ISS2 <-> Wrapper API
340
341    /**
342     * Reset operation, Iss must behave like the processor receiving a reset cycle.
343     */
344    virtual void reset() = 0;
345
346    /**
347     * Tell the Iss to execute *at most* ncycle cycles, knowing the
348     * value of all the irq lines. Each irq is a bit in the
349     * irq_bit_field word.
350     *
351     * Iss must return the number of cycles it actually executed. This
352     * is at least 1, at most ncycle.
353     */
354    virtual uint32_t executeNCycles(
355        uint32_t ncycle,
356        const struct InstructionResponse &,
357        const struct DataResponse &,
358        uint32_t irq_bit_field ) = 0;
359
360    /**
361     * This function is used to translate a virtual address to
362     * physical address Return false if address not mapped.
363     */
364    virtual bool virtualToPhys(addr_t &addr) const
365    {
366        return true;
367    }
368
369    /**
370     * Iss must populate the request fields.
371     */
372    virtual void getRequests( struct InstructionRequest &,
373                              struct DataRequest & ) const = 0;
374
375    /**
376     * The cache received an imprecise write error condition, this
377     * signalling is asynchronous.
378     */
379    virtual void setWriteBerr() = 0;
380
381    struct CacheInfo
382    {
383        bool has_mmu;
384        size_t icache_line_size;
385        size_t icache_assoc;
386        size_t icache_n_lines;
387        size_t dcache_line_size;
388        size_t dcache_assoc;
389        size_t dcache_n_lines;
390    };
391
392    /**
393     * Inform the Iss about the cache
394     */
395    virtual void setCacheInfo( const struct CacheInfo &info )
396    {
397    }
398
399    /*
400     * Debugger API
401     */
402
403    /**
404     * Iss must return the count of registers known to GDB. This must
405     * follow GDB protocol for this architecture.
406     */
407    virtual unsigned int debugGetRegisterCount() const = 0;
408    /**
409     * Accessor for an Iss register, register number meaning is
410     * defined in GDB protocol for this architecture.
411     */
412    virtual debug_register_t debugGetRegisterValue(unsigned int reg) const = 0;
413    /**
414     * Accessor for an Iss register, register number meaning is
415     * defined in GDB protocol for this architecture. Special virtual
416     * register ids defined by debugSpecialRegisters enum can be used
417     * to get additionnal information on current processor state.
418     */
419    virtual void debugSetRegisterValue(unsigned int reg, debug_register_t value) = 0;
420    /**
421     * Get the size for a given register. This is defined in GDB
422     * protocol for this architecture.
423     */
424    virtual size_t debugGetRegisterSize(unsigned int reg) const = 0;
425
426    enum debugCpuEndianness {
427        ISS_LITTLE_ENDIAN,
428        ISS_BIG_ENDIAN,
429    };
430
431    enum debugSpecialRegisters {
432        /** is non-zero if processor is currently executing user code */
433        ISS_DEBUG_REG_IS_USERMODE               = 100000,
434        /** is non-zero if processor can react on irqs */
435        ISS_DEBUG_REG_IS_INTERRUPTIBLE          = 100001,
436        /** give number of bytes which can be legitimately accessed below stack pointer */
437        ISS_DEBUG_REG_STACK_REDZONE_SIZE        = 100002,
438    };
439
440    /** Dump processor state (optional) */
441    virtual void dump() const
442    {
443    }
444
445    /** set debug mask */
446    inline void set_debug_mask(uint v) {
447        m_debug_mask = v;
448    }
449
450protected:
451   
452    /**
453     * On exception condition, an Iss should call this method to let
454     * the debugger inform the monitoring entity. If return value is
455     * true, Iss must not jump to exception handler and continue with
456     * execution. This permits implementation of software breakpoints.
457     */
458    virtual bool debugExceptionBypassed( ExceptionClass cl, ExceptionCause ca  = EXCA_OTHER )
459    {
460        return false;
461    }
462
463};
464
465const char *mode_str(Iss2::ExecMode mode);
466const char *type_str(Iss2::DataOperationType type);
467const char *xtn_str(Iss2::ExternalAccessType type);
468
469}}
470
471#endif // _SOCLIB_ISS2_H_
472
473// Local Variables:
474// tab-width: 4
475// c-basic-offset: 4
476// c-file-offsets:((innamespace . 0)(inline-open . 0))
477// indent-tabs-mode: nil
478// End:
479
480// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Note: See TracBrowser for help on using the repository browser.