1 # SPDX-License-Identifier: LGPL-3-or-later
2 # Copyright 2023 Andrey Miroshnikov
3 # Thanks to NLnet, EU Grant NLnet 2021 cavatools proposal 2021-08-071
6 from openpower
.test
.common
import TestAccumulatorBase
, skip_case
7 from openpower
.endian
import bigendian
8 from openpower
.simulator
.program
import Program
9 #from openpower.decoder.selectable_int import SelectableInt
10 #from openpower.decoder.power_enums import XER_bits
11 #from openpower.decoder.isa.caller import special_sprs
12 from openpower
.consts
import MSR
, DEFAULT_MSR
13 from openpower
.decoder
.helpers
import exts
14 from openpower
.test
.state
import ExpectedState
15 from openpower
.util
import log
16 from pathlib
import Path
20 #from hashlib import sha256
21 #from functools import lru_cache
23 # Page numbers, first number is actual pdf number, second is spec page number
24 # See PowerISA 3.1b Book III, Chapter 4,
25 # section 4.3.1 System Linkage Instructions, page 1186/1160
26 # Book III, chapter 7, section 7.5 Interrupt Definitions, page 1300/1274
27 # PowerISA ABI calling convention doc:
28 # https://git.libre-soc.org/?p=openpower-isa.git;a=blob;f=media/calling-conv;hb=HEAD
29 # 'write' syscall Linux man page:
30 # https://man7.org/linux/man-pages/man2/write.2.html
32 class SysCallTestCase(TestAccumulatorBase
):
34 cia
= 4 # current instruction address (typ. called PC)
38 message
= b
'Hello world!\n'
39 message_len
= len(message
)
40 initial_regs
= [0] * 32
41 initial_regs
[0] = 4 # write syscall, see ppc64 ABI
42 initial_regs
[3] = 1 # fd = 1 (stdout)
43 # The example code stores bits 0-63 of the msg into r4
44 # but message is actually 13 bytes, so just store 8 for now
45 msg_8bytes
= int(message
[0:8].hex(), 16)
46 initial_regs
[4] = msg_8bytes
47 initial_regs
[5] = 8 # message_len
49 initial_sprs
= {'SRR0': 0x0, 'SRR1': 0x0}
50 initial_msr
= DEFAULT_MSR
51 e
= ExpectedState(initial_regs
, pc
=cia
, sprs
=initial_sprs
,
54 # TODO: This one fails...endian-ness error?
55 e
.sprs
['SRR0'] = cia
+4
56 msr_0_32
= initial_msr
& 0x1FFFFFFFF
57 msr_37_41
= (initial_msr
>> 37) & 0x1F
58 msr_48_63
= (initial_msr
>> 48) & 0x0FFFF
59 e
.sprs
['SRR1'] = msr_0_32
+ (msr_37_41
<<37) + (msr_48_63
<<48)
60 #print("Old MSR: %s" % hex(e.msr))
61 #print("Expected SRR1: %s" % hex(e.sprs['SRR1']))
63 # Syscall interrupt MSR value in Section 7.5 of Book III, figure 69
64 # IR DR FE0 FE1 EE RI ME HV S
65 # syscall r r 0 0 0 0 - s u
66 # LPCR (Book III, 2.2) doesn't apply, so IR=DR=0;
68 # for 'sc', LEV=0, thus HV not altered
69 # SMFCTRL_E=1, LEV=2, set to 1; otherwise S not altered. LEV=0.
70 old_ME
= (initial_msr
>> MSR
.ME
) & 1
71 old_HV
= (initial_msr
>> MSR
.HV
) & 1
72 old_S
= (initial_msr
>> MSR
.S
) & 1
73 e
.msr
= (old_ME
<< MSR
.ME
) + (old_HV
<< MSR
.HV
) + (old_S
<< MSR
.S
)
75 # Syscall interrupt defined in Section 7.5 of Book III, figure 70
76 e
.nia
= 0x0000000000000C00
77 # TODO: This one fails...sim gives 0x700 which doesn't make sense
78 # Not sure what the resulting PC is actually meant to be
79 # For now changed to pass (to show SRR0/1 assert errors)
80 e
.pc
= 0x700 # 0x0000000000000C00
82 self
.add_case(Program(lst
, bigendian
), initial_regs
, initial_sprs
,