25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: arcbios.c,v 1.96 2005/03/20 11:11:39 debug Exp $ |
* $Id: arcbios.c,v 1.103 2005/05/23 12:21:45 debug Exp $ |
29 |
* |
* |
30 |
* ARCBIOS emulation. |
* ARCBIOS emulation. |
|
* |
|
|
* This whole file is a mess. |
|
|
* |
|
|
* TODO: Fix. |
|
|
* |
|
|
* TODO: FACTOR OUT COMMON PARTS OF THE 64-bit and 32-bit stuff!! |
|
31 |
*/ |
*/ |
32 |
|
|
33 |
#include <stdio.h> |
#include <stdio.h> |
40 |
#include <sys/resource.h> |
#include <sys/resource.h> |
41 |
|
|
42 |
#include "arcbios.h" |
#include "arcbios.h" |
43 |
|
#include "arcbios_other.h" |
44 |
#include "console.h" |
#include "console.h" |
45 |
#include "cpu.h" |
#include "cpu.h" |
46 |
#include "cpu_mips.h" |
#include "cpu_mips.h" |
54 |
|
|
55 |
|
|
56 |
/* |
/* |
|
* TODO: all this should be _per machine_! |
|
|
*/ |
|
|
|
|
|
/* Configuration data: */ |
|
|
#define MAX_CONFIG_DATA 50 |
|
|
static int n_configuration_data = 0; |
|
|
static uint64_t configuration_data_next_addr = ARC_CONFIG_DATA_ADDR; |
|
|
static uint64_t configuration_data_component[MAX_CONFIG_DATA]; |
|
|
static int configuration_data_len[MAX_CONFIG_DATA]; |
|
|
static uint64_t configuration_data_configdata[MAX_CONFIG_DATA]; |
|
|
|
|
|
static int arc_64bit = 0; /* For some SGI modes */ |
|
|
static int arc_wordlen = sizeof(uint32_t); |
|
|
|
|
|
static uint64_t scsicontroller = 0; |
|
|
|
|
|
static int arc_n_memdescriptors = 0; |
|
|
static uint64_t arcbios_memdescriptor_base = ARC_MEMDESC_ADDR; |
|
|
|
|
|
static uint64_t arcbios_next_component_address = FIRST_ARC_COMPONENT; |
|
|
static int n_arc_components = 0; |
|
|
|
|
|
static uint64_t arcbios_console_vram = 0; |
|
|
static uint64_t arcbios_console_ctrlregs = 0; |
|
|
#define MAX_ESC 16 |
|
|
static char arcbios_escape_sequence[MAX_ESC+1]; |
|
|
static int arcbios_in_escape_sequence; |
|
|
static int arcbios_console_maxx, arcbios_console_maxy; |
|
|
int arcbios_console_curx = 0, arcbios_console_cury = 0; |
|
|
static int arcbios_console_reverse = 0; |
|
|
int arcbios_console_curcolor = 0x1f; |
|
|
|
|
|
/* Open file handles: */ |
|
|
#define MAX_OPEN_STRINGLEN 200 |
|
|
#define MAX_HANDLES 10 |
|
|
static int file_handle_in_use[MAX_HANDLES]; |
|
|
static unsigned char *file_handle_string[MAX_HANDLES]; |
|
|
static uint64_t arcbios_current_seek_offset[MAX_HANDLES]; |
|
|
|
|
|
#define MAX_STRING_TO_COMPONENT 20 |
|
|
static char *arcbios_string_to_component[MAX_STRING_TO_COMPONENT]; |
|
|
static uint64_t arcbios_string_to_component_value[MAX_STRING_TO_COMPONENT]; |
|
|
static int arcbios_n_string_to_components = 0; |
|
|
|
|
|
|
|
|
/* |
|
57 |
* arcbios_add_string_to_component(): |
* arcbios_add_string_to_component(): |
58 |
*/ |
*/ |
59 |
void arcbios_add_string_to_component(char *string, uint64_t component) |
void arcbios_add_string_to_component(struct machine *machine, |
60 |
|
char *string, uint64_t component) |
61 |
{ |
{ |
62 |
if (arcbios_n_string_to_components >= MAX_STRING_TO_COMPONENT) { |
if (machine->md.arc.n_string_to_components >= MAX_STRING_TO_COMPONENT) { |
63 |
printf("Too many string-to-component mappings.\n"); |
printf("Too many string-to-component mappings.\n"); |
64 |
exit(1); |
exit(1); |
65 |
} |
} |
66 |
|
|
67 |
arcbios_string_to_component[arcbios_n_string_to_components] = |
machine->md.arc.string_to_component[machine-> |
68 |
strdup(string); |
md.arc.n_string_to_components] = strdup(string); |
69 |
if (arcbios_string_to_component[arcbios_n_string_to_components] == |
if (machine->md.arc.string_to_component[machine-> |
70 |
NULL) { |
md.arc.n_string_to_components] == NULL) { |
71 |
fprintf(stderr, "out of memory in " |
fprintf(stderr, "out of memory in " |
72 |
"arcbios_add_string_to_component()\n"); |
"arcbios_add_string_to_component()\n"); |
73 |
exit(1); |
exit(1); |
75 |
debug("adding ARC component mapping: 0x%08x = %s\n", |
debug("adding ARC component mapping: 0x%08x = %s\n", |
76 |
(int)component, string); |
(int)component, string); |
77 |
|
|
78 |
arcbios_string_to_component_value[arcbios_n_string_to_components] = |
machine->md.arc.string_to_component_value[ |
79 |
component; |
machine->md.arc.n_string_to_components] = component; |
80 |
arcbios_n_string_to_components ++; |
|
81 |
|
machine->md.arc.n_string_to_components ++; |
82 |
} |
} |
83 |
|
|
84 |
|
|
87 |
* |
* |
88 |
* Fills in an arcbios_dsp_stat struct with valid data. |
* Fills in an arcbios_dsp_stat struct with valid data. |
89 |
*/ |
*/ |
90 |
void arcbios_get_dsp_stat(struct cpu *cpu, struct arcbios_dsp_stat *dspstat) |
static void arcbios_get_dsp_stat(struct cpu *cpu, |
91 |
|
struct arcbios_dsp_stat *dspstat) |
92 |
{ |
{ |
93 |
memset(dspstat, 0, sizeof(struct arcbios_dsp_stat)); |
memset(dspstat, 0, sizeof(struct arcbios_dsp_stat)); |
94 |
|
|
95 |
store_16bit_word_in_host(cpu, (unsigned char *)&dspstat-> |
store_16bit_word_in_host(cpu, (unsigned char *)&dspstat-> |
96 |
CursorXPosition, arcbios_console_curx + 1); |
CursorXPosition, cpu->machine->md.arc.console_curx + 1); |
97 |
store_16bit_word_in_host(cpu, (unsigned char *)&dspstat-> |
store_16bit_word_in_host(cpu, (unsigned char *)&dspstat-> |
98 |
CursorYPosition, arcbios_console_cury + 1); |
CursorYPosition, cpu->machine->md.arc.console_cury + 1); |
99 |
store_16bit_word_in_host(cpu, (unsigned char *)&dspstat-> |
store_16bit_word_in_host(cpu, (unsigned char *)&dspstat-> |
100 |
CursorMaxXPosition, ARC_CONSOLE_MAX_X); |
CursorMaxXPosition, ARC_CONSOLE_MAX_X); |
101 |
store_16bit_word_in_host(cpu, (unsigned char *)&dspstat-> |
store_16bit_word_in_host(cpu, (unsigned char *)&dspstat-> |
102 |
CursorMaxYPosition, ARC_CONSOLE_MAX_Y); |
CursorMaxYPosition, ARC_CONSOLE_MAX_Y); |
103 |
dspstat->ForegroundColor = arcbios_console_curcolor; |
dspstat->ForegroundColor = cpu->machine->md.arc.console_curcolor; |
104 |
dspstat->HighIntensity = arcbios_console_curcolor ^ 0x08; |
dspstat->HighIntensity = cpu->machine->md.arc.console_curcolor ^ 0x08; |
105 |
} |
} |
106 |
|
|
107 |
|
|
112 |
{ |
{ |
113 |
unsigned char buf[2]; |
unsigned char buf[2]; |
114 |
buf[0] = ch; |
buf[0] = ch; |
115 |
buf[1] = arcbios_console_curcolor; |
buf[1] = cpu->machine->md.arc.console_curcolor; |
116 |
if (arcbios_console_reverse) |
if (cpu->machine->md.arc.console_reverse) |
117 |
buf[1] = ((buf[1] & 0x70) >> 4) | ((buf[1] & 7) << 4) |
buf[1] = ((buf[1] & 0x70) >> 4) | ((buf[1] & 7) << 4) |
118 |
| (buf[1] & 0x88); |
| (buf[1] & 0x88); |
119 |
cpu->memory_rw(cpu, cpu->mem, arcbios_console_vram + |
cpu->memory_rw(cpu, cpu->mem, cpu->machine->md.arc.console_vram + |
120 |
2*(x + arcbios_console_maxx * y), |
2*(x + cpu->machine->md.arc.console_maxx * y), |
121 |
&buf[0], sizeof(buf), MEM_WRITE, |
&buf[0], sizeof(buf), MEM_WRITE, |
122 |
CACHE_NONE | PHYSICAL); |
CACHE_NONE | PHYSICAL); |
123 |
} |
} |
124 |
|
|
125 |
|
|
126 |
/* |
/* |
|
* arcbios_console_init(): |
|
|
* |
|
|
* Called from machine.c whenever an ARC-based machine is running with |
|
|
* a graphical VGA-style framebuffer, which can be used as console. |
|
|
*/ |
|
|
void arcbios_console_init(struct cpu *cpu, |
|
|
uint64_t vram, uint64_t ctrlregs, int maxx, int maxy) |
|
|
{ |
|
|
int x, y; |
|
|
|
|
|
arcbios_console_vram = vram; |
|
|
arcbios_console_ctrlregs = ctrlregs; |
|
|
arcbios_console_maxx = maxx; |
|
|
arcbios_console_maxy = maxy; |
|
|
arcbios_in_escape_sequence = 0; |
|
|
arcbios_escape_sequence[0] = '\0'; |
|
|
arcbios_console_curcolor = 0x1f; |
|
|
|
|
|
for (y=1; y<arcbios_console_maxy; y++) |
|
|
for (x=0; x<arcbios_console_maxx; x++) |
|
|
arcbios_putcell(cpu, ' ', x, y); |
|
|
|
|
|
arcbios_console_curx = 0; |
|
|
arcbios_console_cury = 1; |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
127 |
* handle_esc_seq(): |
* handle_esc_seq(): |
128 |
* |
* |
129 |
* Used by arcbios_putchar(). |
* Used by arcbios_putchar(). |
130 |
*/ |
*/ |
131 |
static void handle_esc_seq(struct cpu *cpu) |
static void handle_esc_seq(struct cpu *cpu) |
132 |
{ |
{ |
133 |
int i, len = strlen(arcbios_escape_sequence); |
int i, len = strlen(cpu->machine->md.arc.escape_sequence); |
134 |
int row, col, color, code, start, stop; |
int row, col, color, code, start, stop; |
135 |
char *p; |
char *p; |
136 |
|
|
137 |
if (arcbios_escape_sequence[0] != '[') |
if (cpu->machine->md.arc.escape_sequence[0] != '[') |
138 |
return; |
return; |
139 |
|
|
140 |
code = arcbios_escape_sequence[len-1]; |
code = cpu->machine->md.arc.escape_sequence[len-1]; |
141 |
arcbios_escape_sequence[len-1] = '\0'; |
cpu->machine->md.arc.escape_sequence[len-1] = '\0'; |
142 |
|
|
143 |
switch (code) { |
switch (code) { |
144 |
case 'm': |
case 'm': |
145 |
color = atoi(arcbios_escape_sequence + 1); |
color = atoi(cpu->machine->md.arc.escape_sequence + 1); |
146 |
switch (color) { |
switch (color) { |
147 |
case 0: /* Default. */ |
case 0: /* Default. */ |
148 |
arcbios_console_curcolor = 0x1f; |
cpu->machine->md.arc.console_curcolor = 0x1f; |
149 |
arcbios_console_reverse = 0; break; |
cpu->machine->md.arc.console_reverse = 0; break; |
150 |
case 1: /* "Bold". */ |
case 1: /* "Bold". */ |
151 |
arcbios_console_curcolor |= 0x08; break; |
cpu->machine->md.arc.console_curcolor |= 0x08; break; |
152 |
case 7: /* "Reverse". */ |
case 7: /* "Reverse". */ |
153 |
arcbios_console_reverse = 1; break; |
cpu->machine->md.arc.console_reverse = 1; break; |
154 |
case 30: /* Black foreground. */ |
case 30: /* Black foreground. */ |
155 |
arcbios_console_curcolor &= 0xf0; |
cpu->machine->md.arc.console_curcolor &= 0xf0; |
156 |
arcbios_console_curcolor |= 0x00; break; |
cpu->machine->md.arc.console_curcolor |= 0x00; break; |
157 |
case 31: /* Red foreground. */ |
case 31: /* Red foreground. */ |
158 |
arcbios_console_curcolor &= 0xf0; |
cpu->machine->md.arc.console_curcolor &= 0xf0; |
159 |
arcbios_console_curcolor |= 0x04; break; |
cpu->machine->md.arc.console_curcolor |= 0x04; break; |
160 |
case 32: /* Green foreground. */ |
case 32: /* Green foreground. */ |
161 |
arcbios_console_curcolor &= 0xf0; |
cpu->machine->md.arc.console_curcolor &= 0xf0; |
162 |
arcbios_console_curcolor |= 0x02; break; |
cpu->machine->md.arc.console_curcolor |= 0x02; break; |
163 |
case 33: /* Yellow foreground. */ |
case 33: /* Yellow foreground. */ |
164 |
arcbios_console_curcolor &= 0xf0; |
cpu->machine->md.arc.console_curcolor &= 0xf0; |
165 |
arcbios_console_curcolor |= 0x06; break; |
cpu->machine->md.arc.console_curcolor |= 0x06; break; |
166 |
case 34: /* Blue foreground. */ |
case 34: /* Blue foreground. */ |
167 |
arcbios_console_curcolor &= 0xf0; |
cpu->machine->md.arc.console_curcolor &= 0xf0; |
168 |
arcbios_console_curcolor |= 0x01; break; |
cpu->machine->md.arc.console_curcolor |= 0x01; break; |
169 |
case 35: /* Red-blue foreground. */ |
case 35: /* Red-blue foreground. */ |
170 |
arcbios_console_curcolor &= 0xf0; |
cpu->machine->md.arc.console_curcolor &= 0xf0; |
171 |
arcbios_console_curcolor |= 0x05; break; |
cpu->machine->md.arc.console_curcolor |= 0x05; break; |
172 |
case 36: /* Green-blue foreground. */ |
case 36: /* Green-blue foreground. */ |
173 |
arcbios_console_curcolor &= 0xf0; |
cpu->machine->md.arc.console_curcolor &= 0xf0; |
174 |
arcbios_console_curcolor |= 0x03; break; |
cpu->machine->md.arc.console_curcolor |= 0x03; break; |
175 |
case 37: /* White foreground. */ |
case 37: /* White foreground. */ |
176 |
arcbios_console_curcolor &= 0xf0; |
cpu->machine->md.arc.console_curcolor &= 0xf0; |
177 |
arcbios_console_curcolor |= 0x07; break; |
cpu->machine->md.arc.console_curcolor |= 0x07; break; |
178 |
case 40: /* Black background. */ |
case 40: /* Black background. */ |
179 |
arcbios_console_curcolor &= 0x0f; |
cpu->machine->md.arc.console_curcolor &= 0x0f; |
180 |
arcbios_console_curcolor |= 0x00; break; |
cpu->machine->md.arc.console_curcolor |= 0x00; break; |
181 |
case 41: /* Red background. */ |
case 41: /* Red background. */ |
182 |
arcbios_console_curcolor &= 0x0f; |
cpu->machine->md.arc.console_curcolor &= 0x0f; |
183 |
arcbios_console_curcolor |= 0x40; break; |
cpu->machine->md.arc.console_curcolor |= 0x40; break; |
184 |
case 42: /* Green background. */ |
case 42: /* Green background. */ |
185 |
arcbios_console_curcolor &= 0x0f; |
cpu->machine->md.arc.console_curcolor &= 0x0f; |
186 |
arcbios_console_curcolor |= 0x20; break; |
cpu->machine->md.arc.console_curcolor |= 0x20; break; |
187 |
case 43: /* Yellow background. */ |
case 43: /* Yellow background. */ |
188 |
arcbios_console_curcolor &= 0x0f; |
cpu->machine->md.arc.console_curcolor &= 0x0f; |
189 |
arcbios_console_curcolor |= 0x60; break; |
cpu->machine->md.arc.console_curcolor |= 0x60; break; |
190 |
case 44: /* Blue background. */ |
case 44: /* Blue background. */ |
191 |
arcbios_console_curcolor &= 0x0f; |
cpu->machine->md.arc.console_curcolor &= 0x0f; |
192 |
arcbios_console_curcolor |= 0x10; break; |
cpu->machine->md.arc.console_curcolor |= 0x10; break; |
193 |
case 45: /* Red-blue background. */ |
case 45: /* Red-blue background. */ |
194 |
arcbios_console_curcolor &= 0x0f; |
cpu->machine->md.arc.console_curcolor &= 0x0f; |
195 |
arcbios_console_curcolor |= 0x50; break; |
cpu->machine->md.arc.console_curcolor |= 0x50; break; |
196 |
case 46: /* Green-blue background. */ |
case 46: /* Green-blue background. */ |
197 |
arcbios_console_curcolor &= 0x0f; |
cpu->machine->md.arc.console_curcolor &= 0x0f; |
198 |
arcbios_console_curcolor |= 0x30; break; |
cpu->machine->md.arc.console_curcolor |= 0x30; break; |
199 |
case 47: /* White background. */ |
case 47: /* White background. */ |
200 |
arcbios_console_curcolor &= 0x0f; |
cpu->machine->md.arc.console_curcolor &= 0x0f; |
201 |
arcbios_console_curcolor |= 0x70; break; |
cpu->machine->md.arc.console_curcolor |= 0x70; break; |
202 |
default:fatal("{ handle_esc_seq: color %i }\n", color); |
default:fatal("{ handle_esc_seq: color %i }\n", color); |
203 |
} |
} |
204 |
return; |
return; |
205 |
case 'H': |
case 'H': |
206 |
p = strchr(arcbios_escape_sequence, ';'); |
p = strchr(cpu->machine->md.arc.escape_sequence, ';'); |
207 |
if (p == NULL) |
if (p == NULL) |
208 |
return; /* TODO */ |
return; /* TODO */ |
209 |
row = atoi(arcbios_escape_sequence + 1); |
row = atoi(cpu->machine->md.arc.escape_sequence + 1); |
210 |
col = atoi(p + 1); |
col = atoi(p + 1); |
211 |
if (col < 1) |
if (col < 1) |
212 |
col = 1; |
col = 1; |
213 |
if (row < 1) |
if (row < 1) |
214 |
row = 1; |
row = 1; |
215 |
arcbios_console_curx = col - 1; |
cpu->machine->md.arc.console_curx = col - 1; |
216 |
arcbios_console_cury = row - 1; |
cpu->machine->md.arc.console_cury = row - 1; |
217 |
return; |
return; |
218 |
case 'J': |
case 'J': |
219 |
/* |
/* |
221 |
* current line, |
* current line, |
222 |
* 2J = clear whole screen. |
* 2J = clear whole screen. |
223 |
*/ |
*/ |
224 |
i = atoi(arcbios_escape_sequence + 1); |
i = atoi(cpu->machine->md.arc.escape_sequence + 1); |
225 |
if (i != 0 && i != 2) |
if (i != 0 && i != 2) |
226 |
fatal("{ handle_esc_seq(): %iJ }\n", i); |
fatal("{ handle_esc_seq(): %iJ }\n", i); |
227 |
if (i == 0) |
if (i == 0) |
228 |
for (col = arcbios_console_curx; |
for (col = cpu->machine->md.arc.console_curx; |
229 |
col < arcbios_console_maxx; col++) |
col < cpu->machine->md.arc.console_maxx; col++) |
230 |
arcbios_putcell(cpu, ' ', col, |
arcbios_putcell(cpu, ' ', col, |
231 |
arcbios_console_cury); |
cpu->machine->md.arc.console_cury); |
232 |
for (col = 0; col < arcbios_console_maxx; col++) |
for (col = 0; col < cpu->machine->md.arc.console_maxx; col++) |
233 |
for (row = i? 0 : arcbios_console_cury+1; |
for (row = i? 0 : cpu->machine->md.arc.console_cury+1; |
234 |
row < arcbios_console_maxy; row++) |
row < cpu->machine->md.arc.console_maxy; row++) |
235 |
arcbios_putcell(cpu, ' ', col, row); |
arcbios_putcell(cpu, ' ', col, row); |
236 |
return; |
return; |
237 |
case 'K': |
case 'K': |
238 |
col = atoi(arcbios_escape_sequence + 1); |
col = atoi(cpu->machine->md.arc.escape_sequence + 1); |
239 |
/* 2 = clear line to the right. 1 = to the left (?) */ |
/* 2 = clear line to the right. 1 = to the left (?) */ |
240 |
start = 0; stop = arcbios_console_curx; |
start = 0; stop = cpu->machine->md.arc.console_curx; |
241 |
if (col == 2) { |
if (col == 2) { |
242 |
start = arcbios_console_curx; |
start = cpu->machine->md.arc.console_curx; |
243 |
stop = arcbios_console_maxx-1; |
stop = cpu->machine->md.arc.console_maxx - 1; |
244 |
} |
} |
245 |
for (i=start; i<=stop; i++) |
for (i=start; i<=stop; i++) |
246 |
arcbios_putcell(cpu, ' ', i, arcbios_console_cury); |
arcbios_putcell(cpu, ' ', i, |
247 |
|
cpu->machine->md.arc.console_cury); |
248 |
|
|
249 |
return; |
return; |
250 |
} |
} |
251 |
|
|
252 |
fatal("{ handle_esc_seq(): unimplemented escape sequence: "); |
fatal("{ handle_esc_seq(): unimplemented escape sequence: "); |
253 |
for (i=0; i<len; i++) { |
for (i=0; i<len; i++) { |
254 |
int x = arcbios_escape_sequence[i]; |
int x = cpu->machine->md.arc.escape_sequence[i]; |
255 |
if (i == len-1) |
if (i == len-1) |
256 |
x = code; |
x = code; |
257 |
|
|
270 |
static void scroll_if_necessary(struct cpu *cpu) |
static void scroll_if_necessary(struct cpu *cpu) |
271 |
{ |
{ |
272 |
/* Scroll? */ |
/* Scroll? */ |
273 |
if (arcbios_console_cury >= arcbios_console_maxy) { |
if (cpu->machine->md.arc.console_cury >= |
274 |
|
cpu->machine->md.arc.console_maxy) { |
275 |
unsigned char buf[2]; |
unsigned char buf[2]; |
276 |
int x, y; |
int x, y; |
277 |
for (y=0; y<arcbios_console_maxy-1; y++) |
for (y=0; y<cpu->machine->md.arc.console_maxy-1; y++) |
278 |
for (x=0; x<arcbios_console_maxx; x++) { |
for (x=0; x<cpu->machine->md.arc.console_maxx; |
279 |
|
x++) { |
280 |
cpu->memory_rw(cpu, cpu->mem, |
cpu->memory_rw(cpu, cpu->mem, |
281 |
arcbios_console_vram + |
cpu->machine->md.arc.console_vram + |
282 |
2*(x + arcbios_console_maxx * (y+1)), |
2*(x + cpu->machine->md.arc. |
283 |
|
console_maxx * (y+1)), |
284 |
&buf[0], sizeof(buf), MEM_READ, |
&buf[0], sizeof(buf), MEM_READ, |
285 |
CACHE_NONE | PHYSICAL); |
CACHE_NONE | PHYSICAL); |
286 |
cpu->memory_rw(cpu, cpu->mem, |
cpu->memory_rw(cpu, cpu->mem, |
287 |
arcbios_console_vram + |
cpu->machine->md.arc.console_vram + |
288 |
2*(x + arcbios_console_maxx * y), |
2*(x + cpu->machine->md.arc. |
289 |
|
console_maxx * y), |
290 |
&buf[0], sizeof(buf), MEM_WRITE, |
&buf[0], sizeof(buf), MEM_WRITE, |
291 |
CACHE_NONE | PHYSICAL); |
CACHE_NONE | PHYSICAL); |
292 |
} |
} |
293 |
|
|
294 |
arcbios_console_cury = arcbios_console_maxy - 1; |
cpu->machine->md.arc.console_cury = |
295 |
|
cpu->machine->md.arc.console_maxy - 1; |
296 |
|
|
297 |
for (x=0; x<arcbios_console_maxx; x++) |
for (x=0; x<cpu->machine->md.arc.console_maxx; x++) |
298 |
arcbios_putcell(cpu, ' ', x, arcbios_console_cury); |
arcbios_putcell(cpu, ' ', x, |
299 |
|
cpu->machine->md.arc.console_cury); |
300 |
} |
} |
301 |
} |
} |
302 |
|
|
312 |
int addr; |
int addr; |
313 |
unsigned char byte; |
unsigned char byte; |
314 |
|
|
315 |
if (!cpu->machine->use_x11) { |
if (!cpu->machine->md.arc.vgaconsole) { |
316 |
/* Text console output: */ |
/* Text console output: */ |
317 |
|
|
318 |
/* Hack for Windows NT, which uses 0x9b instead of ESC + [ */ |
/* Hack for Windows NT, which uses 0x9b instead of ESC + [ */ |
324 |
return; |
return; |
325 |
} |
} |
326 |
|
|
327 |
if (arcbios_in_escape_sequence) { |
if (cpu->machine->md.arc.in_escape_sequence) { |
328 |
int len = strlen(arcbios_escape_sequence); |
int len = strlen(cpu->machine->md.arc.escape_sequence); |
329 |
arcbios_escape_sequence[len] = ch; |
cpu->machine->md.arc.escape_sequence[len] = ch; |
330 |
len++; |
len++; |
331 |
if (len >= MAX_ESC) |
if (len >= ARC_MAX_ESC) |
332 |
len = MAX_ESC; |
len = ARC_MAX_ESC; |
333 |
arcbios_escape_sequence[len] = '\0'; |
cpu->machine->md.arc.escape_sequence[len] = '\0'; |
334 |
if ((ch >= 'a' && ch <= 'z') || |
if ((ch >= 'a' && ch <= 'z') || |
335 |
(ch >= 'A' && ch <= 'Z') || len >= MAX_ESC) { |
(ch >= 'A' && ch <= 'Z') || len >= ARC_MAX_ESC) { |
336 |
handle_esc_seq(cpu); |
handle_esc_seq(cpu); |
337 |
arcbios_in_escape_sequence = 0; |
cpu->machine->md.arc.in_escape_sequence = 0; |
338 |
} |
} |
339 |
} else { |
} else { |
340 |
if (ch == 27) { |
if (ch == 27) { |
341 |
arcbios_in_escape_sequence = 1; |
cpu->machine->md.arc.in_escape_sequence = 1; |
342 |
arcbios_escape_sequence[0] = '\0'; |
cpu->machine->md.arc.escape_sequence[0] = '\0'; |
343 |
} else if (ch == 0x9b) { |
} else if (ch == 0x9b) { |
344 |
arcbios_in_escape_sequence = 1; |
cpu->machine->md.arc.in_escape_sequence = 1; |
345 |
arcbios_escape_sequence[0] = '['; |
cpu->machine->md.arc.escape_sequence[0] = '['; |
346 |
arcbios_escape_sequence[1] = '\0'; |
cpu->machine->md.arc.escape_sequence[1] = '\0'; |
347 |
} else if (ch == '\b') { |
} else if (ch == '\b') { |
348 |
if (arcbios_console_curx > 0) |
if (cpu->machine->md.arc.console_curx > 0) |
349 |
arcbios_console_curx --; |
cpu->machine->md.arc.console_curx --; |
350 |
} else if (ch == '\r') { |
} else if (ch == '\r') { |
351 |
arcbios_console_curx = 0; |
cpu->machine->md.arc.console_curx = 0; |
352 |
} else if (ch == '\n') { |
} else if (ch == '\n') { |
353 |
arcbios_console_cury ++; |
cpu->machine->md.arc.console_cury ++; |
354 |
} else if (ch == '\t') { |
} else if (ch == '\t') { |
355 |
arcbios_console_curx = |
cpu->machine->md.arc.console_curx = |
356 |
((arcbios_console_curx - 1) | 7) + 1; |
((cpu->machine->md.arc.console_curx - 1) |
357 |
|
| 7) + 1; |
358 |
/* TODO: Print spaces? */ |
/* TODO: Print spaces? */ |
359 |
} else { |
} else { |
360 |
/* Put char: */ |
/* Put char: */ |
361 |
if (arcbios_console_curx >= arcbios_console_maxx) { |
if (cpu->machine->md.arc.console_curx >= |
362 |
arcbios_console_curx = 0; |
cpu->machine->md.arc.console_maxx) { |
363 |
arcbios_console_cury ++; |
cpu->machine->md.arc.console_curx = 0; |
364 |
|
cpu->machine->md.arc.console_cury ++; |
365 |
scroll_if_necessary(cpu); |
scroll_if_necessary(cpu); |
366 |
} |
} |
367 |
arcbios_putcell(cpu, ch, arcbios_console_curx, |
arcbios_putcell(cpu, ch, |
368 |
arcbios_console_cury); |
cpu->machine->md.arc.console_curx, |
369 |
arcbios_console_curx ++; |
cpu->machine->md.arc.console_cury); |
370 |
|
cpu->machine->md.arc.console_curx ++; |
371 |
} |
} |
372 |
} |
} |
373 |
|
|
374 |
scroll_if_necessary(cpu); |
scroll_if_necessary(cpu); |
375 |
|
|
376 |
/* Update cursor position: */ |
/* Update cursor position: */ |
377 |
addr = (arcbios_console_curx >= arcbios_console_maxx? |
addr = (cpu->machine->md.arc.console_curx >= |
378 |
arcbios_console_maxx-1 : arcbios_console_curx) + |
cpu->machine->md.arc.console_maxx? |
379 |
arcbios_console_cury * arcbios_console_maxx; |
cpu->machine->md.arc.console_maxx - 1 : |
380 |
|
cpu->machine->md.arc.console_curx) + |
381 |
|
cpu->machine->md.arc.console_cury * |
382 |
|
cpu->machine->md.arc.console_maxx; |
383 |
byte = 0x0e; |
byte = 0x0e; |
384 |
cpu->memory_rw(cpu, cpu->mem, arcbios_console_ctrlregs + 0x14, |
cpu->memory_rw(cpu, cpu->mem, cpu->machine->md.arc. |
385 |
|
console_ctrlregs + 0x14, |
386 |
&byte, sizeof(byte), MEM_WRITE, CACHE_NONE | PHYSICAL); |
&byte, sizeof(byte), MEM_WRITE, CACHE_NONE | PHYSICAL); |
387 |
byte = (addr >> 8) & 255; |
byte = (addr >> 8) & 255; |
388 |
cpu->memory_rw(cpu, cpu->mem, arcbios_console_ctrlregs + 0x15, |
cpu->memory_rw(cpu, cpu->mem, cpu->machine->md.arc. |
389 |
|
console_ctrlregs + 0x15, |
390 |
&byte, sizeof(byte), MEM_WRITE, CACHE_NONE | PHYSICAL); |
&byte, sizeof(byte), MEM_WRITE, CACHE_NONE | PHYSICAL); |
391 |
byte = 0x0f; |
byte = 0x0f; |
392 |
cpu->memory_rw(cpu, cpu->mem, arcbios_console_ctrlregs + 0x14, |
cpu->memory_rw(cpu, cpu->mem, cpu->machine->md.arc. |
393 |
|
console_ctrlregs + 0x14, |
394 |
&byte, sizeof(byte), MEM_WRITE, CACHE_NONE | PHYSICAL); |
&byte, sizeof(byte), MEM_WRITE, CACHE_NONE | PHYSICAL); |
395 |
byte = addr & 255; |
byte = addr & 255; |
396 |
cpu->memory_rw(cpu, cpu->mem, arcbios_console_ctrlregs + 0x15, |
cpu->memory_rw(cpu, cpu->mem, cpu->machine->md.arc. |
397 |
|
console_ctrlregs + 0x15, |
398 |
&byte, sizeof(byte), MEM_WRITE, CACHE_NONE | PHYSICAL); |
&byte, sizeof(byte), MEM_WRITE, CACHE_NONE | PHYSICAL); |
399 |
} |
} |
400 |
|
|
401 |
|
|
402 |
/* |
/* |
403 |
|
* arcbios_putstring(): |
404 |
|
*/ |
405 |
|
static void arcbios_putstring(struct cpu *cpu, char *s) |
406 |
|
{ |
407 |
|
while (*s) { |
408 |
|
if (*s == '\n') |
409 |
|
arcbios_putchar(cpu, '\r'); |
410 |
|
arcbios_putchar(cpu, *s++); |
411 |
|
} |
412 |
|
} |
413 |
|
|
414 |
|
|
415 |
|
/* |
416 |
* arcbios_register_scsicontroller(): |
* arcbios_register_scsicontroller(): |
417 |
*/ |
*/ |
418 |
void arcbios_register_scsicontroller(uint64_t scsicontroller_component) |
void arcbios_register_scsicontroller(struct machine *machine, |
419 |
|
uint64_t scsicontroller_component) |
420 |
{ |
{ |
421 |
scsicontroller = scsicontroller_component; |
machine->md.arc.scsicontroller = scsicontroller_component; |
422 |
} |
} |
423 |
|
|
424 |
|
|
425 |
/* |
/* |
426 |
* arcbios_get_scsicontroller(): |
* arcbios_get_scsicontroller(): |
427 |
*/ |
*/ |
428 |
uint64_t arcbios_get_scsicontroller(void) |
uint64_t arcbios_get_scsicontroller(struct machine *machine) |
429 |
{ |
{ |
430 |
return scsicontroller; |
return machine->md.arc.scsicontroller; |
431 |
} |
} |
432 |
|
|
433 |
|
|
471 |
/* printf("%i\n", arctype); */ |
/* printf("%i\n", arctype); */ |
472 |
} |
} |
473 |
#endif |
#endif |
474 |
if (arc_64bit) |
if (cpu->machine->md.arc.arc_64bit) |
475 |
s = sizeof(arcbios_mem64); |
s = sizeof(arcbios_mem64); |
476 |
else |
else |
477 |
s = sizeof(arcbios_mem); |
s = sizeof(arcbios_mem); |
478 |
|
|
479 |
memdesc_addr = arcbios_memdescriptor_base + |
memdesc_addr = cpu->machine->md.arc.memdescriptor_base + |
480 |
arc_n_memdescriptors * s; |
cpu->machine->md.arc.n_memdescriptors * s; |
481 |
|
|
482 |
if (arc_64bit) { |
if (cpu->machine->md.arc.arc_64bit) { |
483 |
memset(&arcbios_mem64, 0, s); |
memset(&arcbios_mem64, 0, s); |
484 |
store_32bit_word_in_host(cpu, |
store_32bit_word_in_host(cpu, |
485 |
(unsigned char *)&arcbios_mem64.Type, arctype); |
(unsigned char *)&arcbios_mem64.Type, arctype); |
499 |
store_buf(cpu, memdesc_addr, (char *)&arcbios_mem, s); |
store_buf(cpu, memdesc_addr, (char *)&arcbios_mem, s); |
500 |
} |
} |
501 |
|
|
502 |
arc_n_memdescriptors ++; |
cpu->machine->md.arc.n_memdescriptors ++; |
503 |
} |
} |
504 |
|
|
505 |
|
|
519 |
struct arcbios_component *host_tmp_component, |
struct arcbios_component *host_tmp_component, |
520 |
char *identifier, uint32_t parent) |
char *identifier, uint32_t parent) |
521 |
{ |
{ |
522 |
uint64_t a = arcbios_next_component_address; |
struct machine *machine = cpu->machine; |
523 |
|
uint64_t a = machine->md.arc.next_component_address; |
524 |
uint32_t peer=0; |
uint32_t peer=0; |
525 |
uint32_t child=0; |
uint32_t child=0; |
526 |
int n_left; |
int n_left; |
543 |
* TODO: make this nicer |
* TODO: make this nicer |
544 |
*/ |
*/ |
545 |
|
|
546 |
n_left = n_arc_components; |
n_left = machine->md.arc.n_components; |
547 |
while (n_left > 0) { |
while (n_left > 0) { |
548 |
/* Load parent, child, and peer values: */ |
/* Load parent, child, and peer values: */ |
549 |
uint32_t eparent, echild, epeer, tmp; |
uint32_t eparent, echild, epeer, tmp; |
553 |
(int)peeraddr); */ |
(int)peeraddr); */ |
554 |
|
|
555 |
cpu->memory_rw(cpu, cpu->mem, |
cpu->memory_rw(cpu, cpu->mem, |
556 |
peeraddr + 0 * arc_wordlen, &buf[0], sizeof(eparent), |
peeraddr + 0 * machine->md.arc.wordlen, &buf[0], |
557 |
MEM_READ, CACHE_NONE); |
sizeof(eparent), MEM_READ, CACHE_NONE); |
558 |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
559 |
unsigned char tmp; |
unsigned char tmp; |
560 |
tmp = buf[0]; buf[0] = buf[3]; buf[3] = tmp; |
tmp = buf[0]; buf[0] = buf[3]; buf[3] = tmp; |
562 |
} |
} |
563 |
epeer = buf[0] + (buf[1]<<8) + (buf[2]<<16) + (buf[3]<<24); |
epeer = buf[0] + (buf[1]<<8) + (buf[2]<<16) + (buf[3]<<24); |
564 |
|
|
565 |
cpu->memory_rw(cpu, cpu->mem, peeraddr + 1 * arc_wordlen, |
cpu->memory_rw(cpu, cpu->mem, peeraddr + 1 * |
566 |
|
machine->md.arc.wordlen, |
567 |
&buf[0], sizeof(eparent), MEM_READ, CACHE_NONE); |
&buf[0], sizeof(eparent), MEM_READ, CACHE_NONE); |
568 |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
569 |
unsigned char tmp; tmp = buf[0]; |
unsigned char tmp; tmp = buf[0]; |
572 |
} |
} |
573 |
echild = buf[0] + (buf[1]<<8) + (buf[2]<<16) + (buf[3]<<24); |
echild = buf[0] + (buf[1]<<8) + (buf[2]<<16) + (buf[3]<<24); |
574 |
|
|
575 |
cpu->memory_rw(cpu, cpu->mem, peeraddr + 2 * arc_wordlen, |
cpu->memory_rw(cpu, cpu->mem, peeraddr + 2 * |
576 |
|
machine->md.arc.wordlen, |
577 |
&buf[0], sizeof(eparent), MEM_READ, CACHE_NONE); |
&buf[0], sizeof(eparent), MEM_READ, CACHE_NONE); |
578 |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
579 |
unsigned char tmp; tmp = buf[0]; |
unsigned char tmp; tmp = buf[0]; |
631 |
store_32bit_word(cpu, a+ 0x28, host_tmp_component->IdentifierLength); |
store_32bit_word(cpu, a+ 0x28, host_tmp_component->IdentifierLength); |
632 |
store_32bit_word(cpu, a+ 0x2c, host_tmp_component->Identifier); |
store_32bit_word(cpu, a+ 0x2c, host_tmp_component->Identifier); |
633 |
|
|
634 |
arcbios_next_component_address += 0x30; |
machine->md.arc.next_component_address += 0x30; |
635 |
|
|
636 |
if (host_tmp_component->IdentifierLength != 0) { |
if (host_tmp_component->IdentifierLength != 0) { |
637 |
store_32bit_word(cpu, a + 0x2c, a + 0x30); |
store_32bit_word(cpu, a + 0x2c, a + 0x30); |
638 |
store_string(cpu, a + 0x30, identifier); |
store_string(cpu, a + 0x30, identifier); |
639 |
if (identifier != NULL) |
if (identifier != NULL) |
640 |
arcbios_next_component_address += |
machine->md.arc.next_component_address += |
641 |
strlen(identifier) + 1; |
strlen(identifier) + 1; |
642 |
} |
} |
643 |
|
|
644 |
arcbios_next_component_address ++; |
machine->md.arc.next_component_address ++; |
645 |
|
|
646 |
/* Round up to next 0x4 bytes: */ |
/* Round up to next 0x4 bytes: */ |
647 |
arcbios_next_component_address = |
machine->md.arc.next_component_address = |
648 |
((arcbios_next_component_address - 1) | 3) + 1; |
((machine->md.arc.next_component_address - 1) | 3) + 1; |
649 |
|
|
650 |
n_arc_components ++; |
machine->md.arc.n_components ++; |
651 |
|
|
652 |
return a; |
return a; |
653 |
} |
} |
669 |
struct arcbios_component64 *host_tmp_component, |
struct arcbios_component64 *host_tmp_component, |
670 |
char *identifier, uint64_t parent) |
char *identifier, uint64_t parent) |
671 |
{ |
{ |
672 |
uint64_t a = arcbios_next_component_address; |
struct machine *machine = cpu->machine; |
673 |
|
uint64_t a = machine->md.arc.next_component_address; |
674 |
uint64_t peer=0; |
uint64_t peer=0; |
675 |
uint64_t child=0; |
uint64_t child=0; |
676 |
int n_left; |
int n_left; |
693 |
* TODO: make this nicer |
* TODO: make this nicer |
694 |
*/ |
*/ |
695 |
|
|
696 |
n_left = n_arc_components; |
n_left = machine->md.arc.n_components; |
697 |
while (n_left > 0) { |
while (n_left > 0) { |
698 |
/* Load parent, child, and peer values: */ |
/* Load parent, child, and peer values: */ |
699 |
uint64_t eparent, echild, epeer, tmp; |
uint64_t eparent, echild, epeer, tmp; |
703 |
(long long)peeraddr); */ |
(long long)peeraddr); */ |
704 |
|
|
705 |
cpu->memory_rw(cpu, cpu->mem, |
cpu->memory_rw(cpu, cpu->mem, |
706 |
peeraddr + 0 * arc_wordlen, &buf[0], sizeof(eparent), |
peeraddr + 0 * machine->md.arc.wordlen, &buf[0], |
707 |
MEM_READ, CACHE_NONE); |
sizeof(eparent), MEM_READ, CACHE_NONE); |
708 |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
709 |
unsigned char tmp; |
unsigned char tmp; |
710 |
tmp = buf[0]; buf[0] = buf[7]; buf[7] = tmp; |
tmp = buf[0]; buf[0] = buf[7]; buf[7] = tmp; |
716 |
+ ((uint64_t)buf[4] << 32) + ((uint64_t)buf[5] << 40) |
+ ((uint64_t)buf[4] << 32) + ((uint64_t)buf[5] << 40) |
717 |
+ ((uint64_t)buf[6] << 48) + ((uint64_t)buf[7] << 56); |
+ ((uint64_t)buf[6] << 48) + ((uint64_t)buf[7] << 56); |
718 |
|
|
719 |
cpu->memory_rw(cpu, cpu->mem, peeraddr + 1 * arc_wordlen, |
cpu->memory_rw(cpu, cpu->mem, peeraddr + 1 * |
720 |
|
machine->md.arc.wordlen, |
721 |
&buf[0], sizeof(eparent), MEM_READ, CACHE_NONE); |
&buf[0], sizeof(eparent), MEM_READ, CACHE_NONE); |
722 |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
723 |
unsigned char tmp; |
unsigned char tmp; |
730 |
+ ((uint64_t)buf[4] << 32) + ((uint64_t)buf[5] << 40) |
+ ((uint64_t)buf[4] << 32) + ((uint64_t)buf[5] << 40) |
731 |
+ ((uint64_t)buf[6] << 48) + ((uint64_t)buf[7] << 56); |
+ ((uint64_t)buf[6] << 48) + ((uint64_t)buf[7] << 56); |
732 |
|
|
733 |
cpu->memory_rw(cpu, cpu->mem, peeraddr + 2 * arc_wordlen, |
cpu->memory_rw(cpu, cpu->mem, peeraddr + 2 * |
734 |
|
machine->md.arc.wordlen, |
735 |
&buf[0], sizeof(eparent), MEM_READ, CACHE_NONE); |
&buf[0], sizeof(eparent), MEM_READ, CACHE_NONE); |
736 |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
737 |
unsigned char tmp; |
unsigned char tmp; |
750 |
|
|
751 |
if (eparent == parent && epeer == 0) { |
if (eparent == parent && epeer == 0) { |
752 |
epeer = a; |
epeer = a; |
753 |
store_64bit_word(cpu, peeraddr + 0 * arc_wordlen, |
store_64bit_word(cpu, peeraddr + 0 * |
754 |
epeer); |
machine->md.arc.wordlen, epeer); |
755 |
/* debug("[ addchild: adding 0x%016llx as peer " |
/* debug("[ addchild: adding 0x%016llx as peer " |
756 |
"to 0x%016llx ]\n", (long long)a, |
"to 0x%016llx ]\n", (long long)a, |
757 |
(long long)peeraddr); */ |
(long long)peeraddr); */ |
758 |
} |
} |
759 |
if (peeraddr == parent && echild == 0) { |
if (peeraddr == parent && echild == 0) { |
760 |
echild = a; |
echild = a; |
761 |
store_64bit_word(cpu, peeraddr + 1 * arc_wordlen, |
store_64bit_word(cpu, peeraddr + 1 * |
762 |
echild); |
machine->md.arc.wordlen, echild); |
763 |
/* debug("[ addchild: adding 0x%016llx as child " |
/* debug("[ addchild: adding 0x%016llx as child " |
764 |
"to 0x%016llx ]\n", (long long)a, |
"to 0x%016llx ]\n", (long long)a, |
765 |
(long long)peeraddr); */ |
(long long)peeraddr); */ |
801 |
|
|
802 |
/* TODO: Find out how a REAL ARCS64 implementation does it. */ |
/* TODO: Find out how a REAL ARCS64 implementation does it. */ |
803 |
|
|
804 |
arcbios_next_component_address += 0x50; |
machine->md.arc.next_component_address += 0x50; |
805 |
|
|
806 |
if (host_tmp_component->IdentifierLength != 0) { |
if (host_tmp_component->IdentifierLength != 0) { |
807 |
store_64bit_word(cpu, a + 0x48, a + 0x50); |
store_64bit_word(cpu, a + 0x48, a + 0x50); |
808 |
store_string(cpu, a + 0x50, identifier); |
store_string(cpu, a + 0x50, identifier); |
809 |
if (identifier != NULL) |
if (identifier != NULL) |
810 |
arcbios_next_component_address += |
machine->md.arc.next_component_address += |
811 |
strlen(identifier) + 1; |
strlen(identifier) + 1; |
812 |
} |
} |
813 |
|
|
814 |
arcbios_next_component_address ++; |
machine->md.arc.next_component_address ++; |
815 |
|
|
816 |
/* Round up to next 0x8 bytes: */ |
/* Round up to next 0x8 bytes: */ |
817 |
arcbios_next_component_address = |
machine->md.arc.next_component_address = |
818 |
((arcbios_next_component_address - 1) | 7) + 1; |
((machine->md.arc.next_component_address - 1) | 7) + 1; |
819 |
|
|
820 |
n_arc_components ++; |
machine->md.arc.n_components ++; |
821 |
return a; |
return a; |
822 |
} |
} |
823 |
|
|
836 |
uint64_t affinitymask, char *identifier, uint64_t parent, |
uint64_t affinitymask, char *identifier, uint64_t parent, |
837 |
void *config_data, size_t config_len) |
void *config_data, size_t config_len) |
838 |
{ |
{ |
839 |
|
struct machine *machine = cpu->machine; |
840 |
/* This component is only for temporary use: */ |
/* This component is only for temporary use: */ |
841 |
struct arcbios_component component; |
struct arcbios_component component; |
842 |
struct arcbios_component64 component64; |
struct arcbios_component64 component64; |
845 |
unsigned char *p = config_data; |
unsigned char *p = config_data; |
846 |
int i; |
int i; |
847 |
|
|
848 |
if (n_configuration_data >= MAX_CONFIG_DATA) { |
if (machine->md.arc.n_configuration_data >= MAX_CONFIG_DATA) { |
849 |
printf("fatal error: you need to increase " |
printf("fatal error: you need to increase " |
850 |
"MAX_CONFIG_DATA\n"); |
"MAX_CONFIG_DATA\n"); |
851 |
exit(1); |
exit(1); |
854 |
for (i=0; i<config_len; i++) { |
for (i=0; i<config_len; i++) { |
855 |
unsigned char ch = p[i]; |
unsigned char ch = p[i]; |
856 |
cpu->memory_rw(cpu, cpu->mem, |
cpu->memory_rw(cpu, cpu->mem, |
857 |
configuration_data_next_addr + i, |
machine->md.arc.configuration_data_next_addr + i, |
858 |
&ch, 1, MEM_WRITE, CACHE_NONE); |
&ch, 1, MEM_WRITE, CACHE_NONE); |
859 |
} |
} |
860 |
|
|
861 |
configuration_data_len[n_configuration_data] = config_len; |
machine->md.arc.configuration_data_len[ |
862 |
configuration_data_configdata[n_configuration_data] = |
machine->md.arc.n_configuration_data] = config_len; |
863 |
configuration_data_next_addr; |
machine->md.arc.configuration_data_configdata[ |
864 |
configuration_data_next_addr += config_len; |
machine->md.arc.n_configuration_data] = |
865 |
configuration_data_component[n_configuration_data] = |
machine->md.arc.configuration_data_next_addr; |
866 |
arcbios_next_component_address + (arc_64bit? 0x18 : 0x0c); |
machine->md.arc.configuration_data_next_addr += config_len; |
867 |
|
machine->md.arc.configuration_data_component[ |
868 |
|
machine->md.arc.n_configuration_data] = |
869 |
|
machine->md.arc.next_component_address + |
870 |
|
(cpu->machine->md.arc.arc_64bit? 0x18 : 0x0c); |
871 |
|
|
872 |
/* printf("& ADDING %i: configdata=0x%016llx " |
/* printf("& ADDING %i: configdata=0x%016llx " |
873 |
"component=0x%016llx\n", n_configuration_data, |
"component=0x%016llx\n", |
874 |
(long long)configuration_data_configdata[ |
machine->md.arc.n_configuration_data, |
875 |
n_configuration_data], |
(long long)machine->md.arc.configuration_data_configdata[ |
876 |
(long long)configuration_data_component[ |
machine->md.arc.n_configuration_data], |
877 |
n_configuration_data]); */ |
(long long)machine->md.arc.configuration_data_component[ |
878 |
|
machine->md.arc.n_configuration_data]); */ |
879 |
|
|
880 |
n_configuration_data ++; |
machine->md.arc.n_configuration_data ++; |
881 |
} |
} |
882 |
|
|
883 |
if (!arc_64bit) { |
if (!cpu->machine->md.arc.arc_64bit) { |
884 |
component.Class = class; |
component.Class = class; |
885 |
component.Type = type; |
component.Type = type; |
886 |
component.Flags = flags; |
component.Flags = flags; |
930 |
* for more info. |
* for more info. |
931 |
*/ |
*/ |
932 |
static void arcbios_get_msdos_partition_size(struct machine *machine, |
static void arcbios_get_msdos_partition_size(struct machine *machine, |
933 |
int scsi_id, int partition_nr, uint64_t *start, uint64_t *size) |
int disk_id, int disk_type, int partition_nr, uint64_t *start, |
934 |
|
uint64_t *size) |
935 |
{ |
{ |
936 |
int res, i, partition_type, cur_partition = 0; |
int res, i, partition_type, cur_partition = 0; |
937 |
unsigned char sector[512]; |
unsigned char sector[512]; |
940 |
|
|
941 |
/* Partition 0 is the entire disk image: */ |
/* Partition 0 is the entire disk image: */ |
942 |
*start = 0; |
*start = 0; |
943 |
*size = diskimage_getsize(machine, scsi_id); |
*size = diskimage_getsize(machine, disk_id, disk_type); |
944 |
if (partition_nr == 0) |
if (partition_nr == 0) |
945 |
return; |
return; |
946 |
|
|
950 |
/* printf("reading MSDOS partition from offset 0x%llx\n", |
/* printf("reading MSDOS partition from offset 0x%llx\n", |
951 |
(long long)offset); */ |
(long long)offset); */ |
952 |
|
|
953 |
res = diskimage_access(machine, scsi_id, 0, offset, |
res = diskimage_access(machine, disk_id, disk_type, 0, offset, |
954 |
sector, sizeof(sector)); |
sector, sizeof(sector)); |
955 |
if (!res) { |
if (!res) { |
956 |
fatal("[ arcbios_get_msdos_partition_size(): couldn't " |
fatal("[ arcbios_get_msdos_partition_size(): couldn't " |
957 |
"read the disk image, id %i, offset 0x%llx ]\n", |
"read the disk image, id %i, offset 0x%llx ]\n", |
958 |
scsi_id, (long long)offset); |
disk_id, (long long)offset); |
959 |
return; |
return; |
960 |
} |
} |
961 |
|
|
1009 |
|
|
1010 |
|
|
1011 |
/* |
/* |
1012 |
* arcbios_handle_to_scsi_id(): |
* arcbios_handle_to_disk_id_and_type(): |
1013 |
*/ |
*/ |
1014 |
static int arcbios_handle_to_scsi_id(int handle) |
static int arcbios_handle_to_disk_id_and_type(struct machine *machine, |
1015 |
|
int handle, int *typep) |
1016 |
{ |
{ |
1017 |
int id, cdrom; |
int id, cdrom; |
1018 |
char *s; |
char *s; |
1019 |
|
|
1020 |
if (handle < 0 || handle >= MAX_HANDLES) |
if (handle < 0 || handle >= ARC_MAX_HANDLES) |
1021 |
return -1; |
return -1; |
1022 |
|
|
1023 |
s = (char *)file_handle_string[handle]; |
s = machine->md.arc.file_handle_string[handle]; |
1024 |
if (s == NULL) |
if (s == NULL) |
1025 |
return -1; |
return -1; |
1026 |
|
|
1032 |
if (strncmp(s, "scsi(", 5) != 0 || strlen(s) < 13) |
if (strncmp(s, "scsi(", 5) != 0 || strlen(s) < 13) |
1033 |
return -1; |
return -1; |
1034 |
|
|
1035 |
|
*typep = DISKIMAGE_SCSI; |
1036 |
|
|
1037 |
cdrom = (s[7] == 'c'); |
cdrom = (s[7] == 'c'); |
1038 |
id = cdrom? atoi(s + 13) : atoi(s + 12); |
id = cdrom? atoi(s + 13) : atoi(s + 12); |
1039 |
|
|
1047 |
static void arcbios_handle_to_start_and_size(struct machine *machine, |
static void arcbios_handle_to_start_and_size(struct machine *machine, |
1048 |
int handle, uint64_t *start, uint64_t *size) |
int handle, uint64_t *start, uint64_t *size) |
1049 |
{ |
{ |
1050 |
char *s = (char *)file_handle_string[handle]; |
char *s = machine->md.arc.file_handle_string[handle]; |
1051 |
char *s2; |
char *s2; |
1052 |
int scsi_id = arcbios_handle_to_scsi_id(handle); |
int disk_id, disk_type; |
1053 |
|
|
1054 |
if (scsi_id < 0) |
disk_id = arcbios_handle_to_disk_id_and_type(machine, |
1055 |
|
handle, &disk_type); |
1056 |
|
|
1057 |
|
if (disk_id < 0) |
1058 |
return; |
return; |
1059 |
|
|
1060 |
/* This works for "partition(0)": */ |
/* This works for "partition(0)": */ |
1061 |
*start = 0; |
*start = 0; |
1062 |
*size = diskimage_getsize(machine, scsi_id); |
*size = diskimage_getsize(machine, disk_id, disk_type); |
1063 |
|
|
1064 |
s2 = strstr(s, "partition("); |
s2 = strstr(s, "partition("); |
1065 |
if (s2 != NULL) { |
if (s2 != NULL) { |
1067 |
/* printf("partition_nr = %i\n", partition_nr); */ |
/* printf("partition_nr = %i\n", partition_nr); */ |
1068 |
if (partition_nr != 0) |
if (partition_nr != 0) |
1069 |
arcbios_get_msdos_partition_size(machine, |
arcbios_get_msdos_partition_size(machine, |
1070 |
scsi_id, partition_nr, start, size); |
disk_id, disk_type, partition_nr, start, size); |
1071 |
} |
} |
1072 |
} |
} |
1073 |
|
|
1160 |
*/ |
*/ |
1161 |
int arcbios_emul(struct cpu *cpu) |
int arcbios_emul(struct cpu *cpu) |
1162 |
{ |
{ |
1163 |
|
struct machine *machine = cpu->machine; |
1164 |
int vector = cpu->pc & 0xfff; |
int vector = cpu->pc & 0xfff; |
1165 |
int i, j, handle; |
int i, j, handle; |
1166 |
unsigned char ch2; |
unsigned char ch2; |
1172 |
return 1; |
return 1; |
1173 |
} |
} |
1174 |
|
|
1175 |
if (arc_64bit) |
if (machine->md.arc.arc_64bit) |
1176 |
vector /= 2; |
vector /= 2; |
1177 |
|
|
1178 |
/* Special case for reboot by jumping to 0xbfc00000: */ |
/* Special case for reboot by jumping to 0xbfc00000: */ |
1188 |
case 0x20: /* ReturnFromMain() */ |
case 0x20: /* ReturnFromMain() */ |
1189 |
debug("[ ARCBIOS Halt() or similar ]\n"); |
debug("[ ARCBIOS Halt() or similar ]\n"); |
1190 |
/* Halt all CPUs. */ |
/* Halt all CPUs. */ |
1191 |
for (i=0; i<cpu->machine->ncpus; i++) { |
for (i=0; i<machine->ncpus; i++) { |
1192 |
cpu->machine->cpus[i]->running = 0; |
machine->cpus[i]->running = 0; |
1193 |
cpu->machine->cpus[i]->dead = 1; |
machine->cpus[i]->dead = 1; |
1194 |
} |
} |
1195 |
cpu->machine->exit_without_entering_debugger = 1; |
machine->exit_without_entering_debugger = 1; |
1196 |
break; |
break; |
1197 |
case 0x24: /* GetPeer(node) */ |
case 0x24: /* GetPeer(node) */ |
1198 |
if (cpu->cd.mips.gpr[MIPS_GPR_A0] == 0) { |
if (cpu->cd.mips.gpr[MIPS_GPR_A0] == 0) { |
1201 |
} else { |
} else { |
1202 |
uint64_t peer; |
uint64_t peer; |
1203 |
cpu->memory_rw(cpu, cpu->mem, |
cpu->memory_rw(cpu, cpu->mem, |
1204 |
cpu->cd.mips.gpr[MIPS_GPR_A0] - 3 * arc_wordlen, |
cpu->cd.mips.gpr[MIPS_GPR_A0] - 3 * |
1205 |
&buf[0], arc_wordlen, MEM_READ, CACHE_NONE); |
machine->md.arc.wordlen, &buf[0], |
1206 |
if (arc_64bit) { |
machine->md.arc.wordlen, MEM_READ, CACHE_NONE); |
1207 |
|
if (machine->md.arc.arc_64bit) { |
1208 |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
1209 |
unsigned char tmp; tmp = buf[0]; |
unsigned char tmp; tmp = buf[0]; |
1210 |
buf[0] = buf[7]; buf[7] = tmp; |
buf[0] = buf[7]; buf[7] = tmp; |
1234 |
} |
} |
1235 |
|
|
1236 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = peer? |
cpu->cd.mips.gpr[MIPS_GPR_V0] = peer? |
1237 |
(peer + 3 * arc_wordlen) : 0; |
(peer + 3 * machine->md.arc.wordlen) : 0; |
1238 |
if (!arc_64bit) |
if (!machine->md.arc.arc_64bit) |
1239 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = (int64_t) |
cpu->cd.mips.gpr[MIPS_GPR_V0] = (int64_t) |
1240 |
(int32_t) cpu->cd.mips.gpr[MIPS_GPR_V0]; |
(int32_t) cpu->cd.mips.gpr[MIPS_GPR_V0]; |
1241 |
} |
} |
1246 |
case 0x28: /* GetChild(node) */ |
case 0x28: /* GetChild(node) */ |
1247 |
/* 0 for the root, non-0 for children: */ |
/* 0 for the root, non-0 for children: */ |
1248 |
if (cpu->cd.mips.gpr[MIPS_GPR_A0] == 0) |
if (cpu->cd.mips.gpr[MIPS_GPR_A0] == 0) |
1249 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = |
cpu->cd.mips.gpr[MIPS_GPR_V0] = FIRST_ARC_COMPONENT |
1250 |
FIRST_ARC_COMPONENT + arc_wordlen * 3; |
+ machine->md.arc.wordlen * 3; |
1251 |
else { |
else { |
1252 |
uint64_t child = 0; |
uint64_t child = 0; |
1253 |
cpu->memory_rw(cpu, cpu->mem, |
cpu->memory_rw(cpu, cpu->mem, |
1254 |
cpu->cd.mips.gpr[MIPS_GPR_A0] - 2 * arc_wordlen, |
cpu->cd.mips.gpr[MIPS_GPR_A0] - 2 * |
1255 |
&buf[0], arc_wordlen, MEM_READ, CACHE_NONE); |
machine->md.arc.wordlen, &buf[0], machine-> |
1256 |
if (arc_64bit) { |
md.arc.wordlen, MEM_READ, CACHE_NONE); |
1257 |
|
if (machine->md.arc.arc_64bit) { |
1258 |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
1259 |
unsigned char tmp; tmp = buf[0]; |
unsigned char tmp; tmp = buf[0]; |
1260 |
buf[0] = buf[7]; buf[7] = tmp; |
buf[0] = buf[7]; buf[7] = tmp; |
1285 |
} |
} |
1286 |
|
|
1287 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = child? |
cpu->cd.mips.gpr[MIPS_GPR_V0] = child? |
1288 |
(child + 3 * arc_wordlen) : 0; |
(child + 3 * machine->md.arc.wordlen) : 0; |
1289 |
if (!arc_64bit) |
if (!machine->md.arc.arc_64bit) |
1290 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = (int64_t) |
cpu->cd.mips.gpr[MIPS_GPR_V0] = (int64_t) |
1291 |
(int32_t)cpu->cd.mips.gpr[MIPS_GPR_V0]; |
(int32_t)cpu->cd.mips.gpr[MIPS_GPR_V0]; |
1292 |
} |
} |
1299 |
uint64_t parent; |
uint64_t parent; |
1300 |
|
|
1301 |
cpu->memory_rw(cpu, cpu->mem, |
cpu->memory_rw(cpu, cpu->mem, |
1302 |
cpu->cd.mips.gpr[MIPS_GPR_A0] - 1 * arc_wordlen, |
cpu->cd.mips.gpr[MIPS_GPR_A0] - 1 * machine-> |
1303 |
&buf[0], arc_wordlen, MEM_READ, CACHE_NONE); |
md.arc.wordlen, &buf[0], machine->md.arc.wordlen, |
1304 |
|
MEM_READ, CACHE_NONE); |
1305 |
|
|
1306 |
if (arc_64bit) { |
if (machine->md.arc.arc_64bit) { |
1307 |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
if (cpu->byte_order == EMUL_BIG_ENDIAN) { |
1308 |
unsigned char tmp; tmp = buf[0]; |
unsigned char tmp; tmp = buf[0]; |
1309 |
buf[0] = buf[7]; buf[7] = tmp; |
buf[0] = buf[7]; buf[7] = tmp; |
1334 |
} |
} |
1335 |
|
|
1336 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = parent? |
cpu->cd.mips.gpr[MIPS_GPR_V0] = parent? |
1337 |
(parent + 3 * arc_wordlen) : 0; |
(parent + 3 * machine->md.arc.wordlen) : 0; |
1338 |
if (!arc_64bit) |
if (!machine->md.arc.arc_64bit) |
1339 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = (int64_t) |
cpu->cd.mips.gpr[MIPS_GPR_V0] = (int64_t) |
1340 |
(int32_t) cpu->cd.mips.gpr[MIPS_GPR_V0]; |
(int32_t) cpu->cd.mips.gpr[MIPS_GPR_V0]; |
1341 |
} |
} |
1348 |
"0x%016llx) ]\n", (long long)cpu->cd.mips.gpr[MIPS_GPR_A0], |
"0x%016llx) ]\n", (long long)cpu->cd.mips.gpr[MIPS_GPR_A0], |
1349 |
(long long)cpu->cd.mips.gpr[MIPS_GPR_A1]); */ |
(long long)cpu->cd.mips.gpr[MIPS_GPR_A1]); */ |
1350 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = ARCBIOS_EINVAL; |
cpu->cd.mips.gpr[MIPS_GPR_V0] = ARCBIOS_EINVAL; |
1351 |
for (i=0; i<n_configuration_data; i++) { |
for (i=0; i<machine->md.arc.n_configuration_data; i++) { |
1352 |
/* fatal("configuration_data_component[%i] = " |
/* fatal("configuration_data_component[%i] = " |
1353 |
"0x%016llx\n", i, |
"0x%016llx\n", i, (long long)machine-> |
1354 |
(long long)configuration_data_component[i]); */ |
md.arc.configuration_data_component[i]); */ |
1355 |
if (cpu->cd.mips.gpr[MIPS_GPR_A1] == |
if (cpu->cd.mips.gpr[MIPS_GPR_A1] == |
1356 |
configuration_data_component[i]) { |
machine->md.arc.configuration_data_component[i]) { |
1357 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = 0; |
cpu->cd.mips.gpr[MIPS_GPR_V0] = 0; |
1358 |
for (j=0; j<configuration_data_len[i]; j++) { |
for (j=0; j<machine-> |
1359 |
|
md.arc.configuration_data_len[i]; j++) { |
1360 |
unsigned char ch; |
unsigned char ch; |
1361 |
cpu->memory_rw(cpu, cpu->mem, |
cpu->memory_rw(cpu, cpu->mem, |
1362 |
|
machine->md.arc. |
1363 |
configuration_data_configdata[i] + |
configuration_data_configdata[i] + |
1364 |
j, &ch, 1, MEM_READ, CACHE_NONE); |
j, &ch, 1, MEM_READ, CACHE_NONE); |
1365 |
cpu->memory_rw(cpu, cpu->mem, |
cpu->memory_rw(cpu, cpu->mem, |
1399 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = 0; |
cpu->cd.mips.gpr[MIPS_GPR_V0] = 0; |
1400 |
|
|
1401 |
/* Scan the string to component table: */ |
/* Scan the string to component table: */ |
1402 |
for (i=0; i<arcbios_n_string_to_components; i++) { |
for (i=0; i<machine->md.arc.n_string_to_components; |
1403 |
|
i++) { |
1404 |
int m = 0; |
int m = 0; |
1405 |
while (buf[m] && arcbios_string_to_component |
while (buf[m] && machine->md.arc. |
1406 |
[i][m] && arcbios_string_to_component[i][m] |
string_to_component[i][m] && |
1407 |
|
machine->md.arc.string_to_component[i][m] |
1408 |
== buf[m]) |
== buf[m]) |
1409 |
m++; |
m++; |
1410 |
if (m > match_len) { |
if (m > match_len) { |
1415 |
|
|
1416 |
if (match_index >= 0) { |
if (match_index >= 0) { |
1417 |
/* printf("Longest match: '%s'\n", |
/* printf("Longest match: '%s'\n", |
1418 |
arcbios_string_to_component[ |
machine->md.arc.string_to_component[ |
1419 |
match_index]); */ |
match_index]); */ |
1420 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = |
cpu->cd.mips.gpr[MIPS_GPR_V0] = |
1421 |
arcbios_string_to_component_value[ |
machine->md.arc.string_to_component_value[ |
1422 |
match_index]; |
match_index]; |
1423 |
} |
} |
1424 |
} |
} |
1434 |
/* If a0=NULL, then return the first descriptor: */ |
/* If a0=NULL, then return the first descriptor: */ |
1435 |
if ((uint32_t)cpu->cd.mips.gpr[MIPS_GPR_A0] == 0) |
if ((uint32_t)cpu->cd.mips.gpr[MIPS_GPR_A0] == 0) |
1436 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = |
cpu->cd.mips.gpr[MIPS_GPR_V0] = |
1437 |
arcbios_memdescriptor_base; |
machine->md.arc.memdescriptor_base; |
1438 |
else { |
else { |
1439 |
int s = arc_64bit? sizeof(struct arcbios_mem64) |
int s = machine->md.arc.arc_64bit? |
1440 |
|
sizeof(struct arcbios_mem64) |
1441 |
: sizeof(struct arcbios_mem); |
: sizeof(struct arcbios_mem); |
1442 |
int nr = cpu->cd.mips.gpr[MIPS_GPR_A0] - |
int nr = cpu->cd.mips.gpr[MIPS_GPR_A0] - |
1443 |
arcbios_memdescriptor_base; |
machine->md.arc.memdescriptor_base; |
1444 |
nr /= s; |
nr /= s; |
1445 |
nr ++; |
nr ++; |
1446 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = |
cpu->cd.mips.gpr[MIPS_GPR_V0] = |
1447 |
arcbios_memdescriptor_base + s * nr; |
machine->md.arc.memdescriptor_base + s * nr; |
1448 |
if (nr >= arc_n_memdescriptors) |
if (nr >= machine->md.arc.n_memdescriptors) |
1449 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = 0; |
cpu->cd.mips.gpr[MIPS_GPR_V0] = 0; |
1450 |
} |
} |
1451 |
break; |
break; |
1469 |
|
|
1470 |
handle = 3; |
handle = 3; |
1471 |
/* TODO: Starting at 0 would require some updates... */ |
/* TODO: Starting at 0 would require some updates... */ |
1472 |
while (file_handle_in_use[handle]) { |
while (machine->md.arc.file_handle_in_use[handle]) { |
1473 |
handle ++; |
handle ++; |
1474 |
if (handle >= MAX_HANDLES) { |
if (handle >= ARC_MAX_HANDLES) { |
1475 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = ARCBIOS_EMFILE; |
cpu->cd.mips.gpr[MIPS_GPR_V0] = ARCBIOS_EMFILE; |
1476 |
break; |
break; |
1477 |
} |
} |
1478 |
} |
} |
1479 |
|
|
1480 |
if (handle >= MAX_HANDLES) { |
if (handle >= ARC_MAX_HANDLES) { |
1481 |
fatal("[ ARCBIOS Open: out of file handles ]\n"); |
fatal("[ ARCBIOS Open: out of file handles ]\n"); |
1482 |
} else if (cpu->cd.mips.gpr[MIPS_GPR_A0] == 0) { |
} else if (cpu->cd.mips.gpr[MIPS_GPR_A0] == 0) { |
1483 |
fatal("[ ARCBIOS Open: NULL ptr ]\n"); |
fatal("[ ARCBIOS Open: NULL ptr ]\n"); |
1501 |
i = MAX_OPEN_STRINGLEN; |
i = MAX_OPEN_STRINGLEN; |
1502 |
} |
} |
1503 |
buf[MAX_OPEN_STRINGLEN - 1] = '\0'; |
buf[MAX_OPEN_STRINGLEN - 1] = '\0'; |
1504 |
file_handle_string[handle] = buf; |
machine->md.arc.file_handle_string[handle] = |
1505 |
arcbios_current_seek_offset[handle] = 0; |
(char *)buf; |
1506 |
|
machine->md.arc.current_seek_offset[handle] = 0; |
1507 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = ARCBIOS_ESUCCESS; |
cpu->cd.mips.gpr[MIPS_GPR_V0] = ARCBIOS_ESUCCESS; |
1508 |
} |
} |
1509 |
|
|
1511 |
debug(" = handle %i ]\n", (int)handle); |
debug(" = handle %i ]\n", (int)handle); |
1512 |
store_32bit_word(cpu, cpu->cd.mips.gpr[MIPS_GPR_A2], |
store_32bit_word(cpu, cpu->cd.mips.gpr[MIPS_GPR_A2], |
1513 |
handle); |
handle); |
1514 |
file_handle_in_use[handle] = 1; |
machine->md.arc.file_handle_in_use[handle] = 1; |
1515 |
} else |
} else |
1516 |
debug(" = ERROR %i ]\n", |
debug(" = ERROR %i ]\n", |
1517 |
(int)cpu->cd.mips.gpr[MIPS_GPR_V0]); |
(int)cpu->cd.mips.gpr[MIPS_GPR_V0]); |
1519 |
case 0x60: /* Close(uint32_t handle) */ |
case 0x60: /* Close(uint32_t handle) */ |
1520 |
debug("[ ARCBIOS Close(%i) ]\n", |
debug("[ ARCBIOS Close(%i) ]\n", |
1521 |
(int)cpu->cd.mips.gpr[MIPS_GPR_A0]); |
(int)cpu->cd.mips.gpr[MIPS_GPR_A0]); |
1522 |
if (!file_handle_in_use[cpu->cd.mips.gpr[MIPS_GPR_A0]]) { |
if (!machine->md.arc.file_handle_in_use[cpu->cd.mips.gpr[ |
1523 |
|
MIPS_GPR_A0]]) { |
1524 |
fatal("ARCBIOS Close(%i): bad handle\n", |
fatal("ARCBIOS Close(%i): bad handle\n", |
1525 |
(int)cpu->cd.mips.gpr[MIPS_GPR_A0]); |
(int)cpu->cd.mips.gpr[MIPS_GPR_A0]); |
1526 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = ARCBIOS_EBADF; |
cpu->cd.mips.gpr[MIPS_GPR_V0] = ARCBIOS_EBADF; |
1527 |
} else { |
} else { |
1528 |
file_handle_in_use[cpu->cd.mips.gpr[MIPS_GPR_A0]] = 0; |
machine->md.arc.file_handle_in_use[ |
1529 |
if (file_handle_string[cpu->cd.mips.gpr[MIPS_GPR_A0]] |
cpu->cd.mips.gpr[MIPS_GPR_A0]] = 0; |
1530 |
!= NULL) |
if (machine->md.arc.file_handle_string[ |
1531 |
free(file_handle_string[cpu->cd.mips.gpr[ |
cpu->cd.mips.gpr[MIPS_GPR_A0]] != NULL) |
1532 |
MIPS_GPR_A0]]); |
free(machine->md.arc.file_handle_string[ |
1533 |
file_handle_string[cpu->cd.mips.gpr[MIPS_GPR_A0]] = |
cpu->cd.mips.gpr[MIPS_GPR_A0]]); |
1534 |
NULL; |
machine->md.arc.file_handle_string[cpu->cd.mips. |
1535 |
|
gpr[MIPS_GPR_A0]] = NULL; |
1536 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = ARCBIOS_ESUCCESS; |
cpu->cd.mips.gpr[MIPS_GPR_V0] = ARCBIOS_ESUCCESS; |
1537 |
} |
} |
1538 |
break; |
break; |
1547 |
fflush(stdin); |
fflush(stdin); |
1548 |
fflush(stdout); |
fflush(stdout); |
1549 |
/* NOTE/TODO: This gives a tick to _everything_ */ |
/* NOTE/TODO: This gives a tick to _everything_ */ |
1550 |
for (i=0; i<cpu->machine->n_tick_entries; i++) |
for (i=0; i<machine->n_tick_entries; i++) |
1551 |
cpu->machine->tick_func[i](cpu, |
machine->tick_func[i](cpu, |
1552 |
cpu->machine->tick_extra[i]); |
machine->tick_extra[i]); |
1553 |
|
|
1554 |
for (i=0; i<cpu->cd.mips.gpr[MIPS_GPR_A2]; i++) { |
for (i=0; i<cpu->cd.mips.gpr[MIPS_GPR_A2]; i++) { |
1555 |
int x; |
int x; |
1558 |
/* Read from STDIN is blocking (at least |
/* Read from STDIN is blocking (at least |
1559 |
that seems to be how NetBSD's arcdiag |
that seems to be how NetBSD's arcdiag |
1560 |
wants it) */ |
wants it) */ |
1561 |
x = console_readchar(cpu->machine-> |
x = console_readchar( |
1562 |
main_console_handle); |
machine->main_console_handle); |
1563 |
if (x < 0) |
if (x < 0) |
1564 |
return 0; |
return 0; |
1565 |
|
|
1592 |
nread? ARCBIOS_ESUCCESS: ARCBIOS_EAGAIN; |
nread? ARCBIOS_ESUCCESS: ARCBIOS_EAGAIN; |
1593 |
} else { |
} else { |
1594 |
int handle = cpu->cd.mips.gpr[MIPS_GPR_A0]; |
int handle = cpu->cd.mips.gpr[MIPS_GPR_A0]; |
1595 |
int disk_id = arcbios_handle_to_scsi_id(handle); |
int disk_type; |
1596 |
|
int disk_id = arcbios_handle_to_disk_id_and_type( |
1597 |
|
machine, handle, &disk_type); |
1598 |
uint64_t partition_offset = 0; |
uint64_t partition_offset = 0; |
1599 |
int res; |
int res; |
1600 |
uint64_t size; /* dummy */ |
uint64_t size; /* dummy */ |
1601 |
unsigned char *tmp_buf; |
unsigned char *tmp_buf; |
1602 |
|
|
1603 |
arcbios_handle_to_start_and_size(cpu->machine, |
arcbios_handle_to_start_and_size(machine, handle, |
1604 |
handle, &partition_offset, &size); |
&partition_offset, &size); |
1605 |
|
|
1606 |
debug("[ ARCBIOS Read(%i,0x%08x,0x%08x,0x%08x) ]\n", |
debug("[ ARCBIOS Read(%i,0x%08x,0x%08x,0x%08x) ]\n", |
1607 |
(int)cpu->cd.mips.gpr[MIPS_GPR_A0], |
(int)cpu->cd.mips.gpr[MIPS_GPR_A0], |
1617 |
break; |
break; |
1618 |
} |
} |
1619 |
|
|
1620 |
res = diskimage_access(cpu->machine, disk_id, 0, |
res = diskimage_access(machine, disk_id, disk_type, |
1621 |
partition_offset + arcbios_current_seek_offset[ |
0, partition_offset + machine->md.arc. |
1622 |
handle], tmp_buf, cpu->cd.mips.gpr[MIPS_GPR_A2]); |
current_seek_offset[handle], tmp_buf, |
1623 |
|
cpu->cd.mips.gpr[MIPS_GPR_A2]); |
1624 |
|
|
1625 |
/* If the transfer was successful, transfer the |
/* If the transfer was successful, transfer the |
1626 |
data to emulated memory: */ |
data to emulated memory: */ |
1631 |
store_32bit_word(cpu, |
store_32bit_word(cpu, |
1632 |
cpu->cd.mips.gpr[MIPS_GPR_A3], |
cpu->cd.mips.gpr[MIPS_GPR_A3], |
1633 |
cpu->cd.mips.gpr[MIPS_GPR_A2]); |
cpu->cd.mips.gpr[MIPS_GPR_A2]); |
1634 |
arcbios_current_seek_offset[handle] += |
machine->md.arc.current_seek_offset[handle] += |
1635 |
cpu->cd.mips.gpr[MIPS_GPR_A2]; |
cpu->cd.mips.gpr[MIPS_GPR_A2]; |
1636 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = 0; |
cpu->cd.mips.gpr[MIPS_GPR_V0] = 0; |
1637 |
} else |
} else |
1649 |
*/ |
*/ |
1650 |
if (cpu->cd.mips.gpr[MIPS_GPR_A0] == ARCBIOS_STDIN) { |
if (cpu->cd.mips.gpr[MIPS_GPR_A0] == ARCBIOS_STDIN) { |
1651 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = console_charavail( |
cpu->cd.mips.gpr[MIPS_GPR_V0] = console_charavail( |
1652 |
cpu->machine->main_console_handle)? 0 : 1; |
machine->main_console_handle)? 0 : 1; |
1653 |
} else { |
} else { |
1654 |
fatal("[ ARCBIOS GetReadStatus(%i) from " |
fatal("[ ARCBIOS GetReadStatus(%i) from " |
1655 |
"something other than STDIN: TODO ]\n", |
"something other than STDIN: TODO ]\n", |
1664 |
* TODO: this is just a test |
* TODO: this is just a test |
1665 |
*/ |
*/ |
1666 |
int handle = cpu->cd.mips.gpr[MIPS_GPR_A0]; |
int handle = cpu->cd.mips.gpr[MIPS_GPR_A0]; |
1667 |
int disk_id = arcbios_handle_to_scsi_id(handle); |
int disk_type; |
1668 |
|
int disk_id = arcbios_handle_to_disk_id_and_type( |
1669 |
|
machine, handle, &disk_type); |
1670 |
uint64_t partition_offset = 0; |
uint64_t partition_offset = 0; |
1671 |
int res, i; |
int res, i; |
1672 |
uint64_t size; /* dummy */ |
uint64_t size; /* dummy */ |
1673 |
unsigned char *tmp_buf; |
unsigned char *tmp_buf; |
1674 |
|
|
1675 |
arcbios_handle_to_start_and_size(cpu->machine, |
arcbios_handle_to_start_and_size(machine, |
1676 |
handle, &partition_offset, &size); |
handle, &partition_offset, &size); |
1677 |
|
|
1678 |
debug("[ ARCBIOS Write(%i,0x%08llx,%i,0x%08llx) ]\n", |
debug("[ ARCBIOS Write(%i,0x%08llx,%i,0x%08llx) ]\n", |
1695 |
&tmp_buf[i], sizeof(char), MEM_READ, |
&tmp_buf[i], sizeof(char), MEM_READ, |
1696 |
CACHE_NONE); |
CACHE_NONE); |
1697 |
|
|
1698 |
res = diskimage_access(cpu->machine, disk_id, 1, |
res = diskimage_access(machine, disk_id, disk_type, |
1699 |
partition_offset + arcbios_current_seek_offset[ |
1, partition_offset + machine->md.arc. |
1700 |
handle], tmp_buf, cpu->cd.mips.gpr[MIPS_GPR_A2]); |
current_seek_offset[handle], tmp_buf, |
1701 |
|
cpu->cd.mips.gpr[MIPS_GPR_A2]); |
1702 |
|
|
1703 |
if (res) { |
if (res) { |
1704 |
store_32bit_word(cpu, |
store_32bit_word(cpu, |
1705 |
cpu->cd.mips.gpr[MIPS_GPR_A3], |
cpu->cd.mips.gpr[MIPS_GPR_A3], |
1706 |
cpu->cd.mips.gpr[MIPS_GPR_A2]); |
cpu->cd.mips.gpr[MIPS_GPR_A2]); |
1707 |
arcbios_current_seek_offset[handle] += |
machine->md.arc.current_seek_offset[handle] += |
1708 |
cpu->cd.mips.gpr[MIPS_GPR_A2]; |
cpu->cd.mips.gpr[MIPS_GPR_A2]; |
1709 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = 0; |
cpu->cd.mips.gpr[MIPS_GPR_V0] = 0; |
1710 |
} else |
} else |
1757 |
(buf[3] << 24) + ((uint64_t)buf[4] << 32) + |
(buf[3] << 24) + ((uint64_t)buf[4] << 32) + |
1758 |
((uint64_t)buf[5] << 40) + ((uint64_t)buf[6] << 48) |
((uint64_t)buf[5] << 40) + ((uint64_t)buf[6] << 48) |
1759 |
+ ((uint64_t)buf[7] << 56); |
+ ((uint64_t)buf[7] << 56); |
1760 |
arcbios_current_seek_offset[ |
machine->md.arc.current_seek_offset[ |
1761 |
cpu->cd.mips.gpr[MIPS_GPR_A0]] = ofs; |
cpu->cd.mips.gpr[MIPS_GPR_A0]] = ofs; |
1762 |
debug("%016llx ]\n", (long long)ofs); |
debug("%016llx ]\n", (long long)ofs); |
1763 |
} |
} |
1811 |
(int)cpu->cd.mips.gpr[MIPS_GPR_A0], |
(int)cpu->cd.mips.gpr[MIPS_GPR_A0], |
1812 |
(int)cpu->cd.mips.gpr[MIPS_GPR_A1]); |
(int)cpu->cd.mips.gpr[MIPS_GPR_A1]); |
1813 |
|
|
1814 |
if (cpu->cd.mips.gpr[MIPS_GPR_A0] >= MAX_HANDLES) { |
if (cpu->cd.mips.gpr[MIPS_GPR_A0] >= ARC_MAX_HANDLES) { |
1815 |
debug("invalid file handle ]\n"); |
debug("invalid file handle ]\n"); |
1816 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = ARCBIOS_EINVAL; |
cpu->cd.mips.gpr[MIPS_GPR_V0] = ARCBIOS_EINVAL; |
1817 |
} else if (!file_handle_in_use[cpu->cd.mips.gpr[MIPS_GPR_A0]]) { |
} else if (!machine->md.arc.file_handle_in_use[cpu->cd. |
1818 |
|
mips.gpr[MIPS_GPR_A0]]) { |
1819 |
debug("file handle not in use! ]\n"); |
debug("file handle not in use! ]\n"); |
1820 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = ARCBIOS_EBADF; |
cpu->cd.mips.gpr[MIPS_GPR_V0] = ARCBIOS_EBADF; |
1821 |
} else { |
} else { |
1822 |
debug("'%s' ]\n", file_handle_string[ |
debug("'%s' ]\n", machine->md.arc.file_handle_string[ |
1823 |
cpu->cd.mips.gpr[MIPS_GPR_A0]]); |
cpu->cd.mips.gpr[MIPS_GPR_A0]]); |
1824 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = |
cpu->cd.mips.gpr[MIPS_GPR_V0] = |
1825 |
arcbios_getfileinformation(cpu); |
arcbios_getfileinformation(cpu); |
1849 |
*/ |
*/ |
1850 |
fatal("EXCEPTION, but no exception handler installed yet.\n"); |
fatal("EXCEPTION, but no exception handler installed yet.\n"); |
1851 |
quiet_mode = 0; |
quiet_mode = 0; |
1852 |
cpu_register_dump(cpu->machine, cpu, 1, 0x1); |
cpu_register_dump(machine, cpu, 1, 0x1); |
1853 |
cpu->running = 0; |
cpu->running = 0; |
1854 |
cpu->dead = 1; |
cpu->dead = 1; |
1855 |
break; |
break; |
1856 |
default: |
default: |
1857 |
quiet_mode = 0; |
quiet_mode = 0; |
1858 |
cpu_register_dump(cpu->machine, cpu, 1, 0x1); |
cpu_register_dump(machine, cpu, 1, 0x1); |
1859 |
debug("a0 points to: "); |
debug("a0 points to: "); |
1860 |
dump_mem_string(cpu, cpu->cd.mips.gpr[MIPS_GPR_A0]); |
dump_mem_string(cpu, cpu->cd.mips.gpr[MIPS_GPR_A0]); |
1861 |
debug("\n"); |
debug("\n"); |
1869 |
|
|
1870 |
|
|
1871 |
/* |
/* |
|
* arcbios_set_64bit_mode(): |
|
|
* |
|
|
* Should be used for some SGI modes. |
|
|
*/ |
|
|
void arcbios_set_64bit_mode(int enable) |
|
|
{ |
|
|
arc_64bit = enable; |
|
|
arc_wordlen = arc_64bit? sizeof(uint64_t) : sizeof(uint32_t); |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
1872 |
* arcbios_set_default_exception_handler(): |
* arcbios_set_default_exception_handler(): |
1873 |
*/ |
*/ |
1874 |
void arcbios_set_default_exception_handler(struct cpu *cpu) |
void arcbios_set_default_exception_handler(struct cpu *cpu) |
1900 |
|
|
1901 |
|
|
1902 |
/* |
/* |
1903 |
|
* arcbios_add_other_components(): |
1904 |
|
* |
1905 |
|
* TODO: How should this be synched with the hardware devices |
1906 |
|
* added in machine.c? |
1907 |
|
*/ |
1908 |
|
static void arcbios_add_other_components(struct machine *machine, |
1909 |
|
uint64_t system) |
1910 |
|
{ |
1911 |
|
struct cpu *cpu = machine->cpus[0]; |
1912 |
|
|
1913 |
|
if (machine->machine_type == MACHINE_ARC && |
1914 |
|
( machine->machine_subtype == MACHINE_ARC_NEC_RD94 || |
1915 |
|
machine->machine_subtype == MACHINE_ARC_NEC_R94 || |
1916 |
|
machine->machine_subtype == MACHINE_ARC_NEC_R96 )) { |
1917 |
|
uint64_t jazzbus, eisa, other; |
1918 |
|
|
1919 |
|
jazzbus = arcbios_addchild_manual(cpu, |
1920 |
|
COMPONENT_CLASS_AdapterClass, |
1921 |
|
COMPONENT_TYPE_MultiFunctionAdapter, |
1922 |
|
0, 1, 2, 0, 0xffffffff, "Jazz-Internal Bus", |
1923 |
|
system, NULL, 0); |
1924 |
|
|
1925 |
|
switch (machine->machine_subtype) { |
1926 |
|
case MACHINE_ARC_NEC_RD94: |
1927 |
|
case MACHINE_ARC_NEC_R94: |
1928 |
|
if (machine->use_x11) |
1929 |
|
arcbios_addchild_manual(cpu, |
1930 |
|
COMPONENT_CLASS_ControllerClass, |
1931 |
|
COMPONENT_TYPE_DisplayController, |
1932 |
|
0, 1, 2, 0, 0x0, "10110004", |
1933 |
|
system, NULL, 0); |
1934 |
|
break; |
1935 |
|
case MACHINE_ARC_NEC_R96: |
1936 |
|
if (machine->use_x11) { |
1937 |
|
uint64_t x; |
1938 |
|
x = arcbios_addchild_manual(cpu, |
1939 |
|
COMPONENT_CLASS_ControllerClass, |
1940 |
|
COMPONENT_TYPE_DisplayController, |
1941 |
|
COMPONENT_FLAG_ConsoleOut | |
1942 |
|
COMPONENT_FLAG_Output, |
1943 |
|
1, 2, 0, 0x0, "necvdfrb", |
1944 |
|
jazzbus, NULL, 0); |
1945 |
|
arcbios_addchild_manual(cpu, |
1946 |
|
COMPONENT_CLASS_PeripheralClass, |
1947 |
|
COMPONENT_TYPE_MonitorPeripheral, |
1948 |
|
COMPONENT_FLAG_ConsoleOut | |
1949 |
|
COMPONENT_FLAG_Output, |
1950 |
|
1, 2, 0, 0xffffffff, "640x480", |
1951 |
|
x, NULL, 0); |
1952 |
|
} |
1953 |
|
|
1954 |
|
/* TODO: R[D]94 too? */ |
1955 |
|
eisa = arcbios_addchild_manual(cpu, |
1956 |
|
COMPONENT_CLASS_AdapterClass, |
1957 |
|
COMPONENT_TYPE_EISAAdapter, |
1958 |
|
0, 1, 2, 0, 0xffffffff, "EISA", |
1959 |
|
system, NULL, 0); |
1960 |
|
|
1961 |
|
other = arcbios_addchild_manual(cpu, |
1962 |
|
COMPONENT_CLASS_ControllerClass, |
1963 |
|
COMPONENT_TYPE_OtherController, |
1964 |
|
0, 1, 2, 0, 0xffffffff, "NEC1C01", |
1965 |
|
eisa, NULL, 0); |
1966 |
|
break; |
1967 |
|
} |
1968 |
|
} |
1969 |
|
|
1970 |
|
if (machine->machine_type == MACHINE_ARC && |
1971 |
|
(machine->machine_subtype == MACHINE_ARC_JAZZ_PICA |
1972 |
|
|| machine->machine_subtype == MACHINE_ARC_JAZZ_MAGNUM)) { |
1973 |
|
uint64_t jazzbus, ali_s3, vxl; |
1974 |
|
uint64_t diskcontroller, floppy, kbdctl, kbd; |
1975 |
|
uint64_t ptrctl, ptr, paral, audio; |
1976 |
|
uint64_t eisa, scsi; |
1977 |
|
/* uint64_t serial1, serial2; */ |
1978 |
|
|
1979 |
|
jazzbus = arcbios_addchild_manual(cpu, |
1980 |
|
COMPONENT_CLASS_AdapterClass, |
1981 |
|
COMPONENT_TYPE_MultiFunctionAdapter, |
1982 |
|
0, 1, 2, 0, 0xffffffff, "Jazz-Internal Bus", |
1983 |
|
system, NULL, 0); |
1984 |
|
|
1985 |
|
/* |
1986 |
|
* DisplayController, needed by NetBSD: |
1987 |
|
* TODO: NetBSD still doesn't use it :( |
1988 |
|
*/ |
1989 |
|
switch (machine->machine_subtype) { |
1990 |
|
case MACHINE_ARC_JAZZ_PICA: |
1991 |
|
/* Default TLB entries on PICA-61: */ |
1992 |
|
|
1993 |
|
/* 7: 256K, asid: 0x0, v: 0xe1000000, |
1994 |
|
p0: 0xfff00000(2.VG), p1: 0x0(0..G) */ |
1995 |
|
mips_coproc_tlb_set_entry(cpu, 7, 262144, |
1996 |
|
0xffffffffe1000000ULL, |
1997 |
|
0x0fff00000ULL, 0, 1, 0, 0, 0, 1, 0, 2, 0); |
1998 |
|
|
1999 |
|
/* 8: 64K, asid: 0x0, v: 0xe0000000, |
2000 |
|
p0: 0x80000000(2DVG), p1: 0x0(0..G) */ |
2001 |
|
mips_coproc_tlb_set_entry(cpu, 8, 65536, |
2002 |
|
0xffffffffe0000000ULL, |
2003 |
|
0x080000000ULL, 0, 1, 0, 1, 0, 1, 0, 2, 0); |
2004 |
|
|
2005 |
|
/* 9: 64K, asid: 0x0, v: 0xe00e0000, |
2006 |
|
p0: 0x800e0000(2DVG), p1: 0x800f0000(2DVG) */ |
2007 |
|
mips_coproc_tlb_set_entry(cpu, 9, 65536, |
2008 |
|
(uint64_t)0xffffffffe00e0000ULL, |
2009 |
|
(uint64_t)0x0800e0000ULL, |
2010 |
|
(uint64_t)0x0800f0000ULL, 1, 1, 1, 1, 1, 0, 2, 2); |
2011 |
|
|
2012 |
|
/* 10: 4K, asid: 0x0, v: 0xe0100000, |
2013 |
|
p0: 0xf0000000(2DVG), p1: 0x0(0..G) */ |
2014 |
|
mips_coproc_tlb_set_entry(cpu, 10, 4096, |
2015 |
|
(uint64_t)0xffffffffe0100000ULL, |
2016 |
|
(uint64_t)0x0f0000000ULL, 0,1, 0, 1, 0, 1, 0, 2, 0); |
2017 |
|
|
2018 |
|
/* 11: 1M, asid: 0x0, v: 0xe0200000, |
2019 |
|
p0: 0x60000000(2DVG), p1: 0x60100000(2DVG) */ |
2020 |
|
mips_coproc_tlb_set_entry(cpu, 11, 1048576, |
2021 |
|
0xffffffffe0200000ULL, |
2022 |
|
0x060000000ULL, 0x060100000ULL,1,1,1,1,1, 0, 2, 2); |
2023 |
|
|
2024 |
|
/* 12: 1M, asid: 0x0, v: 0xe0400000, |
2025 |
|
p0: 0x60200000(2DVG), p1: 0x60300000(2DVG) */ |
2026 |
|
mips_coproc_tlb_set_entry(cpu, 12, 1048576, |
2027 |
|
0xffffffffe0400000ULL, 0x060200000ULL, |
2028 |
|
0x060300000ULL, 1, 1, 1, 1, 1, 0, 2, 2); |
2029 |
|
|
2030 |
|
/* 13: 4M, asid: 0x0, v: 0xe0800000, |
2031 |
|
p0: 0x40000000(2DVG), p1: 0x40400000(2DVG) */ |
2032 |
|
mips_coproc_tlb_set_entry(cpu, 13, 1048576*4, |
2033 |
|
0xffffffffe0800000ULL, 0x040000000ULL, |
2034 |
|
0x040400000ULL, 1, 1, 1, 1, 1, 0, 2, 2); |
2035 |
|
|
2036 |
|
/* 14: 16M, asid: 0x0, v: 0xe2000000, |
2037 |
|
p0: 0x90000000(2DVG), p1: 0x91000000(2DVG) */ |
2038 |
|
mips_coproc_tlb_set_entry(cpu, 14, 1048576*16, |
2039 |
|
0xffffffffe2000000ULL, 0x090000000ULL, |
2040 |
|
0x091000000ULL, 1, 1, 1, 1, 1, 0, 2, 2); |
2041 |
|
|
2042 |
|
if (machine->use_x11) { |
2043 |
|
ali_s3 = arcbios_addchild_manual(cpu, |
2044 |
|
COMPONENT_CLASS_ControllerClass, |
2045 |
|
COMPONENT_TYPE_DisplayController, |
2046 |
|
COMPONENT_FLAG_ConsoleOut | |
2047 |
|
COMPONENT_FLAG_Output, |
2048 |
|
1, 2, 0, 0xffffffff, "ALI_S3", |
2049 |
|
jazzbus, NULL, 0); |
2050 |
|
|
2051 |
|
arcbios_addchild_manual(cpu, |
2052 |
|
COMPONENT_CLASS_PeripheralClass, |
2053 |
|
COMPONENT_TYPE_MonitorPeripheral, |
2054 |
|
COMPONENT_FLAG_ConsoleOut | |
2055 |
|
COMPONENT_FLAG_Output, |
2056 |
|
1, 2, 0, 0xffffffff, "1024x768", |
2057 |
|
ali_s3, NULL, 0); |
2058 |
|
} |
2059 |
|
break; |
2060 |
|
case MACHINE_ARC_JAZZ_MAGNUM: |
2061 |
|
if (machine->use_x11) { |
2062 |
|
vxl = arcbios_addchild_manual(cpu, |
2063 |
|
COMPONENT_CLASS_ControllerClass, |
2064 |
|
COMPONENT_TYPE_DisplayController, |
2065 |
|
COMPONENT_FLAG_ConsoleOut | |
2066 |
|
COMPONENT_FLAG_Output, |
2067 |
|
1, 2, 0, 0xffffffff, "VXL", |
2068 |
|
jazzbus, NULL, 0); |
2069 |
|
|
2070 |
|
arcbios_addchild_manual(cpu, |
2071 |
|
COMPONENT_CLASS_PeripheralClass, |
2072 |
|
COMPONENT_TYPE_MonitorPeripheral, |
2073 |
|
COMPONENT_FLAG_ConsoleOut | |
2074 |
|
COMPONENT_FLAG_Output, |
2075 |
|
1, 2, 0, 0xffffffff, "1024x768", |
2076 |
|
vxl, NULL, 0); |
2077 |
|
} |
2078 |
|
break; |
2079 |
|
} |
2080 |
|
|
2081 |
|
diskcontroller = arcbios_addchild_manual(cpu, |
2082 |
|
COMPONENT_CLASS_ControllerClass, |
2083 |
|
COMPONENT_TYPE_DiskController, |
2084 |
|
COMPONENT_FLAG_Input | COMPONENT_FLAG_Output, |
2085 |
|
1, 2, 0, 0xffffffff, "I82077", jazzbus, NULL, 0); |
2086 |
|
|
2087 |
|
floppy = arcbios_addchild_manual(cpu, |
2088 |
|
COMPONENT_CLASS_PeripheralClass, |
2089 |
|
COMPONENT_TYPE_FloppyDiskPeripheral, |
2090 |
|
COMPONENT_FLAG_Removable | |
2091 |
|
COMPONENT_FLAG_Input | COMPONENT_FLAG_Output, |
2092 |
|
1, 2, 0, 0xffffffff, NULL, diskcontroller, NULL, 0); |
2093 |
|
|
2094 |
|
kbdctl = arcbios_addchild_manual(cpu, |
2095 |
|
COMPONENT_CLASS_ControllerClass, |
2096 |
|
COMPONENT_TYPE_KeyboardController, |
2097 |
|
COMPONENT_FLAG_ConsoleIn | COMPONENT_FLAG_Input, |
2098 |
|
1, 2, 0, 0xffffffff, "I8742", jazzbus, NULL, 0); |
2099 |
|
|
2100 |
|
kbd = arcbios_addchild_manual(cpu, |
2101 |
|
COMPONENT_CLASS_PeripheralClass, |
2102 |
|
COMPONENT_TYPE_KeyboardPeripheral, |
2103 |
|
COMPONENT_FLAG_ConsoleIn | COMPONENT_FLAG_Input, |
2104 |
|
1, 2, 0, 0xffffffff, "PCAT_ENHANCED", kbdctl, NULL, 0); |
2105 |
|
|
2106 |
|
ptrctl = arcbios_addchild_manual(cpu, |
2107 |
|
COMPONENT_CLASS_ControllerClass, |
2108 |
|
COMPONENT_TYPE_PointerController, COMPONENT_FLAG_Input, |
2109 |
|
1, 2, 0, 0xffffffff, "I8742", jazzbus, NULL, 0); |
2110 |
|
|
2111 |
|
ptr = arcbios_addchild_manual(cpu, |
2112 |
|
COMPONENT_CLASS_PeripheralClass, |
2113 |
|
COMPONENT_TYPE_PointerPeripheral, COMPONENT_FLAG_Input, |
2114 |
|
1, 2, 0, 0xffffffff, "PS2 MOUSE", ptrctl, NULL, 0); |
2115 |
|
|
2116 |
|
/* These cause Windows NT to bug out. */ |
2117 |
|
#if 0 |
2118 |
|
serial1 = arcbios_addchild_manual(cpu, |
2119 |
|
COMPONENT_CLASS_ControllerClass, |
2120 |
|
COMPONENT_TYPE_SerialController, |
2121 |
|
COMPONENT_FLAG_Input | COMPONENT_FLAG_Output, |
2122 |
|
1, 2, 0, 0xffffffff, "COM1", jazzbus, NULL, 0); |
2123 |
|
|
2124 |
|
serial2 = arcbios_addchild_manual(cpu, |
2125 |
|
COMPONENT_CLASS_ControllerClass, |
2126 |
|
COMPONENT_TYPE_SerialController, |
2127 |
|
COMPONENT_FLAG_Input | COMPONENT_FLAG_Output, |
2128 |
|
1, 2, 0, 0xffffffff, "COM1", jazzbus, NULL, 0); |
2129 |
|
#endif |
2130 |
|
|
2131 |
|
paral = arcbios_addchild_manual(cpu, |
2132 |
|
COMPONENT_CLASS_ControllerClass, |
2133 |
|
COMPONENT_TYPE_ParallelController, |
2134 |
|
COMPONENT_FLAG_Input | COMPONENT_FLAG_Output, |
2135 |
|
1, 2, 0, 0xffffffff, "LPT1", jazzbus, NULL, 0); |
2136 |
|
|
2137 |
|
audio = arcbios_addchild_manual(cpu, |
2138 |
|
COMPONENT_CLASS_ControllerClass, |
2139 |
|
COMPONENT_TYPE_AudioController, |
2140 |
|
COMPONENT_FLAG_Input | COMPONENT_FLAG_Output, |
2141 |
|
1, 2, 0, 0xffffffff, "MAGNUM", jazzbus, NULL, 0); |
2142 |
|
|
2143 |
|
eisa = arcbios_addchild_manual(cpu, |
2144 |
|
COMPONENT_CLASS_AdapterClass, COMPONENT_TYPE_EISAAdapter, |
2145 |
|
0, 1, 2, 0, 0xffffffff, "EISA", system, NULL, 0); |
2146 |
|
|
2147 |
|
{ |
2148 |
|
unsigned char config[78]; |
2149 |
|
memset(config, 0, sizeof(config)); |
2150 |
|
|
2151 |
|
/* config data version: 1, revision: 2, count: 4 */ |
2152 |
|
config[0] = 0x01; config[1] = 0x00; |
2153 |
|
config[2] = 0x02; config[3] = 0x00; |
2154 |
|
config[4] = 0x04; config[5] = 0x00; config[6] = 0x00; config[7] = 0x00; |
2155 |
|
|
2156 |
|
/* |
2157 |
|
type: Interrupt |
2158 |
|
share_disposition: DeviceExclusive, flags: LevelSensitive |
2159 |
|
level: 4, vector: 22, reserved1: 0 |
2160 |
|
*/ |
2161 |
|
config[8] = arc_CmResourceTypeInterrupt; |
2162 |
|
config[9] = arc_CmResourceShareDeviceExclusive; |
2163 |
|
config[10] = arc_CmResourceInterruptLevelSensitive; |
2164 |
|
config[12] = 4; |
2165 |
|
config[16] = 22; |
2166 |
|
config[20] = 0; |
2167 |
|
|
2168 |
|
/* |
2169 |
|
type: Memory |
2170 |
|
share_disposition: DeviceExclusive, flags: ReadWrite |
2171 |
|
start: 0x 0 80002000, length: 0x1000 |
2172 |
|
*/ |
2173 |
|
config[24] = arc_CmResourceTypeMemory; |
2174 |
|
config[25] = arc_CmResourceShareDeviceExclusive; |
2175 |
|
config[26] = arc_CmResourceMemoryReadWrite; |
2176 |
|
config[28] = 0x00; config[29] = 0x20; config[30] = 0x00; config[31] = 0x80; |
2177 |
|
config[32] = 0x00; config[33] = 0x00; config[34] = 0x00; config[35] = 0x00; |
2178 |
|
config[36] = 0x00; config[37] = 0x10; config[38] = 0x00; config[39] = 0x00; |
2179 |
|
|
2180 |
|
/* |
2181 |
|
type: DMA |
2182 |
|
share_disposition: DeviceExclusive, flags: 0x0 |
2183 |
|
channel: 0, port: 0, reserved1: 0 |
2184 |
|
*/ |
2185 |
|
config[40] = arc_CmResourceTypeDMA; |
2186 |
|
config[41] = arc_CmResourceShareDeviceExclusive; |
2187 |
|
/* 42..43 = flags, 44,45,46,47 = channel, 48,49,50,51 = port, 52,53,54,55 |
2188 |
|
= reserved */ |
2189 |
|
|
2190 |
|
/* type: DeviceSpecific |
2191 |
|
share_disposition: DeviceExclusive, flags: 0x0 |
2192 |
|
datasize: 6, reserved1: 0, reserved2: 0 |
2193 |
|
data: [0x1:0x0:0x2:0x0:0x7:0x30] |
2194 |
|
*/ |
2195 |
|
config[56] = arc_CmResourceTypeDeviceSpecific; |
2196 |
|
config[57] = arc_CmResourceShareDeviceExclusive; |
2197 |
|
/* 58,59 = flags 60,61,62,63 = data size, 64..71 = reserved */ |
2198 |
|
config[60] = 6; |
2199 |
|
/* 72..77 = the data */ |
2200 |
|
config[72] = 0x01; config[73] = 0x00; config[74] = 0x02; |
2201 |
|
config[75] = 0x00; config[76] = 0x07; config[77] = 0x30; |
2202 |
|
scsi = arcbios_addchild_manual(cpu, |
2203 |
|
COMPONENT_CLASS_AdapterClass, |
2204 |
|
COMPONENT_TYPE_SCSIAdapter, |
2205 |
|
0, 1, 2, 0, 0xffffffff, "ESP216", |
2206 |
|
system, config, sizeof(config)); |
2207 |
|
|
2208 |
|
arcbios_register_scsicontroller(machine, scsi); |
2209 |
|
} |
2210 |
|
} |
2211 |
|
} |
2212 |
|
|
2213 |
|
|
2214 |
|
/* |
2215 |
|
* arcbios_console_init(): |
2216 |
|
* |
2217 |
|
* Called from machine.c whenever an ARC-based machine is running with |
2218 |
|
* a graphical VGA-style framebuffer, which can be used as console. |
2219 |
|
*/ |
2220 |
|
void arcbios_console_init(struct machine *machine, |
2221 |
|
uint64_t vram, uint64_t ctrlregs) |
2222 |
|
{ |
2223 |
|
machine->md.arc.vgaconsole = 1; |
2224 |
|
|
2225 |
|
machine->md.arc.console_vram = vram; |
2226 |
|
machine->md.arc.console_ctrlregs = ctrlregs; |
2227 |
|
machine->md.arc.console_maxx = ARC_CONSOLE_MAX_X; |
2228 |
|
machine->md.arc.console_maxy = ARC_CONSOLE_MAX_Y; |
2229 |
|
machine->md.arc.in_escape_sequence = 0; |
2230 |
|
machine->md.arc.escape_sequence[0] = '\0'; |
2231 |
|
} |
2232 |
|
|
2233 |
|
|
2234 |
|
/* |
2235 |
* arcbios_init(): |
* arcbios_init(): |
2236 |
* |
* |
2237 |
* Should be called before any other arcbios function is used. |
* Should be called before any other arcbios function is used. An exception |
2238 |
|
* is arcbios_console_init(), which may be called before this function. |
2239 |
*/ |
*/ |
2240 |
void arcbios_init(void) |
void arcbios_init(struct machine *machine, int is64bit, |
2241 |
|
uint64_t sgi_ram_offset) |
2242 |
{ |
{ |
2243 |
int i; |
int i, alloclen = 20; |
2244 |
|
char *name; |
2245 |
|
uint64_t arc_reserved, mem_base, mem_count; |
2246 |
|
struct cpu *cpu = machine->cpus[0]; |
2247 |
|
struct arcbios_sysid arcbios_sysid; |
2248 |
|
struct arcbios_dsp_stat arcbios_dsp_stat; |
2249 |
|
uint64_t system = 0; |
2250 |
|
struct arcbios_spb arcbios_spb; |
2251 |
|
struct arcbios_spb_64 arcbios_spb_64; |
2252 |
|
|
2253 |
|
machine->md.arc.arc_64bit = is64bit; |
2254 |
|
machine->md.arc.wordlen = is64bit? sizeof(uint64_t) : sizeof(uint32_t); |
2255 |
|
|
2256 |
|
machine->md.arc.next_component_address = FIRST_ARC_COMPONENT; |
2257 |
|
machine->md.arc.configuration_data_next_addr = ARC_CONFIG_DATA_ADDR; |
2258 |
|
|
2259 |
|
if (machine->physical_ram_in_mb < 16) |
2260 |
|
fprintf(stderr, "WARNING! The ARC platform specification " |
2261 |
|
"doesn't allow less than 16 MB of RAM. Continuing " |
2262 |
|
"anyway.\n"); |
2263 |
|
|
2264 |
/* File handles 0, 1, and 2 are stdin, stdout, and stderr. */ |
/* File handles 0, 1, and 2 are stdin, stdout, and stderr. */ |
2265 |
for (i=0; i<MAX_HANDLES; i++) { |
for (i=0; i<ARC_MAX_HANDLES; i++) { |
2266 |
file_handle_in_use[i] = i<3? 1 : 0; |
machine->md.arc.file_handle_in_use[i] = i<3? 1 : 0; |
2267 |
file_handle_string[i] = NULL; |
machine->md.arc.file_handle_string[i] = i>=3? NULL : |
2268 |
arcbios_current_seek_offset[i] = 0; |
(i==0? "(stdin)" : (i==1? "(stdout)" : "(stderr)")); |
2269 |
|
machine->md.arc.current_seek_offset[i] = 0; |
2270 |
|
} |
2271 |
|
|
2272 |
|
if (!machine->use_x11) |
2273 |
|
machine->md.arc.vgaconsole = 0; |
2274 |
|
|
2275 |
|
if (machine->md.arc.vgaconsole) { |
2276 |
|
char tmpstr[100]; |
2277 |
|
int x, y; |
2278 |
|
|
2279 |
|
machine->md.arc.console_curcolor = 0x1f; |
2280 |
|
for (y=0; y<machine->md.arc.console_maxy; y++) |
2281 |
|
for (x=0; x<machine->md.arc.console_maxx; x++) |
2282 |
|
arcbios_putcell(cpu, ' ', x, y); |
2283 |
|
|
2284 |
|
machine->md.arc.console_curx = 0; |
2285 |
|
machine->md.arc.console_cury = 0; |
2286 |
|
|
2287 |
|
arcbios_putstring(cpu, "GXemul"); |
2288 |
|
#ifdef VERSION |
2289 |
|
arcbios_putstring(cpu, " "VERSION); |
2290 |
|
#endif |
2291 |
|
arcbios_putstring(cpu, " ARCBIOS emulation\n"); |
2292 |
|
|
2293 |
|
sprintf(tmpstr, "%i cpu%s (%s), %i MB memory\n\n", |
2294 |
|
machine->ncpus, machine->ncpus > 1? "s" : "", |
2295 |
|
cpu->cd.mips.cpu_type.name, |
2296 |
|
machine->physical_ram_in_mb); |
2297 |
|
arcbios_putstring(cpu, tmpstr); |
2298 |
|
} |
2299 |
|
|
2300 |
|
arcbios_set_default_exception_handler(cpu); |
2301 |
|
|
2302 |
|
memset(&arcbios_sysid, 0, sizeof(arcbios_sysid)); |
2303 |
|
if (machine->machine_type == MACHINE_SGI) { |
2304 |
|
/* Vendor ID, max 8 chars: */ |
2305 |
|
strncpy(arcbios_sysid.VendorId, "SGI", 3); |
2306 |
|
switch (machine->machine_subtype) { |
2307 |
|
case 22: |
2308 |
|
strncpy(arcbios_sysid.ProductId, |
2309 |
|
"87654321", 8); /* some kind of ID? */ |
2310 |
|
break; |
2311 |
|
case 32: |
2312 |
|
strncpy(arcbios_sysid.ProductId, "8", 1); |
2313 |
|
/* 6 or 8 (?) */ |
2314 |
|
break; |
2315 |
|
default: |
2316 |
|
snprintf(arcbios_sysid.ProductId, 8, "IP%i", |
2317 |
|
machine->machine_subtype); |
2318 |
|
} |
2319 |
|
} else { |
2320 |
|
switch (machine->machine_subtype) { |
2321 |
|
case MACHINE_ARC_NEC_RD94: |
2322 |
|
strncpy(arcbios_sysid.VendorId, "NEC W&S", 8); |
2323 |
|
strncpy(arcbios_sysid.ProductId, "RD94", 4); |
2324 |
|
break; |
2325 |
|
case MACHINE_ARC_NEC_R94: |
2326 |
|
strncpy(arcbios_sysid.VendorId, "NEC W&S", 8); |
2327 |
|
strncpy(arcbios_sysid.ProductId, "ijkl", 4); |
2328 |
|
break; |
2329 |
|
case MACHINE_ARC_NEC_R96: |
2330 |
|
strncpy(arcbios_sysid.VendorId, "MIPS DUO", 8); |
2331 |
|
strncpy(arcbios_sysid.ProductId, "blahblah", 8); |
2332 |
|
break; |
2333 |
|
case MACHINE_ARC_NEC_R98: |
2334 |
|
strncpy(arcbios_sysid.VendorId, "NEC W&S", 8); |
2335 |
|
strncpy(arcbios_sysid.ProductId, "R98", 4); |
2336 |
|
break; |
2337 |
|
case MACHINE_ARC_JAZZ_PICA: |
2338 |
|
strncpy(arcbios_sysid.VendorId, "MIPS MAG", 8); |
2339 |
|
strncpy(arcbios_sysid.ProductId, "ijkl", 4); |
2340 |
|
break; |
2341 |
|
case MACHINE_ARC_JAZZ_MAGNUM: |
2342 |
|
strncpy(arcbios_sysid.VendorId, "MIPS MAG", 8); |
2343 |
|
strncpy(arcbios_sysid.ProductId, "ijkl", 4); |
2344 |
|
break; |
2345 |
|
case MACHINE_ARC_JAZZ_M700: |
2346 |
|
strncpy(arcbios_sysid.VendorId, "OLI00000", 8); |
2347 |
|
strncpy(arcbios_sysid.ProductId, "ijkl", 4); |
2348 |
|
break; |
2349 |
|
case MACHINE_ARC_DESKTECH_TYNE: |
2350 |
|
strncpy(arcbios_sysid.VendorId, "DESKTECH", 8); |
2351 |
|
strncpy(arcbios_sysid.ProductId, "ijkl", 4); |
2352 |
|
break; |
2353 |
|
default: |
2354 |
|
fatal("error in machine.c sysid\n"); |
2355 |
|
exit(1); |
2356 |
|
} |
2357 |
|
} |
2358 |
|
|
2359 |
|
store_buf(cpu, SGI_SYSID_ADDR, (char *)&arcbios_sysid, |
2360 |
|
sizeof(arcbios_sysid)); |
2361 |
|
|
2362 |
|
arcbios_get_dsp_stat(cpu, &arcbios_dsp_stat); |
2363 |
|
store_buf(cpu, ARC_DSPSTAT_ADDR, (char *)&arcbios_dsp_stat, |
2364 |
|
sizeof(arcbios_dsp_stat)); |
2365 |
|
|
2366 |
|
/* |
2367 |
|
* The first 12 MBs of RAM are simply reserved... this simplifies |
2368 |
|
* things a lot. If there's more than 512MB of RAM, it has to be |
2369 |
|
* split in two, according to the ARC spec. This code creates a |
2370 |
|
* number of chunks of at most 512MB each. |
2371 |
|
* |
2372 |
|
* NOTE: The region of physical address space between 0x10000000 and |
2373 |
|
* 0x1fffffff (256 - 512 MB) is usually occupied by memory mapped |
2374 |
|
* devices, so that portion is "lost". |
2375 |
|
*/ |
2376 |
|
machine->md.arc.memdescriptor_base = ARC_MEMDESC_ADDR; |
2377 |
|
|
2378 |
|
arc_reserved = 0x2000; |
2379 |
|
if (machine->machine_type == MACHINE_SGI) |
2380 |
|
arc_reserved = 0x4000; |
2381 |
|
|
2382 |
|
arcbios_add_memory_descriptor(cpu, 0, arc_reserved, |
2383 |
|
ARCBIOS_MEM_FirmwarePermanent); |
2384 |
|
arcbios_add_memory_descriptor(cpu, sgi_ram_offset + arc_reserved, |
2385 |
|
0x60000-arc_reserved, ARCBIOS_MEM_FirmwareTemporary); |
2386 |
|
|
2387 |
|
mem_base = 12; |
2388 |
|
mem_base += sgi_ram_offset / 1048576; |
2389 |
|
|
2390 |
|
while (mem_base < machine->physical_ram_in_mb+sgi_ram_offset/1048576) { |
2391 |
|
mem_count = machine->physical_ram_in_mb+sgi_ram_offset/1048576 |
2392 |
|
- mem_base; |
2393 |
|
|
2394 |
|
/* Skip the 256-512MB region (for devices) */ |
2395 |
|
if (mem_base < 256 && mem_base + mem_count > 256) { |
2396 |
|
mem_count = 256-mem_base; |
2397 |
|
} |
2398 |
|
|
2399 |
|
/* At most 512MB per descriptor (at least the first 512MB |
2400 |
|
must be separated this way, according to the ARC spec) */ |
2401 |
|
if (mem_count > 512) |
2402 |
|
mem_count = 512; |
2403 |
|
|
2404 |
|
arcbios_add_memory_descriptor(cpu, mem_base * 1048576, |
2405 |
|
mem_count * 1048576, ARCBIOS_MEM_FreeMemory); |
2406 |
|
|
2407 |
|
mem_base += mem_count; |
2408 |
|
|
2409 |
|
/* Skip the devices: */ |
2410 |
|
if (mem_base == 256) |
2411 |
|
mem_base = 512; |
2412 |
|
} |
2413 |
|
|
2414 |
|
/* |
2415 |
|
* Components: (this is an example of what a system could look like) |
2416 |
|
* |
2417 |
|
* [System] |
2418 |
|
* [CPU] (one for each cpu) |
2419 |
|
* [FPU] (one for each cpu) |
2420 |
|
* [CPU Caches] |
2421 |
|
* [Memory] |
2422 |
|
* [Ethernet] |
2423 |
|
* [Serial] |
2424 |
|
* [SCSI] |
2425 |
|
* [Disk] |
2426 |
|
* |
2427 |
|
* Here's a good list of what hardware is in different IP-models: |
2428 |
|
* http://www.linux-mips.org/archives/linux-mips/2001-03/msg00101.html |
2429 |
|
*/ |
2430 |
|
|
2431 |
|
if (machine->machine_name == NULL) |
2432 |
|
fatal("ERROR: machine_name == NULL\n"); |
2433 |
|
|
2434 |
|
/* Add the root node: */ |
2435 |
|
switch (machine->machine_type) { |
2436 |
|
case MACHINE_SGI: |
2437 |
|
name = malloc(alloclen); |
2438 |
|
if (name == NULL) { |
2439 |
|
fprintf(stderr, "out of memory\n"); |
2440 |
|
exit(1); |
2441 |
|
} |
2442 |
|
snprintf(name, alloclen, "SGI-IP%i", |
2443 |
|
machine->machine_subtype); |
2444 |
|
|
2445 |
|
/* A very special case for IP24 (which identifies itself |
2446 |
|
as an IP22): */ |
2447 |
|
if (machine->machine_subtype == 24) |
2448 |
|
sprintf(name, "SGI-IP22"); |
2449 |
|
break; |
2450 |
|
case MACHINE_ARC: |
2451 |
|
/* ARC: */ |
2452 |
|
switch (machine->machine_subtype) { |
2453 |
|
case MACHINE_ARC_NEC_RD94: |
2454 |
|
name = "NEC-RD94"; |
2455 |
|
break; |
2456 |
|
case MACHINE_ARC_NEC_R94: |
2457 |
|
name = "NEC-R94"; |
2458 |
|
break; |
2459 |
|
case MACHINE_ARC_NEC_R96: |
2460 |
|
name = "NEC-R96"; |
2461 |
|
break; |
2462 |
|
case MACHINE_ARC_NEC_R98: |
2463 |
|
name = "NEC-R98"; |
2464 |
|
break; |
2465 |
|
case MACHINE_ARC_JAZZ_PICA: |
2466 |
|
name = "PICA-61"; |
2467 |
|
break; |
2468 |
|
case MACHINE_ARC_JAZZ_MAGNUM: |
2469 |
|
case MACHINE_ARC_JAZZ_M700: |
2470 |
|
name = "Microsoft-Jazz"; |
2471 |
|
break; |
2472 |
|
case MACHINE_ARC_DESKTECH_TYNE: |
2473 |
|
name = "DESKTECH-TYNE"; |
2474 |
|
break; |
2475 |
|
default: |
2476 |
|
fatal("Unimplemented ARC machine type %i\n", |
2477 |
|
machine->machine_subtype); |
2478 |
|
exit(1); |
2479 |
|
} |
2480 |
|
break; |
2481 |
|
default: |
2482 |
|
fatal("ERROR: non-SGI and non-ARC?\n"); |
2483 |
|
exit(1); |
2484 |
|
} |
2485 |
|
|
2486 |
|
system = arcbios_addchild_manual(cpu, COMPONENT_CLASS_SystemClass, |
2487 |
|
COMPONENT_TYPE_ARC, 0,1,2,0, 0xffffffff, name, 0/*ROOT*/, NULL, 0); |
2488 |
|
debug("ARC system @ 0x%llx (\"%s\")\n", (long long)system, name); |
2489 |
|
|
2490 |
|
|
2491 |
|
/* |
2492 |
|
* Add tree nodes for CPUs and their caches: |
2493 |
|
*/ |
2494 |
|
|
2495 |
|
for (i=0; i<machine->ncpus; i++) { |
2496 |
|
uint64_t cpuaddr, fpu=0, picache, pdcache, sdcache=0; |
2497 |
|
int cache_size, cache_line_size; |
2498 |
|
unsigned int jj; |
2499 |
|
char arc_cpu_name[100]; |
2500 |
|
char arc_fpc_name[105]; |
2501 |
|
|
2502 |
|
snprintf(arc_cpu_name, sizeof(arc_cpu_name), |
2503 |
|
"MIPS-%s", machine->cpu_name); |
2504 |
|
|
2505 |
|
if (machine->machine_type == MACHINE_ARC && |
2506 |
|
machine->machine_subtype == MACHINE_ARC_NEC_R96) |
2507 |
|
snprintf(arc_cpu_name, sizeof(arc_cpu_name), |
2508 |
|
"MIPS-%s - Pr 4/5.0, Fp 5/0", machine->cpu_name); |
2509 |
|
|
2510 |
|
arc_cpu_name[sizeof(arc_cpu_name)-1] = 0; |
2511 |
|
for (jj=0; jj<strlen(arc_cpu_name); jj++) |
2512 |
|
if (arc_cpu_name[jj] >= 'a' && arc_cpu_name[jj] <= 'z') |
2513 |
|
arc_cpu_name[jj] += ('A' - 'a'); |
2514 |
|
|
2515 |
|
strcpy(arc_fpc_name, arc_cpu_name); |
2516 |
|
strcat(arc_fpc_name, "FPC"); |
2517 |
|
|
2518 |
|
cpuaddr = arcbios_addchild_manual(cpu, |
2519 |
|
COMPONENT_CLASS_ProcessorClass, COMPONENT_TYPE_CPU, |
2520 |
|
0, 1, 2, i, 0xffffffff, arc_cpu_name, system, NULL, 0); |
2521 |
|
|
2522 |
|
/* |
2523 |
|
* TODO: This was in the ARC specs, but it isn't really used |
2524 |
|
* by ARC implementations? At least SGI-IP32 uses it. |
2525 |
|
*/ |
2526 |
|
if (machine->machine_type == MACHINE_SGI) |
2527 |
|
fpu = arcbios_addchild_manual(cpu, |
2528 |
|
COMPONENT_CLASS_ProcessorClass, COMPONENT_TYPE_FPU, |
2529 |
|
0, 1, 2, 0, 0xffffffff, arc_fpc_name, cpuaddr, |
2530 |
|
NULL, 0); |
2531 |
|
|
2532 |
|
cache_size = DEFAULT_PCACHE_SIZE - 12; |
2533 |
|
if (machine->cache_picache) |
2534 |
|
cache_size = machine->cache_picache - 12; |
2535 |
|
if (cache_size < 0) |
2536 |
|
cache_size = 0; |
2537 |
|
|
2538 |
|
cache_line_size = DEFAULT_PCACHE_LINESIZE; |
2539 |
|
if (machine->cache_picache_linesize) |
2540 |
|
cache_line_size = machine->cache_picache_linesize; |
2541 |
|
if (cache_line_size < 0) |
2542 |
|
cache_line_size = 0; |
2543 |
|
|
2544 |
|
picache = arcbios_addchild_manual(cpu, |
2545 |
|
COMPONENT_CLASS_CacheClass, COMPONENT_TYPE_PrimaryICache, |
2546 |
|
0, 1, 2, |
2547 |
|
/* |
2548 |
|
* Key bits: 0xXXYYZZZZ |
2549 |
|
* XX is refill-size. |
2550 |
|
* Cache line size is 1 << YY, |
2551 |
|
* Cache size is 4KB << ZZZZ. |
2552 |
|
*/ |
2553 |
|
0x01000000 + (cache_line_size << 16) + cache_size, |
2554 |
|
/* 32 bytes per line, default = 32 KB total */ |
2555 |
|
0xffffffff, NULL, cpuaddr, NULL, 0); |
2556 |
|
|
2557 |
|
cache_size = DEFAULT_PCACHE_SIZE - 12; |
2558 |
|
if (machine->cache_pdcache) |
2559 |
|
cache_size = machine->cache_pdcache - 12; |
2560 |
|
if (cache_size < 0) |
2561 |
|
cache_size = 0; |
2562 |
|
|
2563 |
|
cache_line_size = DEFAULT_PCACHE_LINESIZE; |
2564 |
|
if (machine->cache_pdcache_linesize) |
2565 |
|
cache_line_size = machine->cache_pdcache_linesize; |
2566 |
|
if (cache_line_size < 0) |
2567 |
|
cache_line_size = 0; |
2568 |
|
|
2569 |
|
pdcache = arcbios_addchild_manual(cpu, |
2570 |
|
COMPONENT_CLASS_CacheClass, |
2571 |
|
COMPONENT_TYPE_PrimaryDCache, 0, 1, 2, |
2572 |
|
/* |
2573 |
|
* Key bits: 0xYYZZZZ |
2574 |
|
* Cache line size is 1 << YY, |
2575 |
|
* Cache size is 4KB << ZZZZ. |
2576 |
|
*/ |
2577 |
|
0x01000000 + (cache_line_size << 16) + cache_size, |
2578 |
|
/* 32 bytes per line, default = 32 KB total */ |
2579 |
|
0xffffffff, NULL, cpuaddr, NULL, 0); |
2580 |
|
|
2581 |
|
if (machine->cache_secondary >= 12) { |
2582 |
|
cache_size = machine->cache_secondary - 12; |
2583 |
|
|
2584 |
|
cache_line_size = 6; /* 64 bytes default */ |
2585 |
|
if (machine->cache_secondary_linesize) |
2586 |
|
cache_line_size = machine-> |
2587 |
|
cache_secondary_linesize; |
2588 |
|
if (cache_line_size < 0) |
2589 |
|
cache_line_size = 0; |
2590 |
|
|
2591 |
|
sdcache = arcbios_addchild_manual(cpu, |
2592 |
|
COMPONENT_CLASS_CacheClass, |
2593 |
|
COMPONENT_TYPE_SecondaryDCache, 0, 1, 2, |
2594 |
|
/* |
2595 |
|
* Key bits: 0xYYZZZZ |
2596 |
|
* Cache line size is 1 << YY, |
2597 |
|
* Cache size is 4KB << ZZZZ. |
2598 |
|
*/ |
2599 |
|
0x01000000 + (cache_line_size << 16) + cache_size, |
2600 |
|
/* 64 bytes per line, default = 1 MB total */ |
2601 |
|
0xffffffff, NULL, cpuaddr, NULL, 0); |
2602 |
|
} |
2603 |
|
|
2604 |
|
debug("ARC cpu%i @ 0x%llx", i, (long long)cpuaddr); |
2605 |
|
|
2606 |
|
if (fpu != 0) |
2607 |
|
debug(" (fpu @ 0x%llx)\n", (long long)fpu); |
2608 |
|
else |
2609 |
|
debug("\n"); |
2610 |
|
|
2611 |
|
debug(" picache @ 0x%llx, pdcache @ 0x%llx\n", |
2612 |
|
(long long)picache, (long long)pdcache); |
2613 |
|
|
2614 |
|
if (machine->cache_secondary >= 12) |
2615 |
|
debug(" sdcache @ 0x%llx\n", |
2616 |
|
(long long)sdcache); |
2617 |
|
|
2618 |
|
if (machine->machine_type == MACHINE_SGI) { |
2619 |
|
/* TODO: Memory amount (and base address?)! */ |
2620 |
|
uint64_t memory = arcbios_addchild_manual(cpu, |
2621 |
|
COMPONENT_CLASS_MemoryClass, |
2622 |
|
COMPONENT_TYPE_MemoryUnit, 0, 1, 2, 0, |
2623 |
|
0xffffffff, "memory", cpuaddr, NULL, 0); |
2624 |
|
debug("ARC memory @ 0x%llx\n", (long long)memory); |
2625 |
|
} |
2626 |
|
} |
2627 |
|
|
2628 |
|
|
2629 |
|
/* |
2630 |
|
* Add other components: |
2631 |
|
* |
2632 |
|
* TODO: How should this be synched with the hardware devices |
2633 |
|
* added in machine.c? |
2634 |
|
*/ |
2635 |
|
|
2636 |
|
arcbios_add_other_components(machine, system); |
2637 |
|
|
2638 |
|
|
2639 |
|
/* |
2640 |
|
* Defalt TLB entry for 64-bit SGI machines: |
2641 |
|
*/ |
2642 |
|
if (machine->machine_type == MACHINE_SGI) { |
2643 |
|
/* TODO: On which models is this required? */ |
2644 |
|
mips_coproc_tlb_set_entry(cpu, 0, 1048576*16, |
2645 |
|
0xc000000000000000ULL, 0, 1048576*16, 1,1,1,1,1, 0, 2, 2); |
2646 |
|
} |
2647 |
|
|
2648 |
|
|
2649 |
|
/* |
2650 |
|
* Set up Firmware Vectors: |
2651 |
|
*/ |
2652 |
|
add_symbol_name(&machine->symbol_context, |
2653 |
|
ARC_FIRMWARE_ENTRIES, 0x10000, "[ARCBIOS entry]", 0); |
2654 |
|
|
2655 |
|
for (i=0; i<100; i++) { |
2656 |
|
if (is64bit) { |
2657 |
|
store_64bit_word(cpu, ARC_FIRMWARE_VECTORS + i*8, |
2658 |
|
ARC_FIRMWARE_ENTRIES + i*8); |
2659 |
|
store_64bit_word(cpu, ARC_PRIVATE_VECTORS + i*8, |
2660 |
|
ARC_PRIVATE_ENTRIES + i*8); |
2661 |
|
} else { |
2662 |
|
store_32bit_word(cpu, ARC_FIRMWARE_VECTORS + i*4, |
2663 |
|
ARC_FIRMWARE_ENTRIES + i*4); |
2664 |
|
store_32bit_word(cpu, ARC_PRIVATE_VECTORS + i*4, |
2665 |
|
ARC_PRIVATE_ENTRIES + i*4); |
2666 |
|
} |
2667 |
|
} |
2668 |
|
|
2669 |
|
|
2670 |
|
/* |
2671 |
|
* Set up the ARC SPD: |
2672 |
|
*/ |
2673 |
|
if (is64bit) { |
2674 |
|
/* ARCS64 SPD (TODO: This is just a guess) */ |
2675 |
|
memset(&arcbios_spb_64, 0, sizeof(arcbios_spb_64)); |
2676 |
|
store_64bit_word_in_host(cpu, (unsigned char *) |
2677 |
|
&arcbios_spb_64.SPBSignature, ARCBIOS_SPB_SIGNATURE); |
2678 |
|
store_16bit_word_in_host(cpu, (unsigned char *) |
2679 |
|
&arcbios_spb_64.Version, 64); |
2680 |
|
store_16bit_word_in_host(cpu, (unsigned char *) |
2681 |
|
&arcbios_spb_64.Revision, 0); |
2682 |
|
store_64bit_word_in_host(cpu, (unsigned char *) |
2683 |
|
&arcbios_spb_64.FirmwareVector, ARC_FIRMWARE_VECTORS); |
2684 |
|
store_buf(cpu, SGI_SPB_ADDR, (char *)&arcbios_spb_64, |
2685 |
|
sizeof(arcbios_spb_64)); |
2686 |
|
} else { |
2687 |
|
/* ARCBIOS SPB: (For ARC and 32-bit SGI modes) */ |
2688 |
|
memset(&arcbios_spb, 0, sizeof(arcbios_spb)); |
2689 |
|
store_32bit_word_in_host(cpu, (unsigned char *) |
2690 |
|
&arcbios_spb.SPBSignature, ARCBIOS_SPB_SIGNATURE); |
2691 |
|
store_32bit_word_in_host(cpu, (unsigned char *) |
2692 |
|
&arcbios_spb.SPBLength, sizeof(arcbios_spb)); |
2693 |
|
store_16bit_word_in_host(cpu, (unsigned char *) |
2694 |
|
&arcbios_spb.Version, 1); |
2695 |
|
store_16bit_word_in_host(cpu, (unsigned char *) |
2696 |
|
&arcbios_spb.Revision, machine->machine_type == |
2697 |
|
MACHINE_SGI? 10 : 2); |
2698 |
|
store_32bit_word_in_host(cpu, (unsigned char *) |
2699 |
|
&arcbios_spb.FirmwareVector, ARC_FIRMWARE_VECTORS); |
2700 |
|
store_32bit_word_in_host(cpu, (unsigned char *) |
2701 |
|
&arcbios_spb.FirmwareVectorLength, 100 * 4); /* ? */ |
2702 |
|
store_32bit_word_in_host(cpu, (unsigned char *) |
2703 |
|
&arcbios_spb.PrivateVector, ARC_PRIVATE_VECTORS); |
2704 |
|
store_32bit_word_in_host(cpu, (unsigned char *) |
2705 |
|
&arcbios_spb.PrivateVectorLength, 100 * 4); /* ? */ |
2706 |
|
store_buf(cpu, SGI_SPB_ADDR, (char *)&arcbios_spb, |
2707 |
|
sizeof(arcbios_spb)); |
2708 |
} |
} |
2709 |
} |
} |
2710 |
|
|