isa.hh revision 7320:6aacf11f7dbf
12567SN/A/*
22567SN/A * Copyright (c) 2010 ARM Limited
32567SN/A * All rights reserved
42567SN/A *
52567SN/A * The license below extends only to copyright in the software and shall
62567SN/A * not be construed as granting a license to any other intellectual
72567SN/A * property including but not limited to intellectual property relating
82567SN/A * to a hardware implementation of the functionality of the software
92567SN/A * licensed hereunder.  You may use the software subject to the license
102567SN/A * terms below provided that you ensure that this notice is replicated
112567SN/A * unmodified and in its entirety in all distributions of the software,
122567SN/A * modified or unmodified, in source code or in binary form.
132567SN/A *
142567SN/A * Copyright (c) 2009 The Regents of The University of Michigan
152567SN/A * All rights reserved.
162567SN/A *
172567SN/A * Redistribution and use in source and binary forms, with or without
182567SN/A * modification, are permitted provided that the following conditions are
192567SN/A * met: redistributions of source code must retain the above copyright
202567SN/A * notice, this list of conditions and the following disclaimer;
212567SN/A * redistributions in binary form must reproduce the above copyright
222567SN/A * notice, this list of conditions and the following disclaimer in the
232567SN/A * documentation and/or other materials provided with the distribution;
242567SN/A * neither the name of the copyright holders nor the names of its
252567SN/A * contributors may be used to endorse or promote products derived from
262567SN/A * this software without specific prior written permission.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
292567SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
302567SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
312567SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
322567SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
332567SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
342567SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
352567SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
362567SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
372567SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
382567SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
392567SN/A *
404762Snate@binkert.org * Authors: Gabe Black
412567SN/A */
422567SN/A
432567SN/A#ifndef __ARCH_ARM_ISA_HH__
442567SN/A#define __ARCH_MRM_ISA_HH__
452567SN/A
462567SN/A#include "arch/arm/registers.hh"
474762Snate@binkert.org#include "arch/arm/types.hh"
482567SN/A
492650Ssaidi@eecs.umich.educlass ThreadContext;
502567SN/Aclass Checkpoint;
5111341Sandreas.hansson@arm.comclass EventManager;
528706Sandreas.hansson@arm.com
532567SN/Anamespace ArmISA
542567SN/A{
552567SN/A    class ISA
562567SN/A    {
5711168Sandreas.hansson@arm.com      protected:
5811168Sandreas.hansson@arm.com        MiscReg miscRegs[NumMiscRegs];
592567SN/A        const IntRegIndex *intRegMap;
602567SN/A
612567SN/A        void
622567SN/A        updateRegMap(CPSR cpsr)
632567SN/A        {
642567SN/A            switch (cpsr.mode) {
652567SN/A              case MODE_USER:
662567SN/A              case MODE_SYSTEM:
672567SN/A                intRegMap = IntRegUsrMap;
682567SN/A                break;
693745Sgblack@eecs.umich.edu              case MODE_FIQ:
703745Sgblack@eecs.umich.edu                intRegMap = IntRegFiqMap;
713745Sgblack@eecs.umich.edu                break;
723745Sgblack@eecs.umich.edu              case MODE_IRQ:
733745Sgblack@eecs.umich.edu                intRegMap = IntRegIrqMap;
743745Sgblack@eecs.umich.edu                break;
753745Sgblack@eecs.umich.edu              case MODE_SVC:
763745Sgblack@eecs.umich.edu                intRegMap = IntRegSvcMap;
773745Sgblack@eecs.umich.edu                break;
782567SN/A              case MODE_MON:
792567SN/A                intRegMap = IntRegMonMap;
802567SN/A                break;
812567SN/A              case MODE_ABORT:
822567SN/A                intRegMap = IntRegAbtMap;
832567SN/A                break;
842567SN/A              case MODE_UNDEFINED:
852567SN/A                intRegMap = IntRegUndMap;
862567SN/A                break;
873745Sgblack@eecs.umich.edu              default:
883745Sgblack@eecs.umich.edu                panic("Unrecognized mode setting in CPSR.\n");
893745Sgblack@eecs.umich.edu            }
903745Sgblack@eecs.umich.edu        }
913745Sgblack@eecs.umich.edu
923745Sgblack@eecs.umich.edu      public:
933745Sgblack@eecs.umich.edu        void clear()
943745Sgblack@eecs.umich.edu        {
953745Sgblack@eecs.umich.edu            memset(miscRegs, 0, sizeof(miscRegs));
962650Ssaidi@eecs.umich.edu            CPSR cpsr = 0;
972650Ssaidi@eecs.umich.edu            cpsr.mode = MODE_USER;
982650Ssaidi@eecs.umich.edu            miscRegs[MISCREG_CPSR] = cpsr;
992567SN/A            updateRegMap(cpsr);
1002567SN/A
1012567SN/A            SCTLR sctlr = 0;
1022567SN/A            sctlr.nmfi = 1;
1032567SN/A            sctlr.rao1 = 1;
1047741Sgblack@eecs.umich.edu            sctlr.rao2 = 1;
1057741Sgblack@eecs.umich.edu            sctlr.rao3 = 1;
1062567SN/A            sctlr.rao4 = 1;
1072567SN/A            miscRegs[MISCREG_SCTLR] = sctlr;
1082567SN/A
1092567SN/A            /*
1102567SN/A             * Technically this should be 0, but we don't support those
1112567SN/A             * settings.
1127741Sgblack@eecs.umich.edu             */
1137741Sgblack@eecs.umich.edu            CPACR cpacr = 0;
1142567SN/A            // Enable CP 10, 11
1152567SN/A            cpacr.cp10 = 0x3;
1162567SN/A            cpacr.cp11 = 0x3;
1172567SN/A            miscRegs[MISCREG_CPACR] = cpacr;
1182567SN/A
1192567SN/A            /* One region, unified map. */
1207741Sgblack@eecs.umich.edu            miscRegs[MISCREG_MPUIR] = 0x100;
1217741Sgblack@eecs.umich.edu
1222567SN/A            /*
1232567SN/A             * Implemented = '5' from "M5",
1242567SN/A             * Variant = 0,
1252567SN/A             */
12611347Sandreas.hansson@arm.com            miscRegs[MISCREG_MIDR] =
12711347Sandreas.hansson@arm.com                (0x35 << 24) | //Implementor is '5' from "M5"
1283553Sgblack@eecs.umich.edu                (0 << 20)    | //Variant
1293553Sgblack@eecs.umich.edu                (0xf << 16)  | //Architecture from CPUID scheme
1303553Sgblack@eecs.umich.edu                (0 << 4)     | //Primary part number
1313553Sgblack@eecs.umich.edu                (0 << 0)     | //Revision
1322567SN/A                0;
1332567SN/A
1342567SN/A            //XXX We need to initialize the rest of the state.
1352567SN/A        }
136
137        MiscReg
138        readMiscRegNoEffect(int misc_reg)
139        {
140            assert(misc_reg < NumMiscRegs);
141            if (misc_reg == MISCREG_SPSR) {
142                CPSR cpsr = miscRegs[MISCREG_CPSR];
143                switch (cpsr.mode) {
144                  case MODE_USER:
145                    return miscRegs[MISCREG_SPSR];
146                  case MODE_FIQ:
147                    return miscRegs[MISCREG_SPSR_FIQ];
148                  case MODE_IRQ:
149                    return miscRegs[MISCREG_SPSR_IRQ];
150                  case MODE_SVC:
151                    return miscRegs[MISCREG_SPSR_SVC];
152                  case MODE_MON:
153                    return miscRegs[MISCREG_SPSR_MON];
154                  case MODE_ABORT:
155                    return miscRegs[MISCREG_SPSR_ABT];
156                  case MODE_UNDEFINED:
157                    return miscRegs[MISCREG_SPSR_UND];
158                  default:
159                    return miscRegs[MISCREG_SPSR];
160                }
161            }
162            return miscRegs[misc_reg];
163        }
164
165        MiscReg
166        readMiscReg(int misc_reg, ThreadContext *tc)
167        {
168            if (misc_reg == MISCREG_CPSR) {
169                CPSR cpsr = miscRegs[misc_reg];
170                Addr pc = tc->readPC();
171                if (pc & (ULL(1) << PcJBitShift))
172                    cpsr.j = 1;
173                else
174                    cpsr.j = 0;
175                if (pc & (ULL(1) << PcTBitShift))
176                    cpsr.t = 1;
177                else
178                    cpsr.t = 0;
179                return cpsr;
180            }
181            if (misc_reg >= MISCREG_CP15_UNIMP_START &&
182                misc_reg < MISCREG_CP15_END) {
183                panic("Unimplemented CP15 register %s read.\n",
184                      miscRegName[misc_reg]);
185            }
186            switch (misc_reg) {
187              case MISCREG_CLIDR:
188                warn("The clidr register always reports 0 caches.\n");
189                break;
190              case MISCREG_CCSIDR:
191                warn("The ccsidr register isn't implemented and "
192                        "always reads as 0.\n");
193                break;
194            }
195            return readMiscRegNoEffect(misc_reg);
196        }
197
198        void
199        setMiscRegNoEffect(int misc_reg, const MiscReg &val)
200        {
201            assert(misc_reg < NumMiscRegs);
202            if (misc_reg == MISCREG_SPSR) {
203                CPSR cpsr = miscRegs[MISCREG_CPSR];
204                switch (cpsr.mode) {
205                  case MODE_USER:
206                    miscRegs[MISCREG_SPSR] = val;
207                    return;
208                  case MODE_FIQ:
209                    miscRegs[MISCREG_SPSR_FIQ] = val;
210                    return;
211                  case MODE_IRQ:
212                    miscRegs[MISCREG_SPSR_IRQ] = val;
213                    return;
214                  case MODE_SVC:
215                    miscRegs[MISCREG_SPSR_SVC] = val;
216                    return;
217                  case MODE_MON:
218                    miscRegs[MISCREG_SPSR_MON] = val;
219                    return;
220                  case MODE_ABORT:
221                    miscRegs[MISCREG_SPSR_ABT] = val;
222                    return;
223                  case MODE_UNDEFINED:
224                    miscRegs[MISCREG_SPSR_UND] = val;
225                    return;
226                  default:
227                    miscRegs[MISCREG_SPSR] = val;
228                    return;
229                }
230            }
231            miscRegs[misc_reg] = val;
232        }
233
234        void
235        setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
236        {
237            MiscReg newVal = val;
238            if (misc_reg == MISCREG_CPSR) {
239                updateRegMap(val);
240                CPSR cpsr = val;
241                Addr npc = tc->readNextPC() & ~PcModeMask;
242                if (cpsr.j)
243                    npc = npc | (ULL(1) << PcJBitShift);
244                if (cpsr.t)
245                    npc = npc | (ULL(1) << PcTBitShift);
246
247                tc->setNextPC(npc);
248            }
249            if (misc_reg >= MISCREG_CP15_UNIMP_START &&
250                misc_reg < MISCREG_CP15_END) {
251                panic("Unimplemented CP15 register %s wrote with %#x.\n",
252                      miscRegName[misc_reg], val);
253            }
254            switch (misc_reg) {
255              case MISCREG_CPACR:
256                {
257                    CPACR newCpacr = 0;
258                    CPACR valCpacr = val;
259                    newCpacr.cp10 = valCpacr.cp10;
260                    newCpacr.cp11 = valCpacr.cp11;
261                    if (newCpacr.cp10 != 0x3 || newCpacr.cp11 != 3) {
262                        panic("Disabling coprocessors isn't implemented.\n");
263                    }
264                    newVal = newCpacr;
265                }
266                break;
267              case MISCREG_CSSELR:
268                warn("The csselr register isn't implemented.\n");
269                break;
270            }
271            return setMiscRegNoEffect(misc_reg, newVal);
272        }
273
274        int
275        flattenIntIndex(int reg)
276        {
277            assert(reg >= 0);
278            if (reg < NUM_ARCH_INTREGS) {
279                return intRegMap[reg];
280            } else if (reg < NUM_INTREGS) {
281                return reg;
282            } else {
283                int mode = reg / intRegsPerMode;
284                reg = reg % intRegsPerMode;
285                switch (mode) {
286                  case MODE_USER:
287                  case MODE_SYSTEM:
288                    return INTREG_USR(reg);
289                  case MODE_FIQ:
290                    return INTREG_FIQ(reg);
291                  case MODE_IRQ:
292                    return INTREG_IRQ(reg);
293                  case MODE_SVC:
294                    return INTREG_SVC(reg);
295                  case MODE_MON:
296                    return INTREG_MON(reg);
297                  case MODE_ABORT:
298                    return INTREG_ABT(reg);
299                  case MODE_UNDEFINED:
300                    return INTREG_UND(reg);
301                  default:
302                    panic("Flattening into an unknown mode.\n");
303                }
304            }
305        }
306
307        int
308        flattenFloatIndex(int reg)
309        {
310            return reg;
311        }
312
313        void serialize(EventManager *em, std::ostream &os)
314        {}
315        void unserialize(EventManager *em, Checkpoint *cp,
316                const std::string &section)
317        {}
318
319        ISA()
320        {
321            clear();
322        }
323    };
324}
325
326#endif
327