cdt/cdt_6_0_x/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIMemory.java
author Steve Sobek <steve.sobek@nokia.com>
Fri, 30 Oct 2009 10:27:11 -0500
changeset 105 fbceb3d6fb44
parent 37 c2bce6dd59e7
permissions -rw-r--r--
let expression getAddress() return a string, such as register name or invalid access message
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
37
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     1
/*******************************************************************************
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     2
 * Copyright (c) 2007, 2008 Wind River Systems and others.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     3
 * All rights reserved. This program and the accompanying materials
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     4
 * are made available under the terms of the Eclipse Public License v1.0
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     5
 * which accompanies this distribution, and is available at
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     6
 * http://www.eclipse.org/legal/epl-v10.html
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     7
 * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     8
 * Contributors:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
     9
 *     Wind River Systems - initial API and implementation
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    10
 *     Ericsson AB - expanded from initial stub
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    11
 *     Ericsson AB - added support for event handling
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    12
 *     Ericsson AB - added memory cache
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    13
 *******************************************************************************/
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    14
package org.eclipse.cdt.dsf.mi.service;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    15
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    16
import java.util.HashMap;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    17
import java.util.Hashtable;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    18
import java.util.LinkedList;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    19
import java.util.ListIterator;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    20
import java.util.Map;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    21
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    22
import org.eclipse.cdt.core.IAddress;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    23
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    24
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    25
import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    26
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    27
import org.eclipse.cdt.dsf.datamodel.AbstractDMEvent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    28
import org.eclipse.cdt.dsf.datamodel.DMContexts;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    29
import org.eclipse.cdt.dsf.datamodel.IDMContext;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    30
import org.eclipse.cdt.dsf.debug.service.ICachingService;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    31
import org.eclipse.cdt.dsf.debug.service.IExpressions;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    32
import org.eclipse.cdt.dsf.debug.service.IMemory;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    33
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMAddress;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    34
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    35
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerResumedDMEvent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    36
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    37
import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    38
import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    39
import org.eclipse.cdt.dsf.debug.service.IRunControl.StateChangeReason;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    40
import org.eclipse.cdt.dsf.debug.service.command.CommandCache;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    41
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    42
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    43
import org.eclipse.cdt.dsf.mi.service.MIExpressions.ExpressionChangedEvent;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    44
import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataReadMemory;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    45
import org.eclipse.cdt.dsf.mi.service.command.commands.MIDataWriteMemory;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    46
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataReadMemoryInfo;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    47
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataWriteMemoryInfo;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    48
import org.eclipse.cdt.dsf.service.AbstractDsfService;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    49
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    50
import org.eclipse.cdt.dsf.service.DsfSession;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    51
import org.eclipse.cdt.utils.Addr64;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    52
import org.eclipse.core.runtime.IStatus;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    53
import org.eclipse.core.runtime.Status;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    54
import org.eclipse.debug.core.model.MemoryByte;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    55
import org.osgi.framework.BundleContext;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    56
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    57
/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    58
 * Memory service implementation
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    59
 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    60
public class MIMemory extends AbstractDsfService implements IMemory, ICachingService {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    61
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    62
    public class MemoryChangedEvent extends AbstractDMEvent<IMemoryDMContext> 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    63
        implements IMemoryChangedEvent 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    64
    {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    65
        IAddress[] fAddresses;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    66
        IDMContext fContext;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    67
        
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    68
        public MemoryChangedEvent(IMemoryDMContext context, IAddress[] addresses) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    69
            super(context);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    70
            fAddresses = addresses;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    71
        }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    72
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    73
        public IAddress[] getAddresses() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    74
            return fAddresses;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    75
        }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    76
    }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    77
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    78
	// Back-end commands cache
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    79
	private CommandCache fCommandCache;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    80
	// Map of memory caches
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    81
    private Map<IMemoryDMContext, MIMemoryCache> fMemoryCaches;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    82
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    83
    private MIMemoryCache getMemoryCache(IMemoryDMContext memoryDMC) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    84
    	MIMemoryCache cache = fMemoryCaches.get(memoryDMC);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    85
    	if (cache == null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    86
    		cache = new MIMemoryCache();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    87
    		fMemoryCaches.put(memoryDMC, cache);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    88
    	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    89
    	return cache;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    90
    }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    91
    
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    92
	/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    93
	 *  Constructor 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    94
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    95
	public MIMemory(DsfSession session) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    96
		super(session);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    97
    }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    98
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
    99
    ///////////////////////////////////////////////////////////////////////////
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   100
    // AbstractDsfService overrides
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   101
    ///////////////////////////////////////////////////////////////////////////
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   102
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   103
	/* (non-Javadoc)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   104
	 * @see org.eclipse.cdt.dsf.service.AbstractDsfService#initialize(org.eclipse.cdt.dsf.concurrent.RequestMonitor)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   105
	 * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   106
	 * This function is called during the launch sequence (where the service is 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   107
	 * instantiated). See LaunchSequence.java.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   108
	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   109
	@Override
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   110
    public void initialize(final RequestMonitor requestMonitor) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   111
        super.initialize(new RequestMonitor(getExecutor(), requestMonitor) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   112
            @Override
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   113
            protected void handleSuccess() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   114
                doInitialize(requestMonitor);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   115
            }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   116
        });
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   117
    }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   118
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   119
    /*
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   120
     * Initialization function:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   121
     * - Register the service
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   122
     * - Create the command cache
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   123
     * - Register self to service events
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   124
     * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   125
     * @param requestMonitor
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   126
     */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   127
    private void doInitialize(final RequestMonitor requestMonitor) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   128
    	// Create the command cache
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   129
        ICommandControlService commandControl = getServicesTracker().getService(ICommandControlService.class);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   130
    	fCommandCache = new CommandCache(getSession(), commandControl);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   131
    	fCommandCache.setContextAvailable(commandControl.getContext(), true);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   132
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   133
    	// Register this service
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   134
    	register(new String[] { MIMemory.class.getName(), IMemory.class.getName() }, new Hashtable<String, String>());
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   135
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   136
    	// Create the memory requests cache
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   137
    	fMemoryCaches = new HashMap<IMemoryDMContext, MIMemoryCache>();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   138
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   139
		// Register as service event listener
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   140
    	getSession().addServiceEventListener(this, null);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   141
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   142
    	// Done 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   143
    	requestMonitor.done();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   144
    }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   145
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   146
    /* (non-Javadoc)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   147
     * @see org.eclipse.cdt.dsf.service.AbstractDsfService#shutdown(org.eclipse.cdt.dsf.concurrent.RequestMonitor)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   148
     */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   149
    @Override
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   150
    public void shutdown(final RequestMonitor requestMonitor) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   151
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   152
    	// Unregister this service
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   153
        unregister();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   154
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   155
		// Remove event listener
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   156
    	getSession().removeServiceEventListener(this);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   157
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   158
    	// Complete the shutdown
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   159
        super.shutdown(requestMonitor);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   160
    }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   161
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   162
    /* (non-Javadoc)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   163
     * @see org.eclipse.cdt.dsf.service.AbstractDsfService#getBundleContext()
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   164
     */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   165
    @Override
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   166
    protected BundleContext getBundleContext() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   167
        return GdbPlugin.getBundleContext();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   168
    }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   169
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   170
    ///////////////////////////////////////////////////////////////////////////
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   171
    // IMemory
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   172
    ///////////////////////////////////////////////////////////////////////////
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   173
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   174
    /* (non-Javadoc)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   175
     * @see org.eclipse.cdt.dsf.debug.service.IMemory#getMemory(org.eclipse.cdt.dsf.datamodel.IDMContext, org.eclipse.cdt.core.IAddress, long, int, org.eclipse.cdt.dsf.concurrent.DataRequestMonitor)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   176
     */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   177
    public void getMemory(IMemoryDMContext memoryDMC, IAddress address, long offset,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   178
    		int word_size, int count, DataRequestMonitor<MemoryByte[]> drm)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   179
	{
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   180
        // Validate the context
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   181
        if (memoryDMC == null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   182
            drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   183
            drm.done();            
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   184
            return;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   185
        }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   186
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   187
        // Validate the word size
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   188
    	// NOTE: We only accept 1 byte words for this implementation
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   189
    	if (word_size != 1) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   190
    		drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Word size not supported (!= 1)", null)); //$NON-NLS-1$
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   191
    		drm.done();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   192
    		return;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   193
    	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   194
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   195
    	// Validate the byte count
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   196
    	if (count < 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   197
    		drm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid word count (< 0)", null)); //$NON-NLS-1$
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   198
    		drm.done();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   199
    		return;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   200
    	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   201
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   202
    	// All is clear: go for it
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   203
    	getMemoryCache(memoryDMC).getMemory(memoryDMC, address.add(offset), word_size, count, drm);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   204
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   205
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   206
    /* (non-Javadoc)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   207
     * @see org.eclipse.cdt.dsf.debug.service.IMemory#setMemory(org.eclipse.cdt.dsf.datamodel.IDMContext, org.eclipse.cdt.core.IAddress, long, int, byte[], org.eclipse.cdt.dsf.concurrent.RequestMonitor)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   208
     */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   209
    public void setMemory(IMemoryDMContext memoryDMC, IAddress address, long offset,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   210
    		int word_size, int count, byte[] buffer, RequestMonitor rm)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   211
    {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   212
        // Validate the context
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   213
        if (memoryDMC == null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   214
            rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   215
            rm.done();            
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   216
            return;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   217
        }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   218
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   219
    	// Validate the word size
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   220
    	// NOTE: We only accept 1 byte words for this implementation
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   221
    	if (word_size != 1) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   222
    		rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Word size not supported (!= 1)", null)); //$NON-NLS-1$
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   223
    		rm.done();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   224
    		return;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   225
    	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   226
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   227
    	// Validate the byte count
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   228
    	if (count < 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   229
    		rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid word count (< 0)", null)); //$NON-NLS-1$
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   230
    		rm.done();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   231
    		return;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   232
    	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   233
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   234
    	// Validate the buffer size
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   235
    	if (buffer.length < count) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   236
    		rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Buffer too short", null)); //$NON-NLS-1$
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   237
    		rm.done();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   238
    		return;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   239
    	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   240
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   241
    	// All is clear: go for it
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   242
    	getMemoryCache(memoryDMC).setMemory(memoryDMC, address, offset, word_size, count, buffer, rm);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   243
    }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   244
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   245
    /* (non-Javadoc)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   246
     * @see org.eclipse.cdt.dsf.debug.service.IMemory#fillMemory(org.eclipse.cdt.dsf.datamodel.IDMContext, org.eclipse.cdt.core.IAddress, long, int, byte[], org.eclipse.cdt.dsf.concurrent.RequestMonitor)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   247
     */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   248
    public void fillMemory(IMemoryDMContext memoryDMC, IAddress address, long offset,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   249
    		int word_size, int count, byte[] pattern, RequestMonitor rm)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   250
    {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   251
        // Validate the context
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   252
        if (memoryDMC == null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   253
            rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INTERNAL_ERROR, "Unknown context type", null)); //$NON-NLS-1$);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   254
            rm.done();            
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   255
            return;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   256
        }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   257
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   258
    	// Validate the word size
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   259
    	// NOTE: We only accept 1 byte words for this implementation
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   260
    	if (word_size != 1) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   261
    		rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Word size not supported (!= 1)", null)); //$NON-NLS-1$
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   262
    		rm.done();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   263
    		return;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   264
    	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   265
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   266
    	// Validate the repeat count
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   267
    	if (count < 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   268
    		rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Invalid repeat count (< 0)", null)); //$NON-NLS-1$
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   269
    		rm.done();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   270
    		return;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   271
    	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   272
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   273
    	// Validate the pattern
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   274
    	if (pattern.length < 1) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   275
    		rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, IDsfStatusConstants.INTERNAL_ERROR, "Empty pattern", null)); //$NON-NLS-1$
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   276
    		rm.done();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   277
    		return;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   278
    	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   279
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   280
    	// Create an aggregate buffer so we can write in 1 shot
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   281
    	int length = pattern.length;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   282
    	byte[] buffer = new byte[count * length];
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   283
    	for (int i = 0; i < count; i++) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   284
    		System.arraycopy(pattern, 0, buffer, i * length, length);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   285
    	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   286
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   287
    	// All is clear: go for it
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   288
    	getMemoryCache(memoryDMC).setMemory(memoryDMC, address, offset, word_size, count * length, buffer, rm);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   289
    }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   290
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   291
    ///////////////////////////////////////////////////////////////////////
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   292
    // Back-end functions 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   293
    ///////////////////////////////////////////////////////////////////////
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   294
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   295
    /**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   296
     * @param memoryDMC
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   297
     * @param address
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   298
     * @param offset
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   299
     * @param word_size
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   300
     * @param count
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   301
     * @param drm
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   302
     * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   303
     * @since 1.1
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   304
     */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   305
    protected void readMemoryBlock(IDMContext dmc, IAddress address, final long offset,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   306
    		final int word_size, final int count, final DataRequestMonitor<MemoryByte[]> drm)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   307
    {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   308
    	/* To simplify the parsing of the MI result, we request the output to
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   309
    	 * be on 1 row of [count] columns, no char interpretation.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   310
    	 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   311
    	int mode = MIFormat.HEXADECIMAL;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   312
    	int nb_rows = 1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   313
    	int nb_cols = count;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   314
    	Character asChar = null;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   315
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   316
    	fCommandCache.execute(
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   317
    			new MIDataReadMemory(dmc, offset, address.toString(), mode, word_size, nb_rows, nb_cols, asChar),
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   318
    			new DataRequestMonitor<MIDataReadMemoryInfo>(getExecutor(), drm) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   319
    				@Override
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   320
    				protected void handleSuccess() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   321
    					// Retrieve the memory block
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   322
    					drm.setData(getData().getMIMemoryBlock());
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   323
    					drm.done();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   324
    				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   325
    				@Override
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   326
    				protected void handleFailure() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   327
    					// Bug234289: If memory read fails, return a block marked as invalid
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   328
    					MemoryByte[] block = new MemoryByte[word_size * count];
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   329
    					for (int i = 0; i < block.length; i++)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   330
    						block[i] = new MemoryByte((byte) 0, (byte) 0);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   331
    					drm.setData(block);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   332
    					drm.done();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   333
    				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   334
    			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   335
    	);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   336
    }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   337
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   338
    /**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   339
     * @param memoryDMC
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   340
     * @param address
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   341
     * @param offset
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   342
     * @param word_size
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   343
     * @param count
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   344
     * @param buffer
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   345
     * @param rm
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   346
     * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   347
     * @since 1.1
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   348
     */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   349
    protected void writeMemoryBlock(final IDMContext dmc, final IAddress address, final long offset,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   350
    		final int word_size, final int count, final byte[] buffer, final RequestMonitor rm)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   351
    {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   352
    	// Each byte is written individually (GDB power...)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   353
    	// so we need to keep track of the count
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   354
    	final CountingRequestMonitor countingRM = new CountingRequestMonitor(getExecutor(), rm);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   355
    	countingRM.setDoneCount(count);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   356
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   357
    	// We will format the individual bytes in decimal
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   358
    	int format = MIFormat.DECIMAL;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   359
    	String baseAddress = address.toString();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   360
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   361
    	// Issue an MI request for each byte to write
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   362
    	for (int i = 0; i < count; i++) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   363
    		String value = new Byte(buffer[i]).toString();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   364
    		fCommandCache.execute(
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   365
    				new MIDataWriteMemory(dmc, offset + i, baseAddress, format, word_size, value),
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   366
    				new DataRequestMonitor<MIDataWriteMemoryInfo>(getExecutor(), countingRM)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   367
    		);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   368
    	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   369
    }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   370
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   371
    //////////////////////////////////////////////////////////////////////////
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   372
    // Event handlers
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   373
    //////////////////////////////////////////////////////////////////////////
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   374
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   375
    /**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   376
     * @nooverride This method is not intended to be re-implemented or extended by clients.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   377
     * @noreference This method is not intended to be referenced by clients.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   378
     */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   379
    @DsfServiceEventHandler
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   380
	public void eventDispatched(IResumedDMEvent e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   381
    	if (e instanceof IContainerResumedDMEvent) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   382
    		fCommandCache.setContextAvailable(e.getDMContext(), false);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   383
    	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   384
    	
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   385
   		if (e.getReason() != StateChangeReason.STEP) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   386
	    	fCommandCache.reset(e.getDMContext());
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   387
	    	IMemoryDMContext memoryDMC = DMContexts.getAncestorOfType(e.getDMContext(), IMemoryDMContext.class);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   388
	    	if (fMemoryCaches.containsKey(memoryDMC)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   389
	    		// We do not want to use the call to getMemoryCache() here.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   390
	    		// This is because:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   391
	    		// 1- if there is not an entry already , we do not want to automatically 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   392
	    		//    create one, just to call reset() on it.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   393
	    		// 2- if memoryDMC == null, we do not want to create a cache
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   394
	    		//    entry for which the key is 'null'
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   395
	    		fMemoryCaches.get(memoryDMC).reset();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   396
	    	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   397
   		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   398
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   399
   
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   400
    /**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   401
     * @nooverride This method is not intended to be re-implemented or extended by clients.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   402
     * @noreference This method is not intended to be referenced by clients.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   403
     */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   404
    @DsfServiceEventHandler
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   405
	public void eventDispatched(ISuspendedDMEvent e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   406
    	if (e instanceof IContainerSuspendedDMEvent) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   407
    		fCommandCache.setContextAvailable(e.getDMContext(), true);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   408
    	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   409
    	
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   410
    	fCommandCache.reset(e.getDMContext());
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   411
    	IMemoryDMContext memoryDMC = DMContexts.getAncestorOfType(e.getDMContext(), IMemoryDMContext.class);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   412
    	if (fMemoryCaches.containsKey(memoryDMC)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   413
    		// We do not want to use the call to getMemoryCache() here.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   414
    		// This is because:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   415
    		// 1- if there is not an entry already , we do not want to automatically 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   416
    		//    create one, just to call reset() on it.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   417
    		// 2- if memoryDMC == null, we do not want to create a cache
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   418
    		//    entry for which the key is 'null'
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   419
    		fMemoryCaches.get(memoryDMC).reset();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   420
    	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   421
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   422
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   423
    /**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   424
     * @nooverride This method is not intended to be re-implemented or extended by clients.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   425
     * @noreference This method is not intended to be referenced by clients.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   426
     */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   427
   	@DsfServiceEventHandler
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   428
	public void eventDispatched(ExpressionChangedEvent e) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   429
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   430
   		// Get the context and expression service handle
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   431
   		final IExpressionDMContext context = e.getDMContext();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   432
		IExpressions expressionService = getServicesTracker().getService(IExpressions.class);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   433
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   434
		// Get the variable information and update the corresponding memory locations
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   435
		if (expressionService != null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   436
			expressionService.getExpressionAddressData(context,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   437
				new DataRequestMonitor<IExpressionDMAddress>(getExecutor(), null) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   438
					@Override
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   439
					protected void handleSuccess() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   440
						// Figure out which memory area was modified
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   441
						IExpressionDMAddress expression = getData();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   442
						final int count = expression.getSize();
105
fbceb3d6fb44 let expression getAddress() return a string, such as register name or invalid access message
Steve Sobek <steve.sobek@nokia.com>
parents: 37
diff changeset
   443
						Object expAddress = expression.getAddress();
37
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   444
						final Addr64 address;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   445
						if (expAddress instanceof Addr64)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   446
							address = (Addr64) expAddress;
105
fbceb3d6fb44 let expression getAddress() return a string, such as register name or invalid access message
Steve Sobek <steve.sobek@nokia.com>
parents: 37
diff changeset
   447
						else if (expAddress instanceof IAddress)
fbceb3d6fb44 let expression getAddress() return a string, such as register name or invalid access message
Steve Sobek <steve.sobek@nokia.com>
parents: 37
diff changeset
   448
							address = new Addr64(((IAddress)expAddress).getValue());
37
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   449
						else
105
fbceb3d6fb44 let expression getAddress() return a string, such as register name or invalid access message
Steve Sobek <steve.sobek@nokia.com>
parents: 37
diff changeset
   450
							return; // not a valid memory address
37
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   451
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   452
						final IMemoryDMContext memoryDMC = DMContexts.getAncestorOfType(context, IMemoryDMContext.class);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   453
						getMemoryCache(memoryDMC).refreshMemory(memoryDMC, address, 0, 1, count,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   454
								new RequestMonitor(getExecutor(), null));
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   455
						}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   456
			});
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   457
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   458
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   459
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   460
	///////////////////////////////////////////////////////////////////////////
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   461
	// SortedLinkedlist
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   462
	///////////////////////////////////////////////////////////////////////////
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   463
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   464
	// This class is really the equivalent of a C struct (old habits die hard...)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   465
   	// For simplicity, everything is public.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   466
   	private class MemoryBlock {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   467
		public IAddress fAddress;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   468
		public long fLength;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   469
		public MemoryByte[] fBlock;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   470
		public MemoryBlock(IAddress address, long length, MemoryByte[] block) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   471
			fAddress = address;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   472
			fLength = length;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   473
			fBlock = block;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   474
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   475
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   476
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   477
   	// Address-ordered data structure to cache the memory blocks.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   478
   	// Contiguous blocks are merged if possible.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   479
	@SuppressWarnings("serial")
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   480
	private class SortedMemoryBlockList extends LinkedList<MemoryBlock> {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   481
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   482
		public SortedMemoryBlockList() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   483
			super();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   484
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   485
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   486
		// Insert the block in the sorted linked list and merge contiguous
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   487
		// blocks if necessary
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   488
		@Override
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   489
		public boolean add(MemoryBlock block) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   490
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   491
			// If the list is empty, just store the block
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   492
			if (isEmpty()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   493
				addFirst(block);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   494
				return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   495
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   496
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   497
			// Insert the block at the correct location and then
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   498
			// merge the blocks if possible
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   499
			ListIterator<MemoryBlock> it = listIterator();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   500
			while (it.hasNext()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   501
				int index = it.nextIndex();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   502
				MemoryBlock item = it.next();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   503
				if (block.fAddress.compareTo(item.fAddress) < 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   504
					add(index, block);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   505
					compact(index);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   506
					return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   507
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   508
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   509
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   510
			// Put at the end of the list and merge if necessary 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   511
			addLast(block);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   512
			compact(size() - 1);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   513
			return true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   514
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   515
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   516
		// Merge this block with its contiguous neighbors (if any)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   517
		// Note: Merge is not performed if resulting block size would exceed MAXINT
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   518
		private void compact(int index) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   519
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   520
			MemoryBlock newBlock = get(index); 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   521
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   522
			// Case where the block is to be merged with the previous block
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   523
			if (index > 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   524
				MemoryBlock prevBlock = get(index - 1);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   525
				IAddress endOfPreviousBlock = prevBlock.fAddress.add(prevBlock.fLength);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   526
				if (endOfPreviousBlock.distanceTo(newBlock.fAddress).longValue() == 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   527
					long newLength = prevBlock.fLength + newBlock.fLength;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   528
					if (newLength <= Integer.MAX_VALUE) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   529
						MemoryByte[] block = new MemoryByte[(int) newLength] ;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   530
						System.arraycopy(prevBlock.fBlock, 0, block, 0, (int) prevBlock.fLength);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   531
						System.arraycopy(newBlock.fBlock, 0, block, (int) prevBlock.fLength, (int) newBlock.fLength);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   532
						newBlock = new MemoryBlock(prevBlock.fAddress, newLength, block);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   533
						remove(index);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   534
						index -= 1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   535
						set(index, newBlock);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   536
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   537
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   538
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   539
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   540
			// Case where the block is to be merged with the following block
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   541
			int lastIndex = size() - 1;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   542
			if (index < lastIndex) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   543
				MemoryBlock nextBlock = get(index + 1);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   544
				IAddress endOfNewBlock = newBlock.fAddress.add(newBlock.fLength);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   545
				if (endOfNewBlock.distanceTo(nextBlock.fAddress).longValue() == 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   546
					long newLength = newBlock.fLength + nextBlock.fLength;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   547
					if (newLength <= Integer.MAX_VALUE) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   548
						MemoryByte[] block = new MemoryByte[(int) newLength] ;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   549
						System.arraycopy(newBlock.fBlock, 0, block, 0, (int) newBlock.fLength);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   550
						System.arraycopy(nextBlock.fBlock, 0, block, (int) newBlock.fLength, (int) nextBlock.fLength);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   551
						newBlock = new MemoryBlock(newBlock.fAddress, newLength, block);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   552
						set(index, newBlock);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   553
						remove(index + 1);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   554
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   555
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   556
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   557
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   558
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   559
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   560
	///////////////////////////////////////////////////////////////////////////
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   561
	// MIMemoryCache
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   562
	///////////////////////////////////////////////////////////////////////////
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   563
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   564
	private class MIMemoryCache {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   565
		// The memory cache data structure
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   566
		private SortedMemoryBlockList fMemoryBlockList;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   567
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   568
		public MIMemoryCache() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   569
	    	// Create the memory block cache
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   570
	    	fMemoryBlockList = new SortedMemoryBlockList();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   571
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   572
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   573
		public void reset() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   574
	    	// Clear the memory cache
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   575
	    	fMemoryBlockList.clear();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   576
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   577
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   578
	    /**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   579
 	     *  This function walks the address-sorted memory block list to identify
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   580
	     *  the 'missing' blocks (i.e. the holes) that need to be fetched on the target.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   581
	     * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   582
	     *  The idea is fairly simple but an illustration could perhaps help.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   583
	     *  Assume the cache holds a number of cached memory blocks with gaps i.e.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   584
	     *  there is un-cached memory areas between blocks A, B and C:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   585
	     * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   586
	     *        +---------+      +---------+      +---------+
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   587
	     *        +    A    +      +    B    +      +    C    +
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   588
	     *        +---------+      +---------+      +---------+
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   589
	     *        :         :      :         :      :         :
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   590
	     *   [a]  :         :  [b] :         :  [c] :         :  [d]
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   591
	     *        :         :      :         :      :         :
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   592
	     *   [e---+--]      :  [f--+---------+--]   :         :
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   593
	     *   [g---+---------+------+---------+------+---------+----]
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   594
	     *        :         :      :         :      :         :
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   595
	     *        :   [h]   :      :   [i----+--]   :         :
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   596
	     * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   597
	     * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   598
	     *  We have the following cases to consider.The requested block [a-i] either:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   599
	     * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   600
	     *  [1] Fits entirely before A, in one of the gaps, or after C
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   601
	     *      with no overlap and no contiguousness (e.g. [a], [b], [c] and [d])
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   602
	     *      -> Add the requested block to the list of blocks to fetch
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   603
	     * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   604
	     *  [2] Starts before an existing block but overlaps part of it, possibly
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   605
	     *      spilling in the gap following the cached block (e.g. [e], [f] and [g])
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   606
	     *      -> Determine the length of the missing part (< count)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   607
	     *      -> Add a request to fill the gap before the existing block
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   608
	     *      -> Update the requested block for the next iteration:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   609
	     *         - Start address to point just after the end of the cached block
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   610
	     *         - Count reduced by cached block length (possibly becoming negative, e.g. [e])
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   611
	     *      At this point, the updated requested block starts just beyond the cached block
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   612
	     *      for the next iteration.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   613
	     * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   614
	     *  [3] Starts at or into an existing block and overlaps part of it ([h] and [i])
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   615
	     *      -> Update the requested block for the next iteration:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   616
	     *         - Start address to point just after the end of the cached block
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   617
	     *         - Count reduced by length to end of cached block (possibly becoming negative, e.g. [h])
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   618
	     *      At this point, the updated requested block starts just beyond the cached block
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   619
	     *      for the next iteration.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   620
	     * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   621
	     *  We iterate over the cached blocks list until there is no entry left or until
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   622
	     *  the remaining requested block count is <= 0, meaning the result list contains
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   623
	     *  only the sub-blocks needed to fill the gap(s), if any.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   624
	     * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   625
	     *  (As is often the case, it takes much more typing to explain it than to just do it :-)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   626
	     *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   627
	     *  What is missing is a parameter that indicates the minimal block size that is worth fetching.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   628
	     *  This is target-specific and straight in the realm of the coalescing function... 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   629
	     *  
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   630
	     * @param reqBlockStart The address of the requested block
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   631
	     * @param count Its length
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   632
	     * @return A list of the sub-blocks to fetch in order to fill enough gaps in the memory cache
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   633
	     * to service the request
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   634
	     */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   635
	    private LinkedList<MemoryBlock> getListOfMissingBlocks(IAddress reqBlockStart, int count) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   636
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   637
			LinkedList<MemoryBlock> list = new LinkedList<MemoryBlock>();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   638
			ListIterator<MemoryBlock> it = fMemoryBlockList.listIterator();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   639
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   640
			// Look for holes in the list of memory blocks
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   641
			while (it.hasNext() && count > 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   642
				MemoryBlock cachedBlock = it.next();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   643
				IAddress cachedBlockStart = cachedBlock.fAddress;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   644
				IAddress cachedBlockEnd   = cachedBlock.fAddress.add(cachedBlock.fLength);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   645
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   646
				// Case where we miss a block before the cached block
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   647
				if (reqBlockStart.distanceTo(cachedBlockStart).longValue() >= 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   648
					int length = (int) Math.min(reqBlockStart.distanceTo(cachedBlockStart).longValue(), count);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   649
					// If both blocks start at the same location, no need to create a new cached block
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   650
					if (length > 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   651
						MemoryBlock newBlock = new MemoryBlock(reqBlockStart, length, new MemoryByte[0]);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   652
						list.add(newBlock);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   653
					}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   654
					// Adjust request block start and length for the next iteration
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   655
					reqBlockStart = cachedBlockEnd;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   656
					count -= length + cachedBlock.fLength;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   657
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   658
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   659
				// Case where the requested block starts somewhere in the cached block
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   660
				else if (cachedBlockStart.distanceTo(reqBlockStart).longValue() > 0
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   661
					&&  reqBlockStart.distanceTo(cachedBlockEnd).longValue() >= 0)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   662
				{
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   663
					// Start of the requested block already in cache
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   664
					// Adjust request block start and length for the next iteration
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   665
					count -= reqBlockStart.distanceTo(cachedBlockEnd).longValue();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   666
					reqBlockStart = cachedBlockEnd;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   667
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   668
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   669
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   670
			// Case where we miss a block at the end of the cache
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   671
			if (count > 0) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   672
				MemoryBlock newBlock = new MemoryBlock(reqBlockStart, count, new MemoryByte[0]);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   673
				list.add(newBlock);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   674
			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   675
			
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   676
			return list;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   677
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   678
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   679
	    /**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   680
	     *  This function walks the address-sorted memory block list to get the
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   681
	     *  cached memory bytes (possibly from multiple contiguous blocks).
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   682
	     *  This function is called *after* the missing blocks have been read from
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   683
	     *  the back end i.e. the requested memory is all cached. 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   684
	     *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   685
	     *  Again, this is fairly simple. As we loop over the address-ordered list,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   686
	     *  There are really only 2 cases:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   687
	     *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   688
	     *  [1] The requested block fits entirely in the cached block ([a] or [b])
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   689
	     *  [2] The requested block starts in a cached block and ends in the
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   690
	     *      following (contiguous) one ([c]) in which case it is treated
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   691
	     *      as 2 contiguous requests ([c'] and [c"])
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   692
	     *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   693
	     *       +--------------+--------------+
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   694
	     *       +       A      +      B       +
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   695
	     *       +--------------+--------------+
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   696
	     *       :  [a----]     :   [b-----]   :
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   697
	     *       :              :              :
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   698
	     *       :       [c-----+------]       :
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   699
	     *       :       [c'---]+[c"---]       :
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   700
		 *
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   701
	     * @param reqBlockStart The address of the requested block
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   702
	     * @param count Its length
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   703
	     * @return The cached memory content
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   704
	     */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   705
	    private MemoryByte[] getMemoryBlockFromCache(IAddress reqBlockStart, int count) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   706
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   707
			IAddress reqBlockEnd = reqBlockStart.add(count);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   708
			MemoryByte[] resultBlock = new MemoryByte[count];
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   709
			ListIterator<MemoryBlock> iter = fMemoryBlockList.listIterator();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   710
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   711
			while (iter.hasNext()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   712
				MemoryBlock cachedBlock = iter.next();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   713
				IAddress cachedBlockStart = cachedBlock.fAddress;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   714
				IAddress cachedBlockEnd   = cachedBlock.fAddress.add(cachedBlock.fLength);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   715
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   716
				// Case where the cached block overlaps completely the requested memory block  
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   717
				if (cachedBlockStart.distanceTo(reqBlockStart).longValue() >= 0
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   718
					&& reqBlockEnd.distanceTo(cachedBlockEnd).longValue() >= 0)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   719
				{
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   720
					int pos = (int) cachedBlockStart.distanceTo(reqBlockStart).longValue();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   721
					System.arraycopy(cachedBlock.fBlock, pos, resultBlock, 0, count);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   722
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   723
				
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   724
				// Case where the beginning of the cached block is within the requested memory block  
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   725
				else if (reqBlockStart.distanceTo(cachedBlockStart).longValue() >= 0
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   726
					&& cachedBlockStart.distanceTo(reqBlockEnd).longValue() > 0)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   727
				{
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   728
					int pos = (int) reqBlockStart.distanceTo(cachedBlockStart).longValue();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   729
					int length = (int) Math.min(cachedBlock.fLength, count - pos);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   730
					System.arraycopy(cachedBlock.fBlock, 0, resultBlock, pos, length);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   731
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   732
				
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   733
				// Case where the end of the cached block is within the requested memory block  
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   734
				else if (cachedBlockStart.distanceTo(reqBlockStart).longValue() >= 0
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   735
					&& reqBlockStart.distanceTo(cachedBlockEnd).longValue() > 0)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   736
				{
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   737
					int pos = (int) cachedBlockStart.distanceTo(reqBlockStart).longValue();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   738
					int length = (int) Math.min(cachedBlock.fLength - pos, count);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   739
					System.arraycopy(cachedBlock.fBlock, pos, resultBlock, 0, length);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   740
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   741
 			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   742
			return resultBlock;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   743
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   744
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   745
		/**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   746
	     *  This function walks the address-sorted memory block list and updates
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   747
	     *  the content with the actual memory just read from the target.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   748
	     * 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   749
		 * @param modBlockStart
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   750
		 * @param count
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   751
		 * @param modBlock
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   752
		 */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   753
		private void updateMemoryCache(IAddress modBlockStart, int count, MemoryByte[] modBlock) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   754
			
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   755
			IAddress modBlockEnd = modBlockStart.add(count);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   756
			ListIterator<MemoryBlock> iter = fMemoryBlockList.listIterator();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   757
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   758
			while (iter.hasNext()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   759
				MemoryBlock cachedBlock = iter.next();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   760
				IAddress cachedBlockStart = cachedBlock.fAddress;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   761
				IAddress cachedBlockEnd   = cachedBlock.fAddress.add(cachedBlock.fLength);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   762
				
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   763
				// For now, we only bother to update bytes already cached.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   764
				// Note: In a better implementation (v1.1), we would augment
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   765
				// the cache with the missing memory blocks since we went 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   766
				// through the pains of reading them in the first place.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   767
				// (this is left as an exercise to the reader :-)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   768
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   769
				// Case where the modified block is completely included in the cached block  
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   770
				if (cachedBlockStart.distanceTo(modBlockStart).longValue() >= 0
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   771
					&& modBlockEnd.distanceTo(cachedBlockEnd).longValue() >= 0)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   772
				{
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   773
					int pos = (int) cachedBlockStart.distanceTo(modBlockStart).longValue();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   774
					System.arraycopy(modBlock, 0, cachedBlock.fBlock, pos, count);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   775
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   776
				
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   777
				// Case where the beginning of the modified block is within the cached block  
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   778
				else if (cachedBlockStart.distanceTo(modBlockStart).longValue() >= 0
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   779
					&& modBlockStart.distanceTo(cachedBlockEnd).longValue() > 0)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   780
				{
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   781
					int pos = (int) cachedBlockStart.distanceTo(modBlockStart).longValue();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   782
					int length = (int) cachedBlockStart.distanceTo(modBlockEnd).longValue();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   783
					System.arraycopy(modBlock, 0, cachedBlock.fBlock, pos, length);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   784
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   785
				
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   786
				// Case where the end of the modified block is within the cached block  
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   787
				else if (cachedBlockStart.distanceTo(modBlockEnd).longValue() > 0
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   788
					&& modBlockEnd.distanceTo(cachedBlockEnd).longValue() >= 0)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   789
				{
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   790
					int pos = (int) modBlockStart.distanceTo(cachedBlockStart).longValue();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   791
					int length = (int) cachedBlockStart.distanceTo(modBlockEnd).longValue();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   792
					System.arraycopy(modBlock, pos, cachedBlock.fBlock, 0, length);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   793
				}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   794
 			}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   795
			return;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   796
		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   797
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   798
	    /**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   799
		 * @param memoryDMC
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   800
	     * @param address	the memory block address (on the target)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   801
	     * @param word_size	the size, in bytes, of an addressable item
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   802
	     * @param count		the number of bytes to read
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   803
	     * @param drm		the asynchronous data request monitor
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   804
	     */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   805
	    public void getMemory(IMemoryDMContext memoryDMC, final IAddress address, final int word_size, 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   806
	    		final int count, final DataRequestMonitor<MemoryByte[]> drm)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   807
	    {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   808
	    	// Determine the number of read requests to issue 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   809
	    	LinkedList<MemoryBlock> missingBlocks = getListOfMissingBlocks(address, count);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   810
	    	int numberOfRequests = missingBlocks.size();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   811
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   812
	    	// A read request will be issued for each block needed
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   813
	    	// so we need to keep track of the count
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   814
	        final CountingRequestMonitor countingRM =
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   815
	        	new CountingRequestMonitor(getExecutor(), drm) { 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   816
	                @Override
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   817
	                protected void handleSuccess() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   818
	                	// We received everything so read the result from the memory cache
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   819
	                	drm.setData(getMemoryBlockFromCache(address, count));
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   820
	                    drm.done();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   821
	                }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   822
	            };
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   823
	       	countingRM.setDoneCount(numberOfRequests);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   824
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   825
	        // Issue the read requests
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   826
	        for (int i = 0; i < numberOfRequests; i++) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   827
	        	MemoryBlock block = missingBlocks.get(i);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   828
	        	final IAddress startAddress = block.fAddress;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   829
	        	final int length = (int) block.fLength;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   830
		        readMemoryBlock(memoryDMC, startAddress, 0, word_size, length,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   831
					    new DataRequestMonitor<MemoryByte[]>(getSession().getExecutor(), drm) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   832
					    	@Override
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   833
					    	protected void handleSuccess() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   834
					    		MemoryByte[] block = new MemoryByte[count];
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   835
					    		block = getData();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   836
					    		MemoryBlock memoryBlock = new MemoryBlock(startAddress, length, block);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   837
					    		fMemoryBlockList.add(memoryBlock);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   838
					    		countingRM.done();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   839
					    	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   840
					    });
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   841
	        }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   842
	    }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   843
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   844
	    /**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   845
		 * @param memoryDMC
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   846
	     * @param address	the memory block address (on the target)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   847
	     * @param offset	the offset from the start address
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   848
	     * @param word_size	the size, in bytes, of an addressable item
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   849
	     * @param count		the number of bytes to write
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   850
	     * @param buffer	the source buffer
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   851
	     * @param rm		the asynchronous request monitor
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   852
	     */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   853
	   public void setMemory(final IMemoryDMContext memoryDMC, final IAddress address,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   854
			   final long offset, final int word_size, final int count, final byte[] buffer,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   855
			   final RequestMonitor rm)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   856
	   {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   857
	       	writeMemoryBlock(
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   858
	       	    memoryDMC, address, offset, word_size, count, buffer,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   859
				new RequestMonitor(getSession().getExecutor(), rm) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   860
					@Override
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   861
				    protected void handleSuccess() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   862
				    	// Clear the command cache (otherwise we can't guarantee
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   863
						// that the subsequent memory read will be correct) 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   864
						fCommandCache.reset();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   865
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   866
				    	// Re-read the modified memory block to asynchronously update of the memory cache
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   867
				        readMemoryBlock(memoryDMC, address, offset, word_size, count,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   868
					        new DataRequestMonitor<MemoryByte[]>(getExecutor(), rm) { 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   869
					        	@Override
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   870
	                            protected void handleSuccess() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   871
									updateMemoryCache(address.add(offset), count, getData());
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   872
									// Send the MemoryChangedEvent
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   873
									IAddress[] addresses = new IAddress[count];
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   874
									for (int i = 0; i < count; i++) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   875
										addresses[i] = address.add(offset + i);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   876
									}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   877
									getSession().dispatchEvent(new MemoryChangedEvent(memoryDMC, addresses), getProperties());
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   878
									// Finally...
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   879
									rm.done();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   880
					        	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   881
							});
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   882
				    }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   883
				});
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   884
	   }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   885
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   886
 	   /**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   887
 	    * @param memoryDMC
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   888
 	    * @param address
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   889
 	    * @param offset
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   890
 	    * @param word_size
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   891
 	    * @param count
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   892
 	    * @param rm
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   893
 	    */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   894
	   public void refreshMemory(final IMemoryDMContext memoryDMC, final IAddress address,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   895
 			   final long offset, final int word_size, final int count, final RequestMonitor rm)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   896
	   {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   897
		   // Check if we already cache part of this memory area (which means it
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   898
		   // is used by a memory service client that will have to be updated)
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   899
		   LinkedList<MemoryBlock> list = getListOfMissingBlocks(address, count);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   900
		   int sizeToRead = 0;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   901
		   for (MemoryBlock block : list) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   902
			   sizeToRead += block.fLength;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   903
		   }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   904
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   905
		   // If none of the requested memory is in cache, just get out
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   906
		   if (sizeToRead == count) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   907
			   rm.done();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   908
			   return;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   909
		   }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   910
		
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   911
		   // Prepare the data for the MemoryChangedEvent
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   912
		   final IAddress[] addresses = new IAddress[count];
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   913
		   for (int i = 0; i < count; i++) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   914
			   addresses[i] = address.add(i);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   915
		   }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   916
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   917
		   // Read the corresponding memory block
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   918
		   fCommandCache.reset();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   919
		   readMemoryBlock(memoryDMC, address, 0, 1, count,
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   920
				   new DataRequestMonitor<MemoryByte[]>(getExecutor(), rm) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   921
					   @Override
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   922
					   protected void handleSuccess() {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   923
						   MemoryByte[] oldBlock = getMemoryBlockFromCache(address, count);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   924
						   MemoryByte[] newBlock = getData();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   925
						   boolean blocksDiffer = false;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   926
						   for (int i = 0; i < oldBlock.length; i++) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   927
						       if (oldBlock[i].getValue() != newBlock[i].getValue()) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   928
						          blocksDiffer = true;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   929
						          break;
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   930
						       }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   931
						   }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   932
						   if (blocksDiffer) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   933
							   updateMemoryCache(address, count, newBlock);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   934
							   getSession().dispatchEvent(new MemoryChangedEvent(memoryDMC, addresses), getProperties());
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   935
						   }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   936
						   rm.done();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   937
					   }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   938
			   });
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   939
 		}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   940
	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   941
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   942
   /**
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   943
    * {@inheritDoc}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   944
    * @since 1.1
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   945
    */
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   946
    public void flushCache(IDMContext context) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   947
    	fCommandCache.reset(context);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   948
    	
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   949
    	IMemoryDMContext memoryDMC = DMContexts.getAncestorOfType(context, IMemoryDMContext.class);
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   950
    	if (fMemoryCaches.containsKey(memoryDMC)) {
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   951
    		// We do not want to use the call to getMemoryCache() here.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   952
    		// This is because:
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   953
    		// 1- if there is not an entry already , we do not want to automatically 
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   954
    		//    create one, just to call reset() on it.
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   955
    		// 2- if memoryDMC == null, we do not want to create a cache
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   956
    		//    entry for which the key is 'null'
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   957
    		fMemoryCaches.get(memoryDMC).reset();
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   958
    	}
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   959
    }
c2bce6dd59e7 add cdt_6_0_x
cawthron
parents:
diff changeset
   960
}