From d37a0e8824182597abf31ac3f1087a5321b33ad7 Mon Sep 17 00:00:00 2001 From: Anirudha Sarangi Date: Thu, 3 Jun 2021 13:45:21 +0530 Subject: [PATCH] sw_apps: dhrystone: Add support for Microblaze Microblaze CPU support is being added into the dhrystone application through this patch. For Microblaze Dhrystone to work, it is mandatory that the design has an Axi Timer. Signed-off-by: Anirudha Sarangi Acked-by: Siva Durga Prasad Paladugu --- lib/sw_apps/dhrystone/data/dhrystone.tcl | 64 +++++++++++++++++---- lib/sw_apps/dhrystone/src/dhry.h | 47 +++++++++++++-- lib/sw_apps/dhrystone/src/dhry_1.c | 36 ++++++++++++ lib/sw_apps/dhrystone/src/platform.c | 18 ++++-- lib/sw_apps/dhrystone/src/platform_config.h | 17 ------ 5 files changed, 142 insertions(+), 40 deletions(-) delete mode 100644 lib/sw_apps/dhrystone/src/platform_config.h diff --git a/lib/sw_apps/dhrystone/data/dhrystone.tcl b/lib/sw_apps/dhrystone/data/dhrystone.tcl index de4317dd975..18bb98ac1fb 100644 --- a/lib/sw_apps/dhrystone/data/dhrystone.tcl +++ b/lib/sw_apps/dhrystone/data/dhrystone.tcl @@ -8,7 +8,7 @@ proc swapp_get_name {} { } proc swapp_get_description {} { - return "Dhrystone synthetic benchmark program for baremetal environment. Not supported for Microblaze in 2021.1."; + return "Dhrystone synthetic benchmark program for baremetal environment."; } proc check_standalone_os {} { @@ -64,23 +64,40 @@ proc check_stdout_hw {} { set hw_processor [common::get_property HW_INSTANCE $proc_instance] set proc_type [common::get_property IP_NAME [hsi::get_cells -hier $hw_processor]]; - if {($proc_type == "psu_microblaze")} { - error "This application is not supported for PMU Microblaze processor (psu_microblaze)."; - } - - if {($proc_type == "microblaze")} { - error "This application is not supported for Microblaze processor as of now."; + if {$proc_type == "psu_pmu" || $proc_type == "psu_pmc" || $proc_type == "psu_psm" || $proc_type == "psv_pmc" || $proc_type == "psv_psm" } { + #error "This application is not supported for non-standard and hardened Microblaze configurations."; } set slaves [common::get_property SLAVES [hsi::get_cells -hier [hsi::get_sw_processor]]] foreach slave $slaves { set slave_type [common::get_property IP_NAME [hsi::get_cells -hier $slave]]; - if { $slave_type == "ps7_uart" || $slave_type == "psu_uart" || $slave_type == "psv_sbsauart" } { + if { $slave_type == "ps7_uart" || $slave_type == "psu_uart" || $slave_type == "psv_sbsauart" || $slave_type == "axi_uartlite" || + $slave_type == "axi_uart16550" || $slave_type == "iomodule" || + $slave_type == "mdm" } { return; } } - error "This application requires a Uart IP in the hardware." + error "This application requires a Uart IP in the hardware." +} + +proc check_axi_timer_hw {} { + set proc_instance [hsi::get_sw_processor]; + set hw_processor [common::get_property HW_INSTANCE $proc_instance] + set proc_type [common::get_property IP_NAME [hsi::get_cells -hier $hw_processor]]; + + if {($proc_type == "microblaze")} { + set slaves [common::get_property SLAVES [hsi::get_cells -hier [hsi::get_sw_processor]]] + foreach slave $slaves { + set slave_type [common::get_property IP_NAME [hsi::get_cells -hier $slave]]; + if { $slave_type == "axi_timer" } { + return; + } + } + } else { + return; + } + error "This application requires a Axi Timer IP in the hardware." } proc check_stdout_sw {} { @@ -124,6 +141,9 @@ proc swapp_is_supported_hw {} { # check for uart peripheral check_stdout_hw; + # check for axi timer + check_axi_timer_hw; + # we require atleast 30k memory require_memory "30000"; } @@ -137,7 +157,29 @@ proc swapp_is_supported_sw {} { } proc swapp_generate {} { -# To be filled up once Microblaze support is added + # cleanup this file for writing + set fid [open "platform_config.h" "w+"]; + puts $fid "/******************************************************************************"; + puts $fid "* Copyright (c) 2010 - 2021 Xilinx, Inc. All rights reserved."; + puts $fid "* SPDX-License-Identifier: MIT"; + puts $fid "******************************************************************************/"; + puts $fid "#ifndef __PLATFORM_CONFIG_H_"; + puts $fid "#define __PLATFORM_CONFIG_H_\n"; + + puts $fid "/* declare strcpy */"; + puts $fid "#include "; + + puts $fid "\n"; + + puts $fid "/* declare functions in platform.c */"; + puts $fid "void init_platform();"; + puts $fid "void cleanup_platform();"; + + # if we have a uart16550 as stdout, then generate some config for that + generate_stdout_config $fid; + + puts $fid "#endif"; + close $fid; } proc swapp_get_linker_constraints {} { @@ -146,7 +188,7 @@ proc swapp_get_linker_constraints {} { } proc swapp_get_supported_processors {} { - return "psu_cortexa53 ps7_cortexa9 psv_cortexa72 psu_cortexr5 psv_cortexr5"; + return "microblaze psu_cortexa53 ps7_cortexa9 psv_cortexa72 psu_cortexr5 psv_cortexr5"; } proc swapp_get_supported_os {} { diff --git a/lib/sw_apps/dhrystone/src/dhry.h b/lib/sw_apps/dhrystone/src/dhry.h index 7bf83be2cd3..b10a6ae8777 100644 --- a/lib/sw_apps/dhrystone/src/dhry.h +++ b/lib/sw_apps/dhrystone/src/dhry.h @@ -343,7 +343,7 @@ * data. * * On Xilinx baremetal environment, the dhrystone app is well tested for - * Cortex-A9, Cortex-A53, Cortex-R5 processors. + * Cortex-A9, Cortex-A53, Cortex-R5, and Microblaze processors. * * Typical numbers to expect (when the Dhrystone App is compiled with -O2 optimization * with the available 2021.1 toolchains are as following: @@ -384,6 +384,19 @@ * DMIPS/Sec: 673.280151 * DMIPS/MHz: 1.795432 * + * + * For Microblaze (CPU Freq: 100000000 Hz), with D-Cache and + * I_Cache configured for 16KB: + * + * Microseconds for one run through Dhrystone: 173.160339 + * Dhrystones per Second: 5774.994141 + * DMIPS/Sec: 3.286849 + * DMIPS/MHz: 0.032868 + * Please note that Microblaze CPU being configurable, the Dhrystone + * numbers may vary significantly based on various configurations (e.g. + * D-cache and I_cache sizes). + * Also, the Microblaze application expects an Axi Timer in the design. + * *************************************************************************** */ @@ -391,7 +404,6 @@ #define __DRHY_H_ #if defined (__GNUC__) && !defined (__clang__) && !defined (__ICCARM__) -#if !defined (__MICROBLAZE__) /* Compiler and system dependent definitions: */ #include @@ -400,25 +412,35 @@ #include #include #include "xil_io.h" -#include "xpseudo_asm.h" #include "xparameters.h" #include "platform_config.h" +#if !defined (__MICROBLAZE__) #include "xtime_l.h" - +#include "xpseudo_asm.h" +#endif typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5} Enumeration; /* General definitions: */ +#if !defined (__MICROBLAZE__) #define ITERATIONS 16000000 -#define Mic_secs_Per_Second 1000000.0 +#else +#define ITERATIONS 16000 +#endif +#define Mic_secs_Per_Second 1000000.0 #define Null 0 /* Value of a Null pointer */ #define true 1 #define false 0 +#if defined (__MICROBLAZE__) +typedef u64 XTime; +#endif + #define structassign(d, s) d = s +#if !defined (__MICROBLAZE__) #if defined (__aarch64__) && !defined (ARMR5) #if !defined (versal) #define CLOCKS_PER_SEC XPAR_CPU_CORTEXA53_0_CPU_CLK_FREQ_HZ @@ -438,10 +460,24 @@ typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5} #ifdef ARMA9 #define CLOCKS_PER_SEC XPAR_CPU_CORTEXA9_CORE_CLOCK_FREQ_HZ #endif +#else +#define CLOCKS_PER_SEC XPAR_MICROBLAZE_CORE_CLOCK_FREQ_HZ +#define COUNTS_PER_SECOND XPAR_TMRCTR_0_CLOCK_FREQ_HZ +#endif #define Too_Small_Time COUNTS_PER_SECOND #define GETTIME(_t) (*_t=barebones_clock()) +/* Axi Timer specific macros used for Microblaze CPU */ +#if defined (__MICROBLAZE__) +#define MB_AXITIMER_BASEADDR XPAR_TMRCTR_0_BASEADDR +#define MB_AXITIMER_TCSR0_OFFSET 0U +#define MB_AXITIMER_TLR_OFFSET 4U +#define MB_AXITIMER_TCR_OFFSET 8U +#define MB_AXITIMER_CSR_ENABLE_TMR_MASK 0x00000080U +#define MB_AXITIMER_CSR_AUTO_RELOAD_MASK 0x00000010U +#endif + typedef int One_Thirty; typedef int One_Fifty; typedef char Capital_Letter; @@ -471,5 +507,4 @@ typedef struct record { } Rec_Type, *Rec_Pointer; #endif /* defined (__GNUC__) && !defined (__clang__) && !defined (__ICCARM__) */ -#endif /*!defined (__MICROBLAZE__)*/ #endif /* __DRHY_H_ */ diff --git a/lib/sw_apps/dhrystone/src/dhry_1.c b/lib/sw_apps/dhrystone/src/dhry_1.c index 23e5fd7ebd7..78cb0470a6a 100644 --- a/lib/sw_apps/dhrystone/src/dhry_1.c +++ b/lib/sw_apps/dhrystone/src/dhry_1.c @@ -17,6 +17,39 @@ #include "dhry.h" +#if defined (__MICROBLAZE__) +static void MB_StartAxiTimer(void) +{ + u32 ControlStatusReg; + + /* Checking if the timer is enabled */ + if(Xil_In32(MB_AXITIMER_BASEADDR + MB_AXITIMER_TCSR0_OFFSET) && + MB_AXITIMER_CSR_ENABLE_TMR_MASK) + { + return; + } + /* + * Read the current register contents such that only the necessary bits + * of the register are modified in the following operations + */ + ControlStatusReg = Xil_In32(MB_AXITIMER_BASEADDR + + MB_AXITIMER_TCSR0_OFFSET); + /* + * Remove the reset condition such that the timer counter starts running + * with the value loaded from the compare register + */ + Xil_Out32((MB_AXITIMER_BASEADDR + MB_AXITIMER_TCSR0_OFFSET), + (ControlStatusReg | MB_AXITIMER_CSR_ENABLE_TMR_MASK | + MB_AXITIMER_CSR_AUTO_RELOAD_MASK)); +} + +void XTime_GetTime(XTime *time_val) +{ + *time_val = Xil_In32((MB_AXITIMER_BASEADDR) + + (MB_AXITIMER_TCR_OFFSET)); +} +#endif + /* Porting : Timing functions * How to capture time and convert to seconds must be ported to whatever * is supported by the platform. @@ -223,6 +256,9 @@ int main () /***************/ /* Start timer */ /***************/ +#if defined (__MICROBLAZE__) + MB_StartAxiTimer(); +#endif start_time(); for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index){ diff --git a/lib/sw_apps/dhrystone/src/platform.c b/lib/sw_apps/dhrystone/src/platform.c index b702aa66883..fb1f9456c22 100644 --- a/lib/sw_apps/dhrystone/src/platform.c +++ b/lib/sw_apps/dhrystone/src/platform.c @@ -1,7 +1,7 @@ -#/****************************************************************************** -#* Copyright (c) 2010 - 2021 Xilinx, Inc. All rights reserved. -#* SPDX-License-Identifier: MIT -#******************************************************************************/ +/****************************************************************************** +* Copyright (c) 2010 - 2021 Xilinx, Inc. All rights reserved. +* SPDX-License-Identifier: MIT +******************************************************************************/ #include "xparameters.h" #include "xil_cache.h" @@ -12,8 +12,14 @@ void enable_caches() { - /* Empty function for ARM platforms */ - /* Once support for MB is added, this function will be populated */ +#if defined (__MICROBLAZE__) +#ifdef XPAR_MICROBLAZE_USE_ICACHE + Xil_ICacheEnable(); +#endif +#ifdef XPAR_MICROBLAZE_USE_DCACHE + Xil_DCacheEnable(); +#endif +#endif } void disable_caches() diff --git a/lib/sw_apps/dhrystone/src/platform_config.h b/lib/sw_apps/dhrystone/src/platform_config.h deleted file mode 100644 index 0fb2ee89f10..00000000000 --- a/lib/sw_apps/dhrystone/src/platform_config.h +++ /dev/null @@ -1,17 +0,0 @@ -#/****************************************************************************** -#* Copyright (c) 2010 - 2021 Xilinx, Inc. All rights reserved. -#* SPDX-License-Identifier: MIT -#******************************************************************************/ - -#ifndef __PLATFORM_CONFIG_H_ -#define __PLATFORM_CONFIG_H_ - -/* declare strcpy */ -#include - - -/* declare functions in platform.c */ -void init_platform(); -void cleanup_platform(); - -#endif