/* SPDX-License-Identifier: MIT */ #include #include #include #include #include "../compat/cpu.h" static unsigned checks; #define CHECK(x) do { checks++; if (!(x)) { \ fprintf(stderr,"line %d: %s\n",__LINE__,#x); exit(1); } } while (0) static const uint64_t pa=UINT64_C(0x8cec80000),va=UINT64_C(0xfffffe010ec80000); static const uint64_t low=UINT64_C(0x8c0000000),high=UINT64_C(0xac0000000); static const uint64_t affinity[6]={0,1,2,3,0x100,0x101}; int main(void) { struct guest_cpu_registry cpus={0}; uint64_t slot=99; struct guest_cpu_buffer buffer={11,22}; CHECK(guest_cpu_buffers_valid(pa,va,low,high)); CHECK(guest_cpu_id(&cpus,0,&slot)==CPU_NOT_REGISTERED && slot==99); CHECK(guest_cpu_output(&cpus,0,pa,va,low,high,&buffer)==CPU_NOT_REGISTERED); CHECK(buffer.pa==11 && buffer.va==22 && !cpus.output_queries); for(unsigned i=0;i<6;i++) { CHECK(guest_cpu_register(&cpus,affinity[i])==CPU_OK); CHECK(cpus.registered==((UINT64_C(1)<<(i+1))-1)); CHECK(guest_cpu_id(&cpus,affinity[i],&slot)==CPU_OK && slot==i); CHECK(guest_cpu_output(&cpus,slot,pa,va,low,high,&buffer)==CPU_OK); CHECK(buffer.pa==pa+i*GUEST_CPU_SCRATCH_STRIDE); CHECK(buffer.va==va+i*GUEST_CPU_SCRATCH_STRIDE); } CHECK(cpus.registrations==6 && cpus.id_queries==6 && cpus.output_queries==6); CHECK(guest_cpu_register(&cpus,0x101)==CPU_OK && cpus.registered==63); CHECK(cpus.registrations==7); /* Repeat announcement is idempotent metadata. */ for(uint64_t id=0;id<0x20000;id++) { struct guest_cpu_registry before=cpus; slot=99; enum guest_cpu_result r=guest_cpu_id(&cpus,id,&slot); if(id<4 || id==0x100 || id==0x101) { CHECK(r==CPU_OK && slot==(id<4?id:id-0x100+4)); } else { CHECK(r==CPU_BAD_AFFINITY && slot==99); CHECK(!memcmp(&cpus,&before,sizeof(cpus))); CHECK(guest_cpu_register(&cpus,id)==CPU_BAD_AFFINITY); CHECK(!memcmp(&cpus,&before,sizeof(cpus))); } } for(unsigned i=0;i<64;i++) { uint64_t bad=(UINT64_C(1)<