Skip to content

Commit

Permalink
sw/tests: Some cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
paulsc96 committed Nov 28, 2024
1 parent db1aede commit dee9900
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 74 deletions.
75 changes: 34 additions & 41 deletions sw/tests/axirt_budget.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,36 @@
#include "regs/axi_rt.h"
#include "regs/cheshire.h"
#include "util.h"
#include "printf.h"

// transfer
#define SIZE_BEAT_BYTES 8
#define DMA_NUM_BEATS 128
#define DMA_NUM_REPS 1
#define DMA_SIZE_BYTES (SIZE_BEAT_BYTES * DMA_NUM_BEATS)
#define DMA_TOTAL_SIZE_BYTES (DMA_SIZE_BYTES * DMA_NUM_REPS)
#define DMA_SRC_STRIDE 0
#define DMA_DST_STRIDE 0
#define DMA_SRC_ADDRESS 0x10008000
#define DMA_DST_ADDRESS 0x80008000

// AXI-REALM (IDs assume default config; adapt as needed)

#define CVA6_BASE_MGR_ID 0
#define CVA6_ALLOCATED_BUDGET 0x10000000
#define CVA6_ALLOCATED_PERIOD 0x10000000
#define DMA_NUM_BEATS 128 // We assume 64b AXI data width here
#define DMA_ALLOCATED_BUDGET 0x10000000
#define DMA_ALLOCATED_PERIOD 0x10000000
#define FRAGMENTATION_SIZE_BEATS 0 // Max fragmentation applied to bursts

int main(void) {
// Immediately return an error if AXI_REALM or DMA are not present
CHECK_ASSERT(-1, chs_hw_feature_present(CHESHIRE_HW_FEATURES_AXIRT_BIT));
CHECK_ASSERT(-2, chs_hw_feature_present(CHESHIRE_HW_FEATURES_DMA_BIT));

// This test requires at least two subordinate regions
CHECK_ASSERT(-3, AXI_RT_PARAM_NUM_SUB >= 2);

// Immediately return an error if DMA is not present in cheshire
CHECK_ASSERT(-1, chs_hw_feature_present(CHESHIRE_HW_FEATURES_DMA_BIT));
// Get internal hart count
int num_int_harts = *reg32(&__base_regs, CHESHIRE_NUM_INT_HARTS_REG_OFFSET);

uint32_t cheshire_num_harts = *reg32(&__base_regs, CHESHIRE_NUM_INT_HARTS_REG_OFFSET);
// Allocate DMA buffers
volatile uint64_t dma_src_cached[DMA_NUM_BEATS];
volatile uint64_t dma_dst_cached[DMA_NUM_BEATS];

volatile uint64_t *dma_src = (volatile uint64_t *)(DMA_SRC_ADDRESS);
volatile uint64_t *dma_dst = (volatile uint64_t *)(DMA_DST_ADDRESS);
// Use pointers to uncached buffers allocated in SPM
volatile uint64_t *dma_src = dma_src_cached + (0x04000000 / sizeof(uint64_t));
volatile uint64_t *dma_dst = dma_dst_cached + (0x04000000 / sizeof(uint64_t));

uint64_t golden[DMA_NUM_BEATS]; // Declare non-volatile array for golden values
// Declare non-volatile array for golden values
uint64_t golden[DMA_NUM_BEATS];

// Enable and configure axi rt
__axirt_claim(1, 1);
Expand All @@ -53,7 +51,7 @@ int main(void) {
fence();

// Configure RT unit for all the CVA6 cores
for (uint32_t id = CVA6_BASE_MGR_ID; id < cheshire_num_harts; id++) {
for (int id = CVA6_BASE_MGR_ID; id < num_int_harts; id++) {
__axirt_set_region(0, 0xffffffff, 0, id);
__axirt_set_region(0x100000000, 0xffffffffffffffff, 1, id);
__axirt_set_budget(CVA6_ALLOCATED_BUDGET, 0, id);
Expand All @@ -64,8 +62,7 @@ int main(void) {
}

// Configure RT unit for the DMA
uint32_t chs_dma_id = CVA6_BASE_MGR_ID + cheshire_num_harts + 1;

int chs_dma_id = CVA6_BASE_MGR_ID + num_int_harts + 1;
__axirt_set_region(0, 0xffffffff, 0, chs_dma_id);
__axirt_set_region(0x100000000, 0xffffffffffffffff, 1, chs_dma_id);
__axirt_set_budget(DMA_ALLOCATED_BUDGET, 0, chs_dma_id);
Expand All @@ -75,7 +72,7 @@ int main(void) {
fence();

// Enable RT unit for all the cores
__axirt_enable(BIT_MASK(cheshire_num_harts));
__axirt_enable(BIT_MASK(num_int_harts));

// Enable RT unit for the DMA
__axirt_enable(BIT(chs_dma_id));
Expand All @@ -85,32 +82,28 @@ int main(void) {
for (int i = 0; i < DMA_NUM_BEATS; i++) {
golden[i] = 0xcafedeadbaadf00dULL + i; // Compute golden values
dma_src[i] = golden[i]; // Initialize source memory
fence();
}

// Launch blocking DMA transfer
sys_dma_2d_blk_memcpy((uintptr_t)(void *)dma_dst, (uintptr_t)(void *)dma_src, DMA_SIZE_BYTES,
DMA_DST_STRIDE, DMA_SRC_STRIDE, DMA_NUM_REPS);
// Wait for writes, then launch blocking DMA transfer
fence();
sys_dma_2d_blk_memcpy((uintptr_t)(void *)dma_dst, (uintptr_t)(void *)dma_src, sizeof(golden),
0, 0, 1);

// Check DMA transfers against gold.
for (int i = 0; i < DMA_NUM_BEATS; i++) {
CHECK_ASSERT(20, dma_dst[i] == golden[i]);
}
for (int i = 0; i < DMA_NUM_BEATS; i++) CHECK_ASSERT(20 + i, dma_dst[i] == golden[i]);

// Read budget registers for dma and compare
volatile uint32_t dma_read_budget_left =
*reg32(&__base_axirt, AXI_RT_READ_BUDGET_LEFT_4_REG_OFFSET);
volatile uint32_t dma_write_budget_left =
*reg32(&__base_axirt, AXI_RT_WRITE_BUDGET_LEFT_4_REG_OFFSET);
int dma_read_budget_left = *reg32(&__base_axirt, AXI_RT_READ_BUDGET_LEFT_0_REG_OFFSET
+ AXI_RT_PARAM_NUM_SUB * chs_dma_id * sizeof(uint32_t));
int dma_write_budget_left = *reg32(&__base_axirt, AXI_RT_WRITE_BUDGET_LEFT_0_REG_OFFSET
+ AXI_RT_PARAM_NUM_SUB * chs_dma_id * sizeof(uint32_t));

// Check budget: return 0 if (initial budget - final budget) matches the
// number of transferred bytes, otherwise return 1
volatile uint8_t dma_r_difference =
(DMA_ALLOCATED_BUDGET - dma_read_budget_left) != DMA_TOTAL_SIZE_BYTES;
volatile uint8_t dma_w_difference =
(DMA_ALLOCATED_BUDGET - dma_write_budget_left) != DMA_TOTAL_SIZE_BYTES;
int dma_r_difference = (DMA_ALLOCATED_BUDGET - dma_read_budget_left) != sizeof(golden);
int dma_w_difference = (DMA_ALLOCATED_BUDGET - dma_write_budget_left) != sizeof(golden);
// W and R are symmetric on the dma: left budgets should be equal
volatile uint8_t dma_rw_mismatch = dma_read_budget_left != dma_write_budget_left;
int dma_rw_mismatch = dma_read_budget_left != dma_write_budget_left;

return (dma_rw_mismatch | dma_r_difference | dma_w_difference);
return dma_rw_mismatch + dma_r_difference + dma_w_difference;
}
61 changes: 28 additions & 33 deletions sw/tests/axirt_budget_isolate.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,35 @@
#include "regs/cheshire.h"
#include "util.h"

// Transfer
#define SIZE_BEAT_BYTES 8
#define DMA_NUM_BEATS 32
#define DMA_NUM_REPS 8
#define DMA_SIZE_BYTES (SIZE_BEAT_BYTES * DMA_NUM_BEATS)
#define DMA_TOTAL_SIZE_BYTES (DMA_SIZE_BYTES * DMA_NUM_REPS)
#define DMA_SRC_STRIDE 0
#define DMA_DST_STRIDE 0
#define DMA_SRC_ADDRESS 0x10008000
#define DMA_DST_ADDRESS 0x80008000

// AXI-REALM (IDs assume default config; adapt as needed)
#define CVA6_BASE_MGR_ID 0
#define CVA6_ALLOCATED_BUDGET 0x10000000
#define CVA6_ALLOCATED_PERIOD 0x10000000
#define DMA_ALLOCATED_BUDGET \
(DMA_TOTAL_SIZE_BYTES / 2) // Set budget as half of the number of bytes to
// transfer. This is done intentionally to test
// isolation capabilities.
#define DMA_NUM_BEATS 32 // We assume 64b AXI data width here
#define DMA_NUM_REPS 8
// Set DMA budget as half of the number of bytes to transfer.
// This is done intentionally to test isolation capabilities.
#define DMA_ALLOCATED_BUDGET (8 * DMA_NUM_BEATS * DMA_NUM_REPS / 2)
#define DMA_ALLOCATED_PERIOD 0x10000000
#define FRAGMENTATION_SIZE_BEATS 0 // Max fragmentation applied to bursts

int main(void) {
// Immediately return an error if AXI_REALM or DMA are not present
CHECK_ASSERT(-1, chs_hw_feature_present(CHESHIRE_HW_FEATURES_AXIRT_BIT));
CHECK_ASSERT(-2, chs_hw_feature_present(CHESHIRE_HW_FEATURES_DMA_BIT));

// Immediately return an error if DMA is not present in cheshire
CHECK_ASSERT(-1, chs_hw_feature_present(CHESHIRE_HW_FEATURES_DMA_BIT));
// This test requires at least two subordinate regions
CHECK_ASSERT(-3, AXI_RT_PARAM_NUM_SUB >= 2);

uint32_t cheshire_num_harts = *reg32(&__base_regs, CHESHIRE_NUM_INT_HARTS_REG_OFFSET);
// Get internal hart count
int num_int_harts = *reg32(&__base_regs, CHESHIRE_NUM_INT_HARTS_REG_OFFSET);

volatile uint64_t *dma_src = (volatile uint64_t *)(DMA_SRC_ADDRESS);
volatile uint64_t *dma_dst = (volatile uint64_t *)(DMA_DST_ADDRESS);
// Allocate DMA buffers
volatile uint64_t dma_src_cached[DMA_NUM_BEATS];
volatile uint64_t dma_dst_cached[DMA_NUM_BEATS];

// Use pointers to uncached buffers allocated in SPM
volatile uint64_t *dma_src = dma_src_cached + (0x04000000 / sizeof(uint64_t));
volatile uint64_t *dma_dst = dma_dst_cached + (0x04000000 / sizeof(uint64_t));

// Enable and configure axi rt
__axirt_claim(1, 1);
Expand All @@ -52,7 +50,7 @@ int main(void) {
fence();

// Configure RT unit for all the CVA6 cores (adapt ID if needed).
for (uint32_t id = CVA6_BASE_MGR_ID; id < cheshire_num_harts; id++) {
for (int id = CVA6_BASE_MGR_ID; id < num_int_harts; id++) {
__axirt_set_region(0, 0xffffffff, 0, id);
__axirt_set_region(0x100000000, 0xffffffffffffffff, 1, id);
__axirt_set_budget(CVA6_ALLOCATED_BUDGET, 0, id);
Expand All @@ -63,8 +61,7 @@ int main(void) {
}

// Configure RT unit for the DMA
uint32_t chs_dma_id = CVA6_BASE_MGR_ID + cheshire_num_harts + 1;

int chs_dma_id = CVA6_BASE_MGR_ID + num_int_harts + 1;
__axirt_set_region(0, 0xffffffff, 0, chs_dma_id);
__axirt_set_region(0x100000000, 0xffffffffffffffff, 1, chs_dma_id);
__axirt_set_budget(DMA_ALLOCATED_BUDGET, 0, chs_dma_id);
Expand All @@ -74,25 +71,23 @@ int main(void) {
fence();

// Enable RT unit for all the cores
__axirt_enable(BIT_MASK(cheshire_num_harts));
__axirt_enable(BIT_MASK(num_int_harts));

// Enable RT unit for the DMA
__axirt_enable(BIT(chs_dma_id));
fence();

// Initialize src region and golden values
for (int i = 0; i < DMA_NUM_BEATS; i++) {
dma_src[i] = 0xcafedeadbaadf00dULL + i;
fence();
}
for (int i = 0; i < DMA_NUM_BEATS; i++) dma_src[i] = 0xcafedeadbaadf00dULL + i;

// Launch blocking DMA transfer
sys_dma_2d_blk_memcpy((uintptr_t)(void *)dma_dst, (uintptr_t)(void *)dma_src, DMA_SIZE_BYTES,
DMA_DST_STRIDE, DMA_SRC_STRIDE, DMA_NUM_REPS);
// Wait for writes, then launch blocking DMA transfer
fence();
sys_dma_2d_blk_memcpy((uintptr_t)(void *)dma_dst, (uintptr_t)(void *)dma_src,
sizeof(dma_src_cached), 0, 0, DMA_NUM_REPS);

// Poll isolate to check if AXI-REALM isolates the dma when the budget is
// exceeded. Should return 1 if dma is isolated.
uint8_t isolate_status = __axirt_poll_isolate(chs_dma_id);
int isolate_status = __axirt_poll_isolate(chs_dma_id);

// Return 0 if manager was correctly isolated
return !isolate_status;
Expand Down

0 comments on commit dee9900

Please sign in to comment.