1 /* Definitions to support the physical memory system.
2    Copyright 2001, 2003 Brian R. Gaeke.
3 
4 This file is part of VMIPS.
5 
6 VMIPS is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2 of the License, or (at your
9 option) any later version.
10 
11 VMIPS is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15 
16 You should have received a copy of the GNU General Public License along
17 with VMIPS; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
19 
20 #ifndef _MAPPER_H_
21 #define _MAPPER_H_
22 
23 #include "range.h"
24 #include <cstdio>
25 #include <vector>
26 class DeviceExc;
27 
28 class Cache {
29 public:
30         Cache(unsigned int bits_);
31         ~Cache();
32 
33         struct Entry {
34                 bool valid;
35                 uint32 tag;
36                 uint32 data;
37         };
38 
39         uint32 bits;
40         uint32 size;
41         uint32 mask;
42         Entry *entries;
43 };
44 
45 class Mapper {
46 public:
47 	struct BusErrorInfo {
48 		bool valid;
49 		DeviceExc *client;
50 		int32 mode;
51 		uint32 addr;
52 		int32 width;
53 		uint32 data;
54 	};
55 
56 private:
57 	/* We keep lists of ranges in a vector of pointers to range
58 	   objects. */
59 	typedef std::vector<Range *> Ranges;
60 
61 	/* Information about the last bus error triggered, if any. */
62 	BusErrorInfo last_berr_info;
63 
64 	/* A pointer to the last mapping that was successfully returned by
65 	   find_mapping_range. */
66 	Range *last_used_mapping;
67 
68 	/* A list of all currently mapped ranges. */
69 	Ranges ranges;
70 
71 	/* Saved option values. */
72 	bool opt_bigendian;
73 	bool byteswapped;
74 
75 	/* Add range R to the mapping. R must not overlap with any existing
76 	   ranges in the mapping. Return 0 if R added sucessfully or -1 if
77 	   R overlapped with an existing range. The Mapper takes ownership
78 	   of R. */
79 	int add_range (Range *r);
80 
81 	/* Record information about a bad access that caused a bus error,
82 	   and then signal the exception to CLIENT. */
83 	void bus_error (DeviceExc *client, int32 mode, uint32 addr, int32 width,
84 		uint32 data = 0xffffffff);
85 
86 	/* Cache configuration. */
87 	bool caches_isolated;
88 	bool caches_swapped;
89 
90 	/* Cache objects. */
91 	Cache *icache;
92 	Cache *dcache;
93 
94 	/* Cache implementation. */
95 	bool cache_use_entry(const Cache::Entry *const entry, uint32 tag,
96 		int32 mode) const;
97 
98 	bool cache_hit(bool cacheable, int32 mode, uint32 &tag, uint32 &addr,
99 		Cache::Entry *&entry);
100 
101 	uint32 cache_get_data_from_entry(const Cache::Entry *const entry,
102 			int size, uint32 addr);
103 
104 	void cache_set_data_into_entry(Cache::Entry *const entry,
105 			int size, uint32 addr, uint32 data);
106 
107 	uint32 cache_do_fill(Cache::Entry *const entry, uint32 tag,
108 			Range *l, uint32 offset, int32 mode, DeviceExc *client,
109 			int32 size, uint32 addr);
110 
111 	void cache_write(int size, uint32 addr, uint32 data, Range *l,
112 		DeviceExc *client);
113 
114 public:
115 	Mapper();
116 	~Mapper();
117 
118 	/* Add range R to the mapping, as with add_range(), but first set its
119 	   base address to PA. The Mapper takes ownership of R. */
map_at_physical_address(Range * r,uint32 pa)120 	int map_at_physical_address (Range *r, uint32 pa) {
121 		r->setBase (pa); return add_range (r);
122 	}
123 
124 	/* Byte-swapping routines. The mips_to_host and host_to_mips routines
125 	   act according to the current setting of the 'bigendian' option.  */
126 	static uint32 swap_word(uint32 w);
127 	static uint16 swap_halfword(uint16 h);
128 	uint32 mips_to_host_word(uint32 w);
129 	uint32 host_to_mips_word(uint32 w);
130 	uint16 mips_to_host_halfword(uint16 h);
131 	uint16 host_to_mips_halfword(uint16 h);
132 
133 	/* Fetch and store methods for word (32-bit), half-word (16-bit),
134 	   and byte (8-bit) widths. ADDR specifies a physical address, which
135 	   must be at the correct alignment, otherwise an address error
136 	   exception will be generated. The 32-bit fetches take an extra
137 	   MODE argument which tags the fetch as a instruction (INSTFETCH)
138 	   or data (DATALOAD) fetch. The CACHEABLE parameter is currently
139 	   not used, but represents the TLB's information about whether
140 	   the access should be cacheable. CLIENT receives any exceptions
141 	   which may be generated. */
142 	uint32 fetch_word(uint32 addr, int32 mode, bool cacheable,
143 		DeviceExc *client);
144 	uint16 fetch_halfword(uint32 addr, bool cacheable, DeviceExc *client);
145 	uint8 fetch_byte(uint32 addr, bool cacheable, DeviceExc *client);
146 	void store_word(uint32 addr, uint32 data, bool cacheable,
147 		DeviceExc *client);
148 	void store_halfword(uint32 addr, uint16 data, bool cacheable,
149 		DeviceExc *client);
150 	void store_byte(uint32 addr, uint8 data, bool cacheable,
151 		DeviceExc *client);
152 
153 	/* Returns the Range object which would be used for a fetch or store to
154 	   physical address P. Ordinarily, you shouldn't mess with these. */
155 	Range *find_mapping_range(uint32 p);
156 
157 	/* Print out a hex dump to file pointer F of the first 8 words of
158 	   stack starting at the physical stack pointer STACKPHYS.  An error
159 	   message is printed instead if STACKPHYS would lead to a bus
160 	   error or something which is not RAM (e.g. device I/O space). */
161 	void dump_stack(FILE *f, uint32 stackphys);
162 
163         /* Print a hex dump of the first word of memory at physical address
164            ADDR to the filehandle pointed to by F. */
165 	void dump_mem(FILE *f, uint32 phys);
166 
167 	/* Copy information about the most recent bus error to INFO. */
get_last_berr_info(BusErrorInfo & info)168 	void get_last_berr_info (BusErrorInfo &info) { info = last_berr_info; }
169 
170 	/* Set the cache control bits to the given values. */
171 	void cache_set_control_bits(bool isolated, bool swapped);
172 
173 };
174 
175 #endif /* _MAPPER_H_ */
176