isa.hh revision 7400
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            SCTLR sctlr_rst = miscRegs[MISCREG_SCTLR_RST];
96
97            memset(miscRegs, 0, sizeof(miscRegs));
98            CPSR cpsr = 0;
99            cpsr.mode = MODE_USER;
100            miscRegs[MISCREG_CPSR] = cpsr;
101            updateRegMap(cpsr);
102
103            SCTLR sctlr = 0;
104            sctlr.nmfi = (bool)sctlr_rst.nmfi;
105            sctlr.v = (bool)sctlr_rst.v;
106            sctlr.u    = 1;
107            sctlr.rao1 = 1;
108            sctlr.rao2 = 1;
109            sctlr.rao3 = 1;
110            sctlr.rao4 = 1;
111            miscRegs[MISCREG_SCTLR] = sctlr;
112            miscRegs[MISCREG_SCTLR_RST] = sctlr_rst;
113
114
115            /*
116             * Technically this should be 0, but we don't support those
117             * settings.
118             */
119            CPACR cpacr = 0;
120            // Enable CP 10, 11
121            cpacr.cp10 = 0x3;
122            cpacr.cp11 = 0x3;
123            miscRegs[MISCREG_CPACR] = cpacr;
124
125            /* Start with an event in the mailbox */
126            miscRegs[MISCREG_SEV_MAILBOX] = 1;
127
128            /*
129             * Implemented = '5' from "M5",
130             * Variant = 0,
131             */
132            miscRegs[MISCREG_MIDR] =
133                (0x35 << 24) | //Implementor is '5' from "M5"
134                (0 << 20)    | //Variant
135                (0xf << 16)  | //Architecture from CPUID scheme
136                (0 << 4)     | //Primary part number
137                (0 << 0)     | //Revision
138                0;
139
140            // Separate Instruction and Data TLBs.
141            miscRegs[MISCREG_TLBTR] = 1;
142
143            MVFR0 mvfr0 = 0;
144            mvfr0.advSimdRegisters = 2;
145            mvfr0.singlePrecision = 2;
146            mvfr0.doublePrecision = 2;
147            mvfr0.vfpExceptionTrapping = 0;
148            mvfr0.divide = 1;
149            mvfr0.squareRoot = 1;
150            mvfr0.shortVectors = 1;
151            mvfr0.roundingModes = 1;
152            miscRegs[MISCREG_MVFR0] = mvfr0;
153
154            MVFR1 mvfr1 = 0;
155            mvfr1.flushToZero = 1;
156            mvfr1.defaultNaN = 1;
157            mvfr1.advSimdLoadStore = 1;
158            mvfr1.advSimdInteger = 1;
159            mvfr1.advSimdSinglePrecision = 1;
160            mvfr1.advSimdHalfPrecision = 1;
161            mvfr1.vfpHalfPrecision = 1;
162            miscRegs[MISCREG_MVFR1] = mvfr1;
163
164            miscRegs[MISCREG_MPIDR] = 0;
165
166            //XXX We need to initialize the rest of the state.
167        }
168
169        MiscReg
170        readMiscRegNoEffect(int misc_reg)
171        {
172            assert(misc_reg < NumMiscRegs);
173            if (misc_reg == MISCREG_SPSR) {
174                CPSR cpsr = miscRegs[MISCREG_CPSR];
175                switch (cpsr.mode) {
176                  case MODE_USER:
177                    return miscRegs[MISCREG_SPSR];
178                  case MODE_FIQ:
179                    return miscRegs[MISCREG_SPSR_FIQ];
180                  case MODE_IRQ:
181                    return miscRegs[MISCREG_SPSR_IRQ];
182                  case MODE_SVC:
183                    return miscRegs[MISCREG_SPSR_SVC];
184                  case MODE_MON:
185                    return miscRegs[MISCREG_SPSR_MON];
186                  case MODE_ABORT:
187                    return miscRegs[MISCREG_SPSR_ABT];
188                  case MODE_UNDEFINED:
189                    return miscRegs[MISCREG_SPSR_UND];
190                  default:
191                    return miscRegs[MISCREG_SPSR];
192                }
193            }
194            return miscRegs[misc_reg];
195        }
196
197        MiscReg
198        readMiscReg(int misc_reg, ThreadContext *tc)
199        {
200            if (misc_reg == MISCREG_CPSR) {
201                CPSR cpsr = miscRegs[misc_reg];
202                Addr pc = tc->readPC();
203                if (pc & (ULL(1) << PcJBitShift))
204                    cpsr.j = 1;
205                else
206                    cpsr.j = 0;
207                if (pc & (ULL(1) << PcTBitShift))
208                    cpsr.t = 1;
209                else
210                    cpsr.t = 0;
211                return cpsr;
212            }
213            if (misc_reg >= MISCREG_CP15_UNIMP_START &&
214                misc_reg < MISCREG_CP15_END) {
215                panic("Unimplemented CP15 register %s read.\n",
216                      miscRegName[misc_reg]);
217            }
218            switch (misc_reg) {
219              case MISCREG_CLIDR:
220                warn("The clidr register always reports 0 caches.\n");
221                break;
222              case MISCREG_CCSIDR:
223                warn("The ccsidr register isn't implemented and "
224                        "always reads as 0.\n");
225                break;
226            }
227            return readMiscRegNoEffect(misc_reg);
228        }
229
230        void
231        setMiscRegNoEffect(int misc_reg, const MiscReg &val)
232        {
233            assert(misc_reg < NumMiscRegs);
234            if (misc_reg == MISCREG_SPSR) {
235                CPSR cpsr = miscRegs[MISCREG_CPSR];
236                switch (cpsr.mode) {
237                  case MODE_USER:
238                    miscRegs[MISCREG_SPSR] = val;
239                    return;
240                  case MODE_FIQ:
241                    miscRegs[MISCREG_SPSR_FIQ] = val;
242                    return;
243                  case MODE_IRQ:
244                    miscRegs[MISCREG_SPSR_IRQ] = val;
245                    return;
246                  case MODE_SVC:
247                    miscRegs[MISCREG_SPSR_SVC] = val;
248                    return;
249                  case MODE_MON:
250                    miscRegs[MISCREG_SPSR_MON] = val;
251                    return;
252                  case MODE_ABORT:
253                    miscRegs[MISCREG_SPSR_ABT] = val;
254                    return;
255                  case MODE_UNDEFINED:
256                    miscRegs[MISCREG_SPSR_UND] = val;
257                    return;
258                  default:
259                    miscRegs[MISCREG_SPSR] = val;
260                    return;
261                }
262            }
263            miscRegs[misc_reg] = val;
264        }
265
266        void
267        setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
268        {
269            MiscReg newVal = val;
270            if (misc_reg == MISCREG_CPSR) {
271                updateRegMap(val);
272                CPSR cpsr = val;
273                DPRINTF(Arm, "Updating CPSR to %#x f:%d i:%d a:%d mode:%#x\n",
274                        cpsr, cpsr.f, cpsr.i, cpsr.a, cpsr.mode);
275                Addr npc = tc->readNextPC() & ~PcModeMask;
276                if (cpsr.j)
277                    npc = npc | (ULL(1) << PcJBitShift);
278                if (cpsr.t)
279                    npc = npc | (ULL(1) << PcTBitShift);
280
281                tc->setNextPC(npc);
282            }
283            if (misc_reg >= MISCREG_CP15_UNIMP_START &&
284                misc_reg < MISCREG_CP15_END) {
285                panic("Unimplemented CP15 register %s wrote with %#x.\n",
286                      miscRegName[misc_reg], val);
287            }
288            switch (misc_reg) {
289              case MISCREG_CPACR:
290                {
291                    CPACR newCpacr = 0;
292                    CPACR valCpacr = val;
293                    newCpacr.cp10 = valCpacr.cp10;
294                    newCpacr.cp11 = valCpacr.cp11;
295                    if (newCpacr.cp10 != 0x3 || newCpacr.cp11 != 3) {
296                        panic("Disabling coprocessors isn't implemented.\n");
297                    }
298                    newVal = newCpacr;
299                }
300                break;
301              case MISCREG_CSSELR:
302                warn("The csselr register isn't implemented.\n");
303                break;
304              case MISCREG_FPSCR:
305                {
306                    const uint32_t ones = (uint32_t)(-1);
307                    FPSCR fpscrMask = 0;
308                    fpscrMask.ioc = ones;
309                    fpscrMask.dzc = ones;
310                    fpscrMask.ofc = ones;
311                    fpscrMask.ufc = ones;
312                    fpscrMask.ixc = ones;
313                    fpscrMask.idc = ones;
314                    fpscrMask.len = ones;
315                    fpscrMask.stride = ones;
316                    fpscrMask.rMode = ones;
317                    fpscrMask.fz = ones;
318                    fpscrMask.dn = ones;
319                    fpscrMask.ahp = ones;
320                    fpscrMask.qc = ones;
321                    fpscrMask.v = ones;
322                    fpscrMask.c = ones;
323                    fpscrMask.z = ones;
324                    fpscrMask.n = ones;
325                    newVal = (newVal & (uint32_t)fpscrMask) |
326                             (miscRegs[MISCREG_FPSCR] & ~(uint32_t)fpscrMask);
327                }
328                break;
329              case MISCREG_FPEXC:
330                {
331                    const uint32_t fpexcMask = 0x60000000;
332                    newVal = (newVal & fpexcMask) |
333                             (miscRegs[MISCREG_FPEXC] & ~fpexcMask);
334                }
335                break;
336              case MISCREG_SCTLR:
337                {
338                    SCTLR sctlr = miscRegs[MISCREG_SCTLR];
339                    SCTLR new_sctlr = newVal;
340                    new_sctlr.nmfi =  (bool)sctlr.nmfi;
341                    miscRegs[MISCREG_SCTLR] = (MiscReg)new_sctlr;
342                    return;
343                }
344              case MISCREG_TLBTR:
345              case MISCREG_MVFR0:
346              case MISCREG_MVFR1:
347              case MISCREG_MPIDR:
348              case MISCREG_FPSID:
349                return;
350            }
351            setMiscRegNoEffect(misc_reg, newVal);
352        }
353
354        int
355        flattenIntIndex(int reg)
356        {
357            assert(reg >= 0);
358            if (reg < NUM_ARCH_INTREGS) {
359                return intRegMap[reg];
360            } else if (reg < NUM_INTREGS) {
361                return reg;
362            } else {
363                int mode = reg / intRegsPerMode;
364                reg = reg % intRegsPerMode;
365                switch (mode) {
366                  case MODE_USER:
367                  case MODE_SYSTEM:
368                    return INTREG_USR(reg);
369                  case MODE_FIQ:
370                    return INTREG_FIQ(reg);
371                  case MODE_IRQ:
372                    return INTREG_IRQ(reg);
373                  case MODE_SVC:
374                    return INTREG_SVC(reg);
375                  case MODE_MON:
376                    return INTREG_MON(reg);
377                  case MODE_ABORT:
378                    return INTREG_ABT(reg);
379                  case MODE_UNDEFINED:
380                    return INTREG_UND(reg);
381                  default:
382                    panic("Flattening into an unknown mode.\n");
383                }
384            }
385        }
386
387        int
388        flattenFloatIndex(int reg)
389        {
390            return reg;
391        }
392
393        void serialize(EventManager *em, std::ostream &os)
394        {}
395        void unserialize(EventManager *em, Checkpoint *cp,
396                const std::string &section)
397        {}
398
399        ISA()
400        {
401            SCTLR sctlr;
402            sctlr = 0;
403            miscRegs[MISCREG_SCTLR_RST] = sctlr;
404
405            clear();
406        }
407    };
408}
409
410#endif
411