summaryrefslogtreecommitdiff
path: root/rtl/core
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2022-12-10 19:36:38 -0600
committerAlejandro Soto <alejandro@34project.org>2022-12-10 19:36:38 -0600
commit8026947ecdf9b023c3720b26bf257bf46f7a2805 (patch)
tree8b2fbd0beb29c575730a76b010e8aa35977d5417 /rtl/core
parent02f76bae32e295bf1da04e38dfa12dfbc5832aec (diff)
Implement rest of cp15 registers
Diffstat (limited to 'rtl/core')
-rw-r--r--rtl/core/cp15/cache.sv15
-rw-r--r--rtl/core/cp15/cache_lockdown.sv18
-rw-r--r--rtl/core/cp15/cp15.sv94
-rw-r--r--rtl/core/cp15/domain.sv24
-rw-r--r--rtl/core/cp15/far.sv27
-rw-r--r--rtl/core/cp15/fsr.sv20
-rw-r--r--rtl/core/cp15/map.sv46
-rw-r--r--rtl/core/cp15/syscfg.sv66
-rw-r--r--rtl/core/cp15/tlb.sv15
-rw-r--r--rtl/core/cp15/tlb_lockdown.sv18
-rw-r--r--rtl/core/cp15/ttbr.sv45
-rw-r--r--rtl/core/mmu/format.sv20
12 files changed, 402 insertions, 6 deletions
diff --git a/rtl/core/cp15/cache.sv b/rtl/core/cp15/cache.sv
new file mode 100644
index 0000000..cb6d4ad
--- /dev/null
+++ b/rtl/core/cp15/cache.sv
@@ -0,0 +1,15 @@
+`include "core/uarch.sv"
+
+module core_cp15_cache
+(
+ input logic clk,
+ rst_n,
+
+ input logic load,
+ transfer,
+ input word write
+);
+
+ //TODO
+
+endmodule
diff --git a/rtl/core/cp15/cache_lockdown.sv b/rtl/core/cp15/cache_lockdown.sv
new file mode 100644
index 0000000..65d4c0f
--- /dev/null
+++ b/rtl/core/cp15/cache_lockdown.sv
@@ -0,0 +1,18 @@
+`include "core/uarch.sv"
+
+module core_cp15_cache_lockdown
+(
+ input logic clk,
+ rst_n,
+
+ input logic load,
+ transfer,
+ input word write,
+
+ output word read
+);
+
+ //TODO, aunque al parecer Linux no usa esto
+ assign read = 0;
+
+endmodule
diff --git a/rtl/core/cp15/cp15.sv b/rtl/core/cp15/cp15.sv
index 907576a..f924c21 100644
--- a/rtl/core/cp15/cp15.sv
+++ b/rtl/core/cp15/cp15.sv
@@ -13,15 +13,15 @@ module core_cp15
);
logic load;
- reg_num crm;
+ 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;
- assign crm = dec.crm;
- assign op1 = dec.op1;
- assign op2 = dec.op2;
- word read_cpuid;
+ word read_cpuid, read_syscfg, read_ttbr, read_domain,
+ read_far, read_fsr, read_cache_lockdown, read_tlb_lockdown;
core_cp15_cpuid cpuid
(
@@ -29,11 +29,93 @@ module core_cp15
.*
);
+ 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(dec.crn)
+ 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
diff --git a/rtl/core/cp15/domain.sv b/rtl/core/cp15/domain.sv
new file mode 100644
index 0000000..4e5f5d6
--- /dev/null
+++ b/rtl/core/cp15/domain.sv
@@ -0,0 +1,24 @@
+`include "core/uarch.sv"
+
+module core_cp15_domain
+(
+ input logic clk,
+ rst_n,
+
+ input logic load,
+ transfer,
+ input word write,
+
+ output word read
+);
+
+ word dac;
+ assign read = dac;
+
+ always @(posedge clk or negedge rst_n)
+ if(!rst_n)
+ dac <= 0;
+ else if(transfer && !load)
+ dac <= write;
+
+endmodule
diff --git a/rtl/core/cp15/far.sv b/rtl/core/cp15/far.sv
new file mode 100644
index 0000000..b90dc0f
--- /dev/null
+++ b/rtl/core/cp15/far.sv
@@ -0,0 +1,27 @@
+`include "core/uarch.sv"
+`include "core/cp15/map.sv"
+
+module core_cp15_far
+(
+ input logic clk,
+ rst_n,
+
+ input logic load,
+ transfer,
+ input cp_opcode op2,
+ input word write,
+
+ output word read
+);
+
+ word far;
+
+ assign read = far;
+
+ always @(posedge clk or negedge rst_n)
+ if(!rst_n)
+ far <= 0;
+ else if(transfer && !load)
+ far <= write;
+
+endmodule
diff --git a/rtl/core/cp15/fsr.sv b/rtl/core/cp15/fsr.sv
new file mode 100644
index 0000000..0a7d0d4
--- /dev/null
+++ b/rtl/core/cp15/fsr.sv
@@ -0,0 +1,20 @@
+`include "core/uarch.sv"
+`include "core/cp15/map.sv"
+
+module core_cp15_fsr
+(
+ input logic clk,
+ rst_n,
+
+ input logic load,
+ transfer,
+ input cp_opcode op2,
+ input word write,
+
+ output word read
+);
+
+ //TODO
+ assign read = 0;
+
+endmodule
diff --git a/rtl/core/cp15/map.sv b/rtl/core/cp15/map.sv
index 1f8c58f..7b74967 100644
--- a/rtl/core/cp15/map.sv
+++ b/rtl/core/cp15/map.sv
@@ -77,4 +77,50 @@ typedef struct packed
logic[0:0] s;
} cp15_cpuid_mpu;
+`define CP15_SYSCFG_CTRL 3'b000
+
+typedef struct packed
+{
+ logic[31:27] reserved;
+ logic[26:26] l2;
+ logic[25:25] ee;
+ logic[24:24] ve;
+ logic[23:23] xp;
+ logic[22:22] u;
+ logic[21:21] fi;
+ logic[20:20] st;
+ logic[19:19] sbz0;
+ logic[18:18] it;
+ logic[17:17] sbz1;
+ logic[16:16] dt;
+ logic[15:15] l4;
+ logic[14:14] rr;
+ logic[13:13] v;
+ logic[12:12] i;
+ logic[11:11] z;
+ logic[10:10] f;
+ logic[9:9] r;
+ logic[8:8] s;
+ logic[7:7] b;
+ logic[6:6] l;
+ logic[5:5] d;
+ logic[4:4] p;
+ logic[3:3] w;
+ logic[2:2] c;
+ logic[1:1] a;
+ logic[0:0] m;
+} cp15_syscfg_ctrl;
+
+`define CP15_SYSCFG_ACCESS 3'b010
+
+typedef struct packed
+{
+ logic[31:14] base;
+ logic[13:5] sbz;
+ logic[4:3] rgn;
+ logic[2:2] imp;
+ logic[1:1] s;
+ logic[0:0] c;
+} cp15_ttbr;
+
`endif
diff --git a/rtl/core/cp15/syscfg.sv b/rtl/core/cp15/syscfg.sv
new file mode 100644
index 0000000..599b682
--- /dev/null
+++ b/rtl/core/cp15/syscfg.sv
@@ -0,0 +1,66 @@
+`include "core/uarch.sv"
+`include "core/cp15/map.sv"
+
+module core_cp15_syscfg
+(
+ input logic clk,
+ rst_n,
+
+ input logic load,
+ transfer,
+ input cp_opcode op2,
+ input word write,
+
+ output word read
+);
+
+ logic mmu_enable, dcache_enable, icache_enable, high_vectors;
+
+ cp15_syscfg_ctrl ctrl, write_ctrl;
+
+ assign write_ctrl = write;
+
+ always_comb begin
+ ctrl = {$bits(ctrl){1'b0}};
+ ctrl.m = mmu_enable;
+ ctrl.c = dcache_enable;
+ ctrl.l = 1;
+ ctrl.d = 1;
+ ctrl.p = 1;
+ ctrl.z = 1;
+ ctrl.i = icache_enable;
+ ctrl.v = high_vectors;
+ ctrl.dt = 1;
+ ctrl.it = 1;
+
+ unique case(op2)
+ `CP15_SYSCFG_CTRL:
+ read = ctrl;
+
+ `CP15_SYSCFG_ACCESS:
+ read = 0;
+
+ default:
+ read = 0;
+ endcase
+ end
+
+ always @(posedge clk or negedge rst_n)
+ if(!rst_n) begin
+ mmu_enable <= 0;
+ high_vectors <= 0;
+ dcache_enable <= 0;
+ icache_enable <= 0;
+ end else if(transfer && !load)
+ unique case(op2)
+ `CP15_SYSCFG_CTRL: begin
+ mmu_enable <= write_ctrl.m;
+ high_vectors <= write_ctrl.v;
+ dcache_enable <= write_ctrl.c;
+ icache_enable <= write_ctrl.i;
+ end
+
+ default: ;
+ endcase
+
+endmodule
diff --git a/rtl/core/cp15/tlb.sv b/rtl/core/cp15/tlb.sv
new file mode 100644
index 0000000..5cbd19d
--- /dev/null
+++ b/rtl/core/cp15/tlb.sv
@@ -0,0 +1,15 @@
+`include "core/uarch.sv"
+
+module core_cp15_tlb
+(
+ input logic clk,
+ rst_n,
+
+ input logic load,
+ transfer,
+ input word write
+);
+
+ //TODO
+
+endmodule
diff --git a/rtl/core/cp15/tlb_lockdown.sv b/rtl/core/cp15/tlb_lockdown.sv
new file mode 100644
index 0000000..1972c33
--- /dev/null
+++ b/rtl/core/cp15/tlb_lockdown.sv
@@ -0,0 +1,18 @@
+`include "core/uarch.sv"
+
+module core_cp15_tlb_lockdown
+(
+ input logic clk,
+ rst_n,
+
+ input logic load,
+ transfer,
+ input word write,
+
+ output word read
+);
+
+ //TODO, aunque al parecer Linux no usa esto
+ assign read = 0;
+
+endmodule
diff --git a/rtl/core/cp15/ttbr.sv b/rtl/core/cp15/ttbr.sv
new file mode 100644
index 0000000..622dd3f
--- /dev/null
+++ b/rtl/core/cp15/ttbr.sv
@@ -0,0 +1,45 @@
+`include "core/cp15/map.sv"
+`include "core/mmu/format.sv"
+`include "core/uarch.sv"
+
+module core_cp15_ttbr
+(
+ input logic clk,
+ rst_n,
+
+ input logic load,
+ transfer,
+ input word write,
+
+ output word read
+);
+
+ logic s, c;
+ mmu_base base;
+ cp15_ttbr read_ttbr, write_ttbr;
+ logic[1:0] rgn;
+
+ assign read = read_ttbr;
+ assign write_ttbr = write;
+
+ assign read_ttbr.s = s;
+ assign read_ttbr.c = c;
+ assign read_ttbr.sbz = 9'd0;
+ assign read_ttbr.rgn = rgn;
+ assign read_ttbr.imp = 0;
+ assign read_ttbr.base = base;
+
+ always @(posedge clk or negedge rst_n)
+ if(!rst_n) begin
+ s <= 0;
+ c <= 0;
+ rgn <= 0;
+ base <= 0;
+ end else if(transfer && !load) begin
+ s <= write_ttbr.s;
+ c <= write_ttbr.c;
+ rgn <= write_ttbr.rgn;
+ base <= write_ttbr.base;
+ end
+
+endmodule
diff --git a/rtl/core/mmu/format.sv b/rtl/core/mmu/format.sv
new file mode 100644
index 0000000..c0918a3
--- /dev/null
+++ b/rtl/core/mmu/format.sv
@@ -0,0 +1,20 @@
+`ifndef CORE_MMU_FORMAT_SV
+`define CORE_MMU_FORMAT_SV
+
+typedef logic[17:0] mmu_base;
+
+`define MMU_L1_INDEX [29:18]
+`define MMU_L1_FAULT 2'b00
+`define MMU_L1_PAGETABLE 2'b01
+`define MMU_L1_SECTION 2'b10
+
+`define MMU_L2_INDEX [17:10]
+`define MMU_L2_FAULT 2'b00
+`define MMU_L2_LARGE 2'b01
+`define MMU_L2_SMALL 2'b10
+`define MMU_L2_SMALLEXT 2'b11
+
+`define MMU_LARGE_INDEX [13:0]
+`define MMU_SMALL_INDEX [11:0]
+
+`endif