cp0.hh 4.6 KB
Newer Older
Benoit Perrot's avatar
Benoit Perrot committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//
// This file is part of Mipsy, a tiny MIPS simulator
// Copyright (C) 2003, 2004 Benoit Perrot <benoit@lrde.epita.fr>
//
// Mipsy is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// Mipsy is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
/** \file vm/cp0.hh
    \brief Declare Coprocessor 0 class. */
#ifndef VM_CP0_HH
# define VM_CP0_HH

# include "inst/register.hh"

namespace vm
{

  /// Coprocessor 0 (control coprocessor) abstraction
  class Cp0
  {
    typedef uint32_t	register_type;

  public:
    /// Coprocessor 0 registers indices
    enum kind_type
      {
	index = 0,		///< Index register
	random = 1,		///< Random register
	entry_lo0 = 2,		///< Entry for even pages
	entry_lo1 = 3,		///< Entry for odd pages
	context = 4,		///< Context register
	page_mask = 5,		///< Page mask register
	wired = 6,		///< Wired register
	error = 7,		///< Status/control register
	bad_vaddr = 8,		///< Bad virtual address register
	count = 9,		///< Count register
	entry_hi = 10,		///< Entry high
	compare = 11,		///< Compare register
	status = 12,		///< Status (kernel/user mode, etc.) register
	cause = 13,		///< Cause of exception register
	epc = 14,		///< Exception program counter
	pr_id = 15,		///< Processor identification
	config = 16,		///< Configuration register (64 bits)
	lladdr = 17,		///< Loaded linked address
	watch_lo = 18,		///< Watch point debug facility, low part
	watch_hi = 19,		///< Watch point debug facility, high part
	x_context = 20,		///< X context register
	reserved0 = 21,		///< (Reserved register)
	reserved1 = 22,		///< (Reserved register)
	debug = 23,		///< Debug register
	depc = 24,		///< Debug exception program counter
	perf_cnt = 25,		///< Performance counter register
	err_ctl = 26,		///< Error control register
	cache_err = 27,		///< Cache error register
	cache_tag_lo = 28,	///< Cache tag/data low
	cache_tag_hi = 29,	///< Cache tag/data high
	error_epc = 30,		///< Error exception program counter
	desave = 31		///< Debug exception SAVE
      };

Benoit Perrot's avatar
Benoit Perrot committed
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
  public:
    /// Cause exception codes
    enum exception_type
      {
	interrupt = 0,		///< Interrupt
	tlb_modified = 1,	///< TLB modified
	tlb_load = 2,		///< TLB load
	tlb_store = 3,		///< TLB store
	addr_load = 4,		///< Address error on load
	addr_store = 5,		///< Address error on store
	bus_inst = 6,		///< Bus error on instruction fetch
	bus_data = 7,		///< Bus error on data load or store
	syscall = 8,		///< System call 
	breakpoint = 9,		///< Breakpoint 
	reserved_inst = 10,	///< Reserved instruction 
	cop_unusable = 11,	///< Coprocessor unusable 
	overflow = 12,		///< Arithmetic overflow 
	trap = 13,		///< Trap
	floating_point = 15	///< Floating point exception
      };
Benoit Perrot's avatar
Benoit Perrot committed
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134

    /** \name Constructor and destructor 
	\{ */
  public:
    Cp0()
    {
      reset();
    }
    /** \} */

  public:
    /// Reset the CPU (set registers to zero)
    void	reset()
    {
      // Initialize registers to 0.
      for (unsigned i = 0; i < 32; ++i)
	registers[i] = 0;
    }

    /** \name Explicit register accessors
	\{ */
  public:
    register_type	get_count() const { return registers[count]; }
    void	set_count(register_type r) { registers[count] = r; }
    /** \} */

    /** \name Register unified accessors.
	\{ */
  public:
    /// Return the register identified by \a reg.
    register_type	get_register(const inst::Register &reg) const
    {
      precondition(reg.get_kind() == inst::Register::generic);
      return registers[reg.get_index()];
    }
    /// Set the register identified by \a reg to \a r.
    void	set_register(const inst::Register &reg, register_type r)
    {
      precondition(reg.get_kind() == inst::Register::generic);
      registers[reg.get_index()] = r;
    }
    /** \} */

Benoit Perrot's avatar
Benoit Perrot committed
135
136
137
138
139
140
141
142
143
144
145
146
147

    /** \name Exception handling
        \{ */
  public:
    /// Raise an arithmetic overflow exception
    void	raise_overflow()
    {
      registers[cause] = overflow;
      std::cerr << "Runtime Exception: Overflow" << std::endl;
      exit_set(exit_runtime);
    }
    /** \} */

Benoit Perrot's avatar
Benoit Perrot committed
148
149
150
151
152
153
154
155
  protected:
    /// Dedicated registers (32 bits)
    register_type	registers[32];
  };

} // namespace vm

#endif // !VM_CP0_HH