-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathcpu-config.c
275 lines (218 loc) · 8.41 KB
/
cpu-config.c
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
/* cpu-config.c -- CPU configuration
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
Copyright (C) 2008 Embecosm Limited
Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
This file is part of OpenRISC 1000 Architectural Simulator.
This program 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 3 of the License, or (at your option)
any later version.
This program 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, see <http://www.gnu.org/licenses/>. */
/* This program is commented throughout in a fashion suitable for processing
with Doxygen. */
/* Broken out from sim-config.c */
/* Autoconf and/or portability configuration */
#include "config.h"
/* System includes */
#include <stdio.h>
/* Package includes */
#include "cpu-config.h"
#include "sim-config.h"
#include "spr-defs.h"
#include "execute.h"
#define WARNING(s) fprintf (stderr, "Warning: config.cpu: %s\n", (s))
/*---------------------------------------------------------------------------*/
/*!Set the CPU version
Value must be an 8-bit integer. Larger values are truncated with a warning.
@param[in] val The value to use
@param[in] dat The config data structure (not used here) */
/*---------------------------------------------------------------------------*/
static void
cpu_ver (union param_val val,
void *dat)
{
if (val.int_val > 0xff)
{
WARNING ("CPU version > 8 bits truncated\n");
}
cpu_state.sprs[SPR_VR] &= ~SPR_VR_VER;
cpu_state.sprs[SPR_VR] |= (val.int_val & 0xff) << SPR_VR_VER_OFF;
} /* cpu_ver() */
/*---------------------------------------------------------------------------*/
/*!Set the CPU configuration
Value must be an 8-bit integer. Larger values are truncated with a warning.
@param[in] val The value to use
@param[in] dat The config data structure (not used here) */
/*---------------------------------------------------------------------------*/
static void
cpu_cfg (union param_val val,
void *dat)
{
if (val.int_val > 0xff)
{
WARNING ("CPU configuration > 8 bits truncated\n");
}
cpu_state.sprs[SPR_VR] &= ~SPR_VR_CFG;
cpu_state.sprs[SPR_VR] |= (val.int_val & 0xff) << SPR_VR_CFG_OFF;
} /* cpu_cfg() */
/*---------------------------------------------------------------------------*/
/*!Set the CPU revision
Value must be an 6-bit integer. Larger values are truncated with a warning.
@param[in] val The value to use
@param[in] dat The config data structure (not used here) */
/*---------------------------------------------------------------------------*/
static void
cpu_rev (union param_val val,
void *dat)
{
if (val.int_val > 0x3f)
{
WARNING ("CPU revision > 6 bits truncated\n");
}
cpu_state.sprs[SPR_VR] &= ~SPR_VR_REV_OFF ;
cpu_state.sprs[SPR_VR] |= (val.int_val & 0x3f) << SPR_VR_REV_OFF ;
} /* cpu_rev() */
static void
cpu_upr (union param_val val, void *dat)
{
cpu_state.sprs[SPR_UPR] = val.int_val;
}
/*---------------------------------------------------------------------------*/
/*!Set the CPU configuration
Value must be just the OB32S instruction set bit. Nothing else is currently
supported. If other values are specified, they will be set, but with a
warning.
@param[in] val The value to use
@param[in] dat The config data structure (not used here) */
/*---------------------------------------------------------------------------*/
static void
cpu_cfgr (union param_val val,
void *dat)
{
uorreg_t cfgr = val.int_val;
if (0 != (cfgr & SPR_CPUCFGR_NSGF))
{
WARNING ("CPU configuration: shadow GPR files are not supported, will be disabled\n");
cfgr &= ~SPR_CPUCFGR_NSGF;
}
if (SPR_CPUCFGR_CGF == (cfgr & SPR_CPUCFGR_CGF))
{
WARNING ("CPU configuration: custom GPR file is not supported, will be disabled\n");
cfgr &= ~SPR_CPUCFGR_CGF;
}
if (SPR_CPUCFGR_OB32S != (cfgr & SPR_CPUCFGR_OB32S))
{
WARNING ("CPU configuration: OB32S support cannot be disabled, will be enabled\n");
cfgr |= SPR_CPUCFGR_OB32S;
}
if (SPR_CPUCFGR_OB64S == (cfgr & SPR_CPUCFGR_OB64S))
{
WARNING ("CPU configuration: OB64S is not supported, will be disabled\n");
cfgr &= ~SPR_CPUCFGR_OB64S;
}
if (SPR_CPUCFGR_OF64S == (cfgr & SPR_CPUCFGR_OF64S))
{
WARNING ("CPU configuration: OF64S is not supported, will be disabled\n");
cfgr &= ~SPR_CPUCFGR_OF64S;
}
if (SPR_CPUCFGR_EVBARP == (cfgr & SPR_CPUCFGR_EVBARP))
{
WARNING ("CPU configuration: exception vector base address register not supported, will be disabled");
cfgr &= ~SPR_CPUCFGR_EVBARP;
}
if (SPR_CPUCFGR_ISRP == (cfgr & SPR_CPUCFGR_ISRP))
{
WARNING ("CPU configuration: implementation specific registers not supported, will be disabled");
cfgr &= ~SPR_CPUCFGR_ISRP;
}
cpu_state.sprs[SPR_CPUCFGR] = cfgr;
} /* cpu_cfgr() */
/*---------------------------------------------------------------------------*/
/*!Set the CPU supervision register
Only the lowest 17 bits may be set. The top 4 bits are for context ID's
(not currently supported), the rest are reserved and should not be set.
If such values are specified, the value will be set (it has no effect), but
with a warning.
@param[in] val The value to use
@param[in] dat The config data structure (not used here) */
/*---------------------------------------------------------------------------*/
static void
cpu_sr (union param_val val,
void *dat)
{
if (0 != (val.int_val & 0xf0000000))
{
WARNING ("Supervision Register ContextID not supported: ignored\n");
}
else if (val.int_val > 0x1ffff)
{
WARNING ("Supervision Register reserved bits set: ignored\n");
}
cpu_state.sprs[SPR_SR] = val.int_val;
} /* cpu_sr() */
static void
cpu_hazards (union param_val val, void *dat)
{
config.cpu.hazards = val.int_val;
}
static void
cpu_superscalar (union param_val val, void *dat)
{
config.cpu.superscalar = val.int_val;
}
static void
cpu_dependstats (union param_val val, void *dat)
{
config.cpu.dependstats = val.int_val;
}
static void
cpu_sbuf_len (union param_val val, void *dat)
{
if (val.int_val >= MAX_SBUF_LEN)
{
config.cpu.sbuf_len = MAX_SBUF_LEN - 1;
WARNING ("sbuf_len too large; truncated.");
}
else if (val.int_val < 0)
{
config.cpu.sbuf_len = 0;
WARNING ("sbuf_len negative; disabled.");
}
else
config.cpu.sbuf_len = val.int_val;
}
static void
cpu_hardfloat (union param_val val, void *dat)
{
config.cpu.hardfloat = val.int_val;
cpu_state.sprs[SPR_CPUCFGR] |= SPR_CPUCFGR_OF32S;
}
/*---------------------------------------------------------------------------*/
/*!Register the functions to handle a section cpu
This section does not allocate dynamically a data structure holding its
config information. It's all in the global config.sim data
structure. Therefore it does not need a start and end function to
initialize default values (although it might be clearer to do so). The
default values are set in init_defconfig(). */
/*---------------------------------------------------------------------------*/
void
reg_cpu_sec ()
{
struct config_section *sec = reg_config_sec ("cpu", NULL, NULL);
reg_config_param (sec, "ver", PARAMT_INT, cpu_ver);
reg_config_param (sec, "cfg", PARAMT_INT, cpu_cfg);
reg_config_param (sec, "rev", PARAMT_INT, cpu_rev);
reg_config_param (sec, "upr", PARAMT_INT, cpu_upr);
reg_config_param (sec, "cfgr", PARAMT_INT, cpu_cfgr);
reg_config_param (sec, "sr", PARAMT_INT, cpu_sr);
reg_config_param (sec, "superscalar", PARAMT_INT, cpu_superscalar);
reg_config_param (sec, "hazards", PARAMT_INT, cpu_hazards);
reg_config_param (sec, "dependstats", PARAMT_INT, cpu_dependstats);
reg_config_param (sec, "sbuf_len", PARAMT_INT, cpu_sbuf_len);
reg_config_param (sec, "hardfloat", PARAMT_INT, cpu_hardfloat);
} /* reg_cpu_sec() */