Changeset 26614 in vbox
- Timestamp:
- Feb 17, 2010 3:03:18 PM (15 years ago)
- Location:
- trunk/src/VBox/Devices/PC
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/PC/ACPI/VBoxAcpi.cpp
r26185 r26614 137 137 return 0; 138 138 } 139 140 /** 141 * Patch the CPU hot-plug SSDT version to 142 * only contain the ACPI containers which may have a CPU 143 */ 144 static int patchAmlCpuHotPlug(PPDMDEVINS pDevIns, uint8_t* pAml, size_t uAmlLen) 145 { 146 uint16_t cNumCpus; 147 int rc; 148 uint32_t idxAml = 0; 149 150 rc = CFGMR3QueryU16Def(pDevIns->pCfg, "NumCPUs", &cNumCpus, 1); 151 152 if (RT_FAILURE(rc)) 153 return rc; 154 155 /** 156 * Now search AML for: 157 * AML_DEVICE_OP (UINT16) 0x5b82 158 * and replace whole block with 159 * AML_NOOP_OP (UINT16) 0xa3 160 * for VCPU not configured 161 */ 162 while (idxAml < uAmlLen - 7) 163 { 164 /* 165 * AML_DEVICE_OP 166 * 167 * DefDevice := DeviceOp PkgLength NameString ObjectList 168 * DeviceOp := ExtOpPrefix 0x82 169 */ 170 if ((pAml[idxAml] == 0x5b) && (pAml[idxAml+1] == 0x82)) 171 { 172 /* Check if the enclosed CPU device is configured. */ 173 uint8_t *pbAmlPkgLength = &pAml[idxAml+2]; 174 uint32_t cBytes = 0; 175 uint32_t cLengthBytesFollow = pbAmlPkgLength[0] >> 6; 176 177 if (cLengthBytesFollow == 0) 178 { 179 /* Simple package length */ 180 cBytes = pbAmlPkgLength[0]; 181 } 182 else 183 { 184 unsigned idxLengthByte = 1; 185 186 cBytes = pbAmlPkgLength[0] & 0xF; 187 188 while (idxLengthByte <= cLengthBytesFollow) 189 { 190 cBytes |= pbAmlPkgLength[idxLengthByte] << (4*idxLengthByte); 191 idxLengthByte++; 192 } 193 } 194 195 uint8_t *pbAmlDevName = &pbAmlPkgLength[cLengthBytesFollow+1]; 196 uint8_t *pbAmlCpu = &pbAmlDevName[4]; 197 bool fCpuConfigured = false; 198 bool fCpuFound = false; 199 200 if ((pbAmlDevName[0] != 'S') || (pbAmlDevName[1] != 'C') || (pbAmlDevName[2] != 'K')) 201 { 202 /* false alarm, not named starting SCK */ 203 idxAml++; 204 continue; 205 } 206 207 for (uint32_t idxAmlCpu = 0; idxAmlCpu < cBytes - 7; idxAmlCpu++) 208 { 209 /* 210 * AML_PROCESSOR_OP 211 * 212 * DefProcessor := ProcessorOp PkgLength NameString ProcID 213 PblkAddr PblkLen ObjectList 214 * ProcessorOp := ExtOpPrefix 0x83 215 * ProcID := ByteData 216 * PblkAddr := DwordData 217 * PblkLen := ByteData 218 */ 219 if ((pbAmlCpu[idxAmlCpu] == 0x5b) && (pbAmlCpu[idxAmlCpu+1] == 0x83)) 220 { 221 if ((pbAmlCpu[idxAmlCpu+4] != 'C') || (pbAmlCpu[idxAmlCpu+5] != 'P')) 222 /* false alarm, not named starting CP */ 223 continue; 224 225 fCpuFound = true; 226 227 /* Processor ID */ 228 if (pbAmlCpu[idxAmlCpu+8] < cNumCpus) 229 { 230 LogFlow(("CPU %d is configured\n", pbAmlCpu[idxAmlCpu+8])); 231 fCpuConfigured = true; 232 break; 233 } 234 else 235 { 236 LogFlow(("CPU %d is not configured\n", pbAmlCpu[idxAmlCpu+8])); 237 fCpuConfigured = false; 238 break; 239 } 240 } 241 } 242 243 Assert(fCpuFound); 244 245 if (!fCpuConfigured) 246 { 247 /* Will fill unwanted CPU block with NOOPs */ 248 /* 249 * See 18.2.4 Package Length Encoding in ACPI spec 250 * for full format 251 */ 252 253 /* including AML_DEVICE_OP itself */ 254 for (uint32_t j = 0; j < cBytes + 2; j++) 255 pAml[idxAml+j] = 0xa3; 256 } 257 258 idxAml++; 259 } 260 else 261 idxAml++; 262 } 263 264 /* now recompute checksum, whole file byte sum must be 0 */ 265 pAml[9] = 0; 266 uint8_t aSum = 0; 267 for (uint32_t i = 0; i < uAmlLen; i++) 268 aSum = aSum + (uint8_t)pAml[i]; 269 pAml[9] = (uint8_t) (0 - aSum); 270 271 return 0; 272 } 139 273 #endif 140 274 … … 290 424 pbAmlCodeSsdt = (uint8_t *)RTMemAllocZ(cbAmlCodeSsdt); 291 425 if (pbAmlCodeSsdt) 426 { 292 427 memcpy(pbAmlCodeSsdt, pbAmlCode, cbAmlCodeSsdt); 428 429 if (fCpuHotPlug) 430 patchAmlCpuHotPlug(pDevIns, pbAmlCodeSsdt, cbAmlCodeSsdt); 431 else 432 patchAml(pDevIns, pbAmlCodeSsdt, cbAmlCodeSsdt); 433 } 293 434 else 294 435 rc = VERR_NO_MEMORY; … … 300 441 if (RT_SUCCESS(rc)) 301 442 { 302 patchAml(pDevIns, pbAmlCodeSsdt, cbAmlCodeSsdt);303 443 *ppPtr = pbAmlCodeSsdt; 304 444 *puSsdtLen = cbAmlCodeSsdt; -
trunk/src/VBox/Devices/PC/DevACPI.cpp
r26594 r26614 2242 2242 /* Disable the CPU */ 2243 2243 VMCPUSET_DEL(&s->CpuSetAttached, iLUN); 2244 s->u32CpuEventType = CPU_EVENT_TYPE_REMOVE; 2245 s->u32CpuEvent = iLUN; 2244 2246 /* Notify the guest */ 2245 2247 update_gpe0(s, s->gpe0_sts | 0x2, s->gpe0_en);
Note:
See TracChangeset
for help on using the changeset viewer.