isa.hh revision 7270
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            //XXX We need to initialize the rest of the state.
110        }
111
112        MiscReg
113        readMiscRegNoEffect(int misc_reg)
114        {
115            assert(misc_reg < NumMiscRegs);
116            if (misc_reg == MISCREG_SPSR) {
117                CPSR cpsr = miscRegs[MISCREG_CPSR];
118                switch (cpsr.mode) {
119                  case MODE_USER:
120                    return miscRegs[MISCREG_SPSR];
121                  case MODE_FIQ:
122                    return miscRegs[MISCREG_SPSR_FIQ];
123                  case MODE_IRQ:
124                    return miscRegs[MISCREG_SPSR_IRQ];
125                  case MODE_SVC:
126                    return miscRegs[MISCREG_SPSR_SVC];
127                  case MODE_MON:
128                    return miscRegs[MISCREG_SPSR_MON];
129                  case MODE_ABORT:
130                    return miscRegs[MISCREG_SPSR_ABT];
131                  case MODE_UNDEFINED:
132                    return miscRegs[MISCREG_SPSR_UND];
133                  default:
134                    return miscRegs[MISCREG_SPSR];
135                }
136            }
137            return miscRegs[misc_reg];
138        }
139
140        MiscReg
141        readMiscReg(int misc_reg, ThreadContext *tc)
142        {
143            if (misc_reg == MISCREG_CPSR) {
144                CPSR cpsr = miscRegs[misc_reg];
145                Addr pc = tc->readPC();
146                if (pc & (ULL(1) << PcJBitShift))
147                    cpsr.j = 1;
148                else
149                    cpsr.j = 0;
150                if (pc & (ULL(1) << PcTBitShift))
151                    cpsr.t = 1;
152                else
153                    cpsr.t = 0;
154                return cpsr;
155            }
156            if (misc_reg >= MISCREG_CP15_UNIMP_START &&
157                misc_reg < MISCREG_CP15_END) {
158                panic("Unimplemented CP15 register %s read.\n",
159                      miscRegName[misc_reg]);
160            }
161            return readMiscRegNoEffect(misc_reg);
162        }
163
164        void
165        setMiscRegNoEffect(int misc_reg, const MiscReg &val)
166        {
167            assert(misc_reg < NumMiscRegs);
168            if (misc_reg == MISCREG_SPSR) {
169                CPSR cpsr = miscRegs[MISCREG_CPSR];
170                switch (cpsr.mode) {
171                  case MODE_USER:
172                    miscRegs[MISCREG_SPSR] = val;
173                    return;
174                  case MODE_FIQ:
175                    miscRegs[MISCREG_SPSR_FIQ] = val;
176                    return;
177                  case MODE_IRQ:
178                    miscRegs[MISCREG_SPSR_IRQ] = val;
179                    return;
180                  case MODE_SVC:
181                    miscRegs[MISCREG_SPSR_SVC] = val;
182                    return;
183                  case MODE_MON:
184                    miscRegs[MISCREG_SPSR_MON] = val;
185                    return;
186                  case MODE_ABORT:
187                    miscRegs[MISCREG_SPSR_ABT] = val;
188                    return;
189                  case MODE_UNDEFINED:
190                    miscRegs[MISCREG_SPSR_UND] = val;
191                    return;
192                  default:
193                    miscRegs[MISCREG_SPSR] = val;
194                    return;
195                }
196            }
197            miscRegs[misc_reg] = val;
198        }
199
200        void
201        setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
202        {
203            if (misc_reg == MISCREG_CPSR) {
204                updateRegMap(val);
205                CPSR cpsr = val;
206                Addr npc = tc->readNextPC() & ~PcModeMask;
207                if (cpsr.j)
208                    npc = npc | (ULL(1) << PcJBitShift);
209                if (cpsr.t)
210                    npc = npc | (ULL(1) << PcTBitShift);
211
212                tc->setNextPC(npc);
213            }
214            if (misc_reg >= MISCREG_CP15_UNIMP_START &&
215                misc_reg < MISCREG_CP15_END) {
216                panic("Unimplemented CP15 register %s wrote with %#x.\n",
217                      miscRegName[misc_reg], val);
218            }
219            return setMiscRegNoEffect(misc_reg, val);
220        }
221
222        int
223        flattenIntIndex(int reg)
224        {
225            assert(reg >= 0);
226            if (reg < NUM_ARCH_INTREGS) {
227                return intRegMap[reg];
228            } else if (reg < NUM_INTREGS) {
229                return reg;
230            } else {
231                reg -= NUM_INTREGS;
232                assert(reg < NUM_ARCH_INTREGS);
233                return reg;
234            }
235        }
236
237        int
238        flattenFloatIndex(int reg)
239        {
240            return reg;
241        }
242
243        void serialize(EventManager *em, std::ostream &os)
244        {}
245        void unserialize(EventManager *em, Checkpoint *cp,
246                const std::string &section)
247        {}
248
249        ISA()
250        {
251            clear();
252        }
253    };
254}
255
256#endif
257