Ticket #3460: gdb-8.0.1-sis-leon3-smp.diff

File gdb-8.0.1-sis-leon3-smp.diff, 96.9 KB (added by Sebastian Huber, on 12/17/18 at 06:20:50)
  • sim/erc32/README.leon3

    From adf4a4390d41becac3d406e57b40115c31e5d962 Mon Sep 17 00:00:00 2001
    From: Jiri Gaisler <jiri@gaisler.se>
    Date: Sun, 9 Dec 2018 10:56:14 +0100
    Subject: [PATCH] sim/erc32: SMP support for leon3
    
    ---
     sim/erc32/README.leon3 |  18 +-
     sim/erc32/README.run   |  17 ++
     sim/erc32/README.sis   |  11 +-
     sim/erc32/erc32.c      |  51 ++--
     sim/erc32/exec.c       | 345 ++++++++--------------
     sim/erc32/func.c       | 655 +++++++++++++++++++++++++++++------------
     sim/erc32/help.c       |   2 +-
     sim/erc32/interf.c     | 201 ++++++-------
     sim/erc32/leon2.c      |  37 +--
     sim/erc32/leon3.c      | 272 +++++++++++------
     sim/erc32/run.c        |  22 +-
     sim/erc32/sis.c        | 126 ++------
     sim/erc32/sis.h        |  81 +++--
     13 files changed, 1003 insertions(+), 835 deletions(-)
     create mode 100644 sim/erc32/README.run
    
    diff --git a/sim/erc32/README.leon3 b/sim/erc32/README.leon3
    index e6d5f5e57e..80fff5f46c 100644
    a b MMU. 
    1010To start sis in Leon3 mode, add the -leon3 switch. In gdb,
    1111use 'target sim -leon3' .
    1212
    13 1.1 UART
     131.1 Multiprocessing
     14
     15It is possible to emulate an SMP leon3 system with up to 4 cores.
     16Add the switch -m <n> when starting the simulator, where n can be
     172 - 4. The cores are simulated in a round-robin fashion with a time-
     18slice of 50 clocks. Shorter or longer time-slices can be selected
     19using -d <clocks>/
     20
     211.2 UART
    1422
    1523The UART emulates an APBUART and is located at address 0x80000100.
    1624The following registers are implemented:
    The following registers are implemented: 
    2028
    2129The UART generates interrupt 3.
    2230
    23 1.2 Timer unit (GPTIMER)
     311.3 Timer unit (GPTIMER)
    2432
    2533The GPTIMER programmable counter is emulated and located at
    2634address 0x80000300. It is configured with two timers and separate
    2735interrupts (8 and 9).
    2836
    29 1.3 Interrupt controller
     371.4 Interrupt controller
    3038
    3139The IRQMP interrupt controller is implemented as described in the
    3240GRLIB IP manual, with the exception of the interrupt level register.
    The following memory areas are valid for the Leon3 simulator: 
    4452
    4553Access to non-existing memory will result in a memory exception trap.
    4654
    47 1.8 Power-down mode
     551.6 Power-down mode
    4856
    4957The Leon3 power-down feature (%asr19) is supported. When power-down is
    5058entered, time is skipped forward until the next event in the event queue.
    51 However, if the simulator event queue is empty, power-down mode is not
    52 entered since no interrupt would be generated to exit from the mode. A
    5359Ctrl-C in the simulator window will exit the power-down mode.
  • new file sim/erc32/README.run

    diff --git a/sim/erc32/README.run b/sim/erc32/README.run
    new file mode 100644
    index 0000000000..555231cb64
    - +  
     1
     2The 'run' application allows to execute a binary directly without starting sis.
     3Nota that sis now also have this feature included through the -r switch.
     4
     5The following options are useful for erc32/leon2/3 simulation:
     6
     7-a -leon2       Emulate a leon2 system (erc32 is default)
     8
     9-a -leon3       Emulate a leon3 system (erc32 is default)
     10
     11-m <n>          Enable SMP emulation with n cores
     12
     13-t <n>          Set a simulator time-out for n seconds
     14
     15-v <n>          Set debug level to n
     16
     17It is not possible to pass other sis options to the simulator.
  • sim/erc32/README.sis

    diff --git a/sim/erc32/README.sis b/sim/erc32/README.sis
    index bf2f7a7f90..7e687e41b0 100644
    a b and peripherals. 
    1313
    1414The simulator is started as follows:
    1515
    16 sis [-leon2] [-leon3] [-uart1 uart_device1] [-uart2 uart_device2]
    17     [-nfp] [-freq frequency] [-c batch_file] [-v] [-r] [-tlim time] [files]
     16sis [-leon2] [-leon3] [-uart1 uart_device1] [-uart2 uart_device2] [-m cores]
     17[-d clocks] [-nfp] [-freq freq] [-c batch_file] [-v] [-r] [-tlim time] [files]
    1818
    1919By default, SIS emulates an ERC32 system. The -leon2 switch enables
    2020LEON2 emulation, while the -leon3 switch enables emulation of a
    for automated testing of large number of binaries. 
    4040-tlim can be used together with -r to limit the amount of simulated time that
    4141the simulator runs for before exiting. The following units are recognized:
    4242us, ms and s. To limit simulated time to 100 seconds, it should thus be
    43 started with -r -tlim 100s .
     43started with -r -tlim 100 s .
     44
     45-m sets the number of cores (2 - 4) in a leon3 multi-processor system.
     46
     47-d set the the number of clocks in each time-slice for multi-processor
     48simulation. Default is 50, set lower for higher accuracy.
    4449
    4550Files to be loaded must be in one of the formats supported by the BFD library.
    4651This inlude elf, a.out, srec and binary. On start-up, the files will be
  • sim/erc32/erc32.c

    diff --git a/sim/erc32/erc32.c b/sim/erc32/erc32.c
    index d2b9194591..085d215a45 100644
    a b reset() 
    307307    mec_reset();
    308308    uart_irq_start();
    309309    wdog_start();
     310    sregs[0].intack = mec_intack;
    310311}
    311312
    312313static void
    chk_irq() 
    559560    uint32          itmp;
    560561    int             old_irl;
    561562
    562     old_irl = ext_irl;
     563    old_irl = ext_irl[0];
    563564    if (mec_tcr & 0x80000) itmp = mec_ifr;
    564565    else itmp  = 0;
    565566    itmp = ((mec_ipr | itmp) & ~mec_imr) & 0x0fffe;
    566     ext_irl = 0;
     567    ext_irl[0] = 0;
    567568    if (itmp != 0) {
    568569        for (i = 15; i > 0; i--) {
    569570            if (((itmp >> i) & 1) != 0) {
    570571                if ((sis_verbose) && (i > old_irl))
    571572                    printf("IU irl: %d\n", i);
    572                 ext_irl = i;
    573                 set_int(i, mec_intack, i);
     573                ext_irl[0] = i;
    574574                break;
    575575            }
    576576        }
    mec_write(addr, data) 
    905905
    906906    case MEC_PWDR:
    907907        if (mec_mcr & 1)
    908             wait_for_irq();
     908            sregs->pwd_mode = 1;
     909            sregs->pwdstart = sregs->simtime;
    909910        break;
    910911
    911912    default:
    memory_iread (uint32 addr, uint32 *data, int32 *ws) 
    16181619
    16191620    if (sis_verbose)
    16201621        printf ("Memory exception at %x (illegal address)\n", addr);
    1621     if (sregs.psr & 0x080)
     1622    if (sregs->psr & 0x080)
    16221623        asi = 9;
    16231624    else
    16241625        asi = 8;
    memory_read (uint32 addr, uint32 *data, int32 sz, int32 *ws) 
    16371638    if (errmec) {
    16381639        if (sis_verbose)
    16391640            printf("Inserted MEC error %d\n",errmec);
    1640         asi = (sregs.psr & 0x080) ? 11 : 10;
     1641        asi = (sregs->psr & 0x080) ? 11 : 10;
    16411642        set_sfsr(errmec, addr, asi, 1);
    16421643        if (errmec == 5) mecparerror();
    16431644        if (errmec == 6) iucomperr();
    memory_read (uint32 addr, uint32 *data, int32 sz, int32 *ws) 
    16511652        *ws = mem_ramr_ws;
    16521653        return 0;
    16531654    } else if ((addr >= MEC_START) && (addr < MEC_END)) {
    1654         asi = (sregs.psr & 0x080) ? 11 : 10;
     1655        asi = (sregs->psr & 0x080) ? 11 : 10;
    16551656        mexc = mec_read(addr, asi, data);
    16561657        if (mexc) {
    16571658            set_sfsr(MEC_ACC, addr, asi, 1);
    memory_read (uint32 addr, uint32 *data, int32 sz, int32 *ws) 
    16911692
    16921693    if (sis_verbose)
    16931694        printf ("Memory exception at %x (illegal address)\n", addr);
    1694     asi = (sregs.psr & 0x080) ? 11 : 10;
     1695    asi = (sregs->psr & 0x080) ? 11 : 10;
    16951696    set_sfsr(UIMP_ACC, addr, asi, 1);
    16961697    *ws = MEM_EX_WS;
    16971698    return 1;
    16981699}
    16991700
    1700 static int
    1701 memory_read_asi (int32 asi, uint32 addr, uint32 *data, int32 sz, int32 *ws)
    1702 {
    1703   return memory_read (addr, data, sz, ws);
    1704 }
    1705 
    17061701static int
    17071702memory_write (uint32 addr, uint32 *data, int32 sz, int32 *ws)
    17081703{
    memory_write (uint32 addr, uint32 *data, int32 sz, int32 *ws) 
    17191714    if (errmec) {
    17201715        if (sis_verbose)
    17211716            printf("Inserted MEC error %d\n",errmec);
    1722         asi = (sregs.psr & 0x080) ? 11 : 10;
     1717        asi = (sregs->psr & 0x080) ? 11 : 10;
    17231718        set_sfsr(errmec, addr, asi, 0);
    17241719        if (errmec == 5) mecparerror();
    17251720        if (errmec == 6) iucomperr();
    memory_write (uint32 addr, uint32 *data, int32 sz, int32 *ws) 
    17321727        if (mem_accprot) {
    17331728
    17341729            waddr = (addr & 0x7fffff) >> 2;
    1735             asi = (sregs.psr & 0x080) ? 11 : 10;
     1730            asi = (sregs->psr & 0x080) ? 11 : 10;
    17361731            for (i = 0; i < 2; i++)
    17371732                wphit[i] =
    17381733                    (((asi == 0xa) && (mec_wpr[i] & 1)) ||
    memory_write (uint32 addr, uint32 *data, int32 sz, int32 *ws) 
    17541749        store_bytes (ramb, waddr, data, sz, ws);
    17551750        return 0;
    17561751    } else if ((addr >= MEC_START) && (addr < MEC_END)) {
    1757         asi = (sregs.psr & 0x080) ? 11 : 10;
     1752        asi = (sregs->psr & 0x080) ? 11 : 10;
    17581753        if ((sz != 2) || (asi != 0xb)) {
    17591754            set_sfsr(MEC_ACC, addr, asi, 0);
    17601755            *ws = MEM_EX_WS;
    memory_write (uint32 addr, uint32 *data, int32 sz, int32 *ws) 
    18111806    }
    18121807       
    18131808    *ws = MEM_EX_WS;
    1814     asi = (sregs.psr & 0x080) ? 11 : 10;
     1809    asi = (sregs->psr & 0x080) ? 11 : 10;
    18151810    set_sfsr(UIMP_ACC, addr, asi, 0);
    18161811    return 1;
    18171812}
    18181813
    1819 static int
    1820 memory_write_asi (int32 asi, uint32 addr, uint32 *data, int32 sz, int32 *ws)
    1821 {
    1822   return memory_write (addr, data, sz, ws);
    1823 }
    1824 
    18251814static unsigned char  *
    18261815get_mem_ptr(addr, size)
    18271816    uint32          addr;
    boot_init (void) 
    18861875{
    18871876    mec_write(MEC_WCR, 0);      /* zero waitstates */
    18881877    mec_write(MEC_TRAPD, 0);    /* turn off watch-dog */
    1889     mec_write(MEC_RTC_SCALER, sregs.freq - 1); /* generate 1 MHz RTC tick */
     1878    mec_write(MEC_RTC_SCALER, ebase.freq - 1); /* generate 1 MHz RTC tick */
    18901879    mec_write(MEC_MEMCFG, (3 << 18) | (4 << 10)); /* 1 MB ROM, 4 MB RAM */
    1891     sregs.wim = 2;
    1892     sregs.psr = 0x110010e0;
    1893     sregs.r[30] = RAM_END;
    1894     sregs.r[14] = sregs.r[30] - 96 * 4;
     1880    sregs->wim = 2;
     1881    sregs->psr = 0x110010e0;
     1882    sregs->r[30] = RAM_END;
     1883    sregs->r[14] = sregs->r[30] - 96 * 4;
    18951884    mec_mcr |= 1;               /* power-down enabled */
    18961885}
    18971886
    const struct memsys erc32sys = { 
    19051894    restore_stdio,
    19061895    memory_iread,
    19071896    memory_read,
    1908     memory_read_asi,
    19091897    memory_write,
    1910     memory_write_asi,
    19111898    sis_memory_write,
    19121899    sis_memory_read,
    19131900    boot_init
  • sim/erc32/exec.c

    diff --git a/sim/erc32/exec.c b/sim/erc32/exec.c
    index ce5a72978b..085193e84f 100644
    a b  
    2121#include <math.h>
    2222#include <stdio.h>
    2323
    24 int ext_irl = 0;
     24int ext_irl[NCPU];
    2525
    2626/* Load/store interlock delay */
    2727#define FLSTHOLD 1
    dispatch_instruction(sregs) 
    417417    uint32          ldep, icc;
    418418    int32           operand1, operand2, *rdd, result, eicc,
    419419                    new_cwp;
    420     int32           pc, npc, data, address, ws, mexc, fcc;
     420    int32           pc, npc, data, address, ws, mexc, fcc, annul;
    421421    int32           ddata[2];
    422422
    423423    sregs->ninst++;
    dispatch_instruction(sregs) 
    427427    npc = sregs->npc + 4;
    428428    op3 = rd = rs1 = operand2 = eicc = 0;
    429429    rdd = 0;
     430    annul = 0;
     431
    430432    if (op & 2) {
    431433
    432434        op3 = (sregs->inst >> 19) & 0x3f;
    dispatch_instruction(sregs) 
    436438#ifdef LOAD_DEL
    437439
    438440        /* Check if load dependecy is possible */
    439         if (ebase.simtime <= sregs->ildtime)
     441        if (sregs->simtime <= sregs->ildtime)
    440442            ldep = (((op3 & 0x38) != 0x28) && ((op3 & 0x3e) != 0x34) && (sregs->ildreg != 0));
    441443        else
    442444            ldep = 0;
    dispatch_instruction(sregs) 
    522524            case BICC_BA:
    523525                eicc = 1;
    524526                if (sregs->inst & 0x20000000)
    525                     sregs->annul = 1;
     527                    annul = 1;
    526528                break;
    527529            case BICC_BNE:
    528530                eicc = ~(ICC_Z);
    dispatch_instruction(sregs) 
    552554                npc = sregs->pc + operand1;
    553555            } else {
    554556                if (sregs->inst & 0x20000000)
    555                     sregs->annul = 1;
     557                    annul = 1;
    556558            }
    557559            break;
    558560        case FPBCC:
    dispatch_instruction(sregs) 
    563565                sregs->trap = TRAP_FPDIS;
    564566                break;
    565567            }
    566             if (ebase.simtime < sregs->ftime) {
    567                 sregs->ftime = ebase.simtime + sregs->hold;
     568            if (sregs->simtime < sregs->ftime) {
     569                sregs->ftime = sregs->simtime + sregs->hold;
    568570            }
    569571            cond = ((sregs->inst >> 25) & 0x0f);
    570572            fcc = (sregs->fsr >> 10) & 0x3;
    dispatch_instruction(sregs) 
    596598            case FBA:
    597599                eicc = 1;
    598600                if (sregs->inst & 0x20000000)
    599                     sregs->annul = 1;
     601                    annul = 1;
    600602                break;
    601603            case FBE:
    602604                eicc = !(fcc != FCC_E);
    dispatch_instruction(sregs) 
    626628                npc = sregs->pc + operand1;
    627629            } else {
    628630                if (sregs->inst & 0x20000000)
    629                     sregs->annul = 1;
     631                    annul = 1;
    630632            }
    631633            break;
    632634
    dispatch_instruction(sregs) 
    714716                                (sregs->inst == 0x91d02001))
    715717                    {
    716718                        sregs->trap = WPT_TRAP;
    717                         sregs->bphit = 1;
     719                        ebase.bphit = 1;
    718720                    }
    719721                }
    720722                break;
    dispatch_instruction(sregs) 
    11411143                    if ( 0 == rd )
    11421144                        sregs->y = (rs1 ^ operand2);
    11431145                    else if ( 17 == rd ) {
    1144                         if (sparclite)
    1145                             sregs->asr17 = (rs1 ^ operand2);
     1146                        sregs->asr17 &= ~0x0FFFE000;
     1147                        sregs->asr17 |= 0x0FFFE000 & (rs1 ^ operand2);
    11461148                    }
    11471149                    else if ( 19 == rd ) {
    1148                         if (cputype == CPU_LEON3)
    1149                             wait_for_irq();
     1150                        if (cputype == CPU_LEON3) {
     1151                            pwd_enter(sregs);
     1152                        }
    11501153                    }
    11511154                }
    11521155                break;
    dispatch_instruction(sregs) 
    12231226
    12241227        if (op3 & 4) {
    12251228            sregs->icnt = T_ST; /* Set store instruction count */
    1226             if (sregs->wpwnum) {
    1227                if (sregs->wphit = check_wpw(sregs, address, wpmask(op3))) {
     1229            if (ebase.wpwnum) {
     1230               if (ebase.wphit = check_wpw(sregs, address, wpmask(op3))) {
    12281231                   sregs->trap = WPT_TRAP;
    12291232                   break;
    12301233               }
    dispatch_instruction(sregs) 
    12341237#endif
    12351238        } else {
    12361239            sregs->icnt = T_LD; /* Set load instruction count */
    1237             if (sregs->wprnum) {
    1238                if (sregs->wphit = check_wpr(sregs, address, wpmask(op3))) {
     1240            if (ebase.wprnum) {
     1241               if (ebase.wphit = check_wpr(sregs, address, wpmask(op3))) {
    12391242                   sregs->trap = WPT_TRAP;
    12401243                   break;
    12411244               }
    dispatch_instruction(sregs) 
    12501253        switch (op3) {
    12511254        case LDDA:
    12521255            if (!chk_asi(sregs, &asi, op3)) break;
    1253             if (address & 0x7) {
    1254                 sregs->trap = TRAP_UNALI;
    1255                 break;
    1256             }
    1257             if (rd & 1) {
    1258                 rd &= 0x1e;
    1259                 if (rd > 7)
    1260                     rdd = &(sregs->r[(cwp + rd) & 0x7f]);
    1261                 else
    1262                     rdd = &(sregs->g[rd]);
    1263             }
    1264             mexc = ms->memory_read_asi (asi, address, ddata, 2, &ws);
    1265             sregs->hold += ws;
    1266             mexc |= ms->memory_read_asi (asi, address+4, &ddata[1], 2, &ws);
    1267             sregs->hold += ws;
    1268             sregs->icnt = T_LDD;
    1269             if (mexc)
    1270                 sregs->trap = TRAP_DEXC;
    1271             else {
    1272                 rdd[0] = ddata[0];
    1273                 rdd[1] = ddata[1];
    1274 #ifdef STAT
    1275                 sregs->nload++; /* Double load counts twice */
    1276 #endif
    1277             }
    1278             break;
    12791256        case LDD:
    12801257            if (address & 0x7) {
    12811258                sregs->trap = TRAP_UNALI;
    dispatch_instruction(sregs) 
    13101287                sregs->trap = TRAP_UNALI;
    13111288                break;
    13121289            }
    1313             mexc = ms->memory_read_asi (asi, address, &data, 2, &ws);
    1314             sregs->hold += ws;
    1315             if (mexc)
    1316                 sregs->trap = TRAP_DEXC;
    1317             else
    1318                 *rdd = data;
    1319             break;
     1290            if ((cputype == CPU_LEON3) && (asi == 2)) {
     1291                if (address == 0) *rdd = sregs->cache_ctrl;
     1292                else *rdd = 1 << 27;
     1293                break;
     1294            }
    13201295        case LD:
    13211296            if (address & 0x3) {
    13221297                sregs->trap = TRAP_UNALI;
    dispatch_instruction(sregs) 
    13321307            break;
    13331308        case LDSTUBA:
    13341309            if (!chk_asi(sregs, &asi, op3)) break;
    1335             mexc = ms->memory_read_asi (asi, address, &data, 0, &ws);
    1336             sregs->hold += ws;
    1337             sregs->icnt = T_LDST;
    1338             if (mexc) {
    1339                 sregs->trap = TRAP_DEXC;
    1340                 break;
    1341             }
    1342             data = extract_byte (data, address);
    1343             *rdd = data;
    1344             data = 0x0ff;
    1345             mexc = ms->memory_write_asi (asi, address, &data, 0, &ws);
    1346             sregs->hold += ws;
    1347             if (mexc)
    1348                 sregs->trap = TRAP_DEXC;
    1349 #ifdef STAT
    1350             sregs->nload++;
    1351 #endif
    1352             break;
     1310            /* fall through to LDSTUB */
    13531311        case LDSTUB:
    13541312            mexc = ms->memory_read (address, &data, 0, &ws);
    13551313            sregs->hold += ws;
    dispatch_instruction(sregs) 
    13731331        case LDSBA:
    13741332        case LDUBA:
    13751333            if (!chk_asi(sregs, &asi, op3)) break;
    1376             mexc = ms->memory_read_asi (asi, address, &data, 0, &ws);
    1377             sregs->hold += ws;
    1378             if (mexc) {
    1379                 sregs->trap = TRAP_DEXC;
    1380                 break;
    1381             }
    1382             if (op3 == LDSB)
    1383                 data = extract_byte_signed (data, address);
    1384             else
    1385                 data = extract_byte (data, address);
    1386             *rdd = data;
    1387             break;
     1334            /* fall through to LDSB */
    13881335        case LDSB:
    13891336        case LDUB:
    13901337            mexc = ms->memory_read (address, &data, 0, &ws);
    dispatch_instruction(sregs) 
    14021349        case LDSHA:
    14031350        case LDUHA:
    14041351            if (!chk_asi(sregs, &asi, op3)) break;
    1405             if (address & 0x1) {
    1406                 sregs->trap = TRAP_UNALI;
    1407                 break;
    1408             }
    1409             mexc = ms->memory_read_asi (asi, address, &data, 1, &ws);
    1410             sregs->hold += ws;
    1411             if (mexc) {
    1412                 sregs->trap = TRAP_DEXC;
    1413                 break;
    1414             }
    1415             if (op3 == LDSH)
    1416                 data = extract_short_signed (data, address);
    1417             else
    1418                 data = extract_short (data, address);
    1419             *rdd = data;
    1420             break;
     1352            /* fall through to LDSB */
    14211353        case LDSH:
    14221354        case LDUH:
    14231355            if (address & 0x1) {
    dispatch_instruction(sregs) 
    14451377                sregs->trap = TRAP_UNALI;
    14461378                break;
    14471379            }
    1448             if (ebase.simtime < sregs->ftime) {
     1380            if (sregs->simtime < sregs->ftime) {
    14491381                if ((sregs->frd == rd) || (sregs->frs1 == rd) ||
    14501382                    (sregs->frs2 == rd))
    1451                     sregs->fhold += (sregs->ftime - ebase.simtime);
     1383                    sregs->fhold += (sregs->ftime - sregs->simtime);
    14521384            }
    14531385            mexc = ms->memory_read (address, &data, 2, &ws);
    14541386            sregs->hold += ws;
    14551387            sregs->flrd = rd;
    1456             sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD +
     1388            sregs->ltime = sregs->simtime + sregs->icnt + FLSTHOLD +
    14571389                sregs->hold + sregs->fhold;
    14581390            if (mexc) {
    14591391                sregs->trap = TRAP_DEXC;
    dispatch_instruction(sregs) 
    14701402                sregs->trap = TRAP_UNALI;
    14711403                break;
    14721404            }
    1473             if (ebase.simtime < sregs->ftime) {
     1405            if (sregs->simtime < sregs->ftime) {
    14741406                if (((sregs->frd >> 1) == (rd >> 1)) ||
    14751407                    ((sregs->frs1 >> 1) == (rd >> 1)) ||
    14761408                    ((sregs->frs2 >> 1) == (rd >> 1)))
    1477                     sregs->fhold += (sregs->ftime - ebase.simtime);
     1409                    sregs->fhold += (sregs->ftime - sregs->simtime);
    14781410            }
    14791411            mexc = ms->memory_read (address, ddata, 2, &ws);
    14801412            sregs->hold += ws;
    dispatch_instruction(sregs) 
    14911423                sregs->nload++; /* Double load counts twice */
    14921424#endif
    14931425                sregs->fs[rd + 1] = *((float32 *) & ddata[1]);
    1494                 sregs->ltime = ebase.simtime + sregs->icnt + FLSTHOLD +
     1426                sregs->ltime = sregs->simtime + sregs->icnt + FLSTHOLD +
    14951427                               sregs->hold + sregs->fhold;
    14961428            }
    14971429            break;
    14981430        case LDFSR:
    1499             if (ebase.simtime < sregs->ftime) {
    1500                 sregs->fhold += (sregs->ftime - ebase.simtime);
     1431            if (sregs->simtime < sregs->ftime) {
     1432                sregs->fhold += (sregs->ftime - sregs->simtime);
    15011433            }
    15021434            if (!((sregs->psr & PSR_EF) && FP_PRES)) {
    15031435                sregs->trap = TRAP_FPDIS;
    dispatch_instruction(sregs) 
    15261458                sregs->trap = TRAP_UNALI;
    15271459                break;
    15281460            }
    1529             if (ebase.simtime < sregs->ftime) {
    1530                 sregs->fhold += (sregs->ftime - ebase.simtime);
     1461            if (sregs->simtime < sregs->ftime) {
     1462                sregs->fhold += (sregs->ftime - sregs->simtime);
    15311463            }
    15321464            mexc = ms->memory_write (address, &sregs->fsr, 2, &ws);
    15331465            sregs->hold += ws;
    dispatch_instruction(sregs) 
    15421474                sregs->trap = TRAP_UNALI;
    15431475                break;
    15441476            }
    1545             mexc = ms->memory_write_asi (asi, address, rdd, 2, &ws);
    1546             sregs->hold += ws;
    1547             if (mexc)
    1548                 sregs->trap = TRAP_DEXC;
    1549             break;
     1477            if ((cputype == CPU_LEON3) && (asi == 2)) {
     1478                sregs->cache_ctrl = *rdd;
     1479                break;
     1480            }
    15501481        case ST:
    15511482            if (address & 0x3) {
    15521483                sregs->trap = TRAP_UNALI;
    dispatch_instruction(sregs) 
    15601491            break;
    15611492        case STBA:
    15621493            if (!chk_asi(sregs, &asi, op3)) break;
    1563             mexc = ms->memory_write_asi (asi, address, rdd, 0, &ws);
    1564             sregs->hold += ws;
    1565             if (mexc)
    1566                 sregs->trap = TRAP_DEXC;
    1567             break;
     1494            /* fall through to STB */
    15681495        case STB:
    15691496            mexc = ms->memory_write (address, rdd, 0, &ws);
    15701497            sregs->hold += ws;
    dispatch_instruction(sregs) 
    15741501            break;
    15751502        case STDA:
    15761503            if (!chk_asi(sregs, &asi, op3)) break;
    1577             if (address & 0x7) {
    1578                 sregs->trap = TRAP_UNALI;
    1579                 break;
    1580             }
    1581             if (rd & 1) {
    1582                 rd &= 0x1e;
    1583                 if (rd > 7)
    1584                     rdd = &(sregs->r[(cwp + rd) & 0x7f]);
    1585                 else
    1586                     rdd = &(sregs->g[rd]);
    1587             }
    1588             mexc = ms->memory_write_asi (asi, address, rdd, 3, &ws);
    1589             sregs->hold += ws;
    1590             sregs->icnt = T_STD;
    1591 #ifdef STAT
    1592             sregs->nstore++;    /* Double store counts twice */
    1593 #endif
    1594             if (mexc) {
    1595                 sregs->trap = TRAP_DEXC;
    1596                 break;
    1597             }
    1598             break;
    15991504        case STD:
    16001505            if (address & 0x7) {
    16011506                sregs->trap = TRAP_UNALI;
    dispatch_instruction(sregs) 
    16531558            break;
    16541559        case STHA:
    16551560            if (!chk_asi(sregs, &asi, op3)) break;
    1656             if (address & 0x1) {
    1657                 sregs->trap = TRAP_UNALI;
    1658                 break;
    1659             }
    1660             mexc = ms->memory_write_asi (asi, address, rdd, 1, &ws);
    1661             sregs->hold += ws;
    1662             if (mexc)
    1663                 sregs->trap = TRAP_DEXC;
    1664             break;
    16651561        case STH:
    16661562            if (address & 0x1) {
    16671563                sregs->trap = TRAP_UNALI;
    dispatch_instruction(sregs) 
    16821578                sregs->trap = TRAP_UNALI;
    16831579                break;
    16841580            }
    1685             if (ebase.simtime < sregs->ftime) {
     1581            if (sregs->simtime < sregs->ftime) {
    16861582                if (sregs->frd == rd)
    1687                     sregs->fhold += (sregs->ftime - ebase.simtime);
     1583                    sregs->fhold += (sregs->ftime - sregs->simtime);
    16881584            }
    16891585            mexc = ms->memory_write (address, &sregs->fsi[rd], 2, &ws);
    16901586            sregs->hold += ws;
    dispatch_instruction(sregs) 
    17021598                break;
    17031599            }
    17041600            rd &= 0x1E;
    1705             if (ebase.simtime < sregs->ftime) {
     1601            if (sregs->simtime < sregs->ftime) {
    17061602                if ((sregs->frd == rd) || (sregs->frd + 1 == rd))
    1707                     sregs->fhold += (sregs->ftime - ebase.simtime);
     1603                    sregs->fhold += (sregs->ftime - sregs->simtime);
    17081604            }
    17091605            mexc = ms->memory_write (address, &sregs->fsi[rd], 3, &ws);
    17101606            sregs->hold += ws;
    dispatch_instruction(sregs) 
    17181614            break;
    17191615        case SWAPA:
    17201616            if (!chk_asi(sregs, &asi, op3)) break;
    1721             if (address & 0x3) {
    1722                 sregs->trap = TRAP_UNALI;
    1723                 break;
    1724             }
    1725             mexc = ms->memory_read_asi (asi, address, &data, 2, &ws);
    1726             sregs->hold += ws;
    1727             if (mexc) {
    1728                 sregs->trap = TRAP_DEXC;
    1729                 break;
    1730             }
    1731             mexc = ms->memory_write_asi (asi, address, rdd, 2, &ws);
    1732             sregs->hold += ws;
    1733             sregs->icnt = T_LDST;
    1734             if (mexc) {
    1735                 sregs->trap = TRAP_DEXC;
    1736                 break;
    1737             } else
    1738                 *rdd = data;
    1739 #ifdef STAT
    1740             sregs->nload++;
    1741 #endif
    1742             break;
    17431617        case SWAP:
    17441618            if (address & 0x3) {
    17451619                sregs->trap = TRAP_UNALI;
    dispatch_instruction(sregs) 
    17721646                sregs->trap = TRAP_UNALI;
    17731647                break;
    17741648            }
    1775             mexc = ms->memory_read_asi (asi, address, &data, 2, &ws);
     1649            mexc = ms->memory_read (address, &data, 2, &ws);
    17761650            sregs->hold += ws;
    17771651            if (mexc) {
    17781652                sregs->trap = TRAP_DEXC;
    17791653                break;
    17801654            }
    17811655            if (data == operand2) {
    1782                 mexc = ms->memory_write_asi (asi, address, rdd, 2, &ws);
     1656                mexc = ms->memory_write (address, rdd, 2, &ws);
    17831657                if (mexc) {
    17841658                    sregs->trap = TRAP_DEXC;
    17851659                    break;
    dispatch_instruction(sregs) 
    18001674#ifdef LOAD_DEL
    18011675
    18021676        if (!(op3 & 4)) {
    1803             sregs->ildtime = ebase.simtime + sregs->hold + sregs->icnt;
     1677            sregs->ildtime = sregs->simtime + sregs->hold + sregs->icnt;
    18041678            sregs->ildreg = rd;
    18051679            if ((op3 | 0x10) == 0x13)
    18061680                sregs->ildreg |= 1;     /* Double load, odd register loaded
    dispatch_instruction(sregs) 
    18171691    if (!sregs->trap) {
    18181692        sregs->pc = pc;
    18191693        sregs->npc = npc;
     1694        if (annul) {
     1695            sregs->pc = sregs->npc;
     1696            sregs->npc = sregs->npc + 4;
     1697            sregs->icnt += 1;
     1698        }
    18201699    }
    18211700    return 0;
    18221701}
    fpexec(op3, rd, rs1, rs2, sregs) 
    18941773     * finished by incrementing fhold with the remaining execution time
    18951774     */
    18961775
    1897     if (ebase.simtime < sregs->ftime) {
    1898         sregs->fhold = (sregs->ftime - ebase.simtime);
     1776    if (sregs->simtime < sregs->ftime) {
     1777        sregs->fhold = (sregs->ftime - sregs->simtime);
    18991778    } else {
    19001779        sregs->fhold = 0;
    19011780
    19021781        /* Check load dependencies. */
    19031782
    1904         if (ebase.simtime < sregs->ltime) {
     1783        if (sregs->simtime < sregs->ltime) {
    19051784
    19061785            /* Don't check rs1 if single operand instructions */
    19071786
    fpexec(op3, rd, rs1, rs2, sregs) 
    19221801    sregs->frs2 = rs2;
    19231802    sregs->frd = rd;
    19241803
    1925     sregs->ftime = ebase.simtime + sregs->hold + sregs->fhold;
     1804    sregs->ftime = sregs->simtime + sregs->hold + sregs->fhold;
    19261805
    19271806    /* SPARC is big-endian - swap double floats if host is little-endian */
    19281807    /* This is ugly - I know ... */
    execute_trap(sregs) 
    21982077
    21992078        if ((sregs->psr & PSR_ET) == 0)
    22002079            return ERROR;
     2080        if ((sregs->trap > 16) && (sregs->trap < 32))
     2081            sregs->intack(sregs->trap - 16, sregs->cpu);
    22012082
    22022083        sregs->tbr = (sregs->tbr & 0xfffff000) | (sregs->trap << 4);
    22032084        sregs->trap = 0;
    22042085        sregs->psr &= ~PSR_ET;
    22052086        sregs->psr |= ((sregs->psr & PSR_S) >> 1);
    2206         sregs->annul = 0;
    22072087        sregs->psr = (((sregs->psr & PSR_CWP) - 1) & 0x7) | (sregs->psr & ~PSR_CWP);
    22082088        cwp = ((sregs->psr & PSR_CWP) << 4);
    22092089        sregs->r[(cwp + 17) & 0x7f] = sregs->pc;
    int 
    22322112check_interrupts(sregs)
    22332113    struct pstate  *sregs;
    22342114{
    2235 #ifdef ERRINJ
    2236     if (errtt) {
    2237         sregs->trap = errtt;
    2238         if (sis_verbose) printf("Inserted error trap 0x%02X\n",errtt);
    2239         errtt = 0;
    2240     }
    2241 #endif
    2242 
    2243     if ((ext_irl) && (sregs->psr & PSR_ET) &&
    2244         ((ext_irl == 15) || (ext_irl > (int) ((sregs->psr & PSR_PIL) >> 8)))) {
     2115    if ((ext_irl[sregs->cpu]) && (sregs->psr & PSR_ET) &&
     2116        ((ext_irl[sregs->cpu] == 15) || (ext_irl[sregs->cpu] > (int) ((sregs->psr & PSR_PIL) >> 8)))) {
     2117        if (sregs->pwd_mode) {
     2118            sregs->pwdtime += sregs->simtime -sregs->pwdstart;
     2119            sregs->pwd_mode = 0;
     2120        }
    22452121        if (sregs->trap == 0) {
    2246             sregs->trap = 16 + ext_irl;
    2247             irqarr[ext_irl & 0x0f].callback(irqarr[ext_irl & 0x0f].arg);
    2248             return 1;
     2122            return ext_irl[sregs->cpu];
    22492123        }
    22502124    }
    22512125    return 0;
    void 
    22552129init_regs(sregs)
    22562130    struct pstate  *sregs;
    22572131{
    2258     sregs->pc = 0;
    2259     sregs->npc = 4;
    2260     sregs->trap = 0;
    2261     sregs->psr &= 0x00f03fdf;
     2132  int i;
     2133
     2134  for (i=0; i<NCPU; i++) { 
     2135    sregs[i].pc = 0;
     2136    sregs[i].npc = 4;
     2137    sregs[i].trap = 0;
     2138    sregs[i].psr &= 0x00f03fdf;
    22622139    if (cputype == CPU_LEON3)
    2263       sregs->psr |= 0xF3000080; /* Set supervisor bit */
     2140      sregs[i].psr |= 0xF3000080;       /* Set supervisor bit */
    22642141    else
    22652142    if (cputype == CPU_LEON2)
    2266       sregs->psr |= 0x00000080; /* Set supervisor bit */
     2143      sregs[i].psr |= 0x00000080;       /* Set supervisor bit */
    22672144    else
    2268       sregs->psr |= 0x11000080; /* Set supervisor bit */
    2269     sregs->breakpoint = 0;
    2270     sregs->annul = 0;
    2271     sregs->fpstate = FP_EXE_MODE;
    2272     sregs->fpqn = 0;
    2273     sregs->ftime = 0;
    2274     sregs->ltime = 0;
    2275     sregs->err_mode = 0;
    2276     ext_irl = 0;
    2277     sregs->g[0] = 0;
     2145      sregs[i].psr |= 0x11000080;       /* Set supervisor bit */
     2146    sregs[i].breakpoint = 0;
     2147    sregs[i].fpstate = FP_EXE_MODE;
     2148    sregs[i].fpqn = 0;
     2149    sregs[i].ftime = 0;
     2150    sregs[i].ltime = 0;
     2151    sregs[i].err_mode = 0;
     2152    ext_irl[i] = 0;
     2153    sregs[i].g[0] = 0;
    22782154#ifdef HOST_LITTLE_ENDIAN
    2279     sregs->fdp = (float32 *) sregs->fd;
    2280     sregs->fsi = (int32 *) sregs->fs;
     2155    sregs[i].fdp = (float32 *) sregs[i].fd;
     2156    sregs[i].fsi = (int32 *) sregs[i].fs;
    22812157#else
    2282     sregs->fs = (float32 *) sregs->fd;
    2283     sregs->fsi = (int32 *) sregs->fd;
     2158    sregs[i].fs = (float32 *) sregs[i].fd;
     2159    sregs[i].fsi = (int32 *) sregs[i].fd;
    22842160#endif
    2285     sregs->fsr = 0;
    2286     sregs->fpu_pres = !nfp;
    2287     set_fsr(sregs->fsr);
    2288     sregs->bphit = 0;
    2289     sregs->wphit = 0;
    2290     sregs->ildreg = 0;
    2291     sregs->ildtime = 0;
    2292 
    2293     sregs->y = 0;
    2294     sregs->asr17 = 0;
    2295 
    2296     sregs->rett_err = 0;
    2297     sregs->jmpltime = 0;
     2161    sregs[i].fsr = 0;
     2162    sregs[i].fpu_pres = !nfp;
     2163    set_fsr(sregs[i].fsr);
     2164    ebase.bphit = 0;
     2165    ebase.wphit = 0;
     2166    sregs[i].ildreg = 0;
     2167    sregs[i].ildtime = 0;
     2168
     2169    sregs[i].y = 0;
     2170    sregs[i].asr17 = 0;
     2171
     2172    sregs[i].rett_err = 0;
     2173    sregs[i].jmpltime = 0;
    22982174    if (cputype == CPU_LEON3) {
    2299         sregs->asr17 = 0x107;
    2300         if (!nfp) sregs->asr17 |= (3 << 10);  /* Meiko FPU */
     2175        sregs[i].asr17 = 0x04000107 | (i << 28);
     2176        if (!nfp) sregs[i].asr17 |= (3 << 10);  /* Meiko FPU */
    23012177    }
     2178    sregs[i].cpu = i;
     2179    sregs[i].simtime = 0;
     2180    sregs[i].pwdtime = 0;
     2181    sregs[i].pwdstart = 0;
     2182    if (i == 0)
     2183        sregs[i].pwd_mode = 0;
     2184    else
     2185        sregs[i].pwd_mode = 1;
     2186  }
    23022187}
  • sim/erc32/func.c

    diff --git a/sim/erc32/func.c b/sim/erc32/func.c
    index 1cf7e451bb..b1a56d75bb 100644
    a b int dumbio = 0; 
    3737int tty_setup = 1;
    3838
    3939struct disassemble_info dinfo;
    40 struct pstate   sregs;
     40struct pstate   sregs[NCPU];
    4141struct estate   ebase;
    4242struct evcell   evbuf[EVENT_MAX];
    43 struct irqcell  irqarr[16];
    4443
    4544int             ctrl_c = 0;
    4645int             sis_verbose = 0;
    47 char           *sis_version = "2.8";
     46char           *sis_version = "2.9";
    4847int             nfp = 0;
    4948int             ift = 0;
    5049int             wrp = 0;
    host_callback *sim_callback; 
    6160const struct memsys *ms = &erc32sys;
    6261int             cputype = 0;            /* 0 = erc32, 2 = leon2,3 = leon3 */
    6362int             sis_gdb_break;
     63int             cpu = 0;                /* active cpu */
     64int             ncpu = 1;               /* number of cpus to emulate */
     65int             delta = 50;             /* time slice for MP simulation */
    6466
    6567#ifdef ERRINJ
    6668uint32          errcnt = 0;
    batch(sregs, fname) 
    103105        if (slen && (lbuf[slen - 1] == '\n')) {
    104106            lbuf[slen - 1] = 0;
    105107            printf("sis> %s\n", lbuf);
    106             exec_cmd(sregs, lbuf);
     108            exec_cmd(lbuf);
    107109        }
    108110    }
    109111    free(lbuf);
    limcalc (freq) 
    374376            lim = (uint64) flim;
    375377        } else  {
    376378            printf("error in expression\n");
    377             lim = -1;
     379            lim = 0;
    378380        }
    379381    }
    380382    return lim;
    381383}
    382384
    383385int
    384 exec_cmd(struct pstate *sregs, const char *cmd)
     386exec_cmd(const char *cmd)
    385387{
    386388    char           *cmd1, *cmd2;
    387389    int32           stat;
    exec_cmd(struct pstate *sregs, const char *cmd) 
    395397    if ((cmd1 = strtok (cmdsave2, " \t")) != NULL) {
    396398        clen = strlen(cmd1);
    397399        if (strncmp(cmd1, "bp", clen) == 0) {
    398             for (i = 0; i < sregs->bptnum; i++) {
    399                 printf("  %d : 0x%08x\n", i + 1, sregs->bpts[i]);
     400            for (i = 0; i < ebase.bptnum; i++) {
     401                printf("  %d : 0x%08x\n", i + 1, ebase.bpts[i]);
    400402            }
    401403        } else if (strncmp(cmd1, "+bp", clen) == 0) {
    402404            if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
    403                 sregs->bpts[sregs->bptnum] = VAL(cmd1) & ~0x3;
     405                ebase.bpts[ebase.bptnum] = VAL(cmd1) & ~0x3;
    404406                printf("added breakpoint %d at 0x%08x\n",
    405                        sregs->bptnum + 1, sregs->bpts[sregs->bptnum]);
    406                 sregs->bptnum += 1;
     407                       ebase.bptnum + 1, ebase.bpts[ebase.bptnum]);
     408                ebase.bptnum += 1;
    407409            }
    408410        } else if (strncmp(cmd1, "-bp", clen) == 0) {
    409411            if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
    410412                i = VAL(cmd1) - 1;
    411                 if ((i >= 0) && (i < sregs->bptnum)) {
     413                if ((i >= 0) && (i < ebase.bptnum)) {
    412414                    printf("deleted breakpoint %d at 0x%08x\n", i + 1,
    413                            sregs->bpts[i]);
    414                     for (; i < sregs->bptnum - 1; i++) {
    415                         sregs->bpts[i] = sregs->bpts[i + 1];
     415                           ebase.bpts[i]);
     416                    for (; i < ebase.bptnum - 1; i++) {
     417                        ebase.bpts[i] = ebase.bpts[i + 1];
    416418                    }
    417                     sregs->bptnum -= 1;
     419                    ebase.bptnum -= 1;
    418420                }
    419421            }
    420422        } else if (strncmp(cmd1, "batch", clen) == 0) {
    exec_cmd(struct pstate *sregs, const char *cmd) 
    425427            }
    426428        } else if (strncmp(cmd1, "cont", clen) == 0) {
    427429            if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
    428                 stat = run_sim(sregs, UINT64_MAX, 0);
     430                stat = run_sim(UINT64_MAX/2, 0);
    429431            } else {
    430                 stat = run_sim(sregs, VAL(cmd1), 0);
     432                stat = run_sim(VAL(cmd1), 0);
    431433            }
    432434            daddr = sregs->pc;
    433435            ms->sim_halt ();
    exec_cmd(struct pstate *sregs, const char *cmd) 
    470472            } else {
    471473                len = VAL(cmd1);
    472474            }
    473             sregs->pc = len & ~3;
    474             sregs->npc = sregs->pc + 4;
     475            for (i=0; i<ncpu; i++) {
     476                sregs[i].pc = len & ~3;
     477                sregs[i].npc = sregs->pc + 4;
     478            }
    475479            if ((sregs->pc != 0) && (ebase.simtime == 0))
    476480                ms->boot_init ();
    477481            printf("resuming at 0x%08x\n",sregs->pc);
    478482            if ((cmd2 = strtok(NULL, " \t\n\r")) != NULL) {
    479                 stat = run_sim(sregs, VAL(cmd2), 0);
     483                stat = run_sim(VAL(cmd2), 0);
    480484            } else {
    481                 stat = run_sim(sregs, UINT64_MAX, 0);
     485                stat = run_sim(UINT64_MAX/2, 0);
    482486            }
    483487            daddr = sregs->pc;
    484488            ms->sim_halt ();
    exec_cmd(struct pstate *sregs, const char *cmd) 
    486490            gen_help();
    487491        } else if (strncmp(cmd1, "history", clen) == 0) {
    488492            if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
    489                 sregs->histlen = VAL(cmd1);
    490                 if (sregs->histbuf != NULL)
    491                     free(sregs->histbuf);
    492                 sregs->histbuf = (struct histype *) calloc(sregs->histlen, sizeof(struct histype));
    493                 printf("trace history length = %d\n\r", sregs->histlen);
    494                 sregs->histind = 0;
     493                ebase.histlen = VAL(cmd1);
     494                for (i=0; i<ncpu; i++) {
     495                    if (sregs[i].histbuf != NULL)
     496                        free(sregs[i].histbuf);
     497                        sregs[i].histbuf = (struct histype *) calloc(ebase.histlen, sizeof(struct histype));
     498                        sregs[i].histind = 0;
     499                }
     500                printf("trace history length = %d\n\r", ebase.histlen);
    495501
    496502            } else {
    497                 j = sregs->histind;
    498                 for (i = 0; i < sregs->histlen; i++) {
    499                     if (j >= sregs->histlen)
     503                j = sregs[cpu].histind;
     504                for (i = 0; i < ebase.histlen; i++) {
     505                    if (j >= ebase.histlen)
    500506                        j = 0;
    501                     printf(" %8d ", sregs->histbuf[j].time);
    502                     dis_mem(sregs->histbuf[j].addr, 1, &dinfo);
     507                    printf(" %8d ", sregs[cpu].histbuf[j].time);
     508                    dis_mem(sregs[cpu].histbuf[j].addr, 1, &dinfo);
    503509                    j++;
    504510                }
    505511            }
    exec_cmd(struct pstate *sregs, const char *cmd) 
    521527                len = 64;
    522528            disp_mem(daddr, len);
    523529            daddr += len;
     530        } else if (strncmp(cmd1, "cpu", clen) == 0) {
     531            if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
     532                cpu = VAL(cmd1);
     533                if (cpu > NCPU) cpu = NCPU;
     534            }
     535            printf("active cpu: %d\n", cpu);
     536        } else if (strncmp(cmd1, "ncpu", clen) == 0) {
     537            if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
     538                ncpu = VAL(cmd1);
     539                if (ncpu > NCPU) ncpu = NCPU;
     540            }
     541            printf("number of online cpus: %d\n", ncpu);
    524542        } else if (strncmp(cmd1, "wmem", clen) == 0) {
    525543            if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL)
    526544                daddr = VAL(cmd1);
    exec_cmd(struct pstate *sregs, const char *cmd) 
    540558            cmd1 = strtok(NULL, " \t\n\r");
    541559            cmd2 = strtok(NULL, " \t\n\r");
    542560            if (cmd2 != NULL)
    543                 set_rega(sregs, cmd1, VAL(cmd2));
     561                set_rega(&sregs[cpu], cmd1, VAL(cmd2));
    544562            else if (cmd1 != NULL)
    545                 disp_reg(sregs, cmd1);
     563                disp_reg(&sregs[cpu], cmd1);
    546564            else {
    547                 disp_regs(sregs,sregs->psr);
    548                 disp_ctrl(sregs);
     565                disp_regs(&sregs[cpu], sregs[cpu].psr);
     566                disp_ctrl(&sregs[cpu]);
    549567            }
    550568        } else if (strncmp(cmd1, "reset", clen) == 0) {
    551569            ebase.simtime = 0;
     570            ebase.simstart = 0;
    552571            reset_all();
    553572            reset_stat(sregs);
    554573        } else if (strncmp(cmd1, "run", clen) == 0) {
    555574            ebase.simtime = 0;
     575            ebase.simstart = 0;
    556576            reset_all();
    557577            reset_stat(sregs);
    558578            if (last_load_addr != 0) {
    559                 sregs->pc = last_load_addr & ~3;
    560                 sregs->npc = sregs->pc + 4;
     579                for (i=0; i<ncpu; i++) {
     580                  sregs[i].pc = last_load_addr & ~3;
     581                  sregs[i].npc = sregs[i].pc + 4;
     582                }
    561583            }
    562584            if ((sregs->pc != 0) && (ebase.simtime == 0)) ms->boot_init ();
    563585            if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
    564                 stat = run_sim(sregs, UINT64_MAX, 0);
     586                stat = run_sim(UINT64_MAX/2, 0);
    565587            } else {
    566                 stat = run_sim(sregs, VAL(cmd1), 0);
     588                stat = run_sim(VAL(cmd1), 0);
    567589            }
    568590            daddr = sregs->pc;
    569591            ms->sim_halt ();
    exec_cmd(struct pstate *sregs, const char *cmd) 
    574596                }
    575597            }
    576598        } else if (strncmp(cmd1, "step", clen) == 0) {
    577             stat = run_sim(sregs, 1, 1);
     599            stat = run_sim(1, 1);
    578600            daddr = sregs->pc;
    579601            ms->sim_halt ();
    580602        } else if (strncmp(cmd1, "tcont", clen) == 0) {
    581             sregs->tlimit = limcalc(sregs->freq);
    582             stat = run_sim(sregs, UINT64_MAX, 0);
     603            ebase.tlimit = limcalc(ebase.freq);
     604            stat = run_sim(UINT64_MAX/2, 0);
    583605            daddr = sregs->pc;
    584606            ms->sim_halt ();
    585607        } else if (strncmp(cmd1, "tgo", clen) == 0) {
    exec_cmd(struct pstate *sregs, const char *cmd) 
    587609                len = last_load_addr;
    588610            } else {
    589611                len = VAL(cmd1);
    590                 sregs->tlimit = limcalc(sregs->freq);
     612                ebase.tlimit = limcalc(ebase.freq);
    591613            }
    592614            sregs->pc = len & ~3;
    593615            sregs->npc = sregs->pc + 4;
    594616            printf("resuming at 0x%08x\n",sregs->pc);
    595             stat = run_sim(sregs, UINT64_MAX, 0);
     617            stat = run_sim(UINT64_MAX/2, 0);
    596618            daddr = sregs->pc;
    597619            ms->sim_halt ();
    598620        } else if (strncmp(cmd1, "tlimit", clen) == 0) {
    599            sregs->tlimit = limcalc(sregs->freq);
    600            if (sregs->tlimit != (uint32) -1)
    601               printf("simulation limit = %u (%.3f ms)\n",(uint32) sregs->tlimit,
    602                 sregs->tlimit / sregs->freq / 1000);
     621           ebase.tlimit = limcalc(ebase.freq);
     622           if (ebase.tlimit != (uint32) -1)
     623              if (sis_verbose)
     624                  printf("simulation limit = %u (%.3f ms)\n",
     625                      (uint32) ebase.tlimit, ebase.tlimit / ebase.freq / 1000);
    603626        } else if (strncmp(cmd1, "tra", clen) == 0) {
    604627            if ((cmd1 = strtok(NULL, " \t\n\r")) == NULL) {
    605                 stat = run_sim(sregs, UINT64_MAX, 1);
     628                stat = run_sim(UINT64_MAX/2, 1);
    606629            } else {
    607                 stat = run_sim(sregs, VAL(cmd1), 1);
     630                stat = run_sim(VAL(cmd1), 1);
    608631            }
    609632            printf("\n");
    610633            daddr = sregs->pc;
    611634            ms->sim_halt ();
    612635        } else if (strncmp(cmd1, "trun", clen) == 0) {
    613636            ebase.simtime = 0;
     637            ebase.simstart = 0;
    614638            reset_all();
    615639            reset_stat(sregs);
    616640            if (last_load_addr != 0) {
    exec_cmd(struct pstate *sregs, const char *cmd) 
    618642                sregs->npc = sregs->pc + 4;
    619643            }
    620644            if ((sregs->pc != 0) && (ebase.simtime == 0)) ms->boot_init ();
    621             sregs->tlimit = limcalc(sregs->freq);
    622             stat = run_sim(sregs, UINT64_MAX, 0);
     645            ebase.tlimit = limcalc(ebase.freq);
     646            stat = run_sim(UINT64_MAX/2, 0);
    623647            daddr = sregs->pc;
    624648            ms->sim_halt ();
    625649        } else if (strncmp(cmd1, "wp", clen) == 0) {
    626             for (i = 0; i < sregs->wprnum; i++) {
    627                 printf("  %d : 0x%08x (read)\n", i + 1, sregs->wprs[i]);
     650            for (i = 0; i < ebase.wprnum; i++) {
     651                printf("  %d : 0x%08x (read)\n", i + 1, ebase.wprs[i]);
    628652            }
    629             for (i = 0; i < sregs->wpwnum; i++) {
    630                 printf("  %d : 0x%08x (write)\n", i + 1, sregs->wpws[i]);
     653            for (i = 0; i < ebase.wpwnum; i++) {
     654                printf("  %d : 0x%08x (write)\n", i + 1, ebase.wpws[i]);
    631655            }
    632656        } else if (strncmp(cmd1, "+wpr", clen) == 0) {
    633657            if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
    634                 sregs->wprs[sregs->wprnum] = VAL(cmd1) & ~0x3;
    635                 sregs->wprm[sregs->wprnum] = 3;
     658                ebase.wprs[ebase.wprnum] = VAL(cmd1) & ~0x3;
     659                ebase.wprm[ebase.wprnum] = 3;
    636660                printf("added read watchpoint %d at 0x%08x\n",
    637                        sregs->wprnum + 1, sregs->wprs[sregs->wprnum]);
    638                 sregs->wprnum += 1;
     661                       ebase.wprnum + 1, ebase.wprs[ebase.wprnum]);
     662                ebase.wprnum += 1;
    639663            }
    640664        } else if (strncmp(cmd1, "-wpr", clen) == 0) {
    641665            if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
    642666                i = VAL(cmd1) - 1;
    643                 if ((i >= 0) && (i < sregs->wprnum)) {
     667                if ((i >= 0) && (i < ebase.wprnum)) {
    644668                    printf("deleted read watchpoint %d at 0x%08x\n", i + 1,
    645                            sregs->wprs[i]);
    646                     for (; i < sregs->wprnum - 1; i++) {
    647                         sregs->wprs[i] = sregs->wprs[i + 1];
     669                           ebase.wprs[i]);
     670                    for (; i < ebase.wprnum - 1; i++) {
     671                        ebase.wprs[i] = ebase.wprs[i + 1];
    648672                    }
    649                     sregs->wprnum -= 1;
     673                    ebase.wprnum -= 1;
    650674                }
    651675            }
    652676        } else if (strncmp(cmd1, "+wpw", clen) == 0) {
    653677            if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
    654                 sregs->wpws[sregs->wpwnum] = VAL(cmd1) & ~0x3;
    655                 sregs->wpwm[sregs->wpwnum] = 3;
     678                ebase.wpws[ebase.wpwnum] = VAL(cmd1) & ~0x3;
     679                ebase.wpwm[ebase.wpwnum] = 3;
    656680                printf("added write watchpoint %d at 0x%08x\n",
    657                        sregs->wpwnum + 1, sregs->wpws[sregs->wpwnum]);
    658                 sregs->wpwnum += 1;
     681                       ebase.wpwnum + 1, ebase.wpws[ebase.wpwnum]);
     682                ebase.wpwnum += 1;
    659683            }
    660684        } else if (strncmp(cmd1, "-wpw", clen) == 0) {
    661685            if ((cmd1 = strtok(NULL, " \t\n\r")) != NULL) {
    662686                i = VAL(cmd1) - 1;
    663                 if ((i >= 0) && (i < sregs->wpwnum)) {
     687                if ((i >= 0) && (i < ebase.wpwnum)) {
    664688                    printf("deleted write watchpoint %d at 0x%08x\n", i + 1,
    665                            sregs->wpws[i]);
    666                     for (; i < sregs->wpwnum - 1; i++) {
    667                         sregs->wpws[i] = sregs->wpws[i + 1];
     689                           ebase.wpws[i]);
     690                    for (; i < ebase.wpwnum - 1; i++) {
     691                        ebase.wpws[i] = ebase.wpws[i + 1];
    668692                    }
    669                     sregs->wpwnum -= 1;
     693                    ebase.wpwnum -= 1;
    670694                }
    671695            }
    672696        } else
    void 
    684708reset_stat(sregs)
    685709    struct pstate  *sregs;
    686710{
    687     sregs->tottime = 0.0;
     711    ebase.tottime = 0.0;
    688712    sregs->pwdtime = 0;
    689713    sregs->ninst = 0;
    690714    sregs->fholdt = 0;
    reset_stat(sregs) 
    694718    sregs->nstore = 0;
    695719    sregs->nload = 0;
    696720    sregs->nbranch = 0;
    697     sregs->simstart = ebase.simtime;
     721    ebase.simstart = ebase.simtime;
    698722
    699723}
    700724
    void 
    702726show_stat(sregs)
    703727    struct pstate  *sregs;
    704728{
    705     uint64          iinst;
    706     uint64          stime;
    707 
    708     if (sregs->tottime == 0.0)
    709         sregs->tottime += 1E-6;
    710     stime = ebase.simtime - sregs->simstart;    /* Total simulated time */
     729    uint64          iinst, ninst, pwdtime;
     730    uint64          stime, atime;
     731    int         i;
     732
     733    ninst = 0;
     734    pwdtime = 0;
     735    atime = 0;
     736    if (ebase.tottime == 0.0)
     737        ebase.tottime += 1E-6;
     738    for (i=0; i<ncpu; i++) {
     739        if (sregs[i].pwd_mode) {
     740            sregs[i].pwdtime += sregs[i].simtime - sregs[i].pwdstart;
     741            sregs[i].pwdstart = sregs[i].simtime;
     742        }
     743        ninst += sregs[i].ninst;
     744        pwdtime += sregs[i].pwdtime;
     745    }
     746    stime = ebase.simtime - ebase.simstart; /* Total simulated time */
     747    printf ("\n Frequency       : %4.1f MHz\n", ebase.freq);
     748    printf(" Cycles          : %" PRIu64 "\n", stime);
     749    printf(" Instructions    : %" PRIu64 "\n", ninst);
     750    printf(" Simulated time  : %.2f s\n",
     751        (double) (stime) / 1000000.0 / ebase.freq);
     752    printf(" System perf.    : %.2f MOPS\n",
     753        (double) ninst / ((double) (stime) / ebase.freq));
     754    printf(" Real-time perf. : %.2f %%\n",
     755        100.0 / (ebase.tottime / ((double) (stime) / (ebase.freq * 1.0E6))));
     756    printf(" Simulator perf. : %.2f MIPS\n",
     757        (double)(ninst / ebase.tottime / 1E6));
     758    printf(" Wall time       : %.2f s\n\n", ebase.tottime);
     759    printf (" Core   MIPS   MFLOPS     CPI     Util\n");
     760    for (i=0; i<ncpu; i++) {
    711761#ifdef STAT
    712 
    713     iinst = sregs->ninst - sregs->finst - sregs->nload - sregs->nstore -
    714         sregs->nbranch;
     762        iinst = sregs[i].ninst - sregs[i].finst - sregs[i].nload - sregs[i].nstore -
     763            sregs[i].nbranch;
    715764#endif
    716765
    717     printf("\n Cycles       : %9" PRIu64 "\n\r", ebase.simtime - sregs->simstart);
    718     printf(" Instructions : %9" PRIu64 "\n", sregs->ninst);
     766        stime = sregs[i].simtime - ebase.simstart + 1; /* Core simulated time */
     767        printf ("  %d    %5.2f    %5.2f    %5.2f    %5.2f %%\n", i,
     768          ebase.freq * (double) (sregs[i].ninst - sregs[i].finst) /
     769          (double) (stime - sregs[i].pwdtime),
     770          ebase.freq * (double) sregs[i].finst / (double) (stime - sregs[i].pwdtime),
     771          (double) (stime - sregs[i].pwdtime) / (double) (sregs[i].ninst + 1),
     772         100.0 * (1.0 - ((double) sregs[i].pwdtime / (double) stime)));
     773    }
    719774
    720775#ifdef STAT
    721     printf ("   integer    : %9.2f %%\n", 100.0 * (double) iinst / (double) sregs->ninst);
     776    printf ("   integer    : %9.2f %%\n", 100.0 * (double) iinst / (double) sregs[i].ninst);
    722777    printf("   load       : %9.2f %%\n",
    723            100.0 * (double) sregs->nload / (double) sregs->ninst);
     778           100.0 * (double) sregs->nload / (double) sregs[i].ninst);
    724779    printf("   store      : %9.2f %%\n",
    725            100.0 * (double) sregs->nstore / (double) sregs->ninst);
     780           100.0 * (double) sregs->nstore / (double) sregs[i].ninst);
    726781    printf("   branch     : %9.2f %%\n",
    727            100.0 * (double) sregs->nbranch / (double) sregs->ninst);
     782           100.0 * (double) sregs->nbranch / (double) sregs[i].ninst);
    728783    printf("   float      : %9.2f %%\n",
    729            100.0 * (double) sregs->finst / (double) sregs->ninst);
     784           100.0 * (double) sregs->finst / (double) sregs[i].ninst);
    730785    printf(" Integer CPI  : %9.2f\n",
    731            ((double) (stime - sregs->pwdtime - sregs->fholdt - sregs->finst))
     786           ((double) (stime - sregs[i].pwdtime - sregs[i].fholdt - sregs[i].finst))
    732787           /
    733            (double) (sregs->ninst - sregs->finst));
     788           (double) (sregs[i].ninst - sregs[i].finst));
    734789    printf(" Float CPI    : %9.2f\n",
    735            ((double) sregs->fholdt / (double) sregs->finst) + 1.0);
     790           ((double) sregs[i].fholdt / (double) sregs[i].finst) + 1.0);
    736791#endif
    737     printf(" Overall CPI  : %9.2f\n",
    738           (double) (stime - sregs->pwdtime) / (double) sregs->ninst);
    739     printf ("\n CPU performance (%4.1f MHz)  : %5.2f MOPS (%5.2f MIPS, %5.2f MFLOPS)\n",
    740           sregs->freq, sregs->freq * (double) sregs->ninst / (double) (stime - sregs->pwdtime),
    741           sregs->freq * (double) (sregs->ninst - sregs->finst) /
    742           (double) (stime - sregs->pwdtime),
    743      sregs->freq * (double) sregs->finst / (double) (stime - sregs->pwdtime));
    744     printf (" Simulated CPU time          : %.2f s\n",
    745         (double) (ebase.simtime - sregs->simstart) / 1000000.0 / sregs->freq);
    746     printf(" Processor utilisation       : %.2f %%\n",
    747         100.0 * (1.0 - ((double) sregs->pwdtime / (double) stime)));
    748     printf(" Real-time performance       : %.2f %%\n",
    749         100.0 / (sregs->tottime / ((double) (stime) / (sregs->freq * 1.0E6))));
    750     printf(" Simulator performance       : %.2f MIPS\n",
    751         (double)(sregs->ninst) / sregs->tottime / 1E6);
    752     printf(" Used time (sys + user)      : %.2f s\n\n", sregs->tottime);
     792    printf("\n");
    753793}
    754794
    755795
    void 
    758798init_bpt(sregs)
    759799    struct pstate  *sregs;
    760800{
    761     sregs->bptnum = 0;
    762     sregs->wprnum = 0;
    763     sregs->wpwnum = 0;
    764     sregs->histlen = 0;
    765     sregs->histind = 0;
    766     sregs->histbuf = NULL;
    767     sregs->tlimit = -1;
     801    int i;
     802
     803    ebase.bptnum = 0;
     804    ebase.wprnum = 0;
     805    ebase.wpwnum = 0;
     806    ebase.histlen = 0;
     807    for (i=0; i<ncpu; i++) {
     808        sregs[i].histind = 0;
     809        sregs[i].histbuf = NULL;
     810    }
     811    ebase.tlimit = 0;
    768812}
    769813
    770814static void
    disp_ctrl(sregs) 
    852896
    853897    printf("\n psr: %08X   wim: %08X   tbr: %08X   y: %08X\n",
    854898           sregs->psr, sregs->wim, sregs->tbr, sregs->y);
     899    printf(" cc: %08X   asr17: %08X\n",
     900           sregs->cache_ctrl, sregs->asr17);
    855901    ms->sis_memory_read (sregs->pc, (char *) &i, 4);
    856902    printf ("\n  pc: %08X = %08X    ", sregs->pc, i);
    857903    print_insn_sparc_sis(sregs->pc, &dinfo);
    disp_ctrl(sregs) 
    860906    print_insn_sparc_sis(sregs->npc, &dinfo);
    861907    if (sregs->err_mode)
    862908        printf("\n IU in error mode");
     909    else if (sregs->pwd_mode)
     910        printf("\n IU in power-down mode");
    863911    printf("\n\n");
    864912}
    865913
    event(cfunc, arg, delta) 
    949997    ev1->nxt->time = delta;
    950998    ev1->nxt->cfunc = cfunc;
    951999    ev1->nxt->arg = arg;
     1000    ebase.evtime = ebase.eq.nxt->time;
    9521001}
    9531002
    954 #if 0   /* apparently not used */
     1003/* remove event from event queue */
    9551004void
    956 stop_event()
     1005remove_event(cfunc)
     1006    void            (*cfunc) ();
     1007{
     1008    struct evcell  *ev1, *evdel;
     1009
     1010    ev1 = &ebase.eq;
     1011    while (ev1->nxt != NULL) {
     1012        if (ev1->nxt->cfunc == cfunc) {
     1013            evdel = ev1->nxt;
     1014            ev1->nxt = ev1->nxt->nxt;
     1015            evdel->nxt = ebase.freeq;
     1016            ebase.freeq = evdel;
     1017        }
     1018        ev1 = ev1->nxt;
     1019    }
     1020    ebase.evtime = ebase.eq.nxt->time;
     1021}
     1022
     1023static void
     1024last_event (int32 arg)
    9571025{
     1026    printf("Warning: end of time ... exiting!\n");
     1027    exit(0);
    9581028}
    959 #endif
    9601029
    9611030void
    9621031init_event()
    init_event() 
    9691038        evbuf[i].nxt = &evbuf[i + 1];
    9701039    }
    9711040    evbuf[EVENT_MAX - 1].nxt = NULL;
    972 }
    973 
    974 void
    975 set_int(level, callback, arg)
    976     int32           level;
    977     void            (*callback) ();
    978     int32           arg;
    979 {
    980     irqarr[level & 0x0f].callback = callback;
    981     irqarr[level & 0x0f].arg = arg;
     1041    event(last_event, 0, UINT64_MAX);
    9821042}
    9831043
    9841044/* Advance simulator time */
    9851045
    9861046void
    987 advance_time(sregs)
    988     struct pstate  *sregs;
     1047advance_time(endtime)
     1048    uint64          endtime;
    9891049{
    9901050
    9911051    struct evcell  *evrem;
    9921052    void            (*cfunc) ();
    9931053    uint32          arg;
    994     uint64          endtime;
    9951054
    996 #ifdef STAT
    997     sregs->fholdt += sregs->fhold;
    998     sregs->holdt += sregs->hold;
    999     sregs->icntt += sregs->icnt;
    1000 #endif
    1001 
    1002     endtime = ebase.simtime + sregs->icnt + sregs->hold + sregs->fhold;
    1003 
    1004     while ((ebase.eq.nxt->time <= (endtime)) && (ebase.eq.nxt != NULL)) {
     1055    while (ebase.evtime <= endtime) {
    10051056        ebase.simtime = ebase.eq.nxt->time;
    10061057        cfunc = ebase.eq.nxt->cfunc;
    10071058        arg = ebase.eq.nxt->arg;
    10081059        evrem = ebase.eq.nxt;
    10091060        ebase.eq.nxt = ebase.eq.nxt->nxt;
     1061        ebase.evtime = ebase.eq.nxt->time;
    10101062        evrem->nxt = ebase.freeq;
    10111063        ebase.freeq = evrem;
    10121064        cfunc(arg);
    advance_time(sregs) 
    10181070uint32
    10191071now()
    10201072{
    1021     return ebase.simtime;
     1073    return (uint32) ebase.simtime;
    10221074}
    10231075
    1024 
    1025 /* Advance time until an external interrupt is seen */
    1026 
    1027 int
    1028 wait_for_irq()
     1076void
     1077pwd_enter(struct pstate *sregs)
    10291078{
    1030     struct evcell  *evrem;
    1031     void            (*cfunc) ();
    1032     int32           arg;
    1033     uint64          endtime;
    1034 
    1035     if (ebase.eq.nxt == NULL)
    1036         printf("Warning: event queue empty - power-down mode not entered\n");
    1037     endtime = ebase.simtime;
    1038     while (!ext_irl && (ebase.eq.nxt != NULL)) {
    1039         ebase.simtime = ebase.eq.nxt->time;
    1040         cfunc = ebase.eq.nxt->cfunc;
    1041         arg = ebase.eq.nxt->arg;
    1042         evrem = ebase.eq.nxt;
    1043         ebase.eq.nxt = ebase.eq.nxt->nxt;
    1044         evrem->nxt = ebase.freeq;
    1045         ebase.freeq = evrem;
    1046         cfunc(arg);
    1047         if (ctrl_c) {
    1048             printf("\bwarning: power-down mode interrupted\n");
    1049             break;
    1050         }
    1051     }
    1052     sregs.pwdtime += ebase.simtime - endtime;
    1053     return ebase.simtime - endtime;
     1079    sregs->pwd_mode = 1;
     1080    sregs->pwdstart = sregs->simtime;
     1081    sregs->hold += delta;
    10541082}
    10551083
    10561084int
    check_bpt(sregs) 
    10591087{
    10601088    int32           i;
    10611089
    1062     if ((sregs->bphit) || (sregs->annul))
     1090    if (ebase.bphit)
    10631091        return 0;
    1064     for (i = 0; i < (int32) sregs->bptnum; i++) {
    1065         if (sregs->pc == sregs->bpts[i])
     1092    for (i = 0; i < (int32) ebase.bptnum; i++) {
     1093        if (sregs->pc == ebase.bpts[i])
    10661094            return BPT_HIT;
    10671095    }
    10681096    return 0;
    check_wpr(sregs, address, mask) 
    10761104{
    10771105    int32           i, msk;
    10781106
    1079     for (i = 0; i < sregs->wprnum; i++) {
    1080         msk = ~(mask | sregs->wprm[i]);
    1081         if (((address ^ sregs->wprs[i]) & msk) == 0) {
    1082             sregs->wpaddress = address;
    1083             if (sregs->wphit) return (0);
     1107    for (i = 0; i < ebase.wprnum; i++) {
     1108        msk = ~(mask | ebase.wprm[i]);
     1109        if (((address ^ ebase.wprs[i]) & msk) == 0) {
     1110            ebase.wpaddress = address;
     1111            if (ebase.wphit) return (0);
    10841112            return (WPT_HIT);
    10851113        }
    10861114    }
    check_wpw(sregs, address, mask) 
    10951123{
    10961124    int32           i, msk;
    10971125
    1098     for (i = 0; i < sregs->wpwnum; i++) {
    1099         msk = ~(mask | sregs->wpwm[i]);
    1100         if (((address ^ sregs->wpws[i]) & msk) == 0) {
    1101             sregs->wpaddress = address;
    1102             if (sregs->wphit) return (0);
     1126    for (i = 0; i < ebase.wpwnum; i++) {
     1127        msk = ~(mask | ebase.wpwm[i]);
     1128        if (((address ^ ebase.wpws[i]) & msk) == 0) {
     1129            ebase.wpaddress = ebase.wpws[i];
     1130            if (ebase.wphit) return (0);
    11031131            return (WPT_HIT);
    11041132        }
    11051133    }
    void 
    11101138reset_all()
    11111139{
    11121140    init_event();               /* Clear event queue */
    1113     init_regs(&sregs);
     1141    init_regs(sregs);
    11141142    ms->reset ();
    11151143#ifdef ERRINJ
    11161144    errinjstart();
    void 
    11211149sys_reset()
    11221150{
    11231151    reset_all();
    1124     sregs.trap = 256;           /* Force fake reset trap */
     1152    sregs[0].trap = 256;                /* Force fake reset trap */
    11251153}
    11261154
    11271155void
    11281156sys_halt()
    11291157{
    1130     sregs.trap = 257;           /* Force fake halt trap */
     1158    sregs[0].trap = 257;           /* Force fake halt trap */
     1159}
     1160
     1161/* simulate uni-processor system */
     1162
     1163static int
     1164run_sim_un(icount, dis)
     1165    uint64          icount;
     1166    int             dis;
     1167{
     1168    int             irq, mexc, deb;
     1169
     1170    if (sregs->err_mode) icount = 0;
     1171    deb = dis || ebase.histlen || ebase.bptnum;
     1172    irq = 0;
     1173    while (icount > 0) {
     1174        if (sregs->pwd_mode) {
     1175            sregs->simtime = ebase.evtime; /* skip forward to next event */
     1176            if (ext_irl[0]) irq = check_interrupts(sregs);
     1177        } else {
     1178            sregs->icnt = 1;
     1179            sregs->fhold = 0;
     1180            if (ext_irl[0]) irq = check_interrupts(sregs);
     1181            if (!irq) {
     1182                mexc = ms->memory_iread (sregs->pc, &sregs->inst, &sregs->hold);
     1183                if (mexc) {
     1184                    sregs->trap = I_ACC_EXC;
     1185                } else {
     1186                    if (deb) {
     1187                        if (ebase.histlen) {
     1188                            sregs->histbuf[sregs->histind].addr = sregs->pc;
     1189                            sregs->histbuf[sregs->histind].time = ebase.simtime;
     1190                            sregs->histind++;
     1191                            if (sregs->histind >= ebase.histlen)
     1192                                sregs->histind = 0;
     1193                        }
     1194                        if (dis) {
     1195                            printf(" %8" PRIu64 " ", ebase.simtime);
     1196                            dis_mem(sregs->pc, 1, &dinfo);
     1197                        }
     1198                        if ((ebase.bptnum) && (ebase.bphit = check_bpt(sregs)))
     1199                            icount = 0;
     1200                        else {
     1201                            dispatch_instruction(sregs);
     1202                            icount--;
     1203                        }
     1204                    } else {
     1205                        dispatch_instruction(sregs);
     1206                        icount--;
     1207                    }
     1208                }
     1209            } else
     1210                sregs->trap = irq + 16;
     1211            if (sregs->trap) {
     1212                irq = 0;
     1213                if ((sregs->err_mode = execute_trap(sregs)) == WPT_HIT) {
     1214                    sregs->err_mode = 0;
     1215                    sregs->trap = 0;
     1216                    icount = 0;
     1217                }
     1218                if (sregs->err_mode) {
     1219                    ms->error_mode (sregs->pc);
     1220                    icount = 0;
     1221                }
     1222            }
     1223#ifdef STAT
     1224            sregs->fholdt += sregs->fhold;
     1225            sregs->holdt += sregs->hold;
     1226            sregs->icntt += sregs->icnt;
     1227#endif
     1228            sregs->simtime += sregs->icnt + sregs->hold + sregs->fhold;
     1229        }
     1230        advance_time(sregs->simtime);
     1231        if (ctrl_c) {
     1232            icount = 0;
     1233        }
     1234    }
     1235    if (sregs->err_mode)
     1236        return ERROR;
     1237    if (ebase.bphit)
     1238        return (BPT_HIT);
     1239    if (ebase.wphit)
     1240        return (WPT_HIT);
     1241    if (ctrl_c) {
     1242        return CTRL_C;
     1243    }
     1244    return TIME_OUT;
     1245}
     1246
     1247/* stop simulation after specified time */
     1248
     1249static void
     1250sim_timeout(int32 arg)
     1251{
     1252    ctrl_c = arg;
     1253}
     1254
     1255/* simulate one core in an mp system */
     1256
     1257static int
     1258run_sim_core(sregs, ntime, deb, dis)
     1259    struct pstate  *sregs;
     1260    uint64 ntime;
     1261    int deb;
     1262    int dis;
     1263{
     1264    int mexc, irq;
     1265        irq = 0;
     1266        if (sregs->pwd_mode == 0)
     1267          while (ntime > sregs->simtime) {
     1268            if (ext_irl[sregs->cpu])
     1269                irq = check_interrupts(sregs);
     1270            else
     1271                irq = 0;
     1272            sregs->icnt = 1;
     1273            mexc = ms->memory_iread (sregs->pc, &sregs->inst, &sregs->hold);
     1274            sregs->fhold = 0;
     1275            if (!irq) {
     1276                if (mexc) {
     1277                    sregs->trap = I_ACC_EXC;
     1278                } else {
     1279                    if (deb) {
     1280                        if (ebase.histlen) {
     1281                            sregs->histbuf[sregs->histind].addr = sregs->pc;
     1282                            sregs->histbuf[sregs->histind].time = sregs->simtime;
     1283                            sregs->histind++;
     1284                            if (sregs->histind >= ebase.histlen)
     1285                                sregs->histind = 0;
     1286                        }
     1287                        if (dis) {
     1288                            printf("cpu %d  %8" PRIu64 " ", sregs->cpu, sregs->simtime);
     1289                            dis_mem(sregs->pc, 1, &dinfo);
     1290                        }
     1291                        if ((ebase.bptnum) && (ebase.bphit = check_bpt(sregs))) {
     1292                            ntime = sregs->simtime;
     1293                        } else {
     1294                            dispatch_instruction(sregs);
     1295                        }
     1296                    } else {
     1297                        dispatch_instruction(sregs);
     1298                    }
     1299                }
     1300            } else
     1301                sregs->trap = irq + 16;
     1302            if (sregs->trap) {
     1303                irq = 0;
     1304                if ((sregs->err_mode = execute_trap(sregs)) == WPT_HIT) {
     1305                    sregs->err_mode = 0;
     1306                    sregs->trap = 0;
     1307                    ntime = sregs->simtime;
     1308                    ctrl_c = 1;
     1309                    break;
     1310                }
     1311                if (sregs->err_mode) {
     1312                    ms->error_mode (sregs->pc);
     1313                    sregs->pwd_mode = 1;
     1314                    sregs->pwdstart = sregs->simtime;
     1315                    sregs->simtime = ntime;
     1316                    ctrl_c = 1;
     1317                    break;
     1318                }
     1319            }
     1320#ifdef STAT
     1321            sregs->fholdt += sregs->fhold;
     1322            sregs->holdt += sregs->hold;
     1323            sregs->icntt += sregs->icnt;
     1324#endif
     1325            sregs->simtime += sregs->icnt + sregs->hold + sregs->fhold;
     1326          }
     1327        else
     1328            sregs->simtime = ntime;
     1329            if (ext_irl[sregs->cpu]) irq = check_interrupts(sregs);
     1330}
     1331
     1332/* time slice simulation of cpu cores in MP system */
     1333
     1334static int
     1335run_sim_mp(icount, dis)
     1336    uint64          icount;
     1337    int             dis;
     1338{
     1339    uint64          ntime;
     1340    int             deb, i;
     1341    int             err_mode, bphit, wphit;
     1342
     1343    err_mode = bphit = wphit = 0;
     1344    icount += ebase.simtime;
     1345    for(i=0; i<ncpu; i++) {
     1346      if (sregs[i].err_mode) {
     1347          icount = 0;
     1348          err_mode = 1;
     1349      }
     1350    }
     1351    while (icount > ebase.simtime) {
     1352      ntime = ebase.simtime + delta;
     1353      if (ntime > icount) ntime = icount;
     1354      for(i=0; i<ncpu; i++) {
     1355        deb = dis || ebase.histlen || ebase.bptnum;
     1356        run_sim_core(&sregs[i], ntime, deb, dis);
     1357        err_mode |= sregs[i].err_mode;
     1358        bphit |= ebase.bphit;
     1359        wphit |= ebase.wphit;
     1360      }
     1361      advance_time(ntime);
     1362      if (ctrl_c) {
     1363          icount = 0;
     1364      }
     1365    }
     1366    /* align time of all cores to allow single stepping */
     1367    for(i=0; i<ncpu; i++) {
     1368        sregs[i].simtime = ebase.simtime;
     1369    }
     1370    if (err_mode)
     1371        return ERROR;
     1372    if (bphit)
     1373        return (BPT_HIT);
     1374    if (wphit)
     1375        return (WPT_HIT);
     1376    if (ctrl_c) {
     1377        return CTRL_C;
     1378    }
     1379    return TIME_OUT;
     1380}
     1381
     1382int
     1383run_sim(icount, dis)
     1384    uint64          icount;
     1385    int             dis;
     1386{
     1387    int res;
     1388
     1389    ctrl_c = 0;
     1390    ebase.starttime = get_time();
     1391    ms->init_stdio ();
     1392    if (ebase.tlimit > ebase.simtime)
     1393        event(sim_timeout, 2, ebase.tlimit - ebase.simtime);
     1394    if (ncpu > 1)
     1395        res = run_sim_mp(icount, dis);
     1396    else
     1397        res = run_sim_un(icount, dis);
     1398    remove_event(sim_timeout);
     1399    ebase.tottime += get_time() - ebase.starttime;
     1400    ms->restore_stdio ();
     1401    if ((res == CTRL_C) && (ctrl_c == 2))
     1402        printf("\nTime-out limit reached\n");   
     1403    return res;
    11311404}
    11321405
    11331406#include "ansidecl.h"
  • sim/erc32/help.c

    diff --git a/sim/erc32/help.c b/sim/erc32/help.c
    index 1e1339e1c7..60496cdb23 100644
    a b  
    2121#include "sis.h"
    2222
    2323void
    24 usage()
     24sis_usage()
    2525{
    2626
    2727    printf("usage: sis [-uart1 uart_device1] [-uart2 uart_device2]\n");
  • sim/erc32/interf.c

    diff --git a/sim/erc32/interf.c b/sim/erc32/interf.c
    index da0e7c3e66..0a756f6e35 100644
    a b  
    3535#include "gdb/common/break-common.h"
    3636
    3737#define PSR_CWP 0x7
     38#define VAL(x)  strtol(x,(char **)NULL,0)
    3839
    39 int
    40 run_sim(sregs, icount, dis)
    41     struct pstate  *sregs;
     40static int
     41run_sim_gdb(icount, dis)
    4242    uint64          icount;
    4343    int             dis;
    4444{
    45     int             mexc, irq;
     45    int             res;
    4646
    4747    if (sis_verbose)
    4848        (*sim_callback->printf_filtered) (sim_callback, "resuming at %x\n",
    4949                                          sregs->pc);
    50    ms->init_stdio ();
    51    sregs->starttime = get_time();
    52    irq = 0;
    53    if (sregs->err_mode) icount = 0;
    54    if ((sregs->pc != 0) && (ebase.simtime == 0))
     50    if ((sregs->pc != 0) && (ebase.simtime == 0))
    5551        ms->boot_init ();
    56    while (icount > 0) {
    57         sregs->fhold = 0;
    58         sregs->icnt = 1;
    59         mexc = ms->memory_iread (sregs->pc, &sregs->inst, &sregs->hold);
    60         if (sregs->annul) {
    61             sregs->annul = 0;
    62             sregs->pc = sregs->npc;
    63             sregs->npc = sregs->npc + 4;
    64         } else {
    65             if (ext_irl) irq = check_interrupts(sregs);
    66             if (!irq) {
    67                 if (mexc) {
    68                     sregs->trap = I_ACC_EXC;
    69                 } else {
    70                     dispatch_instruction(sregs);
    71                     icount--;
    72                 }
    73             }
    74             if (sregs->trap) {
    75                 irq = 0;
    76                 if ((sregs->err_mode = execute_trap(sregs)) == WPT_HIT) {
    77                     sregs->err_mode = 0;
    78                     sregs->trap = 0;
    79                     icount = 0;
    80                 }
    81                 if (sregs->err_mode) icount = 0;
    82             }
    83         }
    84         advance_time(sregs);
    85         if (ctrl_c)
    86             icount = 0;
    87     }
    88     ms->sim_halt ();
    89     sregs->tottime += get_time() - sregs->starttime;
    90     ms->restore_stdio ();
     52    res = run_sim(icount, dis);
    9153    clearerr(stdin);
    92     if (sregs->err_mode) {
    93         ms->error_mode (sregs->pc);
    94         return ERROR;
    95     }
    96     if (ctrl_c) {
    97         ctrl_c = 0;
    98         sregs->wphit = sregs->bphit = 0;
    99         return CTRL_C;
    100     }
    101     if ((sregs->bphit) || (sregs->wphit))
    102         return (BPT_HIT);
    103     return TIME_OUT;
     54    return res;
    10455}
    10556
    10657SIM_DESC
    sim_open (kind, callback, abfd, argv) 
    11364
    11465    int             argc = 0;
    11566    int             stat = 1;
    116     int             freq = 0;
    11767
    11868    sim_callback = callback;
    119     sis_gdb_break = 1;
    12069
     70    if (!ebase.freq) ebase.freq = 14;
    12171    sis_gdb_break = 1;
    12272    argc = countargv (argv);
    12373    while (stat < argc) {
    sim_open (kind, callback, abfd, argv) 
    14696            if (strcmp (argv[stat], "-leon2") == 0) {
    14797                ms = &leon2;
    14898                cputype = CPU_LEON2;
     99                ebase.freq = 50;
    149100            } else
    150101            if (strcmp (argv[stat], "-leon3") == 0) {
    151102                ms = &leon3;
    152103                cputype = CPU_LEON3;
     104                ebase.freq = 50;
    153105            } else
    154106            if (strcmp(argv[stat], "-wrp") == 0) {
    155107                wrp = 1;
    sim_open (kind, callback, abfd, argv) 
    173125            } else
    174126            if (strcmp(argv[stat], "-freq") == 0) {
    175127                if ((stat + 1) < argc) {
    176                     freq = strtol(argv[++stat], (char **)NULL, 0);
     128                    ebase.freq = strtol(argv[++stat], (char **)NULL, 0);
    177129                }
     130            } else if (strcmp(argv[stat], "-m") == 0) {
     131                if ((stat + 1) < argc)
     132                    ncpu = VAL(argv[++stat]);
     133                    if ((ncpu < 1) || (ncpu > NCPU)) ncpu = 1;
     134            } else if (strcmp(argv[stat], "-d") == 0) {
     135                if ((stat + 1) < argc)
     136                    delta = VAL(argv[++stat]);
     137                    if (delta <= 0) delta = 25;
    178138            } else
    179139            if (strncmp(argv[stat], "--sysroot=", sizeof("--sysroot=") - 1) == 0) {
    180140                /* Ignore until we start to support this.  */
    sim_open (kind, callback, abfd, argv) 
    188148        stat++;
    189149    }
    190150
    191     if ((cputype == CPU_LEON3) || (cputype == CPU_LEON2))
    192         sregs.freq = freq ? freq : 50;
    193     else
    194         sregs.freq = freq ? freq : 14;
    195 
    196151    if (sis_verbose) {
    197152        (*sim_callback->printf_filtered) (sim_callback, "\n SIS - SPARC instruction simulator %s\n", sis_version);
    198153        (*sim_callback->printf_filtered) (sim_callback, " Bug-reports to Jiri Gaisler (jiri@gaisler.se)\n\n");
    sim_open (kind, callback, abfd, argv) 
    201156            (*sim_callback->printf_filtered) (sim_callback, "LEON2 emulation enabled\n");
    202157            break;
    203158        case CPU_LEON3:
    204             (*sim_callback->printf_filtered) (sim_callback, "LEON3 emulation enabled\n");
     159            (*sim_callback->printf_filtered) (sim_callback, "LEON3 emulation enabled, %d core(s)\n", ncpu);
    205160            break;
    206161        default:
    207162            (*sim_callback->printf_filtered) (sim_callback, "ERC32 emulation enabled\n");
    sim_open (kind, callback, abfd, argv) 
    214169          (*sim_callback->printf_filtered) (sim_callback, "dumb IO (no input, dumb output)\n");
    215170        if (sis_gdb_break == 0)
    216171          (*sim_callback->printf_filtered) (sim_callback, "disabling GDB trap handling for breakpoints\n");
    217           (*sim_callback->printf_filtered) (sim_callback, "CPU freq %3.1f MHz\n", sregs.freq);
     172          (*sim_callback->printf_filtered) (sim_callback, "CPU freq %3.1f MHz\n", ebase.freq);
    218173    }
    219174
    220175#ifdef F_GETFL
    sim_open (kind, callback, abfd, argv) 
    228183#endif
    229184    reset_all();
    230185    ebase.simtime = 0;
     186    ebase.simstart = 0;
    231187    ms->init_sim ();
    232     init_bpt(&sregs);
    233     reset_stat(&sregs);
     188    init_bpt(sregs);
     189    reset_stat(sregs);
    234190
    235191    /* Fudge our descriptor for now.  */
    236192    return (SIM_DESC) 1;
    sim_create_inferior(sd, abfd, argv, env) 
    267223     char * const *argv;
    268224     char * const *env;
    269225{
     226    int i;
     227
    270228    bfd_vma start_address = 0;
    271229    if (abfd != NULL)
    272230      start_address = bfd_get_start_address (abfd);
    273231
    274232    ebase.simtime = 0;
     233    ebase.simstart = 0;
    275234    reset_all();
    276     reset_stat(&sregs);
    277     sregs.pc = start_address & ~3;
    278     sregs.npc = sregs.pc + 4;
     235    reset_stat(sregs);
     236    for (i=0; i<ncpu; i++){
     237        sregs[i].pc = start_address & ~3;
     238        sregs[i].npc = sregs[cpu].pc + 4;
     239    }
    279240    return SIM_RC_OK;
    280241}
    281242
    sim_store_register(sd, regno, value, length) 
    290251
    291252    regval = (value[0] << 24) | (value[1] << 16)
    292253                 | (value[2] << 8) | value[3];
    293     set_regi(&sregs, regno, regval);
     254    set_regi(sregs, regno, regval);
    294255    return length;
    295256}
    296257
    sim_fetch_register(sd, regno, buf, length) 
    302263    unsigned char  *buf;
    303264     int length;
    304265{
    305     get_regi(&sregs, regno, buf);
     266    get_regi(sregs, regno, buf);
    306267    return -1;
    307268}
    308269
    sim_info(sd, verbose) 
    333294     SIM_DESC sd;
    334295     int verbose;
    335296{
    336     show_stat(&sregs);
     297    show_stat(sregs);
    337298}
    338299
    339300int             simstat = OK;
    sim_stop_reason(sd, reason, sigrc) 
    356317        *sigrc = 0;
    357318        break;
    358319    case BPT_HIT:
     320    case WPT_HIT:
    359321        *reason = sim_stopped;
    360322        *sigrc = GDB_SIGNAL_TRAP;
    361323        break;
    sim_stop_reason(sd, reason, sigrc) 
    381343*/
    382344
    383345static void
    384 flush_windows ()
     346flush_windows (struct pstate *sregs)
    385347{
    386348  int invwin;
    387349  int cwp;
    flush_windows () 
    390352
    391353  /* Keep current window handy */
    392354
    393   cwp = sregs.psr & PSR_CWP;
     355  cwp = sregs->psr & PSR_CWP;
    394356
    395357  /* Calculate the invalid window from the wim. */
    396358
    397359  for (invwin = 0; invwin <= PSR_CWP; invwin++)
    398     if ((sregs.wim >> invwin) & 1)
     360    if ((sregs->wim >> invwin) & 1)
    399361      break;
    400362
    401363  /* Start saving with the window after the invalid window. */
    flush_windows () 
    407369      uint32 sp;
    408370      int i;
    409371
    410       sp = sregs.r[(win * 16 + 14) & 0x7f];
     372      sp = sregs->r[(win * 16 + 14) & 0x7f];
    411373#if 1
    412374      if (sis_verbose > 2) {
    413         uint32 fp = sregs.r[(win * 16 + 30) & 0x7f];
     375        uint32 fp = sregs->r[(win * 16 + 30) & 0x7f];
    414376        printf("flush_window: win %d, sp %x, fp %x\n", win, sp, fp);
    415377      }
    416378#endif
    417379
    418380      for (i = 0; i < 16; i++)
    419         ms->memory_write (sp + 4 * i, &sregs.r[(win * 16 + 16 + i) & 0x7f], 2,
     381        ms->memory_write (sp + 4 * i, &sregs->r[(win * 16 + 16 + i) & 0x7f], 2,
    420382                      &ws);
    421383
    422384      if (win == cwp)
    sim_resume(SIM_DESC sd, int step, int siggnal) 
    429391{
    430392    if (sis_verbose)
    431393        (*sim_callback->printf_filtered) (sim_callback,
    432             "sim_resume %x : %x : %x : %x : 0x%08x\n", step, siggnal, sregs.bphit, sregs.wphit, sregs.pc);
     394            "sim_resume_start %x : %x : %x : %x : 0x%08x\n", step, siggnal, ebase.bphit, ebase.wphit, sregs[cpu].pc);
    433395    if (step) {
    434         sregs.bphit = 0;
    435         sregs.wphit = 1;
    436         simstat = run_sim(&sregs, 1, 0);
    437         sregs.bphit = 0;
    438         sregs.wphit = 0;
    439     } else if (sregs.bphit || sregs.wphit) {
    440         sregs.bphit = 0;
    441         sregs.wphit = 1;
    442         simstat = run_sim(&sregs, 1, 0);
    443         sregs.bphit = sregs.wphit = 0;
    444         simstat = run_sim(&sregs, UINT64_MAX, 0);
    445         sregs.bphit = 0;
     396        ebase.bphit = 0;
     397        ebase.wphit = 1;
     398        simstat = run_sim_gdb(1, 0);
     399        ebase.bphit = 0;
     400        ebase.wphit = 0;
     401    } else if (ebase.bphit || ebase.wphit) {
     402        ebase.bphit = 0;
     403        ebase.wphit = 1;
     404        simstat = run_sim_gdb(1, 0);
     405        ebase.bphit = ebase.wphit = 0;
     406        simstat = run_sim_gdb(UINT64_MAX/2, 0);
     407        ebase.bphit = 0;
    446408    }
    447409    else
    448         simstat = run_sim(&sregs, UINT64_MAX, 0);
     410        simstat = run_sim_gdb(UINT64_MAX/2, 0);
    449411
    450     if (sis_gdb_break) flush_windows ();
     412    if (sis_verbose)
     413        (*sim_callback->printf_filtered) (sim_callback,
     414            "sim_resume_end %x : %x : %x : %x : %x : 0x%08x\n", step, siggnal, ebase.bphit, ebase.wphit, simstat, sregs[cpu].pc);
     415    if (sis_gdb_break) flush_windows (sregs);
    451416}
    452417
    453418void
    sim_do_command(sd, cmd) 
    455420     SIM_DESC sd;
    456421     const char *cmd;
    457422{
    458     exec_cmd(&sregs, cmd);
     423    exec_cmd(cmd);
    459424}
    460425
    461426char **
    sim_stop (SIM_DESC sd) 
    474439static int
    475440sis_insert_watchpoint_read(int addr, unsigned char mask)
    476441{
    477     if (sregs.wprnum < WPR_MAX) {
    478         sregs.wprs[sregs.wprnum] = addr;
    479         sregs.wprm[sregs.wprnum] = mask;
    480         sregs.wprnum++;
     442    if (ebase.wprnum < WPR_MAX) {
     443        ebase.wprs[ebase.wprnum] = addr;
     444        ebase.wprm[ebase.wprnum] = mask;
     445        ebase.wprnum++;
    481446        if (sis_verbose)
    482447            (*sim_callback->printf_filtered) (sim_callback, "inserted read watchpoint at %x\n", addr);
    483448        return SIM_RC_OK;
    sis_remove_watchpoint_read(int addr) 
    490455{
    491456    int             i = 0;
    492457
    493     while ((i < sregs.wprnum) && (sregs.wprs[i] != addr))
     458    while ((i < ebase.wprnum) && (ebase.wprs[i] != addr))
    494459        i++;
    495     if (addr == sregs.wprs[i]) {
    496         for (; i < sregs.wprnum - 1; i++)
    497             sregs.wprs[i] = sregs.wprs[i + 1];
    498         sregs.wprnum -= 1;
     460    if (addr == ebase.wprs[i]) {
     461        for (; i < ebase.wprnum - 1; i++)
     462            ebase.wprs[i] = ebase.wprs[i + 1];
     463        ebase.wprnum -= 1;
    499464        if (sis_verbose)
    500465            (*sim_callback->printf_filtered) (sim_callback, "removed read watchpoint at %x\n", addr);
    501466        return 0;
    sis_remove_watchpoint_read(int addr) 
    506471static int
    507472sis_insert_watchpoint_write(int32 addr, unsigned char mask)
    508473{
    509     if (sregs.wpwnum < WPR_MAX) {
    510         sregs.wpws[sregs.wpwnum] = addr;
    511         sregs.wpwm[sregs.wpwnum] = mask;
    512         sregs.wpwnum++;
     474    if (ebase.wpwnum < WPR_MAX) {
     475        ebase.wpws[ebase.wpwnum] = addr;
     476        ebase.wpwm[ebase.wpwnum] = mask;
     477        ebase.wpwnum++;
    513478        if (sis_verbose)
    514479            (*sim_callback->printf_filtered) (sim_callback, "sim_insert_watchpoint_write: 0x%08x : %x\n", addr, mask);
    515480        return SIM_RC_OK;
    sis_remove_watchpoint_write(int addr) 
    522487{
    523488    int             i = 0;
    524489
    525     while ((i < sregs.wpwnum) && (sregs.wpws[i] != addr))
     490    while ((i < ebase.wpwnum) && (ebase.wpws[i] != addr))
    526491        i++;
    527     if (addr == sregs.wpws[i]) {
    528         for (; i < sregs.wpwnum - 1; i++)
    529             sregs.wpws[i] = sregs.wpws[i + 1];
    530         sregs.wpwnum -= 1;
     492    if (addr == ebase.wpws[i]) {
     493        for (; i < ebase.wpwnum - 1; i++)
     494            ebase.wpws[i] = ebase.wpws[i + 1];
     495        ebase.wpwnum -= 1;
    531496        if (sis_verbose)
    532497            (*sim_callback->printf_filtered) (sim_callback, "removed write watchpoint at %x\n", addr);
    533498        return SIM_RC_OK;
    int sim_clear_watchpoint (SIM_DESC sd, SIM_ADDR mem, int length, int type) 
    601566int sim_stopped_by_watchpoint (SIM_DESC sd)
    602567{
    603568    if (sis_verbose)
    604        (*sim_callback->printf_filtered) (sim_callback, "sim_stopped_by_watchpoint %x\n", sregs.wphit);
    605     return((sregs.wphit != 0));
     569       (*sim_callback->printf_filtered) (sim_callback, "sim_stopped_by_watchpoint %x\n", ebase.wphit);
     570    return((ebase.wphit != 0));
    606571}
    607572
    608573int sim_watchpoint_address (SIM_DESC sd)
    609574{
    610     return(sregs.wpaddress);
     575    if (sis_verbose)
     576       (*sim_callback->printf_filtered) (sim_callback, "sim__watchpoint_address %x\n", ebase.wpaddress);
     577    return(ebase.wpaddress);
    611578}
    612579
    613580#if 0 /* FIXME: These shouldn't exist.  */
  • sim/erc32/leon2.c

    diff --git a/sim/erc32/leon2.c b/sim/erc32/leon2.c
    index 09402f7fff..90cae3bd5d 100644
    a b reset (void) 
    191191  leon2_reset ();
    192192  uart_irq_start ();
    193193  gpt_reset ();
     194  sregs[0].intack = irqctrl_intack;
     195
    194196}
    195197
    196198/* IU error mode manager. */
    chk_irq (void) 
    277279  uint32 itmp;
    278280  int old_irl;
    279281
    280   old_irl = ext_irl;
     282  old_irl = ext_irl[0];
    281283  itmp = ((irqctrl_ipr | irqctrl_ifr) & irqctrl_imr) & 0x0fffe;
    282   ext_irl = 0;
     284  ext_irl[0] = 0;
    283285  if (itmp != 0)
    284286    {
    285287      for (i = 15; i > 0; i--)
    chk_irq (void) 
    288290            {
    289291              if ((sis_verbose > 2) && (i > old_irl))
    290292                printf ("IU irl: %d\n", i);
    291               ext_irl = i;
    292               set_int (i, irqctrl_intack, i);
     293              ext_irl[0] = i;
    293294              break;
    294295            }
    295296        }
    apb_write (uint32 addr, uint32 data) 
    435436      break;
    436437
    437438    case POWER_DOWN:            /* 0x328 */
    438       wait_for_irq ();
     439      pwd_enter(sregs);
    439440      break;
    440441
    441442    case CACHE_CTRL:            /* 0x328 */
    memory_read (uint32 addr, uint32 * data, int32 sz, int32 * ws) 
    908909  return 1;
    909910}
    910911
    911 static int
    912 memory_read_asi (int32 asi, uint32 addr, uint32 * data, int32 sz, int32 * ws)
    913 {
    914   return memory_read (addr, data, sz, ws);
    915 }
    916 
    917912static int
    918913memory_write (uint32 addr, uint32 * data, int32 sz, int32 * ws)
    919914{
    memory_write (uint32 addr, uint32 * data, int32 sz, int32 * ws) 
    953948  return 1;
    954949}
    955950
    956 static int
    957 memory_write_asi (int32 asi, uint32 addr, uint32 * data, int32 sz, int32 * ws)
    958 {
    959   return memory_write (addr, data, sz, ws);
    960 }
    961 
    962951static unsigned char *
    963952get_mem_ptr (uint32 addr, uint32 size)
    964953{
    static void 
    10111000boot_init (void)
    10121001{
    10131002  /* Generate 1 MHz RTC tick.  */
    1014   apb_write (TIMER_SCALER, sregs.freq - 1);
    1015   apb_write (TIMER_SCLOAD, sregs.freq - 1);
     1003  apb_write (TIMER_SCALER, ebase.freq - 1);
     1004  apb_write (TIMER_SCLOAD, ebase.freq - 1);
    10161005  apb_write (TIMER_TIMER1, -1);
    10171006  apb_write (TIMER_RELOAD1, -1);
    10181007  apb_write (TIMER_CTRL1, 0x7);
    10191008
    1020   sregs.wim = 2;
    1021   sregs.psr = 0x000010e0;
    1022   sregs.r[30] = RAM_END;
    1023   sregs.r[14] = sregs.r[30] - 96 * 4;
     1009  sregs->wim = 2;
     1010  sregs->psr = 0x000010e0;
     1011  sregs->r[30] = RAM_END;
     1012  sregs->r[14] = sregs->r[30] - 96 * 4;
    10241013  cache_ctrl = 0x01000f;
    10251014}
    10261015
    const struct memsys leon2 = { 
    10341023  restore_stdio,
    10351024  memory_iread,
    10361025  memory_read,
    1037   memory_read_asi,
    10381026  memory_write,
    1039   memory_write_asi,
    10401027  sis_memory_write,
    10411028  sis_memory_read,
    10421029  boot_init
  • sim/erc32/leon3.c

    diff --git a/sim/erc32/leon3.c b/sim/erc32/leon3.c
    index 05234115f3..9f8fba222f 100644
    a b  
    2727#include <sys/types.h>
    2828#include <stdio.h>
    2929#include <string.h>
     30#include <inttypes.h>
    3031#ifdef HAVE_TERMIOS_H
    3132#include <termios.h>
    3233#endif
     
    4748
    4849/* LEON3 APB register addresses.  */
    4950
    50 #define IRQMP_IPR               0x204
    51 #define IRQMP_IMR       0x240
    52 #define IRQMP_ICR       0x20C
     51#define IRQMP_IPR       0x204
    5352#define IRQMP_IFR       0x208
     53#define IRQMP_ICR       0x20C
     54#define IRQMP_ISR       0x210
     55#define IRQMP_IBR       0x214
     56#define IRQMP_IMR       0x240
     57#define IRQMP_IMR1      0x244
     58#define IRQMP_IMR2      0x248
     59#define IRQMP_IMR3      0x24C
     60#define IRQMP_IFR0      0x280
     61#define IRQMP_IFR1      0x284
     62#define IRQMP_IFR2      0x288
     63#define IRQMP_IFR3      0x28C
    5464#define GPTIMER_SCALER  0x300
    5565#define GPTIMER_SCLOAD  0x304
    5666#define GPTIMER_CONFIG  0x308
     
    6373
    6474#define APBUART_RXTX    0x100
    6575#define APBUART_STATUS  0x104
     76#define APBUART_CTRL    0x108
    6677
    6778/* Size of UART buffers (bytes).  */
    6879#define UARTBUF 1024
     
    8293/* IRQMP registers.  */
    8394
    8495static uint32 irqmp_ipr;
    85 static uint32 irqmp_imr;
    86 static uint32 irqmp_ifr;
     96static uint32 irqmp_ibr;
     97static uint32 irqmp_imr[NCPU];
     98static uint32 irqmp_ifr[NCPU];
    8799
    88100/* GPTIMER registers.  */
    89101
    static uint32 gpt_ctrl[NGPTIMERS]; 
    109121/* Memory.  */
    110122static unsigned char romb[ROM_END - ROM_START];
    111123static unsigned char ramb[RAM_END - RAM_START];
    112 static uint32 cache_ctrl;
    113 
    114124
    115125/* UART support variables.  */
    116126
    static int f1open = 0; 
    139149static char uarta_sreg, uarta_hreg;
    140150static uint32 uart_stat_reg;
    141151static uint32 uarta_data;
     152static uint xcpu;
    142153
    143154/* Forward declarations. */
    144155
    145156static void mem_init (void);
    146157static void close_port (void);
    147158static void leon3_reset (void);
    148 static void irqmp_intack (int32 level);
     159static void irqmp_intack (int level, int cpu);
    149160static void chk_irq (void);
    150161static void set_irq (int32 level);
    151162static int32 apb_read (uint32 addr, uint32 * data);
    leon3_reset (void) 
    246257  int i;
    247258
    248259  irqmp_ipr = 0;
    249   irqmp_imr = 0;
    250   irqmp_ifr = 0;
    251 
     260  for (i=0; i<NCPU; i++) {
     261    irqmp_imr[i] = 0;
     262    irqmp_ifr[i] = 0;
     263    sregs[i].intack = irqmp_intack;
     264  }
    252265  wnuma = wnumb = 0;
    253266  anum = aind = bnum = bind = 0;
    254267
    leon3_reset (void) 
    263276}
    264277
    265278static void
    266 irqmp_intack (int32 level)
     279irqmp_intack (int level, int cpu)
    267280{
    268281  int irq_test;
    269282
    270   if (sis_verbose > 2)
    271     printf ("interrupt %d acknowledged\n", level);
    272   if (irqmp_ifr & (1 << level))
    273     irqmp_ifr &= ~(1 << level);
     283  if ((sis_verbose > 2) && (level != 10))
     284          printf ("%8" PRIu64 " cpu %d interrupt %d acknowledged\n",
     285                          ebase.simtime, cpu, level);
     286  if (irqmp_ifr[cpu] & (1 << level))
     287    irqmp_ifr[cpu] &= ~(1 << level);
    274288  else
    275289    irqmp_ipr &= ~(1 << level);
    276290  chk_irq ();
    277291}
    278292
    279293static void
    280 chk_irq (void)
     294chk_irq ()
    281295{
    282   int32 i;
     296  int32 i, cpu;
    283297  uint32 itmp;
    284298  int old_irl;
    285299
    286   old_irl = ext_irl;
    287   itmp = ((irqmp_ipr | irqmp_ifr) & irqmp_imr) & 0x0fffe;
    288   ext_irl = 0;
    289   if (itmp != 0)
     300  for (cpu = 0; cpu<ncpu; cpu++) {
     301    old_irl = ext_irl[cpu];
     302    itmp = ((irqmp_ipr | irqmp_ifr[cpu]) & irqmp_imr[cpu]) & 0x0fffe;
     303    ext_irl[cpu] = 0;
     304    if (itmp != 0)
    290305    {
    291306      for (i = 15; i > 0; i--)
    292307        {
    293308          if (((itmp >> i) & 1) != 0)
    294309            {
    295               if ((sis_verbose > 2) && (i > old_irl))
    296                 printf ("IU irl: %d\n", i);
    297               ext_irl = i;
    298               set_int (i, irqmp_intack, i);
     310              if ((sis_verbose > 2) && (i != old_irl))
     311                printf ("%8" PRIu64 " cpu %d irl: %d\n",
     312                                ebase.simtime, cpu, i);
     313              ext_irl[cpu] = i;
    299314              break;
    300315            }
    301316        }
    302317    }
     318  }
    303319}
    304320
    305321static void
    306322set_irq (int32 level)
    307323{
    308   irqmp_ipr |= (1 << level);
     324  int i;
     325
     326  if ((irqmp_ibr >> level) & 1)
     327    for (i=0; i<ncpu; i++)
     328      irqmp_ifr[i] |= (1 << level);
     329  else
     330    irqmp_ipr |= (1 << level);
    309331  chk_irq ();
    310332}
    311333
    312334static int32
    313335apb_read (uint32 addr, uint32 * data)
    314336{
     337  int i;
    315338
    316339  switch (addr & 0xfff)
    317340    {
    apb_read (uint32 addr, uint32 * data) 
    320343    case APBUART_STATUS:        /* 0x104 */
    321344      *data = grlib_read_uart (addr);
    322345      break;
     346    case APBUART_CTRL:          /* 0x108 */
     347      *data = 3;
     348      break;
    323349
    324350    case IRQMP_IPR:             /* 0x204 */
    325351      *data = irqmp_ipr;
    326352      break;
    327353
    328354    case IRQMP_IFR:             /* 0x208 */
    329       *data = irqmp_ifr;
     355      *data = irqmp_ifr[0];
     356      break;
     357
     358    case IRQMP_ISR:             /* 0x210 */
     359      *data = ((ncpu - 1) << 28);
     360      for (i=0;i<ncpu;i++)
     361          *data |= (sregs[i].pwd_mode << i);
     362      break;
     363
     364    case IRQMP_IBR:             /* 0x214 */
     365      *data = irqmp_ibr;
    330366      break;
    331367
    332368    case IRQMP_IMR:             /* 0x240 */
    333       *data = irqmp_imr;
     369      *data = irqmp_imr[0];
     370      break;
     371
     372    case IRQMP_IMR1:            /* 0x244 */
     373      *data = irqmp_imr[1];
     374      break;
     375
     376    case IRQMP_IMR2:            /* 0x248 */
     377      *data = irqmp_imr[2];
     378      break;
     379
     380    case IRQMP_IMR3:            /* 0x24C */
     381      *data = irqmp_imr[3];
     382      break;
     383
     384    case IRQMP_IFR0:            /* 0x280 */
     385      *data = irqmp_ifr[0];
     386      break;
     387
     388    case IRQMP_IFR1:            /* 0x284 */
     389      *data = irqmp_ifr[1];
     390      break;
     391
     392    case IRQMP_IFR2:            /* 0x288 */
     393      *data = irqmp_ifr[2];
     394      break;
     395
     396    case IRQMP_IFR3:            /* 0x28C */
     397      *data = irqmp_ifr[3];
    334398      break;
    335399
    336400    case GPTIMER_SCALER:        /* 0x300 */
    apb_read (uint32 addr, uint32 * data) 
    371435
    372436    default:
    373437      *data = 0;
     438      if (sis_verbose > 1)
     439          printf ("%8" PRIu64 " cpu %d APB read  a: %08x, d: %08x  unimplemented!\n",
     440                          ebase.simtime, xcpu, addr, *data);
    374441      break;
    375442    }
    376443
    377444  if (sis_verbose > 1)
    378     printf ("APB read  a: %08x, d: %08x\n", addr, *data);
     445      if ((addr & 0xF00) != 0x100)
     446          printf ("%8" PRIu64 " cpu %d APB read  a: %08x, d: %08x\n",
     447                          ebase.simtime, xcpu, addr, *data);
    379448
    380449  return MOK;
    381450}
    apb_read (uint32 addr, uint32 * data) 
    383452static int
    384453apb_write (uint32 addr, uint32 data)
    385454{
     455  int i;
     456
    386457  if (sis_verbose > 1)
    387     printf ("APB write a: %08x, d: %08x\n", addr, data);
     458      if ((addr & 0xF00) != 0x100)
     459          printf ("%8" PRIu64 " cpu %d APB write a: %08x, d: %08x\n",
     460                          ebase.simtime, xcpu, addr, data);
    388461  switch (addr & 0xfff)
    389462    {
    390463
    apb_write (uint32 addr, uint32 data) 
    392465    case APBUART_STATUS:        /* 0x104 */
    393466      grlib_write_uart (addr, data);
    394467      break;
     468    case APBUART_CTRL:          /* 0x108 */
     469      break;
    395470
    396471    case IRQMP_IFR:             /* 0x208 */
    397       irqmp_ifr = data & 0xfffe;
     472      irqmp_ifr[0] = data & 0xfffe;
    398473      chk_irq ();
    399474      break;
    400475
    apb_write (uint32 addr, uint32 data) 
    403478      chk_irq ();
    404479      break;
    405480
     481    case IRQMP_ISR:             /* 0x210 */
     482      for (i=0;i<ncpu;i++) {
     483          if ((data >> i) & 1) {
     484              if (sregs[i].pwd_mode) {
     485                  sregs[i].simtime = ebase.simtime;
     486                  if (sis_verbose > 1)
     487                      printf ("%8" PRIu64 " cpu %d starting\n", ebase.simtime, i);
     488                  sregs[i].pwdtime += ebase.simtime - sregs[i].pwdstart;
     489              }
     490              sregs[i].pwd_mode = 0;
     491          }
     492      }
     493      break;
     494
     495    case IRQMP_IBR:             /* 0x214 */
     496      irqmp_ibr = data & 0xfffe;
     497      break;
     498
    406499    case IRQMP_IMR:             /* 0x240 */
    407       irqmp_imr = data & 0x7ffe;
     500      irqmp_imr[0] = data & 0x7ffe;
     501      chk_irq ();
     502      break;
     503
     504    case IRQMP_IMR1:            /* 0x244 */
     505      irqmp_imr[1] = data & 0x7ffe;
     506      chk_irq ();
     507      break;
     508
     509    case IRQMP_IMR2:            /* 0x248 */
     510      irqmp_imr[2] = data & 0x7ffe;
     511      chk_irq ();
     512      break;
     513
     514    case IRQMP_IMR3:            /* 0x24C */
     515      irqmp_imr[3] = data & 0x7ffe;
     516      chk_irq ();
     517      break;
     518
     519    case IRQMP_IFR0:            /* 0x280 */
     520      irqmp_ifr[0] = data & 0xfffe;
     521      chk_irq ();
     522      break;
     523
     524    case IRQMP_IFR1:            /* 0x284 */
     525      irqmp_ifr[1] = data & 0xfffe;
     526      chk_irq ();
     527      break;
     528
     529    case IRQMP_IFR2:            /* 0x288 */
     530      irqmp_ifr[2] = data & 0xfffe;
     531      chk_irq ();
     532      break;
     533
     534    case IRQMP_IFR3:            /* 0x28C */
     535      irqmp_ifr[3] = data & 0xfffe;
    408536      chk_irq ();
    409537      break;
    410538
    apb_write (uint32 addr, uint32 data) 
    437565      break;
    438566
    439567    default:
     568      if (sis_verbose)
     569          printf ("%8" PRIu64 " cpu %d APB write a: %08x, d: %08x  unimplemented!\n",
     570                          ebase.simtime, xcpu, addr, data);
    440571      break;
    441572    }
    442573  return MOK;
    static void 
    828959store_bytes (unsigned char *mem, uint32 waddr, uint32 * data, int32 sz,
    829960             int32 * ws)
    830961{
    831   switch (sz)
     962  if (sz == 2)
     963      memcpy (&mem[waddr], data, 4);
     964  else
     965    switch (sz)
    832966    {
    833967    case 0:
    834968#ifdef HOST_LITTLE_ENDIAN
    835969      waddr ^= EBT;
    836970#endif
    837971      mem[waddr] = *data & 0x0ff;
    838       *ws = 0;
    839972      break;
    840973    case 1:
    841974#ifdef HOST_LITTLE_ENDIAN
    842975      waddr ^= 2;
    843976#endif
    844977      memcpy (&mem[waddr], data, 2);
    845       *ws = 0;
    846       break;
    847     case 2:
    848       memcpy (&mem[waddr], data, 4);
    849       *ws = 0;
    850978      break;
    851979    case 3:
    852980      memcpy (&mem[waddr], data, 8);
    853       *ws = 0;
    854981      break;
    855982    }
     983    *ws = 0;
    856984}
    857985
    858986
    memory_read (uint32 addr, uint32 * data, int32 sz, int32 * ws) 
    9291057  return 1;
    9301058}
    9311059
    932 static int
    933 memory_read_asi (int32 asi, uint32 addr, uint32 * data, int32 sz, int32 * ws)
    934 {
    935   if (asi == 2)
    936     {
    937       if (addr == 0)
    938         *data = cache_ctrl;
    939       else
    940         *data = 0;
    941       return MOK;
    942     }
    943   else
    944     return memory_read (addr, data, sz, ws);
    945 }
    946 
    9471060static int
    9481061memory_write (uint32 addr, uint32 * data, int32 sz, int32 * ws)
    9491062{
    memory_write (uint32 addr, uint32 * data, int32 sz, int32 * ws) 
    9841097  return 1;
    9851098}
    9861099
    987 static int
    988 memory_write_asi (int32 asi, uint32 addr, uint32 * data, int32 sz, int32 * ws)
    989 {
    990   if (asi == 2)
    991     {
    992       cache_ctrl = *data & 0x81000f;
    993       if (sis_verbose)
    994         printf ("cache ctrl reg : 0x%08x\n", cache_ctrl);
    995       return MOK;
    996     }
    997   else
    998     return (memory_write (addr, data, sz, ws));
    999 }
    1000 
    10011100static unsigned char *
    10021101get_mem_ptr (uint32 addr, uint32 size)
    10031102{
    static int 
    10171116sis_memory_write (uint32 addr, const unsigned char *data, uint32 length)
    10181117{
    10191118  char *mem;
     1119  int32 ws;
    10201120
    1021   if ((mem = get_mem_ptr (addr, length)) == ((char *) -1))
    1022     return 0;
    1023 
    1024   memcpy (mem, data, length);
    1025   return length;
     1121  if ((mem = get_mem_ptr (addr, length)) != ((char *) -1)) {
     1122    memcpy (mem, data, length);
     1123    return length;
     1124  } else if (length == 4)
     1125    memory_write (addr, (uint32 *) data, 2, &ws);
     1126  return 0;
    10261127}
    10271128
    10281129static int
    sis_memory_read (uint32 addr, char *data, uint32 length) 
    10471148static void
    10481149boot_init (void)
    10491150{
     1151
     1152  int i;
     1153
    10501154  /* Generate 1 MHz RTC tick.  */
    1051   apb_write (GPTIMER_SCALER, sregs.freq - 1);
    1052   apb_write (GPTIMER_SCLOAD, sregs.freq - 1);
     1155//  apb_write (GPTIMER_SCALER, ebase.freq - 1);
     1156  apb_write (GPTIMER_SCLOAD, ebase.freq - 1);
    10531157  apb_write (GPTIMER_TIMER1, -1);
    10541158  apb_write (GPTIMER_RELOAD1, -1);
    10551159  apb_write (GPTIMER_CTRL1, 0x7);
    10561160
    1057   sregs.wim = 2;
    1058   sregs.psr = 0xF30010e0;
    1059   sregs.r[30] = RAM_END;
    1060   sregs.r[14] = sregs.r[30] - 96 * 4;
    1061   cache_ctrl = 0x81000f;
     1161  for (i=0;i<NCPU;i++) {
     1162    sregs[i].wim = 2;
     1163    sregs[i].psr = 0xF30010e0;
     1164    sregs[i].r[30] = RAM_END - (i * 0x20000);
     1165    sregs[i].r[14] = sregs[i].r[30] - 96 * 4;
     1166    sregs[i].cache_ctrl = 0x81000f;
     1167  }
    10621168}
    10631169
    10641170const struct memsys leon3 = {
    const struct memsys leon3 = { 
    10711177  restore_stdio,
    10721178  memory_iread,
    10731179  memory_read,
    1074   memory_read_asi,
    10751180  memory_write,
    1076   memory_write_asi,
    10771181  sis_memory_write,
    10781182  sis_memory_read,
    10791183  boot_init
  • sim/erc32/run.c

    diff --git a/sim/erc32/run.c b/sim/erc32/run.c
    index 70ae411fc6..a3e3a69519 100644
    a b along with this program. If not, see <http://www.gnu.org/licenses/>. */ 
    4646#include "ansidecl.h"
    4747#include "run-sim.h"
    4848#include "version.h"
     49#include "sis.h"
    4950
    5051static void usage (int help);
    5152static void print_version (void);
    main (ac, av) 
    9495  char **prog_args;
    9596  enum sim_stop reason;
    9697  int sigrc;
     98  char tlim[64] = "";
     99
    97100
    98101  myname = av[0] + strlen (av[0]);
    99102  while (myname > av[0] && myname[-1] != '/')
    main (ac, av) 
    132135  /* FIXME: This is currently being rewritten to have each simulator
    133136     do all argv processing.  */
    134137
    135   while ((i = getopt (ac, av, "a:c:m:op:s:tv")) != EOF)
     138  while ((i = getopt (ac, av, "a:c:m:op:s:t:v:")) != EOF)
    136139    switch (i)
    137140      {
    138141      case 'a':
    main (ac, av) 
    155158        sim_set_simcache_size (atoi (optarg));
    156159        break;
    157160#endif
     161      case 'd':
     162        delta = (atoi (optarg));
     163        break;
    158164      case 'm':
    159165        /* FIXME: Rename to sim_set_mem_size.  */
    160166        //sim_size (atoi (optarg));
     167        ncpu = (atoi (optarg));
    161168        break;
    162169#ifdef SIM_HAVE_ENVIRONMENT
    163170      case 'o':
    main (ac, av) 
    175182        break;
    176183#endif
    177184      case 't':
    178         trace = 1;
     185//      trace = 1;
     186        strcpy(tlim, "tlim ");
     187        strcat(tlim, optarg);
     188        strcat(tlim, " s");
    179189        break;
    180190      case 'v':
    181191        /* Things that are printed with -v are the kinds of things that
    182192           gcc -v prints.  This is not meant to include detailed tracing
    183193           or debugging information, just summaries.  */
    184         verbose = 1;
     194        sis_verbose = atoi(optarg);
    185195        /* sim_set_verbose (1); */
    186196        break;
    187197        /* FIXME: Quick hack, to be replaced by more general facility.  */
    main (ac, av) 
    243253  if (sim_create_inferior (sd, abfd, prog_args, NULL) == SIM_RC_FAIL)
    244254    exit (1);
    245255
     256  if (tlim[0]) {
     257    exec_cmd(tlim);
     258  }
     259
    246260#ifdef SIM_HAVE_ENVIRONMENT
    247261  /* NOTE: An old simulator supporting the operating environment MUST
    248262     provide sim_set_trace() and not sim_trace(). That way
    main (ac, av) 
    275289      prev_sigint = signal (SIGINT, cntrl_c);
    276290      sigrc = 0;
    277291      sim_resume (sd, 0, sigrc);
     292      if (sis_verbose)
     293          exec_cmd("per");
    278294      signal (SIGINT, prev_sigint);
    279295      sim_stop_reason (sd, &reason, &sigrc);
    280296    }
  • sim/erc32/sis.c

    diff --git a/sim/erc32/sis.c b/sim/erc32/sis.c
    index f78986e2e4..f311e14908 100644
    a b  
    4343extern int era;
    4444#endif
    4545
    46 int
    47 run_sim(sregs, icount, dis)
    48     struct pstate  *sregs;
    49     uint64          icount;
    50     int             dis;
    51 {
    52     int             irq, mexc, deb;
    53 
    54     sregs->starttime = get_time();
    55     ms->init_stdio ();
    56     if (sregs->err_mode) icount = 0;
    57     deb = dis || sregs->histlen || sregs->bptnum;
    58     irq = 0;
    59     while (icount > 0) {
    60 
    61         mexc = ms->memory_iread (sregs->pc, &sregs->inst, &sregs->hold);
    62         sregs->icnt = 1;
    63         if (sregs->annul) {
    64             sregs->annul = 0;
    65             sregs->pc = sregs->npc;
    66             sregs->npc = sregs->npc + 4;
    67         } else {
    68             sregs->fhold = 0;
    69             if (ext_irl) irq = check_interrupts(sregs);
    70             if (!irq) {
    71                 if (mexc) {
    72                     sregs->trap = I_ACC_EXC;
    73                 } else {
    74                     if (deb) {
    75                         if (sregs->histlen) {
    76                             sregs->histbuf[sregs->histind].addr = sregs->pc;
    77                             sregs->histbuf[sregs->histind].time = ebase.simtime;
    78                             sregs->histind++;
    79                             if (sregs->histind >= sregs->histlen)
    80                                 sregs->histind = 0;
    81                         }
    82                         if (dis) {
    83                             printf(" %8" PRIu64 " ", ebase.simtime);
    84                             dis_mem(sregs->pc, 1, &dinfo);
    85                         }
    86                         if ((sregs->bptnum) && (sregs->bphit = check_bpt(sregs)))
    87                             icount = 0;
    88                         else {
    89                             dispatch_instruction(sregs);
    90                             icount--;
    91                         }
    92                     } else {
    93                         dispatch_instruction(sregs);
    94                         icount--;
    95                     }
    96                 }
    97             }
    98             if (sregs->trap) {
    99                 irq = 0;
    100                 if ((sregs->err_mode = execute_trap(sregs)) == WPT_HIT) {
    101                     sregs->err_mode = 0;
    102                     sregs->trap = 0;
    103                     icount = 0;
    104                 }
    105                 if (sregs->err_mode) {
    106                     ms->error_mode (sregs->pc);
    107                     icount = 0;
    108                 }
    109             }
    110         }
    111         advance_time(sregs);
    112         if (ctrl_c || (sregs->tlimit <= ebase.simtime)) {
    113             icount = 0;
    114             if (sregs->tlimit <= ebase.simtime) sregs->tlimit = -1;
    115         }
    116     }
    117     sregs->tottime += get_time() - sregs->starttime;
    118     ms->restore_stdio ();
    119     if (sregs->err_mode)
    120         return ERROR;
    121     if (ctrl_c) {
    122         ctrl_c = 0;
    123         return CTRL_C;
    124     }
    125     if (sregs->bphit)
    126         return (BPT_HIT);
    127     if (sregs->wphit)
    128         return (WPT_HIT);
    129     return TIME_OUT;
    130 }
    131 
    13246int
    13347main(argc, argv)
    13448    int             argc;
    main(argc, argv) 
    208122                    strcat(tlim, " ");
    209123                    strcat(tlim, argv[++stat]);
    210124                }
     125            } else if (strcmp(argv[stat], "-m") == 0) {
     126                if ((stat + 1) < argc)
     127                    ncpu = VAL(argv[++stat]);
     128                    if ((ncpu < 1) || (ncpu > NCPU)) ncpu = 1;
     129            } else if (strcmp(argv[stat], "-d") == 0) {
     130                if ((stat + 1) < argc)
     131                    delta = VAL(argv[++stat]);
     132                    if (delta <= 0) delta = 25;
    211133            } else {
    212134                printf("unknown option %s\n", argv[stat]);
    213                 usage();
     135                sis_usage();
    214136                exit(1);
    215137            }
    216138        } else {
    main(argc, argv) 
    224146        printf (" LEON2 emulation enabled\n");
    225147        break;
    226148    case CPU_LEON3:
    227         printf (" LEON3 emulation enabled\n");
     149        printf (" LEON3 emulation enabled, %d cpus online, delta %d clocks\n",
     150                        ncpu, delta);
    228151        break;
    229152    default:
    230153        printf (" ERC32 emulation enabled\n");
    main(argc, argv) 
    232155
    233156    if (nfp)
    234157        printf(" FPU disabled\n");
    235     sregs.freq = freq;
     158    ebase.freq = freq;
    236159    printf("\n");
    237160
    238161    INIT_DISASSEMBLE_INFO(dinfo, stdout, (fprintf_ftype) fprintf);
    main(argc, argv) 
    248171    using_history();
    249172    init_signals();
    250173    ebase.simtime = 0;
     174    ebase.simstart = 0;
    251175    reset_all();
    252     init_bpt(&sregs);
     176    init_bpt(sregs);
    253177    ms->init_sim ();
    254178    if (lfile)
    255179        last_load_addr = bfd_load(argv[lfile]);
    main(argc, argv) 
    261185        bacmd = (char *) malloc(256);
    262186        strcpy(bacmd, "batch ");
    263187        strcat(bacmd, cfile);
    264         exec_cmd(&sregs, bacmd);
     188        exec_cmd(bacmd);
    265189    }
    266190    if (tlim[0]) {
    267         exec_cmd(&sregs, tlim);
     191        exec_cmd(tlim);
    268192    }
    269193
    270194    while (cont) {
    main(argc, argv) 
    279203            cmdq[cmdi] = 0;
    280204        }
    281205        if (run) {
    282             stat = exec_cmd(&sregs, "run");
     206            stat = exec_cmd("run");
    283207            cont = 0;
    284208        }
    285209        else {
    main(argc, argv) 
    287211            if (cmdq[cmdi] && *cmdq[cmdi])
    288212                add_history(cmdq[cmdi]);
    289213            if (cmdq[cmdi])
    290                 stat = exec_cmd(&sregs, cmdq[cmdi]);
     214                stat = exec_cmd(cmdq[cmdi]);
    291215            else {
    292216                puts("\n");
    293217                exit(0);
    main(argc, argv) 
    300224            printf("\b\bInterrupt!\n");
    301225        case TIME_OUT:
    302226            printf(" Stopped at time %" PRIu64 " (%.3f ms)\n", ebase.simtime,
    303               ((double) ebase.simtime / (double) sregs.freq) / 1000.0);
     227              ((double) ebase.simtime / (double) ebase.freq) / 1000.0);
    304228            break;
    305229        case BPT_HIT:
    306             printf("breakpoint at 0x%08x reached\n", sregs.pc);
    307             sregs.bphit = 1;
     230            printf("breakpoint at 0x%08x reached\n", sregs[cpu].pc);
     231            ebase.bphit = 1;
    308232            break;
    309233        case ERROR:
    310             printf("IU in error mode (%d)\n", sregs.trap);
     234            printf("IU in error mode (%d)\n", sregs[cpu].trap);
    311235            stat = 0;
    312236            printf(" %8" PRIu64 " ", ebase.simtime);
    313             dis_mem(sregs.pc, 1, &dinfo);
     237            dis_mem(sregs[cpu].pc, 1, &dinfo);
    314238            break;
    315239        case WPT_HIT:
    316240            printf("watchpoint at 0x%08x reached, pc = 0x%08x\n",
    317                 sregs.wpaddress, sregs.pc);
    318             sregs.wphit = 1;
     241                ebase.wpaddress, sregs[cpu].pc);
     242            ebase.wphit = 1;
    319243            break;
    320244        default:
    321245            break;
  • sim/erc32/sis.h

    diff --git a/sim/erc32/sis.h b/sim/erc32/sis.h
    index f046d5c718..274422893b 100644
    a b  
    4141#define WPR_MAX 256
    4242#define WPW_MAX 256
    4343
     44/* Maximum number of cpus */
     45#define NCPU 4
     46
    4447struct histype {
    4548    unsigned        addr;
    4649    unsigned        time;
    struct pstate { 
    9093
    9194
    9295    uint32          trap;       /* Current trap type */
    93     uint32          annul;      /* Instruction annul */
    9496    uint32          data;       /* Loaded data       */
    9597    uint32          inst;       /* Current instruction */
    9698    uint32          asi;        /* Current ASI */
    9799    uint32          err_mode;   /* IU error mode */
     100    uint32          pwd_mode;   /* IU in power-down mode */
    98101    uint32          breakpoint;
    99     uint32          bptnum;
    100     uint32          bphit;
    101     uint32          bpts[BPT_MAX];      /* Breakpoints */
    102     uint32          wprnum;
    103     uint32          wphit;
    104     uint32          wprs[WPR_MAX];      /* Read Watchpoints */
    105     unsigned char   wprm[WPR_MAX];      /* Read Watchpoint masks*/
    106     uint32          wpwnum;
    107     uint32          wpws[WPW_MAX];      /* Write Watchpoints */
    108     unsigned char   wpwm[WPW_MAX];      /* Write Watchpoint masks */
    109     uint32          wpaddress;
    110102
    111103    uint32          ltime;      /* Load interlock time */
    112104    uint32          hold;       /* IU hold cycles in current inst */
    113105    uint32          fhold;      /* FPU hold cycles in current inst */
    114106    uint32          icnt;       /* Instruction cycles in curr inst */
    115107
    116     uint32          histlen;    /* Trace history management */
    117108    uint32          histind;
    118109    struct histype *histbuf;
    119     float32         freq;       /* Simulated processor frequency */
    120110
    121111
    122     double          tottime;
    123112    uint64          ninst;
    124113    uint64          fholdt;
    125114    uint64          holdt;
    126115    uint64          icntt;
    127116    uint64          finst;
    128     uint64          simstart;
    129     double          starttime;
    130     uint64          tlimit;     /* Simulation time limit */
    131117    uint64          pwdtime;    /* Cycles in power-down mode */
     118    uint64          pwdstart;   /* Start of power-down mode */
    132119    uint64          nstore;     /* Number of load instructions */
    133120    uint64          nload;      /* Number of store instructions */
    134121    uint64          nannul;     /* Number of annuled instructions */
    struct pstate { 
    138125
    139126    int             rett_err;   /* IU in jmpl/restore error state (Rev.0) */
    140127    int             jmpltime;
     128    int             cpu;
     129    uint64          simtime;    /* local processor time */
     130    uint32          cache_ctrl; /* Leon3 cache control register */
     131    void            (*intack) (); /* interrupt ack. callback */
    141132};
    142133
    143134struct evcell {
    struct evcell { 
    150141struct estate {
    151142    struct evcell   eq;
    152143    struct evcell  *freeq;
    153     uint64          simtime;
    154 };
    155 
    156 struct irqcell {
    157     void            (*callback) ();
    158     int32           arg;
     144    uint64          simtime;    /* timestamp of last access to event queue */
     145    uint64          evtime;     /* timestamp of next event */
     146    float32         freq;       /* Simulated processor frequency */
     147    double          starttime;
     148    double          tottime;
     149    uint64          simstart;
     150    uint64          tlimit;     /* Simulation time limit */
     151    uint32          bptnum;
     152    uint32          bphit;
     153    uint32          bpts[BPT_MAX];      /* Breakpoints */
     154    uint32          wprnum;
     155    uint32          wphit;
     156    uint32          wprs[WPR_MAX];      /* Read Watchpoints */
     157    unsigned char   wprm[WPR_MAX];      /* Read Watchpoint masks*/
     158    uint32          wpwnum;
     159    uint32          wpws[WPW_MAX];      /* Write Watchpoints */
     160    unsigned char   wpwm[WPW_MAX];      /* Write Watchpoint masks */
     161    uint32          wpaddress;
     162    uint32          histlen;
    159163};
    160164
    161165/* return values for run_sim */
    struct irqcell { 
    180184extern const struct memsys erc32sys;
    181185
    182186/* func.c */
    183 extern struct   pstate  sregs;
     187extern struct   pstate  sregs[];
    184188extern struct   estate ebase;
    185189extern struct   evcell evbuf[];
    186 extern struct   irqcell irqarr[];
    187190extern int      nfp;
    188191extern int      ift;
    189192extern int      ctrl_c;
    extern int wrp; 
    196199extern int      rom8;
    197200extern int      uben;
    198201extern int      irqpend;
    199 extern int      ext_irl;
     202extern int      ext_irl[];
    200203extern int      termsave;
    201204extern char     uart_dev1[];
    202205extern char     uart_dev2[];
    203206extern void     set_regi (struct pstate *sregs, int32 reg,
    204207                          uint32 rval);
    205208extern void     get_regi (struct pstate *sregs, int32 reg, char *buf);
    206 extern int      exec_cmd (struct pstate *sregs, const char *cmd);
     209extern int      exec_cmd (const char *cmd);
    207210extern void     reset_stat (struct pstate  *sregs);
    208211extern void     show_stat (struct pstate  *sregs);
    209212extern void     init_bpt (struct pstate  *sregs);
    extern struct disassemble_info dinfo; 
    214217extern void     dis_mem (uint32 addr, uint32 len,
    215218                         struct disassemble_info *info);
    216219extern void     event (void (*cfunc) (), int32 arg, uint64 delta);
    217 extern void     set_int (int32 level, void (*callback) (), int32 arg);
    218 extern void     advance_time (struct pstate  *sregs);
    219220extern uint32   now (void);
    220 extern int      wait_for_irq (void);
    221221extern int      check_bpt (struct pstate *sregs);
    222222extern int      check_wpr(struct pstate *sregs, int32 address, unsigned char mask);
    223223extern int      check_wpw(struct pstate *sregs, int32 address, unsigned char mask);
    extern int dumbio; 
    233233extern int      tty_setup;
    234234extern int      cputype;
    235235extern int      sis_gdb_break;
    236 
     236extern int      cpu;    /* active cpu */
     237extern int      ncpu;   /* number of online cpus */
     238extern int      delta;  /* time slice for MP simulation */
     239extern void     pwd_enter(struct pstate *sregs);
     240extern void     remove_event(void (*cfunc) ());
     241extern int      run_sim (uint64 icount, int dis);
    237242
    238243/* exec.c */
    239244extern int      dispatch_instruction (struct pstate *sregs);
    240245extern int      execute_trap (struct pstate *sregs);
    241 extern int      check_interrupts (struct pstate  *sregs);
     246extern int      check_interrupts (struct pstate *sregs);
    242247extern void     init_regs (struct pstate *sregs);
    243248
    244 /* interf.c */
    245 extern int      run_sim (struct pstate *sregs,
    246                          uint64 icount, int dis);
    247 
    248249/* float.c */
    249250extern int      get_accex (void);
    250251extern void     clear_accex (void);
    251252extern void     set_fsr (uint32 fsr);
    252253
    253254/* help.c */
    254 extern void     usage (void);
     255extern void     sis_usage (void);
    255256extern void     gen_help (void);
    256257
    257258struct memsys {
    struct memsys { 
    264265    void        (*restore_stdio) (void);
    265266    int         (*memory_iread) (uint32 addr, uint32 *data, int32 *ws);
    266267    int         (*memory_read) (uint32 addr, uint32 *data, int32 sz, int32 *ws);
    267     int         (*memory_read_asi) (int32 asi, uint32 addr, uint32 *data,
    268                              int32 sz, int32 *ws);
    269268    int         (*memory_write) (uint32 addr, uint32 *data, int32 sz, int32 *ws);
    270     int         (*memory_write_asi) (int32 asi, uint32 addr, uint32 *data,
    271                              int32 sz, int32 *ws);
    272269    int         (*sis_memory_write) (uint32 addr,
    273270                                  const unsigned char *data, uint32 length);
    274271    int         (*sis_memory_read) (uint32 addr, char *data,