OpenCores
URL https://opencores.org/ocsvn/zap/zap/trunk

Subversion Repositories zap

[/] [zap/] [trunk/] [src/] [rtl/] [cpu/] [zap_tlb_check.v] - Blame information for rev 51

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 Revanth
// -----------------------------------------------------------------------------
2
// --                                                                         --
3
// --                   (C) 2016-2018 Revanth Kamaraj.                        --
4
// --                                                                         -- 
5
// -- --------------------------------------------------------------------------
6
// --                                                                         --
7
// -- This program is free software; you can redistribute it and/or           --
8
// -- modify it under the terms of the GNU General Public License             --
9
// -- as published by the Free Software Foundation; either version 2          --
10
// -- of the License, or (at your option) any later version.                  --
11
// --                                                                         --
12
// -- This program is distributed in the hope that it will be useful,         --
13
// -- but WITHOUT ANY WARRANTY; without even the implied warranty of          --
14
// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           --
15
// -- GNU General Public License for more details.                            --
16
// --                                                                         --
17
// -- You should have received a copy of the GNU General Public License       --
18
// -- along with this program; if not, write to the Free Software             --
19
// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA           --
20
// -- 02110-1301, USA.                                                        --
21
// --                                                                         --
22
// -----------------------------------------------------------------------------
23
// --                                                                         -- 
24
// --  Examines TLB entries to authorize access. Purely combo logic.          --                     
25
// --                                                                         --  
26
// -----------------------------------------------------------------------------
27
 
28
`default_nettype none
29
 
30
module zap_tlb_check (   // ZAP TLB Processing Logic.
31
 
32
i_mmu_en,       // MMU enable.
33
 
34
// Dynamics
35
i_va,           // Virtual address.
36
i_rd,           // WB rd.
37
i_wr,           // WB wr.
38
 
39
// Static almost.
40
i_cpsr,
41
i_sr,
42
i_dac_reg,
43
 
44
// Data from TLB dist RAMs.
45
i_sptlb_rdata, i_sptlb_rdav,
46
i_lptlb_rdata, i_lptlb_rdav,
47
i_setlb_rdata, i_setlb_rdav,
48
 
49
// Outputs to other units.
50
o_walk,                 // Need to page walk.
51
o_fsr,                  // FSR.
52
o_far,                  // FAR. 0 means no fault. This is a 4-bit number.
53
o_cacheable,            // Cacheable based on PTE.
54
o_phy_addr              // Physical address.
55
 
56
);
57
 
58
// Pass this from top.
59
parameter LPAGE_TLB_ENTRIES   = 8;
60
parameter SPAGE_TLB_ENTRIES   = 8;
61
parameter SECTION_TLB_ENTRIES = 8;
62
 
63
`include "zap_localparams.vh"
64
`include "zap_defines.vh"
65
`include "zap_functions.vh"
66
 
67
input wire                              i_mmu_en;       // MMU enable.
68
 
69
input wire [31:0]                       i_va;           // Virtual address.
70
input wire                              i_rd;           // Read request.
71
input wire                              i_wr;           // Write request.
72
 
73
input wire [31:0]                       i_cpsr;         // CPSR.
74
input wire [1:0]                        i_sr;           // Status Register.
75
input wire [31:0]                       i_dac_reg;      // Domain Access Control Register.
76
 
77
input wire [`SPAGE_TLB_WDT  -1:0]       i_sptlb_rdata;  // Small page TLB.              
78
input wire                              i_sptlb_rdav;   // TLB entry valid.
79
 
80
input wire [`LPAGE_TLB_WDT  -1:0]       i_lptlb_rdata;  // Large page TLB read data.
81
input wire                              i_lptlb_rdav;   // Large page TLB valid.
82
 
83
input wire [`SECTION_TLB_WDT-1:0]       i_setlb_rdata;  // Small page TLB read data.
84
input wire                              i_setlb_rdav;   // Small page TLB valid.
85
 
86
output reg                              o_walk;         // Signal page walk.
87
output reg [7:0]                        o_fsr;          // FSR. 0 means all OK.
88
output reg [31:0]                       o_far;          // Fault Address Register.
89
output reg                              o_cacheable;    // Cacheble stats of the PTE.
90
output reg [31:0]                       o_phy_addr;     // Physical address.
91
 
92 51 Revanth
// ----------------------------------------------------------------------------
93
 
94 26 Revanth
always @*
95
begin
96
        // Default values. Taken for MMU disabled esp.
97
        o_fsr       = 0;        // No fault.
98
        o_far       = i_va;     // Fault address.
99
        o_phy_addr  = i_va;     // VA = PA
100
        o_walk      = 0;        // Walk disabled.
101
        o_cacheable = 0;        // Uncacheable.
102
 
103
        if ( i_mmu_en && (i_rd|i_wr) ) // MMU enabled.
104
        begin
105
                if ( (i_sptlb_rdata[`SPAGE_TLB__TAG] == i_va[`VA__SPAGE_TAG]) && i_sptlb_rdav )
106
                begin
107
                        // Entry found in small page TLB.
108
                        o_fsr = get_fsr
109
                        (
110
                                1'd0, 1'd1, 1'd0,               // Small page.
111
                                i_va[`VA__SPAGE_AP_SEL],
112
                                i_cpsr[4:0] == USR,
113
                                i_rd,
114
                                i_wr,
115
                                i_sr,
116
                                i_dac_reg,
117
                                i_sptlb_rdata
118
                        ) ;
119
 
120
                        o_phy_addr = {i_sptlb_rdata[`SPAGE_TLB__BASE],
121
                                      i_va[11:0]};
122
 
123
                        o_cacheable = i_sptlb_rdata[`SECTION_TLB__CB] >> 1;
124
 
125
                end
126
                else if ( (i_lptlb_rdata[`LPAGE_TLB__TAG] == i_va[`VA__LPAGE_TAG]) && i_lptlb_rdav )
127
                begin
128
                        // Entry found in large page TLB.
129
                        o_fsr = get_fsr
130
                        (
131
                                1'd0, 1'd0, 1'd1,               // Large page.
132
                                i_va[`VA__LPAGE_AP_SEL],
133
                                i_cpsr[4:0] == USR,
134
                                i_rd,
135
                                i_wr,
136
                                i_sr,
137
                                i_dac_reg,
138
                                i_lptlb_rdata
139
                        ) ;
140
 
141
                        o_phy_addr = {i_lptlb_rdata[`LPAGE_TLB__BASE],
142
                                        i_va[15:0]};
143
 
144
                        o_cacheable = i_lptlb_rdata[`LPAGE_TLB__CB] >> 1;
145
                end
146
                else if ( (i_setlb_rdata[`SECTION_TLB__TAG] == i_va[`VA__SECTION_TAG]) && i_setlb_rdav )
147
                begin
148
                        // Entry found in section TLB.
149
                        o_fsr = get_fsr
150
                        (
151
                                1'd1, 1'd0, 1'd0,               // Section.
152 28 Revanth
                                2'd0,                           // DONT CARE. Sections do not further divisions in AP SEL.
153 26 Revanth
                                i_cpsr[4:0] == USR,
154
                                i_rd,
155
                                i_wr,
156
                                i_sr,
157
                                i_dac_reg,
158
                                i_setlb_rdata
159
                        ) ;
160
 
161
                        o_phy_addr = {i_setlb_rdata[`SECTION_TLB__BASE],
162
                                        i_va[19:0]};
163
 
164
                        o_cacheable = i_setlb_rdata[`SECTION_TLB__CB] >> 1;
165
                end
166
                else
167
                begin
168
                        // Trigger TLB walk.
169
                        o_walk = 1'd1;
170
                end
171
        end // Else MMU disabled.
172
end
173
 
174
// ----------------------------------------------------------------------------
175
 
176
function  [7:0] get_fsr ( // Return 0 means OK to access else is a valid FSR.
177
input                   section, spage, lpage,  // Select one.
178
input   [1:0]           ap_sel,                 // AP sel bits. dont care for sections.
179
input                   user, rd, wr,           // Access properties.
180
input [1:0]             sr,                     // S and R bits.
181
input [31:0]            dac_reg,                // DAC register.
182
input [63:0]            tlb                     // TLB entry.
183
);
184
 
185
reg [3:0] apsr; // Concat of AP and SR.
186
reg [1:0] dac;  // DAC bits.
187
 
188
begin
189
        if ( section )
190
        begin
191
                apsr = (tlb  [ `SECTION_TLB__AP ]) >> (section ? 0 : (ap_sel << 1));
192
                dac  = (dac_reg >> (tlb  [ `SECTION_TLB__DAC_SEL ] << 1));
193
        end
194
        else if ( spage )
195
        begin
196
                apsr = (tlb  [ `SPAGE_TLB__AP ]) >> (section ? 0 : (ap_sel << 1));
197
                dac  = (dac_reg >> (tlb  [ `SPAGE_TLB__DAC_SEL ] << 1));
198
        end
199
        else // large page.
200
        begin
201
                apsr = (tlb  [ `LPAGE_TLB__AP ]) >> (section ? 0 : (ap_sel << 1));
202
                dac  = (dac_reg >> (tlb  [ `LPAGE_TLB__DAC_SEL ] << 1));
203
        end
204
 
205
        case(dac)
206
        DAC_MANAGER: get_fsr = 0; // No fault.
207
 
208
        DAC_CLIENT : get_fsr = is_apsr_ok ( user, rd, wr, apsr ) ? 0 :
209
        (
210
         section ? {tlb[`SECTION_TLB__DAC_SEL], FSR_SECTION_PERMISSION_FAULT}:
211
         spage   ? {tlb[`SPAGE_TLB__DAC_SEL]  , FSR_PAGE_PERMISSION_FAULT   }:
212
                   {tlb[`LPAGE_TLB__DAC_SEL]  , FSR_PAGE_PERMISSION_FAULT   }
213
        );
214
 
215
        default    : get_fsr =
216
        section ?    {tlb[`SECTION_TLB__DAC_SEL], FSR_SECTION_DOMAIN_FAULT} :
217
        spage   ?    {tlb[`SPAGE_TLB__DAC_SEL],   FSR_PAGE_DOMAIN_FAULT   } :
218
                     {tlb[`LPAGE_TLB__DAC_SEL],   FSR_PAGE_DOMAIN_FAULT   } ;
219
        endcase
220
end
221
 
222
endfunction
223
 
224
// ----------------------------------------------------------------------------
225
 
226
// 
227
// Function to check APSR bits.
228
// 
229
// Returns 0 for failure, 1 for okay.
230
// Checks AP and SR bits.
231
//
232
 
233
localparam APSR_BAD = 1'd0;
234
localparam APSR_OK  = 1'd1;
235
 
236
function  is_apsr_ok ( input user, input rd, input wr, input [3:0] apsr);
237
reg x;
238
begin
239
        x = APSR_BAD; // Assume fail.
240
 
241
        casez (apsr)
242
                APSR_NA_NA: x = APSR_BAD;               // No access.
243
                APSR_RO_RO: x = !wr;                    // Reads allowed for all.
244
                APSR_RO_NA: x = !user && rd;            // Only kernel reads.
245
                APSR_RW_NA: x = !user;                  // Only kernel access.
246
                APSR_RW_RO: x = !user | (user && rd);   // User RO, Kernel RW.
247
                APSR_RW_RW: x = APSR_OK;                // Grant all the time.
248
                default   : x = APSR_BAD;               // Deny all the time.
249
        endcase
250
 
251
        // Assign to function. Return.
252
        is_apsr_ok = x;
253
end
254
endfunction
255
 
256 51 Revanth
endmodule // zap_tlb_check.v
257 26 Revanth
 
258
`default_nettype wire
259 51 Revanth
 
260
// ----------------------------------------------------------------------------
261
// EOF
262
// ----------------------------------------------------------------------------

powered by: WebSVN 2.1.0

© copyright 1999-2022 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.