Skip to content

Commit

Permalink
Merge pull request #458 from ved-rivos/1221
Browse files Browse the repository at this point in the history
Add config knobs for Bare translation size
  • Loading branch information
ved-rivos authored Dec 21, 2024
2 parents 5dc4b55 + 816c66d commit a509008
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 37 deletions.
3 changes: 2 additions & 1 deletion iommu_ref_model/libiommu/include/iommu_ref_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ extern int reset_iommu(uint8_t num_hpm, uint8_t hpmctr_bits, uint16_t eventID_ma
uint8_t max_iommu_mode, uint32_t max_devid_mask,
uint8_t gxl_writeable, uint8_t fctl_be_writeable,
uint8_t fill_ats_trans_in_ioatc, capabilities_t capabilities,
fctl_t fctl);
fctl_t fctl, uint64_t sv57_bare_pg_sz, uint64_t sv48_bare_pg_sz,
uint64_t sv39_bare_pg_sz, uint64_t sv32_bare_pg_sz);
extern void iommu_translate_iova(hb_to_iommu_req_t *req, iommu_to_hb_rsp_t *rsp_msg);
extern void handle_page_request(ats_msg_t *pr);
extern uint8_t handle_invalidation_completion(ats_msg_t *inv_cc);
Expand Down
4 changes: 4 additions & 0 deletions iommu_ref_model/libiommu/include/iommu_registers.h
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,10 @@ extern uint8_t g_max_iommu_mode;
extern uint8_t g_fill_ats_trans_in_ioatc;
extern uint32_t g_max_devid_mask;
extern uint8_t g_trans_for_debug;
extern uint64_t g_sv57_bare_pg_sz;
extern uint64_t g_sv48_bare_pg_sz;
extern uint64_t g_sv39_bare_pg_sz;
extern uint64_t g_sv32_bare_pg_sz;

extern void process_commands(void);
#endif //_IOMMU_REGS_H_
11 changes: 10 additions & 1 deletion iommu_ref_model/libiommu/src/iommu_reg.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ uint8_t g_fill_ats_trans_in_ioatc;
uint32_t g_max_devid_mask;
extern uint8_t g_iofence_wait_pending_inv;
uint8_t g_trans_for_debug;
uint64_t g_sv57_bare_pg_sz;
uint64_t g_sv48_bare_pg_sz;
uint64_t g_sv39_bare_pg_sz;
uint64_t g_sv32_bare_pg_sz;

uint8_t
is_access_valid(
Expand Down Expand Up @@ -849,7 +853,8 @@ reset_iommu(uint8_t num_hpm, uint8_t hpmctr_bits, uint16_t eventID_limit,
uint8_t max_iommu_mode, uint32_t max_devid_mask,
uint8_t gxl_writeable, uint8_t fctl_be_writeable,
uint8_t fill_ats_trans_in_ioatc, capabilities_t capabilities,
fctl_t fctl) {
fctl_t fctl, uint64_t sv57_bare_pg_sz, uint64_t sv48_bare_pg_sz,
uint64_t sv39_bare_pg_sz, uint64_t sv32_bare_pg_sz) {
int i;
#ifdef DEBUG
// Only PA upto 56 bits supported in RISC-V
Expand Down Expand Up @@ -977,5 +982,9 @@ reset_iommu(uint8_t num_hpm, uint8_t hpmctr_bits, uint16_t eventID_limit,
g_offset_to_size[i + MSI_DATA_0_OFFSET] = 4;
g_offset_to_size[i + MSI_VEC_CTRL_0_OFFSET] = 4;
}
g_sv57_bare_pg_sz = sv57_bare_pg_sz;
g_sv48_bare_pg_sz = sv48_bare_pg_sz;
g_sv39_bare_pg_sz = sv39_bare_pg_sz;
g_sv32_bare_pg_sz = sv32_bare_pg_sz;
return 0;
}
14 changes: 9 additions & 5 deletions iommu_ref_model/libiommu/src/iommu_second_stage_trans.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,19 @@ second_stage_address_translation(
gpte->X = gpte->W = gpte->R = gpte->V = 1;
gpte->N = 0;
gpte->PBMT = PMA;
// Indicate G-stage page size as largest possible page size
// The translation range size returned in a Success response to
// an ATS translation request, when either stages of address
// translation are Bare, is implementation-defined. However, it
// is recommended that the translation range size be large, such
// as 2 MiB or 1 GiB.
if ( g_reg_file.capabilities.Sv57x4 == 1 )
*gst_page_sz = 512UL * 512UL * 512UL * 512UL * PAGESIZE;
*gst_page_sz = g_sv57_bare_pg_sz;
else if ( g_reg_file.capabilities.Sv48x4 == 1 )
*gst_page_sz = 512UL * 512UL * 512UL * PAGESIZE;
*gst_page_sz = g_sv48_bare_pg_sz;
else if ( g_reg_file.capabilities.Sv39x4 == 1 && g_reg_file.fctl.gxl == 0)
*gst_page_sz = 512UL * 512UL * PAGESIZE;
*gst_page_sz = g_sv39_bare_pg_sz;
else if ( g_reg_file.capabilities.Sv32x4 == 1 && g_reg_file.fctl.gxl == 1)
*gst_page_sz = 2UL * 512UL * PAGESIZE;
*gst_page_sz = g_sv32_bare_pg_sz;
goto step_8;
}

Expand Down
23 changes: 13 additions & 10 deletions iommu_ref_model/libiommu/src/iommu_two_stage_trans.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,6 @@ two_stage_address_translation(
uint64_t gst_page_sz;
uint64_t pa_mask = ((1UL << (g_reg_file.capabilities.pas)) - 1);

// Indicate S/VS-stage page size as largest possible page size
if ( g_reg_file.capabilities.Sv57 == 1 )
*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 && SXL == 0)
*page_sz = 512UL * 512UL * PAGESIZE;
else if ( g_reg_file.capabilities.Sv32 == 1 && SXL == 1)
*page_sz = 2UL * 512UL * PAGESIZE;

*iotval2 = 0;

// Walk page tables
Expand All @@ -50,6 +40,19 @@ two_stage_address_translation(
pte->N = 0;
pte->PBMT = PMA;
*pa = iova;
// The translation range size returned in a Success response to
// an ATS translation request, when either stages of address
// translation are Bare, is implementation-defined. However, it
// is recommended that the translation range size be large, such
// as 2 MiB or 1 GiB.
if ( g_reg_file.capabilities.Sv57 == 1 )
*page_sz = g_sv57_bare_pg_sz;
else if ( g_reg_file.capabilities.Sv48 == 1 )
*page_sz = g_sv48_bare_pg_sz;
else if ( g_reg_file.capabilities.Sv39 == 1 && SXL == 0)
*page_sz = g_sv39_bare_pg_sz;
else if ( g_reg_file.capabilities.Sv32 == 1 && SXL == 1)
*page_sz = g_sv32_bare_pg_sz;
return 0;
}

Expand Down
42 changes: 22 additions & 20 deletions iommu_ref_model/test/test_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ main(void) {
uint32_t i, j, test_num = 0;
uint64_t DC_addr, exp_iotval2, iofence_PPN, iofence_data, spa, gpa;
uint64_t gva, gpte_addr, pte_addr, PC_addr, temp;
uint64_t sv57_bare_sz, sv48_bare_sz, sv39_bare_sz, sv32_bare_sz;
uint64_t g_pg_sz, vs_pg_sz, exp_trn_sz, exp_pa;
volatile uint64_t temp1;
device_context_t DC;
process_context_t PC;
Expand Down Expand Up @@ -67,10 +69,12 @@ main(void) {
cap.dbg = 1;
cap.pas = 50;
cap.pd20 = cap.pd17 = cap.pd8 = 1;

sv57_bare_sz = sv48_bare_sz = sv39_bare_sz = 0x40000000;
sv32_bare_sz = 0x200000;
fail_if( ( reset_iommu(8, 40, 0xff, 3, Off, DDT_3LVL, 0xFFFFFF, 0, 0,
(FILL_IOATC_ATS_T2GPA | FILL_IOATC_ATS_ALWAYS),
cap, fctl) < 0 ) );
cap, fctl, sv57_bare_sz, sv48_bare_sz, sv39_bare_sz,
sv32_bare_sz) < 0 ) );
for ( i = MSI_ADDR_0_OFFSET; i <= MSI_ADDR_7_OFFSET; i += 16 ) {
write_register(i, 8, 0xFF);
fail_if(( read_register(i, 8) != 0xFc ));
Expand Down Expand Up @@ -1386,11 +1390,11 @@ main(void) {
} else {
temp = 0xFFF;
}
fail_if( ( ((rsp.trsp.PPN * PAGESIZE) & ~temp) != (gpte.PPN * PAGESIZE) ) );
fail_if( ( ((temp + 1) != PAGESIZE) && i == 0 ) );
fail_if( ( ((temp + 1) != 512UL * PAGESIZE) && i == 1 ) );
fail_if( ( ((temp + 1) != 512UL * 512UL * PAGESIZE) && i == 2 ) );
fail_if( ( ((temp + 1) != 512UL * 512UL * 512UL * PAGESIZE) && i == 3 ) );
g_pg_sz = (1UL << (i * 9UL)) * PAGESIZE;
exp_trn_sz = g_pg_sz > sv57_bare_sz ? sv57_bare_sz : g_pg_sz;
exp_pa = (((gpte.PPN * PAGESIZE) & ~(g_pg_sz - 1)) | (gpa & (g_pg_sz - 1))) & ~temp;
fail_if( (((rsp.trsp.PPN * PAGESIZE) & ~temp) != exp_pa) );
fail_if( ((temp + 1) != exp_trn_sz) );

// Test for walking past max levels
if ( i == 0 ) {
Expand Down Expand Up @@ -1439,10 +1443,9 @@ main(void) {
fail_if( ( rsp.trsp.S != 1 ) );
temp = rsp.trsp.PPN ^ (rsp.trsp.PPN + 1);
temp = temp * PAGESIZE | 0xFFF;
fail_if( ( i == 0 && ((temp + 1) != 2 * 512UL * PAGESIZE) ) );
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) ) );
exp_trn_sz = i == 3 ? sv57_bare_sz : i == 2 ? sv48_bare_sz :
i == 1 ? sv39_bare_sz : sv32_bare_sz;
fail_if( ((temp + 1) != exp_trn_sz) );
if ( i == 0 ) g_reg_file.fctl.gxl = 0;
if ( i == 0 ) DC.tc.SXL = 0;
}
Expand Down Expand Up @@ -1665,11 +1668,11 @@ main(void) {
} else {
temp = 0xFFF;
}
fail_if( ( ((rsp.trsp.PPN * PAGESIZE) & ~temp) != (pte.PPN * PAGESIZE) ) );
fail_if( ( ((temp + 1) != PAGESIZE) && i == 0 ) );
fail_if( ( ((temp + 1) != 512UL * PAGESIZE) && i == 1 ) );
fail_if( ( ((temp + 1) != 512UL * 512UL * PAGESIZE) && i == 2 ) );
fail_if( ( ((temp + 1) != 512UL * 512UL * 512UL * PAGESIZE) && i == 3 ) );
vs_pg_sz = (1UL << (i * 9UL)) * PAGESIZE;
exp_trn_sz = vs_pg_sz > sv57_bare_sz ? sv57_bare_sz : vs_pg_sz;
exp_pa = (((pte.PPN * PAGESIZE) & ~temp) | (gva & (vs_pg_sz - 1))) & ~temp;
fail_if( (((rsp.trsp.PPN * PAGESIZE) & ~temp) != exp_pa) );
fail_if( ((temp + 1) != exp_trn_sz) );

// Test for walking past max levels
if ( i == 0 ) {
Expand Down Expand Up @@ -1718,10 +1721,9 @@ main(void) {
fail_if( ( rsp.trsp.S != 1 ) );
temp = rsp.trsp.PPN ^ (rsp.trsp.PPN + 1);
temp = temp * PAGESIZE | 0xFFF;
fail_if( ( i == 0 && ((temp + 1) != 2 * 512UL * PAGESIZE) ) );
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) ) );
exp_trn_sz = i == 3 ? sv57_bare_sz : i == 2 ? sv48_bare_sz :
i == 1 ? sv39_bare_sz : sv32_bare_sz;
fail_if( ((temp + 1) != exp_trn_sz) );
if ( i == 0 ) g_reg_file.fctl.gxl = 0;
if ( i == 0 ) DC.tc.SXL = 0;
}
Expand Down

0 comments on commit a509008

Please sign in to comment.