1 // 2 // Copyright (c) 2010-2018 Antmicro 3 // Copyright (c) 2011-2015 Realtime Embedded 4 // 5 // This file is licensed under the MIT License. 6 // Full license text is available in 'licenses/MIT.txt'. 7 // 8 using System; 9 using System.Linq; 10 using Antmicro.Renode.Utilities; 11 using Antmicro.Renode.Peripherals.Bus; 12 13 namespace Antmicro.Renode.Peripherals.USBDeprecated 14 { 15 public class PortStatusAndControlRegister 16 { PortStatusAndControlRegister()17 public PortStatusAndControlRegister() 18 { 19 } 20 setValue(uint value)21 public PortStatusAndControlRegisterChanges setValue(uint value) 22 { 23 PortStatusAndControlRegisterChanges retVal = new PortStatusAndControlRegisterChanges(); //idicates if interrupt should be rised after this fcn 24 retVal.ConnectChange = false; 25 retVal.EnableChange = false; 26 //uint oldValue = portValue; 27 uint tmpValue = portValue & ~(WriteMask); 28 //if(SystemBus != null) this.Log(LogType.Error,"current PC {0:x}", ((IControllableCPU)SystemBus.GetCPUs().First()).PC); 29 portValue = (value & WriteMask) | tmpValue; 30 if((value & ConnectStatusChange) != 0) 31 { 32 portValue &= ~(ConnectStatusChange); 33 } 34 if((value & PortEnabledDisabledChange) != 0) 35 { 36 portValue &= ~(PortEnabledDisabledChange); 37 } 38 if((value & PortPower) != 0 && (powered == false)) 39 { 40 retVal = this.powerUp(); 41 } 42 if((value & PortReset) != 0) 43 { 44 this.resetRise(); 45 // this.resetFall(); 46 } 47 if(((value & PortReset) == 0) && reset == true) 48 { 49 resetFall(); 50 //retVal.ConnectChange = true; 51 } 52 if((value & PortEnabledDisabled) != 0) 53 { 54 retVal = this.Enable(); 55 } 56 if((portValue & PortEnabledDisabled) == 0) 57 { 58 // if(SystemBus != null) 59 // this.Log(LogType.Error,"zerowanie Enable current PC {0:x}", ((IControllableCPU)SystemBus.GetCPUs().First()).PC); 60 } 61 /* Remove reset bit */ 62 portValue &= ~(0x1000u); 63 return retVal; 64 } 65 checkChanges(uint oldPortVal, uint newPortVal)66 private PortStatusAndControlRegisterChanges checkChanges(uint oldPortVal, uint newPortVal) 67 { 68 var change = new PortStatusAndControlRegisterChanges(); 69 change.ConnectChange = false; 70 change.EnableChange = false; 71 if((oldPortVal & CurrentConnectStatus) != (newPortVal & CurrentConnectStatus)) 72 { 73 change.ConnectChange = true; 74 portValue |= ConnectStatusChange; 75 } 76 if((oldPortVal & PortEnabledDisabled) != (newPortVal & PortEnabledDisabled)) 77 { 78 change.EnableChange = true; 79 portValue |= PortEnabledDisabledChange; 80 } 81 return change; 82 } 83 Attach()84 public PortStatusAndControlRegisterChanges Attach() 85 { 86 uint oldPortValue = portValue; 87 portValue |= CurrentConnectStatus | PortEnabledDisabled | PortEnabledDisabledChange | ConnectStatusChange; 88 attached = true; 89 return checkChanges(oldPortValue, portValue); 90 } 91 Attach(IUSBPeripheral portDevice)92 public PortStatusAndControlRegisterChanges Attach(IUSBPeripheral portDevice) 93 { 94 uint oldPortValue = portValue; 95 portValue |= CurrentConnectStatus | PortEnabledDisabled | PortEnabledDisabledChange | ConnectStatusChange; 96 device = portDevice; 97 attached = true; 98 return checkChanges(oldPortValue, portValue); 99 } 100 Detach()101 public PortStatusAndControlRegisterChanges Detach() 102 { 103 uint oldPortValue = portValue; 104 portValue |= ConnectStatusChange; 105 portValue &= (~CurrentConnectStatus) & (~PortEnabledDisabled); 106 attached = false; 107 return checkChanges(oldPortValue, portValue); 108 } 109 getValue()110 public uint getValue() 111 { 112 if(attached && device != null) 113 if(device.GetSpeed() == USBDeviceSpeed.High) 114 portValue |= HighSpeed; 115 return portValue; 116 } 117 powerUp()118 public PortStatusAndControlRegisterChanges powerUp() 119 { 120 uint oldPortValue = portValue; 121 // portValue |= PortEnabledDisabled | CurrentConnectStatus | PortPower; //TODO: Port Power bit should be dependent on PPC 122 //portValue |= PortEnabledDisabled | PortPower; 123 //powered = true; 124 if(attached) 125 { 126 portValue |= (CurrentConnectStatus); //set connected bit 127 portValue |= (ConnectStatusChange); //clear connect change bit 128 } 129 return checkChanges(oldPortValue, portValue); 130 } 131 Enable()132 public PortStatusAndControlRegisterChanges Enable() 133 { 134 uint oldPortValue = portValue; 135 portValue |= PortEnabledDisabled; 136 return checkChanges(oldPortValue, portValue); 137 } 138 getReset()139 public bool getReset() 140 { 141 return reset; 142 } 143 resetRise()144 public void resetRise() 145 { 146 reset = true; 147 } 148 resetFall()149 public void resetFall() 150 { 151 portValue &= ~(PortReset); //clear reset bit 152 //portValue &= ~(PortPower); //clear power bit 153 if(attached) 154 { 155 portValue |= (CurrentConnectStatus); //set connected bit 156 portValue &= ~(ConnectStatusChange); //clear connect change bit 157 portValue |= (PortEnabledDisabled); //set enable bit 158 portValue &= ~(PortEnabledDisabledChange); 159 if(device != null) 160 device.Reset(); 161 } 162 reset = false; 163 164 } 165 166 private bool reset = false; 167 private bool powered = false; 168 private uint portValue; 169 private bool attached = false; 170 public const uint CurrentConnectStatus = 1 << 0; 171 public const uint ConnectStatusChange = 1 << 1; 172 public const uint PortEnabledDisabled = 1 << 2; 173 public const uint PortEnabledDisabledChange = 1 << 3; 174 public const uint PortReset = 1 << 8; 175 public const uint PortPower = 1 << 12; 176 public const uint HighSpeed = 1 << 27; 177 protected IUSBPeripheral device; 178 //FIXME: correct 179 public const uint WriteMask = 0x007FE1CC; 180 } 181 } 182 183