static void dv_core_attach_address_callback (struct hw *me, int level, int space, address_word addr, address_word nr_bytes, struct hw *client) { HW_TRACE ((me, "attach - level=%d, space=%d, addr=0x%lx, nr_bytes=%ld, client=%s", level, space, (unsigned long) addr, (unsigned long) nr_bytes, hw_path (client))); /* NOTE: At preset the space is assumed to be zero. Perhaphs the space should be mapped onto something for instance: space0 - unified memory; space1 - IO memory; ... */ sim_core_attach (hw_system (me), NULL, /*cpu*/ level, access_read_write_exec, space, addr, nr_bytes, 0, /* modulo */ client, NULL); }
static sim_memopt * do_memopt_add (SIM_DESC sd, int level, int space, address_word addr, address_word nr_bytes, unsigned modulo, sim_memopt **entry, void *buffer) { void *fill_buffer; unsigned fill_length; void *free_buffer; unsigned long free_length; if (buffer != NULL) { /* Buffer already given. sim_memory_uninstall will free it. */ sim_core_attach (sd, NULL, level, access_read_write_exec, space, addr, nr_bytes, modulo, NULL, buffer); free_buffer = buffer; free_length = 0; fill_buffer = buffer; fill_length = (modulo == 0) ? nr_bytes : modulo; } else { /* Allocate new well-aligned buffer, just as sim_core_attach(). */ void *aligned_buffer; int padding = (addr % sizeof (unsigned64)); unsigned long bytes; #ifdef HAVE_MMAP struct stat s; if (mmap_next_fd >= 0) { /* Check that given file is big enough. */ int rc = fstat (mmap_next_fd, &s); if (rc < 0) sim_io_error (sd, "Error, unable to stat file: %s\n", strerror (errno)); /* Autosize the mapping to the file length. */ if (nr_bytes == 0) nr_bytes = s.st_size; } #endif bytes = (modulo == 0 ? nr_bytes : modulo) + padding; free_buffer = NULL; free_length = bytes; #ifdef HAVE_MMAP /* Memory map or malloc(). */ if (mmap_next_fd >= 0) { /* Some kernels will SIGBUS the application if mmap'd file is not large enough. */ if (s.st_size < bytes) { sim_io_error (sd, "Error, cannot confirm that mmap file is large enough " "(>= %ld bytes)\n", bytes); } free_buffer = mmap (0, bytes, PROT_READ|PROT_WRITE, MAP_SHARED, mmap_next_fd, 0); if (free_buffer == 0 || free_buffer == (char*)-1) /* MAP_FAILED */ { sim_io_error (sd, "Error, cannot mmap file (%s).\n", strerror (errno)); } } #endif /* Need heap allocation? */ if (free_buffer == NULL) { /* If filling with non-zero value, do not use clearing allocator. */ if (fill_byte_flag && fill_byte_value != 0) free_buffer = xmalloc (bytes); /* don't clear */ else free_buffer = zalloc (bytes); /* clear */ } aligned_buffer = (char*) free_buffer + padding; sim_core_attach (sd, NULL, level, access_read_write_exec, space, addr, nr_bytes, modulo, NULL, aligned_buffer); fill_buffer = aligned_buffer; fill_length = (modulo == 0) ? nr_bytes : modulo; /* If we just used a clearing allocator, and are about to fill with zero, truncate the redundant fill operation. */ if (fill_byte_flag && fill_byte_value == 0) fill_length = 1; /* avoid boundary length=0 case */ } if (fill_byte_flag) { ASSERT (fill_buffer != 0); memset ((char*) fill_buffer, fill_byte_value, fill_length); } while ((*entry) != NULL) entry = &(*entry)->next; (*entry) = ZALLOC (sim_memopt); (*entry)->level = level; (*entry)->space = space; (*entry)->addr = addr; (*entry)->nr_bytes = nr_bytes; (*entry)->modulo = modulo; (*entry)->buffer = free_buffer; /* Record memory unmapping info. */ if (mmap_next_fd >= 0) { (*entry)->munmap_length = free_length; close (mmap_next_fd); mmap_next_fd = -1; } else (*entry)->munmap_length = 0; return (*entry); }
static sim_memopt * do_memopt_add (SIM_DESC sd, int level, int space, address_word addr, address_word nr_bytes, unsigned modulo, sim_memopt **entry, void *buffer) { void *fill_buffer; unsigned fill_length; void *free_buffer; if (buffer != NULL) { /* Buffer already given. sim_memory_uninstall will free it. */ sim_core_attach (sd, NULL, level, access_read_write_exec, space, addr, nr_bytes, modulo, NULL, buffer); free_buffer = buffer; fill_buffer = buffer; fill_length = (modulo == 0) ? nr_bytes : modulo; } else { /* Allocate new well-aligned buffer, just as sim_core_attach(). */ void *aligned_buffer; int padding = (addr % sizeof (unsigned64)); unsigned long bytes = (modulo == 0 ? nr_bytes : modulo) + padding; /* If filling with non-zero value, do not use clearing allocator. */ if (fill_byte_flag && fill_byte_value != 0) free_buffer = xmalloc (bytes); /* don't clear */ else free_buffer = zalloc (bytes); /* clear */ aligned_buffer = (char*) free_buffer + padding; sim_core_attach (sd, NULL, level, access_read_write_exec, space, addr, nr_bytes, modulo, NULL, aligned_buffer); fill_buffer = aligned_buffer; fill_length = (modulo == 0) ? nr_bytes : modulo; /* If we just used a clearing allocator, and are about to fill with zero, truncate the redundant fill operation. */ if (fill_byte_flag && fill_byte_value == 0) fill_length = 1; /* avoid boundary length=0 case */ } if (fill_byte_flag) { ASSERT (fill_buffer != 0); memset ((char*) fill_buffer, fill_byte_value, fill_length); } while ((*entry) != NULL) entry = &(*entry)->next; (*entry) = ZALLOC (sim_memopt); (*entry)->level = level; (*entry)->space = space; (*entry)->addr = addr; (*entry)->nr_bytes = nr_bytes; (*entry)->modulo = modulo; (*entry)->buffer = free_buffer; return (*entry); }
/* Initialize the frv simulator. */ void frv_initialize (SIM_CPU *current_cpu, SIM_DESC sd) { FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (current_cpu); PROFILE_DATA *p = CPU_PROFILE_DATA (current_cpu); FRV_CACHE *insn_cache = CPU_INSN_CACHE (current_cpu); FRV_CACHE *data_cache = CPU_DATA_CACHE (current_cpu); int insn_cache_enabled = CACHE_INITIALIZED (insn_cache); int data_cache_enabled = CACHE_INITIALIZED (data_cache); USI hsr0; /* Initialize the register control information first since some of the register values are used in further configuration. */ frv_register_control_init (current_cpu); /* We need to ensure that the caches are initialized even if they are not initially enabled (via commandline) because they can be enabled by software. */ if (! insn_cache_enabled) frv_cache_init (current_cpu, CPU_INSN_CACHE (current_cpu)); if (! data_cache_enabled) frv_cache_init (current_cpu, CPU_DATA_CACHE (current_cpu)); /* Set the default cpu frequency if it has not been set on the command line. */ if (PROFILE_CPU_FREQ (p) == 0) PROFILE_CPU_FREQ (p) = 266000000; /* 266MHz */ /* Allocate one cache line of memory containing the address of the reset register Use the largest of the insn cache line size and the data cache line size. */ { int addr = RSTR_ADDRESS; void *aligned_buffer; int bytes; if (CPU_INSN_CACHE (current_cpu)->line_size > CPU_DATA_CACHE (current_cpu)->line_size) bytes = CPU_INSN_CACHE (current_cpu)->line_size; else bytes = CPU_DATA_CACHE (current_cpu)->line_size; /* 'bytes' is a power of 2. Calculate the starting address of the cache line. */ addr &= ~(bytes - 1); aligned_buffer = zalloc (bytes); /* clear */ sim_core_attach (sd, NULL, 0, access_read_write, 0, addr, bytes, 0, NULL, aligned_buffer); } PROFILE_INFO_CPU_CALLBACK(p) = frv_profile_info; ps->insn_fetch_address = -1; ps->branch_address = -1; cgen_init_accurate_fpu (current_cpu, CGEN_CPU_FPU (current_cpu), frvbf_fpu_error); /* Now perform power-on reset. */ frv_power_on_reset (current_cpu); /* Make sure that HSR0.ICE and HSR0.DCE are set properly. */ hsr0 = GET_HSR0 (); if (insn_cache_enabled) SET_HSR0_ICE (hsr0); else CLEAR_HSR0_ICE (hsr0); if (data_cache_enabled) SET_HSR0_DCE (hsr0); else CLEAR_HSR0_DCE (hsr0); SET_HSR0 (hsr0); }