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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
/*
* SPDX-FileCopyrightText: (c) 2025-2026 Tenstorrent USA, Inc.
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <sbi/sbi_error.h>
#include <sbi/sbi_console.h>
#include <sbi/sbi_math.h>
#include <libfdt.h>
#include <sbi_utils/fdt/fdt_helper.h>
#include <tenstorrent/pma.h>
/*
* All PMAs in the system should be the same (after boot). The init code
* must have set PMAs for all HARTs.
*/
/*
* Ascalon CPU and IOMMU PMA layout:
* Field
* [2:0] Permission [0] Read, [1] Write, [2] Execute
* [4:3] Memory type 00: Main memory, 01: IO memory relaxed,
* 10: IO memory channel 0, 11: IO memory channel 1
* [6:5] AMO type 00: AMONone, 01: AMOSwap,
* 10: AMOLogical, 11: AMOArithmetic
* [7] Cacheability (main memory type)
* 1: Cacheable, 0: Non-cacheable
* Combining Capability (IO memory type)
* 1: Combining allowed, 0: Combining disallowed
* [8] Routing (coherency)
* 1: Coherent network, 0: Non-coherent network
* [11:9] Reserved
* [51:12] Physical address [51:12] base
* [63:58] Size log 2 (number of address LSB to ignore when matching)
* 0 = invalid entry (no match)
*/
#define PMA_PERMISSION_R 0x1
#define PMA_PERMISSION_W 0x2
#define PMA_PERMISSION_X 0x4
#define PMA_PERMISSION_MASK 0x7
#define PMA_TYPE_MAIN_MEMORY 0x0
#define PMA_TYPE_IO_RELAXED 0x8
#define PMA_TYPE_IO_ORDERED_0 0x10
#define PMA_TYPE_IO_ORDERED_1 0x18
#define PMA_TYPE_MASK 0x18
#define PMA_AMO_NONE 0x0
#define PMA_AMO_SWAP 0x20
#define PMA_AMO_LOGICAL 0x40
#define PMA_AMO_ARITHMETIC 0x60
#define PMA_AMO_MASK 0x60
#define PMA_MEMORY_CACHEABLE 0x80
#define PMA_IO_COMBINING 0x80
#define PMA_ROUTING_COHERENT 0x100
#define PMA_FLAGS_MASK 0x00000000000001ffULL
#define PMA_ADDRESS_MASK 0x000ffffffffff000ULL
#define PMA_SIZE_MASK 0xfc00000000000000ULL
#define PMA_RESERVED_MASK 0x0300000000000e00ULL
#define PMA_SIZE_SHIFT 58
static u64 tt_pma_size(u64 pma)
{
if ((pma & PMA_SIZE_MASK) == 0)
return 0;
return 1ULL << ((pma & PMA_SIZE_MASK) >> PMA_SIZE_SHIFT);
}
static u64 tt_pma_address(u64 pma)
{
return (pma & PMA_ADDRESS_MASK) & ~((tt_pma_size(pma) - 1));
}
bool tt_pma_validate(unsigned int i, u64 pma)
{
if (!pma)
return true;
if (pma & PMA_RESERVED_MASK) {
sbi_printf("PMA%02u 0x%016lx contains reserved bits\n", i, pma);
return false;
}
if (tt_pma_size(pma) < 4096) {
sbi_printf("PMA%02u 0x%016lx size < 4KB\n", i, pma);
return false;
}
if (tt_pma_address(pma) != (pma & PMA_ADDRESS_MASK)) {
sbi_printf("PMA%02u 0x%016lx address is not aligned to size\n", i, pma);
return false;
}
return true;
}
void tt_pma_print(unsigned int i, u64 pma)
{
sbi_printf("PMA%02d : 0x%016lx-0x%016lx perm:%s%s%s type:%s %s %s amo:%s\n", i,
tt_pma_address(pma), tt_pma_address(pma) + tt_pma_size(pma) - 1,
pma & PMA_PERMISSION_R ? "R" : " ",
pma & PMA_PERMISSION_W ? "W" : " ",
pma & PMA_PERMISSION_X ? "X" : " ",
(pma & PMA_TYPE_MASK) == PMA_TYPE_MAIN_MEMORY ? "main-memory" :
((pma & PMA_TYPE_MASK) == PMA_TYPE_IO_RELAXED ? "io-relaxed" :
((pma & PMA_TYPE_MASK) == PMA_TYPE_IO_ORDERED_0 ? "io-ordered-0" : "io-ordered-1")),
(pma & PMA_TYPE_MASK) == PMA_TYPE_MAIN_MEMORY ?
(pma & PMA_MEMORY_CACHEABLE ? "cacheable" : "non-cacheable") :
(pma & PMA_IO_COMBINING ? "combining" : "non-combining"),
pma & PMA_ROUTING_COHERENT ? "coherent" : "non-coherent",
(pma & PMA_AMO_MASK) == PMA_AMO_NONE ? "none" :
((pma & PMA_AMO_MASK) == PMA_AMO_SWAP ? "swap" :
((pma & PMA_AMO_MASK) == PMA_AMO_LOGICAL ? "logical" : "arithmetic")));
}
static u64 pmas[TT_MAX_PMAS];
void tt_pma_set(unsigned int n, u64 pma)
{
if (n >= TT_MAX_PMAS)
sbi_panic("PMA exceeded TT_MAX_PMAS");
pmas[n] = pma;
}
u64 tt_pma_get(unsigned int n)
{
if (n >= TT_MAX_PMAS)
sbi_panic("PMA exceeded TT_MAX_PMAS");
return pmas[n];
}
|