OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /or1k/tags/stable_0_2_0_rc2/or1ksim/cpu/common
    from Rev 1611 to Rev 1765
    Reverse comparison

Rev 1611 → Rev 1765

/abstract.c
0,0 → 1,1081
/* abstract.c -- Abstract entities
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
 
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
/* Abstract memory and routines that go with this. I need to
add all sorts of other abstract entities. Currently we have
only memory. */
 
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
 
#include "config.h"
 
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
 
#include "port.h"
 
#include "arch.h"
#include "parse.h"
#include "abstract.h"
#include "sim-config.h"
#include "labels.h"
#include "except.h"
#include "debug_unit.h"
#include "opcode/or32.h"
#include "spr_defs.h"
#include "execute.h"
#include "sprs.h"
#include "support/profile.h"
#include "dmmu.h"
#include "immu.h"
#include "dcache_model.h"
#include "icache_model.h"
#include "debug.h"
#include "stats.h"
 
#if DYNAMIC_EXECUTION
#include "dyn_rec.h"
#endif
 
extern char *disassembled;
 
/* Pointer to memory area descriptions that are assigned to individual
peripheral devices. */
struct dev_memarea *dev_list;
 
/* Temporary variable to increase speed. */
struct dev_memarea *cur_area;
 
/* Pointer to memory controller device descriptor. */
struct dev_memarea *mc_area = NULL;
 
/* These are set by mmu if cache inhibit bit is set for current acces. */
int data_ci, insn_ci;
 
/* Virtual address of current access. */
static oraddr_t cur_vadd;
 
/* Read functions */
uint32_t eval_mem_32_inv(oraddr_t, void *);
uint16_t eval_mem_16_inv(oraddr_t, void *);
uint8_t eval_mem_8_inv(oraddr_t, void *);
uint32_t eval_mem_32_inv_direct(oraddr_t, void *);
uint16_t eval_mem_16_inv_direct(oraddr_t, void *);
uint8_t eval_mem_8_inv_direct(oraddr_t, void *);
 
/* Write functions */
void set_mem_32_inv(oraddr_t, uint32_t, void *);
void set_mem_16_inv(oraddr_t, uint16_t, void *);
void set_mem_8_inv(oraddr_t, uint8_t, void *);
void set_mem_32_inv_direct(oraddr_t, uint32_t, void *);
void set_mem_16_inv_direct(oraddr_t, uint16_t, void *);
void set_mem_8_inv_direct(oraddr_t, uint8_t, void *);
 
/* Calculates bit mask to fit the data */
static unsigned int bit_mask (uint32_t data) {
int i = 0;
data--;
while (data >> i)
data |= 1 << i++;
return data;
}
 
/* Register read and write function for a memory area.
addr is inside the area, if addr & addr_mask == addr_compare
(used also by peripheral devices like 16450 UART etc.) */
struct dev_memarea *register_memoryarea_mask(oraddr_t addr_mask,
oraddr_t addr_compare,
uint32_t size, unsigned mc_dev)
{
struct dev_memarea **pptmp;
unsigned int size_mask = bit_mask (size);
int found_error = 0;
addr_compare &= addr_mask;
 
debug(5, "addr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR", size %08"PRIx32"\n",
addr_mask, addr_compare, addr_compare | bit_mask (size), size);
/* Go to the end of the list. */
for(pptmp = &dev_list; *pptmp; pptmp = &(*pptmp)->next)
if (((addr_compare >= (*pptmp)->addr_compare) &&
(addr_compare < (*pptmp)->addr_compare + (*pptmp)->size)) ||
((addr_compare + size > (*pptmp)->addr_compare) &&
(addr_compare < (*pptmp)->addr_compare + (*pptmp)->size))) {
if (!found_error) {
fprintf (stderr, "ERROR: Overlapping memory area(s):\n");
fprintf (stderr, "\taddr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR
", size %08"PRIx32"\n",
addr_mask, addr_compare, addr_compare | bit_mask (size), size);
}
found_error = 1;
fprintf (stderr, "and\taddr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR
", size %08"PRIx32"\n",
(*pptmp)->addr_mask, (*pptmp)->addr_compare,
(*pptmp)->addr_compare | (*pptmp)->size_mask, (*pptmp)->size);
}
if (found_error)
exit (-1);
 
cur_area = *pptmp = (struct dev_memarea *)malloc(sizeof(struct dev_memarea));
 
if (mc_dev)
mc_area = *pptmp;
 
(*pptmp)->addr_mask = addr_mask;
(*pptmp)->addr_compare = addr_compare;
(*pptmp)->size = size;
(*pptmp)->size_mask = size_mask;
(*pptmp)->log = NULL;
(*pptmp)->valid = 1;
(*pptmp)->next = NULL;
 
return *pptmp;
}
 
/* Register read and write function for a memory area.
Memory areas should be aligned. Memory area is rounded up to
fit the nearest 2^n aligment.
(used also by peripheral devices like 16450 UART etc.)
If mc_dev is 1, this device will be checked first for a match
and will be accessed in case of overlaping memory areas.
Only one device can have this set to 1 (used for memory controller) */
struct dev_memarea *reg_mem_area(oraddr_t addr, uint32_t size, unsigned mc_dev,
struct mem_ops *ops)
{
unsigned int size_mask = bit_mask (size);
unsigned int addr_mask = ~size_mask;
struct dev_memarea *mem;
 
mem = register_memoryarea_mask(addr_mask, addr & addr_mask, size_mask + 1,
mc_dev);
 
memcpy(&mem->ops, ops, sizeof(struct mem_ops));
memcpy(&mem->direct_ops, ops, sizeof(struct mem_ops));
 
if(!ops->readfunc32) {
mem->ops.readfunc32 = eval_mem_32_inv;
mem->direct_ops.readfunc32 = eval_mem_32_inv_direct;
mem->direct_ops.read_dat32 = mem;
}
if(!ops->readfunc16) {
mem->ops.readfunc16 = eval_mem_16_inv;
mem->direct_ops.readfunc16 = eval_mem_16_inv_direct;
mem->direct_ops.read_dat16 = mem;
}
if(!ops->readfunc8) {
mem->ops.readfunc8 = eval_mem_8_inv;
mem->direct_ops.readfunc8 = eval_mem_8_inv_direct;
mem->direct_ops.read_dat8 = mem;
}
 
if(!ops->writefunc32) {
mem->ops.writefunc32 = set_mem_32_inv;
mem->direct_ops.writefunc32 = set_mem_32_inv_direct;
mem->direct_ops.write_dat32 = mem;
}
if(!ops->writefunc16) {
mem->ops.writefunc16 = set_mem_16_inv;
mem->direct_ops.writefunc16 = set_mem_16_inv_direct;
mem->direct_ops.write_dat16 = mem;
}
if(!ops->writefunc8) {
mem->ops.writefunc8 = set_mem_8_inv;
mem->direct_ops.writefunc8 = set_mem_8_inv_direct;
mem->direct_ops.write_dat8 = mem;
}
 
if(!ops->writeprog8) {
mem->ops.writeprog8 = mem->ops.writefunc8;
mem->ops.writeprog8_dat = mem->ops.write_dat8;
}
 
if(!ops->writeprog32) {
mem->ops.writeprog32 = mem->ops.writefunc32;
mem->ops.writeprog32_dat = mem->ops.write_dat32;
}
 
if(ops->log) {
if(!(mem->log = fopen(ops->log, "w")))
PRINTF("ERR: Unable to open %s to log memory acesses to\n", ops->log);
}
 
return mem;
}
 
/* Check if access is to registered area of memory. */
inline struct dev_memarea *verify_memoryarea(oraddr_t addr)
{
struct dev_memarea *ptmp;
 
/* Check memory controller space first */
if (mc_area && (addr & mc_area->addr_mask) == (mc_area->addr_compare & mc_area->addr_mask))
return cur_area = mc_area;
 
/* Check cached value */
if (cur_area && (addr & cur_area->addr_mask) == (cur_area->addr_compare & cur_area->addr_mask))
return cur_area;
 
/* When mc is enabled, we must check valid also, otherwise we assume it is nonzero */
/* Check list of registered devices. */
for(ptmp = dev_list; ptmp; ptmp = ptmp->next)
if ((addr & ptmp->addr_mask) == (ptmp->addr_compare & ptmp->addr_mask) && ptmp->valid)
return cur_area = ptmp;
return cur_area = NULL;
}
 
/* Sets the valid bit (Used only by memory controllers) */
void set_mem_valid(struct dev_memarea *mem, int valid)
{
mem->valid = valid;
}
 
/* Adjusts the read and write delays for the memory area pointed to by mem. */
void adjust_rw_delay(struct dev_memarea *mem, int delayr, int delayw)
{
mem->ops.delayr = delayr;
mem->ops.delayw = delayw;
}
 
uint8_t eval_mem_8_inv(oraddr_t memaddr, void *dat)
{
except_handle(EXCEPT_BUSERR, cur_vadd);
return 0;
}
 
uint16_t eval_mem_16_inv(oraddr_t memaddr, void *dat)
{
except_handle(EXCEPT_BUSERR, cur_vadd);
return 0;
}
 
uint32_t eval_mem_32_inv(oraddr_t memaddr, void *dat)
{
except_handle(EXCEPT_BUSERR, cur_vadd);
return 0;
}
 
void set_mem_8_inv(oraddr_t memaddr, uint8_t val, void *dat)
{
except_handle(EXCEPT_BUSERR, cur_vadd);
}
 
void set_mem_16_inv(oraddr_t memaddr, uint16_t val, void *dat)
{
except_handle(EXCEPT_BUSERR, cur_vadd);
}
 
void set_mem_32_inv(oraddr_t memaddr, uint32_t val, void *dat)
{
except_handle(EXCEPT_BUSERR, cur_vadd);
}
 
uint8_t eval_mem_8_inv_direct(oraddr_t memaddr, void *dat)
{
struct dev_memarea *mem = dat;
 
PRINTF("ERROR: Invalid 8-bit direct read from memory %"PRIxADDR"\n",
mem->addr_compare | memaddr);
return 0;
}
 
uint16_t eval_mem_16_inv_direct(oraddr_t memaddr, void *dat)
{
struct dev_memarea *mem = dat;
 
PRINTF("ERROR: Invalid 16-bit direct read from memory %"PRIxADDR"\n",
mem->addr_compare | memaddr);
return 0;
}
 
uint32_t eval_mem_32_inv_direct(oraddr_t memaddr, void *dat)
{
struct dev_memarea *mem = dat;
 
PRINTF("ERROR: Invalid 32-bit direct read from memory %"PRIxADDR"\n",
mem->addr_compare | memaddr);
return 0;
}
 
void set_mem_8_inv_direct(oraddr_t memaddr, uint8_t val, void *dat)
{
struct dev_memarea *mem = dat;
 
PRINTF("ERROR: Invalid 32-bit direct write to memory %"PRIxADDR"\n",
mem->addr_compare | memaddr);
}
 
void set_mem_16_inv_direct(oraddr_t memaddr, uint16_t val, void *dat)
{
struct dev_memarea *mem = dat;
 
PRINTF("ERROR: Invalid 16-bit direct write to memory %"PRIxADDR"\n",
mem->addr_compare | memaddr);
}
 
void set_mem_32_inv_direct(oraddr_t memaddr, uint32_t val, void *dat)
{
struct dev_memarea *mem = dat;
 
PRINTF("ERROR: Invalid 32-bit direct write to memory %"PRIxADDR"\n",
mem->addr_compare | memaddr);
}
 
/* For cpu accesses
*
* NOTE: This function _is_ only called from eval_mem32 below and
* {i,d}c_simulate_read. _Don't_ call it from anywere else.
*/
inline uint32_t evalsim_mem32(oraddr_t memaddr, oraddr_t vaddr)
{
struct dev_memarea *mem;
 
if((mem = verify_memoryarea(memaddr))) {
runtime.sim.mem_cycles += mem->ops.delayr;
return mem->ops.readfunc32(memaddr & mem->size_mask, mem->ops.read_dat32);
} else {
PRINTF("EXCEPTION: read out of memory (32-bit access to %"PRIxADDR")\n",
memaddr);
except_handle(EXCEPT_BUSERR, vaddr);
}
 
return 0;
}
 
/* For cpu accesses
*
* NOTE: This function _is_ only called from eval_mem16 below and
* {i,d}c_simulate_read. _Don't_ call it from anywere else.
*/
inline uint16_t evalsim_mem16(oraddr_t memaddr, oraddr_t vaddr)
{
struct dev_memarea *mem;
 
if((mem = verify_memoryarea(memaddr))) {
runtime.sim.mem_cycles += mem->ops.delayr;
return mem->ops.readfunc16(memaddr & mem->size_mask, mem->ops.read_dat16);
} else {
PRINTF("EXCEPTION: read out of memory (16-bit access to %"PRIxADDR")\n",
memaddr);
except_handle(EXCEPT_BUSERR, vaddr);
}
 
return 0;
}
 
/* For cpu accesses
*
* NOTE: This function _is_ only called from eval_mem8 below and
* {i,d}c_simulate_read. _Don't_ call it from anywere else.
*/
inline uint8_t evalsim_mem8(oraddr_t memaddr, oraddr_t vaddr)
{
struct dev_memarea *mem;
 
if((mem = verify_memoryarea(memaddr))) {
runtime.sim.mem_cycles += mem->ops.delayr;
return mem->ops.readfunc8(memaddr & mem->size_mask, mem->ops.read_dat8);
} else {
PRINTF("EXCEPTION: read out of memory (8-bit access to %"PRIxADDR")\n",
memaddr);
except_handle(EXCEPT_BUSERR, vaddr);
}
 
return 0;
}
 
/* Returns 32-bit values from mem array. Big endian version.
*
* STATISTICS OK (only used for cpu_access, that is architectural access)
*/
uint32_t eval_mem32(oraddr_t memaddr,int* breakpoint)
{
uint32_t temp;
oraddr_t phys_memaddr;
 
if (config.sim.mprofile)
mprofile (memaddr, MPROF_32 | MPROF_READ);
 
if (memaddr & 3) {
except_handle (EXCEPT_ALIGN, memaddr);
return 0;
}
 
if (config.debug.enabled)
*breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
 
phys_memaddr = dmmu_translate(memaddr, 0);
if (except_pending)
return 0;
 
if (config.dc.enabled)
temp = dc_simulate_read(phys_memaddr, memaddr, 4);
else
temp = evalsim_mem32(phys_memaddr, memaddr);
 
if (config.debug.enabled)
*breakpoint += CheckDebugUnit(DebugLoadData,temp); /* MM170901 */
 
return temp;
}
 
/* for simulator accesses, the ones that cpu wouldn't do
*
* STATISTICS OK
*/
uint32_t eval_direct32(oraddr_t memaddr, int through_mmu, int through_dc)
{
oraddr_t phys_memaddr;
struct dev_memarea *mem;
 
if (memaddr & 3) {
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
return 0;
}
phys_memaddr = memaddr;
 
if (through_mmu)
phys_memaddr = peek_into_dtlb(memaddr, 0, through_dc);
 
if (through_dc)
return dc_simulate_read(phys_memaddr, memaddr, 4);
else {
if((mem = verify_memoryarea(phys_memaddr)))
return mem->direct_ops.readfunc32(phys_memaddr & mem->size_mask,
mem->direct_ops.read_dat32);
else
PRINTF("ERR: 32-bit read out of memory area: %"PRIxADDR" (physical: %"
PRIxADDR"\n", memaddr, phys_memaddr);
}
return 0;
}
 
 
/* Returns 32-bit values from mem array. Big endian version.
*
* STATISTICS OK (only used for cpu_access, that is architectural access)
*/
uint32_t eval_insn(oraddr_t memaddr, int* breakpoint)
{
uint32_t temp;
oraddr_t phys_memaddr;
 
if (config.sim.mprofile)
mprofile (memaddr, MPROF_32 | MPROF_FETCH);
// memaddr = simulate_ic_mmu_fetch(memaddr);
 
phys_memaddr = memaddr;
#if !(DYNAMIC_EXECUTION)
phys_memaddr = immu_translate(memaddr);
 
if (except_pending)
return 0;
#endif
 
if (config.debug.enabled)
*breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr);
 
if (config.ic.enabled)
temp = ic_simulate_fetch(phys_memaddr, memaddr);
else
temp = evalsim_mem32(phys_memaddr, memaddr);
 
if (config.debug.enabled)
*breakpoint += CheckDebugUnit(DebugLoadData,temp);
return temp;
}
 
/* Returns 32-bit values from mem array. Big endian version.
*
* STATISTICS OK
*/
uint32_t eval_insn_direct(oraddr_t memaddr, int through_mmu)
{
if(through_mmu)
memaddr = peek_into_itlb(memaddr);
 
return eval_direct32(memaddr, 0, 0);
}
 
 
/* Returns 16-bit values from mem array. Big endian version.
*
* STATISTICS OK (only used for cpu_access, that is architectural access)
*/
uint16_t eval_mem16(oraddr_t memaddr,int* breakpoint)
{
uint16_t temp;
oraddr_t phys_memaddr;
if (config.sim.mprofile)
mprofile (memaddr, MPROF_16 | MPROF_READ);
 
if (memaddr & 1) {
except_handle (EXCEPT_ALIGN, memaddr);
return 0;
}
 
if (config.debug.enabled)
*breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
 
phys_memaddr = dmmu_translate(memaddr, 0);
if (except_pending)
return 0;
 
if (config.dc.enabled)
temp = dc_simulate_read(phys_memaddr, memaddr, 2);
else
temp = evalsim_mem16(phys_memaddr, memaddr);
 
if (config.debug.enabled)
*breakpoint += CheckDebugUnit(DebugLoadData,temp); /* MM170901 */
 
return temp;
}
 
/* for simulator accesses, the ones that cpu wouldn't do
*
* STATISTICS OK.
*/
uint16_t eval_direct16(oraddr_t memaddr, int through_mmu, int through_dc)
{
oraddr_t phys_memaddr;
struct dev_memarea *mem;
 
if (memaddr & 1) {
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
return 0;
}
phys_memaddr = memaddr;
 
if (through_mmu)
phys_memaddr = peek_into_dtlb(memaddr, 0, through_dc);
 
if (through_dc)
return dc_simulate_read(phys_memaddr, memaddr, 2);
else {
if((mem = verify_memoryarea(phys_memaddr)))
return mem->direct_ops.readfunc16(phys_memaddr & mem->size_mask,
mem->direct_ops.read_dat16);
else
PRINTF("ERR: 16-bit read out of memory area: %"PRIxADDR" (physical: %"
PRIxADDR"\n", memaddr, phys_memaddr);
}
return 0;
}
 
/* Returns 8-bit values from mem array.
*
* STATISTICS OK (only used for cpu_access, that is architectural access)
*/
uint8_t eval_mem8(oraddr_t memaddr,int* breakpoint)
{
uint8_t temp;
oraddr_t phys_memaddr;
 
if (config.sim.mprofile)
mprofile (memaddr, MPROF_8 | MPROF_READ);
 
if (config.debug.enabled)
*breakpoint += CheckDebugUnit(DebugLoadAddress,memaddr); /* 28/05/01 CZ */
 
phys_memaddr = dmmu_translate(memaddr, 0);
if (except_pending)
return 0;
 
if (config.dc.enabled)
temp = dc_simulate_read(phys_memaddr, memaddr, 1);
else
temp = evalsim_mem8(phys_memaddr, memaddr);
 
if (config.debug.enabled)
*breakpoint += CheckDebugUnit(DebugLoadData,temp); /* MM170901 */
return temp;
}
 
/* for simulator accesses, the ones that cpu wouldn't do
*
* STATISTICS OK.
*/
uint8_t eval_direct8(oraddr_t memaddr, int through_mmu, int through_dc)
{
oraddr_t phys_memaddr;
struct dev_memarea *mem;
 
phys_memaddr = memaddr;
if (through_mmu)
phys_memaddr = peek_into_dtlb(memaddr, 0, through_dc);
if (through_dc)
return dc_simulate_read(phys_memaddr, memaddr, 1);
else {
if((mem = verify_memoryarea(phys_memaddr)))
return mem->direct_ops.readfunc8(phys_memaddr & mem->size_mask,
mem->direct_ops.read_dat8);
else
PRINTF("ERR: 8-bit read out of memory area: %"PRIxADDR" (physical: %"
PRIxADDR"\n", memaddr, phys_memaddr);
}
 
return 0;
}
 
/* For cpu accesses
*
* NOTE: This function _is_ only called from set_mem32 below and
* dc_simulate_write. _Don't_ call it from anywere else.
*/
inline void setsim_mem32(oraddr_t memaddr, oraddr_t vaddr, uint32_t value)
{
struct dev_memarea *mem;
 
if((mem = verify_memoryarea(memaddr))) {
cur_vadd = vaddr;
runtime.sim.mem_cycles += mem->ops.delayw;
mem->ops.writefunc32(memaddr & mem->size_mask, value, mem->ops.write_dat32);
#if DYNAMIC_EXECUTION
dyn_checkwrite(memaddr);
#endif
} else {
PRINTF("EXCEPTION: write out of memory (32-bit access to %"PRIxADDR")\n",
memaddr);
except_handle(EXCEPT_BUSERR, vaddr);
}
}
 
/* For cpu accesses
*
* NOTE: This function _is_ only called from set_mem16 below and
* dc_simulate_write. _Don't_ call it from anywere else.
*/
inline void setsim_mem16(oraddr_t memaddr, oraddr_t vaddr, uint16_t value)
{
struct dev_memarea *mem;
 
if((mem = verify_memoryarea(memaddr))) {
cur_vadd = vaddr;
runtime.sim.mem_cycles += mem->ops.delayw;
mem->ops.writefunc16(memaddr & mem->size_mask, value, mem->ops.write_dat16);
#if DYNAMIC_EXECUTION
dyn_checkwrite(memaddr);
#endif
} else {
PRINTF("EXCEPTION: write out of memory (16-bit access to %"PRIxADDR")\n",
memaddr);
except_handle(EXCEPT_BUSERR, vaddr);
}
}
 
/* For cpu accesses
*
* NOTE: This function _is_ only called from set_mem8 below and
* dc_simulate_write. _Don't_ call it from anywere else.
*/
inline void setsim_mem8(oraddr_t memaddr, oraddr_t vaddr, uint8_t value)
{
struct dev_memarea *mem;
 
if((mem = verify_memoryarea(memaddr))) {
cur_vadd = vaddr;
runtime.sim.mem_cycles += mem->ops.delayw;
mem->ops.writefunc8(memaddr & mem->size_mask, value, mem->ops.write_dat8);
#if DYNAMIC_EXECUTION
dyn_checkwrite(memaddr);
#endif
} else {
PRINTF("EXCEPTION: write out of memory (8-bit access to %"PRIxADDR")\n",
memaddr);
except_handle(EXCEPT_BUSERR, vaddr);
}
}
 
/* Set mem, 32-bit. Big endian version.
*
* STATISTICS OK. (the only suspicious usage is in sim-cmd.c,
* where this instruction is used for patching memory,
* wether this is cpu or architectual access is yet to
* be decided)
*/
void set_mem32(oraddr_t memaddr, uint32_t value, int* breakpoint)
{
oraddr_t phys_memaddr;
 
if (config.sim.mprofile)
mprofile (memaddr, MPROF_32 | MPROF_WRITE);
 
if (memaddr & 3) {
except_handle (EXCEPT_ALIGN, memaddr);
return;
}
 
phys_memaddr = dmmu_translate(memaddr, 1);;
/* If we produced exception don't set anything */
if (except_pending)
return;
 
if (config.debug.enabled) {
*breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr); /* 28/05/01 CZ */
*breakpoint += CheckDebugUnit(DebugStoreData,value);
}
 
if(config.dc.enabled)
dc_simulate_write(phys_memaddr, memaddr, value, 4);
else
setsim_mem32(phys_memaddr, memaddr, value);
 
if (cur_area && cur_area->log)
fprintf (cur_area->log, "[%"PRIxADDR"] -> write %08"PRIx32"\n", memaddr,
value);
}
 
/*
* STATISTICS NOT OK.
*/
void set_direct32(oraddr_t memaddr, uint32_t value, int through_mmu,
int through_dc)
{
oraddr_t phys_memaddr;
struct dev_memarea *mem;
 
if (memaddr & 3) {
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
return;
}
 
phys_memaddr = memaddr;
if (through_mmu) {
/* 0 - no write access, we do not want a DPF exception do we ;)
*/
phys_memaddr = peek_into_dtlb(memaddr, 1, through_dc);
}
 
if(through_dc)
dc_simulate_write(memaddr, memaddr, value, 4);
else {
if((mem = verify_memoryarea(phys_memaddr)))
mem->direct_ops.writefunc32(phys_memaddr & mem->size_mask, value,
mem->direct_ops.write_dat32);
else
PRINTF("ERR: 32-bit write out of memory area: %"PRIxADDR" (physical: %"
PRIxADDR")\n", memaddr, phys_memaddr);
}
 
if (cur_area && cur_area->log)
fprintf (cur_area->log, "[%"PRIxADDR"] -> DIRECT write %08"PRIx32"\n",
memaddr, value);
}
 
 
/* Set mem, 16-bit. Big endian version. */
 
void set_mem16(oraddr_t memaddr, uint16_t value, int* breakpoint)
{
oraddr_t phys_memaddr;
 
if (config.sim.mprofile)
mprofile (memaddr, MPROF_16 | MPROF_WRITE);
if (memaddr & 1) {
except_handle (EXCEPT_ALIGN, memaddr);
return;
}
phys_memaddr = dmmu_translate(memaddr, 1);;
/* If we produced exception don't set anything */
if (except_pending)
return;
 
if (config.debug.enabled) {
*breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr); /* 28/05/01 CZ */
*breakpoint += CheckDebugUnit(DebugStoreData,value);
}
if(config.dc.enabled)
dc_simulate_write(phys_memaddr, memaddr, value, 2);
else
setsim_mem16(phys_memaddr, memaddr, value);
 
if (cur_area && cur_area->log)
fprintf (cur_area->log, "[%"PRIxADDR"] -> write %04"PRIx16"\n", memaddr,
value);
}
 
/*
* STATISTICS NOT OK.
*/
void set_direct16(oraddr_t memaddr, uint16_t value, int through_mmu,
int through_dc)
{
oraddr_t phys_memaddr;
struct dev_memarea *mem;
 
if (memaddr & 1) {
PRINTF("%s:%d %s(): ERR unaligned access\n", __FILE__, __LINE__, __FUNCTION__);
return;
}
 
phys_memaddr = memaddr;
if (through_mmu) {
/* 0 - no write access, we do not want a DPF exception do we ;)
*/
phys_memaddr = peek_into_dtlb(memaddr, 0, through_dc);
}
 
if(through_dc)
dc_simulate_write(memaddr, memaddr, value, 2);
else {
if((mem = verify_memoryarea(phys_memaddr)))
mem->direct_ops.writefunc16(phys_memaddr & mem->size_mask, value,
mem->direct_ops.write_dat16);
else
PRINTF("ERR: 16-bit write out of memory area: %"PRIxADDR" (physical: %"
PRIxADDR"\n", memaddr, phys_memaddr);
}
 
if (cur_area && cur_area->log)
fprintf (cur_area->log, "[%"PRIxADDR"] -> DIRECT write %04"PRIx16"\n",
memaddr, value);
}
 
/* Set mem, 8-bit. */
void set_mem8(oraddr_t memaddr, uint8_t value, int* breakpoint)
{
oraddr_t phys_memaddr;
 
if (config.sim.mprofile)
mprofile (memaddr, MPROF_8 | MPROF_WRITE);
phys_memaddr = memaddr;
 
phys_memaddr = dmmu_translate(memaddr, 1);;
/* If we produced exception don't set anything */
if (except_pending) return;
 
if (config.debug.enabled) {
*breakpoint += CheckDebugUnit(DebugStoreAddress,memaddr); /* 28/05/01 CZ */
*breakpoint += CheckDebugUnit(DebugStoreData,value);
}
 
if(config.dc.enabled)
dc_simulate_write(phys_memaddr, memaddr, value, 1);
else
setsim_mem8(phys_memaddr, memaddr, value);
 
if (cur_area && cur_area->log)
fprintf (cur_area->log, "[%"PRIxADDR"] -> write %02"PRIx8"\n", memaddr,
value);
}
 
/*
* STATISTICS NOT OK.
*/
void set_direct8(oraddr_t memaddr, uint8_t value, int through_mmu,
int through_dc)
{
oraddr_t phys_memaddr;
struct dev_memarea *mem;
 
phys_memaddr = memaddr;
if (through_mmu) {
/* 0 - no write access, we do not want a DPF exception do we ;)
*/
phys_memaddr = peek_into_dtlb(memaddr, 0, through_dc);
}
 
if(through_dc)
dc_simulate_write(phys_memaddr, memaddr, value, 1);
else {
if((mem = verify_memoryarea(phys_memaddr)))
mem->direct_ops.writefunc8(phys_memaddr & mem->size_mask, value,
mem->direct_ops.write_dat8);
else
PRINTF("ERR: 8-bit write out of memory area: %"PRIxADDR" (physical: %"
PRIxADDR"\n", memaddr, phys_memaddr);
}
 
if (cur_area && cur_area->log)
fprintf (cur_area->log, "[%"PRIxADDR"] -> DIRECT write %02"PRIx8"\n",
memaddr, value);
}
 
 
/* set_program32 - same as set_direct32, but it also writes to memory that is
* non-writeable to the rest of the sim. Used to do program
* loading.
*/
void set_program32(oraddr_t memaddr, uint32_t value)
{
struct dev_memarea *mem;
 
if(memaddr & 3) {
PRINTF("%s(): ERR unaligned 32-bit program write\n", __FUNCTION__);
return;
}
 
if((mem = verify_memoryarea(memaddr))) {
mem->ops.writeprog32(memaddr & mem->size_mask, value,
mem->ops.writeprog32_dat);
} else
PRINTF("ERR: 32-bit program load out of memory area: %"PRIxADDR"\n",
memaddr);
}
 
/* set_program8 - same as set_direct8, but it also writes to memory that is
* non-writeable to the rest of the sim. Used to do program
* loading.
*/
void set_program8(oraddr_t memaddr, uint8_t value)
{
struct dev_memarea *mem;
 
if((mem = verify_memoryarea(memaddr))) {
mem->ops.writeprog8(memaddr & mem->size_mask, value,
mem->ops.writeprog8_dat);
} else
PRINTF("ERR: 8-bit program load out of memory area: %"PRIxADDR"\n",
memaddr);
}
 
void dumpmemory(oraddr_t from, oraddr_t to, int disasm, int nl)
{
oraddr_t i, j;
struct label_entry *tmp;
int ilen = disasm ? 4 : 16;
 
for(i = from; i < to; i += ilen) {
 
for (j = 0; j < ilen;) {
if (!disasm) {
tmp = NULL;
if (verify_memoryarea(i + j)) {
struct label_entry *entry;
entry = get_label(i + j);
 
if (entry) {
PRINTF("\n%"PRIxADDR": ", i);
PRINTF("\n<%s>:\n", entry->name);
PRINTF("%"PRIxADDR": ", i);
} else {
PRINTF("%"PRIxADDR": ", i);
}
 
PRINTF("%02"PRIx8" ", eval_direct8(i + j, 0, 0));
} else PRINTF("XX ");
j++;
} else {
uint32_t _insn = eval_direct32(i, 0, 0);
int index = insn_decode (_insn);
int len = insn_len (index);
tmp = NULL;
if (verify_memoryarea(i + j)) {
struct label_entry *entry;
entry = get_label(i + j);
if (entry) {
PRINTF("\n%"PRIxADDR": ", i);
PRINTF("<%s>:\n", entry->name);
PRINTF("%"PRIxADDR": ", i);
} else {
PRINTF("%"PRIxADDR": ", i);
}
 
PRINTF("%08"PRIx32" ", _insn);
if (index >= 0) {
disassemble_insn (_insn);
PRINTF(" %s", disassembled);
} else
PRINTF("<invalid>");
} else PRINTF("XXXXXXXX");
j += len;
}
}
if (nl)
PRINTF ("\n");
}
}
 
/* Closes files, etc. */
 
void done_memory_table (void)
{
struct dev_memarea *ptmp;
 
/* Check list of registered devices. */
for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
if (ptmp->log)
fclose (ptmp->log);
}
}
 
/* Displays current memory configuration */
 
void memory_table_status (void)
{
struct dev_memarea *ptmp;
 
/* Check list of registered devices. */
for(ptmp = dev_list; ptmp; ptmp = ptmp->next) {
PRINTF ("addr & %"PRIxADDR" == %"PRIxADDR" to %"PRIxADDR", size %"PRIx32"\n",
ptmp->addr_mask, ptmp->addr_compare, ptmp->addr_compare | bit_mask (ptmp->size),
ptmp->size);
PRINTF ("\t");
if (ptmp->ops.delayr >= 0)
PRINTF ("read delay = %i cycles, ", ptmp->ops.delayr);
else
PRINTF ("reads not possible, ");
 
if (ptmp->ops.delayw >= 0)
PRINTF ("write delay = %i cycles", ptmp->ops.delayw);
else
PRINTF ("writes not possible");
if (ptmp->log)
PRINTF (", (logged)\n");
else
PRINTF ("\n");
}
}
 
/* Outputs time in pretty form to dest string */
 
char *generate_time_pretty (char *dest, long time_ps)
{
int exp3 = 0;
if (time_ps) {
while ((time_ps % 1000) == 0) {
time_ps /= 1000;
exp3++;
}
}
sprintf (dest, "%li%cs", time_ps, "pnum"[exp3]);
return dest;
}
/Makefile.in
0,0 → 1,424
# Makefile.in generated by automake 1.9.5 from Makefile.am.
# @configure_input@
 
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
 
@SET_MAKE@
 
# Makefile -- Makefile for cpu architecture independent simulation
# Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
#
# This file is part of OpenRISC 1000 Architectural Simulator.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
 
SOURCES = $(libcommon_a_SOURCES)
 
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = cpu/common
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
libcommon_a_AR = $(AR) $(ARFLAGS)
libcommon_a_LIBADD =
am_libcommon_a_OBJECTS = abstract.$(OBJEXT) parse.$(OBJEXT) \
stats.$(OBJEXT) trace.$(OBJEXT) labels.$(OBJEXT)
libcommon_a_OBJECTS = $(am_libcommon_a_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libcommon_a_SOURCES)
DIST_SOURCES = $(libcommon_a_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
ARFLAGS = @ARFLAGS@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
BUILD_DIR = @BUILD_DIR@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CPU_ARCH = @CPU_ARCH@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DYNAMIC_EXECUTION_FALSE = @DYNAMIC_EXECUTION_FALSE@
DYNAMIC_EXECUTION_TRUE = @DYNAMIC_EXECUTION_TRUE@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
GENERATE_NEEDED_FALSE = @GENERATE_NEEDED_FALSE@
GENERATE_NEEDED_TRUE = @GENERATE_NEEDED_TRUE@
INCLUDES = @INCLUDES@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
LOCAL_DEFS = @LOCAL_DEFS@
LOCAL_LDFLAGS = @LOCAL_LDFLAGS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MAKE_SHELL = @MAKE_SHELL@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
SUMVERSION = @SUMVERSION@
TERMCAP_LIB = @TERMCAP_LIB@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
noinst_LIBRARIES = libcommon.a
libcommon_a_SOURCES = abstract.c parse.c stats.c trace.c labels.c
all: all-am
 
.SUFFIXES:
.SUFFIXES: .c .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cpu/common/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu cpu/common/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
 
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
libcommon.a: $(libcommon_a_OBJECTS) $(libcommon_a_DEPENDENCIES)
-rm -f libcommon.a
$(libcommon_a_AR) libcommon.a $(libcommon_a_OBJECTS) $(libcommon_a_LIBADD)
$(RANLIB) libcommon.a
 
mostlyclean-compile:
-rm -f *.$(OBJEXT)
 
distclean-compile:
-rm -f *.tab.c
 
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/abstract.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/labels.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stats.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trace.Po@am__quote@
 
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
 
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
uninstall-info-am:
 
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
 
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
 
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
 
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LIBRARIES)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
 
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
 
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
 
clean-generic:
 
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
 
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
 
clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
 
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
 
dvi: dvi-am
 
dvi-am:
 
html: html-am
 
info: info-am
 
info-am:
 
install-data-am:
 
install-exec-am:
 
install-info: install-info-am
 
install-man:
 
installcheck-am:
 
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
 
mostlyclean: mostlyclean-am
 
mostlyclean-am: mostlyclean-compile mostlyclean-generic
 
pdf: pdf-am
 
pdf-am:
 
ps: ps-am
 
ps-am:
 
uninstall-am: uninstall-info-am
 
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-noinstLIBRARIES ctags distclean distclean-compile \
distclean-generic distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-exec install-exec-am install-info \
install-info-am install-man install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
uninstall-am uninstall-info-am
 
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
/stats.c
0,0 → 1,293
/* stats.c -- Various statistics about instruction scheduling etc.
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
#include <stdio.h>
#include <ctype.h>
#include <string.h>
 
#include "config.h"
 
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
 
#include "port.h"
#include "arch.h"
#include "abstract.h"
#include "sim-config.h"
#include "spr_defs.h"
#include "opcode/or32.h"
#include "execute.h"
#include "sprs.h"
#include "debug.h"
#include "stats.h"
 
struct branchstat {
int taken;
int nottaken;
int forward;
int backward;
};
 
/* See also enum insn_type in abstract.h */
const char func_unit_str[30][30] = { "unknown", "exception", "arith", "shift", "compare",
"branch", "jump", "load", "store", "movimm", "move", "extend", "nop", "mac" };
 
struct dstats_entry dstats[DSTATS_LEN]; /* dependency stats */
struct sstats_entry sstats[SSTATS_LEN]; /* single stats */
struct fstats_entry fstats[FSTATS_LEN]; /* functional units stats */
struct mstats_entry or1k_mstats = {0}; /* misc units stats */
struct cachestats_entry ic_stats = {0}; /* instruction cache stats */
struct cachestats_entry dc_stats = {0}; /* data cache stats */
struct immustats_entry immu_stats = {0}; /* insn mmu stats */
struct dmmustats_entry dmmu_stats = {0}; /* data mmu stats */
struct raw_stats raw_stats; /* RAW hazard stats */
 
void addsstats(int item, int cnt_dynamic)
{
int i = 0;
while(sstats[i].insn != item && sstats[i].insn >= 0 && i < SSTATS_LEN) i++;
 
if (i >= SSTATS_LEN - 1) return;
if (sstats[i].insn >= 0) {
sstats[i].cnt_dynamic += cnt_dynamic;
} else {
sstats[i].insn = item;
sstats[i].cnt_dynamic = cnt_dynamic;
}
}
 
void adddstats(int item1, int item2, int cnt_dynamic, int depend)
{
int i = 0;
debug(7,"adddstats start\n");
 
while((dstats[i].insn1 != item1 || dstats[i].insn2 != item2) && (i < DSTATS_LEN) && dstats[i].insn1 >= 0) i++;
 
if (i >= DSTATS_LEN - 1) return;
if (dstats[i].insn1 >= 0) {
dstats[i].cnt_dynamic += cnt_dynamic;
dstats[i].depend += depend;
} else {
dstats[i].insn1 = item1;
dstats[i].insn2 = item2;
dstats[i].cnt_dynamic = cnt_dynamic;
dstats[i].depend = depend;
}
}
 
void addfstats(enum insn_type item1, enum insn_type item2, int cnt_dynamic, int depend)
{
int i = 0;
while(((fstats[i].insn1 != item1) || (fstats[i].insn2 != item2)) &&
(fstats[i].insn1 != it_unknown) &&
(i < FSTATS_LEN))
i++;
 
if (i >= FSTATS_LEN - 1) return;
if ((fstats[i].insn1 == item1) &&
(fstats[i].insn2 == item2)) {
fstats[i].cnt_dynamic += cnt_dynamic;
fstats[i].depend += depend;
}
else {
fstats[i].insn1 = item1;
fstats[i].insn2 = item2;
fstats[i].cnt_dynamic = cnt_dynamic;
fstats[i].depend = depend;
}
}
 
void initstats()
{
int i;
memset(sstats, 0, sizeof(sstats));
for (i = 0; i < SSTATS_LEN; i++)
sstats[i].insn = -1;
memset(dstats, 0, sizeof(dstats));
for (i = 0; i < DSTATS_LEN; i++)
dstats[i].insn1 = dstats[i].insn2 = -1;
memset(fstats, 0, sizeof(fstats));
memset(&or1k_mstats, 0, sizeof(or1k_mstats));
memset(&ic_stats, 0, sizeof(ic_stats));
memset(&dc_stats, 0, sizeof(dc_stats));
memset(&raw_stats, 0, sizeof(raw_stats));
}
 
void printotherstats(int which)
{
PRINTF ("\n");
if (config.bpb.enabled) {
struct branchstat bf;
struct branchstat bnf;
long bf_all, bnf_all;
bf.taken = or1k_mstats.bf[1][0] + or1k_mstats.bf[1][1];
bf.nottaken = or1k_mstats.bf[0][0] + or1k_mstats.bf[0][1];
bf.forward = or1k_mstats.bf[0][1] + or1k_mstats.bf[1][1];
bf.backward = or1k_mstats.bf[0][0] + or1k_mstats.bf[1][0];
bf_all = bf.forward + bf.backward;
bnf.taken = or1k_mstats.bnf[1][0] + or1k_mstats.bf[1][1];
bnf.nottaken = or1k_mstats.bnf[0][0] + or1k_mstats.bf[0][1];
bnf.forward = or1k_mstats.bnf[0][1] + or1k_mstats.bf[1][1];
bnf.backward = or1k_mstats.bnf[0][0] + or1k_mstats.bf[1][0];
bnf_all = bnf.forward + bnf.backward;
PRINTF("bnf: %d (%ld%%) taken,", bf.taken, (bf.taken * 100) / SD(bf_all));
PRINTF(" %d (%ld%%) not taken,", bf.nottaken, (bf.nottaken * 100) / SD(bf_all));
PRINTF(" %d (%ld%%) forward,", bf.forward, (bf.forward * 100) / SD(bf_all));
PRINTF(" %d (%ld%%) backward\n", bf.backward, (bf.backward * 100) / SD(bf_all));
PRINTF("bf: %d (%ld%%) taken,", bnf.taken, (bnf.taken * 100) / SD(bnf_all));
PRINTF(" %d (%ld%%) not taken,", bnf.nottaken, (bnf.nottaken * 100) / SD(bnf_all));
PRINTF(" %d (%ld%%) forward,", bnf.forward, (bnf.forward * 100) / SD(bnf_all));
PRINTF(" %d (%ld%%) backward\n", bnf.backward, (bnf.backward * 100) / SD(bnf_all));
PRINTF("StaticBP bnf(%s): correct %ld%%\n", config.bpb.sbp_bnf_fwd ? "forward" : "backward",
(or1k_mstats.bnf[0][config.bpb.sbp_bnf_fwd] * 100) / SD(bnf_all));
PRINTF("StaticBP bf(%s): correct %ld%%\n", config.bpb.sbp_bf_fwd ? "forward" : "backward",
(or1k_mstats.bnf[1][config.bpb.sbp_bf_fwd] * 100) / SD(bf_all));
PRINTF("BPB: hit %d (correct %d%%), miss %d\n", or1k_mstats.bpb.hit, (or1k_mstats.bpb.correct * 100) / SD(or1k_mstats.bpb.hit), or1k_mstats.bpb.miss);
} else
PRINTF("BPB simulation disabled. Enable it to see BPB analysis\n");
 
if (config.bpb.btic) {
PRINTF("BTIC: hit %d(%d%%), miss %d\n", or1k_mstats.btic.hit, (or1k_mstats.btic.hit * 100) / SD(or1k_mstats.btic.hit + or1k_mstats.btic.miss), or1k_mstats.btic.miss);
} else
PRINTF("BTIC simulation disabled. Enabled it to see BTIC analysis\n");
 
if (config.ic.enabled) {
PRINTF("IC read: hit %d(%d%%), miss %d\n", ic_stats.readhit, (ic_stats.readhit * 100) / SD(ic_stats.readhit + ic_stats.readmiss), ic_stats.readmiss);
} else
PRINTF("No ICache. Enable it to see IC results.\n");
if (config.dc.enabled) {
PRINTF("DC read: hit %d(%d%%), miss %d\n", dc_stats.readhit, (dc_stats.readhit * 100) / SD(dc_stats.readhit + dc_stats.readmiss), dc_stats.readmiss);
PRINTF("DC write: hit %d(%d%%), miss %d\n", dc_stats.writehit, (dc_stats.writehit * 100) / SD(dc_stats.writehit + dc_stats.writemiss), dc_stats.writemiss);
} else
PRINTF("No DCache. Enable it to see DC results.\n");
 
if (cpu_state.sprs[SPR_UPR] & SPR_UPR_IMP) {
PRINTF("IMMU read: hit %d(%d%%), miss %d\n", immu_stats.fetch_tlbhit, (immu_stats.fetch_tlbhit * 100) / SD(immu_stats.fetch_tlbhit + immu_stats.fetch_tlbmiss), immu_stats.fetch_tlbmiss);
} else
PRINTF("No IMMU. Set UPR[IMP]\n");
 
if (cpu_state.sprs[SPR_UPR] & SPR_UPR_DMP) {
PRINTF("DMMU read: hit %d(%d%%), miss %d\n", dmmu_stats.loads_tlbhit, (dmmu_stats.loads_tlbhit * 100) / SD(dmmu_stats.loads_tlbhit + dmmu_stats.loads_tlbmiss), dmmu_stats.loads_tlbmiss);
} else
PRINTF("No DMMU. Set UPR[DMP]\n");
PRINTF("Additional LOAD CYCLES: %u STORE CYCLES: %u\n", runtime.sim.loadcycles, runtime.sim.storecycles);
}
 
void printstats(int which)
{
int i, all = 0, dependall = 0;
 
if (which > 1 && which <= 5 && !config.cpu.dependstats) {
PRINTF("Hazard analysis disabled. Enable it to see analysis results.\n");
return;
}
 
switch (which) {
case 1:
PRINTF("stats 1: Misc stats\n");
printotherstats(which);
break;
case 2:
PRINTF ("stats 2: Instruction usage\n");
for(i = 0; i < SSTATS_LEN; i++)
all += sstats[i].cnt_dynamic;
for(i = 0; i < SSTATS_LEN; i++)
if (sstats[i].cnt_dynamic)
PRINTF(" %-15s used %6dx (%5.1f%%)\n", insn_name(sstats[i].insn), sstats[i].cnt_dynamic, (sstats[i].cnt_dynamic * 100.)/SD(all));
PRINTF("%d instructions (dynamic, single stats)\n", all);
break;
case 3:
PRINTF ("stats 3: Instruction dependencies\n");
for(i = 0; i < DSTATS_LEN; i++) {
all += dstats[i].cnt_dynamic;
dependall += dstats[i].depend;
}
for(i = 0; i < DSTATS_LEN; i++)
if (dstats[i].cnt_dynamic) {
char temp[100];
sprintf(temp, "%s, %s ", insn_name(dstats[i].insn1), insn_name(dstats[i].insn2));
PRINTF(" %-30s %6dx (%5.1f%%)", temp, dstats[i].cnt_dynamic, (dstats[i].cnt_dynamic * 100.)/SD(all));
PRINTF(" depend: %5.1f%%\n", (dstats[i].depend * 100.) / dstats[i].cnt_dynamic);
}
PRINTF("%d instructions (dynamic, dependency stats) depend: %d%%\n", all, (dependall * 100) / SD(all));
break;
case 4:
PRINTF("stats 4: Functional units dependencies\n");
for(i = 0; i < FSTATS_LEN; i++) {
all += fstats[i].cnt_dynamic;
dependall += fstats[i].depend;
}
for(i = 0; i < FSTATS_LEN; i++)
if (fstats[i].cnt_dynamic) {
char temp[100];
sprintf(temp, "%s, %s", func_unit_str[fstats[i].insn1], func_unit_str[fstats[i].insn2]);
PRINTF(" %-30s %6dx (%5.1f%%)", temp, fstats[i].cnt_dynamic, (fstats[i].cnt_dynamic * 100.)/SD(all));
PRINTF(" depend: %5.1f%%\n", (fstats[i].depend * 100.) / fstats[i].cnt_dynamic);
}
PRINTF ("%d instructions (dynamic, functional units stats) depend: %d%%\n\n", all, (dependall * 100) / SD(all));
break;
case 5:
PRINTF("stats 5: Raw register usage over time\n");
#if RAW_RANGE_STATS
for(i = 0; (i < MAX_RANGE); i++)
PRINTF(" Register set and reused in %d. cycle: %d cases\n", i, raw_stats.range[i]);
#endif
break;
case 6:
if (config.cpu.sbuf_len) {
extern int sbuf_total_cyc, sbuf_wait_cyc;
PRINTF ("stats 6: Store buffer analysis\n");
PRINTF ("Using store buffer of length %i.\n", config.cpu.sbuf_len);
PRINTF ("Number of total memory store cycles: %i/%lli\n", sbuf_total_cyc,
runtime.sim.cycles + sbuf_total_cyc - sbuf_wait_cyc);
PRINTF ("Number of cycles waiting for memory stores: %i\n", sbuf_wait_cyc);
PRINTF ("Number of memory cycles spared: %i\n", sbuf_total_cyc - sbuf_wait_cyc);
PRINTF ("Store speedup %3.2f%%, total speedup %3.2f%%\n", 100.*(sbuf_total_cyc - sbuf_wait_cyc)/sbuf_total_cyc,
100.*(sbuf_total_cyc - sbuf_wait_cyc) / (runtime.sim.cycles + sbuf_total_cyc - sbuf_wait_cyc));
} else
PRINTF ("Store buffer analysis disabled. Enable it to see analysis results.\n");
break;
default:
PRINTF ("Please specify a stats group (1-6).\n");
break;
}
#if 0
PRINTF("Byte ADD: %d instructions\n", or1k_mstats.byteadd);
#endif
}
/parse.c
0,0 → 1,710
/* parce.c -- Architecture independent load
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
 
#include "config.h"
 
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
 
#include "port.h"
#include "arch.h"
#include "abstract.h"
#include "dmmu.h"
#include "coff.h"
#include "elf.h"
#include "debug_unit.h"
#include "opcode/or32.h"
#include "parse.h"
#include "sim-config.h"
#include "labels.h"
#include "debug.h"
 
#define MEMORY_LEN 0x100000000
#define MAXLINE_LEN 18000
 
/* Whether to do immediate statistics */
#define IMM_STATS 0
 
extern char *disassembled;
 
/* Unused mem memory marker. It is used when allocating program and data memory
during parsing */
unsigned int freemem;
 
/* Translation table provided by microkernel. Only used if simulating microkernel. */
static oraddr_t transl_table;
 
/* Used to signal whether during loading of programs a translation fault occured. */
static unsigned long transl_error;
 
char *
stripwhite (string)
char *string;
{
register char *s, *t;
 
for (s = string; whitespace (*s); s++)
;
if (*s == 0)
return (s);
 
t = s + strlen (s) - 1;
while (t > s && whitespace (*t))
t--;
*++t = '\0';
 
return s;
}
 
/* This function is very similar to strncpy, except it null terminates the string */
char *strstrip (char *dst, const char *src, int n)
{
strncpy (dst, src, n);
*(dst + n) = '\0';
return dst;
}
 
/* Used only by the simulator loader to translate logical addresses into physical.
If loadcode() is called with valid virtphy_transl pointer to a table of
translations then translate() performs translation otherwise phy address is
equal to logical. */
static oraddr_t translate(oraddr_t laddr,int* breakpoint)
{
int i;
/* No translation (i.e. when loading kernel into simulator) */
/* PRINTF("transl_table=%x laddr=%x\n", transl_table, laddr);
PRINTF("laddr=%x\n", laddr);*/
if (transl_table == 0)
return laddr;
/* Try to find our translation in the table. */
for(i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
if ((laddr & ~(PAGE_SIZE - 1)) == eval_direct32(transl_table + i, 0, 0)) {
/* Page modified */
set_direct32(transl_table + i + 8, -2, 0, 0);
PRINTF("found paddr=%"PRIx32"\n",
eval_direct32(transl_table + i + 4, 0, 0) |
(laddr & (PAGE_SIZE - 1)));
return (oraddr_t)eval_direct32(transl_table + i + 4, 0, 0) |
(laddr & (oraddr_t)(PAGE_SIZE - 1));
}
 
/* Allocate new phy page for us. */
for(i = 0; i < (MEMORY_LEN / PAGE_SIZE) * 16; i += 16)
if (eval_direct32(transl_table + i + 8, 0, 0) == 0) {
/* VPN */
set_direct32(transl_table + i, laddr & ~(PAGE_SIZE - 1), 0, 0);
/* PPN */
set_direct32(transl_table + i + 4, (i/16) * PAGE_SIZE, 0, 0);
/* Page modified */
set_direct32(transl_table + i + 8, -2, 0, 0);
PRINTF("newly allocated ppn=%"PRIx32"\n",
eval_direct32(transl_table + i + 4, 0, 0));
PRINTF("newly allocated .ppn=%"PRIxADDR"\n", transl_table + i + 4);
PRINTF("newly allocated ofs=%"PRIxADDR"\n", (laddr & (PAGE_SIZE - 1)));
PRINTF("newly allocated paddr=%"PRIx32"\n",
eval_direct32(transl_table + i + 4, 0, 0) |
(laddr & (PAGE_SIZE - 1)));
return (oraddr_t)eval_direct32(transl_table + i + 4, 0, 0) |
(laddr & (oraddr_t)(PAGE_SIZE - 1));
}
/* If we come this far then all phy memory is used and we can't find our page
nor allocate new page. */
transl_error = 1;
PRINTF("can't translate %"PRIxADDR"\n", laddr);
exit(1);
return -1;
}
 
#if IMM_STATS
int bcnt[33][3] = {0};
int bsum[3] = {0};
unsigned long movhi = 0;
 
int bits (unsigned long val) {
int i = 1;
if (!val) return 0;
while (val != 0 && (signed long)val != -1) {i++; val = (signed long)val >> 1;}
return i;
}
 
void check_insn (uint32_t insn) {
int insn_index = insn_decode (insn);
struct insn_op_struct *opd = op_start[insn_index];
uint32_t data = 0;
int dis = 0;
const char *name;
if (!insn || insn_index < 0) return;
name = insn_name (insn_index);
if (strcmp (name, "l.nop") == 0 || strcmp (name, "l.sys") == 0) return;
 
while (1)
{
uint32_t tmp = 0
unsigned int nbits = 0;
while (1)
{
tmp |= ((insn >> (opd->type & OPTYPE_SHR)) & ((1 << opd->data) - 1)) << nbits;
nbits += opd->data;
if (opd->type & OPTYPE_OP)
break;
opd++;
}
 
/* Do we have to sign extend? */
if (opd->type & OPTYPE_SIG)
{
int sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR;
if (tmp & (1 << sbit))
tmp |= 0xFFFFFFFF << sbit;
}
if (opd->type & OPTYPE_DIS) {
/* We have to read register later. */
data += tmp;
dis = 1;
} else
{
if (!(opd->type & OPTYPE_REG) || dis) {
if (!dis) data = tmp;
if (strcmp (name, "l.movhi") == 0) {
movhi = data << 16;
} else {
data |= movhi;
//PRINTF ("%08x %s\n", data, name);
if (!(or32_opcodes[insn_index].flags & OR32_IF_DELAY)) {
bcnt[bits(data)][0]++; bsum[0]++;
} else {
if (strcmp (name, "l.bf") == 0 || strcmp (name, "l.bnf") == 0) {
bcnt[bits(data)][1]++; bsum[1]++;
} else {
bcnt[bits(data)][2]++; bsum[2]++;
}
}
}
}
data = 0;
dis = 0;
}
if(opd->type & OPTYPE_LAST) {
return;
}
opd++;
}
}
#endif
 
/* Replaced several calls to translate(freemem) with vaddr */
/* Added new mode execution code */
/* Changed parameters so address can be passed as argument */
void addprogram(oraddr_t address, uint32_t insn, int* breakpoint)
{
int vaddr = (!runtime.sim.filename) ? translate(address,breakpoint) : translate(freemem,breakpoint);
/* We can't have set_program32 functions since it is not gauranteed that the
* section we're loading is aligned on a 4-byte boundry */
set_program8 (vaddr, (insn >> 24) & 0xff);
set_program8 (vaddr + 1, (insn >> 16) & 0xff);
set_program8 (vaddr + 2, (insn >> 8) & 0xff);
set_program8 (vaddr + 3, insn & 0xff);
#if IMM_STATS
check_insn (insn);
#endif
if(runtime.sim.filename)
freemem += insn_len (insn_decode (insn));
}
 
/* Load big-endian COFF file. */
 
void readfile_coff(char *filename, short sections)
{
FILE *inputfs;
char inputbuf[4];
uint32_t insn;
signed long sectsize;
COFF_AOUTHDR coffaouthdr;
struct COFF_scnhdr coffscnhdr;
int len;
int firstthree = 0;
int breakpoint = 0;
 
if (!(inputfs = fopen(filename, "r"))) {
perror("readfile_coff");
exit(1);
}
 
if (fseek(inputfs, sizeof(struct COFF_filehdr), SEEK_SET) == -1) {
fclose(inputfs);
perror("readfile_coff");
exit(1);
}
 
if (fread(&coffaouthdr, sizeof(coffaouthdr), 1, inputfs) != 1) {
fclose(inputfs);
perror("readfile_coff");
exit(1);
}
while(sections--) {
long scnhdr_pos = sizeof(struct COFF_filehdr) + sizeof(coffaouthdr)
+ sizeof(struct COFF_scnhdr) * firstthree;
if (fseek(inputfs, scnhdr_pos, SEEK_SET) == -1) {
fclose(inputfs);
perror("readfile_coff");
exit(1);
}
if (fread(&coffscnhdr, sizeof(struct COFF_scnhdr), 1, inputfs) != 1) {
fclose(inputfs);
perror("readfile_coff");
exit(1);
}
PRINTF("Section: %s,", coffscnhdr.s_name);
PRINTF(" paddr: 0x%.8lx,", COFF_LONG_H(coffscnhdr.s_paddr));
PRINTF(" vaddr: 0x%.8lx,", COFF_LONG_H(coffscnhdr.s_vaddr));
PRINTF(" size: 0x%.8lx,", COFF_LONG_H(coffscnhdr.s_size));
PRINTF(" scnptr: 0x%.8lx\n", COFF_LONG_H(coffscnhdr.s_scnptr));
sectsize = COFF_LONG_H(coffscnhdr.s_size);
#if 0
/* A couple of sanity checks. */
if (translate(COFF_LONG_H(coffscnhdr.s_vaddr),&breakpoint) < MEMORY_START) {
PRINTF("Section %s starts out of ", coffscnhdr.s_name);
PRINTF("memory (at %x)\n", COFF_LONG_H(coffscnhdr.s_vaddr));
exit(1);
}
if (translate(COFF_LONG_H(coffscnhdr.s_vaddr) + sectsize,&breakpoint) >
MEMORY_START + MEMORY_LEN) {
PRINTF("Section %s ends out of ", coffscnhdr.s_name);
PRINTF("memory.\n");
exit(1);
}
#endif
#if 0
if (++firstthree == 1 && strcmp(coffscnhdr.s_name, ".text") != 0) {
PRINTF("First section should be .text (%s instead)\n", coffscnhdr.s_name);
exit(1);
}
if (firstthree == 2 && strcmp(coffscnhdr.s_name, ".data") != 0) {
PRINTF("Second section should be .data (%s instead)\n", coffscnhdr.s_name);
exit(1);
}
if (firstthree == 3 && strcmp(coffscnhdr.s_name, ".bss") != 0) {
PRINTF("Third section should be .bss (%s instead)\n", coffscnhdr.s_name);
exit(1);
}
#else
++firstthree;
#endif
 
/* loading section */
freemem = COFF_LONG_H(coffscnhdr.s_paddr);
debug(2,"Starting to load at 0x%x\n", freemem);
if (fseek(inputfs, COFF_LONG_H(coffscnhdr.s_scnptr), SEEK_SET) == -1) {
fclose(inputfs);
perror("readfile_coff");
exit(1);
}
while (sectsize > 0 && (len = fread(&inputbuf, sizeof(inputbuf), 1, inputfs))) {
insn = COFF_LONG_H(inputbuf);
len = insn_len (insn_decode (insn));
if (len == 2)
{
fseek(inputfs, -2, SEEK_CUR);
debug(8,"readfile_coff: %lx 0x%x \n", sectsize, insn >> 16);
}
else
debug(8,"readfile_coff: %lx 0x%x \n", sectsize, insn);
addprogram (freemem, insn, &breakpoint);
sectsize -= len;
}
}
if (firstthree < 3) {
PRINTF("One or more missing sections. At least");
PRINTF(" three sections expected (.text, .data, .bss).\n");
exit(1);
}
if (firstthree > 3) {
PRINTF("Warning: one or more extra sections. These");
PRINTF(" sections were handled as .data sections.\n");
}
 
fclose(inputfs);
PRINTF("Finished loading COFF.\n");
return;
}
 
/* Load symbols from big-endian COFF file. */
 
void readsyms_coff(char *filename, unsigned long symptr, long syms)
{
FILE *inputfs;
struct COFF_syment coffsymhdr;
int count = 0;
long nsyms = syms;
if (!(inputfs = fopen(filename, "r"))) {
perror("readsyms_coff");
exit(1);
}
if (fseek(inputfs, symptr, SEEK_SET) == -1) {
fclose(inputfs);
perror("readsyms_coff");
exit(1);
}
while(syms--) {
int i, n;
if (fread(&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1) {
fclose(inputfs);
perror("readsyms_coff");
exit(1);
}
 
n = (unsigned char)coffsymhdr.e_numaux[0];
/* check whether this symbol belongs to a section and is external symbol; ignore all others */
if (COFF_SHORT_H(coffsymhdr.e_scnum) >= 0 && coffsymhdr.e_sclass[0] == C_EXT) {
#if 0
/* If not important or not in text, skip. */
if(COFF_SHORT_H(coffsymhdr.e_type) & COFF_N_TMASK & COFF_STYP_TEXT) {
#endif
 
if (*((unsigned long *)coffsymhdr.e.e.e_zeroes)) {
if (strlen(coffsymhdr.e.e_name) && strlen(coffsymhdr.e.e_name) < 9)
add_label(COFF_LONG_H(coffsymhdr.e_value), coffsymhdr.e.e_name);
debug(8, "[%i] Symbol: %s,", count++, coffsymhdr.e.e_name);
} else {
long fpos = ftell (inputfs);
if (fseek(inputfs, symptr + nsyms * COFF_SYMESZ + COFF_LONG_H(coffsymhdr.e.e.e_offset), SEEK_SET) == 0) {
char tmp[33], *s = &tmp[0];
while (s != &tmp[32])
if ((*(s++) = fgetc(inputfs)) == 0) break;
tmp[32] = 0;
add_label(COFF_LONG_H(coffsymhdr.e_value), &tmp[0]);
debug(8, "[%i] Symbol: %s,", count++, &tmp[0]);
}
fseek(inputfs, fpos, SEEK_SET);
}
debug(9, " val: 0x%.8lx,", COFF_LONG_H(coffsymhdr.e_value));
debug(9, " type: %x, %x, auxs: %i\n", COFF_SHORT_H(coffsymhdr.e_type), *((unsigned short *)coffsymhdr.e_type), n);
}
 
for (i = 0; i < n; i++)
if (fread(&coffsymhdr, COFF_SYMESZ, 1, inputfs) != 1) {
fclose(inputfs);
perror("readsyms_coff3");
exit(1);
}
syms -= n;
count += n;
}
 
fclose(inputfs);
PRINTF("Finished loading symbols.\n");
return;
}
 
void readfile_elf(char *filename)
{
 
FILE *inputfs;
struct elf32_hdr elfhdr;
struct elf32_phdr *elf_phdata = NULL;
struct elf32_shdr *elf_spnt, *elf_shdata;
struct elf32_sym *sym_tbl = (struct elf32_sym *)0;
unsigned long syms = 0;
char *str_tbl = (char *)0;
char *s_str = (char *)0;
int breakpoint = 0;
unsigned long inputbuf;
unsigned long padd;
uint32_t insn;
int i, j, sectsize, len;
 
if (!(inputfs = fopen(filename, "r"))) {
perror("readfile_elf");
exit(1);
}
 
if (fread(&elfhdr, sizeof(elfhdr), 1, inputfs) != 1) {
perror("readfile_elf");
exit(1);
}
 
if ((elf_shdata = (struct elf32_shdr *)malloc(ELF_SHORT_H(elfhdr.e_shentsize) * ELF_SHORT_H(elfhdr.e_shnum))) == NULL) {
perror("readfile_elf");
exit(1);
}
 
if (fseek(inputfs, ELF_LONG_H(elfhdr.e_shoff), SEEK_SET) != 0) {
perror("readfile_elf");
exit(1);
}
 
if (fread(elf_shdata, ELF_SHORT_H(elfhdr.e_shentsize) * ELF_SHORT_H(elfhdr.e_shnum), 1, inputfs) != 1) {
perror("readfile_elf");
exit(1);
}
 
if (ELF_LONG_H(elfhdr.e_phoff)) {
if((elf_phdata = (struct elf32_phdr *)malloc(ELF_SHORT_H(elfhdr.e_phnum) * ELF_SHORT_H(elfhdr.e_phentsize))) == NULL) {
perror("readfile_elf");
exit(1);
}
 
if (fseek(inputfs, ELF_LONG_H(elfhdr.e_phoff), SEEK_SET) != 0) {
perror("readfile_elf");
exit(1);
}
 
if (fread(elf_phdata, ELF_SHORT_H(elfhdr.e_phnum) * ELF_SHORT_H(elfhdr.e_phentsize), 1, inputfs) != 1) {
perror("readfile_elf");
exit(1);
}
}
 
for(i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H(elfhdr.e_shnum); i++, elf_spnt++) {
 
if(ELF_LONG_H(elf_spnt->sh_type) == SHT_STRTAB) {
 
if((str_tbl = (char *)malloc(ELF_LONG_H(elf_spnt->sh_size))) == NULL) {
perror("readfile_elf");
exit(1);
}
 
if (fseek(inputfs, ELF_LONG_H(elf_spnt->sh_offset), SEEK_SET) != 0) {
perror("readfile_elf");
exit(1);
}
 
if (fread(str_tbl, ELF_LONG_H(elf_spnt->sh_size), 1, inputfs) != 1) {
perror("readfile_elf");
exit(1);
}
}
else if(ELF_LONG_H(elf_spnt->sh_type) == SHT_SYMTAB) {
 
if((sym_tbl = (struct elf32_sym *)malloc(ELF_LONG_H(elf_spnt->sh_size))) == NULL) {
perror("readfile_elf");
exit(1);
}
if (fseek(inputfs, ELF_LONG_H(elf_spnt->sh_offset), SEEK_SET) != 0) {
perror("readfile_elf");
exit(1);
}
if (fread(sym_tbl, ELF_LONG_H(elf_spnt->sh_size), 1, inputfs) != 1) {
perror("readfile_elf");
exit(1);
}
 
syms = ELF_LONG_H(elf_spnt->sh_size) / ELF_LONG_H(elf_spnt->sh_entsize);
}
}
 
if (ELF_SHORT_H(elfhdr.e_shstrndx) != SHN_UNDEF) {
elf_spnt = &elf_shdata[ELF_SHORT_H(elfhdr.e_shstrndx)];
if((s_str = (char *)malloc(ELF_LONG_H(elf_spnt->sh_size))) == NULL) {
perror("readfile_elf");
exit(1);
}
 
if (fseek(inputfs, ELF_LONG_H(elf_spnt->sh_offset), SEEK_SET) != 0) {
perror("readfile_elf");
exit(1);
}
 
if (fread(s_str, ELF_LONG_H(elf_spnt->sh_size), 1, inputfs) != 1) {
perror("readfile_elf");
exit(1);
}
}
for(i = 0, elf_spnt = elf_shdata; i < ELF_SHORT_H(elfhdr.e_shnum); i++, elf_spnt++) {
 
if((ELF_LONG_H(elf_spnt->sh_type) & SHT_PROGBITS) && (ELF_LONG_H(elf_spnt->sh_flags) & SHF_ALLOC)) {
 
padd = ELF_LONG_H(elf_spnt->sh_addr);
for(j = 0; j < ELF_SHORT_H(elfhdr.e_phnum); j++) {
if(ELF_LONG_H(elf_phdata[j].p_offset) &&
ELF_LONG_H(elf_phdata[j].p_offset) <= ELF_LONG_H(elf_spnt->sh_offset) &&
(ELF_LONG_H(elf_phdata[j].p_offset) + ELF_LONG_H(elf_phdata[j].p_memsz)) > ELF_LONG_H(elf_spnt->sh_offset))
padd = ELF_LONG_H(elf_phdata[j].p_paddr) + ELF_LONG_H(elf_spnt->sh_offset) - ELF_LONG_H(elf_phdata[j].p_offset);
}
 
 
 
if (ELF_LONG_H(elf_spnt->sh_name) && s_str)
PRINTF("Section: %s,", &s_str[ELF_LONG_H(elf_spnt->sh_name)]);
else
PRINTF("Section: noname,");
PRINTF(" vaddr: 0x%.8lx,", ELF_LONG_H(elf_spnt->sh_addr));
PRINTF(" paddr: 0x%.8lx,", padd);
PRINTF(" offset: 0x%.8lx,", ELF_LONG_H(elf_spnt->sh_offset));
PRINTF(" size: 0x%.8lx\n", ELF_LONG_H(elf_spnt->sh_size));
freemem = padd;
sectsize = ELF_LONG_H(elf_spnt->sh_size);
 
if (fseek(inputfs, ELF_LONG_H(elf_spnt->sh_offset), SEEK_SET) != 0) {
perror("readfile_elf");
exit(1);
}
 
while (sectsize > 0 && (len = fread(&inputbuf, sizeof(inputbuf), 1, inputfs))) {
insn = ELF_LONG_H(inputbuf);
len = insn_len (insn_decode (insn));
if (len == 2)
{
fseek(inputfs, -2, SEEK_CUR);
debug(8, "readfile_elf: %x 0x%x \n", sectsize, insn >> 16);
}
else
debug(8, "readfile_elf: %x 0x%x \n", sectsize, insn);
addprogram (freemem, insn, &breakpoint);
sectsize -= len;
}
}
}
 
if (str_tbl) {
i = 0;
while(syms--) {
if (sym_tbl[i].st_name && sym_tbl[i].st_info && ELF_SHORT_H(sym_tbl[i].st_shndx) < 0x8000) {
add_label(ELF_LONG_H(sym_tbl[i].st_value), &str_tbl[ELF_LONG_H(sym_tbl[i].st_name)]);
debug (8, "%08lx(%s): %x %x %x\n", ELF_LONG_H(sym_tbl[i].st_value), &str_tbl[ELF_LONG_H(sym_tbl[i].st_name)], sym_tbl[i].st_info, sym_tbl[i].st_other, ELF_SHORT_H(sym_tbl[i].st_shndx));
}
i++;
}
}
}
 
/* Identify file type and call appropriate readfile_X routine. It only
handles orX-coff-big executables at the moment. */
 
void identifyfile(char *filename)
{
FILE *inputfs;
struct COFF_filehdr coffhdr;
struct elf32_hdr elfhdr;
if (!(inputfs = fopen(filename, "r"))) {
perror(filename);
fflush(stdout);
fflush(stderr);
exit(1);
}
if (fread(&coffhdr, sizeof(coffhdr), 1, inputfs) == 1) {
if (COFF_SHORT_H(coffhdr.f_magic) == 0x17a) {
unsigned long opthdr_size;
PRINTF("COFF magic: 0x%.4x\n", COFF_SHORT_H(coffhdr.f_magic));
PRINTF("COFF flags: 0x%.4x\n", COFF_SHORT_H(coffhdr.f_flags));
PRINTF("COFF symptr: 0x%.8lx\n", COFF_LONG_H(coffhdr.f_symptr));
if ((COFF_SHORT_H(coffhdr.f_flags) & COFF_F_EXEC) != COFF_F_EXEC) {
PRINTF("This COFF is not an executable.\n");
exit(1);
}
opthdr_size = COFF_SHORT_H(coffhdr.f_opthdr);
if (opthdr_size != sizeof(COFF_AOUTHDR)) {
PRINTF("COFF optional header is missing or not recognized.\n");
PRINTF("COFF f_opthdr: 0x%.2lx\n", opthdr_size);
exit(1);
}
fclose(inputfs);
readfile_coff(filename, COFF_SHORT_H(coffhdr.f_nscns));
readsyms_coff(filename, COFF_LONG_H(coffhdr.f_symptr), COFF_LONG_H(coffhdr.f_nsyms));
return;
}
else {
PRINTF("Not COFF file format\n");
fseek(inputfs, 0, SEEK_SET);
}
}
if (fread(&elfhdr, sizeof(elfhdr), 1, inputfs) == 1) {
if (elfhdr.e_ident[0] == 0x7f && elfhdr.e_ident[1] == 0x45 && elfhdr.e_ident[2] == 0x4c && elfhdr.e_ident[3] == 0x46) {
PRINTF("ELF type: 0x%.4x\n", ELF_SHORT_H(elfhdr.e_type));
PRINTF("ELF machine: 0x%.4x\n", ELF_SHORT_H(elfhdr.e_machine));
PRINTF("ELF version: 0x%.8lx\n", ELF_LONG_H(elfhdr.e_version));
PRINTF("ELF sec = %d\n", ELF_SHORT_H(elfhdr.e_shnum));
if (ELF_SHORT_H(elfhdr.e_type) != ET_EXEC ) {
PRINTF("This ELF is not an executable.\n");
exit(1);
}
fclose(inputfs);
readfile_elf(filename);
return;
}
else {
PRINTF("Not ELF file format.\n");
fseek(inputfs, 0, SEEK_SET);
}
}
perror("identifyfile2");
fclose(inputfs);
 
return;
}
 
 
/* Loads file to memory starting at address startaddr and returns freemem. */
unsigned long loadcode(char *filename, oraddr_t startaddr, oraddr_t virtphy_transl)
{
int breakpoint = 0;
 
transl_error = 0;
transl_table = virtphy_transl;
freemem = startaddr;
PRINTF("loadcode: filename %s startaddr=%"PRIxADDR" virtphy_transl=%"PRIxADDR"\n",
filename, startaddr, virtphy_transl);
identifyfile(filename);
 
#if IMM_STATS
{
int i = 0, a = 0, b = 0, c = 0;
PRINTF ("index:arith/branch/jump\n");
for (i = 0; i < 33; i++)
PRINTF ("%2i:\t%3.0f%% / %3.0f%%/ %3.0f%%\t%5i / %5i / %5i\n", i,
100.* (a += bcnt[i][0])/bsum[0], 100.* (b += bcnt[i][1])/bsum[1],
100.* (c += bcnt[i][2])/bsum[2], bcnt[i][0], bcnt[i][1], bcnt[i][2]);
PRINTF ("\nsum %i %i %i\n", bsum[0], bsum[1], bsum[2]);
}
#endif
 
if (transl_error)
return -1;
else
return translate(freemem,&breakpoint);
}
/abstract.h
0,0 → 1,178
/* abstract.h -- Abstract entities header file
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
#include <stdio.h>
 
#define DEFAULT_MEMORY_START 0
#define DEFAULT_MEMORY_LEN 0x800000
#define STACK_SIZE 20
#define LABELNAME_LEN 50
#define INSNAME_LEN 15
#define OPERANDNAME_LEN 50
 
#define MAX_OPERANDS (5)
 
#define OP_MEM_ACCESS 0x80000000
 
/* Cache tag types. */
#define CT_NONE 0
#define CT_VIRTUAL 1
#define CT_PHYSICAL 2
 
/* Instruction queue */
struct iqueue_entry {
int insn_index;
uint32_t insn;
oraddr_t insn_addr;
};
 
struct mem_ops {
/* Read functions */
uint32_t (*readfunc32)(oraddr_t, void *);
uint16_t (*readfunc16)(oraddr_t, void *);
uint8_t (*readfunc8)(oraddr_t, void *);
 
/* Read functions' data */
void *read_dat8;
void *read_dat16;
void *read_dat32;
 
/* Write functions */
void (*writefunc32)(oraddr_t, uint32_t, void *);
void (*writefunc16)(oraddr_t, uint16_t, void *);
void (*writefunc8)(oraddr_t, uint8_t, void *);
 
/* Write functions' data */
void *write_dat8;
void *write_dat16;
void *write_dat32;
 
/* Program load function. If you have unwritteable memory but you would like
* it if a program would be loaded here, make sure to set this. If this is
* not set, then writefunc8 will be called to load the program */
void (*writeprog32)(oraddr_t, uint32_t, void *);
void (*writeprog8)(oraddr_t, uint8_t, void *);
 
void *writeprog32_dat;
void *writeprog8_dat;
 
/* Read/Write delays */
int delayr;
int delayw;
 
/* Name of log file */
const char *log;
};
 
/* Memory regions assigned to devices */
struct dev_memarea {
struct dev_memarea *next;
oraddr_t addr_mask;
oraddr_t addr_compare;
uint32_t size;
oraddr_t size_mask; /* Address mask, calculated out of size */
int valid; /* This bit reflects the memory controler valid bit */
FILE *log; /* log file if this device is to be logged, NULL otherwise */
 
struct mem_ops ops;
struct mem_ops direct_ops;
};
 
extern void dumpmemory(oraddr_t from, oraddr_t to, int disasm, int nl);
extern uint32_t eval_mem32(oraddr_t memaddr,int*);
extern uint16_t eval_mem16(oraddr_t memaddr,int*);
extern uint8_t eval_mem8(oraddr_t memaddr,int*);
void set_mem32(oraddr_t memaddr, uint32_t value,int*);
extern void set_mem16(oraddr_t memaddr, uint16_t value,int*);
extern void set_mem8(oraddr_t memaddr, uint8_t value,int*);
 
uint32_t evalsim_mem32(oraddr_t, oraddr_t);
uint16_t evalsim_mem16(oraddr_t, oraddr_t);
uint8_t evalsim_mem8(oraddr_t, oraddr_t);
 
void setsim_mem32(oraddr_t, oraddr_t, uint32_t);
void setsim_mem16(oraddr_t, oraddr_t, uint16_t);
void setsim_mem8(oraddr_t, oraddr_t, uint8_t);
 
/* Closes files, etc. */
void done_memory_table (void);
 
/* Displays current memory configuration */
void memory_table_status (void);
 
/* Register memory area */
struct dev_memarea *reg_mem_area(oraddr_t addr, uint32_t size, unsigned mc_dev,
struct mem_ops *ops);
 
/* Adjusts the read and write delays for the memory area pointed to by mem. */
void adjust_rw_delay(struct dev_memarea *mem, int delayr, int delayw);
 
/* Sets the valid bit (Used only by memory controllers) */
void set_mem_valid(struct dev_memarea *mem, int valid);
 
/* Check if access is to registered area of memory. */
struct dev_memarea *verify_memoryarea(oraddr_t addr);
 
/* Outputs time in pretty form to dest string. */
char *generate_time_pretty (char *dest, long time_ps);
 
/* Returns 32-bit values from mem array. */
uint32_t eval_insn(oraddr_t, int *);
 
uint32_t eval_insn_direct(oraddr_t memaddr, int through_mmu);
 
uint8_t eval_direct8(oraddr_t memaddr, int through_mmu, int through_dc);
uint16_t eval_direct16(oraddr_t memaddr, int through_mmu, int through_dc);
uint32_t eval_direct32(oraddr_t addr, int through_mmu, int through_dc);
 
void set_direct8(oraddr_t, uint8_t, int, int);
void set_direct16(oraddr_t, uint16_t, int, int);
void set_direct32(oraddr_t, uint32_t, int, int);
 
/* Same as set_direct32, but it also writes to memory that is non-writeable to
* the rest of the sim. Used to do program loading. */
void set_program32(oraddr_t memaddr, uint32_t value);
void set_program8(oraddr_t memaddr, uint8_t value);
 
/* Temporary variable to increase speed. */
extern struct dev_memarea *cur_area;
 
/* These are set by mmu if cache inhibit bit is set for current acces. */
extern int data_ci, insn_ci;
 
/* Added by MM */
#ifndef LONGEST
#define LONGEST long long
#define ULONGEST unsigned long long
#endif /* ! LONGEST */
 
/* Returns the page that addr belongs to */
#define IADDR_PAGE(addr) ((addr) & config.immu.page_mask)
#define DADDR_PAGE(addr) ((addr) & config.dmmu.page_mask)
 
/* History of execution */
#define HISTEXEC_LEN 200
struct hist_exec {
oraddr_t addr;
struct hist_exec *prev;
struct hist_exec *next;
};
 
extern struct hist_exec *hist_exec_tail;
/execute.h
0,0 → 1,85
/* execute.h -- Header file for architecture dependent execute.c
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
#if DYNAMIC_EXECUTION
#include "dyn_rec.h"
#endif
 
struct cpu_state {
/* General purpose registers. */
uorreg_t reg[MAX_GPRS];
 
/* Sprs */
uorreg_t sprs[MAX_SPRS];
 
/* Effective address of instructions that have an effective address. This is
* only used to get dump_exe_log correct */
oraddr_t insn_ea;
 
/* Is current instruction in execution in a delay slot? */
int delay_insn;
 
/* Program counter (and translated PC) */
oraddr_t pc;
 
/* Delay instruction effective address register */
oraddr_t pc_delay;
 
/* Decoding of the just executed instruction. Only used in analysis(). */
struct iqueue_entry iqueue;
 
/* decoding of the instruction that was executed before this one. Only used
* in analysis(). */
struct iqueue_entry icomplet;
 
#if DYNAMIC_EXECUTION
/* Current page in execution */
struct dyn_page *curr_page;
 
/* Pointers to recompiled pages */
struct dyn_page **dyn_pages;
 
/* Micro operation queue. Only used to speed up recompile_page */
struct op_queue *opqs;
 
/* Set if all temporaries are stored */
int ts_current;
 
/* The contents of the temporaries. Only used in except_handle */
uorreg_t t0;
uorreg_t t1;
uorreg_t t2;
#endif
};
 
extern struct cpu_state cpu_state;
 
#define CURINSN(INSN) (strcmp(cur->insn, (INSN)) == 0)
 
/*extern machword eval_operand(char *srcoperand,int* breakpoint);
extern void set_operand(char *dstoperand, unsigned long value,int* breakpoint);*/
void dumpreg();
inline void dump_exe_log();
inline int cpu_clock ();
void cpu_reset ();
uorreg_t evalsim_reg(unsigned int regno);
void setsim_reg(unsigned int regno, uorreg_t value);
extern oraddr_t pcnext;
int depend_operands(struct iqueue_entry *prev, struct iqueue_entry *next);
/trace.c
0,0 → 1,54
/* trace.c -- Simulator breakpoints
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
#include <stdio.h>
 
#include "config.h"
 
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
 
#include "port.h"
#include "arch.h"
#include "abstract.h"
#include "labels.h"
#include "sim-config.h"
#include "trace.h"
 
/* Set instruction execution breakpoint. */
 
void set_insnbrkpoint(oraddr_t addr)
{
addr &= ~ADDR_C(3); /* 32-bit aligned */
if (!verify_memoryarea(addr))
PRINTF("WARNING: This breakpoint is out of the simulated memory range.\n");
 
if (has_breakpoint (addr)) {
remove_breakpoint (addr);
PRINTF("\nBreakpoint at 0x%"PRIxADDR" cleared.\n", addr);
} else {
add_breakpoint (addr);
PRINTF("\nBreakpoint at 0x%"PRIxADDR" set.\n", addr);
}
 
return;
}
 
/stats.h
0,0 → 1,109
/* stats.h -- Header file for stats.c
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
#define DSTATS_LEN 3000
#define SSTATS_LEN 300
#define FSTATS_LEN 200
#define RAW_RANGE 1000
 
/* Used by safe division - increment divisor by one if it is zero */
#define SD(X) (X != 0 ? X : 1)
 
struct dstats_entry {
int insn1;
int insn2;
int cnt_dynamic;
int depend;
};
 
struct sstats_entry {
int insn;
int cnt_dynamic;
}; /* single stats */
 
struct fstats_entry {
enum insn_type insn1;
enum insn_type insn2;
int cnt_dynamic;
int depend;
}; /* functional units stats */
 
struct bpbstat {
int hit;
int miss;
int correct;
int incorrect;
};
 
struct bticstat {
int hit;
int miss;
};
 
struct mstats_entry {
int byteadd;
int bf[2][2]; /* [taken][fwd/bwd] */
int bnf[2][2]; /* [taken][fwd/bwd] */
struct bpbstat bpb;
struct bticstat btic;
}; /* misc units stats */
 
struct cachestats_entry {
int readhit;
int readmiss;
int writehit;
int writemiss;
}; /* cache stats */
 
struct immustats_entry {
int fetch_tlbhit;
int fetch_tlbmiss;
int fetch_pagefaults;
}; /* IMMU stats */
 
struct dmmustats_entry {
int loads_tlbhit;
int loads_tlbmiss;
int loads_pagefaults;
int stores_tlbhit;
int stores_tlbmiss;
int stores_pagefaults;
}; /* DMMU stats */
 
struct raw_stats {
int reg[64];
int range[RAW_RANGE];
}; /* RAW hazard stats */
 
/* Renamed mstats to or1k_mstats because Mac OS X has a lib function called mstats */
extern struct mstats_entry or1k_mstats;
extern struct sstats_entry sstats[SSTATS_LEN];
extern struct dstats_entry dstats[DSTATS_LEN];
extern struct fstats_entry fstats[FSTATS_LEN];
extern struct cachestats_entry ic_stats;
extern struct cachestats_entry dc_stats;
extern struct immustats_entry immu_stats;
extern struct dmmustats_entry dmmu_stats;
extern struct raw_stats raw_stats;
 
extern void addsstats(int item, int cnt_dynamic);
extern void adddstats(int item1, int item2, int cnt_dynamic, int depend);
extern void addfstats(enum insn_type item1, enum insn_type item2, int cnt_dynamic, int depend);
extern void initstats();
extern void printstats();
/labels.c
0,0 → 1,153
/* abstract.c -- Abstract entities, handling labels
Copyright (C) 2001 Marko Mlinar, markom@opencores.org
 
This file is part of OpenRISC 1000 Architectural Simulator.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
/* Abstract memory and routines that go with this. I need to
add all sorts of other abstract entities. Currently we have
only memory. */
 
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
 
#include "config.h"
 
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
 
#include "port.h"
#include "config.h"
 
#include "arch.h"
#include "sim-config.h"
#include "labels.h"
 
static struct label_entry *label_hash[LABELS_HASH_SIZE];
struct breakpoint_entry *breakpoints;
 
void init_labels () {
int i;
for (i = 0; i < LABELS_HASH_SIZE; i++)
label_hash[i] = NULL;
}
 
void add_label (oraddr_t addr, char *name) {
struct label_entry **tmp;
tmp = &(label_hash[addr % LABELS_HASH_SIZE]);
for (; *tmp; tmp = &((*tmp)->next));
*tmp = malloc(sizeof(**tmp));
(*tmp)->name = malloc(strlen(name) + 1);
(*tmp)->addr = addr;
strcpy((*tmp)->name, name);
(*tmp)->next = NULL;
}
 
struct label_entry *get_label (oraddr_t addr) {
struct label_entry *tmp = label_hash[addr % LABELS_HASH_SIZE];
while (tmp) {
if (tmp->addr == addr)
return tmp;
tmp = tmp->next;
}
return NULL;
}
 
struct label_entry *find_label (char *name) {
int i;
for (i = 0; i < LABELS_HASH_SIZE; i++) {
struct label_entry *tmp = label_hash[i % LABELS_HASH_SIZE];
while (tmp) {
if (strcmp (tmp->name, name) == 0)
return tmp;
tmp = tmp->next;
}
}
return NULL;
}
 
/* Searches mem array for a particular label and returns label's address.
If label does not exist, returns 0. */
oraddr_t eval_label (char *name) {
struct label_entry *le;
char *plus;
char *minus;
int positive_offset = 0;
int negative_offset = 0;
 
if ((plus = strchr(name, '+'))) {
*plus = '\0';
positive_offset = atoi(++plus);
}
 
if ((minus = strchr(name, '-'))) {
*minus = '\0';
negative_offset = atoi(++minus);
}
le = find_label (name);
if (!le)
return 0;
return le->addr + positive_offset - negative_offset;
}
 
void init_breakpoints () {
breakpoints = 0;
}
 
void add_breakpoint (oraddr_t addr) {
struct breakpoint_entry *tmp;
tmp = (struct breakpoint_entry *) malloc (sizeof (struct breakpoint_entry));
tmp->next = breakpoints;
tmp->addr = addr;
breakpoints = tmp;
}
 
void remove_breakpoint (oraddr_t addr) {
struct breakpoint_entry **tmp = &breakpoints;
while (*tmp) {
if ((*tmp)->addr == addr) {
struct breakpoint_entry *t = *tmp;
(*tmp) = t->next;
free (t);
} else
tmp = &((*tmp)->next);
}
}
 
void print_breakpoints () {
struct breakpoint_entry **tmp = &breakpoints;
int i = 1;
printf ("---[breakpoints]------------------\n");
while (*tmp) {
printf ("Breakpoint %i at 0x%"PRIxADDR"\n", i, (*tmp)->addr);
tmp = &((*tmp)->next);
}
printf ("---[breakpoints end]--------------\n");
}
 
inline int has_breakpoint (oraddr_t addr) {
struct breakpoint_entry *tmp = breakpoints;
while (tmp) {
if (tmp->addr == addr)
return 1;
tmp = tmp->next;
}
return 0;
}
labels.c Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: parse.h =================================================================== --- parse.h (nonexistent) +++ parse.h (revision 1765) @@ -0,0 +1,41 @@ +/* parse.h -- Header file for parse.c + Copyright (C) 1999 Damjan Lampret, lampret@opencores.org + +This file is part of OpenRISC 1000 Architectural Simulator. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Here we define some often used caharcters in assembly files. +This wil probably go into architecture dependent directory. */ + +#define COMMENT_CHAR '#' +#define DIRECTIVE_CHAR '.' +#define LABELEND_CHAR ":" +/*#define OPERAND_DELIM ","*/ + +/* Strip whitespace from the start and end of STRING. Return a pointer + into STRING. */ +#ifndef whitespace +#define whitespace(a) ((a) == '\t' ? 1 : ((a) == ' '? 1 : 0)) +#endif + +/* Strips white spaces at beginning and at the end of the string */ +char *stripwhite (char *string); + +/* This function is very similar to strncpy, except it null terminates the string */ +char *strstrip (char *dst, const char *src, int n); + +/* Loads file to memory starting at address startaddr and returns freemem. */ +unsigned long loadcode(char *filename, oraddr_t startaddr, oraddr_t virtphy_transl); Index: trace.h =================================================================== --- trace.h (nonexistent) +++ trace.h (revision 1765) @@ -0,0 +1,2 @@ + +void set_insnbrkpoint(oraddr_t addr); Index: labels.h =================================================================== --- labels.h (nonexistent) +++ labels.h (revision 1765) @@ -0,0 +1,58 @@ +/* labels.h -- Abstract entities header file handling labels + Copyright (C) 2001 Marko Mlinar, markom@opencores.org + +This file is part of OpenRISC 1000 Architectural Simulator. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef _LABELS_H_ +#define _LABELS_H_ + +#define LABELS_HASH_SIZE 119 + +/* Structure for holding one label per particular memory location */ +struct label_entry { + char *name; + oraddr_t addr; + struct label_entry *next; +}; + +struct breakpoint_entry { + oraddr_t addr; + struct breakpoint_entry *next; +}; + +/* Label handling */ +void init_labels(); +void add_label (oraddr_t addr, char *name); +struct label_entry *get_label (oraddr_t addr); +struct label_entry *find_label (char *name); + +/* Searches mem array for a particular label and returns label's address. + If label does not exist, returns 0. */ +oraddr_t eval_label (char *name); + +/* Breakpoint handling */ +void breakpoints_init (); +void add_breakpoint (oraddr_t addr); +void remove_breakpoint (oraddr_t addr); +void print_breakpoints (); +int has_breakpoint (oraddr_t addr); +void init_breakpoints (); + +extern struct breakpoint_entry *breakpoints; +#define CHECK_BREAKPOINTS (breakpoints) + +#endif /* _LABELS_H_ */
labels.h Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: coff.h =================================================================== --- coff.h (nonexistent) +++ coff.h (revision 1765) @@ -0,0 +1,457 @@ +#if HAVE_CONFIG_H +#include +#endif + +/* This file is derived from the GAS 2.1.4 assembler control file. + The GAS product is under the GNU Public License, version 2 or later. + As such, this file is also under that license. + + If the file format changes in the COFF object, this file should be + subsequently updated to reflect the changes. + + The actual loader module only uses a few of these structures. The full + set is documented here because I received the full set. If you wish + more information about COFF, then O'Reilly has a very excellent book. +*/ + +#define E_SYMNMLEN 8 /* Number of characters in a symbol name */ +#define E_FILNMLEN 14 /* Number of characters in a file name */ +#define E_DIMNUM 4 /* Number of array dimensions in auxiliary entry */ + +/* + * These defines are byte order independent. There is no alignment of fields + * permitted in the structures. Therefore they are declared as characters + * and the values loaded from the character positions. It also makes it + * nice to have it "endian" independent. + */ +#if !defined(WORDS_BIGENDIAN) +/* Load a short int from the following tables with little-endian formats */ +#define COFF_SHORT_L SWAP_ENDIAN_SHORT +/* Load a long int from the following tables with little-endian formats */ +#define COFF_LONG_L SWAP_ENDIAN_LONG +/* Load a short int from the following tables with big-endian formats */ +#define COFF_SHORT_H KEEP_ENDIAN_SHORT +/* Load a long int from the following tables with big-endian formats */ +#define COFF_LONG_H KEEP_ENDIAN_LONG +#else +#define COFF_SHORT_L KEEP_ENDIAN_SHORT +#define COFF_LONG_L KEEP_ENDIAN_LONG +#define COFF_SHORT_H SWAP_ENDIAN_SHORT +#define COFF_LONG_H SWAP_ENDIAN_LONG +#endif + +#define SWAP_ENDIAN_SHORT(ps) ((short)(((unsigned short)((unsigned char)ps[1])<<8)|\ + ((unsigned short)((unsigned char)ps[0])))) + +#define SWAP_ENDIAN_LONG(ps) (((long)(((unsigned long)((unsigned char)ps[3])<<24) |\ + ((unsigned long)((unsigned char)ps[2])<<16) |\ + ((unsigned long)((unsigned char)ps[1])<<8) |\ + ((unsigned long)((unsigned char)ps[0]))))) + +#define KEEP_ENDIAN_SHORT(ps) ((short)(((unsigned short)((unsigned char)ps[0])<<8)|\ + ((unsigned short)((unsigned char)ps[1])))) + +#define KEEP_ENDIAN_LONG(ps) (((long)(((unsigned long)((unsigned char)ps[0])<<24) |\ + ((unsigned long)((unsigned char)ps[1])<<16) |\ + ((unsigned long)((unsigned char)ps[2])<<8) |\ + ((unsigned long)((unsigned char)ps[3]))))) + +/* These may be overridden later by brain dead implementations which generate + a big-endian header with little-endian data. In that case, generate a + replacement macro which tests a flag and uses either of the two above + as appropriate. */ + +#define COFF_LONG(v) COFF_LONG_L(v) +#define COFF_SHORT(v) COFF_SHORT_L(v) + +/*** coff information for Intel 386/486. */ + +/********************** FILE HEADER **********************/ + +struct COFF_filehdr { + char f_magic[2]; /* magic number */ + char f_nscns[2]; /* number of sections */ + char f_timdat[4]; /* time & date stamp */ + char f_symptr[4]; /* file pointer to symtab */ + char f_nsyms[4]; /* number of symtab entries */ + char f_opthdr[2]; /* sizeof(optional hdr) */ + char f_flags[2]; /* flags */ +}; + +/* + * Bits for f_flags: + * + * F_RELFLG relocation info stripped from file + * F_EXEC file is executable (i.e. no unresolved external + * references) + * F_LNNO line numbers stripped from file + * F_LSYMS local symbols stripped from file + * F_MINMAL this is a minimal object file (".m") output of fextract + * F_UPDATE this is a fully bound update file, output of ogen + * F_SWABD this file has had its bytes swabbed (in names) + * F_AR16WR this file has the byte ordering of an AR16WR + * (e.g. 11/70) machine + * F_AR32WR this file has the byte ordering of an AR32WR machine + * (e.g. vax and iNTEL 386) + * F_AR32W this file has the byte ordering of an AR32W machine + * (e.g. 3b,maxi) + * F_PATCH file contains "patch" list in optional header + * F_NODF (minimal file only) no decision functions for + * replaced functions + */ + +#define COFF_F_RELFLG 0000001 +#define COFF_F_EXEC 0000002 +#define COFF_F_LNNO 0000004 +#define COFF_F_LSYMS 0000010 +#define COFF_F_MINMAL 0000020 +#define COFF_F_UPDATE 0000040 +#define COFF_F_SWABD 0000100 +#define COFF_F_AR16WR 0000200 +#define COFF_F_AR32WR 0000400 +#define COFF_F_AR32W 0001000 +#define COFF_F_PATCH 0002000 +#define COFF_F_NODF 0002000 + +#define COFF_I386MAGIC 0x14c /* Linux's system */ + +#if 0 /* Perhaps, someday, these formats may be used. */ +#define COFF_I386PTXMAGIC 0x154 +#define COFF_I386AIXMAGIC 0x175 /* IBM's AIX system */ +#define COFF_I386BADMAG(x) ((COFF_SHORT((x).f_magic) != COFF_I386MAGIC) \ + && COFF_SHORT((x).f_magic) != COFF_I386PTXMAGIC \ + && COFF_SHORT((x).f_magic) != COFF_I386AIXMAGIC) +#else +#define COFF_I386BADMAG(x) (COFF_SHORT((x).f_magic) != COFF_I386MAGIC) +#endif + +#define COFF_FILHDR struct COFF_filehdr +#define COFF_FILHSZ sizeof(COFF_FILHDR) + +/********************** AOUT "OPTIONAL HEADER" **********************/ + +/* Linux COFF must have this "optional" header. Standard COFF has no entry + location for the "entry" point. They normally would start with the first + location of the .text section. This is not a good idea for linux. So, + the use of this "optional" header is not optional. It is required. + + Do not be tempted to assume that the size of the optional header is + a constant and simply index the next byte by the size of this structure. + Use the 'f_opthdr' field in the main coff header for the size of the + structure actually written to the file!! +*/ + +typedef struct +{ + char magic[2]; /* type of file */ + char vstamp[2]; /* version stamp */ + char tsize[4]; /* text size in bytes, padded to FW bdry */ + char dsize[4]; /* initialized data " " */ + char bsize[4]; /* uninitialized data " " */ + char entry[4]; /* entry pt. */ + char text_start[4]; /* base of text used for this file */ + char data_start[4]; /* base of data used for this file */ +} +COFF_AOUTHDR; + +#define COFF_AOUTSZ (sizeof(COFF_AOUTHDR)) + +#define COFF_STMAGIC 0401 +#define COFF_OMAGIC 0404 +#define COFF_JMAGIC 0407 /* dirty text and data image, can't share */ +#define COFF_DMAGIC 0410 /* dirty text segment, data aligned */ +#define COFF_ZMAGIC 0413 /* The proper magic number for executables */ +#define COFF_SHMAGIC 0443 /* shared library header */ + +/********************** STORAGE CLASSES **********************/ + +/* This used to be defined as -1, but now n_sclass is unsigned. */ +#define C_EFCN 0xff /* physical end of function */ +#define C_NULL 0 +#define C_AUTO 1 /* automatic variable */ +#define C_EXT 2 /* external symbol */ +#define C_STAT 3 /* static */ +#define C_REG 4 /* register variable */ +#define C_EXTDEF 5 /* external definition */ +#define C_LABEL 6 /* label */ +#define C_ULABEL 7 /* undefined label */ +#define C_MOS 8 /* member of structure */ +#define C_ARG 9 /* function argument */ +#define C_STRTAG 10 /* structure tag */ +#define C_MOU 11 /* member of union */ +#define C_UNTAG 12 /* union tag */ +#define C_TPDEF 13 /* type definition */ +#define C_USTATIC 14 /* undefined static */ +#define C_ENTAG 15 /* enumeration tag */ +#define C_MOE 16 /* member of enumeration */ +#define C_REGPARM 17 /* register parameter */ +#define C_FIELD 18 /* bit field */ +#define C_AUTOARG 19 /* auto argument */ +#define C_LASTENT 20 /* dummy entry (end of block) */ +#define C_BLOCK 100 /* ".bb" or ".eb" */ +#define C_FCN 101 /* ".bf" or ".ef" */ +#define C_EOS 102 /* end of structure */ +#define C_FILE 103 /* file name */ +#define C_LINE 104 /* line # reformatted as symbol table entry */ +#define C_ALIAS 105 /* duplicate tag */ +#define C_HIDDEN 106 /* ext symbol in dmert public lib */ + +#define C_WEAKEXT 127 /* weak symbol -- GNU extension */ + +/* New storage classes for TI COFF */ +#define C_UEXT 19 /* Tentative external definition */ +#define C_STATLAB 20 /* Static load time label */ +#define C_EXTLAB 21 /* External load time label */ +#define C_SYSTEM 23 /* System Wide variable */ + +/* New storage classes for WINDOWS_NT */ +#define C_SECTION 104 /* section name */ +#define C_NT_WEAK 105 /* weak external */ + + /* New storage classes for 80960 */ + +/* C_LEAFPROC is obsolete. Use C_LEAFEXT or C_LEAFSTAT */ +#define C_LEAFPROC 108 /* Leaf procedure, "call" via BAL */ + +#define C_SCALL 107 /* Procedure reachable via system call */ +#define C_LEAFEXT 108 /* External leaf */ +#define C_LEAFSTAT 113 /* Static leaf */ +#define C_OPTVAR 109 /* Optimized variable */ +#define C_DEFINE 110 /* Preprocessor #define */ +#define C_PRAGMA 111 /* Advice to compiler or linker */ +#define C_SEGMENT 112 /* 80960 segment name */ + + /* Storage classes for m88k */ +#define C_SHADOW 107 /* shadow symbol */ +#define C_VERSION 108 /* coff version symbol */ + + /* New storage classes for RS/6000 */ +#define C_HIDEXT 107 /* Un-named external symbol */ +#define C_BINCL 108 /* Marks beginning of include file */ +#define C_EINCL 109 /* Marks ending of include file */ + + /* storage classes for stab symbols for RS/6000 */ +#define C_GSYM (0x80) +#define C_LSYM (0x81) +#define C_PSYM (0x82) +#define C_RSYM (0x83) +#define C_RPSYM (0x84) +#define C_STSYM (0x85) +#define C_TCSYM (0x86) +#define C_BCOMM (0x87) +#define C_ECOML (0x88) +#define C_ECOMM (0x89) +#define C_DECL (0x8c) +#define C_ENTRY (0x8d) +#define C_FUN (0x8e) +#define C_BSTAT (0x8f) +#define C_ESTAT (0x90) + +/* Storage classes for Thumb symbols */ +#define C_THUMBEXT (128 + C_EXT) /* 130 */ +#define C_THUMBSTAT (128 + C_STAT) /* 131 */ +#define C_THUMBLABEL (128 + C_LABEL) /* 134 */ +#define C_THUMBEXTFUNC (C_THUMBEXT + 20) /* 150 */ +#define C_THUMBSTATFUNC (C_THUMBSTAT + 20) /* 151 */ + +/********************** SECTION HEADER **********************/ + +struct COFF_scnhdr { + char s_name[8]; /* section name */ + char s_paddr[4]; /* physical address, aliased s_nlib */ + char s_vaddr[4]; /* virtual address */ + char s_size[4]; /* section size */ + char s_scnptr[4]; /* file ptr to raw data for section */ + char s_relptr[4]; /* file ptr to relocation */ + char s_lnnoptr[4]; /* file ptr to line numbers */ + char s_nreloc[2]; /* number of relocation entries */ + char s_nlnno[2]; /* number of line number entries */ + char s_flags[4]; /* flags */ +}; + +#define COFF_SCNHDR struct COFF_scnhdr +#define COFF_SCNHSZ sizeof(COFF_SCNHDR) + +/* + * names of "special" sections + */ + +#define COFF_TEXT ".text" +#define COFF_DATA ".data" +#define COFF_BSS ".bss" +#define COFF_COMMENT ".comment" +#define COFF_LIB ".lib" + +#define COFF_SECT_TEXT 0 /* Section for instruction code */ +#define COFF_SECT_DATA 1 /* Section for initialized globals */ +#define COFF_SECT_BSS 2 /* Section for un-initialized globals */ +#define COFF_SECT_REQD 3 /* Minimum number of sections for good file */ + +#define COFF_STYP_REG 0x00 /* regular segment */ +#define COFF_STYP_DSECT 0x01 /* dummy segment */ +#define COFF_STYP_NOLOAD 0x02 /* no-load segment */ +#define COFF_STYP_GROUP 0x04 /* group segment */ +#define COFF_STYP_PAD 0x08 /* .pad segment */ +#define COFF_STYP_COPY 0x10 /* copy section */ +#define COFF_STYP_TEXT 0x20 /* .text segment */ +#define COFF_STYP_DATA 0x40 /* .data segment */ +#define COFF_STYP_BSS 0x80 /* .bss segment */ +#define COFF_STYP_INFO 0x200 /* .comment section */ +#define COFF_STYP_OVER 0x400 /* overlay section */ +#define COFF_STYP_LIB 0x800 /* library section */ + +/* + * Shared libraries have the following section header in the data field for + * each library. + */ + +struct COFF_slib { + char sl_entsz[4]; /* Size of this entry */ + char sl_pathndx[4]; /* size of the header field */ +}; + +#define COFF_SLIBHD struct COFF_slib +#define COFF_SLIBSZ sizeof(COFF_SLIBHD) + +/********************** LINE NUMBERS **********************/ + +/* 1 line number entry for every "breakpointable" source line in a section. + * Line numbers are grouped on a per function basis; first entry in a function + * grouping will have l_lnno = 0 and in place of physical address will be the + * symbol table index of the function name. + */ + +struct COFF_lineno { + union { + char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ + char l_paddr[4]; /* (physical) address of line number */ + } l_addr; + char l_lnno[2]; /* line number */ +}; + +#define COFF_LINENO struct COFF_lineno +#define COFF_LINESZ 6 + +/********************** SYMBOLS **********************/ + +#define COFF_E_SYMNMLEN 8 /* # characters in a short symbol name */ +#define COFF_E_FILNMLEN 14 /* # characters in a file name */ +#define COFF_E_DIMNUM 4 /* # array dimensions in auxiliary entry */ + +/* + * All symbols and sections have the following definition + */ + +struct COFF_syment +{ + union { + char e_name[E_SYMNMLEN]; /* Symbol name (first 8 characters) */ + struct { + char e_zeroes[4]; /* Leading zeros */ + char e_offset[4]; /* Offset if this is a header section */ + } e; + } e; + + char e_value[4]; /* Value (address) of the segment */ + char e_scnum[2]; /* Section number */ + char e_type[2]; /* Type of section */ + char e_sclass[1]; /* Loader class */ + char e_numaux[1]; /* Number of auxiliary entries which follow */ +}; + +#define COFF_N_BTMASK (0xf) /* Mask for important class bits */ +#define COFF_N_TMASK (0x30) /* Mask for important type bits */ +#define COFF_N_BTSHFT (4) /* # bits to shift class field */ +#define COFF_N_TSHIFT (2) /* # bits to shift type field */ + +/* + * Auxiliary entries because the main table is too limiting. + */ + +union COFF_auxent { + +/* + * Debugger information + */ + + struct { + char x_tagndx[4]; /* str, un, or enum tag indx */ + union { + struct { + char x_lnno[2]; /* declaration line number */ + char x_size[2]; /* str/union/array size */ + } x_lnsz; + char x_fsize[4]; /* size of function */ + } x_misc; + + union { + struct { /* if ISFCN, tag, or .bb */ + char x_lnnoptr[4]; /* ptr to fcn line # */ + char x_endndx[4]; /* entry ndx past block end */ + } x_fcn; + + struct { /* if ISARY, up to 4 dimen. */ + char x_dimen[E_DIMNUM][2]; + } x_ary; + } x_fcnary; + + char x_tvndx[2]; /* tv index */ + } x_sym; + +/* + * Source file names (debugger information) + */ + + union { + char x_fname[E_FILNMLEN]; + struct { + char x_zeroes[4]; + char x_offset[4]; + } x_n; + } x_file; + +/* + * Section information + */ + + struct { + char x_scnlen[4]; /* section length */ + char x_nreloc[2]; /* # relocation entries */ + char x_nlinno[2]; /* # line numbers */ + } x_scn; + +/* + * Transfer vector (branch table) + */ + + struct { + char x_tvfill[4]; /* tv fill value */ + char x_tvlen[2]; /* length of .tv */ + char x_tvran[2][2]; /* tv range */ + } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ +}; + +#define COFF_SYMENT struct COFF_syment +#define COFF_SYMESZ 18 +#define COFF_AUXENT union COFF_auxent +#define COFF_AUXESZ 18 + +#define COFF_ETEXT "etext" + +/********************** RELOCATION DIRECTIVES **********************/ + +struct COFF_reloc { + char r_vaddr[4]; /* Virtual address of item */ + char r_symndx[4]; /* Symbol index in the symtab */ + char r_type[2]; /* Relocation type */ +}; + +#define COFF_RELOC struct COFF_reloc +#define COFF_RELSZ 10 + +#define COFF_DEF_DATA_SECTION_ALIGNMENT 4 +#define COFF_DEF_BSS_SECTION_ALIGNMENT 4 +#define COFF_DEF_TEXT_SECTION_ALIGNMENT 4 + +/* For new sections we haven't heard of before */ +#define COFF_DEF_SECTION_ALIGNMENT 4 Index: elf.h =================================================================== --- elf.h (nonexistent) +++ elf.h (revision 1765) @@ -0,0 +1,439 @@ +#ifndef _LINUX_ELF_H +#define _LINUX_ELF_H + +#if HAVE_CONFIG_H +#include +#endif + +#ifdef WORDS_BIGENDIAN +#define ELF_SHORT_H +#define ELF_LONG_H +#else +/* Load a short int from the following tables with big-endian formats */ +#define ELF_SHORT_H(ps) ((((unsigned short)(ps) >> 8) & 0xff) |\ + (((unsigned short)(ps) << 8) & 0xff00)) + +/* Load a long int from the following tables with big-endian formats */ +#define ELF_LONG_H(ps) ((((unsigned long)(ps) >> 24) & 0xff) |\ + (((unsigned long)(ps) >> 8) & 0xff00)|\ + (((unsigned long)(ps) << 8) & 0xff0000)|\ + (((unsigned long)(ps) << 24) & 0xff000000)) +#endif + +typedef unsigned long Elf32_Addr; +typedef unsigned short Elf32_Half; +typedef unsigned long Elf32_Off; +typedef long Elf32_Sword; +typedef unsigned long Elf32_Word; + +/* These constants are for the segment types stored in the image headers */ +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff + +/* These constants define the different elf file types */ +#define ET_NONE 0 +#define ET_REL 1 +#define ET_EXEC 2 +#define ET_DYN 3 +#define ET_CORE 4 +#define ET_LOPROC 5 +#define ET_HIPROC 6 + +/* These constants define the various ELF target machines */ +#define EM_NONE 0 +#define EM_M32 1 +#define EM_SPARC 2 +#define EM_386 3 +#define EM_68K 4 +#define EM_88K 5 +#define EM_486 6 /* Perhaps disused */ +#define EM_860 7 + +#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */ + +#define EM_MIPS_RS4_BE 10 /* MIPS R4000 big-endian */ + +#define EM_SPARC64 11 /* SPARC v9 (not official) 64-bit */ + +#define EM_PARISC 15 /* HPPA */ + +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ + +#define EM_PPC 20 /* PowerPC */ + +/* + * This is an interim value that we will use until the committee comes + * up with a final number. + */ +#define EM_ALPHA 0x9026 + + +/* This is the info that is needed to parse the dynamic section of the file */ +#define DT_NULL 0 +#define DT_NEEDED 1 +#define DT_PLTRELSZ 2 +#define DT_PLTGOT 3 +#define DT_HASH 4 +#define DT_STRTAB 5 +#define DT_SYMTAB 6 +#define DT_RELA 7 +#define DT_RELASZ 8 +#define DT_RELAENT 9 +#define DT_STRSZ 10 +#define DT_SYMENT 11 +#define DT_INIT 12 +#define DT_FINI 13 +#define DT_SONAME 14 +#define DT_RPATH 15 +#define DT_SYMBOLIC 16 +#define DT_REL 17 +#define DT_RELSZ 18 +#define DT_RELENT 19 +#define DT_PLTREL 20 +#define DT_DEBUG 21 +#define DT_TEXTREL 22 +#define DT_JMPREL 23 +#define DT_LOPROC 0x70000000 +#define DT_HIPROC 0x7fffffff + +/* This info is needed when parsing the symbol table */ +#define STB_LOCAL 0 +#define STB_GLOBAL 1 +#define STB_WEAK 2 + +#define STT_NOTYPE 0 +#define STT_OBJECT 1 +#define STT_FUNC 2 +#define STT_SECTION 3 +#define STT_FILE 4 + +#define ELF32_ST_BIND(x) ((x) >> 4) +#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf) + +/* Symbolic values for the entries in the auxiliary table + put on the initial stack */ +#define AT_NULL 0 /* end of vector */ +#define AT_IGNORE 1 /* entry should be ignored */ +#define AT_EXECFD 2 /* file descriptor of program */ +#define AT_PHDR 3 /* program headers for program */ +#define AT_PHENT 4 /* size of program header entry */ +#define AT_PHNUM 5 /* number of program headers */ +#define AT_PAGESZ 6 /* system page size */ +#define AT_BASE 7 /* base address of interpreter */ +#define AT_FLAGS 8 /* flags */ +#define AT_ENTRY 9 /* entry point of program */ +#define AT_NOTELF 10 /* program is not ELF */ +#define AT_UID 11 /* real uid */ +#define AT_EUID 12 /* effective uid */ +#define AT_GID 13 /* real gid */ +#define AT_EGID 14 /* effective gid */ + + +typedef struct dynamic{ + Elf32_Sword d_tag; + union{ + Elf32_Sword d_val; + Elf32_Addr d_ptr; + } d_un; +} Elf32_Dyn; + +typedef struct { + unsigned long long d_tag; /* entry tag value */ + union { + unsigned long long d_val; + unsigned long long d_ptr; + } d_un; +} Elf64_Dyn; + +/* The following are used with relocations */ +#define ELF32_R_SYM(x) ((x) >> 8) +#define ELF32_R_TYPE(x) ((x) & 0xff) + +#define R_386_NONE 0 +#define R_386_32 1 +#define R_386_PC32 2 +#define R_386_GOT32 3 +#define R_386_PLT32 4 +#define R_386_COPY 5 +#define R_386_GLOB_DAT 6 +#define R_386_JMP_SLOT 7 +#define R_386_RELATIVE 8 +#define R_386_GOTOFF 9 +#define R_386_GOTPC 10 +#define R_386_NUM 11 + +#define R_68K_NONE 0 +#define R_68K_32 1 +#define R_68K_16 2 +#define R_68K_8 3 +#define R_68K_PC32 4 +#define R_68K_PC16 5 +#define R_68K_PC8 6 +#define R_68K_GOT32 7 +#define R_68K_GOT16 8 +#define R_68K_GOT8 9 +#define R_68K_GOT32O 10 +#define R_68K_GOT16O 11 +#define R_68K_GOT8O 12 +#define R_68K_PLT32 13 +#define R_68K_PLT16 14 +#define R_68K_PLT8 15 +#define R_68K_PLT32O 16 +#define R_68K_PLT16O 17 +#define R_68K_PLT8O 18 +#define R_68K_COPY 19 +#define R_68K_GLOB_DAT 20 +#define R_68K_JMP_SLOT 21 +#define R_68K_RELATIVE 22 + +typedef struct elf32_rel { + Elf32_Addr r_offset; + Elf32_Word r_info; +} Elf32_Rel; + +typedef struct elf64_rel { + unsigned long long r_offset; /* Location at which to apply the action */ + unsigned long long r_info; /* index and type of relocation */ +} Elf64_Rel; + +typedef struct elf32_rela{ + Elf32_Addr r_offset; + Elf32_Word r_info; + Elf32_Sword r_addend; +} Elf32_Rela; + +typedef struct elf64_rela { + unsigned long long r_offset; /* Location at which to apply the action */ + unsigned long long r_info; /* index and type of relocation */ + unsigned long long r_addend; /* Constant addend used to compute value */ +} Elf64_Rela; + +typedef struct elf32_sym{ + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf32_Half st_shndx; +} Elf32_Sym; + +typedef struct elf64_sym { + unsigned int st_name; /* Symbol name, index in string tbl */ + unsigned char st_info; /* Type and binding attributes */ + unsigned char st_other; /* No defined meaning, 0 */ + unsigned short st_shndx; /* Associated section index */ + unsigned long long st_value; /* Value of the symbol */ + unsigned long long st_size; /* Associated symbol size */ +} Elf64_Sym; + + +#define EI_NIDENT 16 + +typedef struct elf32_hdr{ + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; /* Entry point */ + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} Elf32_Ehdr; + +typedef struct elf64_hdr { + unsigned char e_ident[16]; /* ELF "magic number" */ + short int e_type; + short unsigned int e_machine; + int e_version; + unsigned long long e_entry; /* Entry point virtual address */ + unsigned long long e_phoff; /* Program header table file offset */ + unsigned long long e_shoff; /* Section header table file offset */ + int e_flags; + short int e_ehsize; + short int e_phentsize; + short int e_phnum; + short int e_shentsize; + short int e_shnum; + short int e_shstrndx; +} Elf64_Ehdr; + +/* These constants define the permissions on sections in the program + header, p_flags. */ +#define PF_R 0x4 +#define PF_W 0x2 +#define PF_X 0x1 + +typedef struct elf32_phdr{ + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; +} Elf32_Phdr; + +typedef struct elf64_phdr { + int p_type; + int p_flags; + unsigned long long p_offset; /* Segment file offset */ + unsigned long long p_vaddr; /* Segment virtual address */ + unsigned long long p_paddr; /* Segment physical address */ + unsigned long long p_filesz; /* Segment size in file */ + unsigned long long p_memsz; /* Segment size in memory */ + unsigned long long p_align; /* Segment alignment, file & memory */ +} Elf64_Phdr; + +/* sh_type */ +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 +#define SHT_NUM 12 +#define SHT_LOPROC 0x70000000 +#define SHT_HIPROC 0x7fffffff +#define SHT_LOUSER 0x80000000 +#define SHT_HIUSER 0xffffffff + +/* sh_flags */ +#define SHF_WRITE 0x1 +#define SHF_ALLOC 0x2 +#define SHF_EXECINSTR 0x4 +#define SHF_MASKPROC 0xf0000000 + +/* special section indexes */ +#define SHN_UNDEF 0 +#define SHN_LORESERVE 0xff00 +#define SHN_LOPROC 0xff00 +#define SHN_HIPROC 0xff1f +#define SHN_ABS 0xfff1 +#define SHN_COMMON 0xfff2 +#define SHN_HIRESERVE 0xffff + +typedef struct elf32_shdr { + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; +} Elf32_Shdr; + +typedef struct elf64_shdr { + unsigned int sh_name; /* Section name, index in string tbl */ + unsigned int sh_type; /* Type of section */ + unsigned long long sh_flags; /* Miscellaneous section attributes */ + unsigned long long sh_addr; /* Section virtual addr at execution */ + unsigned long long sh_offset; /* Section file offset */ + unsigned long long sh_size; /* Size of section in bytes */ + unsigned int sh_link; /* Index of another section */ + unsigned int sh_info; /* Additional section information */ + unsigned long long sh_addralign; /* Section alignment */ + unsigned long long sh_entsize; /* Entry size if section holds table */ +} Elf64_Shdr; + +#define EI_MAG0 0 /* e_ident[] indexes */ +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_PAD 7 + +#define ELFMAG0 0x7f /* EI_MAG */ +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define ELFCLASSNONE 0 /* EI_CLASS */ +#define ELFCLASS32 1 +#define ELFCLASS64 2 +#define ELFCLASSNUM 3 + +#define ELFDATANONE 0 /* e_ident[EI_DATA] */ +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 + +#define EV_NONE 0 /* e_version, EI_VERSION */ +#define EV_CURRENT 1 +#define EV_NUM 2 + +/* Notes used in ET_CORE */ +#define NT_PRSTATUS 1 +#define NT_PRFPREG 2 +#define NT_PRPSINFO 3 +#define NT_TASKSTRUCT 4 + +/* Note header in a PT_NOTE section */ +typedef struct elf32_note { + Elf32_Word n_namesz; /* Name size */ + Elf32_Word n_descsz; /* Content size */ + Elf32_Word n_type; /* Content type */ +} Elf32_Nhdr; + +/* Note header in a PT_NOTE section */ +/* + * For now we use the 32 bit version of the structure until we figure + * out whether we need anything better. Note - on the Alpha, "unsigned int" + * is only 32 bits. + */ +typedef struct elf64_note { + unsigned int n_namesz; /* Name size */ + unsigned int n_descsz; /* Content size */ + unsigned int n_type; /* Content type */ +} Elf64_Nhdr; + +#ifdef __mc68000__ +#define ELF_START_MMAP 0xC0000000 +#endif +#ifdef __i386__ +#define ELF_START_MMAP 0x80000000 +#endif + +#if ELF_CLASS == ELFCLASS32 + +extern Elf32_Dyn _DYNAMIC []; +#define elfhdr elf32_hdr +#define elf_phdr elf32_phdr +#define elf_note elf32_note + +#else + +extern Elf64_Dyn _DYNAMIC []; +#define elfhdr elf64_hdr +#define elf_phdr elf64_phdr +#define elf_note elf64_note + +#endif + + +#endif /* _LINUX_ELF_H */ Index: Makefile.am =================================================================== --- Makefile.am (nonexistent) +++ Makefile.am (revision 1765) @@ -0,0 +1,22 @@ +# Makefile -- Makefile for cpu architecture independent simulation +# Copyright (C) 1999 Damjan Lampret, lampret@opencores.org +# +# This file is part of OpenRISC 1000 Architectural Simulator. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +noinst_LIBRARIES = libcommon.a +libcommon_a_SOURCES = abstract.c parse.c stats.c trace.c labels.c Index: . =================================================================== --- . (nonexistent) +++ . (revision 1765)
. Property changes : Added: svn:ignore ## -0,0 +1,2 ## +Makefile +.deps

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.