isa.hh revision 7383
1/*
2 * Copyright (c) 2010 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2009 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Authors: Gabe Black
41 */
42
43#ifndef __ARCH_ARM_ISA_HH__
44#define __ARCH_MRM_ISA_HH__
45
46#include "arch/arm/registers.hh"
47#include "arch/arm/types.hh"
48
49class ThreadContext;
50class Checkpoint;
51class EventManager;
52
53namespace ArmISA
54{
55    class ISA
56    {
57      protected:
58        MiscReg miscRegs[NumMiscRegs];
59        const IntRegIndex *intRegMap;
60
61        void
62        updateRegMap(CPSR cpsr)
63        {
64            switch (cpsr.mode) {
65              case MODE_USER:
66              case MODE_SYSTEM:
67                intRegMap = IntRegUsrMap;
68                break;
69              case MODE_FIQ:
70                intRegMap = IntRegFiqMap;
71                break;
72              case MODE_IRQ:
73                intRegMap = IntRegIrqMap;
74                break;
75              case MODE_SVC:
76                intRegMap = IntRegSvcMap;
77                break;
78              case MODE_MON:
79                intRegMap = IntRegMonMap;
80                break;
81              case MODE_ABORT:
82                intRegMap = IntRegAbtMap;
83                break;
84              case MODE_UNDEFINED:
85                intRegMap = IntRegUndMap;
86                break;
87              default:
88                panic("Unrecognized mode setting in CPSR.\n");
89            }
90        }
91
92      public:
93        void clear()
94        {
95            memset(miscRegs, 0, sizeof(miscRegs));
96            CPSR cpsr = 0;
97            cpsr.mode = MODE_USER;
98            miscRegs[MISCREG_CPSR] = cpsr;
99            updateRegMap(cpsr);
100
101            SCTLR sctlr = 0;
102            sctlr.nmfi = 1;
103            sctlr.rao1 = 1;
104            sctlr.rao2 = 1;
105            sctlr.rao3 = 1;
106            sctlr.rao4 = 1;
107            miscRegs[MISCREG_SCTLR] = sctlr;
108
109            /*
110             * Technically this should be 0, but we don't support those
111             * settings.
112             */
113            CPACR cpacr = 0;
114            // Enable CP 10, 11
115            cpacr.cp10 = 0x3;
116            cpacr.cp11 = 0x3;
117            miscRegs[MISCREG_CPACR] = cpacr;
118
119            /* Start with an event in the mailbox */
120            miscRegs[MISCREG_SEV_MAILBOX] = 1;
121
122            /*
123             * Implemented = '5' from "M5",
124             * Variant = 0,
125             */
126            miscRegs[MISCREG_MIDR] =
127                (0x35 << 24) | //Implementor is '5' from "M5"
128                (0 << 20)    | //Variant
129                (0xf << 16)  | //Architecture from CPUID scheme
130                (0 << 4)     | //Primary part number
131                (0 << 0)     | //Revision
132                0;
133
134            // Separate Instruction and Data TLBs.
135            miscRegs[MISCREG_TLBTR] = 1;
136
137            MVFR0 mvfr0 = 0;
138            mvfr0.advSimdRegisters = 2;
139            mvfr0.singlePrecision = 2;
140            mvfr0.doublePrecision = 2;
141            mvfr0.vfpExceptionTrapping = 0;
142            mvfr0.divide = 1;
143            mvfr0.squareRoot = 1;
144            mvfr0.shortVectors = 1;
145            mvfr0.roundingModes = 1;
146            miscRegs[MISCREG_MVFR0] = mvfr0;
147
148            MVFR1 mvfr1 = 0;
149            mvfr1.flushToZero = 1;
150            mvfr1.defaultNaN = 1;
151            mvfr1.advSimdLoadStore = 1;
152            mvfr1.advSimdInteger = 1;
153            mvfr1.advSimdSinglePrecision = 1;
154            mvfr1.advSimdHalfPrecision = 1;
155            mvfr1.vfpHalfPrecision = 1;
156            miscRegs[MISCREG_MVFR1] = mvfr1;
157
158            //XXX We need to initialize the rest of the state.
159        }
160
161        MiscReg
162        readMiscRegNoEffect(int misc_reg)
163        {
164            assert(misc_reg < NumMiscRegs);
165            if (misc_reg == MISCREG_SPSR) {
166                CPSR cpsr = miscRegs[MISCREG_CPSR];
167                switch (cpsr.mode) {
168                  case MODE_USER:
169                    return miscRegs[MISCREG_SPSR];
170                  case MODE_FIQ:
171                    return miscRegs[MISCREG_SPSR_FIQ];
172                  case MODE_IRQ:
173                    return miscRegs[MISCREG_SPSR_IRQ];
174                  case MODE_SVC:
175                    return miscRegs[MISCREG_SPSR_SVC];
176                  case MODE_MON:
177                    return miscRegs[MISCREG_SPSR_MON];
178                  case MODE_ABORT:
179                    return miscRegs[MISCREG_SPSR_ABT];
180                  case MODE_UNDEFINED:
181                    return miscRegs[MISCREG_SPSR_UND];
182                  default:
183                    return miscRegs[MISCREG_SPSR];
184                }
185            }
186            return miscRegs[misc_reg];
187        }
188
189        MiscReg
190        readMiscReg(int misc_reg, ThreadContext *tc)
191        {
192            if (misc_reg == MISCREG_CPSR) {
193                CPSR cpsr = miscRegs[misc_reg];
194                Addr pc = tc->readPC();
195                if (pc & (ULL(1) << PcJBitShift))
196                    cpsr.j = 1;
197                else
198                    cpsr.j = 0;
199                if (pc & (ULL(1) << PcTBitShift))
200                    cpsr.t = 1;
201                else
202                    cpsr.t = 0;
203                return cpsr;
204            }
205            if (misc_reg >= MISCREG_CP15_UNIMP_START &&
206                misc_reg < MISCREG_CP15_END) {
207                panic("Unimplemented CP15 register %s read.\n",
208                      miscRegName[misc_reg]);
209            }
210            switch (misc_reg) {
211              case MISCREG_CLIDR:
212                warn("The clidr register always reports 0 caches.\n");
213                break;
214              case MISCREG_CCSIDR:
215                warn("The ccsidr register isn't implemented and "
216                        "always reads as 0.\n");
217                break;
218            }
219            return readMiscRegNoEffect(misc_reg);
220        }
221
222        void
223        setMiscRegNoEffect(int misc_reg, const MiscReg &val)
224        {
225            assert(misc_reg < NumMiscRegs);
226            if (misc_reg == MISCREG_SPSR) {
227                CPSR cpsr = miscRegs[MISCREG_CPSR];
228                switch (cpsr.mode) {
229                  case MODE_USER:
230                    miscRegs[MISCREG_SPSR] = val;
231                    return;
232                  case MODE_FIQ:
233                    miscRegs[MISCREG_SPSR_FIQ] = val;
234                    return;
235                  case MODE_IRQ:
236                    miscRegs[MISCREG_SPSR_IRQ] = val;
237                    return;
238                  case MODE_SVC:
239                    miscRegs[MISCREG_SPSR_SVC] = val;
240                    return;
241                  case MODE_MON:
242                    miscRegs[MISCREG_SPSR_MON] = val;
243                    return;
244                  case MODE_ABORT:
245                    miscRegs[MISCREG_SPSR_ABT] = val;
246                    return;
247                  case MODE_UNDEFINED:
248                    miscRegs[MISCREG_SPSR_UND] = val;
249                    return;
250                  default:
251                    miscRegs[MISCREG_SPSR] = val;
252                    return;
253                }
254            }
255            miscRegs[misc_reg] = val;
256        }
257
258        void
259        setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
260        {
261            MiscReg newVal = val;
262            if (misc_reg == MISCREG_CPSR) {
263                updateRegMap(val);
264                CPSR cpsr = val;
265                DPRINTF(Arm, "Updating CPSR to %#x f:%d i:%d a:%d mode:%#x\n",
266                        cpsr, cpsr.f, cpsr.i, cpsr.a, cpsr.mode);
267                Addr npc = tc->readNextPC() & ~PcModeMask;
268                if (cpsr.j)
269                    npc = npc | (ULL(1) << PcJBitShift);
270                if (cpsr.t)
271                    npc = npc | (ULL(1) << PcTBitShift);
272
273                tc->setNextPC(npc);
274            }
275            if (misc_reg >= MISCREG_CP15_UNIMP_START &&
276                misc_reg < MISCREG_CP15_END) {
277                panic("Unimplemented CP15 register %s wrote with %#x.\n",
278                      miscRegName[misc_reg], val);
279            }
280            switch (misc_reg) {
281              case MISCREG_CPACR:
282                {
283                    CPACR newCpacr = 0;
284                    CPACR valCpacr = val;
285                    newCpacr.cp10 = valCpacr.cp10;
286                    newCpacr.cp11 = valCpacr.cp11;
287                    if (newCpacr.cp10 != 0x3 || newCpacr.cp11 != 3) {
288                        panic("Disabling coprocessors isn't implemented.\n");
289                    }
290                    newVal = newCpacr;
291                }
292                break;
293              case MISCREG_CSSELR:
294                warn("The csselr register isn't implemented.\n");
295                break;
296              case MISCREG_TLBTR:
297              case MISCREG_MVFR0:
298              case MISCREG_MVFR1:
299                return;
300            }
301            return setMiscRegNoEffect(misc_reg, newVal);
302        }
303
304        int
305        flattenIntIndex(int reg)
306        {
307            assert(reg >= 0);
308            if (reg < NUM_ARCH_INTREGS) {
309                return intRegMap[reg];
310            } else if (reg < NUM_INTREGS) {
311                return reg;
312            } else {
313                int mode = reg / intRegsPerMode;
314                reg = reg % intRegsPerMode;
315                switch (mode) {
316                  case MODE_USER:
317                  case MODE_SYSTEM:
318                    return INTREG_USR(reg);
319                  case MODE_FIQ:
320                    return INTREG_FIQ(reg);
321                  case MODE_IRQ:
322                    return INTREG_IRQ(reg);
323                  case MODE_SVC:
324                    return INTREG_SVC(reg);
325                  case MODE_MON:
326                    return INTREG_MON(reg);
327                  case MODE_ABORT:
328                    return INTREG_ABT(reg);
329                  case MODE_UNDEFINED:
330                    return INTREG_UND(reg);
331                  default:
332                    panic("Flattening into an unknown mode.\n");
333                }
334            }
335        }
336
337        int
338        flattenFloatIndex(int reg)
339        {
340            return reg;
341        }
342
343        void serialize(EventManager *em, std::ostream &os)
344        {}
345        void unserialize(EventManager *em, Checkpoint *cp,
346                const std::string &section)
347        {}
348
349        ISA()
350        {
351            clear();
352        }
353    };
354}
355
356#endif
357