Unified API of memory map a bit.
This commit is contained in:
@@ -4,6 +4,7 @@ import li.cil.circuity.api.vm.device.memory.MemoryAccessException;
|
||||
import li.cil.circuity.api.vm.device.memory.MemoryMappedDevice;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
/**
|
||||
@@ -20,11 +21,30 @@ public interface MemoryMap {
|
||||
*/
|
||||
OptionalInt findFreeRange(final int start, final int end, final int size);
|
||||
|
||||
/**
|
||||
* Tries to add a new device to the mapping at the specified address.
|
||||
* <p>
|
||||
* This can fail if the new device would overlap a memory range already occupied by
|
||||
* an existing device. In that case this method will return <code>false</code>. Use
|
||||
* {@link #findFreeRange(int, int, int)} to obtain an address the device can be
|
||||
* added at.
|
||||
*
|
||||
* @param address the address to add the device add.
|
||||
* @param device the device to add.
|
||||
* @return <code>true</code> if the device was added; <code>false</code> otherwise.
|
||||
*/
|
||||
boolean addDevice(final int address, final MemoryMappedDevice device);
|
||||
|
||||
/**
|
||||
* Removes a device from the memory map.
|
||||
* <p>
|
||||
* If the device is not in this map this is a no-op.
|
||||
*
|
||||
* @param device the device to remove.
|
||||
*/
|
||||
void removeDevice(final MemoryMappedDevice device);
|
||||
|
||||
int getDeviceAddress(final MemoryMappedDevice device);
|
||||
Optional<MemoryRange> getMemoryRange(final MemoryMappedDevice device);
|
||||
|
||||
@Nullable
|
||||
MemoryRange getMemoryRange(final int address);
|
||||
|
||||
@@ -22,6 +22,14 @@ public final class MemoryRange {
|
||||
this(device, address, address + device.getLength() - 1);
|
||||
}
|
||||
|
||||
public int address() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public final int size() {
|
||||
return end - start + 1;
|
||||
}
|
||||
|
||||
public boolean contains(final int address) {
|
||||
return Integer.compareUnsigned(address, start) >= 0 && Integer.compareUnsigned(address, end) <= 0;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import li.cil.circuity.api.vm.device.memory.MemoryMappedDevice;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
public final class SimpleMemoryMap implements MemoryMap {
|
||||
@@ -65,13 +66,8 @@ public final class SimpleMemoryMap implements MemoryMap {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDeviceAddress(final MemoryMappedDevice device) {
|
||||
final MemoryRange range = devices.get(device);
|
||||
if (range != null) {
|
||||
return range.start;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
public Optional<MemoryRange> getMemoryRange(final MemoryMappedDevice device) {
|
||||
return Optional.ofNullable(devices.get(device));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package li.cil.circuity.vm.devicetree.provider;
|
||||
|
||||
import li.cil.circuity.api.vm.MemoryMap;
|
||||
import li.cil.circuity.api.vm.MemoryRange;
|
||||
import li.cil.circuity.api.vm.device.Device;
|
||||
import li.cil.circuity.api.vm.device.memory.MemoryMappedDevice;
|
||||
import li.cil.circuity.api.vm.devicetree.DeviceTree;
|
||||
@@ -19,7 +20,8 @@ public final class CoreLocalInterrupterProvider implements DeviceTreeProvider {
|
||||
|
||||
@Override
|
||||
public Optional<DeviceTree> createNode(final DeviceTree root, final MemoryMap memoryMap, final Device device, final String deviceName) {
|
||||
return Optional.of(root.find("/soc").getChild(deviceName, memoryMap.getDeviceAddress((MemoryMappedDevice) device)));
|
||||
final Optional<MemoryRange> range = memoryMap.getMemoryRange((MemoryMappedDevice) device);
|
||||
return range.map(r -> root.find("/soc").getChild(deviceName, r.address()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package li.cil.circuity.vm.devicetree.provider;
|
||||
|
||||
import li.cil.circuity.api.vm.MemoryMap;
|
||||
import li.cil.circuity.api.vm.MemoryRange;
|
||||
import li.cil.circuity.api.vm.device.Device;
|
||||
import li.cil.circuity.api.vm.device.memory.MemoryMappedDevice;
|
||||
import li.cil.circuity.api.vm.devicetree.DeviceTree;
|
||||
@@ -14,15 +15,18 @@ public class MemoryMappedDeviceProvider implements DeviceTreeProvider {
|
||||
|
||||
@Override
|
||||
public Optional<DeviceTree> createNode(final DeviceTree root, final MemoryMap memoryMap, final Device device, final String deviceName) {
|
||||
return Optional.of(root.getChild(deviceName, memoryMap.getDeviceAddress((MemoryMappedDevice) device)));
|
||||
final Optional<MemoryRange> range = memoryMap.getMemoryRange((MemoryMappedDevice) device);
|
||||
return range.map(r -> root.getChild(deviceName, r.address()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(final DeviceTree node, final MemoryMap memoryMap, final Device device) {
|
||||
final MemoryMappedDevice mappedDevice = (MemoryMappedDevice) device;
|
||||
final Optional<MemoryRange> range = memoryMap.getMemoryRange(mappedDevice);
|
||||
|
||||
// TODO in the future when we may want to change bus widths check parent for cell and size cell num.
|
||||
node.addProp(DeviceTreePropertyNames.REG,
|
||||
((long) memoryMap.getDeviceAddress(mappedDevice)) & 0xFFFFFFFFL,
|
||||
((long) mappedDevice.getLength()) & 0xFFFFFFFFL);
|
||||
range.ifPresent(r -> node.addProp(DeviceTreePropertyNames.REG,
|
||||
((long) r.address()) & 0xFFFFFFFFL,
|
||||
((long) r.size()) & 0xFFFFFFFFL));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,6 @@ public class PhysicalMemoryProvider implements DeviceTreeProvider {
|
||||
|
||||
@Override
|
||||
public void visit(final DeviceTree node, final MemoryMap memoryMap, final Device device) {
|
||||
node.addProp(DeviceTreePropertyNames.DEVICE_TYPE, "memory");
|
||||
node.addProp(DeviceTreePropertyNames.DEVICE_TYPE, DeviceNames.MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package li.cil.circuity.vm.devicetree.provider;
|
||||
|
||||
import li.cil.circuity.api.vm.MemoryMap;
|
||||
import li.cil.circuity.api.vm.MemoryRange;
|
||||
import li.cil.circuity.api.vm.device.Device;
|
||||
import li.cil.circuity.api.vm.device.memory.MemoryMappedDevice;
|
||||
import li.cil.circuity.api.vm.devicetree.DeviceNames;
|
||||
@@ -21,7 +22,8 @@ public final class PlatformLevelInterruptControllerProvider implements DeviceTre
|
||||
|
||||
@Override
|
||||
public Optional<DeviceTree> createNode(final DeviceTree root, final MemoryMap memoryMap, final Device device, final String deviceName) {
|
||||
return Optional.of(root.find("/soc").getChild(deviceName, memoryMap.getDeviceAddress((MemoryMappedDevice) device)));
|
||||
final Optional<MemoryRange> range = memoryMap.getMemoryRange((MemoryMappedDevice) device);
|
||||
return range.map(r -> root.find("/soc").getChild(deviceName, r.address()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user