#ifdef HAVE_CONFIG_H #include #endif #include #include static int failures = 0; #define CHECK(cond,msg) \ do { \ if( !(cond) ) \ { \ fprintf( stderr, "FAIL: %s\n", (msg) ); \ ++failures; \ } \ } while( 0 ) int main( void ) { __mpu_uint32_t psw; __cpu_init(); CHECK( __cpu_pc == 0, "PC after __cpu_init()" ); CHECK( __cpu_sp == 0, "SP after __cpu_init()" ); CHECK( __cpu_fp == 0, "FP after __cpu_init()" ); CHECK( __cpu_get_psw() == 0, "PSW after __cpu_init()" ); /* Verify access to the complete 512 KiB register file. */ __cpu_registers[0] = 0x5a; __cpu_registers[CPU_REGISTERS_MEM_SIZE_IN_UNITS - 1] = 0xa5; CHECK( __cpu_registers[0] == 0x5a, "register file first byte" ); CHECK( __cpu_registers[CPU_REGISTERS_MEM_SIZE_IN_UNITS - 1] == 0xa5, "register file last byte" ); /* Low PSW bits are maintained by LibMPU. */ __mpu_stc(); __mpu_stz(); __mpu_stinx(); psw = __cpu_get_psw(); CHECK( (psw & PSW_CF_MASK) != 0, "PSW reads LibMPU CF" ); CHECK( (psw & PSW_ZF_MASK) != 0, "PSW reads LibMPU ZF" ); CHECK( (psw & PSW_INXF_MASK) != 0, "PSW reads LibMPU INXF" ); /* High PSW bits belong to LibCPU. */ __cpu_sth(); __cpu_stt(); __cpu_sti(); CHECK( __cpu_stmode( 2 ) == 0, "set CPU MODE" ); psw = __cpu_get_psw(); CHECK( (psw & PSW_HF_MASK) != 0, "PSW HF" ); CHECK( (psw & PSW_TF_MASK) != 0, "PSW TF" ); CHECK( (psw & PSW_IF_MASK) != 0, "PSW IF" ); CHECK( __cpu_gtmode() == 2, "PSW MODE" ); /* CPU flag operations do not alter the LibMPU half of PSW. */ __cpu_clh(); __cpu_cmt(); __cpu_cmi(); psw = __cpu_get_psw(); CHECK( (psw & PSW_HF_MASK) == 0, "clear HF" ); CHECK( (psw & PSW_TF_MASK) == 0, "complement TF" ); CHECK( (psw & PSW_IF_MASK) == 0, "complement IF" ); CHECK( (psw & PSW_CF_MASK) != 0, "CF preserved by CPU flags" ); CHECK( (psw & PSW_ZF_MASK) != 0, "ZF preserved by CPU flags" ); CHECK( (psw & PSW_INXF_MASK) != 0, "INXF preserved by CPU flags" ); /* Store/restore the complete logical PSW. */ __cpu_set_psw( PSW_AF_MASK | PSW_OF_MASK | PSW_DOMF_MASK | PSW_HF_MASK | PSW_IF_MASK | ((__mpu_uint32_t)3 << PSW_MODE_SHIFT) ); psw = __cpu_get_psw(); CHECK( psw == (PSW_AF_MASK | PSW_OF_MASK | PSW_DOMF_MASK | PSW_HF_MASK | PSW_IF_MASK | ((__mpu_uint32_t)3 << PSW_MODE_SHIFT)), "complete PSW store/restore" ); CHECK( __mpu_gta() == 1, "LibMPU AF after __cpu_set_psw()" ); CHECK( __mpu_gto() == 1, "LibMPU OF after __cpu_set_psw()" ); CHECK( __mpu_gtdom() == 1, "LibMPU DOMF after __cpu_set_psw()" ); CHECK( __mpu_gtc() == 0, "LibMPU CF cleared by __cpu_set_psw()" ); CHECK( __cpu_gth() == 1, "LibCPU HF after __cpu_set_psw()" ); CHECK( __cpu_gti() == 1, "LibCPU IF after __cpu_set_psw()" ); CHECK( __cpu_gtmode() == 3, "LibCPU MODE after __cpu_set_psw()" ); __cpu_clear_psw(); CHECK( __cpu_get_psw() == 0, "clear complete PSW" ); __cpu_pc = 0x123456789abcdef0ULL; __cpu_sp = 0x0fedcba987654321ULL; __cpu_fp = 0x0123456789abcdefULL; CHECK( __cpu_pc == 0x123456789abcdef0ULL, "PC access" ); CHECK( __cpu_sp == 0x0fedcba987654321ULL, "SP access" ); CHECK( __cpu_fp == 0x0123456789abcdefULL, "FP access" ); __cpu_free_context(); CHECK( __cpu_pc == 0, "PC after __cpu_free_context()" ); CHECK( __cpu_sp == 0, "SP after __cpu_free_context()" ); CHECK( __cpu_fp == 0, "FP after __cpu_free_context()" ); CHECK( __cpu_get_psw() == 0, "PSW after __cpu_free_context()" ); if( failures != 0 ) { fprintf( stderr, "libcpu context regression: %d failure(s)\n", failures ); return( 1 ); } printf( "libcpu context/PSW regression: PASS\n" ); printf( "register file: %u bytes\n", CPU_REGISTERS_MEM_SIZE_IN_UNITS ); printf( "PSW: LibMPU bits 0..15, LibCPU bits 16..20\n" ); return( 0 ); }