isa.hh revision 7350
14158Sgblack@eecs.umich.edu/*
24158Sgblack@eecs.umich.edu * Copyright (c) 2010 ARM Limited
34158Sgblack@eecs.umich.edu * All rights reserved
44158Sgblack@eecs.umich.edu *
54158Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall
64158Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual
74158Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating
84158Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software
94158Sgblack@eecs.umich.edu * licensed hereunder.  You may use the software subject to the license
104158Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated
114158Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software,
124158Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form.
134158Sgblack@eecs.umich.edu *
144158Sgblack@eecs.umich.edu * Copyright (c) 2009 The Regents of The University of Michigan
154158Sgblack@eecs.umich.edu * All rights reserved.
164158Sgblack@eecs.umich.edu *
174158Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
184158Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
194158Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
204158Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
214158Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
224158Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
234158Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
244158Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
254158Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
264158Sgblack@eecs.umich.edu * this software without specific prior written permission.
274158Sgblack@eecs.umich.edu *
284158Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
294158Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
304158Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
314158Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
324158Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
334158Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
344158Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
354158Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
364158Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
374158Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
384158Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
394158Sgblack@eecs.umich.edu *
404158Sgblack@eecs.umich.edu * Authors: Gabe Black
414158Sgblack@eecs.umich.edu */
424158Sgblack@eecs.umich.edu
434158Sgblack@eecs.umich.edu#ifndef __ARCH_ARM_ISA_HH__
444158Sgblack@eecs.umich.edu#define __ARCH_MRM_ISA_HH__
454158Sgblack@eecs.umich.edu
464158Sgblack@eecs.umich.edu#include "arch/arm/registers.hh"
474158Sgblack@eecs.umich.edu#include "arch/arm/types.hh"
484158Sgblack@eecs.umich.edu
494158Sgblack@eecs.umich.educlass ThreadContext;
504158Sgblack@eecs.umich.educlass Checkpoint;
514158Sgblack@eecs.umich.educlass EventManager;
524158Sgblack@eecs.umich.edu
534158Sgblack@eecs.umich.edunamespace ArmISA
544158Sgblack@eecs.umich.edu{
554158Sgblack@eecs.umich.edu    class ISA
564158Sgblack@eecs.umich.edu    {
574158Sgblack@eecs.umich.edu      protected:
584158Sgblack@eecs.umich.edu        MiscReg miscRegs[NumMiscRegs];
594158Sgblack@eecs.umich.edu        const IntRegIndex *intRegMap;
604158Sgblack@eecs.umich.edu
614158Sgblack@eecs.umich.edu        void
624158Sgblack@eecs.umich.edu        updateRegMap(CPSR cpsr)
634158Sgblack@eecs.umich.edu        {
644158Sgblack@eecs.umich.edu            switch (cpsr.mode) {
654158Sgblack@eecs.umich.edu              case MODE_USER:
664158Sgblack@eecs.umich.edu              case MODE_SYSTEM:
674158Sgblack@eecs.umich.edu                intRegMap = IntRegUsrMap;
684158Sgblack@eecs.umich.edu                break;
694158Sgblack@eecs.umich.edu              case MODE_FIQ:
704158Sgblack@eecs.umich.edu                intRegMap = IntRegFiqMap;
714158Sgblack@eecs.umich.edu                break;
724158Sgblack@eecs.umich.edu              case MODE_IRQ:
734158Sgblack@eecs.umich.edu                intRegMap = IntRegIrqMap;
744158Sgblack@eecs.umich.edu                break;
754158Sgblack@eecs.umich.edu              case MODE_SVC:
764158Sgblack@eecs.umich.edu                intRegMap = IntRegSvcMap;
774158Sgblack@eecs.umich.edu                break;
784158Sgblack@eecs.umich.edu              case MODE_MON:
794158Sgblack@eecs.umich.edu                intRegMap = IntRegMonMap;
804158Sgblack@eecs.umich.edu                break;
814158Sgblack@eecs.umich.edu              case MODE_ABORT:
824158Sgblack@eecs.umich.edu                intRegMap = IntRegAbtMap;
834158Sgblack@eecs.umich.edu                break;
844158Sgblack@eecs.umich.edu              case MODE_UNDEFINED:
854158Sgblack@eecs.umich.edu                intRegMap = IntRegUndMap;
864158Sgblack@eecs.umich.edu                break;
874158Sgblack@eecs.umich.edu              default:
884158Sgblack@eecs.umich.edu                panic("Unrecognized mode setting in CPSR.\n");
894158Sgblack@eecs.umich.edu            }
904158Sgblack@eecs.umich.edu        }
914158Sgblack@eecs.umich.edu
924158Sgblack@eecs.umich.edu      public:
934158Sgblack@eecs.umich.edu        void clear()
944158Sgblack@eecs.umich.edu        {
954158Sgblack@eecs.umich.edu            memset(miscRegs, 0, sizeof(miscRegs));
964158Sgblack@eecs.umich.edu            CPSR cpsr = 0;
974158Sgblack@eecs.umich.edu            cpsr.mode = MODE_USER;
984816Sgblack@eecs.umich.edu            miscRegs[MISCREG_CPSR] = cpsr;
994816Sgblack@eecs.umich.edu            updateRegMap(cpsr);
1004816Sgblack@eecs.umich.edu
1014816Sgblack@eecs.umich.edu            SCTLR sctlr = 0;
1024816Sgblack@eecs.umich.edu            sctlr.nmfi = 1;
1034816Sgblack@eecs.umich.edu            sctlr.rao1 = 1;
1044805Sgblack@eecs.umich.edu            sctlr.rao2 = 1;
1055026Sgblack@eecs.umich.edu            sctlr.rao3 = 1;
1065026Sgblack@eecs.umich.edu            sctlr.rao4 = 1;
1075026Sgblack@eecs.umich.edu            miscRegs[MISCREG_SCTLR] = sctlr;
1085026Sgblack@eecs.umich.edu
1095026Sgblack@eecs.umich.edu            /*
1105026Sgblack@eecs.umich.edu             * Technically this should be 0, but we don't support those
1115026Sgblack@eecs.umich.edu             * settings.
1125026Sgblack@eecs.umich.edu             */
1135026Sgblack@eecs.umich.edu            CPACR cpacr = 0;
1144587Sgblack@eecs.umich.edu            // Enable CP 10, 11
1154158Sgblack@eecs.umich.edu            cpacr.cp10 = 0x3;
116            cpacr.cp11 = 0x3;
117            miscRegs[MISCREG_CPACR] = cpacr;
118
119            /* One region, unified map. */
120            miscRegs[MISCREG_MPUIR] = 0x100;
121
122            /* Start with an event in the mailbox */
123            miscRegs[MISCREG_SEV_MAILBOX] = 1;
124
125            /*
126             * Implemented = '5' from "M5",
127             * Variant = 0,
128             */
129            miscRegs[MISCREG_MIDR] =
130                (0x35 << 24) | //Implementor is '5' from "M5"
131                (0 << 20)    | //Variant
132                (0xf << 16)  | //Architecture from CPUID scheme
133                (0 << 4)     | //Primary part number
134                (0 << 0)     | //Revision
135                0;
136
137            //XXX We need to initialize the rest of the state.
138        }
139
140        MiscReg
141        readMiscRegNoEffect(int misc_reg)
142        {
143            assert(misc_reg < NumMiscRegs);
144            if (misc_reg == MISCREG_SPSR) {
145                CPSR cpsr = miscRegs[MISCREG_CPSR];
146                switch (cpsr.mode) {
147                  case MODE_USER:
148                    return miscRegs[MISCREG_SPSR];
149                  case MODE_FIQ:
150                    return miscRegs[MISCREG_SPSR_FIQ];
151                  case MODE_IRQ:
152                    return miscRegs[MISCREG_SPSR_IRQ];
153                  case MODE_SVC:
154                    return miscRegs[MISCREG_SPSR_SVC];
155                  case MODE_MON:
156                    return miscRegs[MISCREG_SPSR_MON];
157                  case MODE_ABORT:
158                    return miscRegs[MISCREG_SPSR_ABT];
159                  case MODE_UNDEFINED:
160                    return miscRegs[MISCREG_SPSR_UND];
161                  default:
162                    return miscRegs[MISCREG_SPSR];
163                }
164            }
165            return miscRegs[misc_reg];
166        }
167
168        MiscReg
169        readMiscReg(int misc_reg, ThreadContext *tc)
170        {
171            if (misc_reg == MISCREG_CPSR) {
172                CPSR cpsr = miscRegs[misc_reg];
173                Addr pc = tc->readPC();
174                if (pc & (ULL(1) << PcJBitShift))
175                    cpsr.j = 1;
176                else
177                    cpsr.j = 0;
178                if (pc & (ULL(1) << PcTBitShift))
179                    cpsr.t = 1;
180                else
181                    cpsr.t = 0;
182                return cpsr;
183            }
184            if (misc_reg >= MISCREG_CP15_UNIMP_START &&
185                misc_reg < MISCREG_CP15_END) {
186                panic("Unimplemented CP15 register %s read.\n",
187                      miscRegName[misc_reg]);
188            }
189            switch (misc_reg) {
190              case MISCREG_CLIDR:
191                warn("The clidr register always reports 0 caches.\n");
192                break;
193              case MISCREG_CCSIDR:
194                warn("The ccsidr register isn't implemented and "
195                        "always reads as 0.\n");
196                break;
197            }
198            return readMiscRegNoEffect(misc_reg);
199        }
200
201        void
202        setMiscRegNoEffect(int misc_reg, const MiscReg &val)
203        {
204            assert(misc_reg < NumMiscRegs);
205            if (misc_reg == MISCREG_SPSR) {
206                CPSR cpsr = miscRegs[MISCREG_CPSR];
207                switch (cpsr.mode) {
208                  case MODE_USER:
209                    miscRegs[MISCREG_SPSR] = val;
210                    return;
211                  case MODE_FIQ:
212                    miscRegs[MISCREG_SPSR_FIQ] = val;
213                    return;
214                  case MODE_IRQ:
215                    miscRegs[MISCREG_SPSR_IRQ] = val;
216                    return;
217                  case MODE_SVC:
218                    miscRegs[MISCREG_SPSR_SVC] = val;
219                    return;
220                  case MODE_MON:
221                    miscRegs[MISCREG_SPSR_MON] = val;
222                    return;
223                  case MODE_ABORT:
224                    miscRegs[MISCREG_SPSR_ABT] = val;
225                    return;
226                  case MODE_UNDEFINED:
227                    miscRegs[MISCREG_SPSR_UND] = val;
228                    return;
229                  default:
230                    miscRegs[MISCREG_SPSR] = val;
231                    return;
232                }
233            }
234            miscRegs[misc_reg] = val;
235        }
236
237        void
238        setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
239        {
240            MiscReg newVal = val;
241            if (misc_reg == MISCREG_CPSR) {
242                updateRegMap(val);
243                CPSR cpsr = val;
244                DPRINTF(Arm, "Updating CPSR to %#x f:%d i:%d a:%d mode:%#x\n",
245                        cpsr, cpsr.f, cpsr.i, cpsr.a, cpsr.mode);
246                Addr npc = tc->readNextPC() & ~PcModeMask;
247                if (cpsr.j)
248                    npc = npc | (ULL(1) << PcJBitShift);
249                if (cpsr.t)
250                    npc = npc | (ULL(1) << PcTBitShift);
251
252                tc->setNextPC(npc);
253            }
254            if (misc_reg >= MISCREG_CP15_UNIMP_START &&
255                misc_reg < MISCREG_CP15_END) {
256                panic("Unimplemented CP15 register %s wrote with %#x.\n",
257                      miscRegName[misc_reg], val);
258            }
259            switch (misc_reg) {
260              case MISCREG_CPACR:
261                {
262                    CPACR newCpacr = 0;
263                    CPACR valCpacr = val;
264                    newCpacr.cp10 = valCpacr.cp10;
265                    newCpacr.cp11 = valCpacr.cp11;
266                    if (newCpacr.cp10 != 0x3 || newCpacr.cp11 != 3) {
267                        panic("Disabling coprocessors isn't implemented.\n");
268                    }
269                    newVal = newCpacr;
270                }
271                break;
272              case MISCREG_CSSELR:
273                warn("The csselr register isn't implemented.\n");
274                break;
275            }
276            return setMiscRegNoEffect(misc_reg, newVal);
277        }
278
279        int
280        flattenIntIndex(int reg)
281        {
282            assert(reg >= 0);
283            if (reg < NUM_ARCH_INTREGS) {
284                return intRegMap[reg];
285            } else if (reg < NUM_INTREGS) {
286                return reg;
287            } else {
288                int mode = reg / intRegsPerMode;
289                reg = reg % intRegsPerMode;
290                switch (mode) {
291                  case MODE_USER:
292                  case MODE_SYSTEM:
293                    return INTREG_USR(reg);
294                  case MODE_FIQ:
295                    return INTREG_FIQ(reg);
296                  case MODE_IRQ:
297                    return INTREG_IRQ(reg);
298                  case MODE_SVC:
299                    return INTREG_SVC(reg);
300                  case MODE_MON:
301                    return INTREG_MON(reg);
302                  case MODE_ABORT:
303                    return INTREG_ABT(reg);
304                  case MODE_UNDEFINED:
305                    return INTREG_UND(reg);
306                  default:
307                    panic("Flattening into an unknown mode.\n");
308                }
309            }
310        }
311
312        int
313        flattenFloatIndex(int reg)
314        {
315            return reg;
316        }
317
318        void serialize(EventManager *em, std::ostream &os)
319        {}
320        void unserialize(EventManager *em, Checkpoint *cp,
321                const std::string &section)
322        {}
323
324        ISA()
325        {
326            clear();
327        }
328    };
329}
330
331#endif
332