--- trunk/src/promemul/yamon.c 2007/10/08 16:19:37 22 +++ trunk/src/promemul/yamon.c 2007/10/08 16:20:58 32 @@ -25,9 +25,9 @@ * SUCH DAMAGE. * * - * $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 $ * - * YAMON emulation. + * YAMON emulation. (Very basic, only what is needed to get NetBSD booting.) */ #include @@ -41,22 +41,95 @@ #include "machine.h" #include "memory.h" #include "misc.h" - +#include "net.h" #ifdef ENABLE_MIPS +#include "yamon.h" + + /* - * mem_readchar(): - * - * Reads a byte from emulated RAM, using a MIPS register as a base address. - * (Helper function.) + * yamon_machine_setup(): */ -static unsigned char mem_readchar(struct cpu *cpu, int regbase, int offset) +void yamon_machine_setup(struct machine *machine, uint64_t env) { - unsigned char ch; - cpu->memory_rw(cpu, cpu->mem, cpu->cd.mips.gpr[regbase] + offset, - &ch, sizeof(ch), MEM_READ, CACHE_DATA | NO_EXCEPTIONS); - return ch; + char tmps[200]; + char macaddr[6]; + uint64_t tmpptr = env + 0x400; + struct cpu *cpu = machine->cpus[0]; + + /* + * Standard YAMON environment variables: + * + * baseboardserial + * bootfile TODO + * bootprot TODO: Non-tftp boot + * bootserport + * bootserver + * cpuconfig TODO + * ethaddr + * fpu TODO + * gateway + * ipaddr TODO: Don't hardcode! + * memsize + * modetty0 + * modetty1 + * prompt + * start TODO + * startdelay TODO + * subnetmask TODO: Real subnet mask + * yamonrev + */ + + add_environment_string_dual(cpu, &env, &tmpptr, + "baseboardserial", "0000000000"); + + /* TODO: Disk boot! */ + add_environment_string_dual(cpu, &env, &tmpptr, "bootprot", "tftp"); + + add_environment_string_dual(cpu, &env, &tmpptr, "bootserport", "tty0"); + + add_environment_string_dual(cpu, &env, &tmpptr, + "bootserver", "10.0.0.254"); + + net_generate_unique_mac(machine, (unsigned char *) macaddr); + snprintf(tmps, sizeof(tmps), "%02x.%02x.%02x.%02x.%02x.%02x", + macaddr[0], macaddr[1], macaddr[2], + macaddr[3], macaddr[4], macaddr[5]); + add_environment_string_dual(cpu, &env, &tmpptr, "ethaddr", tmps); + + add_environment_string_dual(cpu, &env, &tmpptr, + "gateway", "10.0.0.254"); + + /* TODO: Don't hardcode! */ + add_environment_string_dual(cpu, &env, &tmpptr, + "ipaddr", "10.0.0.1"); + + snprintf(tmps, sizeof(tmps), "0x%08x", machine->physical_ram_in_mb<<20); + add_environment_string_dual(cpu, &env, &tmpptr, "memsize", tmps); + + add_environment_string_dual(cpu, &env, &tmpptr, + "modetty0", "38400,n,8,1,none"); + + add_environment_string_dual(cpu, &env, &tmpptr, + "modetty1", "38400,n,8,1,none"); + + add_environment_string_dual(cpu, &env, &tmpptr, "prompt", "YAMON"); + + add_environment_string_dual(cpu, &env, &tmpptr, "yamonrev", "02.06"); + + /* TODO: Real subnet mask: */ + add_environment_string_dual(cpu, &env, &tmpptr, + "subnetmask", "255.0.0.0"); + + + /* FreeBSD development specific: */ + snprintf(tmps, sizeof(tmps), "%i", machine->emulated_hz / 1000); + add_environment_string_dual(cpu, &env, &tmpptr, "khz", tmps); + + /* NULL terminate: */ + tmpptr = 0; + add_environment_string_dual(cpu, &env, &tmpptr, NULL, NULL); } @@ -67,33 +140,69 @@ */ int yamon_emul(struct cpu *cpu) { - int ofs = cpu->pc & 0xfff; + uint32_t ofs = (cpu->pc & 0xff) + YAMON_FUNCTION_BASE; + uint8_t ch; int n; switch (ofs) { - case 0x804: /* "print count": string at a1, count at a2 */ + + case YAMON_PRINT_COUNT_OFS: + /* + * print count: + * a1 = string + * a2 = count + */ n = 0; - while (n < (int)cpu->cd.mips.gpr[MIPS_GPR_A2]) { - char ch = mem_readchar(cpu, MIPS_GPR_A1, n); - console_putchar(cpu->machine->main_console_handle, - ch); + while (n < (int32_t)cpu->cd.mips.gpr[MIPS_GPR_A2]) { + cpu->memory_rw(cpu, cpu->mem, (int32_t)cpu->cd.mips.gpr + [MIPS_GPR_A1] + n, &ch, sizeof(ch), MEM_READ, + CACHE_DATA | NO_EXCEPTIONS); + console_putchar(cpu->machine->main_console_handle, ch); n++; } break; - case 0x820: /* "exit" */ - debug("[ yamon_emul(): exit ]\n"); + + case YAMON_EXIT_OFS: + /* + * exit + */ + debug("[ yamon_emul(): exit ]\n"); cpu->running = 0; break; - case 0x854: /* "syscon" */ + + /* YAMON_FLUSH_CACHE_OFS: TODO */ + /* YAMON_PRINT_OFS: TODO */ + /* YAMON_REG_CPU_ISR_OFS: TODO */ + /* YAMON_DEREG_CPU_ISR_OFS: TODO */ + /* YAMON_REG_IC_ISR_OFS: TODO */ + /* YAMON_DEREG_IC_ISR_OFS: TODO */ + /* YAMON_REG_ESR_OFS: TODO */ + /* YAMON_DEREG_ESR_OFS: TODO */ + + case YAMON_GETCHAR_OFS: + n = console_readchar(cpu->machine->main_console_handle); + /* Note: -1 (if no char was available) becomes 0xff: */ + ch = n; + cpu->memory_rw(cpu, cpu->mem, (int32_t)cpu->cd.mips.gpr[ + MIPS_GPR_A1], &ch, sizeof(ch), MEM_WRITE, + CACHE_DATA | NO_EXCEPTIONS); + break; + + case YAMON_SYSCON_READ_OFS: + /* + * syscon + */ fatal("[ yamon_emul(): syscon: TODO ]\n"); + /* TODO. For now, return some kind of "failure": */ cpu->cd.mips.gpr[MIPS_GPR_V0] = 1; break; + default:cpu_register_dump(cpu->machine, cpu, 1, 0); printf("\n"); - fatal("[ yamon_emul(): unimplemented ofs 0x%x ]\n", ofs); + fatal("[ yamon_emul(): unimplemented yamon function 0x%" + PRIx32" ]\n", ofs); cpu->running = 0; - cpu->dead = 1; } return 1;