LOGIN   :::   RECOVER PASS   :::   GET ACCOUNT    
Browse
  • Projects
  • Code (CVS)
  • Forums
  • News
  • Articles
  • Polls
  •  
    OpenCores
  • FAQ
  • CVS HowTo
  • Mission
  • Media
  • Tools
  • Advertise
  • Mirrors
  • Logos
  • Contact us
  • Find Resources
  • Job Opportunity
  •  
    Tools
  • Search
      
  • Download Cores (CVSGet)
  •  
    More
  • Wishbone
  • Perlilog
  • EDA tools
  • OpenTech CD
  •  
    Navigation: All forums > Openrisc > Message List > Message Post

    Message

    Reply | Reply all
    Date Prev | Date Next | Thread Prev | Thread Next Date Index | Thread Index

    From: =?unknown-8bit?Q?Gy=F6rgy?= 'nog' Jeney<nog@s...>
    Date: Thu Mar 24 21:10:35 CET 2005
    Subject: [openrisc] [or1ksim #59] Don't call mtspr/mfspr when not needed
    Top
    Hi,

    This patch changes some calls to mtspr()/mfspr() to directly accessing
    cpu_state.sprs[]. This is needed to avoid infinate loops in the recompiler when
    the immu is reconfigured. When the immu is reconfigured, immu_translate is
    called to check if the current page in execution is still resident in the immu.
    If it's not then simulate_itlb calls setsprbits, which calls mtspr but mtspr
    detects that the immu is reconfigured and calls immu_translate again.

    I would go asfar as to argue that mfspr() and mtspr() should only be called from
    the l.mfspr and l.mtspr instructions. All code that messes with an spr should
    know exactly what it's doing and not screw up.

    ChangeLog:
    * Replace some problematic calles to mfspr/mtspr with direct access to the spr.

    nog.
    -------------- next part --------------
    diff -urp --unidirectional-new-file /home/nog/or1ksim-split/cpu/or1k/sprs.h ./cpu/or1k/sprs.h
    --- /home/nog/or1ksim-split/cpu/or1k/sprs.h 2005-03-23 18:17:18.000000000 +0100
    +++ ./cpu/or1k/sprs.h 2005-03-06 19:40:06.000000000 +0100
    @@ -64,8 +64,8 @@ mfspr_(const uint16_t regno)
    static inline void
    setsprbits(const int regno, const unsigned long mask, const unsigned long value)
    {
    - sprword regvalue = mfspr(regno);
    - sprword shifted = 0x0;
    + sprword regvalue = cpu_state.sprs[regno];
    + sprword shifted = 0x0;
    int m, v = 0;

    /* m counts bits in valuemask */
    @@ -77,15 +77,15 @@ setsprbits(const int regno, const unsign
    }

    /* PRINTF("oldvalue %x setsprbits(%x, %x, %x) shifted %x", regvalue, regno, mask, value, shifted); */
    - mtspr(regno, (regvalue & ~mask) | shifted);
    + cpu_state.sprs[regno] = (regvalue & ~mask) | shifted;
    }

    /* Get specific SPR bit(s) identified by mask. */
    static inline unsigned long
    getsprbits(const int regno, const unsigned long mask)
    {
    - sprword regvalue = mfspr(regno);
    - sprword shifted = 0x0;
    + sprword regvalue = cpu_state.sprs[regno];
    + sprword shifted = 0x0;
    int m, v = 0;

    /* m counts bits in valuemask */
    @@ -103,12 +103,12 @@ getsprbits(const int regno, const unsign
    static inline void
    setsprbit(const int regno, const int bitnum, const unsigned long bitvalue)
    {
    - sprword mask;
    - sprword regvalue = mfspr(regno);
    + sprword mask;
    + sprword regvalue = cpu_state.sprs[regno];

    mask = ~(1 << bitnum);

    - mtspr(regno, (regvalue & mask) | ((bitvalue & 0x1) << bitnum));
    + cpu_state.sprs[regno] = (regvalue & mask) | ((bitvalue & 0x1) << bitnum);

    return;
    }
    @@ -117,7 +117,7 @@ setsprbit(const int regno, const int bit
    static inline int
    getsprbit(const int regno, const int bitnum)
    {
    - sprword regvalue = mfspr(regno);
    + sprword regvalue = cpu_state.sprs[regno];

    return (regvalue >> bitnum) & 0x1;
    }
    @@ -126,7 +126,7 @@ getsprbit(const int regno, const int bit
    static inline unsigned long
    testsprbits(const int regno, const unsigned long mask)
    {
    - sprword regvalue = mfspr(regno);
    + sprword regvalue = cpu_state.sprs[regno];
    return regvalue & mask;
    }

    --- cpu/or1k/except.c 2005-03-23 18:18:29.000000000 +0100
    +++ /home/nog/or1ksim-split/cpu/or1k/except.c 2005-03-23 19:37:49.000000000 +0100
    @@ -80,6 +80,18 @@

    pcnext = except + (testsprbits (SPR_SR, SPR_SR_EPH) ? 0xf0000000 : 0x00000000);

    + cpu_state.sprs[SPR_EEAR_BASE] = ea;
    + cpu_state.sprs[SPR_ESR_BASE] = cpu_state.sprs[SPR_SR];
    +
    + cpu_state.sprs[SPR_SR] &= ~SPR_SR_OVE; /* Disable overflow flag exception. */
    +
    + cpu_state.sprs[SPR_SR] |= SPR_SR_SM; /* SUPV mode */
    + cpu_state.sprs[SPR_SR] &= ~(SPR_SR_IEE | SPR_SR_TEE); /* Disable interrupts. */
    +
    + /* Address translation is always disabled when starting exception. */
    + cpu_state.sprs[SPR_SR] &= ~SPR_SR_DME;
    + cpu_state.sprs[SPR_SR] &= ~SPR_SR_IME;
    + switch(except) { /* EPCR is irrelevent */ case EXCEPT_RESET: @@ -114,17 +126,5 @@ break; } - mtspr(SPR_EEAR_BASE, ea); - mtspr(SPR_ESR_BASE, mfspr(SPR_SR)); - - /* Address translation is always disabled when starting exception. */ - mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_DME)); - mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_IME)); - - mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_OVE); /* Disable overflow flag exception. */ - - mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_SM); /* SUPV mode */ - mtspr(SPR_SR, mfspr(SPR_SR) & ~(SPR_SR_IEE | SPR_SR_TEE)); /* Disable interrupts. */ - cpu_state.delay_insn = 0; } --- cpu/or32/execute.c 2005-03-23 18:18:29.000000000 +0100 +++ /home/nog/or1ksim-split/cpu/or32/execute.c 2005-03-23 19:37:49.000000000 +0100 @@ -633,10 +633,10 @@ hist_exec_head->prev = hist_exec_tail; /* Cpu configuration */ - mtspr(SPR_UPR, config.cpu.upr); + cpu_state.sprs[SPR_UPR] = config.cpu.upr; setsprbits(SPR_VR, SPR_VR_VER, config.cpu.ver); setsprbits(SPR_VR, SPR_VR_REV, config.cpu.rev); - mtspr(SPR_SR, config.cpu.sr); + cpu_state.sprs[SPR_SR] = config.cpu.sr; pcnext = 0x0; /* MM1409: All programs should start at reset vector entry! */ if (config.sim.verbose) PRINTF ("Starting at 0x%"PRIxADDR"\n", pcnext);

     
    Copyright (c) 1999 OPENCORES.ORG. All rights reserved.