/* 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;
    }

    phys_memaddr = dmmu_translate (memaddr, 0);
    if (except_pending)
        return 0;

    if (config.pcu.enabled)
        pcu_count_event(SPR_PCMR_LA);

    if (config.debug.enabled)
        *breakpoint += check_debug_unit (DebugLoadAddress, memaddr);

    if (config.dc.enabled)
        temp = dc_simulate_read (phys_memaddr, memaddr, 2);
    else
        temp = evalsim_mem16 (phys_memaddr, memaddr);

    if (config.debug.enabled)
        *breakpoint += check_debug_unit (DebugLoadData, temp);

    return temp;
}
示例#2
0
/* WARNING: If this is called during a simulated instruction (ie. from a read/
 * write mem callback), the interrupt will be delivered after the instruction
 * has finished executeing */
void
report_interrupt (int line)
{
  uint32_t lmask = 1 << line;

  /* Disable doze and sleep mode */
  cpu_state.sprs[SPR_PMR] &= ~(SPR_PMR_DME | SPR_PMR_SME);

  /* If PIC is disabled, don't set any register, just raise EXCEPT_INT */
  if (!config.pic.enabled)
    {
      if (cpu_state.sprs[SPR_SR] & SPR_SR_IEE)
	except_handle (EXCEPT_INT, cpu_state.sprs[SPR_EEAR_BASE]);
      return;
    }

  if (cpu_state.pic_lines & lmask)
    {
      /* No edge occured, warn about performance penalty and exit */
      fprintf (stderr, "Warning: Int line %d did not change state\n", line);
      return;
    }

  cpu_state.pic_lines |= lmask;
  cpu_state.sprs[SPR_PICSR] |= lmask;

  if ((cpu_state.sprs[SPR_PICMR] & lmask) || line < 2)
    if (cpu_state.sprs[SPR_SR] & SPR_SR_IEE)
      SCHED_ADD (pic_rep_int, NULL, 0);
}
示例#3
0
/* Handles the reporting of an interrupt if it had to be delayed */
static void
pic_rep_int (void *dat)
{
  if (cpu_state.sprs[SPR_PICSR])
    {
      except_handle (EXCEPT_INT, cpu_state.sprs[SPR_EEAR_BASE]);
    }
}
示例#4
0
/*! Raises a timer exception */
static void
tick_raise_except (void *dat)
{
  cpu_state.sprs[SPR_TTMR] |= SPR_TTMR_IP;

  /* Reschedule unconditionally, since we have to raise the exception until
   * TTMR_IP has been cleared */
  sched_next_insn (tick_raise_except, NULL);

  /* be sure not to issue a timer exception if an exception occured before it */
  if (cpu_state.sprs[SPR_SR] & SPR_SR_TEE)
    {
      except_handle (EXCEPT_TICK, cpu_state.sprs[SPR_EEAR_BASE]);
    }
}
/* For cpu accesses
 *
 * NOTE: This function _is_ only called from set_mem8 below and
 * dc_simulate_write.  _Don't_ call it from anywere else.
 */
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);
    }
    else
    {
        if (config.sim.report_mem_errs)
        {
            PRINTF ("EXCEPTION: write out of memory (8-bit access to %" PRIxADDR
                    ")\n", memaddr);
        }

        except_handle (EXCEPT_BUSERR, vaddr);
    }
}
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.pcu.enabled)
        pcu_count_event(SPR_PCMR_SA);

    if (config.debug.enabled)
    {
        *breakpoint += check_debug_unit (DebugStoreAddress, memaddr);	/* 28/05/01 CZ */
        *breakpoint += check_debug_unit (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);
}
/* 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.
 */
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
    {
        if (config.sim.report_mem_errs)
        {
            PRINTF ("EXCEPTION: read out of memory (8-bit access to %" PRIxADDR
                    ")\n", memaddr);
        }

        except_handle (EXCEPT_BUSERR, vaddr);
    }

    return 0;
}
static void
set_mem_32_inv (oraddr_t memaddr, uint32_t val, void *dat)
{
    except_handle (EXCEPT_BUSERR, cur_vadd);
}
static uint32_t
eval_mem_32_inv (oraddr_t memaddr, void *dat)
{
    except_handle (EXCEPT_BUSERR, cur_vadd);
    return 0;
}