blob: 4af0c7a508ef6c6cd18f133c09e313ae7bcc7557 [file] [log] [blame]
Andrew Scull7fd4bb72018-12-08 23:40:12 +00001/*
2 * Copyright 2018 Google LLC
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "hf/mm.h"
18
19#include "hf/arch/mm.h"
20
21#include "hftest.h"
22
23/** There must be at least two levels in the page table. */
24#define MAX_LEVEL_LOWER_BOUND 1
25
26/**
27 * This is the number of levels that are tested and is constrained as it
28 * controls the depth of recursion in the memory management code.
29 */
30#define MAX_LEVEL_UPPER_BOUND 3
31
32/** X macro to expand tests for all levels. */
33#define EXPAND_LEVEL_TESTS \
34 LEVEL_TEST(0) \
35 LEVEL_TEST(1) \
36 LEVEL_TEST(2) \
37 LEVEL_TEST(3)
38
39/* TODO: work out how to run these test against the host fake arch. */
40
41/**
42 * A block must be allowed at level 0 as this is the level which represents
43 * pages.
44 */
45TEST(arch_mm, block_allowed_at_level0)
46{
47 ASSERT_TRUE(arch_mm_is_block_allowed(0));
48}
49
50/**
51 * The maximum level must be within acceptable bounds.
52 */
53TEST(arch_mm, max_level_stage1)
54{
55 int mode = MM_MODE_STAGE1;
56 uint8_t max_level = arch_mm_max_level(mode);
57 EXPECT_GE(max_level, MAX_LEVEL_LOWER_BOUND);
58 EXPECT_LE(max_level, MAX_LEVEL_UPPER_BOUND);
59}
60
61/* TODO: initialize arch_mm and check max level of stage-2. */
62
63/**
64 * A block is present and mutually exclusive from a table.
65 */
66#define LEVEL_TEST(lvl) \
67 TEST(arch_mm, block_properties_level##lvl) \
68 { \
69 uint8_t level = lvl; \
70 uint64_t attrs = arch_mm_mode_to_attrs(0); \
71 pte_t block_pte; \
72 \
73 /* Test doesn't apply if a block is not allowed. */ \
74 if (!arch_mm_is_block_allowed(level)) { \
75 return; \
76 } \
77 \
78 block_pte = arch_mm_block_pte(level, pa_init(0x12345678000), \
79 attrs); \
80 \
81 EXPECT_TRUE(arch_mm_pte_is_present(block_pte, level)); \
82 EXPECT_TRUE(arch_mm_pte_is_block(block_pte, level)); \
83 EXPECT_FALSE(arch_mm_pte_is_table(block_pte, level)); \
84 }
85EXPAND_LEVEL_TESTS
86#undef LEVEL_TEST