| 227 | } |
| 228 | |
| 229 | int |
| 230 | platform_start_ap(int cpuid) |
| 231 | { |
| 232 | uint32_t reg; |
| 233 | int timeout; |
| 234 | |
| 235 | /* Enter into configuration */ |
| 236 | reg = read_c0_register32(0, 1); |
| 237 | reg |= (MVPCONTROL_VPC); |
| 238 | write_c0_register32(0, 1, reg); |
| 239 | |
| 240 | set_thread_context(cpuid); |
| 241 | |
| 242 | /* |
| 243 | * Hint: how to set entry point. |
| 244 | * reg = 0x80000000; |
| 245 | * mttc0(2, 3, reg); |
| 246 | */ |
| 247 | |
| 248 | /* Enable thread */ |
| 249 | reg = mftc0(2, 1); |
| 250 | reg |= (TCSTATUS_A); |
| 251 | mttc0(2, 1, reg); |
| 252 | |
| 253 | /* Unhalt CPU core */ |
| 254 | mttc0(2, 4, 0); |
| 255 | |
| 256 | /* Activate VPE */ |
| 257 | reg = mftc0(1, 2); |
| 258 | reg |= (VPECONF0_VPA); |
| 259 | mttc0(1, 2, reg); |
| 260 | |
| 261 | /* Out of configuration */ |
| 262 | reg = read_c0_register32(0, 1); |
| 263 | reg &= ~(MVPCONTROL_VPC); |
| 264 | write_c0_register32(0, 1, reg); |
| 265 | |
| 266 | evpe(); |
| 267 | |
| 268 | if (atomic_cmpset_32(&malta_ap_boot, ~0, cpuid) == 0) |
| 269 | return (-1); |
| 270 | |
| 271 | printf("Waiting for cpu%d to start\n", cpuid); |
| 272 | |
| 273 | timeout = 100; |
| 274 | do { |
| 275 | DELAY(1000); |
| 276 | if (atomic_cmpset_32(&malta_ap_boot, 0, ~0) != 0) { |
| 277 | printf("CPU %d started\n", cpuid); |
| 278 | return (0); |
| 279 | } |
| 280 | } while (timeout--); |
| 281 | |
| 282 | printf("CPU %d failed to start\n", cpuid); |
| 283 | |
| 284 | return (0); |
| 285 | } |
no test coverage detected