summaryrefslogtreecommitdiff
path: root/rtl/core/cp15/cp15.sv
blob: 8ddc47406c6ff66ad6b0dab20849ac3928bb0838 (plain)
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
`include "core/cp15/map.sv"
`include "core/mmu/format.sv"
`include "core/uarch.sv"

module core_cp15
(
	input  logic         clk,
	                     rst_n,
	                     transfer,
	input  coproc_decode dec,
	input  word          write,

	output word          read,
	output logic         high_vectors,
	                     mmu_enable,
	output mmu_base      mmu_ttbr
);

	logic load;
	reg_num crn, crm;
	cp_opcode op1, op2;

	assign {crn, crm} = {dec.crn, dec.crm};
	assign {op1, op2} = {dec.op1, dec.op2};
	assign load = dec.load;

	word read_cpuid, read_syscfg, read_ttbr, read_domain,
	     read_far, read_fsr, read_cache_lockdown, read_tlb_lockdown;

	core_cp15_cpuid cpuid
	(
		.read(read_cpuid),
		.*
	);

	core_cp15_syscfg syscfg
	(
		.read(read_syscfg),
		.transfer(transfer && crn == `CP15_CRN_SYSCFG),
		.*
	);

	core_cp15_ttbr ttbr
	(
		.read(read_ttbr),
		.transfer(transfer && crn == `CP15_CRN_TTBR),
		.*
	);

	core_cp15_domain domain
	(
		.read(read_domain),
		.transfer(transfer && crn == `CP15_CRN_DOMAIN),
		.*
	);

	core_cp15_far far
	(
		.read(read_far),
		.transfer(transfer && crn == `CP15_CRN_FAR),
		.*
	);

	core_cp15_far fsr
	(
		.read(read_fsr),
		.transfer(transfer && crn == `CP15_CRN_FSR),
		.*
	);

	core_cp15_cache cache
	(
		.transfer(transfer && crn == `CP15_CRN_CACHE),
		.*
	);

	core_cp15_tlb tlb
	(
		.transfer(transfer && crn == `CP15_CRN_TLB),
		.*
	);

	core_cp15_cache_lockdown cache_lockdown
	(
		.read(read_cache_lockdown),
		.transfer(transfer && crn == `CP15_CRN_CACHE_LCK),
		.*
	);

	core_cp15_tlb_lockdown tlb_lockdown
	(
		.read(read_tlb_lockdown),
		.transfer(transfer && crn == `CP15_CRN_TLB_LCK),
		.*
	);

	always_comb
		unique case(crn)
			`CP15_CRN_CPUID:
				read = read_cpuid;

			`CP15_CRN_SYSCFG:
				read = read_syscfg;

			`CP15_CRN_TTBR:
				read = read_ttbr;

			`CP15_CRN_DOMAIN:
				read = read_domain;

			`CP15_CRN_FAR:
				read = read_far;

			`CP15_CRN_FSR:
				read = read_fsr;

			`CP15_CRN_CACHE_LCK:
				read = read_cache_lockdown;

			`CP15_CRN_TLB_LCK:
				read = read_tlb_lockdown;

			default:
				read = {$bits(read){1'bx}};
		endcase

endmodule