25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: yamon.c,v 1.3 2006/02/16 05:57:10 debug Exp $ |
* $Id: yamon.c,v 1.8 2006/08/22 16:07:34 debug Exp $ |
29 |
* |
* |
30 |
* YAMON emulation. |
* YAMON emulation. (Very basic, only what is needed to get NetBSD booting.) |
31 |
*/ |
*/ |
32 |
|
|
33 |
#include <stdio.h> |
#include <stdio.h> |
41 |
#include "machine.h" |
#include "machine.h" |
42 |
#include "memory.h" |
#include "memory.h" |
43 |
#include "misc.h" |
#include "misc.h" |
44 |
|
#include "net.h" |
45 |
|
|
46 |
#ifdef ENABLE_MIPS |
#ifdef ENABLE_MIPS |
47 |
|
|
48 |
|
#include "yamon.h" |
49 |
|
|
50 |
|
|
51 |
/* |
/* |
52 |
* mem_readchar(): |
* yamon_machine_setup(): |
|
* |
|
|
* Reads a byte from emulated RAM, using a MIPS register as a base address. |
|
|
* (Helper function.) |
|
53 |
*/ |
*/ |
54 |
static unsigned char mem_readchar(struct cpu *cpu, int regbase, int offset) |
void yamon_machine_setup(struct machine *machine, uint64_t env) |
55 |
{ |
{ |
56 |
unsigned char ch; |
char tmps[200]; |
57 |
cpu->memory_rw(cpu, cpu->mem, cpu->cd.mips.gpr[regbase] + offset, |
char macaddr[6]; |
58 |
&ch, sizeof(ch), MEM_READ, CACHE_DATA | NO_EXCEPTIONS); |
uint64_t tmpptr = env + 0x400; |
59 |
return ch; |
struct cpu *cpu = machine->cpus[0]; |
60 |
|
|
61 |
|
/* |
62 |
|
* Standard YAMON environment variables: |
63 |
|
* |
64 |
|
* baseboardserial |
65 |
|
* bootfile TODO |
66 |
|
* bootprot TODO: Non-tftp boot |
67 |
|
* bootserport |
68 |
|
* bootserver |
69 |
|
* cpuconfig TODO |
70 |
|
* ethaddr |
71 |
|
* fpu TODO |
72 |
|
* gateway |
73 |
|
* ipaddr TODO: Don't hardcode! |
74 |
|
* memsize |
75 |
|
* modetty0 |
76 |
|
* modetty1 |
77 |
|
* prompt |
78 |
|
* start TODO |
79 |
|
* startdelay TODO |
80 |
|
* subnetmask TODO: Real subnet mask |
81 |
|
* yamonrev |
82 |
|
*/ |
83 |
|
|
84 |
|
add_environment_string_dual(cpu, &env, &tmpptr, |
85 |
|
"baseboardserial", "0000000000"); |
86 |
|
|
87 |
|
/* TODO: Disk boot! */ |
88 |
|
add_environment_string_dual(cpu, &env, &tmpptr, "bootprot", "tftp"); |
89 |
|
|
90 |
|
add_environment_string_dual(cpu, &env, &tmpptr, "bootserport", "tty0"); |
91 |
|
|
92 |
|
add_environment_string_dual(cpu, &env, &tmpptr, |
93 |
|
"bootserver", "10.0.0.254"); |
94 |
|
|
95 |
|
net_generate_unique_mac(machine, (unsigned char *) macaddr); |
96 |
|
snprintf(tmps, sizeof(tmps), "%02x.%02x.%02x.%02x.%02x.%02x", |
97 |
|
macaddr[0], macaddr[1], macaddr[2], |
98 |
|
macaddr[3], macaddr[4], macaddr[5]); |
99 |
|
add_environment_string_dual(cpu, &env, &tmpptr, "ethaddr", tmps); |
100 |
|
|
101 |
|
add_environment_string_dual(cpu, &env, &tmpptr, |
102 |
|
"gateway", "10.0.0.254"); |
103 |
|
|
104 |
|
/* TODO: Don't hardcode! */ |
105 |
|
add_environment_string_dual(cpu, &env, &tmpptr, |
106 |
|
"ipaddr", "10.0.0.1"); |
107 |
|
|
108 |
|
snprintf(tmps, sizeof(tmps), "0x%08x", machine->physical_ram_in_mb<<20); |
109 |
|
add_environment_string_dual(cpu, &env, &tmpptr, "memsize", tmps); |
110 |
|
|
111 |
|
add_environment_string_dual(cpu, &env, &tmpptr, |
112 |
|
"modetty0", "38400,n,8,1,none"); |
113 |
|
|
114 |
|
add_environment_string_dual(cpu, &env, &tmpptr, |
115 |
|
"modetty1", "38400,n,8,1,none"); |
116 |
|
|
117 |
|
add_environment_string_dual(cpu, &env, &tmpptr, "prompt", "YAMON"); |
118 |
|
|
119 |
|
add_environment_string_dual(cpu, &env, &tmpptr, "yamonrev", "02.06"); |
120 |
|
|
121 |
|
/* TODO: Real subnet mask: */ |
122 |
|
add_environment_string_dual(cpu, &env, &tmpptr, |
123 |
|
"subnetmask", "255.0.0.0"); |
124 |
|
|
125 |
|
|
126 |
|
/* FreeBSD development specific: */ |
127 |
|
snprintf(tmps, sizeof(tmps), "%i", machine->emulated_hz / 1000); |
128 |
|
add_environment_string_dual(cpu, &env, &tmpptr, "khz", tmps); |
129 |
|
|
130 |
|
/* NULL terminate: */ |
131 |
|
tmpptr = 0; |
132 |
|
add_environment_string_dual(cpu, &env, &tmpptr, NULL, NULL); |
133 |
} |
} |
134 |
|
|
135 |
|
|
140 |
*/ |
*/ |
141 |
int yamon_emul(struct cpu *cpu) |
int yamon_emul(struct cpu *cpu) |
142 |
{ |
{ |
143 |
int ofs = cpu->pc & 0xfff; |
uint32_t ofs = (cpu->pc & 0xff) + YAMON_FUNCTION_BASE; |
144 |
|
uint8_t ch; |
145 |
int n; |
int n; |
146 |
|
|
147 |
switch (ofs) { |
switch (ofs) { |
148 |
case 0x804: /* "print count": string at a1, count at a2 */ |
|
149 |
|
case YAMON_PRINT_COUNT_OFS: |
150 |
|
/* |
151 |
|
* print count: |
152 |
|
* a1 = string |
153 |
|
* a2 = count |
154 |
|
*/ |
155 |
n = 0; |
n = 0; |
156 |
while (n < (int)cpu->cd.mips.gpr[MIPS_GPR_A2]) { |
while (n < (int32_t)cpu->cd.mips.gpr[MIPS_GPR_A2]) { |
157 |
char ch = mem_readchar(cpu, MIPS_GPR_A1, n); |
cpu->memory_rw(cpu, cpu->mem, (int32_t)cpu->cd.mips.gpr |
158 |
console_putchar(cpu->machine->main_console_handle, |
[MIPS_GPR_A1] + n, &ch, sizeof(ch), MEM_READ, |
159 |
ch); |
CACHE_DATA | NO_EXCEPTIONS); |
160 |
|
console_putchar(cpu->machine->main_console_handle, ch); |
161 |
n++; |
n++; |
162 |
} |
} |
163 |
break; |
break; |
164 |
case 0x820: /* "exit" */ |
|
165 |
debug("[ yamon_emul(): exit ]\n"); |
case YAMON_EXIT_OFS: |
166 |
|
/* |
167 |
|
* exit |
168 |
|
*/ |
169 |
|
debug("[ yamon_emul(): exit ]\n"); |
170 |
cpu->running = 0; |
cpu->running = 0; |
171 |
break; |
break; |
172 |
case 0x854: /* "syscon" */ |
|
173 |
|
/* YAMON_FLUSH_CACHE_OFS: TODO */ |
174 |
|
/* YAMON_PRINT_OFS: TODO */ |
175 |
|
/* YAMON_REG_CPU_ISR_OFS: TODO */ |
176 |
|
/* YAMON_DEREG_CPU_ISR_OFS: TODO */ |
177 |
|
/* YAMON_REG_IC_ISR_OFS: TODO */ |
178 |
|
/* YAMON_DEREG_IC_ISR_OFS: TODO */ |
179 |
|
/* YAMON_REG_ESR_OFS: TODO */ |
180 |
|
/* YAMON_DEREG_ESR_OFS: TODO */ |
181 |
|
|
182 |
|
case YAMON_GETCHAR_OFS: |
183 |
|
n = console_readchar(cpu->machine->main_console_handle); |
184 |
|
/* Note: -1 (if no char was available) becomes 0xff: */ |
185 |
|
ch = n; |
186 |
|
cpu->memory_rw(cpu, cpu->mem, (int32_t)cpu->cd.mips.gpr[ |
187 |
|
MIPS_GPR_A1], &ch, sizeof(ch), MEM_WRITE, |
188 |
|
CACHE_DATA | NO_EXCEPTIONS); |
189 |
|
break; |
190 |
|
|
191 |
|
case YAMON_SYSCON_READ_OFS: |
192 |
|
/* |
193 |
|
* syscon |
194 |
|
*/ |
195 |
fatal("[ yamon_emul(): syscon: TODO ]\n"); |
fatal("[ yamon_emul(): syscon: TODO ]\n"); |
196 |
|
|
197 |
/* TODO. For now, return some kind of "failure": */ |
/* TODO. For now, return some kind of "failure": */ |
198 |
cpu->cd.mips.gpr[MIPS_GPR_V0] = 1; |
cpu->cd.mips.gpr[MIPS_GPR_V0] = 1; |
199 |
break; |
break; |
200 |
|
|
201 |
default:cpu_register_dump(cpu->machine, cpu, 1, 0); |
default:cpu_register_dump(cpu->machine, cpu, 1, 0); |
202 |
printf("\n"); |
printf("\n"); |
203 |
fatal("[ yamon_emul(): unimplemented ofs 0x%x ]\n", ofs); |
fatal("[ yamon_emul(): unimplemented yamon function 0x%" |
204 |
|
PRIx32" ]\n", ofs); |
205 |
cpu->running = 0; |
cpu->running = 0; |
|
cpu->dead = 1; |
|
206 |
} |
} |
207 |
|
|
208 |
return 1; |
return 1; |