Ejemplo n.º 1
0
static cycles_t
ts_operate(conf_object_t *mem_hier, conf_object_t *space, 
           map_list_t *map, generic_transaction_t *mem_op)
{
        trans_splitter_t *ts = (trans_splitter_t *) mem_hier;
        int total_stall_time;
        cache_memory_transaction_t trans;
        generic_address_t offset;

        ts->transactions++;

        /* Transactions that don't span multiple cache lines or are
         * uncacheable are not modified */
        if (likely(TS_CL_TAG(ts, mem_op->physical_address) 
                   == (TS_CL_TAG(ts, mem_op->physical_address+mem_op->size-1))) 
            || unlikely(is_uncacheable(ts->cache, mem_op, map, &ts->log)))
                return ts->tm_ifc->operate(ts->timing_model, space, 
                                           map, mem_op);

        /* Here we have a cacheable cache line crossing transaction */
        ts->split_transactions++;

        total_stall_time = 0;
        trans.s = *mem_op;
        trans.s.ini_type = Sim_Initiator_Cache;
        trans.s.ini_ptr = (conf_object_t *) ts;
        
        /* we won't need reissue */
        mem_op->reissue = 0;

        /* update the initial_trans field */
        if ((mem_op->ini_type & 0xFF00) == Sim_Initiator_Cache) {
                cache_memory_transaction_t *ct =
                        (cache_memory_transaction_t *) mem_op;
                trans.initial_trans = ct->initial_trans;
        }
        else {
                trans.initial_trans = mem_op;
        }

        offset = 0;
        while (offset < mem_op->size) {
                int stall_time;
                trans.s.physical_address = mem_op->physical_address + offset;
                trans.s.logical_address = mem_op->logical_address + offset;
                trans.s.size = MIN(mem_op->size - offset, 
                                 TS_CL_ADDR(ts, trans.s.physical_address 
                                            + ts->next_cache_line_size) 
                                 - trans.s.physical_address);
                trans.s.id = 0;
                stall_time = ts->tm_ifc->operate(ts->timing_model, space, map, 
                                                 &trans.s);
                total_stall_time = MAX(total_stall_time, stall_time);
                if (trans.s.exception != Sim_PE_No_Exception)
                        mem_op->exception = trans.s.exception;
                offset += trans.s.size;
        }

        return total_stall_time;
}
Ejemplo n.º 2
0
cycles_t
ts_operate(conf_object_t *mem_hier, conf_object_t *space, 
           map_list_t *map, generic_transaction_t *mem_op)
{
        trans_splitter_t *ts = (trans_splitter_t *) mem_hier;
        int stall_time, index;
        double_trans_t *dt;
        
        /* uncacheable transactions are not modified */
        if (likely(TS_TAG(ts, mem_op->physical_address) == 
                   (TS_TAG(ts, mem_op->physical_address + mem_op->size - 1))) ||
            (ts->cache && unlikely(is_uncacheable(ts->cache, mem_op, map, &ts->log)))) {
                stall_time = ts->tm_ifc->operate(ts->timing_model, space, 
                                                 map, mem_op);
                if (!stall_time || !mem_op->reissue)
                        ts->transactions++;
                return stall_time;
        }

        /* here we have a cacheable, cache line crossing transaction */
        index = mem_op->id & TABLE_SPLITTER_MASK;
        if ((dt = ts->table[index]) == NULL) {

                int first_size;

                /* first time transaction */
                dt = new_trans(ts);
                ts->table[index] = dt;

                /* setup the two transactions */
                dt->a.s = *mem_op;
                dt->b.s = *mem_op;

                first_size = TS_CL_ADDR(ts, mem_op->physical_address 
                                        + mem_op->size - 1)
                        - mem_op->physical_address;

                dt->a.s.size = first_size;
                dt->a.s.ini_type = Sim_Initiator_Cache;
                dt->a.s.ini_ptr = (conf_object_t *) ts;
                
                dt->b.s.physical_address += first_size;
                dt->b.s.logical_address += first_size;
                dt->b.s.size -= first_size;
                dt->b.s.ini_type = Sim_Initiator_Cache;
                dt->b.s.ini_ptr = (conf_object_t *) ts;
                dt->b.s.id = SIM_get_unique_memory_transaction_id(
                        GC_CPU(mem_op));
                
                dt->stall_a = 0;
                dt->stall_b = 0;
                dt->a.s.reissue = 1;
                dt->b.s.reissue = 1;
        }

        /* update the initial_trans field */
        if ((mem_op->ini_type & 0xFF00) == Sim_Initiator_Cache) {
                cache_memory_transaction_t *ct =
                        (cache_memory_transaction_t *) mem_op;
                dt->a.initial_trans = ct->initial_trans;
                dt->b.initial_trans = ct->initial_trans;
        }
        else {
                dt->a.initial_trans = mem_op;
                dt->b.initial_trans = mem_op;
        }

        if (!dt->stall_a && dt->a.s.reissue) {
                dt->a.s.reissue = 0;
                dt->stall_a = ts->tm_ifc->operate(ts->timing_model, space,
                                                  map, &dt->a.s);
                if (!dt->stall_a)
                        dt->a.s.reissue = 0;
        }

        if (!dt->stall_b && dt->b.s.reissue) {
                dt->b.s.reissue = 0;
                dt->stall_b = ts->tm_ifc->operate(ts->timing_model, space, 
                                                  map, &dt->b.s);
                if (!dt->stall_b)
                        dt->b.s.reissue = 0;
        }

        /* if at least one of the two needs reissue */
        if (dt->a.s.reissue || dt->b.s.reissue) {

                stall_time = MIN((dt->a.s.reissue) ? dt->stall_a : 0x7FFFFFFF, 
                                 (dt->b.s.reissue) ? dt->stall_b : 0x7FFFFFFF);
                dt->stall_a -= stall_time;
                dt->stall_b -= stall_time;
                mem_op->reissue = 1;
        }
        else {
                /* no reissue */
                stall_time = MAX(dt->stall_a, dt->stall_b);
                dt->used = 0;
                ts->table[index] = NULL;
                mem_op->reissue = 0;
                ts->split_transactions++;
                ts->transactions++;
        }

        return stall_time;
}