Commit 5482c1d3 authored by Dorel Coman's avatar Dorel Coman Committed by Oliver Horst
Browse files

memguard: removed example, it will be written in the documentation

parent 4ba6ec59
/**
* Created by Dorel Coman on 10.05.18.
*/
#include <stdint-gcc.h>
#include "../include/perfmon.h"
#include "freertos/FreeRTOS.h"
#include "freertos/core/task.h"
#include "../include/memguard.h"
#define printf xil_printf
#define MAIN_TASK_PRIORITY tskIDLE_PRIORITY + 2
#define INT_CNT_DEVICE_ID XPAR_SCUGIC_0_DEVICE_ID
#define PMU_INT_CORE0_ID (143U + 32U)
// defining the counters id to be used - there are a total of 6 counters on the A53 cluster
#define PMU_INSTR_COUNTER_ID 0
#define PMU_MEM_ACCESS_COUNTER_ID 1
// lowest priority is 248 - the higher the value the lower the priority - multiples of 8
#define PMU_OVFLOW_INT_PRIORITY 240U
// variables for XScuGic
XScuGic int_controller; /* Instance of the Interrupt Controller */
static XScuGic_Config *gic_config; /* The config params of the controller */
int enable_interrupts();
int setup_perf_mon_interrupt();
void perf_mon_interrupt_handler(void *callback_ref);
volatile int exit_loop;
uint32_t mem_accesses;
#define ARRAY_TYPE double
#define ARRAY_SIZE 12000000 //12 Mil elements = 96 MB space * 3 = 288 MB total
#define CONST 5
ARRAY_TYPE a[ARRAY_SIZE];
ARRAY_TYPE b[ARRAY_SIZE];
ARRAY_TYPE c[ARRAY_SIZE];
static void MainTask(void *arg)
{
for (int j = 0; j < ARRAY_SIZE; ++j) {
a[j] = CONST;
b[j] = CONST;
c[j] = CONST;
}
// we are using this counter for measuring how many accesses to memory
// are done while executing the below loop
pmu_write_counter(PMU_MEM_ACCESS_COUNTER_ID, 0);
// the counter will start counting 500000 instructions before overflowing
uint32_t instructions_to_count = 500000;
pmu_write_counter(PMU_INSTR_COUNTER_ID, mask_value(instructions_to_count));
exit_loop = 0;
// we need to enable the overflow interrupts for the relative counter inside the PMU
// in order to make it trigger the interrupt handler
pmu_enable_intr(PMU_INSTR_COUNTER_ID);
int i=0;
while(!exit_loop){
c[i] = a[i] + CONST * b[i];
i = (i+1 % ARRAY_SIZE);
}
printf("Total number of memory accesses: %u\n\r", mem_accesses);
vTaskSuspend(NULL);
}
int main_(void)
{
int status;
status = enable_interrupts();
if(status != XST_SUCCESS){
print("Error in setup_interrupts\n\r");
return XST_FAILURE;
}
status = setup_perf_mon_interrupt();
pmu_init_counters();
pmu_enable_counter_for_event(PMU_INSTR_COUNTER_ID, ARMV8_PMUV3_PERFCTR_INSTR_EXECUTED);
pmu_enable_counter_for_event(PMU_MEM_ACCESS_COUNTER_ID, ARMV8_PMUV3_PERFCTR_BUS_ACCESS);
xTaskCreate(MainTask, "MainTask", configMINIMAL_STACK_SIZE, NULL, MAIN_TASK_PRIORITY, NULL);
printf("Start scheduling\n\r");
vTaskStartScheduler();
}
/**
*
*/
int enable_interrupts()
{
int status;
// Initialize the interrupt controller driver
gic_config = XScuGic_LookupConfig(INT_CNT_DEVICE_ID);
if (gic_config == NULL){
xil_printf("Failed to LookupConfig\n");
return XST_FAILURE;
}
// the interrupt_controller it is used later by the various parts of the framework
status = XScuGic_CfgInitialize(&int_controller, gic_config,
gic_config->CpuBaseAddress);
if (status != XST_SUCCESS) {
xil_printf("Failed to CfgInitialize\n");
return XST_FAILURE;
}
// Perform test to ensure hw was built correctly
status = XScuGic_SelfTest(&int_controller);
if (status != XST_SUCCESS) {
xil_printf("Failed the SelfTest");
return XST_FAILURE;
}
// Setup the Interrupt System by connecting the interrupt handler to the hw handling logic
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler) XScuGic_InterruptHandler,
&int_controller);
// Enable interrupts in the ARM
Xil_ExceptionEnable();
return XST_SUCCESS;
}
/**
*
*/
int setup_perf_mon_interrupt(){
int status;
// Selecting the right PMU interrupt, in this case for CORE 0
uint32_t PMU_INT_ID = PMU_INT_CORE0_ID;
// connect the handler to the interrupt controller
status = XScuGic_Connect(&int_controller, PMU_INT_ID,
(Xil_ExceptionHandler)perf_mon_interrupt_handler,
(void *)&int_controller);
if (status != XST_SUCCESS) {
xil_printf("Failed to XScuGic_connect");
return XST_FAILURE;
}
// setting the priority of the counter interrupts low, so the timer will not be overwritten by the counters
// Trigger type = 0b01 = Active HIGH level sensitive
XScuGic_SetPriorityTriggerType(&int_controller, PMU_INT_ID, (u8)PMU_OVFLOW_INT_PRIORITY, 0b01);
// seems that the mapping doesn't work on core 0 if the cpu_id is set to 0, for core 1 works if it is set 0 or 1
XScuGic_InterruptMaptoCpu(&int_controller, (u8) (XScuGic_GetCpuID() + 1), PMU_INT_ID);
XScuGic_Enable(&int_controller, PMU_INT_ID);
return XST_SUCCESS;
}
/**
*
* @param callback_ref not used
*/
void perf_mon_interrupt_handler(void *callback_ref)
{
// we want to exit the loop once the number of instructions executed reaches 500000
exit_loop = 1;
// we are reading the amount of memory accesses before exiting the loop
mem_accesses = pmu_read_counter(PMU_MEM_ACCESS_COUNTER_ID);
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment