Index: /branches/v4/platforms/tsarv4_multi_mmu_ioc/Makefile
===================================================================
--- /branches/v4/platforms/tsarv4_multi_mmu_ioc/Makefile	(revision 665)
+++ /branches/v4/platforms/tsarv4_multi_mmu_ioc/Makefile	(revision 665)
@@ -0,0 +1,61 @@
+# where is soclib?
+SOCLIB_DIR=$(shell soclib-cc --getpath)
+
+# name definitions
+SOCLIB_DESC=desc.py
+SOCLIB_TOP=top.cpp
+SIMULATOR_BINARY=system.x
+SIMULATOR_CMD=./$(SIMULATOR_BINARY) --nobanner
+
+# extra arguments for compilation
+#SOCLIB_CC_ARGS=-v
+SOCLIB_CC_ARGS+=-b common:mips32
+
+# extra arguments for execution
+# gdb
+# F: start the simulation in a frozen state so it can be attached with a gdb client
+# X: disable automatic break whenever an exception is caught, the exception handler will be called transparently
+# S: make the simulation stop and wait for a gdb attachment whenever an exception is caught
+# C: dump a trace of every inter-functions branch
+# T: exit the simulator on trap exception
+# Z: same as C but display only function's entrypoint
+# W: disable automatic break whenever a watchpoint is hit, just report it on stderr (watchpoints can be defined using SOCLIB_GDB_WATCH)
+SIMULATOR_GDB=
+ifeq ("$(origin GDB)", "command line")
+ifeq ($(GDB), 1)
+	SIMULATOR_GDB=SOCLIB_GDB=FCX
+else
+	SIMULATOR_GDB=SOCLIB_GDB=$(GDB)
+endif
+endif
+# trace
+SIMULATOR_TRACE=
+ifeq ("$(origin TRACE)", "command line")
+	SIMULATOR_TRACE=--trace $(TRACE)
+endif
+# vmlinux
+SIMULATOR_VMLINUX=./vmlinux
+ifeq ("$(origin VMLINUX)", "command line")
+	SIMULATOR_VMLINUX=$(VMLINUX)
+endif
+
+# recipes
+all: $(SIMULATOR_BINARY)
+
+$(SIMULATOR_BINARY): $(SOCLIB_DESC) $(SOCLIB_TOP)
+	soclib-cc $(SOCLIB_CC_ARGS) -P -p $(SOCLIB_DESC) -o $(SIMULATOR_BINARY)
+
+run_tsar_boot: all tsar_boot.bin disk.img
+	$(SIMULATOR_GDB) $(SIMULATOR_CMD) --rom tsar_boot.bin --dsk disk.img $(SIMULATOR_TRACE)
+
+run_dummy_boot: all vmlinux disk.img
+	$(SIMULATOR_GDB) $(SIMULATOR_CMD) --rom $(SIMULATOR_VMLINUX) --dsk disk.img --dummy-boot $(SIMULATOR_TRACE)
+
+cscope.out:
+	soclib-cc -p $(SOCLIB_DESC) --tags
+
+clean:
+	soclib-cc -P -p $(SOCLIB_DESC) -x -o $(SIMULATOR_BINARY)
+	rm -f $(SIMULATOR_BINARY) *.o vci*
+
+.PHONY: $(SIMULATOR_BINARY)
Index: /branches/v4/platforms/tsarv4_multi_mmu_ioc/desc.py
===================================================================
--- /branches/v4/platforms/tsarv4_multi_mmu_ioc/desc.py	(revision 665)
+++ /branches/v4/platforms/tsarv4_multi_mmu_ioc/desc.py	(revision 665)
@@ -0,0 +1,32 @@
+
+# -*- python -*-
+
+todo = Platform('caba', 'top.cpp',
+        uses = [
+            Uses('common:mapping_table'),
+            Uses('caba:vci_cc_vcache_wrapper_v4', iss_t = 'common:mips32el'),
+            Uses('caba:vci_cc_vcache_wrapper_v4', iss_t = 'common:gdb_iss',
+                gdb_iss_t = 'common:mips32el'),
+            Uses('caba:vci_simple_ram'),
+            Uses('caba:vci_logger'),
+            Uses('caba:vci_multi_tty'),
+            Uses('caba:vci_icu'),
+            Uses('caba:vci_timer'),
+            Uses('caba:vci_block_device_tsar_v4'),
+            Uses('caba:vci_framebuffer'),
+            Uses('caba:vci_vgmn'),
+            Uses('caba:vci_mem_cache_v4'),
+            Uses('common:elf_file_loader'),
+            ],
+        cell_size = 4,
+        plen_size = 8,
+        addr_size = 32,
+        rerror_size = 2,
+        clen_size = 1,
+        rflag_size = 1,
+        srcid_size = 14,
+        pktid_size = 4,
+        trdid_size = 4,
+        wrplen_size = 1
+        )
+
Index: /branches/v4/platforms/tsarv4_multi_mmu_ioc/segmentation.h
===================================================================
--- /branches/v4/platforms/tsarv4_multi_mmu_ioc/segmentation.h	(revision 665)
+++ /branches/v4/platforms/tsarv4_multi_mmu_ioc/segmentation.h	(revision 665)
@@ -0,0 +1,27 @@
+#ifndef _SEGMENTATION_H
+#define _SEGMENTATION_H
+
+#define MEMC_BASE   0x00000000
+#define MEMC_SIZE   0x10000000 // 256Mb
+
+#define BOOT_BASE   0xbfc00000
+#define BOOT_SIZE   0x00040000
+
+#define ICU_BASE    0x10000000
+#define ICU_SIZE    0x00000014 // 5 mapped-registers
+
+#define MTTY_BASE   0x14000000
+#define MTTY_SIZE   0x0000000c // 3 mapped-registers
+
+#define TIMER_BASE  0x18000000
+#define TIMER_SIZE  0x00000010 // 4 mapped-registers
+
+#define BD_BASE     0x1c000000
+#define BD_SIZE     0x00000020 // 8 mapped-registers
+
+#define FB_XSIZE    640
+#define FB_YSIZE    480
+#define FB_BASE     0x20000000
+#define FB_SIZE     (FB_XSIZE * FB_YSIZE * 2)
+
+#endif
Index: /branches/v4/platforms/tsarv4_multi_mmu_ioc/soclib.conf
===================================================================
--- /branches/v4/platforms/tsarv4_multi_mmu_ioc/soclib.conf	(revision 665)
+++ /branches/v4/platforms/tsarv4_multi_mmu_ioc/soclib.conf	(revision 665)
@@ -0,0 +1,6 @@
+config.default.toolchain.set("cflags", config.default.toolchain.cflags + ['-ggdb'])
+
+import os
+config.addDescPath(os.environ['TSARDIR'] + "/branches/v4/lib")
+config.addDescPath(os.environ['TSARDIR'] + "/branches/v4/modules")
+
Index: /branches/v4/platforms/tsarv4_multi_mmu_ioc/top.cpp
===================================================================
--- /branches/v4/platforms/tsarv4_multi_mmu_ioc/top.cpp	(revision 665)
+++ /branches/v4/platforms/tsarv4_multi_mmu_ioc/top.cpp	(revision 665)
@@ -0,0 +1,463 @@
+/*
+ * global config
+ */
+
+#define CONFIG_GDB_SERVER
+
+
+/*
+ * headers
+ */
+
+#ifdef _OPENMP
+#include <omp.h>
+#endif
+
+#include <systemc>
+#include <iostream>
+#include <cstdlib>
+
+#ifdef CONFIG_GDB_SERVER
+#include "gdbserver.h"
+#endif
+
+#include "mapping_table.h"
+
+#include "mips32.h"
+#include "vci_cc_vcache_wrapper_v4.h"
+#include "vci_simple_ram.h"
+#include "vci_mem_cache_v4.h"
+
+#include "vci_icu.h"
+#include "vci_multi_tty.h"
+#include "vci_timer.h"
+#include "vci_block_device_tsar_v4.h"
+#include "vci_framebuffer.h"
+
+#include "vci_vgmn.h"
+
+#include "alloc_elems.h"
+
+
+/*
+ * pf global config
+ */
+
+using namespace sc_core;
+using namespace soclib::caba;
+using namespace soclib::common;
+
+#define cell_width      4
+#define address_width   32
+#define plen_width      8
+#define error_width     2
+#define clen_width      1
+#define rflag_width     1
+#define srcid_width     14
+#define pktid_width     4
+#define trdid_width     4
+#define wrplen_width    1
+
+typedef VciParams<cell_width,
+        plen_width,
+        address_width,
+        error_width,
+        clen_width,
+        rflag_width,
+        srcid_width,
+        pktid_width,
+        trdid_width,
+        wrplen_width> vci_param;
+
+/* mapping table for data */
+MappingTable maptabd(32, IntTab(6), IntTab(6), 0xf0000000);
+/* mapping table for coherence */
+MappingTable maptabc(32, IntTab(srcid_width), IntTab(srcid_width), 0xf0000000);
+
+
+/*
+ * segmentation
+ */
+
+#include "segmentation.h"
+
+
+/*
+ * default parameters
+ */
+
+struct param_s {
+    char *rom_path;
+    char *dsk_path;
+    bool dummy_boot;
+    bool framebuffer;
+    bool trace_enabled;
+    size_t trace_start_cycle;
+};
+
+#define PARAM_INITIALIZER   \
+{                           \
+    .rom_path = NULL,       \
+    .dsk_path = NULL,       \
+    .dummy_boot = false,    \
+    .framebuffer = false,   \
+    .trace_enabled = false, \
+    .trace_start_cycle = 0  \
+}
+
+static inline void print_param(const struct param_s &param)
+{
+    std::cout << std::endl;
+    std::cout << "simulation parameters:" << std::endl;
+    std::cout << "  rom         = " << param.rom_path << std::endl;
+    std::cout << "  dummy boot  = " << param.dummy_boot << std::endl;
+    std::cout << "  framebuffer = " << param.framebuffer << std::endl;
+    std::cout << "  dsk         = " << param.dsk_path << std::endl;
+    std::cout << "  trace       = " << param.trace_enabled << std::endl;
+    if (param.trace_enabled)
+        std::cout << "    start cyc = " << param.trace_start_cycle << std::endl;
+
+    std::cout << std::endl;
+}
+
+
+/*
+ * arguments parsing
+ */
+
+void args_parse(unsigned int argc, char *argv[], struct param_s &param)
+{
+    for (size_t n = 1; n < argc; n = n + 2)
+    {
+        if ((strcmp(argv[n], "--rom") == 0) && ((n + 1) < argc))
+        {
+            assert((param.rom_path = strdup(argv[n + 1]))
+                    && "insufficient memory");
+        }
+        else if ((strcmp(argv[n], "--dsk") == 0) && ((n + 1) < argc))
+        {
+            assert((param.dsk_path = strdup(argv[n + 1]))
+                    && "insufficient memory");
+        }
+        else if (strcmp(argv[n], "--dummy-boot") == 0)
+        {
+            param.dummy_boot = true;
+            /* we don't have an extra argument */
+            n = n - 1;
+        }
+        else if (strcmp(argv[n], "--framebuffer") == 0)
+        {
+            param.framebuffer = true;
+            /* we don't have an extra argument */
+            n = n - 1;
+        }
+        else if ((strcmp(argv[n], "--trace") == 0) && ((n + 1) < argc))
+        {
+            param.trace_enabled = true;
+            param.trace_start_cycle = atoi(argv[n + 1]);
+        }
+        else
+        {
+            std::cout << "Error: don't understand option " << argv[n] << std::endl;
+            std::cout << "Accepted arguments are :" << std::endl;
+            std::cout << "--rom pathname" << std::endl;
+            std::cout << "--dsk pathname" << std::endl;
+            std::cout << "[--dummy-boot]" << std::endl;
+            std::cout << "[--framebuffer]" << std::endl;
+            std::cout << "[--trace trace_start_cycle]" << std::endl;
+            exit(0);
+        }
+    }
+
+    /* check parameters */
+    assert(param.rom_path && "--rom is not optional");
+    assert(param.dsk_path && "--dsk is not optional");
+
+    print_param(param);
+}
+
+
+/*
+ * netlist
+ */
+
+int _main(int argc, char *argv[])
+{
+#ifdef _OPENMP
+    omp_set_dynamic(false);
+    omp_set_num_threads(1);
+    std::cerr << "Built with openmp version " << _OPENMP << std::endl;
+#endif
+
+    struct param_s param = PARAM_INITIALIZER;
+
+    /* parse arguments */
+    args_parse(argc, argv, param);
+
+    /*
+     * mapping table (data and coherence)
+     */
+
+    // caches ram bank
+    maptabd.add(Segment("memc_d" , MEMC_BASE , MEMC_SIZE , IntTab(0), true));
+    maptabd.add(Segment("boot_d" , BOOT_BASE , BOOT_SIZE , IntTab(1), true));
+
+    // uncached peripherals
+    maptabd.add(Segment("icu_d"   , ICU_BASE   , ICU_SIZE   , IntTab(2), false));
+    maptabd.add(Segment("mtty_d"  , MTTY_BASE  , MTTY_SIZE  , IntTab(3), false));
+    maptabd.add(Segment("timer_d" , TIMER_BASE , TIMER_SIZE , IntTab(4), false));
+    maptabd.add(Segment("bd_d"    , BD_BASE    , BD_SIZE    , IntTab(5), false));
+    maptabd.add(Segment("fb_d"    , FB_BASE    , FB_SIZE    , IntTab(6), false));
+
+    std::cout << maptabd << std::endl;
+
+    // procs
+    maptabc.add(Segment("proc_c" , 0x0000000 , 0x10 , IntTab(0) , false));
+    maptabc.add(Segment("memc_c" , 1 << (address_width - srcid_width) , 0x10 , IntTab(1) , false));
+
+    std::cout << maptabc << std::endl;
+
+    /*
+     * components
+     */
+
+    Loader loader;
+    loader.load_file(param.rom_path);
+
+#ifdef CONFIG_GDB_SERVER
+    typedef GdbServer<Mips32ElIss> proc_iss;
+    proc_iss::set_loader(loader);
+#else
+    typedef Mips32ElIss proc_iss;
+#endif
+
+    if (param.dummy_boot == true)
+    {
+        /* boot linux image directly */
+        uint64_t entry_addr = loader.get_entry_point_address();
+        std::cout << "setResetAdress: " << std::hex << entry_addr << std::endl << std::endl;
+        proc_iss::setResetAddress(entry_addr);
+    }
+
+    VciCcVCacheWrapperV4<vci_param, proc_iss > proc("ccvcache",
+                0,          // proc_id
+                maptabd,    // direct space
+                maptabc,    // coherence space
+                IntTab(0),  // srcid_d
+                IntTab(0),  // srcid_c
+                IntTab(0),  // tgtid_c
+                8, 8,       // itlb size
+                8, 8,       // dtlb size
+                4, 64, 16,  // icache size
+                4, 64, 16,  // dcache size
+                4, 4,       // wbuf size
+                0, 0,       // x, y Width
+                1,          // memory cache local id
+                1000,       // max frozen cycles
+                param.trace_start_cycle,
+                param.trace_enabled);
+
+    VciSimpleRam<vci_param> ram("ram", IntTab(0), maptabd, loader);
+
+    VciSimpleRam<vci_param> rom("rom", IntTab(1), maptabd, loader);
+
+    VciMemCacheV4<vci_param> memc("memc",
+            maptabd, maptabc, maptabd,
+            IntTab(0), IntTab(1), IntTab(0), IntTab(1), // srcid_d, srcid_c, tgtid_d, tgtid_c
+            16, 256, 16,    // cache size
+            1024, 4, 4,     // HEAP size, TRT size, UPT size
+            param.trace_start_cycle, param.trace_enabled);
+
+    VciIcu<vci_param> icu("icu", IntTab(2), maptabd,
+            3); // #input_irqs
+
+    VciMultiTty<vci_param> mtty("mtty", IntTab(3), maptabd, "vcitty0", NULL);
+
+    VciTimer<vci_param> timer("timer", IntTab(4), maptabd,
+            1); // #timers
+
+    VciBlockDeviceTsarV4<vci_param> bd("bd", maptabd, IntTab(1), IntTab(5),
+            param.dsk_path); // mapped_file[, block_size=512, latency=0]
+
+    VciFrameBuffer<vci_param> *fb = NULL;
+    if (param.framebuffer == true)
+        fb = new VciFrameBuffer<vci_param>("fb", IntTab(6), maptabd,
+                FB_XSIZE, FB_YSIZE,
+                FbController::RGB_16);
+
+    VciVgmn<vci_param> vgmnd("vgmnd", maptabd,
+            2, 7,       // #initiators, #targets
+            2, 8,       // min_latency, FIFO depth
+            IntTab(1)); // default target
+
+    VciVgmn<vci_param> vgmnc("vgmnc", maptabc,
+            2, 2,   // #initiators, #targets
+            2, 8);  // min_latency, FIFO depth
+
+    /*
+     * signals
+     */
+
+    /* clock and reset */
+    sc_clock signal_clk("signal_clk");
+    sc_signal<bool> signal_resetn("signal_resetn");
+
+    /* irq lines */
+    sc_signal<bool> *signal_proc_irq =
+        alloc_elems<sc_signal<bool> >("signal_proc_irq", proc_iss::n_irq);
+    sc_signal<bool> signal_mtty_irq("signal_mtty_irq");
+    sc_signal<bool> signal_timer_irq("signal_timer_irq");
+    sc_signal<bool> signal_bd_irq("signal_bd_irq");
+
+    /* vci */
+    VciSignals<vci_param> signal_vci_ini_d_proc("vci_ini_d_proc");
+    VciSignals<vci_param> signal_vci_ini_c_proc("vci_ini_c_proc");
+    VciSignals<vci_param> signal_vci_tgt_c_proc("vci_tgt_c_proc");
+
+    VciSignals<vci_param> signal_vci_ram("signal_vci_ram");
+
+    VciSignals<vci_param> signal_vci_tgt_d_rom("signal_vci_tgt_d_rom");
+
+    VciSignals<vci_param> signal_vci_ini_c_memc("signal_vci_ini_c_memc");
+    VciSignals<vci_param> signal_vci_tgt_d_memc("signal_vci_tgt_d_memc");
+    VciSignals<vci_param> signal_vci_tgt_c_memc("signal_vci_tgt_c_memc");
+
+    VciSignals<vci_param> signal_vci_tgt_d_icu("signal_vci_tgt_d_icu");
+
+    VciSignals<vci_param> signal_vci_tgt_d_mtty("signal_vci_tgt_d_mtty");
+
+    VciSignals<vci_param> signal_vci_tgt_d_timer("signal_vci_tgt_d_timer");
+
+    VciSignals<vci_param> signal_vci_ini_d_bd("signal_vci_ini_d_bd");
+    VciSignals<vci_param> signal_vci_tgt_d_bd("signal_vci_tgt_d_bd");
+
+    VciSignals<vci_param> signal_vci_tgt_d_fb("signal_vci_tgt_d_fb");
+
+    /*
+     * netlist
+     */
+
+    proc.p_clk(signal_clk);
+    proc.p_resetn(signal_resetn);
+    for (size_t i = 0; i < proc_iss::n_irq; i++)
+        proc.p_irq[i](signal_proc_irq[i]);
+    proc.p_vci_ini_d(signal_vci_ini_d_proc);
+    proc.p_vci_ini_c(signal_vci_ini_c_proc);
+    proc.p_vci_tgt_c(signal_vci_tgt_c_proc);
+
+    ram.p_clk(signal_clk);
+    ram.p_resetn(signal_resetn);
+    ram.p_vci(signal_vci_ram);
+
+    rom.p_clk(signal_clk);
+    rom.p_resetn(signal_resetn);
+    rom.p_vci(signal_vci_tgt_d_rom);
+
+    memc.p_clk(signal_clk);
+    memc.p_resetn(signal_resetn);
+    memc.p_vci_tgt(signal_vci_tgt_d_memc);
+    memc.p_vci_tgt_cleanup(signal_vci_tgt_c_memc);
+    memc.p_vci_ini(signal_vci_ini_c_memc);
+    memc.p_vci_ixr(signal_vci_ram);
+
+    icu.p_resetn(signal_resetn);
+    icu.p_clk(signal_clk);
+    icu.p_vci(signal_vci_tgt_d_icu);
+    icu.p_irq_in[0](signal_mtty_irq);
+    icu.p_irq_in[1](signal_timer_irq);
+    icu.p_irq_in[2](signal_bd_irq);
+    icu.p_irq(signal_proc_irq[0]);
+
+    mtty.p_clk(signal_clk);
+    mtty.p_resetn(signal_resetn);
+    mtty.p_vci(signal_vci_tgt_d_mtty);
+    mtty.p_irq[0](signal_mtty_irq);
+
+    timer.p_clk(signal_clk);
+    timer.p_resetn(signal_resetn);
+    timer.p_vci(signal_vci_tgt_d_timer);
+    timer.p_irq[0](signal_timer_irq);
+
+    bd.p_clk(signal_clk);
+    bd.p_resetn(signal_resetn);
+    bd.p_vci_target(signal_vci_tgt_d_bd);
+    bd.p_vci_initiator(signal_vci_ini_d_bd);
+    bd.p_irq(signal_bd_irq);
+
+    if (param.framebuffer == true)
+    {
+        fb->p_clk(signal_clk);
+        fb->p_resetn(signal_resetn);
+        fb->p_vci(signal_vci_tgt_d_fb);
+    }
+
+    vgmnd.p_clk(signal_clk);
+    vgmnd.p_resetn(signal_resetn);
+    vgmnd.p_to_initiator[0](signal_vci_ini_d_proc);
+    vgmnd.p_to_initiator[1](signal_vci_ini_d_bd);
+    vgmnd.p_to_target[0](signal_vci_tgt_d_memc);
+    vgmnd.p_to_target[1](signal_vci_tgt_d_rom);
+    vgmnd.p_to_target[2](signal_vci_tgt_d_icu);
+    vgmnd.p_to_target[3](signal_vci_tgt_d_mtty);
+    vgmnd.p_to_target[4](signal_vci_tgt_d_timer);
+    vgmnd.p_to_target[5](signal_vci_tgt_d_bd);
+    vgmnd.p_to_target[6](signal_vci_tgt_d_fb);
+
+    vgmnc.p_clk(signal_clk);
+    vgmnc.p_resetn(signal_resetn);
+    vgmnc.p_to_initiator[0](signal_vci_ini_c_proc);
+    vgmnc.p_to_initiator[1](signal_vci_ini_c_memc);
+    vgmnc.p_to_target[0](signal_vci_tgt_c_proc);
+    vgmnc.p_to_target[1](signal_vci_tgt_c_memc);
+
+    /*
+     * simulation
+     */
+
+    sc_start(sc_time(0, SC_NS));
+    signal_resetn = false;
+
+    sc_start(sc_time(1, SC_NS));
+    signal_resetn = true;
+
+    if (param.trace_enabled)
+    {
+        if (param.trace_start_cycle > 1)
+            // simulate without output until trace_start_cycle
+            sc_start(sc_time(param.trace_start_cycle, SC_NS));
+
+        // enable debugging output
+        for (size_t n = param.trace_start_cycle ;; n++)
+        {
+            std::cout << "****************** cycle " << std::dec << n
+                << " ************************************************" << std::endl;
+            proc.print_trace();
+            memc.print_trace();
+            signal_vci_ini_d_proc.print_trace("proc_ini_d");
+            signal_vci_tgt_c_proc.print_trace("proc_tgt_c");
+            signal_vci_ini_c_proc.print_trace("proc_ini_c");
+            signal_vci_tgt_d_memc.print_trace("memc_tgt_d");
+            signal_vci_tgt_c_memc.print_trace("memc_tgt_c");
+            signal_vci_ini_c_memc.print_trace("memc_ini_c");
+            if (signal_proc_irq[0].read())
+                std::cout << "---- IRQ ----" << std::endl;
+            sc_start(sc_time(1, SC_NS));
+        }
+    } else
+        sc_start();
+
+    return EXIT_SUCCESS;
+}
+
+int sc_main (int argc, char *argv[])
+{
+    try {
+        return _main(argc, argv);
+    } catch (std::exception &e) {
+        std::cout << e.what() << std::endl;
+    } catch (...) {
+        std::cout << "Unknown exception occurred" << std::endl;
+        throw;
+    }
+    return EXIT_FAILURE;
+}
