summaryrefslogtreecommitdiff
path: root/tests/tst-context.c
blob: 6384d7523f27bf8e94231d297d734d345b409787 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>

#include <libmcpu.h>


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 );
}