--- trunk/src/promemul/arcbios.c 2007/10/08 16:18:51 14 +++ trunk/src/promemul/arcbios.c 2007/10/08 16:20:26 28 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2005 Anders Gavare. All rights reserved. + * Copyright (C) 2003-2006 Anders Gavare. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: arcbios.c,v 1.1 2005/08/29 14:46:34 debug Exp $ + * $Id: arcbios.c,v 1.9 2006/06/30 20:22:54 debug Exp $ * * ARCBIOS emulation. */ @@ -451,7 +451,7 @@ /* * TODO: Huh? Why isn't it necessary to convert from arc to sgi types? * - * TODO 2: It seems that it _is_ neccessary, but NetBSD's arcdiag + * TODO 2: It seems that it _is_ necessary, but NetBSD's arcdiag * doesn't handle the sgi case separately. */ #if 1 @@ -699,8 +699,8 @@ uint64_t eparent, echild, epeer, tmp; unsigned char buf[8]; - /* debug("[ addchild: peeraddr = 0x%016llx ]\n", - (long long)peeraddr); */ + /* debug("[ addchild: peeraddr = 0x%016"PRIx64" ]\n", + (uint64_t) peeraddr); */ cpu->memory_rw(cpu, cpu->mem, peeraddr + 0 * machine->md.arc.wordlen, &buf[0], @@ -744,25 +744,25 @@ + ((uint64_t)buf[4] << 32) + ((uint64_t)buf[5] << 40) + ((uint64_t)buf[6] << 48) + ((uint64_t)buf[7] << 56); - /* debug(" epeer=%llx echild=%llx eparent=%llx\n", - (long long)epeer, (long long)echild, - (long long)eparent); */ + /* debug(" epeer=%"PRIx64" echild=%"PRIx64" eparent=%"PRIx64 + "\n", (uint64_t) epeer, (uint64_t) echild, + (uint64_t) eparent); */ if (eparent == parent && epeer == 0) { epeer = a; store_64bit_word(cpu, peeraddr + 0 * machine->md.arc.wordlen, epeer); - /* debug("[ addchild: adding 0x%016llx as peer " - "to 0x%016llx ]\n", (long long)a, - (long long)peeraddr); */ + /* debug("[ addchild: adding 0x%016"PRIx64" as peer " + "to 0x%016"PRIx64" ]\n", (uint64_t) a, + (uint64_t) peeraddr); */ } if (peeraddr == parent && echild == 0) { echild = a; store_64bit_word(cpu, peeraddr + 1 * machine->md.arc.wordlen, echild); - /* debug("[ addchild: adding 0x%016llx as child " - "to 0x%016llx ]\n", (long long)a, - (long long)peeraddr); */ + /* debug("[ addchild: adding 0x%016"PRIx64" as child " + "to 0x%016"PRIx64" ]\n", (uint64_t) a, + (uint64_t) peeraddr); */ } /* Go to the next component: */ @@ -843,7 +843,7 @@ if (config_data != NULL) { unsigned char *p = config_data; - int i; + size_t i; if (machine->md.arc.n_configuration_data >= MAX_CONFIG_DATA) { printf("fatal error: you need to increase " @@ -869,12 +869,12 @@ machine->md.arc.next_component_address + (cpu->machine->md.arc.arc_64bit? 0x18 : 0x0c); - /* printf("& ADDING %i: configdata=0x%016llx " - "component=0x%016llx\n", + /* printf("& ADDING %i: configdata=0x%016"PRIx64" " + "component=0x%016"PRIx64"\n", machine->md.arc.n_configuration_data, - (long long)machine->md.arc.configuration_data_configdata[ + (uint64_t) machine->md.arc.configuration_data_configdata[ machine->md.arc.n_configuration_data], - (long long)machine->md.arc.configuration_data_component[ + (uint64_t) machine->md.arc.configuration_data_component[ machine->md.arc.n_configuration_data]); */ machine->md.arc.n_configuration_data ++; @@ -947,15 +947,15 @@ ugly_goto: *start = 0; *size = 0; - /* printf("reading MSDOS partition from offset 0x%llx\n", - (long long)offset); */ + /* printf("reading MSDOS partition from offset 0x%"PRIx64"\n", + (uint64_t) offset); */ res = diskimage_access(machine, disk_id, disk_type, 0, offset, sector, sizeof(sector)); if (!res) { fatal("[ arcbios_get_msdos_partition_size(): couldn't " - "read the disk image, id %i, offset 0x%llx ]\n", - disk_id, (long long)offset); + "read the disk image, id %i, offset 0x%"PRIx64" ]\n", + disk_id, (uint64_t) offset); return; } @@ -1239,9 +1239,9 @@ cpu->cd.mips.gpr[MIPS_GPR_V0] = (int64_t) (int32_t) cpu->cd.mips.gpr[MIPS_GPR_V0]; } - debug("[ ARCBIOS GetPeer(node 0x%016llx): 0x%016llx ]\n", - (long long)cpu->cd.mips.gpr[MIPS_GPR_A0], - (long long)cpu->cd.mips.gpr[MIPS_GPR_V0]); + debug("[ ARCBIOS GetPeer(node 0x%016"PRIx64"): 0x%016"PRIx64 + " ]\n", (uint64_t) cpu->cd.mips.gpr[MIPS_GPR_A0], + (uint64_t) cpu->cd.mips.gpr[MIPS_GPR_V0]); break; case 0x28: /* GetChild(node) */ /* 0 for the root, non-0 for children: */ @@ -1290,9 +1290,9 @@ cpu->cd.mips.gpr[MIPS_GPR_V0] = (int64_t) (int32_t)cpu->cd.mips.gpr[MIPS_GPR_V0]; } - debug("[ ARCBIOS GetChild(node 0x%016llx): 0x%016llx ]\n", - (long long)cpu->cd.mips.gpr[MIPS_GPR_A0], - (long long)cpu->cd.mips.gpr[MIPS_GPR_V0]); + debug("[ ARCBIOS GetChild(node 0x%016"PRIx64"): 0x%016" + PRIx64" ]\n", (uint64_t) cpu->cd.mips.gpr[MIPS_GPR_A0], + (uint64_t) cpu->cd.mips.gpr[MIPS_GPR_V0]); break; case 0x2c: /* GetParent(node) */ { @@ -1339,18 +1339,19 @@ cpu->cd.mips.gpr[MIPS_GPR_V0] = (int64_t) (int32_t) cpu->cd.mips.gpr[MIPS_GPR_V0]; } - debug("[ ARCBIOS GetParent(node 0x%016llx): 0x%016llx ]\n", - (long long)cpu->cd.mips.gpr[MIPS_GPR_A0], - (long long)cpu->cd.mips.gpr[MIPS_GPR_V0]); + debug("[ ARCBIOS GetParent(node 0x%016"PRIx64"): 0x%016" + PRIx64" ]\n", (uint64_t) cpu->cd.mips.gpr[MIPS_GPR_A0], + (uint64_t) cpu->cd.mips.gpr[MIPS_GPR_V0]); break; case 0x30: /* GetConfigurationData(void *configdata, void *node) */ - /* fatal("[ ARCBIOS GetConfigurationData(0x%016llx," - "0x%016llx) ]\n", (long long)cpu->cd.mips.gpr[MIPS_GPR_A0], - (long long)cpu->cd.mips.gpr[MIPS_GPR_A1]); */ + /* fatal("[ ARCBIOS GetConfigurationData(0x%016"PRIx64"," + "0x%016"PRIx64") ]\n", + (uint64_t) cpu->cd.mips.gpr[MIPS_GPR_A0], + (uint64_t) cpu->cd.mips.gpr[MIPS_GPR_A1]); */ cpu->cd.mips.gpr[MIPS_GPR_V0] = ARCBIOS_EINVAL; for (i=0; imd.arc.n_configuration_data; i++) { /* fatal("configuration_data_component[%i] = " - "0x%016llx\n", i, (long long)machine-> + "0x%016"PRIx64"\n", i, (uint64_t) machine-> md.arc.configuration_data_component[i]); */ if (cpu->cd.mips.gpr[MIPS_GPR_A1] == machine->md.arc.configuration_data_component[i]) { @@ -1383,7 +1384,7 @@ int match_len = 0; memset(buf, 0, sizeof(buf)); - for (i=0; imemory_rw(cpu, cpu->mem, cpu->cd.mips.gpr[MIPS_GPR_A0] + i, &buf[i], 1, MEM_READ, CACHE_NONE); @@ -1551,7 +1552,8 @@ machine->tick_func[i](cpu, machine->tick_extra[i]); - for (i=0; icd.mips.gpr[MIPS_GPR_A2]; i++) { + for (i=0; i<(int32_t)cpu->cd.mips.gpr[MIPS_GPR_A2]; + i++) { int x; unsigned char ch; @@ -1592,7 +1594,7 @@ nread? ARCBIOS_ESUCCESS: ARCBIOS_EAGAIN; } else { int handle = cpu->cd.mips.gpr[MIPS_GPR_A0]; - int disk_type; + int disk_type = 0; int disk_id = arcbios_handle_to_disk_id_and_type( machine, handle, &disk_type); uint64_t partition_offset = 0; @@ -1664,7 +1666,7 @@ * TODO: this is just a test */ int handle = cpu->cd.mips.gpr[MIPS_GPR_A0]; - int disk_type; + int disk_type = 0; int disk_id = arcbios_handle_to_disk_id_and_type( machine, handle, &disk_type); uint64_t partition_offset = 0; @@ -1675,11 +1677,11 @@ arcbios_handle_to_start_and_size(machine, handle, &partition_offset, &size); - debug("[ ARCBIOS Write(%i,0x%08llx,%i,0x%08llx) ]\n", - (int)cpu->cd.mips.gpr[MIPS_GPR_A0], - (long long)cpu->cd.mips.gpr[MIPS_GPR_A1], - (int)cpu->cd.mips.gpr[MIPS_GPR_A2], - (long long)cpu->cd.mips.gpr[MIPS_GPR_A3]); + debug("[ ARCBIOS Write(%i,0x%08"PRIx64",%i,0x%08" + PRIx64") ]\n", (int) cpu->cd.mips.gpr[MIPS_GPR_A0], + (uint64_t) cpu->cd.mips.gpr[MIPS_GPR_A1], + (int) cpu->cd.mips.gpr[MIPS_GPR_A2], + (uint64_t) cpu->cd.mips.gpr[MIPS_GPR_A3]); tmp_buf = malloc(cpu->cd.mips.gpr[MIPS_GPR_A2]); if (tmp_buf == NULL) { @@ -1689,7 +1691,7 @@ break; } - for (i=0; icd.mips.gpr[MIPS_GPR_A2]; i++) + for (i=0; i<(int32_t)cpu->cd.mips.gpr[MIPS_GPR_A2]; i++) cpu->memory_rw(cpu, cpu->mem, cpu->cd.mips.gpr[MIPS_GPR_A1] + i, &tmp_buf[i], sizeof(char), MEM_READ, @@ -1711,7 +1713,8 @@ cpu->cd.mips.gpr[MIPS_GPR_V0] = ARCBIOS_EIO; free(tmp_buf); } else { - for (i=0; icd.mips.gpr[MIPS_GPR_A2]; i++) { + for (i=0; i<(int32_t)cpu->cd.mips.gpr[MIPS_GPR_A2]; + i++) { unsigned char ch = '\0'; cpu->memory_rw(cpu, cpu->mem, cpu->cd.mips.gpr[MIPS_GPR_A1] + i, @@ -1726,18 +1729,18 @@ break; case 0x70: /* Seek(uint32_t handle, int64_t *ofs, uint32_t whence): uint32_t */ - debug("[ ARCBIOS Seek(%i,0x%08llx,%i): ", - (int)cpu->cd.mips.gpr[MIPS_GPR_A0], - (long long)cpu->cd.mips.gpr[MIPS_GPR_A1], - (int)cpu->cd.mips.gpr[MIPS_GPR_A2]); + debug("[ ARCBIOS Seek(%i,0x%08"PRIx64",%i): ", + (int) cpu->cd.mips.gpr[MIPS_GPR_A0], + (uint64_t)cpu->cd.mips.gpr[MIPS_GPR_A1], + (int) cpu->cd.mips.gpr[MIPS_GPR_A2]); if (cpu->cd.mips.gpr[MIPS_GPR_A2] != 0) { - fatal("[ ARCBIOS Seek(%i,0x%08llx,%i): " + fatal("[ ARCBIOS Seek(%i,0x%08"PRIx64",%i): " "UNIMPLEMENTED whence=%i ]\n", - (int)cpu->cd.mips.gpr[MIPS_GPR_A0], - (long long)cpu->cd.mips.gpr[MIPS_GPR_A1], - (int)cpu->cd.mips.gpr[MIPS_GPR_A2], - (int)cpu->cd.mips.gpr[MIPS_GPR_A2]); + (int) cpu->cd.mips.gpr[MIPS_GPR_A0], + (uint64_t) cpu->cd.mips.gpr[MIPS_GPR_A1], + (int) cpu->cd.mips.gpr[MIPS_GPR_A2], + (int) cpu->cd.mips.gpr[MIPS_GPR_A2]); } { @@ -1759,7 +1762,7 @@ + ((uint64_t)buf[7] << 56); machine->md.arc.current_seek_offset[ cpu->cd.mips.gpr[MIPS_GPR_A0]] = ofs; - debug("%016llx ]\n", (long long)ofs); + debug("%016"PRIx64" ]\n", (uint64_t) ofs); } cpu->cd.mips.gpr[MIPS_GPR_V0] = 0; /* Success. */ @@ -1767,7 +1770,7 @@ break; case 0x78: /* GetEnvironmentVariable(char *) */ /* Find the environment variable given by a0: */ - for (i=0; imemory_rw(cpu, cpu->mem, cpu->cd.mips.gpr[MIPS_GPR_A0] + i, &buf[i], sizeof(char), MEM_READ, CACHE_NONE); @@ -1776,7 +1779,7 @@ for (i=0; i<0x1000; i++) { /* Matching string at offset i? */ int nmatches = 0; - for (j=0; jmemory_rw(cpu, cpu->mem, (uint64_t)(ARC_ENV_STRINGS + i + j), &ch2, sizeof(char), MEM_READ, CACHE_NONE); @@ -1787,7 +1790,7 @@ (uint64_t)(ARC_ENV_STRINGS + i + strlen((char *)buf)), &ch2, sizeof(char), MEM_READ, CACHE_NONE); - if (nmatches == strlen((char *)buf) && ch2 == '=') { + if (nmatches == (int)strlen((char *)buf) && ch2=='=') { cpu->cd.mips.gpr[MIPS_GPR_V0] = ARC_ENV_STRINGS + i + strlen((char *)buf) + 1; @@ -2232,13 +2235,248 @@ /* + * arc_environment_setup(): + * + * Initialize the emulated environment variables. + */ +static void arc_environment_setup(struct machine *machine, int is64bit, + char *primary_ether_addr) +{ + size_t bootpath_len = 500; + char *init_bootpath; + uint64_t addr, addr2; + struct cpu *cpu = machine->cpus[0]; + + /* + * Boot string in ARC format: + * + * TODO: How about floppies? multi()disk()fdisk() + * Is tftp() good for netbooting? + */ + init_bootpath = malloc(bootpath_len); + if (init_bootpath == NULL) { + fprintf(stderr, "out of mem, bootpath\n"); + exit(1); + } + init_bootpath[0] = '\0'; + + if (machine->bootdev_id < 0 || machine->force_netboot) { + snprintf(init_bootpath, bootpath_len, "tftp()"); + } else { + /* TODO: Make this nicer. */ + if (machine->machine_type == MACHINE_SGI) { + if (machine->machine_subtype == 30) + strlcat(init_bootpath, "xio(0)pci(15)", + bootpath_len); + if (machine->machine_subtype == 32) + strlcat(init_bootpath, "pci(0)", + bootpath_len); + } + + if (diskimage_is_a_cdrom(machine, machine->bootdev_id, + machine->bootdev_type)) + snprintf(init_bootpath + strlen(init_bootpath), + bootpath_len - strlen(init_bootpath), + "scsi(0)cdrom(%i)fdisk(0)", machine->bootdev_id); + else + snprintf(init_bootpath + strlen(init_bootpath), + bootpath_len - strlen(init_bootpath), + "scsi(0)disk(%i)rdisk(0)partition(1)", + machine->bootdev_id); + } + + if (machine->machine_type == MACHINE_ARC) + strlcat(init_bootpath, "\\", bootpath_len); + + machine->bootstr = malloc(ARC_BOOTSTR_BUFLEN); + if (machine->bootstr == NULL) { + fprintf(stderr, "out of memory\n"); + exit(1); + } + + strlcpy(machine->bootstr, init_bootpath, ARC_BOOTSTR_BUFLEN); + if (strlcat(machine->bootstr, machine->boot_kernel_filename, + ARC_BOOTSTR_BUFLEN) >= ARC_BOOTSTR_BUFLEN) { + fprintf(stderr, "boot string too long?\n"); + exit(1); + } + + /* Boot args., eg "-a" */ + machine->bootarg = machine->boot_string_argument; + + /* argc, argv, envp in a0, a1, a2: */ + cpu->cd.mips.gpr[MIPS_GPR_A0] = 0; /* note: argc is increased later */ + + /* TODO: not needed? */ + cpu->cd.mips.gpr[MIPS_GPR_SP] = (int64_t)(int32_t) + (machine->physical_ram_in_mb * 1048576 + 0x80000000 - 0x2080); + + /* Set up argc/argv: */ + addr = ARC_ENV_STRINGS; + addr2 = ARC_ARGV_START; + cpu->cd.mips.gpr[MIPS_GPR_A1] = addr2; + + /* bootstr: */ + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, machine->bootstr, &addr); + cpu->cd.mips.gpr[MIPS_GPR_A0] ++; + + /* bootarg: */ + if (machine->bootarg[0] != '\0') { + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, machine->bootarg, &addr); + cpu->cd.mips.gpr[MIPS_GPR_A0] ++; + } + + cpu->cd.mips.gpr[MIPS_GPR_A2] = addr2; + + /* + * Add environment variables. For each variable, add it + * as a string using add_environment_string(), and add a + * pointer to it to the ARC_ENV_POINTERS array. + */ + if (machine->use_x11) { + if (machine->machine_type == MACHINE_ARC) { + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, + "CONSOLEIN=multi()key()keyboard()console()", &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, + "CONSOLEOUT=multi()video()monitor()console()", + &addr); + } else { + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "ConsoleIn=keyboard()", + &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "ConsoleOut=video()", + &addr); + + /* g for graphical mode. G for graphical mode + with SGI logo visible on Irix? */ + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "console=g", &addr); + } + } else { + if (machine->machine_type == MACHINE_ARC) { + /* TODO: serial console for ARC? */ + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, + "CONSOLEIN=multi()serial(0)", &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, + "CONSOLEOUT=multi()serial(0)", &addr); + } else { + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "ConsoleIn=serial(0)", + &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "ConsoleOut=serial(0)", + &addr); + + /* 'd' or 'd2' in Irix, 'ttyS0' in Linux? */ + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "console=d", &addr); + } + } + + if (machine->machine_type == MACHINE_SGI) { + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "AutoLoad=No", &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "diskless=0", &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "volume=80", &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "sgilogo=y", &addr); + + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "monitor=h", &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "TimeZone=GMT", &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "nogfxkbd=1", &addr); + + /* TODO: 'xio(0)pci(15)scsi(0)disk(1)rdisk(0)partition(0)' + on IP30 at least */ + + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, + "SystemPartition=pci(0)scsi(0)disk(2)rdisk(0)partition(8)", + &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, + "OSLoadPartition=pci(0)scsi(0)disk(2)rdisk(0)partition(0)", + &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "OSLoadFilename=/unix", &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "OSLoader=sash", &addr); + + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "rbaud=9600", &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "rebound=y", &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "crt_option=1", &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "netaddr=10.0.0.1", &addr); + + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "keybd=US", &addr); + + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "cpufreq=3", &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "dbaud=9600", &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, primary_ether_addr, &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "verbose=istrue", &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "showconfig=istrue", &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "diagmode=v", &addr); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "kernname=unix", &addr); + } else { + char *tmp; + size_t mlen = strlen(machine->bootarg) + + strlen("OSLOADOPTIONS=") + 2; + tmp = malloc(mlen); + snprintf(tmp, mlen, "OSLOADOPTIONS=%s", machine->bootarg); + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, tmp, &addr); + + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "OSLOADPARTITION=scsi(0)cdrom(6)" + "fdisk(0);scsi(0)disk(0)rdisk(0)partition(1)", &addr); + + store_pointer_and_advance(cpu, &addr2, addr, is64bit); + add_environment_string(cpu, "SYSTEMPARTITION=scsi(0)cdrom(6)" + "fdisk(0);scsi(0)disk(0)rdisk(0)partition(1)", &addr); + } + + /* End the environment strings with an empty zero-terminated + string, and the envp array with a NULL pointer. */ + add_environment_string(cpu, "", &addr); /* the end */ + store_pointer_and_advance(cpu, &addr2, 0, is64bit); + + /* Return address: (0x20 = ReturnFromMain()) */ + cpu->cd.mips.gpr[MIPS_GPR_RA] = ARC_FIRMWARE_ENTRIES + 0x20; +} + + +/* * arcbios_init(): * * Should be called before any other arcbios function is used. An exception * is arcbios_console_init(), which may be called before this function. + * + * TODO: Refactor; this is too long. */ -void arcbios_init(struct machine *machine, int is64bit, - uint64_t sgi_ram_offset) +void arcbios_init(struct machine *machine, int is64bit, uint64_t sgi_ram_offset, + char *primary_ether_addr, uint8_t *primary_ether_macaddr) { int i, alloclen = 20; char *name; @@ -2485,7 +2723,7 @@ system = arcbios_addchild_manual(cpu, COMPONENT_CLASS_SystemClass, COMPONENT_TYPE_ARC, 0,1,2,0, 0xffffffff, name, 0/*ROOT*/, NULL, 0); - debug("ARC system @ 0x%llx (\"%s\")\n", (long long)system, name); + debug("ARC system @ 0x%"PRIx64" (\"%s\")\n", (uint64_t) system, name); /* @@ -2601,19 +2839,19 @@ 0xffffffff, NULL, cpuaddr, NULL, 0); } - debug("ARC cpu%i @ 0x%llx", i, (long long)cpuaddr); + debug("ARC cpu%i @ 0x%"PRIx64, i, (uint64_t) cpuaddr); if (fpu != 0) - debug(" (fpu @ 0x%llx)\n", (long long)fpu); + debug(" (fpu @ 0x%"PRIx64")\n", (uint64_t) fpu); else debug("\n"); - debug(" picache @ 0x%llx, pdcache @ 0x%llx\n", - (long long)picache, (long long)pdcache); + debug(" picache @ 0x%"PRIx64", pdcache @ 0x%"PRIx64"\n", + (uint64_t) picache, (uint64_t) pdcache); if (machine->cache_secondary >= 12) - debug(" sdcache @ 0x%llx\n", - (long long)sdcache); + debug(" sdcache @ 0x%"PRIx64"\n", + (uint64_t) sdcache); if (machine->machine_type == MACHINE_SGI) { /* TODO: Memory amount (and base address?)! */ @@ -2621,7 +2859,7 @@ COMPONENT_CLASS_MemoryClass, COMPONENT_TYPE_MemoryUnit, 0, 1, 2, 0, 0xffffffff, "memory", cpuaddr, NULL, 0); - debug("ARC memory @ 0x%llx\n", (long long)memory); + debug("ARC memory @ 0x%"PRIx64"\n", (uint64_t) memory); } } @@ -2659,11 +2897,23 @@ ARC_FIRMWARE_ENTRIES + i*8); store_64bit_word(cpu, ARC_PRIVATE_VECTORS + i*8, ARC_PRIVATE_ENTRIES + i*8); + + /* "Magic trap" instruction: */ + store_32bit_word(cpu, ARC_FIRMWARE_ENTRIES + i*8, + 0x00c0de0c); + store_32bit_word(cpu, ARC_PRIVATE_ENTRIES + i*8, + 0x00c0de0c); } else { store_32bit_word(cpu, ARC_FIRMWARE_VECTORS + i*4, ARC_FIRMWARE_ENTRIES + i*4); store_32bit_word(cpu, ARC_PRIVATE_VECTORS + i*4, ARC_PRIVATE_ENTRIES + i*4); + + /* "Magic trap" instruction: */ + store_32bit_word(cpu, ARC_FIRMWARE_ENTRIES + i*4, + 0x00c0de0c); + store_32bit_word(cpu, ARC_PRIVATE_ENTRIES + i*4, + 0x00c0de0c); } } @@ -2707,5 +2957,13 @@ store_buf(cpu, SGI_SPB_ADDR, (char *)&arcbios_spb, sizeof(arcbios_spb)); } + + + /* + * TODO: How to build the component tree intermixed with + * the rest of device initialization? + */ + + arc_environment_setup(machine, is64bit, primary_ether_addr); }