1*** Variables ***
2# Make sure mem1-3 are far apart so that they get stored on 3 different pages
3${MEM1_NAME}        test_mem1
4${MEM2_NAME}        test_mem2
5${MEM3_NAME}        test_mem3
6${MEM1_ADDR}        0x31000000
7${MEM2_ADDR}        0x32000000
8${MEM3_ADDR}        0x33000000
9
10${REPL}=            SEPARATOR=
11...  """                                                                ${\n}
12...  nvic: IRQControllers.NVIC @ sysbus 0xE000E000                      ${\n}
13...  ${SPACE*4}-> cpu@0                                                 ${\n}
14...                                                                     ${\n}
15...  cpu: CPU.CortexM @ sysbus                                          ${\n}
16...  ${SPACE*4}cpuType: "cortex-m4"                                     ${\n}
17...  ${SPACE*4}nvic: nvic                                               ${\n}
18...                                                                     ${\n}
19...  ram: Memory.MappedMemory @ sysbus 0x800000                         ${\n}
20...  ${SPACE*4}size: 0x40000                                            ${\n}
21...                                                                     ${\n}
22...  ${MEM1_NAME}: Memory.MappedMemory @ sysbus ${MEM1_ADDR}            ${\n}
23...  ${SPACE*4}size: 0x1000                                             ${\n}
24...                                                                     ${\n}
25...  ${MEM2_NAME}: Memory.MappedMemory @ sysbus ${MEM2_ADDR}            ${\n}
26...  ${SPACE*4}size: 0x1000                                             ${\n}
27...                                                                     ${\n}
28...  ${MEM3_NAME}: Memory.MappedMemory @ sysbus ${MEM3_ADDR}            ${\n}
29...  ${SPACE*4}size: 0x1000                                             ${\n}
30...  """
31
32${LOG_TIMEOUT}      1
33${PC_START}         0x800000
34
35*** Keywords ***
36Write Thumb Opcode To
37    [Arguments]                 ${dest}         ${opcode}
38    Execute Command             sysbus WriteWord ${dest} ${opcode}
39
40Write Address To
41    [Arguments]                 ${dest}         ${address}
42    Execute Command             sysbus WriteDoubleWord ${dest} ${address}
43
44Prepare Machine
45    Execute Command             mach create
46    Create Log Tester           ${LOG_TIMEOUT}
47    Execute Command             machine LoadPlatformDescriptionFromString ${REPL}
48
49    Execute Command             emulation SingleStepBlocking false
50    Execute Command             sysbus.cpu PC ${PC_START}
51    Execute Command             sysbus LogPeripheralAccess sysbus.${MEM1_NAME}
52    Execute Command             sysbus LogPeripheralAccess sysbus.${MEM2_NAME}
53    Execute Command             sysbus LogPeripheralAccess sysbus.${MEM3_NAME}
54
55Trigger Page Access
56    [Arguments]                 ${MEM}
57    # Set R1 to MEM, then load the value at MEM into R0
58    Execute Command             sysbus.cpu SetRegister 1 ${MEM}
59    Write Thumb Opcode To       ${PC_START}     0x6808    # ldr r0, [r1, #0]
60
61    Execute Command             sysbus.cpu PC ${PC_START}
62    Execute Command             sysbus.cpu Step 1
63
64Should Access Page Via Io
65    [Arguments]                 ${MEM_NAME}         ${MEM}
66    Trigger Page Access         ${MEM}
67    Wait For Log Entry          ${MEM_NAME}: [cpu: ${PC_START}] ReadUInt32 from 0x0 (unknown), returned
68
69Should Not Access Page Via Io
70    [Arguments]                 ${MEM_NAME}         ${MEM}
71    Trigger Page Access         ${MEM}
72    Should Not Be In Log        ${MEM_NAME}: [cpu: ${PC_START}] ReadUInt32 from 0x0 (unknown), returned
73
74
75*** Test Cases ***
76Should Set And Clear Page Access Modes Correctly
77    Prepare Machine
78
79    Wait For Log Entry              cpu: Patching PC ${PC_START} for Thumb mode.
80
81    Should Not Access Page Via Io   ${MEM1_NAME}    ${MEM1_ADDR}
82    Should Not Access Page Via Io   ${MEM2_NAME}    ${MEM2_ADDR}
83    Should Not Access Page Via Io   ${MEM3_NAME}    ${MEM3_ADDR}
84
85    Execute Command                 sysbus SetPageAccessViaIo ${MEM1_ADDR}
86    Should Access Page Via Io       ${MEM1_NAME}    ${MEM1_ADDR}
87    Should Not Access Page Via Io   ${MEM2_NAME}    ${MEM2_ADDR}
88    Should Not Access Page Via Io   ${MEM3_NAME}    ${MEM3_ADDR}
89
90    Execute Command                 sysbus SetPageAccessViaIo ${MEM2_ADDR}
91    Should Access Page Via Io       ${MEM1_NAME}    ${MEM1_ADDR}
92    Should Access Page Via Io       ${MEM2_NAME}    ${MEM2_ADDR}
93    Should Not Access Page Via Io   ${MEM3_NAME}    ${MEM3_ADDR}
94
95    Execute Command                 sysbus SetPageAccessViaIo ${MEM3_ADDR}
96    Should Access Page Via Io       ${MEM1_NAME}    ${MEM1_ADDR}
97    Should Access Page Via Io       ${MEM2_NAME}    ${MEM2_ADDR}
98    Should Access Page Via Io       ${MEM3_NAME}    ${MEM3_ADDR}
99
100    Execute Command                 sysbus ClearPageAccessViaIo ${MEM1_ADDR}
101    Should Not Access Page Via Io   ${MEM1_NAME}    ${MEM1_ADDR}
102    Should Access Page Via Io       ${MEM2_NAME}    ${MEM2_ADDR}
103    Should Access Page Via Io       ${MEM3_NAME}    ${MEM3_ADDR}
104
105    Execute Command                 sysbus ClearPageAccessViaIo ${MEM2_ADDR}
106    Should Not Access Page Via Io   ${MEM1_NAME}    ${MEM1_ADDR}
107    Should Not Access Page Via Io   ${MEM2_NAME}    ${MEM2_ADDR}
108    Should Access Page Via Io       ${MEM3_NAME}    ${MEM3_ADDR}
109
110    Execute Command                 sysbus ClearPageAccessViaIo ${MEM3_ADDR}
111    Should Not Access Page Via Io   ${MEM1_NAME}    ${MEM1_ADDR}
112    Should Not Access Page Via Io   ${MEM2_NAME}    ${MEM2_ADDR}
113    Should Not Access Page Via Io   ${MEM3_NAME}    ${MEM3_ADDR}
114
115    Execute Command                 sysbus SetPageAccessViaIo ${MEM2_ADDR}
116    Should Not Access Page Via Io   ${MEM1_NAME}    ${MEM1_ADDR}
117    Should Access Page Via Io       ${MEM2_NAME}    ${MEM2_ADDR}
118    Should Not Access Page Via Io   ${MEM3_NAME}    ${MEM3_ADDR}
119
120    Execute Command                 sysbus SetPageAccessViaIo ${MEM1_ADDR}
121    Execute Command                 sysbus ClearPageAccessViaIo ${MEM2_ADDR}
122    Execute Command                 sysbus SetPageAccessViaIo ${MEM3_ADDR}
123    Should Access Page Via Io       ${MEM1_NAME}    ${MEM1_ADDR}
124    Should Not Access Page Via Io   ${MEM2_NAME}    ${MEM2_ADDR}
125    Should Access Page Via Io       ${MEM3_NAME}    ${MEM3_ADDR}
126