Skip to content

Commit

Permalink
update Sv32 encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
ved-rivos committed Aug 13, 2024
1 parent 46fabbd commit e039485
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 48 deletions.
2 changes: 1 addition & 1 deletion iommu_ref_model/libiommu/include/iommu_data_structures.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ typedef union {
} ta_t;

#define IOSATP_Bare 0
#define IOSATP_Sv32 1
#define IOSATP_Sv32 8
#define IOSATP_Sv39 8
#define IOSATP_Sv48 9
#define IOSATP_Sv57 10
Expand Down
2 changes: 1 addition & 1 deletion iommu_ref_model/libiommu/src/iommu_device_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ do_device_context_configuration_checks(
if ( (g_reg_file.fctl.gxl == 1) && (DC->tc.SXL != 1) ) {
return 1;
}
if ( (g_gxl_writeable == 0) && (DC->tc.SXL != 0) ) {
if ( (g_reg_file.fctl.gxl == 0) && (g_gxl_writeable == 0) && (DC->tc.SXL != 0) ) {
return 1;
}

Expand Down
69 changes: 47 additions & 22 deletions iommu_ref_model/libiommu/src/iommu_process_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
// Author: [email protected]

#include "iommu.h"
uint8_t
do_process_context_configuration_checks(
device_context_t *DC, process_context_t *PC);

uint8_t
locate_process_context(
Expand Down Expand Up @@ -160,32 +163,54 @@ locate_process_context(
*cause = 266; // PDT entry not valid
return 1;
}
//11. If any bits or encoding that are reserved for future standard use are set
// within `PC`, stop and report "PDT entry misconfigured" (cause = 267).

//11. If the PC is misconfigured as determined by rules outlined in Section 2.2.4
// then stop and report "PDT entry misconfigured" (cause = 267).
if ( do_process_context_configuration_checks(DC, PC) ) {
*cause = 267; // PDT entry misconfigured
return 1;
}

//12. The Process-context has been successfully located.
cache_ioatc_pc(device_id, process_id, PC);
return 0;
}
uint8_t
do_process_context_configuration_checks(
device_context_t *DC, process_context_t *PC) {
//1. If any bits or encoding that are reserved for future standard use are set
if ( PC->ta.reserved0 != 0 || PC->ta.reserved1 != 0 ||
PC->fsc.iosatp.reserved != 0 ||
((PC->fsc.iosatp.MODE != IOSATP_Bare) &&
(PC->fsc.iosatp.MODE != IOSATP_Sv32) &&
(PC->fsc.iosatp.MODE != IOSATP_Sv39) &&
(PC->fsc.iosatp.MODE != IOSATP_Sv48) &&
(PC->fsc.iosatp.MODE != IOSATP_Sv57)) ) {
*cause = 267; // PDT entry not misconfigured
PC->fsc.iosatp.reserved != 0 ) {
return 1;
}
//12. If any of the following conditions are true then stop and report
// "PDT entry misconfigured" (cause = 267).
// a. `capabilities.Sv32` is 0 and `PC.fsc.MODE` is `Sv32`
// b. `capabilities.Sv39` is 0 and `PC.fsc.MODE` is `Sv39`
// c. `capabilities.Sv48` is 0 and `PC.fsc.MODE` is `Sv48`
// d. `capabilities.Sv57` is 0 and `PC.fsc.MODE` is `Sv57`
if ( ((PC->fsc.iosatp.MODE == IOSATP_Sv32) && (g_reg_file.capabilities.Sv32 == 0)) ||
((PC->fsc.iosatp.MODE == IOSATP_Sv39) && (g_reg_file.capabilities.Sv39 == 0)) ||
((PC->fsc.iosatp.MODE == IOSATP_Sv48) && (g_reg_file.capabilities.Sv48 == 0)) ||
((PC->fsc.iosatp.MODE == IOSATP_Sv57) && (g_reg_file.capabilities.Sv57 == 0)) ) {
*cause = 267; // PDT entry not misconfigured
// 2. PC.fsc.MODE encoding is not valid as determined by Table 3
if ( (DC->tc.SXL == 0) &&
(PC->fsc.iosatp.MODE != IOSATP_Bare) &&
(PC->fsc.iosatp.MODE != IOSATP_Sv39) &&
(PC->fsc.iosatp.MODE != IOSATP_Sv48) &&
(PC->fsc.iosatp.MODE != IOSATP_Sv57) ) {
return 1;
}
if ( (DC->tc.SXL == 1) &&
(PC->fsc.iosatp.MODE != IOSATP_Bare) &&
(PC->fsc.iosatp.MODE != IOSATP_Sv32) ) {
return 1;
}
// 3. DC.tc.SXL is 0 and PC.fsc.MODE is not one of the supported modes
// a. capabilities.Sv39 is 0 and PC.fsc.MODE is Sv39
// b. capabilities.Sv48 is 0 and PC.fsc.MODE is Sv48
// c. capabilities.Sv57 is 0 and PC.fsc.MODE is Sv57
if ( (DC->tc.SXL == 0) &&
(((PC->fsc.iosatp.MODE == IOSATP_Sv39) && (g_reg_file.capabilities.Sv39 == 0)) ||
((PC->fsc.iosatp.MODE == IOSATP_Sv48) && (g_reg_file.capabilities.Sv48 == 0)) ||
((PC->fsc.iosatp.MODE == IOSATP_Sv57) && (g_reg_file.capabilities.Sv57 == 0))) ) {
return 1;
}
//4. DC.tc.SXL is 1 and PC.fsc.MODE is not one of the supported modes
// a. capabilities.Sv32 is 0 and PC.fsc.MODE is Sv32
if ( (DC->tc.SXL == 1) &&
((PC->fsc.iosatp.MODE == IOSATP_Sv32) && (g_reg_file.capabilities.Sv32 == 0)) ) {
return 1;
}
//13. The Process-context has been successfully located.
cache_ioatc_pc(device_id, process_id, PC);
return 0;
}
4 changes: 2 additions & 2 deletions iommu_ref_model/libiommu/src/iommu_second_stage_trans.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ second_stage_address_translation(
*gst_page_sz = 512UL * 512UL * 512UL * 512UL * PAGESIZE;
else if ( g_reg_file.capabilities.Sv48x4 == 1 )
*gst_page_sz = 512UL * 512UL * 512UL * PAGESIZE;
else if ( g_reg_file.capabilities.Sv39x4 == 1 )
else if ( g_reg_file.capabilities.Sv39x4 == 1 && g_reg_file.fctl.gxl == 0)
*gst_page_sz = 512UL * 512UL * PAGESIZE;
else if ( g_reg_file.capabilities.Sv32x4 == 1 )
else if ( g_reg_file.capabilities.Sv32x4 == 1 && g_reg_file.fctl.gxl == 1)
*gst_page_sz = 2UL * 512UL * PAGESIZE;
goto step_8;
}
Expand Down
4 changes: 2 additions & 2 deletions iommu_ref_model/libiommu/src/iommu_two_stage_trans.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ two_stage_address_translation(
*page_sz = 512UL * 512UL * 512UL * 512UL * PAGESIZE;
else if ( g_reg_file.capabilities.Sv48 == 1 )
*page_sz = 512UL * 512UL * 512UL * PAGESIZE;
else if ( g_reg_file.capabilities.Sv39 == 1 )
else if ( g_reg_file.capabilities.Sv39 == 1 && SXL == 0)
*page_sz = 512UL * 512UL * PAGESIZE;
else if ( g_reg_file.capabilities.Sv32 == 1 )
else if ( g_reg_file.capabilities.Sv32 == 1 && SXL == 1)
*page_sz = 2UL * 512UL * PAGESIZE;

*iotval2 = 0;
Expand Down
4 changes: 2 additions & 2 deletions iommu_ref_model/libtables/include/tables_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
uint64_t add_dev_context(device_context_t *DC, uint32_t device_id);
uint64_t add_process_context(device_context_t *DC, process_context_t *PC, uint32_t process_id);
uint64_t add_g_stage_pte(iohgatp_t iohgatp, uint64_t gpa, gpte_t gpte, uint8_t add_level);
uint64_t add_s_stage_pte(iosatp_t satp, uint64_t va, pte_t pte, uint8_t add_level);
uint64_t add_vs_stage_pte(iosatp_t satp, uint64_t va, pte_t pte, uint8_t add_level, iohgatp_t iohgatp);
uint64_t add_s_stage_pte(iosatp_t satp, uint64_t va, pte_t pte, uint8_t add_level, uint8_t SXL);
uint64_t add_vs_stage_pte(iosatp_t satp, uint64_t va, pte_t pte, uint8_t add_level, iohgatp_t iohgatp, uint8_t SXL);
uint64_t translate_gpa (iohgatp_t iohgatp, uint64_t gpa, uint64_t *spa);


Expand Down
4 changes: 2 additions & 2 deletions iommu_ref_model/libtables/src/build_g_stage_pt.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ add_g_stage_pte (
gpte_t nl_gpte;

PTESIZE = 8;
if ( iohgatp.MODE == IOHGATP_Sv32x4 ) {
if ( iohgatp.MODE == IOHGATP_Sv32x4 && g_reg_file.fctl.gxl == 1 ) {
vpn[0] = get_bits(21, 12, gpa);
vpn[1] = get_bits(34, 22, gpa);
LEVELS = 2;
PTESIZE = 4;
}
if ( iohgatp.MODE == IOHGATP_Sv39x4 ) {
if ( iohgatp.MODE == IOHGATP_Sv39x4 && g_reg_file.fctl.gxl == 0) {
vpn[0] = get_bits(20, 12, gpa);
vpn[1] = get_bits(29, 21, gpa);
vpn[2] = get_bits(40, 30, gpa);
Expand Down
6 changes: 3 additions & 3 deletions iommu_ref_model/libtables/src/build_s_stage_pt.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@
#include "tables_api.h"
uint64_t
add_s_stage_pte (
iosatp_t satp, uint64_t va, pte_t pte, uint8_t add_level) {
iosatp_t satp, uint64_t va, pte_t pte, uint8_t add_level, uint8_t SXL) {

uint16_t vpn[5];
uint64_t a;
uint8_t i, PTESIZE, LEVELS;
pte_t nl_pte;

PTESIZE = 8;
if ( satp.MODE == IOSATP_Sv32 ) {
if ( satp.MODE == IOSATP_Sv32 && SXL == 1) {
vpn[0] = get_bits(21, 12, va);
vpn[1] = get_bits(31, 22, va);
LEVELS = 2;
PTESIZE = 4;
}
if ( satp.MODE == IOSATP_Sv39 ) {
if ( satp.MODE == IOSATP_Sv39 && SXL == 0) {
vpn[0] = get_bits(20, 12, va);
vpn[1] = get_bits(29, 21, va);
vpn[2] = get_bits(38, 30, va);
Expand Down
6 changes: 3 additions & 3 deletions iommu_ref_model/libtables/src/build_vs_stage_pt.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@
uint64_t
add_vs_stage_pte (
iosatp_t satp, uint64_t va, pte_t pte, uint8_t add_level,
iohgatp_t iohgatp) {
iohgatp_t iohgatp, uint8_t SXL) {

uint16_t vpn[5];
uint64_t a;
uint8_t i, PTESIZE, LEVELS;
pte_t nl_pte;

PTESIZE = 8;
if ( satp.MODE == IOSATP_Sv32 ) {
if ( satp.MODE == IOSATP_Sv32 && SXL == 1) {
vpn[0] = get_bits(21, 12, va);
vpn[1] = get_bits(31, 22, va);
LEVELS = 2;
PTESIZE = 4;
}
if ( satp.MODE == IOSATP_Sv39 ) {
if ( satp.MODE == IOSATP_Sv39 && SXL == 0) {
vpn[0] = get_bits(20, 12, va);
vpn[1] = get_bits(29, 21, va);
vpn[2] = get_bits(38, 30, va);
Expand Down
36 changes: 26 additions & 10 deletions iommu_ref_model/test/test_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,23 +606,27 @@ main(void) {
priv_req, 0, at, 0xdeadbeef, 16, (no_write ^ 1), &req, &rsp);
fail_if( ( check_rsp_and_faults(&req, &rsp, UNSUPPORTED_REQUEST, 259, 0) < 0 ) );
DC.msi_addr_pattern.reserved = 0;
g_reg_file.fctl.gxl = 1;
DC.iohgatp.MODE = IOHGATP_Sv32x4;
write_memory((char *)&DC, DC_addr, 64);
send_translation_request(0x012345, pid_valid, 0x99, no_write, exec_req,
priv_req, 0, at, 0xdeadbeef, 16, (no_write ^ 1), &req, &rsp);
fail_if( ( check_rsp_and_faults(&req, &rsp, UNSUPPORTED_REQUEST, 259, 0) < 0 ) );
g_reg_file.fctl.gxl = 0;
DC.iohgatp.MODE = IOHGATP_Sv48x4;
DC.iohgatp.MODE = IOHGATP_Sv57x4 + 1;
write_memory((char *)&DC, DC_addr, 64);
send_translation_request(0x012345, pid_valid, 0x99, no_write, exec_req,
priv_req, 0, at, 0xdeadbeef, 16, (no_write ^ 1), &req, &rsp);
fail_if( ( check_rsp_and_faults(&req, &rsp, UNSUPPORTED_REQUEST, 259, 0) < 0 ) );
DC.iohgatp.MODE = IOHGATP_Sv48x4;
g_reg_file.fctl.gxl = 1;
DC.fsc.iosatp.MODE = IOSATP_Sv32;
write_memory((char *)&DC, DC_addr, 64);
send_translation_request(0x012345, pid_valid, 0x99, no_write, exec_req,
priv_req, 0, at, 0xdeadbeef, 16, (no_write ^ 1), &req, &rsp);
fail_if( ( check_rsp_and_faults(&req, &rsp, UNSUPPORTED_REQUEST, 259, 0) < 0 ) );
g_reg_file.fctl.gxl = 0;
DC.fsc.iosatp.MODE = IOSATP_Bare;
DC.fsc.iosatp.MODE = IOSATP_Sv57 + 1;
write_memory((char *)&DC, DC_addr, 64);
Expand Down Expand Up @@ -946,7 +950,7 @@ main(void) {
g_reg_file.fctl.be = 0;
g_reg_file.capabilities.end = 0;


iodir(INVAL_DDT, 1, 0x012345, 0);


END_TEST();
Expand Down Expand Up @@ -1393,6 +1397,8 @@ main(void) {
g_reg_file.capabilities.Sv32x4 = 0;
for ( i = 0; i < 4; i++ ) {
if ( i == 0 ) g_reg_file.capabilities.Sv32x4 = 1;
if ( i == 0 ) g_reg_file.fctl.gxl = 1;
if ( i == 0 ) DC.tc.SXL = 1;
if ( i == 1 ) g_reg_file.capabilities.Sv39x4 = 1;
if ( i == 2 ) g_reg_file.capabilities.Sv48x4 = 1;
if ( i == 3 ) g_reg_file.capabilities.Sv57x4 = 1;
Expand All @@ -1417,6 +1423,8 @@ main(void) {
fail_if( ( i == 1 && ((temp + 1) != 512UL * 512UL * PAGESIZE) ) );
fail_if( ( i == 2 && ((temp + 1) != 512UL * 512UL * 512UL * PAGESIZE) ) );
fail_if( ( i == 3 && ((temp + 1) != 512UL * 512UL * 512UL * 512UL * PAGESIZE) ) );
if ( i == 0 ) g_reg_file.fctl.gxl = 0;
if ( i == 0 ) DC.tc.SXL = 0;
}
END_TEST();

Expand Down Expand Up @@ -1620,7 +1628,7 @@ main(void) {
req.tr.iova = gva;
pte.PPN = 512UL * 512UL * 512UL * 512UL;
pte.PPN |= (1UL << (i * 9UL));
pte_addr = add_s_stage_pte(DC.fsc.iosatp, gva, pte, i);
pte_addr = add_s_stage_pte(DC.fsc.iosatp, gva, pte, i, DC.tc.SXL);
iommu_translate_iova(&req, &rsp);
fail_if( ( rsp.status != SUCCESS ) );
fail_if( ( rsp.trsp.S == 1 && i == 0 ) );
Expand Down Expand Up @@ -1668,6 +1676,8 @@ main(void) {
g_reg_file.capabilities.Sv32 = 0;
for ( i = 0; i < 4; i++ ) {
if ( i == 0 ) g_reg_file.capabilities.Sv32 = 1;
if ( i == 0 ) g_reg_file.fctl.gxl = 1;
if ( i == 0 ) DC.tc.SXL = 1;
if ( i == 1 ) g_reg_file.capabilities.Sv39 = 1;
if ( i == 2 ) g_reg_file.capabilities.Sv48 = 1;
if ( i == 3 ) g_reg_file.capabilities.Sv57 = 1;
Expand All @@ -1692,6 +1702,8 @@ main(void) {
fail_if( ( i == 1 && ((temp + 1) != 512UL * 512UL * PAGESIZE) ) );
fail_if( ( i == 2 && ((temp + 1) != 512UL * 512UL * 512UL * PAGESIZE) ) );
fail_if( ( i == 3 && ((temp + 1) != 512UL * 512UL * 512UL * 512UL * PAGESIZE) ) );
if ( i == 0 ) g_reg_file.fctl.gxl = 0;
if ( i == 0 ) DC.tc.SXL = 0;
}

// IOTINVAL not allowed to set PSCV
Expand Down Expand Up @@ -1761,7 +1773,7 @@ main(void) {
gva = gva | ((1 << (i * 9)) * PAGESIZE) | 2048;
req.tr.iova = gva;
pte.PPN = 512UL * 512UL * 512UL * 512UL;
pte_addr = add_s_stage_pte(DC.fsc.iosatp, gva, pte, i);
pte_addr = add_s_stage_pte(DC.fsc.iosatp, gva, pte, i, DC.tc.SXL);
read_memory(pte_addr, 8, (char *)&pte);

pte.U = 1;
Expand Down Expand Up @@ -2116,7 +2128,7 @@ main(void) {
gva = gva | ((1 << (i * 9)) * PAGESIZE) | 2048;
req.tr.iova = gva;
pte.PPN = 512UL * 512UL * 512UL * 512UL;
pte_addr = add_s_stage_pte(DC.fsc.iosatp, gva, pte, 0);
pte_addr = add_s_stage_pte(DC.fsc.iosatp, gva, pte, 0, DC.tc.SXL);

event.eventID = IOATC_TLB_MISS;
event.dmask = 0;
Expand Down Expand Up @@ -2314,6 +2326,10 @@ main(void) {
fail_if( ( check_rsp_and_faults(&req, &rsp, UNSUPPORTED_REQUEST, 269, 0) < 0 ) );
data_corruption_addr = -1;

g_reg_file.fctl.gxl = 0;
DC.tc.SXL = 0;
write_memory((char *)&DC, DC_addr, 64);
iodir(INVAL_DDT, 1, 0x112233, 0);
g_reg_file.capabilities.Sv57 = 0;
g_reg_file.capabilities.Sv48 = 0;
g_reg_file.capabilities.Sv39 = 0;
Expand Down Expand Up @@ -2392,7 +2408,7 @@ main(void) {
spa = gpte.PPN * PAGESIZE;
gpte_addr = add_g_stage_pte(DC.iohgatp, gpa, gpte, 0);
gva = 0x100000;
pte_addr = add_vs_stage_pte(PC.fsc.iosatp, gva, pte, 0, DC.iohgatp);
pte_addr = add_vs_stage_pte(PC.fsc.iosatp, gva, pte, 0, DC.iohgatp, DC.tc.SXL);
send_translation_request(0x112233, 1, 0xBABEC, 0,
0, 1, 0, ADDR_TYPE_UNTRANSLATED, gva,
1, WRITE, &req, &rsp);
Expand Down Expand Up @@ -2595,7 +2611,7 @@ main(void) {
gpte.PPN |= 0x4;
gpte_addr = add_g_stage_pte(DC.iohgatp, gpa, gpte, 0);
gva = 0x900000;
pte_addr = add_vs_stage_pte(PC.fsc.iosatp, gva, pte, 0, DC.iohgatp);
pte_addr = add_vs_stage_pte(PC.fsc.iosatp, gva, pte, 0, DC.iohgatp, DC.tc.SXL);
send_translation_request(0x112233, 1, 0xBABEC, 0,
0, 0, 0, ADDR_TYPE_UNTRANSLATED, gva,
1, WRITE, &req, &rsp);
Expand Down Expand Up @@ -2716,7 +2732,7 @@ main(void) {
spa = gpte.PPN * PAGESIZE;
gpte_addr = add_g_stage_pte(DC.iohgatp, gpa, gpte, 0);
gva = 0x100000;
pte_addr = add_vs_stage_pte(PC.fsc.iosatp, gva, pte, 0, DC.iohgatp);
pte_addr = add_vs_stage_pte(PC.fsc.iosatp, gva, pte, 0, DC.iohgatp, DC.tc.SXL);
}
for ( i = 0; i < 10; i++ ) {
send_translation_request(0x112233, 1, 0x1000+i, 0,
Expand Down Expand Up @@ -2914,7 +2930,7 @@ main(void) {
spa = gpte.PPN * PAGESIZE;
gpte_addr = add_g_stage_pte(DC.iohgatp, gpa, gpte, 0);
gva = 0x900000;
pte_addr = add_vs_stage_pte(PC.fsc.iosatp, gva, pte, 0, DC.iohgatp);
pte_addr = add_vs_stage_pte(PC.fsc.iosatp, gva, pte, 0, DC.iohgatp, DC.tc.SXL);

send_translation_request(0x112233, 1, 0x7000, 1, 0,
0, 0, ADDR_TYPE_PCIE_ATS_TRANSLATION_REQUEST, 0x900000,
Expand Down Expand Up @@ -3839,7 +3855,7 @@ main(void) {
spa = gpte.PPN * PAGESIZE;
gpte_addr = add_g_stage_pte(DC.iohgatp, gpa, gpte, 0);
gva = 0x100000;
pte_addr = add_vs_stage_pte(PC.fsc.iosatp, gva, pte, 0, DC.iohgatp);
pte_addr = add_vs_stage_pte(PC.fsc.iosatp, gva, pte, 0, DC.iohgatp, DC.tc.SXL);
send_translation_request(0x000000, 1, 0xBABEC, 0,
0, 1, 0, ADDR_TYPE_UNTRANSLATED, gva,
1, WRITE, &req, &rsp);
Expand All @@ -3853,7 +3869,7 @@ main(void) {
spa = gpte.PPN * PAGESIZE;
gpte_addr = add_g_stage_pte(DC.iohgatp, gpa, gpte, 1);
gva = 0x19000000;
pte_addr = add_vs_stage_pte(PC.fsc.iosatp, gva, pte, 1, DC.iohgatp);
pte_addr = add_vs_stage_pte(PC.fsc.iosatp, gva, pte, 1, DC.iohgatp, DC.tc.SXL);
send_translation_request(0x000000, 1, 0xBABEC, 0,
0, 1, 0, ADDR_TYPE_UNTRANSLATED, gva,
1, WRITE, &req, &rsp);
Expand Down

0 comments on commit e039485

Please sign in to comment.