From acc772b4d760bc435ab3a97727cc332423f92e4c Mon Sep 17 00:00:00 2001 From: Robert Norton Date: Wed, 1 May 2019 17:09:02 +0100 Subject: Add base address register as extra argument to ext_data_check_addr hook to assist with implementing CHERI capability mode. --- model/riscv_addr_checks.sail | 2 +- model/riscv_insts_aext.sail | 6 +++--- model/riscv_insts_base.sail | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/model/riscv_addr_checks.sail b/model/riscv_addr_checks.sail index c485577..eaace3c 100644 --- a/model/riscv_addr_checks.sail +++ b/model/riscv_addr_checks.sail @@ -42,7 +42,7 @@ function ext_handle_control_check_error(err : ext_control_addr_error) -> unit = /* default data address checks */ type ext_data_addr_error = unit -function ext_data_check_addr(addr : xlenbits, acc : AccessType, rt : ReadType, width : word_width) +function ext_data_check_addr(base : regbits, addr : xlenbits, acc : AccessType, rt : ReadType, width : word_width) -> Ext_DataAddr_Check(ext_data_addr_error) = Ext_DataAddr_OK(addr) diff --git a/model/riscv_insts_aext.sail b/model/riscv_insts_aext.sail index f38b28f..d0e1580 100644 --- a/model/riscv_insts_aext.sail +++ b/model/riscv_insts_aext.sail @@ -43,7 +43,7 @@ function clause execute(LOADRES(aq, rl, rs1, width, rd)) = { if haveAtomics() then { let pre_vaddr : xlenbits = X(rs1); /* Let extensions get the first check on address validity. */ - match ext_data_check_addr(pre_vaddr, Read, Data, width) { + match ext_data_check_addr(rs1, pre_vaddr, Read, Data, width) { Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); false }, Ext_DataAddr_OK(vaddr) => { let aligned : bool = @@ -101,7 +101,7 @@ function clause execute (STORECON(aq, rl, rs2, rs1, width, rd)) = { */ pre_vaddr : xlenbits = X(rs1); /* Let extensions get the first check on address validity. */ - match ext_data_check_addr(pre_vaddr, Read, Data, width) { + match ext_data_check_addr(rs1, pre_vaddr, Read, Data, width) { Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); false }, Ext_DataAddr_OK(vaddr) => { let aligned : bool = @@ -185,7 +185,7 @@ function clause execute (AMO(op, aq, rl, rs2, rs1, width, rd)) = { if haveAtomics() then { pre_vaddr : xlenbits = X(rs1); /* Let extensions get the first check on address validity. */ - match ext_data_check_addr(pre_vaddr, Read, Data, width) { + match ext_data_check_addr(rs1, pre_vaddr, Read, Data, width) { Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); false }, Ext_DataAddr_OK(vaddr) => { match translateAddr(vaddr, ReadWrite, Data) { diff --git a/model/riscv_insts_base.sail b/model/riscv_insts_base.sail index 0cfc0ec..5e48153 100644 --- a/model/riscv_insts_base.sail +++ b/model/riscv_insts_base.sail @@ -317,7 +317,7 @@ function check_misaligned(vaddr : xlenbits, width : word_width) -> bool = function clause execute(LOAD(imm, rs1, rd, is_unsigned, width, aq, rl)) = { let pre_vaddr : xlenbits = X(rs1) + EXTS(imm); /* Let extensions get the first check on address validity. */ - match ext_data_check_addr(pre_vaddr, Read, Data, width) { + match ext_data_check_addr(rs1, pre_vaddr, Read, Data, width) { Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); false }, Ext_DataAddr_OK(vaddr) => if check_misaligned(vaddr, width) @@ -372,7 +372,7 @@ mapping clause encdec = STORE(imm7 @ imm5, rs2, rs1, size, false, false) function clause execute (STORE(imm, rs2, rs1, width, aq, rl)) = { let pre_vaddr : xlenbits = X(rs1) + EXTS(imm); /* Let extensions get the first check on address validity. */ - match ext_data_check_addr(pre_vaddr, Write, Data, width) { + match ext_data_check_addr(rs1, pre_vaddr, Write, Data, width) { Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); false }, Ext_DataAddr_OK(vaddr) => if check_misaligned(vaddr, width) -- cgit v1.1 From 42df9693eb5e2747e4a57aac269196d80116da0c Mon Sep 17 00:00:00 2001 From: Robert Norton Date: Thu, 2 May 2019 12:46:22 +0100 Subject: Push address calculation inside the data_check_addr hook and rename it to data_get_addr. This avoids a double register read in CHERI case. --- model/riscv_addr_checks.sail | 9 +++++++-- model/riscv_insts_aext.sail | 21 ++++++++++++--------- model/riscv_insts_base.sail | 14 ++++++++------ 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/model/riscv_addr_checks.sail b/model/riscv_addr_checks.sail index eaace3c..2471075 100644 --- a/model/riscv_addr_checks.sail +++ b/model/riscv_addr_checks.sail @@ -39,11 +39,16 @@ function ext_control_check_pc(pc : xlenbits) -> Ext_ControlAddr_Check(ext_contro function ext_handle_control_check_error(err : ext_control_addr_error) -> unit = () -/* default data address checks */ + +/* The default data address function does not perform any checks so + just uses unit for error type. */ type ext_data_addr_error = unit -function ext_data_check_addr(base : regbits, addr : xlenbits, acc : AccessType, rt : ReadType, width : word_width) +/* Default data addr is just base register + immediate offset (may be zero). + Extensions might override and add additional checks. */ +function ext_data_get_addr(base : regbits, offset : xlenbits, acc : AccessType, rt : ReadType, width : word_width) -> Ext_DataAddr_Check(ext_data_addr_error) = + let addr = X(base) + offset in Ext_DataAddr_OK(addr) function ext_handle_data_check_error(err : ext_data_addr_error) -> unit = diff --git a/model/riscv_insts_aext.sail b/model/riscv_insts_aext.sail index d0e1580..86a8b32 100644 --- a/model/riscv_insts_aext.sail +++ b/model/riscv_insts_aext.sail @@ -41,9 +41,10 @@ function process_loadres(rd, addr, value, is_unsigned) = function clause execute(LOADRES(aq, rl, rs1, width, rd)) = { if haveAtomics() then { - let pre_vaddr : xlenbits = X(rs1); - /* Let extensions get the first check on address validity. */ - match ext_data_check_addr(rs1, pre_vaddr, Read, Data, width) { + /* Get the address, X(rs1) (no offset). + * Extensions might perform additional checks on address validity. + */ + match ext_data_get_addr(rs1, zeros(), Read, Data, width) { Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); false }, Ext_DataAddr_OK(vaddr) => { let aligned : bool = @@ -99,9 +100,10 @@ function clause execute (STORECON(aq, rl, rs2, rs1, width, rd)) = { /* normal non-rmem case * rmem: SC is allowed to succeed (but might fail later) */ - pre_vaddr : xlenbits = X(rs1); - /* Let extensions get the first check on address validity. */ - match ext_data_check_addr(rs1, pre_vaddr, Read, Data, width) { + /* Get the address, X(rs1) (no offset). + * Extensions might perform additional checks on address validity. + */ + match ext_data_get_addr(rs1, zeros(), Read, Data, width) { Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); false }, Ext_DataAddr_OK(vaddr) => { let aligned : bool = @@ -183,9 +185,10 @@ mapping clause encdec = AMO(op, aq, rl, rs2, rs1, size, rd) This may need revisiting. */ function clause execute (AMO(op, aq, rl, rs2, rs1, width, rd)) = { if haveAtomics() then { - pre_vaddr : xlenbits = X(rs1); - /* Let extensions get the first check on address validity. */ - match ext_data_check_addr(rs1, pre_vaddr, Read, Data, width) { + /* Get the address, X(rs1) (no offset). + * Some extensions perform additional checks on address validity. + */ + match ext_data_get_addr(rs1, zeros(), Read, Data, width) { Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); false }, Ext_DataAddr_OK(vaddr) => { match translateAddr(vaddr, ReadWrite, Data) { diff --git a/model/riscv_insts_base.sail b/model/riscv_insts_base.sail index 5e48153..5819a81 100644 --- a/model/riscv_insts_base.sail +++ b/model/riscv_insts_base.sail @@ -315,9 +315,10 @@ function check_misaligned(vaddr : xlenbits, width : word_width) -> bool = } function clause execute(LOAD(imm, rs1, rd, is_unsigned, width, aq, rl)) = { - let pre_vaddr : xlenbits = X(rs1) + EXTS(imm); - /* Let extensions get the first check on address validity. */ - match ext_data_check_addr(rs1, pre_vaddr, Read, Data, width) { + let offset : xlenbits = EXTS(imm); + /* Get the address, X(rs1) + offset. + Some extensions perform additional checks on address validity. */ + match ext_data_get_addr(rs1, offset, Read, Data, width) { Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); false }, Ext_DataAddr_OK(vaddr) => if check_misaligned(vaddr, width) @@ -370,9 +371,10 @@ mapping clause encdec = STORE(imm7 @ imm5, rs2, rs1, size, false, false) /* NOTE: Currently, we only EA if address translation is successful. This may need revisiting. */ function clause execute (STORE(imm, rs2, rs1, width, aq, rl)) = { - let pre_vaddr : xlenbits = X(rs1) + EXTS(imm); - /* Let extensions get the first check on address validity. */ - match ext_data_check_addr(rs1, pre_vaddr, Write, Data, width) { + let offset : xlenbits = EXTS(imm); + /* Get the address, X(rs1) + offset. + Some extensions perform additional checks on address validity. */ + match ext_data_get_addr(rs1, offset, Write, Data, width) { Ext_DataAddr_Error(e) => { ext_handle_data_check_error(e); false }, Ext_DataAddr_OK(vaddr) => if check_misaligned(vaddr, width) -- cgit v1.1