diff options
author | Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> | 2021-07-15 18:40:22 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-15 18:40:22 -0700 |
commit | 2fedeff3328346fcd97e8b8e68176e62a1ed7ff9 (patch) | |
tree | d8a4c6bb53d749ced89c8415f9a0f77ffb70ee1b | |
parent | b550e6090d26a19dc72b390f64e7b6573c214ef1 (diff) | |
download | freertos-git-2fedeff3328346fcd97e8b8e68176e62a1ed7ff9.tar.gz |
Update BSP and SDK for HiFive board (#645)
* Update BSP and SDK for HiFive board
This commit also adds demo start and success/failure output messages.
263 files changed, 36586 insertions, 6658 deletions
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.cproject b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.cproject index 648ec1c9f..baa18f1aa 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.cproject +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.cproject @@ -1,176 +1,93 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
-
- <storageModule moduleId="org.eclipse.cdt.core.settings">
-
- <cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.debug.206163480">
-
- <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.debug.206163480" moduleId="org.eclipse.cdt.core.settings" name="Debug">
-
- <externalSettings/>
-
- <extensions>
-
- <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
-
- <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-
- <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-
- <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-
- <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
-
- <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
-
- </extensions>
-
- </storageModule>
-
- <storageModule moduleId="cdtBuildSystem" version="4.0.0">
-
- <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.debug.206163480" name="Debug" parent="cdt.managedbuild.config.gnu.cross.exe.debug">
-
- <folderInfo id="cdt.managedbuild.config.gnu.cross.exe.debug.206163480." name="/" resourcePath="">
-
- <toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.debug.1023181676" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.debug">
-
- <option id="cdt.managedbuild.option.gnu.cross.path.2116215758" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${eclipse_home}/SiFive/riscv64-unknown-elf-gcc-8.3.0-2019.08.0/bin" valueType="string"/>
-
- <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.1119183919" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
-
- <builder buildPath="${workspace_loc:/RTOSDemo}/Debug" id="cdt.managedbuild.builder.gnu.cross.1388532167" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.builder.gnu.cross"/>
-
- <tool command="riscv64-unknown-elf-gcc" id="cdt.managedbuild.tool.gnu.cross.c.compiler.1469975065" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
-
- <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.option.optimization.level.440219377" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
-
- <option id="gnu.c.compiler.option.debugging.level.1721555429" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/>
-
- <option id="gnu.c.compiler.option.dialect.std.1648189865" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
-
- <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.include.paths.1720192082" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
-
- <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/include}""/>
-
- <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/full_demo/Common_Demo_Tasks/include}""/>
-
- <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}}""/>
-
- <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/portable/GCC/RISC-V}""/>
-
- <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/include}""/>
-
- <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/freedom-metal}""/>
-
- <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/bsp/install/include}""/>
-
- </option>
-
- <option id="gnu.c.compiler.option.misc.other.257964774" name="Other flags" superClass="gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-c -fmessage-length=0 -march=rv32imac -mabi=ilp32 -mcmodel=medlow -ffunction-sections -fdata-sections --specs=nano.specs -Wno-unused-parameter" valueType="string"/>
-
- <option id="gnu.c.compiler.option.warnings.extrawarn.1802410957" name="Extra warnings (-Wextra)" superClass="gnu.c.compiler.option.warnings.extrawarn" useByScannerDiscovery="false" value="true" valueType="boolean"/>
-
- <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1079251302" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
-
- </tool>
-
- <tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.420742449" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler">
-
- <option id="gnu.cpp.compiler.option.optimization.level.1056760450" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
-
- <option id="gnu.cpp.compiler.option.debugging.level.52506316" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
-
- </tool>
-
- <tool command="riscv64-unknown-elf-gcc" id="cdt.managedbuild.tool.gnu.cross.c.linker.558060359" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker">
-
- <option id="gnu.c.link.option.ldflags.46965227" name="Linker flags" superClass="gnu.c.link.option.ldflags" useByScannerDiscovery="false" value="-Xlinker --gc-sections -Wl,-Map,RTOSDemo.map -T../bsp/metal.default.lds -march=rv32imac -mabi=ilp32 -mcmodel=medlow -Wl,--start-group -lc -lgcc -Wl,--end-group --specs=nano.specs" valueType="string"/>
-
- <option id="gnu.c.link.option.nostart.1038463237" name="Do not use standard start files (-nostartfiles)" superClass="gnu.c.link.option.nostart" useByScannerDiscovery="false" value="true" valueType="boolean"/>
-
- <option id="gnu.c.link.option.nostdlibs.934043026" name="No startup or default libs (-nostdlib)" superClass="gnu.c.link.option.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean"/>
-
- <option id="gnu.c.link.option.nodeflibs.1095611620" name="Do not use default libraries (-nodefaultlibs)" superClass="gnu.c.link.option.nodeflibs" useByScannerDiscovery="false" value="false" valueType="boolean"/>
-
- <inputType id="cdt.managedbuild.tool.gnu.c.linker.input.549526426" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
-
- <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
-
- <additionalInput kind="additionalinput" paths="$(LIBS)"/>
-
- </inputType>
-
- </tool>
-
- <tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.2105463183" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker"/>
-
- <tool id="cdt.managedbuild.tool.gnu.cross.archiver.424513814" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
-
- <tool command="riscv64-unknown-elf-gcc" id="cdt.managedbuild.tool.gnu.cross.assembler.825438707" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
-
- <option id="gnu.both.asm.option.flags.1946908814" name="Assembler flags" superClass="gnu.both.asm.option.flags" useByScannerDiscovery="false" value="-march=rv32imac -mabi=ilp32 -mcmodel=medlow -c -DportasmHANDLE_INTERRUPT=handle_trap -g3" valueType="string"/>
-
- <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.both.asm.option.include.paths.1448234506" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
-
- <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions}""/>
-
- </option>
-
- <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1723023894" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
-
- </tool>
-
- </toolChain>
-
- </folderInfo>
-
- <sourceEntries>
-
- <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
-
- </sourceEntries>
-
- </configuration>
-
- </storageModule>
-
- <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
-
- </cconfiguration>
-
- </storageModule>
-
- <storageModule moduleId="cdtBuildSystem" version="4.0.0">
-
- <project id="RTOSDemo.cdt.managedbuild.target.gnu.cross.exe.1669036252" name="Executable" projectType="cdt.managedbuild.target.gnu.cross.exe"/>
-
- </storageModule>
-
- <storageModule moduleId="scannerConfiguration">
-
- <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-
- <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.206163480;cdt.managedbuild.config.gnu.cross.exe.debug.206163480.;cdt.managedbuild.tool.gnu.cross.c.compiler.1469975065;cdt.managedbuild.tool.gnu.c.compiler.input.1079251302">
-
- <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
-
- </scannerConfigBuildInfo>
-
- </storageModule>
-
- <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
-
- <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
-
- <storageModule moduleId="refreshScope" versionNumber="2">
-
- <configuration configurationName="Debug">
-
- <resource resourceType="PROJECT" workspacePath="/RTOSDemo"/>
-
- </configuration>
-
- </storageModule>
-
-</cproject>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage"> + <storageModule moduleId="org.eclipse.cdt.core.settings"> + <cconfiguration id="cdt.managedbuild.config.gnu.cross.exe.debug.206163480"> + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.cross.exe.debug.206163480" moduleId="org.eclipse.cdt.core.settings" name="Debug"> + <externalSettings/> + <extensions> + <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> + <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> + <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> + </extensions> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.cross.exe.debug.206163480" name="Debug" parent="cdt.managedbuild.config.gnu.cross.exe.debug" postbuildStep="riscv64-unknown-elf-objcopy -O binary ${ProjName} ${ProjName}.bin"> + <folderInfo id="cdt.managedbuild.config.gnu.cross.exe.debug.206163480." name="/" resourcePath=""> + <toolChain id="cdt.managedbuild.toolchain.gnu.cross.exe.debug.1023181676" name="Cross GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.debug"> + <option id="cdt.managedbuild.option.gnu.cross.path.2116215758" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path" useByScannerDiscovery="false" value="${eclipse_home}/SiFive/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8/bin" valueType="string"/> + <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.1119183919" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/> + <builder buildPath="${workspace_loc:/RTOSDemo}/Debug" id="cdt.managedbuild.builder.gnu.cross.1388532167" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.builder.gnu.cross"/> + <tool command="riscv64-unknown-elf-gcc" id="cdt.managedbuild.tool.gnu.cross.c.compiler.1469975065" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler"> + <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.option.optimization.level.440219377" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/> + <option id="gnu.c.compiler.option.debugging.level.1721555429" name="Debug Level" superClass="gnu.c.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.c.debugging.level.max" valueType="enumerated"/> + <option id="gnu.c.compiler.option.dialect.std.1648189865" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" useByScannerDiscovery="true" value="gnu.c.compiler.dialect.default" valueType="enumerated"/> + <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.include.paths.1720192082" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath"> + <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/include}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/full_demo/Common_Demo_Tasks/include}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/portable/GCC/RISC-V}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/include}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/freedom-metal}""/> + <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/bsp/install/include}""/> + </option> + <option id="gnu.c.compiler.option.misc.other.257964774" name="Other flags" superClass="gnu.c.compiler.option.misc.other" useByScannerDiscovery="false" value="-c -fmessage-length=0 -march=rv32imac -mabi=ilp32 -mcmodel=medlow -ffunction-sections -fdata-sections --specs=nano.specs -Wno-unused-parameter" valueType="string"/> + <option id="gnu.c.compiler.option.warnings.extrawarn.1802410957" name="Extra warnings (-Wextra)" superClass="gnu.c.compiler.option.warnings.extrawarn" useByScannerDiscovery="false" value="true" valueType="boolean"/> + <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1079251302" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> + </tool> + <tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.420742449" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler"> + <option id="gnu.cpp.compiler.option.optimization.level.1056760450" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/> + <option id="gnu.cpp.compiler.option.debugging.level.52506316" name="Debug Level" superClass="gnu.cpp.compiler.option.debugging.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/> + </tool> + <tool command="riscv64-unknown-elf-gcc" id="cdt.managedbuild.tool.gnu.cross.c.linker.558060359" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"> + <option id="gnu.c.link.option.ldflags.46965227" name="Linker flags" superClass="gnu.c.link.option.ldflags" useByScannerDiscovery="false" value="-Xlinker --gc-sections -Wl,-Map,RTOSDemo.map -T../bsp/metal.default.lds -march=rv32imac -mabi=ilp32 -mcmodel=medlow -Wl,--start-group -lc -lgcc -Wl,--end-group --specs=nano.specs" valueType="string"/> + <option id="gnu.c.link.option.nostart.1038463237" name="Do not use standard start files (-nostartfiles)" superClass="gnu.c.link.option.nostart" useByScannerDiscovery="false" value="true" valueType="boolean"/> + <option id="gnu.c.link.option.nostdlibs.934043026" name="No startup or default libs (-nostdlib)" superClass="gnu.c.link.option.nostdlibs" useByScannerDiscovery="false" value="false" valueType="boolean"/> + <option id="gnu.c.link.option.nodeflibs.1095611620" name="Do not use default libraries (-nodefaultlibs)" superClass="gnu.c.link.option.nodeflibs" useByScannerDiscovery="false" value="false" valueType="boolean"/> + <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.link.option.other.875927818" name="Other options (-Xlinker [option])" superClass="gnu.c.link.option.other" useByScannerDiscovery="false" valueType="stringList"> + <listOptionValue builtIn="false" value="--defsym=__heap_max=1"/> + </option> + <inputType id="cdt.managedbuild.tool.gnu.c.linker.input.549526426" superClass="cdt.managedbuild.tool.gnu.c.linker.input"> + <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> + <additionalInput kind="additionalinput" paths="$(LIBS)"/> + </inputType> + </tool> + <tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.2105463183" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker"/> + <tool id="cdt.managedbuild.tool.gnu.cross.archiver.424513814" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/> + <tool command="riscv64-unknown-elf-gcc" id="cdt.managedbuild.tool.gnu.cross.assembler.825438707" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler"> + <option id="gnu.both.asm.option.flags.1946908814" name="Assembler flags" superClass="gnu.both.asm.option.flags" useByScannerDiscovery="false" value="-march=rv32imac -mabi=ilp32 -mcmodel=medlow -c -DportasmHANDLE_INTERRUPT=handle_trap -g3" valueType="string"/> + <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.both.asm.option.include.paths.1448234506" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" useByScannerDiscovery="false" valueType="includePath"> + <listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/FreeRTOS_Source/portable/GCC/RISC-V/chip_specific_extensions/RV32I_CLINT_no_extensions}""/> + </option> + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1723023894" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> + </tool> + </toolChain> + </folderInfo> + <sourceEntries> + <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/> + </sourceEntries> + </configuration> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> + </cconfiguration> + </storageModule> + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> + <project id="RTOSDemo.cdt.managedbuild.target.gnu.cross.exe.1669036252" name="Executable" projectType="cdt.managedbuild.target.gnu.cross.exe"/> + </storageModule> + <storageModule moduleId="scannerConfiguration"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.206163480;cdt.managedbuild.config.gnu.cross.exe.debug.206163480.;cdt.managedbuild.tool.gnu.cross.c.compiler.1469975065;cdt.managedbuild.tool.gnu.c.compiler.input.1079251302"> + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> + </scannerConfigBuildInfo> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/> + <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/> + <storageModule moduleId="refreshScope" versionNumber="2"> + <configuration configurationName="Debug"> + <resource resourceType="PROJECT" workspacePath="/RTOSDemo"/> + </configuration> + </storageModule> + <storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/> +</cproject>
\ No newline at end of file diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.project b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.project index f22f74077..f5bd48af5 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.project +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.project @@ -1,303 +1,303 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>RTOSDemo</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
- <triggers>clean,full,incremental,</triggers>
- <arguments>
- </arguments>
- </buildCommand>
- <buildCommand>
- <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
- <triggers>full,incremental,</triggers>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.cdt.core.cnature</nature>
- <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
- <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
- </natures>
- <linkedResources>
- <link>
- <name>FreeRTOS_Source</name>
- <type>2</type>
- <locationURI>FREERTOS_ROOT/FreeRTOS/Source</locationURI>
- </link>
- <link>
- <name>full_demo/Common_Demo_Tasks</name>
- <type>2</type>
- <locationURI>FREERTOS_ROOT/FreeRTOS/Demo/Common/Minimal</locationURI>
- </link>
- <link>
- <name>full_demo/Common_Demo_Tasks/include</name>
- <type>2</type>
- <locationURI>FREERTOS_ROOT/FreeRTOS/Demo/Common/include</locationURI>
- </link>
- </linkedResources>
- <filteredResources>
- <filter>
- <id>1570727806810</id>
- <name>FreeRTOS_Source</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-event_groups.c</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570727806825</id>
- <name>FreeRTOS_Source</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-list.c</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570727806841</id>
- <name>FreeRTOS_Source</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-queue.c</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570727806841</id>
- <name>FreeRTOS_Source</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-stream_buffer.c</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570727806841</id>
- <name>FreeRTOS_Source</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-timers.c</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570727806856</id>
- <name>FreeRTOS_Source</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-tasks.c</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570727892841</id>
- <name>FreeRTOS_Source/include</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-event_groups.h</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570727892856</id>
- <name>FreeRTOS_Source/include</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-FreeRTOS.h</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570727892856</id>
- <name>FreeRTOS_Source/include</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-message_buffer.h</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570727892856</id>
- <name>FreeRTOS_Source/include</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-queue.h</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570727892872</id>
- <name>FreeRTOS_Source/include</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-semphr.h</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570727892872</id>
- <name>FreeRTOS_Source/include</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-stream_buffer.h</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570727892888</id>
- <name>FreeRTOS_Source/include</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-task.h</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570727892888</id>
- <name>FreeRTOS_Source/include</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-timers.h</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570727962643</id>
- <name>FreeRTOS_Source/portable</name>
- <type>9</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-MemMang</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570727962643</id>
- <name>FreeRTOS_Source/portable</name>
- <type>9</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-GCC</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1571005814144</id>
- <name>full_demo/Common_Demo_Tasks</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-TimerDemo.c</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1571005814150</id>
- <name>full_demo/Common_Demo_Tasks</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-blocktim.c</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1571005814159</id>
- <name>full_demo/Common_Demo_Tasks</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-dynamic.c</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1571005814167</id>
- <name>full_demo/Common_Demo_Tasks</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-TaskNotify.c</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570727992991</id>
- <name>FreeRTOS_Source/portable/GCC</name>
- <type>9</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-RISC-V</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570727979500</id>
- <name>FreeRTOS_Source/portable/MemMang</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-heap_4.c</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1571005832815</id>
- <name>full_demo/Common_Demo_Tasks/include</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-TimerDemo.h</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1571005832820</id>
- <name>full_demo/Common_Demo_Tasks/include</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-blocktim.h</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1571005832824</id>
- <name>full_demo/Common_Demo_Tasks/include</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-dynamic.h</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1571005832829</id>
- <name>full_demo/Common_Demo_Tasks/include</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-MessageBufferDemo.h</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1571005832835</id>
- <name>full_demo/Common_Demo_Tasks/include</name>
- <type>5</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-TaskNotify.h</arguments>
- </matcher>
- </filter>
- <filter>
- <id>1570728021983</id>
- <name>FreeRTOS_Source/portable/GCC/RISC-V/chip_specific_extensions</name>
- <type>9</type>
- <matcher>
- <id>org.eclipse.ui.ide.multiFilter</id>
- <arguments>1.0-name-matches-false-false-RV32I_CLINT_no_extensions</arguments>
- </matcher>
- </filter>
- </filteredResources>
- <variableList>
- <variable>
- <name>FREERTOS_ROOT</name>
- <value>$%7BPARENT-3-PROJECT_LOC%7D</value>
- </variable>
- </variableList>
-</projectDescription>
+<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>RTOSDemo</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name> + <triggers>clean,full,incremental,</triggers> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name> + <triggers>full,incremental,</triggers> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.cdt.core.cnature</nature> + <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature> + <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature> + </natures> + <linkedResources> + <link> + <name>FreeRTOS_Source</name> + <type>2</type> + <locationURI>FREERTOS_ROOT/FreeRTOS/Source</locationURI> + </link> + <link> + <name>full_demo/Common_Demo_Tasks</name> + <type>2</type> + <locationURI>FREERTOS_ROOT/FreeRTOS/Demo/Common/Minimal</locationURI> + </link> + <link> + <name>full_demo/Common_Demo_Tasks/include</name> + <type>2</type> + <locationURI>FREERTOS_ROOT/FreeRTOS/Demo/Common/include</locationURI> + </link> + </linkedResources> + <filteredResources> + <filter> + <id>1570727806810</id> + <name>FreeRTOS_Source</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-event_groups.c</arguments> + </matcher> + </filter> + <filter> + <id>1570727806825</id> + <name>FreeRTOS_Source</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-list.c</arguments> + </matcher> + </filter> + <filter> + <id>1570727806841</id> + <name>FreeRTOS_Source</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-queue.c</arguments> + </matcher> + </filter> + <filter> + <id>1570727806841</id> + <name>FreeRTOS_Source</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-stream_buffer.c</arguments> + </matcher> + </filter> + <filter> + <id>1570727806841</id> + <name>FreeRTOS_Source</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-timers.c</arguments> + </matcher> + </filter> + <filter> + <id>1570727806856</id> + <name>FreeRTOS_Source</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-tasks.c</arguments> + </matcher> + </filter> + <filter> + <id>1570727892841</id> + <name>FreeRTOS_Source/include</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-event_groups.h</arguments> + </matcher> + </filter> + <filter> + <id>1570727892856</id> + <name>FreeRTOS_Source/include</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-FreeRTOS.h</arguments> + </matcher> + </filter> + <filter> + <id>1570727892856</id> + <name>FreeRTOS_Source/include</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-message_buffer.h</arguments> + </matcher> + </filter> + <filter> + <id>1570727892856</id> + <name>FreeRTOS_Source/include</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-queue.h</arguments> + </matcher> + </filter> + <filter> + <id>1570727892872</id> + <name>FreeRTOS_Source/include</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-semphr.h</arguments> + </matcher> + </filter> + <filter> + <id>1570727892872</id> + <name>FreeRTOS_Source/include</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-stream_buffer.h</arguments> + </matcher> + </filter> + <filter> + <id>1570727892888</id> + <name>FreeRTOS_Source/include</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-task.h</arguments> + </matcher> + </filter> + <filter> + <id>1570727892888</id> + <name>FreeRTOS_Source/include</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-timers.h</arguments> + </matcher> + </filter> + <filter> + <id>1570727962643</id> + <name>FreeRTOS_Source/portable</name> + <type>9</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-MemMang</arguments> + </matcher> + </filter> + <filter> + <id>1570727962643</id> + <name>FreeRTOS_Source/portable</name> + <type>9</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-GCC</arguments> + </matcher> + </filter> + <filter> + <id>1571005814144</id> + <name>full_demo/Common_Demo_Tasks</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-TimerDemo.c</arguments> + </matcher> + </filter> + <filter> + <id>1571005814150</id> + <name>full_demo/Common_Demo_Tasks</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-blocktim.c</arguments> + </matcher> + </filter> + <filter> + <id>1571005814159</id> + <name>full_demo/Common_Demo_Tasks</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-dynamic.c</arguments> + </matcher> + </filter> + <filter> + <id>1571005814167</id> + <name>full_demo/Common_Demo_Tasks</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-TaskNotify.c</arguments> + </matcher> + </filter> + <filter> + <id>1570727992991</id> + <name>FreeRTOS_Source/portable/GCC</name> + <type>9</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-RISC-V</arguments> + </matcher> + </filter> + <filter> + <id>1570727979500</id> + <name>FreeRTOS_Source/portable/MemMang</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-heap_4.c</arguments> + </matcher> + </filter> + <filter> + <id>1571005832815</id> + <name>full_demo/Common_Demo_Tasks/include</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-TimerDemo.h</arguments> + </matcher> + </filter> + <filter> + <id>1571005832820</id> + <name>full_demo/Common_Demo_Tasks/include</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-blocktim.h</arguments> + </matcher> + </filter> + <filter> + <id>1571005832824</id> + <name>full_demo/Common_Demo_Tasks/include</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-dynamic.h</arguments> + </matcher> + </filter> + <filter> + <id>1571005832829</id> + <name>full_demo/Common_Demo_Tasks/include</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-MessageBufferDemo.h</arguments> + </matcher> + </filter> + <filter> + <id>1571005832835</id> + <name>full_demo/Common_Demo_Tasks/include</name> + <type>5</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-TaskNotify.h</arguments> + </matcher> + </filter> + <filter> + <id>1570728021983</id> + <name>FreeRTOS_Source/portable/GCC/RISC-V/chip_specific_extensions</name> + <type>9</type> + <matcher> + <id>org.eclipse.ui.ide.multiFilter</id> + <arguments>1.0-name-matches-false-false-RV32I_CLINT_no_extensions</arguments> + </matcher> + </filter> + </filteredResources> + <variableList> + <variable> + <name>FREERTOS_ROOT</name> + <value>$%7BPARENT-3-PROJECT_LOC%7D</value> + </variable> + </variableList> +</projectDescription> diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.settings/language.settings.xml b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.settings/language.settings.xml index 49f601efa..b1990cea1 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.settings/language.settings.xml +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/.settings/language.settings.xml @@ -1,26 +1,14 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<project>
-
- <configuration id="cdt.managedbuild.config.gnu.cross.exe.debug.206163480" name="Debug">
-
- <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
-
- <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
-
- <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
-
- <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
-
- <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-1852838222473283" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
-
- <language-scope id="org.eclipse.cdt.core.gcc"/>
-
- <language-scope id="org.eclipse.cdt.core.g++"/>
-
- </provider>
-
- </extension>
-
- </configuration>
-
-</project>
+<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<project> + <configuration id="cdt.managedbuild.config.gnu.cross.exe.debug.206163480" name="Debug"> + <extension point="org.eclipse.cdt.core.LanguageSettingsProvider"> + <provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/> + <provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/> + <provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/> + <provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="644150116465149599" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true"> + <language-scope id="org.eclipse.cdt.core.gcc"/> + <language-scope id="org.eclipse.cdt.core.g++"/> + </provider> + </extension> + </configuration> +</project>
\ No newline at end of file diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/FreeRTOSConfig.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/FreeRTOSConfig.h index 6f5106c9a..9ea57c84f 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/FreeRTOSConfig.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/FreeRTOSConfig.h @@ -1,102 +1,105 @@ -/*
- * FreeRTOS V202104.00
- * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-#ifndef FREERTOS_CONFIG_H
-#define FREERTOS_CONFIG_H
-
-/*-----------------------------------------------------------
- * Application specific definitions.
- *
- * These definitions should be adjusted for your particular hardware and
- * application requirements.
- *
- * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
- * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
- *
- * See http://www.freertos.org/a00110.html.
- *----------------------------------------------------------*/
-#define CLINT_CTRL_ADDR ( 0x02000000UL )
-#define configMTIME_BASE_ADDRESS ( CLINT_CTRL_ADDR + 0xBFF8UL )
-#define configMTIMECMP_BASE_ADDRESS ( CLINT_CTRL_ADDR + 0x4000UL )
-#define configUSE_PREEMPTION 1
-#define configUSE_IDLE_HOOK 0
-#define configUSE_TICK_HOOK 1
-#define configCPU_CLOCK_HZ ( 32768 )
-#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
-#define configMAX_PRIORITIES ( 7 )
-#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 120 ) /* Only needs to be this high as some demo tasks also use this constant. In production only the idle task would use this. */
-#define configTOTAL_HEAP_SIZE ( ( size_t ) 10900 )
-#define configMAX_TASK_NAME_LEN ( 16 )
-#define configUSE_TRACE_FACILITY 0
-#define configUSE_16_BIT_TICKS 0
-#define configIDLE_SHOULD_YIELD 0
-#define configUSE_MUTEXES 1
-#define configQUEUE_REGISTRY_SIZE 8
-#define configCHECK_FOR_STACK_OVERFLOW 2
-#define configUSE_RECURSIVE_MUTEXES 1
-#define configUSE_MALLOC_FAILED_HOOK 1
-#define configUSE_APPLICATION_TASK_TAG 0
-#define configUSE_COUNTING_SEMAPHORES 1
-#define configGENERATE_RUN_TIME_STATS 0
-#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
-
-/* Co-routine definitions. */
-#define configUSE_CO_ROUTINES 0
-#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
-
-/* Software timer definitions. */
-#define configUSE_TIMERS 1
-#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
-#define configTIMER_QUEUE_LENGTH 8
-#define configTIMER_TASK_STACK_DEPTH ( 160 )
-
-/* Task priorities. Allow these to be overridden. */
-#ifndef uartPRIMARY_PRIORITY
- #define uartPRIMARY_PRIORITY ( configMAX_PRIORITIES - 3 )
-#endif
-
-/* Set the following definitions to 1 to include the API function, or zero
-to exclude the API function. */
-#define INCLUDE_vTaskPrioritySet 1
-#define INCLUDE_uxTaskPriorityGet 1
-#define INCLUDE_vTaskDelete 1
-#define INCLUDE_vTaskCleanUpResources 1
-#define INCLUDE_vTaskSuspend 1
-#define INCLUDE_vTaskDelayUntil 1
-#define INCLUDE_vTaskDelay 1
-#define INCLUDE_eTaskGetState 1
-#define INCLUDE_xTimerPendFunctionCall 1
-#define INCLUDE_xTaskAbortDelay 1
-#define INCLUDE_xTaskGetHandle 1
-#define INCLUDE_xSemaphoreGetMutexHolder 1
-
-/* Normal assert() semantics without relying on the provision of an assert.h
-header file. */
-void vAssertCalled( void );
-#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled()
-
-#endif /* FREERTOS_CONFIG_H */
+/* + * FreeRTOS V202104.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ +#define CLINT_CTRL_ADDR ( 0x02000000UL ) +#define configMTIME_BASE_ADDRESS ( CLINT_CTRL_ADDR + 0xBFF8UL ) +#define configMTIMECMP_BASE_ADDRESS ( CLINT_CTRL_ADDR + 0x4000UL ) +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 1 +#define configCPU_CLOCK_HZ ( 32768 ) +#define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) +#define configMAX_PRIORITIES ( 7 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 120 ) /* Only needs to be this high as some demo tasks also use this constant. In production only the idle task would use this. */ +#define configTOTAL_HEAP_SIZE ( ( size_t ) 10900 ) +#define configMAX_TASK_NAME_LEN ( 16 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 0 +#define configUSE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 8 +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configUSE_APPLICATION_TASK_TAG 0 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Software timer definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define configTIMER_QUEUE_LENGTH 8 +#define configTIMER_TASK_STACK_DEPTH ( 160 ) + +/* Task priorities. Allow these to be overridden. */ +#ifndef uartPRIMARY_PRIORITY + #define uartPRIMARY_PRIORITY ( configMAX_PRIORITIES - 3 ) +#endif + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTaskAbortDelay 1 +#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_xSemaphoreGetMutexHolder 1 + +/* Normal assert() semantics without relying on the provision of an assert.h +header file. */ +void vAssertCalled( void ); +#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled() + +/* Map to the platform write function. */ +#define configPRINT_STRING( pcString ) write( STDOUT_FILENO, pcString, strlen( pcString ) ) + +#endif /* FREERTOS_CONFIG_H */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/SiFive_HiFive1_RTOS_demo.url b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/SiFive_HiFive1_RTOS_demo.url index 809b91304..34f8fc0bc 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/SiFive_HiFive1_RTOS_demo.url +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/SiFive_HiFive1_RTOS_demo.url @@ -1,5 +1,5 @@ -[InternetShortcut]
-URL=https://www.freertos.org/RTOS-RISC-V-FreedomStudio-IAR-HiFive-RevB.html
-IDList=
-[{000214A0-0000-0000-C000-000000000046}]
-Prop3=19,2
+[InternetShortcut] +URL=https://www.freertos.org/RTOS-RISC-V-FreedomStudio-IAR-HiFive-RevB.html +IDList= +[{000214A0-0000-0000-C000-000000000046}] +Prop3=19,2 diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/blinky_demo/main_blinky.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/blinky_demo/main_blinky.c index de0a85bf3..e4e572e1f 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/blinky_demo/main_blinky.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/blinky_demo/main_blinky.c @@ -1,197 +1,197 @@ -/*
- * FreeRTOS V202104.00
- * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-/******************************************************************************
- * NOTE 1: This project provides two demo applications. A simple blinky
- * style project, and a more comprehensive test and demo application. The
- * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select
- * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
- * in main.c. This file implements the simply blinky style version.
- *
- * NOTE 2: This file only contains the source code that is specific to the
- * blinky demo. Generic functions, such FreeRTOS hook functions, and functions
- * required to configure the hardware are defined in main.c.
- ******************************************************************************
- *
- * main_blinky() creates one queue, and two tasks. It then starts the
- * scheduler.
- *
- * The Queue Send Task:
- * The queue send task is implemented by the prvQueueSendTask() function in
- * this file. prvQueueSendTask() sits in a loop that causes it to repeatedly
- * block for 1000 milliseconds, before sending the value 100 to the queue that
- * was created within main_blinky(). Once the value is sent, the task loops
- * back around to block for another 1000 milliseconds...and so on.
- *
- * The Queue Receive Task:
- * The queue receive task is implemented by the prvQueueReceiveTask() function
- * in this file. prvQueueReceiveTask() sits in a loop where it repeatedly
- * blocks on attempts to read data from the queue that was created within
- * main_blinky(). When data is received, the task checks the value of the
- * data, and if the value equals the expected 100, toggles an LED. The 'block
- * time' parameter passed to the queue receive function specifies that the task
- * should be held in the Blocked state indefinitely to wait for data to be
- * available on the queue. The queue receive task will only leave the Blocked
- * state when the queue send task writes to the queue. As the queue send task
- * writes to the queue every 1000 milliseconds, the queue receive task leaves
- * the Blocked state every 1000 milliseconds, and therefore toggles the LED
- * every 200 milliseconds.
- */
-
-/* Standard includes. */
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-/* Kernel includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-
-/* Priorities used by the tasks. */
-#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
-#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
-
-/* The rate at which data is sent to the queue. The 200ms value is converted
-to ticks using the pdMS_TO_TICKS() macro. */
-#define mainQUEUE_SEND_FREQUENCY_MS pdMS_TO_TICKS( 1000 )
-
-/* The maximum number items the queue can hold. The priority of the receiving
-task is above the priority of the sending task, so the receiving task will
-preempt the sending task and remove the queue items each time the sending task
-writes to the queue. Therefore the queue will never have more than one item in
-it at any time, and even with a queue length of 1, the sending task will never
-find the queue full. */
-#define mainQUEUE_LENGTH ( 1 )
-
-/*-----------------------------------------------------------*/
-
-/*
- * Called by main when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1 in
- * main.c.
- */
-void main_blinky( void );
-
-/*
- * The tasks as described in the comments at the top of this file.
- */
-static void prvQueueReceiveTask( void *pvParameters );
-static void prvQueueSendTask( void *pvParameters );
-
-/*-----------------------------------------------------------*/
-
-/* The queue used by both tasks. */
-static QueueHandle_t xQueue = NULL;
-
-/*-----------------------------------------------------------*/
-
-void main_blinky( void )
-{
- /* Create the queue. */
- xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) );
-
- if( xQueue != NULL )
- {
- /* Start the two tasks as described in the comments at the top of this
- file. */
- xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */
- "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
- configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
- NULL, /* The parameter passed to the task - not used in this case. */
- mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
- NULL ); /* The task handle is not required, so NULL is passed. */
-
- xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
-
- /* Start the tasks and timer running. */
- vTaskStartScheduler();
- }
-
- /* If all is well, the scheduler will now be running, and the following
- line will never be reached. If the following line does execute, then
- there was insufficient FreeRTOS heap memory available for the Idle and/or
- timer tasks to be created. See the memory management section on the
- FreeRTOS web site for more details on the FreeRTOS heap
- http://www.freertos.org/a00111.html. */
- for( ;; );
-}
-/*-----------------------------------------------------------*/
-
-static void prvQueueSendTask( void *pvParameters )
-{
-TickType_t xNextWakeTime;
-const unsigned long ulValueToSend = 100UL;
-BaseType_t xReturned;
-
- /* Remove compiler warning about unused parameter. */
- ( void ) pvParameters;
-
- /* Initialise xNextWakeTime - this only needs to be done once. */
- xNextWakeTime = xTaskGetTickCount();
-
- for( ;; )
- {
- /* Place this task in the blocked state until it is time to run again. */
- vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS );
-
- /* Send to the queue - causing the queue receive task to unblock and
- toggle the LED. 0 is used as the block time so the sending operation
- will not block - it shouldn't need to block as the queue should always
- be empty at this point in the code. */
- xReturned = xQueueSend( xQueue, &ulValueToSend, 0U );
- configASSERT( xReturned == pdPASS );
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvQueueReceiveTask( void *pvParameters )
-{
-unsigned long ulReceivedValue;
-const unsigned long ulExpectedValue = 100UL;
-extern void vToggleLED( void );
-
- /* Remove compiler warning about unused parameter. */
- ( void ) pvParameters;
-
- for( ;; )
- {
- /* Wait until something arrives in the queue - this task will block
- indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
- FreeRTOSConfig.h. */
- xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
-
- /* To get here something must have been received from the queue, but
- is it the expected value? If it is, toggle the LED. */
- if( ulReceivedValue == ulExpectedValue )
- {
- vToggleLED();
- ulReceivedValue = 0U;
- }
- }
-}
-/*-----------------------------------------------------------*/
-
+/* + * FreeRTOS V202104.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/****************************************************************************** + * NOTE 1: This project provides two demo applications. A simple blinky + * style project, and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select + * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY + * in main.c. This file implements the simply blinky style version. + * + * NOTE 2: This file only contains the source code that is specific to the + * blinky demo. Generic functions, such FreeRTOS hook functions, and functions + * required to configure the hardware are defined in main.c. + ****************************************************************************** + * + * main_blinky() creates one queue, and two tasks. It then starts the + * scheduler. + * + * The Queue Send Task: + * The queue send task is implemented by the prvQueueSendTask() function in + * this file. prvQueueSendTask() sits in a loop that causes it to repeatedly + * block for 1000 milliseconds, before sending the value 100 to the queue that + * was created within main_blinky(). Once the value is sent, the task loops + * back around to block for another 1000 milliseconds...and so on. + * + * The Queue Receive Task: + * The queue receive task is implemented by the prvQueueReceiveTask() function + * in this file. prvQueueReceiveTask() sits in a loop where it repeatedly + * blocks on attempts to read data from the queue that was created within + * main_blinky(). When data is received, the task checks the value of the + * data, and if the value equals the expected 100, toggles an LED. The 'block + * time' parameter passed to the queue receive function specifies that the task + * should be held in the Blocked state indefinitely to wait for data to be + * available on the queue. The queue receive task will only leave the Blocked + * state when the queue send task writes to the queue. As the queue send task + * writes to the queue every 1000 milliseconds, the queue receive task leaves + * the Blocked state every 1000 milliseconds, and therefore toggles the LED + * every 200 milliseconds. + */ + +/* Standard includes. */ +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +/* Priorities used by the tasks. */ +#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 ) + +/* The rate at which data is sent to the queue. The 200ms value is converted +to ticks using the pdMS_TO_TICKS() macro. */ +#define mainQUEUE_SEND_FREQUENCY_MS pdMS_TO_TICKS( 1000 ) + +/* The maximum number items the queue can hold. The priority of the receiving +task is above the priority of the sending task, so the receiving task will +preempt the sending task and remove the queue items each time the sending task +writes to the queue. Therefore the queue will never have more than one item in +it at any time, and even with a queue length of 1, the sending task will never +find the queue full. */ +#define mainQUEUE_LENGTH ( 1 ) + +/*-----------------------------------------------------------*/ + +/* + * Called by main when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1 in + * main.c. + */ +void main_blinky( void ); + +/* + * The tasks as described in the comments at the top of this file. + */ +static void prvQueueReceiveTask( void *pvParameters ); +static void prvQueueSendTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +/* The queue used by both tasks. */ +static QueueHandle_t xQueue = NULL; + +/*-----------------------------------------------------------*/ + +void main_blinky( void ) +{ + /* Create the queue. */ + xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) ); + + if( xQueue != NULL ) + { + /* Start the two tasks as described in the comments at the top of this + file. */ + xTaskCreate( prvQueueReceiveTask, /* The function that implements the task. */ + "Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */ + configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */ + NULL, /* The parameter passed to the task - not used in this case. */ + mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */ + NULL ); /* The task handle is not required, so NULL is passed. */ + + xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); + + /* Start the tasks and timer running. */ + vTaskStartScheduler(); + } + + /* If all is well, the scheduler will now be running, and the following + line will never be reached. If the following line does execute, then + there was insufficient FreeRTOS heap memory available for the Idle and/or + timer tasks to be created. See the memory management section on the + FreeRTOS web site for more details on the FreeRTOS heap + http://www.freertos.org/a00111.html. */ + for( ;; ); +} +/*-----------------------------------------------------------*/ + +static void prvQueueSendTask( void *pvParameters ) +{ +TickType_t xNextWakeTime; +const unsigned long ulValueToSend = 100UL; +BaseType_t xReturned; + + /* Remove compiler warning about unused parameter. */ + ( void ) pvParameters; + + /* Initialise xNextWakeTime - this only needs to be done once. */ + xNextWakeTime = xTaskGetTickCount(); + + for( ;; ) + { + /* Place this task in the blocked state until it is time to run again. */ + vTaskDelayUntil( &xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS ); + + /* Send to the queue - causing the queue receive task to unblock and + toggle the LED. 0 is used as the block time so the sending operation + will not block - it shouldn't need to block as the queue should always + be empty at this point in the code. */ + xReturned = xQueueSend( xQueue, &ulValueToSend, 0U ); + configASSERT( xReturned == pdPASS ); + } +} +/*-----------------------------------------------------------*/ + +static void prvQueueReceiveTask( void *pvParameters ) +{ +unsigned long ulReceivedValue; +const unsigned long ulExpectedValue = 100UL; +extern void vToggleLED( void ); + + /* Remove compiler warning about unused parameter. */ + ( void ) pvParameters; + + for( ;; ) + { + /* Wait until something arrives in the queue - this task will block + indefinitely provided INCLUDE_vTaskSuspend is set to 1 in + FreeRTOSConfig.h. */ + xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY ); + + /* To get here something must have been received from the queue, but + is it the expected value? If it is, toggle the LED. */ + if( ulReceivedValue == ulExpectedValue ) + { + vToggleLED(); + ulReceivedValue = 0U; + } + } +} +/*-----------------------------------------------------------*/ + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/README.md b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/README.md new file mode 100644 index 000000000..f5abca5bf --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/README.md @@ -0,0 +1,13 @@ +HiFive1 Rev B is a low-cost, Arduino-compatible development board featuring the Freedom E310. It’s the best way to start prototyping and developing your RISC‑V applications. + +This target is ideal for getting familiar with the RISC-V ISA instruction set and the freedom-metal libraries. It supports: + +- 1 hart with RV32IMAC core +- 4 hardware breakpoints +- Physical Memory Protection with 8 regions +- 16 local interrupts signal that can be connected to off core complex devices +- Up to 127 PLIC interrupt signals that can be connected to off core complex devices, with 7 priority levels +- GPIO memory with 16 interrupt lines +- SPI memory with 1 interrupt line +- Serial port with 1 interrupt line +- 1 RGB LEDS diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/core.dts b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/core.dts new file mode 100644 index 000000000..f68e58441 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/core.dts @@ -0,0 +1,262 @@ +/dts-v1/; +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "sifive,hifive1-revb"; + model = "sifive,hifive1-revb"; + cpus { + #address-cells = <1>; + #size-cells = <0>; + compatible = "sifive,fe310-g000"; + L6: cpu@0 { + clocks = <&hfclk>; + compatible = "sifive,rocket0", "riscv"; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <16384>; + next-level-cache = <&spi0>; + reg = <0>; + riscv,isa = "rv32imac"; + riscv,pmpregions = <8>; + sifive,itim = <&itim>; + sifive,dtim = <&dtim>; + status = "okay"; + timebase-frequency = <16000000>; + hardware-exec-breakpoint-count = <4>; + hlic: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + }; + soc { + #address-cells = <1>; + #size-cells = <1>; + #clock-cells = <1>; + compatible = "sifive,hifive1"; + ranges; + hfxoscin: clock@0 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <16000000>; + }; + hfxoscout: clock@1 { + compatible = "sifive,fe310-g000,hfxosc"; + clocks = <&hfxoscin>; + reg = <&prci 0x4>; + reg-names = "config"; + }; + hfroscin: clock@2 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <72000000>; + }; + hfroscout: clock@3 { + compatible = "sifive,fe310-g000,hfrosc"; + clocks = <&hfroscin>; + reg = <&prci 0x0>; + reg-names = "config"; + }; + hfclk: clock@4 { + compatible = "sifive,fe310-g000,pll"; + clocks = <&hfxoscout &hfroscout>; + clock-names = "pllref", "pllsel0"; + reg = <&prci 0x8 &prci 0xc>; + reg-names = "config", "divider"; + clock-frequency = <16000000>; + }; + lfrosc: clock@5 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + }; + psdlfaltclk: clock@6 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + }; + lfclk: clock@7 { + compatible = "sifive,fe310-g000,lfrosc"; + clocks = <&lfrosc &psdlfaltclk>; + clock-names = "lfrosc", "psdlfaltclk"; + reg = <&aon 0x70 &aon 0x7C>; + reg-names = "config", "mux"; + }; + debug-controller@0 { + compatible = "sifive,debug-011", "riscv,debug-011"; + interrupts-extended = <&hlic 65535>; + reg = <0x0 0x1000>; + reg-names = "control"; + }; + /* Missing: Error device */ + maskrom@1000 { + reg = <0x1000 0x2000>; + reg-names = "mem"; + }; + otp@20000 { + reg = <0x20000 0x2000 0x10010000 0x1000>; + reg-names = "mem", "control"; + }; + clint: clint@2000000 { + compatible = "riscv,clint0"; + interrupts-extended = <&hlic 3 &hlic 7>; + reg = <0x2000000 0x10000>; + reg-names = "control"; + }; + itim: itim@8000000 { + compatible = "sifive,itim0"; + reg = <0x8000000 0x2000>; + reg-names = "mem"; + }; + plic: interrupt-controller@c000000 { + #interrupt-cells = <1>; + compatible = "riscv,plic0"; + interrupt-controller; + interrupts-extended = <&hlic 11>; + reg = <0xc000000 0x4000000>; + reg-names = "control"; + riscv,max-priority = <7>; + riscv,ndev = <52>; + }; + aon: aon@10000000 { + compatible = "sifive,aon0"; + reg = <0x10000000 0x8000>; + reg-names = "mem"; + interrupt-parent = <&plic>; + interrupts = <1 2>; + clocks = <&lfclk>; + }; + prci: prci@10008000 { + compatible = "sifive,fe310-g000,prci"; + reg = <0x10008000 0x8000>; + reg-names = "mem"; + }; + gpio0: gpio@10012000 { + compatible = "sifive,gpio0"; + interrupt-parent = <&plic>; + interrupts = <8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + 23 24 25 26 27 28 29 30 31 32 33 34 35 36 + 27 28 29>; + reg = <0x10012000 0x1000>; + reg-names = "control"; + }; + led@0 { + compatible = "sifive,gpio-leds"; + label = "LD0red"; + gpios = <&gpio0 22>; + linux,default-trigger = "none"; + }; + led@1 { + compatible = "sifive,gpio-leds"; + label = "LD0green"; + gpios = <&gpio0 19>; + linux,default-trigger = "none"; + }; + led@2 { + compatible = "sifive,gpio-leds"; + label = "LD0blue"; + gpios = <&gpio0 21>; + linux,default-trigger = "none"; + }; + uart0: serial@10013000 { + compatible = "sifive,uart0"; + interrupt-parent = <&plic>; + interrupts = <3>; + reg = <0x10013000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0x30000>; + }; + spi0: spi@10014000 { + compatible = "sifive,spi0"; + interrupt-parent = <&plic>; + interrupts = <5>; + reg = <0x10014000 0x1000 0x20000000 0x7A120>; + reg-names = "control", "mem"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0x0>; + #address-cells = <1>; + #size-cells = <1>; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x20000000 0x424000>; + }; + }; + pwm0: pwm@10015000 { + compatible = "sifive,pwm0"; + sifive,comparator-widthbits = <8>; + sifive,ncomparators = <4>; + interrupt-parent = <&plic>; + interrupts = <40 41 42 43>; + reg = <0x10015000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0F 0x0F>; + }; + i2c0: i2c@10016000 { + compatible = "sifive,i2c0"; + interrupt-parent = <&plic>; + interrupts = <52>; + reg = <0x10016000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0x3000>; + }; + uart1: serial@10023000 { + compatible = "sifive,uart0"; + interrupt-parent = <&plic>; + interrupts = <4>; + reg = <0x10023000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0x840000>; + }; + spi1: spi@10024000 { + compatible = "sifive,spi0"; + interrupt-parent = <&plic>; + interrupts = <6>; + reg = <0x10024000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0x0003C>; + }; + pwm1: pwm@10025000 { + compatible = "sifive,pwm0"; + sifive,comparator-widthbits = <16>; + sifive,ncomparators = <4>; + interrupt-parent = <&plic>; + interrupts = <44 45 46 47>; + reg = <0x10025000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x780000 0x780000>; + }; + spi2: spi@10034000 { + compatible = "sifive,spi0"; + interrupt-parent = <&plic>; + interrupts = <7>; + reg = <0x10034000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0xFC000000>; + }; + pwm2: pwm@10035000 { + compatible = "sifive,pwm0"; + sifive,comparator-widthbits = <16>; + sifive,ncomparators = <4>; + interrupt-parent = <&plic>; + interrupts = <48 49 50 51>; + reg = <0x10035000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x3C00 0x3C00>; + }; + dtim: dtim@80000000 { + compatible = "sifive,dtim0"; + reg = <0x80000000 0x4000>; + reg-names = "mem"; + }; + }; +}; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.dts b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.dts index 970d3be72..098c25c4b 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.dts +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.dts @@ -1,209 +1,10 @@ -/dts-v1/; - +/include/ "core.dts" / { - #address-cells = <1>; - #size-cells = <1>; - compatible = "sifive,hifive1-revb"; - model = "sifive,hifive1-revb"; - - chosen { - stdout-path = "/soc/serial@10013000:115200"; - metal,entry = <&spi0 0x10000>; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - compatible = "sifive,fe310-g000"; - L6: cpu@0 { - clocks = <&hfclk>; - compatible = "sifive,rocket0", "riscv"; - device_type = "cpu"; - i-cache-block-size = <64>; - i-cache-sets = <128>; - i-cache-size = <16384>; - next-level-cache = <&spi0>; - reg = <0>; - riscv,isa = "rv32imac"; - riscv,pmpregions = <8>; - sifive,dtim = <&dtim>; - status = "okay"; - timebase-frequency = <1000000>; - hardware-exec-breakpoint-count = <4>; - hlic: interrupt-controller { - #interrupt-cells = <1>; - compatible = "riscv,cpu-intc"; - interrupt-controller; - }; - }; - }; - - soc { - #address-cells = <1>; - #size-cells = <1>; - #clock-cells = <1>; - compatible = "sifive,hifive1"; - ranges; - hfxoscin: clock@0 { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <16000000>; - }; - hfxoscout: clock@1 { - compatible = "sifive,fe310-g000,hfxosc"; - clocks = <&hfxoscin>; - reg = <&prci 0x4>; - reg-names = "config"; - }; - hfroscin: clock@2 { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <72000000>; - }; - hfroscout: clock@3 { - compatible = "sifive,fe310-g000,hfrosc"; - clocks = <&hfroscin>; - reg = <&prci 0x0>; - reg-names = "config"; - }; - hfclk: clock@4 { - compatible = "sifive,fe310-g000,pll"; - clocks = <&hfxoscout &hfroscout>; - clock-names = "pllref", "pllsel0"; - reg = <&prci 0x8 &prci 0xc>; - reg-names = "config", "divider"; - clock-frequency = <16000000>; - }; - - lfroscin: clock@5 { - #clock-cells = <0>; - compatible = "fixed-clock"; - clock-frequency = <32000000>; - }; - lfclk: clock@6 { - compatible = "sifive,fe310-g000,lfrosc"; - clocks = <&lfroscin>; - reg = <&aon 0x70>; - reg-names = "config"; - }; - - aon: aon@10000000 { - compatible = "sifive,aon0"; - reg = <0x10000000 0x8000>; - reg-names = "mem"; - }; - - prci: prci@10008000 { - compatible = "sifive,fe310-g000,prci"; - reg = <0x10008000 0x8000>; - reg-names = "mem"; - }; - - clint: clint@2000000 { - compatible = "riscv,clint0"; - interrupts-extended = <&hlic 3 &hlic 7>; - reg = <0x2000000 0x10000>; - reg-names = "control"; - }; - local-external-interrupts-0 { - compatible = "sifive,local-external-interrupts0"; - interrupt-parent = <&hlic>; - interrupts = <16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31>; - }; - plic: interrupt-controller@c000000 { - #interrupt-cells = <1>; - compatible = "riscv,plic0"; - interrupt-controller; - interrupts-extended = <&hlic 11>; - reg = <0xc000000 0x4000000>; - reg-names = "control"; - riscv,max-priority = <7>; - riscv,ndev = <26>; - }; - global-external-interrupts { - compatile = "sifive,global-external-interrupts0"; - interrupt-parent = <&plic>; - interrupts = <1 2 3 4>; - }; - - debug-controller@0 { - compatible = "sifive,debug-011", "riscv,debug-011"; - interrupts-extended = <&hlic 65535>; - reg = <0x0 0x100>; - reg-names = "control"; - }; - - maskrom@1000 { - reg = <0x1000 0x2000>; - reg-names = "mem"; - }; - otp@20000 { - reg = <0x20000 0x2000 0x10010000 0x1000>; - reg-names = "mem", "control"; - }; - - dtim: dtim@80000000 { - compatible = "sifive,dtim0"; - reg = <0x80000000 0x4000>; - reg-names = "mem"; - }; - - pwm@10015000 { - compatible = "sifive,pwm0"; - interrupt-parent = <&plic>; - interrupts = <23 24 25 26>; - reg = <0x10015000 0x1000>; - reg-names = "control"; - }; - gpio0: gpio@10012000 { - compatible = "sifive,gpio0"; - interrupt-parent = <&plic>; - interrupts = <7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22>; - reg = <0x10012000 0x1000>; - reg-names = "control"; - }; - uart0: serial@10013000 { - compatible = "sifive,uart0"; - interrupt-parent = <&plic>; - interrupts = <5>; - reg = <0x10013000 0x1000>; - reg-names = "control"; - clocks = <&hfclk>; - pinmux = <&gpio0 0x30000 0x30000>; - }; - spi0: spi@10014000 { - compatible = "sifive,spi0"; - interrupt-parent = <&plic>; - interrupts = <6>; - reg = <0x10014000 0x1000 0x20000000 0x7A120>; - reg-names = "control", "mem"; - clocks = <&hfclk>; - pinmux = <&gpio0 0x0003C 0x0003C>; - }; - i2c0: i2c@10016000 { - compatible = "sifive,i2c0"; - interrupt-parent = <&plic>; - interrupts = <52>; - reg = <0x10016000 0x1000>; - reg-names = "control"; - }; - led@0red { - compatible = "sifive,gpio-leds"; - label = "LD0red"; - gpios = <&gpio0 22>; - linux,default-trigger = "none"; - }; - led@0green { - compatible = "sifive,gpio-leds"; - label = "LD0green"; - gpios = <&gpio0 19>; - linux,default-trigger = "none"; - }; - led@0blue { - compatible = "sifive,gpio-leds"; - label = "LD0blue"; - gpios = <&gpio0 21>; - linux,default-trigger = "none"; - }; - }; + chosen { + metal,entry = <&spi0 1 65536>; + metal,boothart = <&L6>; + stdout-path = "/soc/serial@10013000:115200"; + metal,itim = <&itim 0 0>; + metal,ram = <&dtim 0 0>; + }; }; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.svd b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.svd new file mode 100644 index 000000000..3ad2768bd --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/design.svd @@ -0,0 +1,3169 @@ +<?xml version="1.0" encoding="utf-8"?> +<device schemaVersion="1.3" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="CMSIS-SVD.xsd"> + <name>sifive_hifive1_revb</name> + <version>0.1</version> + <description>From sifive,hifive1-revb,model device generator</description> + <addressUnitBits>8</addressUnitBits> + <width>32</width> + <size>32</size> + <access>read-write</access> + <peripherals> + <peripheral> + <name>riscv_clint0_0</name> + <description>From riscv,clint0,control peripheral generator</description> + <baseAddress>0x2000000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x10000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>msip_0</name> + <description>MSIP Register for hart 0</description> + <addressOffset>0x0</addressOffset> + </register> + <register> + <name>mtimecmp_0</name> + <description>MTIMECMP Register for hart 0</description> + <addressOffset>0x4000</addressOffset> + <size>64</size> + </register> + <register> + <name>mtime</name> + <description>MTIME Register</description> + <addressOffset>0xBFF8</addressOffset> + <size>64</size> + </register> + </registers> + </peripheral> + <peripheral> + <name>riscv_plic0_0</name> + <description>From riscv,plic0,control peripheral generator</description> + <baseAddress>0xC000000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x4000000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>priority_1</name> + <description>PRIORITY Register for interrupt id 1</description> + <addressOffset>0x4</addressOffset> + </register> + <register> + <name>priority_2</name> + <description>PRIORITY Register for interrupt id 2</description> + <addressOffset>0x8</addressOffset> + </register> + <register> + <name>priority_3</name> + <description>PRIORITY Register for interrupt id 3</description> + <addressOffset>0xC</addressOffset> + </register> + <register> + <name>priority_4</name> + <description>PRIORITY Register for interrupt id 4</description> + <addressOffset>0x10</addressOffset> + </register> + <register> + <name>priority_5</name> + <description>PRIORITY Register for interrupt id 5</description> + <addressOffset>0x14</addressOffset> + </register> + <register> + <name>priority_6</name> + <description>PRIORITY Register for interrupt id 6</description> + <addressOffset>0x18</addressOffset> + </register> + <register> + <name>priority_7</name> + <description>PRIORITY Register for interrupt id 7</description> + <addressOffset>0x1C</addressOffset> + </register> + <register> + <name>priority_8</name> + <description>PRIORITY Register for interrupt id 8</description> + <addressOffset>0x20</addressOffset> + </register> + <register> + <name>priority_9</name> + <description>PRIORITY Register for interrupt id 9</description> + <addressOffset>0x24</addressOffset> + </register> + <register> + <name>priority_10</name> + <description>PRIORITY Register for interrupt id 10</description> + <addressOffset>0x28</addressOffset> + </register> + <register> + <name>priority_11</name> + <description>PRIORITY Register for interrupt id 11</description> + <addressOffset>0x2C</addressOffset> + </register> + <register> + <name>priority_12</name> + <description>PRIORITY Register for interrupt id 12</description> + <addressOffset>0x30</addressOffset> + </register> + <register> + <name>priority_13</name> + <description>PRIORITY Register for interrupt id 13</description> + <addressOffset>0x34</addressOffset> + </register> + <register> + <name>priority_14</name> + <description>PRIORITY Register for interrupt id 14</description> + <addressOffset>0x38</addressOffset> + </register> + <register> + <name>priority_15</name> + <description>PRIORITY Register for interrupt id 15</description> + <addressOffset>0x3C</addressOffset> + </register> + <register> + <name>priority_16</name> + <description>PRIORITY Register for interrupt id 16</description> + <addressOffset>0x40</addressOffset> + </register> + <register> + <name>priority_17</name> + <description>PRIORITY Register for interrupt id 17</description> + <addressOffset>0x44</addressOffset> + </register> + <register> + <name>priority_18</name> + <description>PRIORITY Register for interrupt id 18</description> + <addressOffset>0x48</addressOffset> + </register> + <register> + <name>priority_19</name> + <description>PRIORITY Register for interrupt id 19</description> + <addressOffset>0x4C</addressOffset> + </register> + <register> + <name>priority_20</name> + <description>PRIORITY Register for interrupt id 20</description> + <addressOffset>0x50</addressOffset> + </register> + <register> + <name>priority_21</name> + <description>PRIORITY Register for interrupt id 21</description> + <addressOffset>0x54</addressOffset> + </register> + <register> + <name>priority_22</name> + <description>PRIORITY Register for interrupt id 22</description> + <addressOffset>0x58</addressOffset> + </register> + <register> + <name>priority_23</name> + <description>PRIORITY Register for interrupt id 23</description> + <addressOffset>0x5C</addressOffset> + </register> + <register> + <name>priority_24</name> + <description>PRIORITY Register for interrupt id 24</description> + <addressOffset>0x60</addressOffset> + </register> + <register> + <name>priority_25</name> + <description>PRIORITY Register for interrupt id 25</description> + <addressOffset>0x64</addressOffset> + </register> + <register> + <name>priority_26</name> + <description>PRIORITY Register for interrupt id 26</description> + <addressOffset>0x68</addressOffset> + </register> + <register> + <name>priority_27</name> + <description>PRIORITY Register for interrupt id 27</description> + <addressOffset>0x6C</addressOffset> + </register> + <register> + <name>priority_28</name> + <description>PRIORITY Register for interrupt id 28</description> + <addressOffset>0x70</addressOffset> + </register> + <register> + <name>priority_29</name> + <description>PRIORITY Register for interrupt id 29</description> + <addressOffset>0x74</addressOffset> + </register> + <register> + <name>priority_30</name> + <description>PRIORITY Register for interrupt id 30</description> + <addressOffset>0x78</addressOffset> + </register> + <register> + <name>priority_31</name> + <description>PRIORITY Register for interrupt id 31</description> + <addressOffset>0x7C</addressOffset> + </register> + <register> + <name>priority_32</name> + <description>PRIORITY Register for interrupt id 32</description> + <addressOffset>0x80</addressOffset> + </register> + <register> + <name>priority_33</name> + <description>PRIORITY Register for interrupt id 33</description> + <addressOffset>0x84</addressOffset> + </register> + <register> + <name>priority_34</name> + <description>PRIORITY Register for interrupt id 34</description> + <addressOffset>0x88</addressOffset> + </register> + <register> + <name>priority_35</name> + <description>PRIORITY Register for interrupt id 35</description> + <addressOffset>0x8C</addressOffset> + </register> + <register> + <name>priority_36</name> + <description>PRIORITY Register for interrupt id 36</description> + <addressOffset>0x90</addressOffset> + </register> + <register> + <name>priority_37</name> + <description>PRIORITY Register for interrupt id 37</description> + <addressOffset>0x94</addressOffset> + </register> + <register> + <name>priority_38</name> + <description>PRIORITY Register for interrupt id 38</description> + <addressOffset>0x98</addressOffset> + </register> + <register> + <name>priority_39</name> + <description>PRIORITY Register for interrupt id 39</description> + <addressOffset>0x9C</addressOffset> + </register> + <register> + <name>priority_40</name> + <description>PRIORITY Register for interrupt id 40</description> + <addressOffset>0xA0</addressOffset> + </register> + <register> + <name>priority_41</name> + <description>PRIORITY Register for interrupt id 41</description> + <addressOffset>0xA4</addressOffset> + </register> + <register> + <name>priority_42</name> + <description>PRIORITY Register for interrupt id 42</description> + <addressOffset>0xA8</addressOffset> + </register> + <register> + <name>priority_43</name> + <description>PRIORITY Register for interrupt id 43</description> + <addressOffset>0xAC</addressOffset> + </register> + <register> + <name>priority_44</name> + <description>PRIORITY Register for interrupt id 44</description> + <addressOffset>0xB0</addressOffset> + </register> + <register> + <name>priority_45</name> + <description>PRIORITY Register for interrupt id 45</description> + <addressOffset>0xB4</addressOffset> + </register> + <register> + <name>priority_46</name> + <description>PRIORITY Register for interrupt id 46</description> + <addressOffset>0xB8</addressOffset> + </register> + <register> + <name>priority_47</name> + <description>PRIORITY Register for interrupt id 47</description> + <addressOffset>0xBC</addressOffset> + </register> + <register> + <name>priority_48</name> + <description>PRIORITY Register for interrupt id 48</description> + <addressOffset>0xC0</addressOffset> + </register> + <register> + <name>priority_49</name> + <description>PRIORITY Register for interrupt id 49</description> + <addressOffset>0xC4</addressOffset> + </register> + <register> + <name>priority_50</name> + <description>PRIORITY Register for interrupt id 50</description> + <addressOffset>0xC8</addressOffset> + </register> + <register> + <name>priority_51</name> + <description>PRIORITY Register for interrupt id 51</description> + <addressOffset>0xCC</addressOffset> + </register> + <register> + <name>priority_52</name> + <description>PRIORITY Register for interrupt id 52</description> + <addressOffset>0xD0</addressOffset> + </register> + <register> + <name>pending_0</name> + <description>PENDING Register for interrupt ids 31 to 0</description> + <addressOffset>0x1000</addressOffset> + </register> + <register> + <name>pending_1</name> + <description>PENDING Register for interrupt ids 52 to 32</description> + <addressOffset>0x1004</addressOffset> + </register> + <register> + <name>enable_0_0</name> + <description>ENABLE Register for interrupt ids 31 to 0 for hart 0</description> + <addressOffset>0x2000</addressOffset> + </register> + <register> + <name>enable_1_0</name> + <description>ENABLE Register for interrupt ids 52 to 32 for hart 0</description> + <addressOffset>0x2004</addressOffset> + </register> + <register> + <name>threshold_0</name> + <description>PRIORITY THRESHOLD Register for hart 0</description> + <addressOffset>0x200000</addressOffset> + </register> + <register> + <name>claimplete_0</name> + <description>CLAIM and COMPLETE Register for hart 0</description> + <addressOffset>0x200004</addressOffset> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_aon0_0</name> + <description>From sifive,aon0,mem peripheral generator</description> + <baseAddress>0x10000000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x8000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>backup_0</name> + <description>Backup Register 0</description> + <addressOffset>0x80</addressOffset> + </register> + <register> + <name>backup_1</name> + <description>Backup Register 1</description> + <addressOffset>0x84</addressOffset> + </register> + <register> + <name>backup_2</name> + <description>Backup Register 2</description> + <addressOffset>0x88</addressOffset> + </register> + <register> + <name>backup_3</name> + <description>Backup Register 3</description> + <addressOffset>0x8C</addressOffset> + </register> + <register> + <name>backup_4</name> + <description>Backup Register 4</description> + <addressOffset>0x90</addressOffset> + </register> + <register> + <name>backup_5</name> + <description>Backup Register 5</description> + <addressOffset>0x94</addressOffset> + </register> + <register> + <name>backup_6</name> + <description>Backup Register 6</description> + <addressOffset>0x98</addressOffset> + </register> + <register> + <name>backup_7</name> + <description>Backup Register 7</description> + <addressOffset>0x9C</addressOffset> + </register> + <register> + <name>backup_8</name> + <description>Backup Register 8</description> + <addressOffset>0xA0</addressOffset> + </register> + <register> + <name>backup_9</name> + <description>Backup Register 9</description> + <addressOffset>0xA4</addressOffset> + </register> + <register> + <name>backup_10</name> + <description>Backup Register 10</description> + <addressOffset>0xA8</addressOffset> + </register> + <register> + <name>backup_11</name> + <description>Backup Register 11</description> + <addressOffset>0xAC</addressOffset> + </register> + <register> + <name>backup_12</name> + <description>Backup Register 12</description> + <addressOffset>0xB0</addressOffset> + </register> + <register> + <name>backup_13</name> + <description>Backup Register 13</description> + <addressOffset>0xB4</addressOffset> + </register> + <register> + <name>backup_14</name> + <description>Backup Register 14</description> + <addressOffset>0xB8</addressOffset> + </register> + <register> + <name>backup_15</name> + <description>Backup Register 15</description> + <addressOffset>0xBC</addressOffset> + </register> + <register> + <name>wdogcfg</name> + <description>wdog Configuration</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>wdogscale</name> + <description>Counter scale value.</description> + <bitRange>[3:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wdogrsten</name> + <description>Controls whether the comparator output can set the wdogrst bit and hence cause a full reset.</description> + <bitRange>[8:8]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wdogzerocmp</name> + <description>Reset counter to zero after match.</description> + <bitRange>[9:9]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wdogenalways</name> + <description>Enable Always - run continuously</description> + <bitRange>[12:12]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wdogcoreawake</name> + <description>Increment the watchdog counter if the processor is not asleep</description> + <bitRange>[13:13]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wdogip0</name> + <description>Interrupt 0 Pending</description> + <bitRange>[28:28]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>wdogcount</name> + <description>Counter Register</description> + <addressOffset>0x8</addressOffset> + </register> + <register> + <name>wdogs</name> + <description>Scaled value of Counter</description> + <addressOffset>0x10</addressOffset> + </register> + <register> + <name>wdogfeed</name> + <description>Feed register</description> + <addressOffset>0x18</addressOffset> + </register> + <register> + <name>wdogkey</name> + <description>Key Register</description> + <addressOffset>0x1C</addressOffset> + </register> + <register> + <name>wdogcmp0</name> + <description>Comparator 0</description> + <addressOffset>0x20</addressOffset> + </register> + <register> + <name>rtccfg</name> + <description>rtc Configuration</description> + <addressOffset>0x40</addressOffset> + <fields> + <field> + <name>rtcscale</name> + <description>Counter scale value.</description> + <bitRange>[3:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rtcenalways</name> + <description>Enable Always - run continuously</description> + <bitRange>[12:12]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rtcip0</name> + <description>Interrupt 0 Pending</description> + <bitRange>[28:28]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>rtccountlo</name> + <description>Low bits of Counter</description> + <addressOffset>0x48</addressOffset> + </register> + <register> + <name>rtccounthi</name> + <description>High bits of Counter</description> + <addressOffset>0x4C</addressOffset> + </register> + <register> + <name>rtcs</name> + <description>Scaled value of Counter</description> + <addressOffset>0x50</addressOffset> + </register> + <register> + <name>rtccmp0</name> + <description>Comparator 0</description> + <addressOffset>0x60</addressOffset> + </register> + <register> + <name>pmuwakeupi0</name> + <description>Wakeup program instruction 0</description> + <addressOffset>0x100</addressOffset> + </register> + <register> + <name>pmuwakeupi1</name> + <description>Wakeup program instruction 1</description> + <addressOffset>0x104</addressOffset> + </register> + <register> + <name>pmuwakeupi2</name> + <description>Wakeup program instruction 2</description> + <addressOffset>0x108</addressOffset> + </register> + <register> + <name>pmuwakeupi3</name> + <description>Wakeup program instruction 3</description> + <addressOffset>0x10C</addressOffset> + </register> + <register> + <name>pmuwakeupi4</name> + <description>Wakeup program instruction 4</description> + <addressOffset>0x110</addressOffset> + </register> + <register> + <name>pmuwakeupi5</name> + <description>Wakeup program instruction 5</description> + <addressOffset>0x114</addressOffset> + </register> + <register> + <name>pmuwakeupi6</name> + <description>Wakeup program instruction 6</description> + <addressOffset>0x118</addressOffset> + </register> + <register> + <name>pmuwakeupi7</name> + <description>Wakeup program instruction 7</description> + <addressOffset>0x11C</addressOffset> + </register> + <register> + <name>pmusleepi0</name> + <description>Sleep program instruction 0</description> + <addressOffset>0x120</addressOffset> + </register> + <register> + <name>pmusleepi1</name> + <description>Sleep program instruction 1</description> + <addressOffset>0x124</addressOffset> + </register> + <register> + <name>pmusleepi2</name> + <description>Sleep program instruction 2</description> + <addressOffset>0x128</addressOffset> + </register> + <register> + <name>pmusleepi3</name> + <description>Sleep program instruction 3</description> + <addressOffset>0x12C</addressOffset> + </register> + <register> + <name>pmusleepi4</name> + <description>Sleep program instruction 4</description> + <addressOffset>0x130</addressOffset> + </register> + <register> + <name>pmusleepi5</name> + <description>Sleep program instruction 5</description> + <addressOffset>0x134</addressOffset> + </register> + <register> + <name>pmusleepi6</name> + <description>Sleep program instruction 6</description> + <addressOffset>0x138</addressOffset> + </register> + <register> + <name>pmusleepi7</name> + <description>Sleep program instruction 7</description> + <addressOffset>0x13C</addressOffset> + </register> + <register> + <name>pmuie</name> + <description>PMU Interrupt Enables</description> + <addressOffset>0x140</addressOffset> + </register> + <register> + <name>pmucause</name> + <description>PMU Wakeup Cause</description> + <addressOffset>0x144</addressOffset> + </register> + <register> + <name>pmusleep</name> + <description>Initiate PMU Sleep Sequence</description> + <addressOffset>0x148</addressOffset> + </register> + <register> + <name>pmukey</name> + <description>PMU Key. Reads as 1 when PMU is unlocked</description> + <addressOffset>0x14C</addressOffset> + </register> + <register> + <name>aoncfg</name> + <description>AON Block Configuration Information</description> + <addressOffset>0x300</addressOffset> + <fields> + <field> + <name>has_bandgap</name> + <description>Bandgap feature is present</description> + <bitRange>[0:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>has_bod</name> + <description>Brownout detector feature is present</description> + <bitRange>[1:1]</bitRange> + <access>read-only</access> + </field> + <field> + <name>has_lfrosc</name> + <description>Low Frequency Ring Oscillator feature is present</description> + <bitRange>[2:2]</bitRange> + <access>read-only</access> + </field> + <field> + <name>has_lfrcosc</name> + <description>Low Frequency RC Oscillator feature is present</description> + <bitRange>[3:3]</bitRange> + <access>read-only</access> + </field> + <field> + <name>has_lfxosc</name> + <description>Low Frequency Crystal Oscillator feature is present</description> + <bitRange>[4:4]</bitRange> + <access>read-only</access> + </field> + <field> + <name>has_por</name> + <description>Power-On-Reset feature is present</description> + <bitRange>[5:5]</bitRange> + <access>read-only</access> + </field> + <field> + <name>has_ldo</name> + <description>Low Dropout Regulator feature is present</description> + <bitRange>[6:6]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>lfrosccfg</name> + <description>Ring Oscillator Configuration and Status</description> + <addressOffset>0x70</addressOffset> + <fields> + <field> + <name>lfroscdiv</name> + <description>Ring Oscillator Divider Register</description> + <bitRange>[5:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>lfrosctrim</name> + <description>Ring Oscillator Trim Register</description> + <bitRange>[20:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>lfroscen</name> + <description>Ring Oscillator Enable</description> + <bitRange>[30:30]</bitRange> + <access>read-write</access> + </field> + <field> + <name>lfroscrdy</name> + <description>Ring Oscillator Ready</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>lfclkmux</name> + <description>Low-Frequency Clock Mux Control and Status</description> + <addressOffset>0x7C</addressOffset> + <fields> + <field> + <name>lfextclk_sel</name> + <description>Low Frequency Clock Source Selector</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + <enumeratedValues> + <enumeratedValue> + <name>internal</name> + <description>Use internal LF clock source</description> + <value>0</value> + </enumeratedValue> + <enumeratedValue> + <name>external</name> + <description>Use external LF clock source</description> + <value>1</value> + </enumeratedValue> + </enumeratedValues> + </field> + <field> + <name>lfextclk_mux_status</name> + <description>Setting of the aon_lfclksel pin</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + <enumeratedValues> + <enumeratedValue> + <name>external</name> + <description>Use external LF clock source</description> + <value>0</value> + </enumeratedValue> + <enumeratedValue> + <name>sw</name> + <description>Use clock source selected by lfextclk_sel</description> + <value>1</value> + </enumeratedValue> + </enumeratedValues> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_fe310_g000_prci_0</name> + <description>From sifive,fe310-g000,prci,mem peripheral generator</description> + <baseAddress>0x10008000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x8000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>hfrosccfg</name> + <description>Ring Oscillator Configuration and Status</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>hfroscdiv</name> + <description>Ring Oscillator Divider Register</description> + <bitRange>[5:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>hfrosctrim</name> + <description>Ring Oscillator Trim Register</description> + <bitRange>[20:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>hfroscen</name> + <description>Ring Oscillator Enable</description> + <bitRange>[30:30]</bitRange> + <access>read-write</access> + </field> + <field> + <name>hfroscrdy</name> + <description>Ring Oscillator Ready</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>hfxosccfg</name> + <description>Crystal Oscillator Configuration and Status</description> + <addressOffset>0x4</addressOffset> + <fields> + <field> + <name>hfxoscen</name> + <description>Crystal Oscillator Enable</description> + <bitRange>[30:30]</bitRange> + <access>read-write</access> + </field> + <field> + <name>hfxoscrdy</name> + <description>Crystal Oscillator Ready</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>pllcfg</name> + <description>PLL Configuration and Status</description> + <addressOffset>0x8</addressOffset> + <fields> + <field> + <name>pllr</name> + <description>PLL R Value</description> + <bitRange>[2:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pllf</name> + <description>PLL F Value</description> + <bitRange>[9:4]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pllq</name> + <description>PLL Q Value</description> + <bitRange>[11:10]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pllsel</name> + <description>PLL Select</description> + <bitRange>[16:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pllrefsel</name> + <description>PLL Reference Select</description> + <bitRange>[17:17]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pllbypass</name> + <description>PLL Bypass</description> + <bitRange>[18:18]</bitRange> + <access>read-write</access> + </field> + <field> + <name>plllock</name> + <description>PLL Lock</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>plloutdiv</name> + <description>PLL Final Divide Configuration</description> + <addressOffset>0xC</addressOffset> + <fields> + <field> + <name>plloutdiv</name> + <description>PLL Final Divider Value</description> + <bitRange>[5:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>plloutdivby1</name> + <description>PLL Final Divide By 1</description> + <bitRange>[13:8]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>procmoncfg</name> + <description>Process Monitor Configuration and Status</description> + <addressOffset>0xF0</addressOffset> + <fields> + <field> + <name>procmon_div_sel</name> + <description>Proccess Monitor Divider</description> + <bitRange>[4:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>procmon_delay_sel</name> + <description>Process Monitor Delay Selector</description> + <bitRange>[12:8]</bitRange> + <access>read-write</access> + </field> + <field> + <name>procmon_en</name> + <description>Process Monitor Enable</description> + <bitRange>[16:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>procomon_sel</name> + <description>Process Monitor Select</description> + <bitRange>[25:24]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_gpio0_0</name> + <description>From sifive,gpio0,control peripheral generator</description> + <baseAddress>0x10012000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>input_val</name> + <description>Pin value</description> + <addressOffset>0x0</addressOffset> + </register> + <register> + <name>input_en</name> + <description>Pin input enable</description> + <addressOffset>0x4</addressOffset> + </register> + <register> + <name>output_en</name> + <description>Pin output enable</description> + <addressOffset>0x8</addressOffset> + </register> + <register> + <name>output_val</name> + <description>Output value</description> + <addressOffset>0xC</addressOffset> + </register> + <register> + <name>pue</name> + <description>Internal pull-up enable</description> + <addressOffset>0x10</addressOffset> + </register> + <register> + <name>ds</name> + <description>Pin drive strength</description> + <addressOffset>0x14</addressOffset> + </register> + <register> + <name>rise_ie</name> + <description>Rise interrupt enable</description> + <addressOffset>0x18</addressOffset> + </register> + <register> + <name>rise_ip</name> + <description>Rise interrupt pending</description> + <addressOffset>0x1C</addressOffset> + </register> + <register> + <name>fall_ie</name> + <description>Fall interrupt enable</description> + <addressOffset>0x20</addressOffset> + </register> + <register> + <name>fall_ip</name> + <description>Fall interrupt pending</description> + <addressOffset>0x24</addressOffset> + </register> + <register> + <name>high_ie</name> + <description>High interrupt enable</description> + <addressOffset>0x28</addressOffset> + </register> + <register> + <name>high_ip</name> + <description>High interrupt pending</description> + <addressOffset>0x2C</addressOffset> + </register> + <register> + <name>low_ie</name> + <description>Low interrupt enable</description> + <addressOffset>0x30</addressOffset> + </register> + <register> + <name>low_ip</name> + <description>Low interrupt pending</description> + <addressOffset>0x34</addressOffset> + </register> + <register> + <name>iof_en</name> + <description>I/O function enable</description> + <addressOffset>0x38</addressOffset> + </register> + <register> + <name>iof_sel</name> + <description>I/O function select</description> + <addressOffset>0x3C</addressOffset> + </register> + <register> + <name>out_xor</name> + <description>Output XOR (invert)</description> + <addressOffset>0x40</addressOffset> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_uart0_0</name> + <description>From sifive,uart0,control peripheral generator</description> + <baseAddress>0x10013000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>txdata</name> + <description>Transmit data register</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>data</name> + <description>Transmit data</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>full</name> + <description>Transmit FIFO full</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>rxdata</name> + <description>Receive data register</description> + <addressOffset>0x4</addressOffset> + <fields> + <field> + <name>data</name> + <description>Received data</description> + <bitRange>[7:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>empty</name> + <description>Receive FIFO empty</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>txctrl</name> + <description>Transmit control register</description> + <addressOffset>0x8</addressOffset> + <fields> + <field> + <name>txen</name> + <description>Transmit enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>nstop</name> + <description>Number of stop bits</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + <field> + <name>txcnt</name> + <description>Transmit watermark level</description> + <bitRange>[18:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>rxctrl</name> + <description>Receive control register</description> + <addressOffset>0xC</addressOffset> + <fields> + <field> + <name>rxen</name> + <description>Receive enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rxcnt</name> + <description>Receive watermark level</description> + <bitRange>[18:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ie</name> + <description>UART interrupt enable</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark interrupt enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark interrupt enable</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ip</name> + <description>UART interrupt pending</description> + <addressOffset>0x14</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark interrupt pending</description> + <bitRange>[0:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark interrupt pending</description> + <bitRange>[1:1]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>div</name> + <description>Baud rate divisor</description> + <addressOffset>0x18</addressOffset> + <fields> + <field> + <name>div</name> + <description>Baud rate divisor.</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_spi0_0</name> + <description>From sifive,spi0,control peripheral generator</description> + <baseAddress>0x10014000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>sckdiv</name> + <description>Serial clock divisor</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>div</name> + <description>Divisor for serial clock.</description> + <bitRange>[11:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>sckmode</name> + <description>Serial clock mode</description> + <addressOffset>0x4</addressOffset> + <fields> + <field> + <name>pha</name> + <description>Serial clock phase</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pol</name> + <description>Serial clock polarity</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csid</name> + <description>Chip select ID</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>csid</name> + <description>Chip select ID.</description> + <bitRange>[31:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csdef</name> + <description>Chip select default</description> + <addressOffset>0x14</addressOffset> + <fields> + <field> + <name>csdef</name> + <description>Chip select default value. Reset to all-1s.</description> + <bitRange>[31:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csmode</name> + <description>Chip select mode</description> + <addressOffset>0x18</addressOffset> + <fields> + <field> + <name>mode</name> + <description>Chip select mode</description> + <bitRange>[1:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>delay0</name> + <description>Delay control 0</description> + <addressOffset>0x28</addressOffset> + <fields> + <field> + <name>cssck</name> + <description>CS to SCK Delay</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>sckcs</name> + <description>SCK to CS Delay</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>delay1</name> + <description>Delay control 1</description> + <addressOffset>0x2C</addressOffset> + <fields> + <field> + <name>intercs</name> + <description>Minimum CS inactive time</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>interxfr</name> + <description>Maximum interframe delay</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>extradel</name> + <description>SPI extra sampling delay to increase the SPI frequency</description> + <addressOffset>0x38</addressOffset> + <fields> + <field> + <name>coarse</name> + <description>Coarse grain sample delay (multiples of system clocks)</description> + <bitRange>[11:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>fine</name> + <description>Fine grain sample delay (multiples of process-specific buffer delay)</description> + <bitRange>[16:12]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>sampledel</name> + <description>Number of delay stages from slave to the SPI controller</description> + <addressOffset>0x3C</addressOffset> + <fields> + <field> + <name>sd</name> + <description>Number of delay stages from slave to SPI controller</description> + <bitRange>[4:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>fmt</name> + <description>Frame format</description> + <addressOffset>0x40</addressOffset> + <fields> + <field> + <name>proto</name> + <description>SPI protocol</description> + <bitRange>[1:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>endian</name> + <description>SPI endianness</description> + <bitRange>[2:2]</bitRange> + <access>read-write</access> + </field> + <field> + <name>dir</name> + <description>SPI I/O direction. This is reset to 1 for flash-enabled SPI controllers, 0 otherwise.</description> + <bitRange>[3:3]</bitRange> + <access>read-write</access> + </field> + <field> + <name>len</name> + <description>Number of bits per frame</description> + <bitRange>[19:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>txdata</name> + <description>Tx FIFO Data</description> + <addressOffset>0x48</addressOffset> + <fields> + <field> + <name>data</name> + <description>Transmit data</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>full</name> + <description>FIFO full flag</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>rxdata</name> + <description>Rx FIFO data</description> + <addressOffset>0x4C</addressOffset> + <fields> + <field> + <name>data</name> + <description>Received data</description> + <bitRange>[7:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>empty</name> + <description>FIFO empty flag</description> + <bitRange>[31:31]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>txmark</name> + <description>Tx FIFO watermark</description> + <addressOffset>0x50</addressOffset> + <fields> + <field> + <name>txmark</name> + <description>Transmit watermark. The reset value is 1 for flash-enabled controllers, 0 otherwise.</description> + <bitRange>[2:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>rxmark</name> + <description>Rx FIFO watermark</description> + <addressOffset>0x54</addressOffset> + <fields> + <field> + <name>rxmark</name> + <description>Receive watermark</description> + <bitRange>[2:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>fctrl</name> + <description>SPI flash interface control</description> + <addressOffset>0x60</addressOffset> + <fields> + <field> + <name>en</name> + <description>SPI Flash Mode Select</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ffmt</name> + <description>SPI flash instruction format</description> + <addressOffset>0x64</addressOffset> + <fields> + <field> + <name>cmd_en</name> + <description>Enable sending of command</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>addr_len</name> + <description>Number of address bytes (0 to 4)</description> + <bitRange>[3:1]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pad_cnt</name> + <description>Number of dummy cycles</description> + <bitRange>[7:4]</bitRange> + <access>read-write</access> + </field> + <field> + <name>cmd_proto</name> + <description>Protocol for transmitting command</description> + <bitRange>[9:8]</bitRange> + <access>read-write</access> + </field> + <field> + <name>addr_proto</name> + <description>Protocol for transmitting address and padding</description> + <bitRange>[11:10]</bitRange> + <access>read-write</access> + </field> + <field> + <name>data_proto</name> + <description>Protocol for receiving data bytes</description> + <bitRange>[13:12]</bitRange> + <access>read-write</access> + </field> + <field> + <name>cmd_code</name> + <description>Value of command byte</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pad_code</name> + <description>First 8 bits to transmit during dummy cycles</description> + <bitRange>[31:24]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ie</name> + <description>SPI interrupt enable</description> + <addressOffset>0x70</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark enable</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ip</name> + <description>SPI interrupt pending</description> + <addressOffset>0x74</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark pending</description> + <bitRange>[0:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark pending</description> + <bitRange>[1:1]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_pwm0_0</name> + <description>From sifive,pwm0,control peripheral generator</description> + <baseAddress>0x10015000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>pwmcfg</name> + <description>PWM configuration register</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>pwmscale</name> + <description>PWM Counter scale</description> + <bitRange>[3:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmsticky</name> + <description>PWM Sticky - disallow clearing pwmcmpXip bits</description> + <bitRange>[8:8]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmzerocmp</name> + <description>PWM Zero - counter resets to zero after match</description> + <bitRange>[9:9]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmdeglitch</name> + <description>PWM Deglitch - latch pwmcmpXip within same cycle</description> + <bitRange>[10:10]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmenalways</name> + <description>PWM enable always - run continuously</description> + <bitRange>[12:12]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmenoneshot</name> + <description>PWM enable one shot - run one cycle</description> + <bitRange>[13:13]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0center</name> + <description>PWM0 Compare Center</description> + <bitRange>[16:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1center</name> + <description>PWM1 Compare Center</description> + <bitRange>[17:17]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2center</name> + <description>PWM2 Compare Center</description> + <bitRange>[18:18]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3center</name> + <description>PWM3 Compare Center</description> + <bitRange>[19:19]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0invert</name> + <description>PWM0 Invert</description> + <bitRange>[20:20]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1invert</name> + <description>PWM1 Invert</description> + <bitRange>[21:21]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2invert</name> + <description>PWM2 Invert</description> + <bitRange>[22:22]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3invert</name> + <description>PWM3 Invert</description> + <bitRange>[23:23]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0gang</name> + <description>PWM0/PWM1 Compare Gang</description> + <bitRange>[24:24]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1gang</name> + <description>PWM1/PWM2 Compare Gang</description> + <bitRange>[25:25]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2gang</name> + <description>PWM2/PWM3 Compare Gang</description> + <bitRange>[26:26]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3gang</name> + <description>PWM3/PWM0 Compare Gang</description> + <bitRange>[27:27]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0ip</name> + <description>PWM0 Interrupt Pending</description> + <bitRange>[28:28]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1ip</name> + <description>PWM1 Interrupt Pending</description> + <bitRange>[29:29]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2ip</name> + <description>PWM2 Interrupt Pending</description> + <bitRange>[30:30]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3ip</name> + <description>PWM3 Interrupt Pending</description> + <bitRange>[31:31]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcount</name> + <description>PWM count register</description> + <addressOffset>0x8</addressOffset> + <fields> + <field> + <name>pwmcount</name> + <description>PWM count register.</description> + <bitRange>[30:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwms</name> + <description>Scaled PWM count register</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>pwms</name> + <description>Scaled PWM count register.</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp0</name> + <description>PWM 0 compare register</description> + <addressOffset>0x20</addressOffset> + <fields> + <field> + <name>pwmcmp0</name> + <description>PWM 0 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp1</name> + <description>PWM 1 compare register</description> + <addressOffset>0x24</addressOffset> + <fields> + <field> + <name>pwmcmp1</name> + <description>PWM 1 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp2</name> + <description>PWM 2 compare register</description> + <addressOffset>0x28</addressOffset> + <fields> + <field> + <name>pwmcmp2</name> + <description>PWM 2 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp3</name> + <description>PWM 3 compare register</description> + <addressOffset>0x2C</addressOffset> + <fields> + <field> + <name>pwmcmp3</name> + <description>PWM 3 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_i2c0_0</name> + <description>From sifive,i2c0,control peripheral generator</description> + <baseAddress>0x10016000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>prescale_low</name> + <description>Clock Prescale register lo-byte</description> + <addressOffset>0x0</addressOffset> + </register> + <register> + <name>prescale_high</name> + <description>Clock Prescale register hi-byte</description> + <addressOffset>0x4</addressOffset> + </register> + <register> + <name>control</name> + <description>Control register</description> + <addressOffset>0x8</addressOffset> + <fields> + <field> + <name>en</name> + <description>I2C core enable bit</description> + <bitRange>[6:6]</bitRange> + <access>read-write</access> + </field> + <field> + <name>ien</name> + <description>I2C core interrupt enable bit</description> + <bitRange>[7:7]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>transmit__receive</name> + <description>Transmit and receive data byte register</description> + <addressOffset>0xC</addressOffset> + </register> + <register> + <name>command__status</name> + <description>Command write and status read register</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>wr_iack__rd_if</name> + <description>Clear interrupt and Interrupt pending</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wr_res__rd_tip</name> + <description>Reserved and Transfer in progress</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wr_res__rd_res</name> + <description>Reserved and Reserved</description> + <bitRange>[2:2]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wr_ack__rd_res</name> + <description>Send ACK/NACK and Reserved</description> + <bitRange>[3:3]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wr_txd__rd_res</name> + <description>Transmit data and Reserved</description> + <bitRange>[4:4]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wr_rxd__rd_al</name> + <description>Receive data and Arbitration lost</description> + <bitRange>[5:5]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wr_sto__rd_busy</name> + <description>Generate stop and I2C bus busy</description> + <bitRange>[6:6]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wr_sta__rd_rxack</name> + <description>Generate start and Got ACK/NACK</description> + <bitRange>[7:7]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_uart0_1</name> + <description>From sifive,uart0,control peripheral generator</description> + <baseAddress>0x10023000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>txdata</name> + <description>Transmit data register</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>data</name> + <description>Transmit data</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>full</name> + <description>Transmit FIFO full</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>rxdata</name> + <description>Receive data register</description> + <addressOffset>0x4</addressOffset> + <fields> + <field> + <name>data</name> + <description>Received data</description> + <bitRange>[7:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>empty</name> + <description>Receive FIFO empty</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>txctrl</name> + <description>Transmit control register</description> + <addressOffset>0x8</addressOffset> + <fields> + <field> + <name>txen</name> + <description>Transmit enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>nstop</name> + <description>Number of stop bits</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + <field> + <name>txcnt</name> + <description>Transmit watermark level</description> + <bitRange>[18:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>rxctrl</name> + <description>Receive control register</description> + <addressOffset>0xC</addressOffset> + <fields> + <field> + <name>rxen</name> + <description>Receive enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rxcnt</name> + <description>Receive watermark level</description> + <bitRange>[18:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ie</name> + <description>UART interrupt enable</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark interrupt enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark interrupt enable</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ip</name> + <description>UART interrupt pending</description> + <addressOffset>0x14</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark interrupt pending</description> + <bitRange>[0:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark interrupt pending</description> + <bitRange>[1:1]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>div</name> + <description>Baud rate divisor</description> + <addressOffset>0x18</addressOffset> + <fields> + <field> + <name>div</name> + <description>Baud rate divisor.</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_spi0_1</name> + <description>From sifive,spi0,control peripheral generator</description> + <baseAddress>0x10024000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>sckdiv</name> + <description>Serial clock divisor</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>div</name> + <description>Divisor for serial clock.</description> + <bitRange>[11:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>sckmode</name> + <description>Serial clock mode</description> + <addressOffset>0x4</addressOffset> + <fields> + <field> + <name>pha</name> + <description>Serial clock phase</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pol</name> + <description>Serial clock polarity</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csid</name> + <description>Chip select ID</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>csid</name> + <description>Chip select ID.</description> + <bitRange>[31:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csdef</name> + <description>Chip select default</description> + <addressOffset>0x14</addressOffset> + <fields> + <field> + <name>csdef</name> + <description>Chip select default value. Reset to all-1s.</description> + <bitRange>[31:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csmode</name> + <description>Chip select mode</description> + <addressOffset>0x18</addressOffset> + <fields> + <field> + <name>mode</name> + <description>Chip select mode</description> + <bitRange>[1:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>delay0</name> + <description>Delay control 0</description> + <addressOffset>0x28</addressOffset> + <fields> + <field> + <name>cssck</name> + <description>CS to SCK Delay</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>sckcs</name> + <description>SCK to CS Delay</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>delay1</name> + <description>Delay control 1</description> + <addressOffset>0x2C</addressOffset> + <fields> + <field> + <name>intercs</name> + <description>Minimum CS inactive time</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>interxfr</name> + <description>Maximum interframe delay</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>extradel</name> + <description>SPI extra sampling delay to increase the SPI frequency</description> + <addressOffset>0x38</addressOffset> + <fields> + <field> + <name>coarse</name> + <description>Coarse grain sample delay (multiples of system clocks)</description> + <bitRange>[11:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>fine</name> + <description>Fine grain sample delay (multiples of process-specific buffer delay)</description> + <bitRange>[16:12]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>sampledel</name> + <description>Number of delay stages from slave to the SPI controller</description> + <addressOffset>0x3C</addressOffset> + <fields> + <field> + <name>sd</name> + <description>Number of delay stages from slave to SPI controller</description> + <bitRange>[4:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>fmt</name> + <description>Frame format</description> + <addressOffset>0x40</addressOffset> + <fields> + <field> + <name>proto</name> + <description>SPI protocol</description> + <bitRange>[1:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>endian</name> + <description>SPI endianness</description> + <bitRange>[2:2]</bitRange> + <access>read-write</access> + </field> + <field> + <name>dir</name> + <description>SPI I/O direction. This is reset to 1 for flash-enabled SPI controllers, 0 otherwise.</description> + <bitRange>[3:3]</bitRange> + <access>read-write</access> + </field> + <field> + <name>len</name> + <description>Number of bits per frame</description> + <bitRange>[19:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>txdata</name> + <description>Tx FIFO Data</description> + <addressOffset>0x48</addressOffset> + <fields> + <field> + <name>data</name> + <description>Transmit data</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>full</name> + <description>FIFO full flag</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>rxdata</name> + <description>Rx FIFO data</description> + <addressOffset>0x4C</addressOffset> + <fields> + <field> + <name>data</name> + <description>Received data</description> + <bitRange>[7:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>empty</name> + <description>FIFO empty flag</description> + <bitRange>[31:31]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>txmark</name> + <description>Tx FIFO watermark</description> + <addressOffset>0x50</addressOffset> + <fields> + <field> + <name>txmark</name> + <description>Transmit watermark. The reset value is 1 for flash-enabled controllers, 0 otherwise.</description> + <bitRange>[2:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>rxmark</name> + <description>Rx FIFO watermark</description> + <addressOffset>0x54</addressOffset> + <fields> + <field> + <name>rxmark</name> + <description>Receive watermark</description> + <bitRange>[2:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>fctrl</name> + <description>SPI flash interface control</description> + <addressOffset>0x60</addressOffset> + <fields> + <field> + <name>en</name> + <description>SPI Flash Mode Select</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ffmt</name> + <description>SPI flash instruction format</description> + <addressOffset>0x64</addressOffset> + <fields> + <field> + <name>cmd_en</name> + <description>Enable sending of command</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>addr_len</name> + <description>Number of address bytes (0 to 4)</description> + <bitRange>[3:1]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pad_cnt</name> + <description>Number of dummy cycles</description> + <bitRange>[7:4]</bitRange> + <access>read-write</access> + </field> + <field> + <name>cmd_proto</name> + <description>Protocol for transmitting command</description> + <bitRange>[9:8]</bitRange> + <access>read-write</access> + </field> + <field> + <name>addr_proto</name> + <description>Protocol for transmitting address and padding</description> + <bitRange>[11:10]</bitRange> + <access>read-write</access> + </field> + <field> + <name>data_proto</name> + <description>Protocol for receiving data bytes</description> + <bitRange>[13:12]</bitRange> + <access>read-write</access> + </field> + <field> + <name>cmd_code</name> + <description>Value of command byte</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pad_code</name> + <description>First 8 bits to transmit during dummy cycles</description> + <bitRange>[31:24]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ie</name> + <description>SPI interrupt enable</description> + <addressOffset>0x70</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark enable</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ip</name> + <description>SPI interrupt pending</description> + <addressOffset>0x74</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark pending</description> + <bitRange>[0:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark pending</description> + <bitRange>[1:1]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_pwm0_1</name> + <description>From sifive,pwm0,control peripheral generator</description> + <baseAddress>0x10025000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>pwmcfg</name> + <description>PWM configuration register</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>pwmscale</name> + <description>PWM Counter scale</description> + <bitRange>[3:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmsticky</name> + <description>PWM Sticky - disallow clearing pwmcmpXip bits</description> + <bitRange>[8:8]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmzerocmp</name> + <description>PWM Zero - counter resets to zero after match</description> + <bitRange>[9:9]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmdeglitch</name> + <description>PWM Deglitch - latch pwmcmpXip within same cycle</description> + <bitRange>[10:10]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmenalways</name> + <description>PWM enable always - run continuously</description> + <bitRange>[12:12]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmenoneshot</name> + <description>PWM enable one shot - run one cycle</description> + <bitRange>[13:13]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0center</name> + <description>PWM0 Compare Center</description> + <bitRange>[16:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1center</name> + <description>PWM1 Compare Center</description> + <bitRange>[17:17]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2center</name> + <description>PWM2 Compare Center</description> + <bitRange>[18:18]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3center</name> + <description>PWM3 Compare Center</description> + <bitRange>[19:19]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0invert</name> + <description>PWM0 Invert</description> + <bitRange>[20:20]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1invert</name> + <description>PWM1 Invert</description> + <bitRange>[21:21]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2invert</name> + <description>PWM2 Invert</description> + <bitRange>[22:22]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3invert</name> + <description>PWM3 Invert</description> + <bitRange>[23:23]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0gang</name> + <description>PWM0/PWM1 Compare Gang</description> + <bitRange>[24:24]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1gang</name> + <description>PWM1/PWM2 Compare Gang</description> + <bitRange>[25:25]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2gang</name> + <description>PWM2/PWM3 Compare Gang</description> + <bitRange>[26:26]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3gang</name> + <description>PWM3/PWM0 Compare Gang</description> + <bitRange>[27:27]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0ip</name> + <description>PWM0 Interrupt Pending</description> + <bitRange>[28:28]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1ip</name> + <description>PWM1 Interrupt Pending</description> + <bitRange>[29:29]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2ip</name> + <description>PWM2 Interrupt Pending</description> + <bitRange>[30:30]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3ip</name> + <description>PWM3 Interrupt Pending</description> + <bitRange>[31:31]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcount</name> + <description>PWM count register</description> + <addressOffset>0x8</addressOffset> + <fields> + <field> + <name>pwmcount</name> + <description>PWM count register.</description> + <bitRange>[30:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwms</name> + <description>Scaled PWM count register</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>pwms</name> + <description>Scaled PWM count register.</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp0</name> + <description>PWM 0 compare register</description> + <addressOffset>0x20</addressOffset> + <fields> + <field> + <name>pwmcmp0</name> + <description>PWM 0 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp1</name> + <description>PWM 1 compare register</description> + <addressOffset>0x24</addressOffset> + <fields> + <field> + <name>pwmcmp1</name> + <description>PWM 1 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp2</name> + <description>PWM 2 compare register</description> + <addressOffset>0x28</addressOffset> + <fields> + <field> + <name>pwmcmp2</name> + <description>PWM 2 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp3</name> + <description>PWM 3 compare register</description> + <addressOffset>0x2C</addressOffset> + <fields> + <field> + <name>pwmcmp3</name> + <description>PWM 3 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_spi0_2</name> + <description>From sifive,spi0,control peripheral generator</description> + <baseAddress>0x10034000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>sckdiv</name> + <description>Serial clock divisor</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>div</name> + <description>Divisor for serial clock.</description> + <bitRange>[11:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>sckmode</name> + <description>Serial clock mode</description> + <addressOffset>0x4</addressOffset> + <fields> + <field> + <name>pha</name> + <description>Serial clock phase</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pol</name> + <description>Serial clock polarity</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csid</name> + <description>Chip select ID</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>csid</name> + <description>Chip select ID.</description> + <bitRange>[31:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csdef</name> + <description>Chip select default</description> + <addressOffset>0x14</addressOffset> + <fields> + <field> + <name>csdef</name> + <description>Chip select default value. Reset to all-1s.</description> + <bitRange>[31:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csmode</name> + <description>Chip select mode</description> + <addressOffset>0x18</addressOffset> + <fields> + <field> + <name>mode</name> + <description>Chip select mode</description> + <bitRange>[1:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>delay0</name> + <description>Delay control 0</description> + <addressOffset>0x28</addressOffset> + <fields> + <field> + <name>cssck</name> + <description>CS to SCK Delay</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>sckcs</name> + <description>SCK to CS Delay</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>delay1</name> + <description>Delay control 1</description> + <addressOffset>0x2C</addressOffset> + <fields> + <field> + <name>intercs</name> + <description>Minimum CS inactive time</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>interxfr</name> + <description>Maximum interframe delay</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>extradel</name> + <description>SPI extra sampling delay to increase the SPI frequency</description> + <addressOffset>0x38</addressOffset> + <fields> + <field> + <name>coarse</name> + <description>Coarse grain sample delay (multiples of system clocks)</description> + <bitRange>[11:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>fine</name> + <description>Fine grain sample delay (multiples of process-specific buffer delay)</description> + <bitRange>[16:12]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>sampledel</name> + <description>Number of delay stages from slave to the SPI controller</description> + <addressOffset>0x3C</addressOffset> + <fields> + <field> + <name>sd</name> + <description>Number of delay stages from slave to SPI controller</description> + <bitRange>[4:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>fmt</name> + <description>Frame format</description> + <addressOffset>0x40</addressOffset> + <fields> + <field> + <name>proto</name> + <description>SPI protocol</description> + <bitRange>[1:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>endian</name> + <description>SPI endianness</description> + <bitRange>[2:2]</bitRange> + <access>read-write</access> + </field> + <field> + <name>dir</name> + <description>SPI I/O direction. This is reset to 1 for flash-enabled SPI controllers, 0 otherwise.</description> + <bitRange>[3:3]</bitRange> + <access>read-write</access> + </field> + <field> + <name>len</name> + <description>Number of bits per frame</description> + <bitRange>[19:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>txdata</name> + <description>Tx FIFO Data</description> + <addressOffset>0x48</addressOffset> + <fields> + <field> + <name>data</name> + <description>Transmit data</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>full</name> + <description>FIFO full flag</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>rxdata</name> + <description>Rx FIFO data</description> + <addressOffset>0x4C</addressOffset> + <fields> + <field> + <name>data</name> + <description>Received data</description> + <bitRange>[7:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>empty</name> + <description>FIFO empty flag</description> + <bitRange>[31:31]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>txmark</name> + <description>Tx FIFO watermark</description> + <addressOffset>0x50</addressOffset> + <fields> + <field> + <name>txmark</name> + <description>Transmit watermark. The reset value is 1 for flash-enabled controllers, 0 otherwise.</description> + <bitRange>[2:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>rxmark</name> + <description>Rx FIFO watermark</description> + <addressOffset>0x54</addressOffset> + <fields> + <field> + <name>rxmark</name> + <description>Receive watermark</description> + <bitRange>[2:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>fctrl</name> + <description>SPI flash interface control</description> + <addressOffset>0x60</addressOffset> + <fields> + <field> + <name>en</name> + <description>SPI Flash Mode Select</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ffmt</name> + <description>SPI flash instruction format</description> + <addressOffset>0x64</addressOffset> + <fields> + <field> + <name>cmd_en</name> + <description>Enable sending of command</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>addr_len</name> + <description>Number of address bytes (0 to 4)</description> + <bitRange>[3:1]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pad_cnt</name> + <description>Number of dummy cycles</description> + <bitRange>[7:4]</bitRange> + <access>read-write</access> + </field> + <field> + <name>cmd_proto</name> + <description>Protocol for transmitting command</description> + <bitRange>[9:8]</bitRange> + <access>read-write</access> + </field> + <field> + <name>addr_proto</name> + <description>Protocol for transmitting address and padding</description> + <bitRange>[11:10]</bitRange> + <access>read-write</access> + </field> + <field> + <name>data_proto</name> + <description>Protocol for receiving data bytes</description> + <bitRange>[13:12]</bitRange> + <access>read-write</access> + </field> + <field> + <name>cmd_code</name> + <description>Value of command byte</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pad_code</name> + <description>First 8 bits to transmit during dummy cycles</description> + <bitRange>[31:24]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ie</name> + <description>SPI interrupt enable</description> + <addressOffset>0x70</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark enable</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ip</name> + <description>SPI interrupt pending</description> + <addressOffset>0x74</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark pending</description> + <bitRange>[0:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark pending</description> + <bitRange>[1:1]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_pwm0_2</name> + <description>From sifive,pwm0,control peripheral generator</description> + <baseAddress>0x10035000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>pwmcfg</name> + <description>PWM configuration register</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>pwmscale</name> + <description>PWM Counter scale</description> + <bitRange>[3:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmsticky</name> + <description>PWM Sticky - disallow clearing pwmcmpXip bits</description> + <bitRange>[8:8]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmzerocmp</name> + <description>PWM Zero - counter resets to zero after match</description> + <bitRange>[9:9]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmdeglitch</name> + <description>PWM Deglitch - latch pwmcmpXip within same cycle</description> + <bitRange>[10:10]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmenalways</name> + <description>PWM enable always - run continuously</description> + <bitRange>[12:12]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmenoneshot</name> + <description>PWM enable one shot - run one cycle</description> + <bitRange>[13:13]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0center</name> + <description>PWM0 Compare Center</description> + <bitRange>[16:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1center</name> + <description>PWM1 Compare Center</description> + <bitRange>[17:17]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2center</name> + <description>PWM2 Compare Center</description> + <bitRange>[18:18]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3center</name> + <description>PWM3 Compare Center</description> + <bitRange>[19:19]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0invert</name> + <description>PWM0 Invert</description> + <bitRange>[20:20]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1invert</name> + <description>PWM1 Invert</description> + <bitRange>[21:21]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2invert</name> + <description>PWM2 Invert</description> + <bitRange>[22:22]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3invert</name> + <description>PWM3 Invert</description> + <bitRange>[23:23]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0gang</name> + <description>PWM0/PWM1 Compare Gang</description> + <bitRange>[24:24]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1gang</name> + <description>PWM1/PWM2 Compare Gang</description> + <bitRange>[25:25]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2gang</name> + <description>PWM2/PWM3 Compare Gang</description> + <bitRange>[26:26]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3gang</name> + <description>PWM3/PWM0 Compare Gang</description> + <bitRange>[27:27]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0ip</name> + <description>PWM0 Interrupt Pending</description> + <bitRange>[28:28]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1ip</name> + <description>PWM1 Interrupt Pending</description> + <bitRange>[29:29]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2ip</name> + <description>PWM2 Interrupt Pending</description> + <bitRange>[30:30]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3ip</name> + <description>PWM3 Interrupt Pending</description> + <bitRange>[31:31]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcount</name> + <description>PWM count register</description> + <addressOffset>0x8</addressOffset> + <fields> + <field> + <name>pwmcount</name> + <description>PWM count register.</description> + <bitRange>[30:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwms</name> + <description>Scaled PWM count register</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>pwms</name> + <description>Scaled PWM count register.</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp0</name> + <description>PWM 0 compare register</description> + <addressOffset>0x20</addressOffset> + <fields> + <field> + <name>pwmcmp0</name> + <description>PWM 0 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp1</name> + <description>PWM 1 compare register</description> + <addressOffset>0x24</addressOffset> + <fields> + <field> + <name>pwmcmp1</name> + <description>PWM 1 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp2</name> + <description>PWM 2 compare register</description> + <addressOffset>0x28</addressOffset> + <fields> + <field> + <name>pwmcmp2</name> + <description>PWM 2 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp3</name> + <description>PWM 3 compare register</description> + <addressOffset>0x2C</addressOffset> + <fields> + <field> + <name>pwmcmp3</name> + <description>PWM 3 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + </registers> + </peripheral> + </peripherals> +</device>
\ No newline at end of file diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/atomic.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/atomic.h new file mode 100644 index 000000000..32a33abd7 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/atomic.h @@ -0,0 +1,259 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__ATOMIC_H +#define METAL__ATOMIC_H + +#include <stdint.h> + +#include <metal/compiler.h> + +typedef volatile int32_t metal_atomic_t; + +#define METAL_ATOMIC_DECLARE(name) \ + __attribute((section(".data.atomics"))) metal_atomic_t name + +#define _METAL_STORE_AMO_ACCESS_FAULT 7 + +/* This macro stores the memory address in mtval like a normal store/amo access + * fault, triggers a trap, and then if execution returns, returns 0 as an + * arbitrary choice */ +#define _METAL_TRAP_AMO_ACCESS(addr) \ + __asm__("csrw mtval, %[atomic]" ::[atomic] "r"(a)); \ + _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); \ + return 0; + +/*! + * @brief Check if the platform supports atomic operations + * + * @return 1 if atomic operations are supported, 0 if not + */ +__inline__ int32_t metal_atomic_available(void) { +#ifdef __riscv_atomic + return 1; +#else + return 0; +#endif +} + +/*! + * @brief Atomically increment a metal_atomic_t and return its old value + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to increment + * @param increment the amount to increment the value + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_add(metal_atomic_t *a, int32_t increment) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amoadd.w %[old], %[increment], (%[atomic])" + : [old] "=r"(old) + : [increment] "r"(increment), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically bitwise-AND a metal_atomic_t and return its old value + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to bitwise-AND + * @param mask the bitmask to AND + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_and(metal_atomic_t *a, int32_t mask) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amoand.w %[old], %[mask], (%[atomic])" + : [old] "=r"(old) + : [mask] "r"(mask), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically bitwise-OR a metal_atomic_t and return its old value + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to bitwise-OR + * @param mask the bitmask to OR + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_or(metal_atomic_t *a, int32_t mask) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amoor.w %[old], %[mask], (%[atomic])" + : [old] "=r"(old) + : [mask] "r"(mask), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically swap a metal_atomic_t and return its old value + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to swap + * @param new_value the value to store in the metal_atomic_t + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_swap(metal_atomic_t *a, int32_t new_value) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amoswap.w %[old], %[newval], (%[atomic])" + : [old] "=r"(old) + : [newval] "r"(new_value), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically bitwise-XOR a metal_atomic_t and return its old value + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to bitwise-XOR + * @param mask the bitmask to XOR + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_xor(metal_atomic_t *a, int32_t mask) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amoxor.w %[old], %[mask], (%[atomic])" + : [old] "=r"(old) + : [mask] "r"(mask), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically set the value of a memory location to the greater of + * its current value or a value to compare it with. + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to swap + * @param compare the value to compare with the value in memory + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_max(metal_atomic_t *a, int32_t compare) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amomax.w %[old], %[compare], (%[atomic])" + : [old] "=r"(old) + : [compare] "r"(compare), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically set the value of a memory location to the (unsigned) + * greater of its current value or a value to compare it with. + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to swap + * @param compare the value to compare with the value in memory + * + * @return The previous value of the metal_atomic_t + */ +__inline__ uint32_t metal_atomic_max_u(metal_atomic_t *a, uint32_t compare) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amomaxu.w %[old], %[compare], (%[atomic])" + : [old] "=r"(old) + : [compare] "r"(compare), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically set the value of a memory location to the lesser of + * its current value or a value to compare it with. + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to swap + * @param compare the value to compare with the value in memory + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_min(metal_atomic_t *a, int32_t compare) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amomin.w %[old], %[compare], (%[atomic])" + : [old] "=r"(old) + : [compare] "r"(compare), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically set the value of a memory location to the (unsigned) lesser + * of its current value or a value to compare it with. + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to swap + * @param compare the value to compare with the value in memory + * + * @return The previous value of the metal_atomic_t + */ +__inline__ uint32_t metal_atomic_min_u(metal_atomic_t *a, uint32_t compare) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amominu.w %[old], %[compare], (%[atomic])" + : [old] "=r"(old) + : [compare] "r"(compare), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +#endif /* METAL__ATOMIC_H */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/button.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/button.h index 0c26f435a..bef645967 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/button.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/button.h @@ -15,7 +15,8 @@ struct metal_button; struct metal_button_vtable { int (*button_exist)(struct metal_button *button, char *label); - struct metal_interrupt* (*interrupt_controller)(struct metal_button *button); + struct metal_interrupt *(*interrupt_controller)( + struct metal_button *button); int (*get_interrupt_id)(struct metal_button *button); }; @@ -35,8 +36,7 @@ struct metal_button { * @param label The DeviceTree label for the button * @return A handle for the button */ -struct metal_button* metal_button_get(char *label); - +struct metal_button *metal_button_get(char *label); /*! * @brief Get the interrupt controller for a button @@ -45,8 +45,10 @@ struct metal_button* metal_button_get(char *label); * @return A pointer to the interrupt controller responsible for handling * button interrupts. */ -inline struct metal_interrupt* - metal_button_interrupt_controller(struct metal_button *button) { return button->vtable->interrupt_controller(button); } +__inline__ struct metal_interrupt * +metal_button_interrupt_controller(struct metal_button *button) { + return button->vtable->interrupt_controller(button); +} /*! * @brief Get the interrupt id for a button @@ -54,6 +56,8 @@ inline struct metal_interrupt* * @param button The handle for the button * @return The interrupt id corresponding to a button. */ -inline int metal_button_get_interrupt_id(struct metal_button *button) { return button->vtable->get_interrupt_id(button); } +__inline__ int metal_button_get_interrupt_id(struct metal_button *button) { + return button->vtable->get_interrupt_id(button); +} #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cache.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cache.h index a8a60ada6..673a8b13e 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cache.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cache.h @@ -1,4 +1,4 @@ -/* Copyright 2018 SiFive, Inc */ +/* Copyright 2020 SiFive, Inc */ /* SPDX-License-Identifier: Apache-2.0 */ #ifndef METAL__CACHE_H @@ -9,40 +9,58 @@ * * @brief API for configuring caches */ - -struct metal_cache; - -struct __metal_cache_vtable { - void (*init)(struct metal_cache *cache, int ways); - int (*get_enabled_ways)(struct metal_cache *cache); - int (*set_enabled_ways)(struct metal_cache *cache, int ways); -}; +#include <stdint.h> /*! * @brief a handle for a cache + * Note: To be deprecated in next release. */ struct metal_cache { - const struct __metal_cache_vtable *vtable; + uint8_t __no_empty_structs; }; /*! + * @brief Initialize L2 cache controller. + * Enables all available cache ways. + * @param None + * @return 0 If no error + */ +int metal_l2cache_init(void); + +/*! + * @brief Get the current number of enabled L2 cache ways + * @param None + * @return The current number of enabled L2 cache ways + */ +int metal_l2cache_get_enabled_ways(void); + +/*! + * @brief Enable the requested number of L2 cache ways + * @param ways Number of ways to enable + * @return 0 if the ways are successfully enabled + */ +int metal_l2cache_set_enabled_ways(int ways); + +/*! * @brief Initialize a cache * @param cache The handle for the cache to initialize * @param ways The number of ways to enable * * Initializes a cache with the requested number of ways enabled. + * Note: API to be deprecated in next release. */ -inline void metal_cache_init(struct metal_cache *cache, int ways) { - return cache->vtable->init(cache, ways); +__inline__ void metal_cache_init(struct metal_cache *cache, int ways) { + metal_l2cache_init(); } /*! * @brief Get the current number of enabled cache ways * @param cache The handle for the cache * @return The current number of enabled cache ways + * Note: API to be deprecated in next release. */ -inline int metal_cache_get_enabled_ways(struct metal_cache *cache) { - return cache->vtable->get_enabled_ways(cache); +__inline__ int metal_cache_get_enabled_ways(struct metal_cache *cache) { + return metal_l2cache_get_enabled_ways(); } /*! @@ -50,9 +68,41 @@ inline int metal_cache_get_enabled_ways(struct metal_cache *cache) { * @param cache The handle for the cache * @param ways The number of ways to enabled * @return 0 if the ways are successfully enabled + * Note: API to be deprecated in next release. */ -inline int metal_cache_set_enabled_ways(struct metal_cache *cache, int ways) { - return cache->vtable->set_enabled_ways(cache, ways); +__inline__ int metal_cache_set_enabled_ways(struct metal_cache *cache, + int ways) { + return metal_l2cache_set_enabled_ways(ways); } +/*! + * @brief Check if dcache is supported on the core + * @param hartid The core to check + * @return 1 if dcache is present + */ +int metal_dcache_l1_available(int hartid); + +/*! + * @brief Flush dcache for L1 on the requested core with write back + * @param hartid The core to flush + * @param address The virtual address of cacheline to invalidate + * @return None + */ +void metal_dcache_l1_flush(int hartid, uintptr_t address); + +/*! + * @brief Discard dcache for L1 on the requested core with no write back + * @param hartid The core to discard + * @param address The virtual address of cacheline to invalidate + * @return None + */ +void metal_dcache_l1_discard(int hartid, uintptr_t address); + +/*! + * @brief Check if icache is supported on the core + * @param hartid The core to check + * @return 1 if icache is present + */ +int metal_icache_l1_available(int hartid); + #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/clock.h index 277841e01..cfe29f6b7 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/clock.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/clock.h @@ -4,11 +4,12 @@ #ifndef METAL__CLOCK_H #define METAL__CLOCK_H -/*! +/*! * @file clock.h * @brief API for manipulating clock sources * - * The clock interface allows for controlling the rate of various clocks in the system. + * The clock interface allows for controlling the rate of various clocks in the + * system. */ struct metal_clock; @@ -22,37 +23,82 @@ struct __metal_clock_vtable { }; /*! - * @brief Function signature of clock pre-rate change callbacks + * @brief Function signature of clock rate change callbacks + */ +typedef void (*metal_clock_rate_change_callback)(void *priv); + +struct _metal_clock_callback_t; +struct _metal_clock_callback_t { + /* The callback function */ + metal_clock_rate_change_callback callback; + + /* Private data for the callback function */ + void *priv; + + struct _metal_clock_callback_t *_next; +}; + +/*! + * @brief Type for the linked list of callbacks for clock rate changes */ -typedef void (*metal_clock_pre_rate_change_callback)(void *priv); +typedef struct _metal_clock_callback_t metal_clock_callback; /*! - * @brief Function signature of clock post-rate change callbacks + * @brief Call all callbacks in the linked list, if any are registered */ -typedef void (*metal_clock_post_rate_change_callback)(void *priv); +__inline__ void +_metal_clock_call_all_callbacks(const metal_clock_callback *const list) { + const metal_clock_callback *current = list; + while (current) { + current->callback(current->priv); + current = current->_next; + } +} + +/*! + * @brief Append a callback to the linked list and return the head of the list + */ +__inline__ metal_clock_callback * +_metal_clock_append_to_callbacks(metal_clock_callback *list, + metal_clock_callback *const cb) { + cb->_next = NULL; + + if (!list) { + return cb; + } + + metal_clock_callback *current = list; + + while ((current->_next) != NULL) { + current = current->_next; + } + + current->_next = cb; + + return list; +} /*! * @struct metal_clock * @brief The handle for a clock * - * Clocks are defined as a pointer to a `struct metal_clock`, the contents of which - * are implementation defined. Users of the clock interface must call functions - * which accept a `struct metal_clock *` as an argument to interract with the clock. + * Clocks are defined as a pointer to a `struct metal_clock`, the contents of + * which are implementation defined. Users of the clock interface must call + * functions which accept a `struct metal_clock *` as an argument to interract + * with the clock. * - * Note that no mechanism for obtaining a pointer to a `struct metal_clock` has been - * defined, making it impossible to call any of these functions without invoking - * implementation-defined behavior. + * Note that no mechanism for obtaining a pointer to a `struct metal_clock` has + * been defined, making it impossible to call any of these functions without + * invoking implementation-defined behavior. */ struct metal_clock { const struct __metal_clock_vtable *vtable; - /* Pre-rate change callback */ - metal_clock_pre_rate_change_callback _pre_rate_change_callback; - void *_pre_rate_change_callback_priv; + /* Pre-rate change callback linked list */ + metal_clock_callback *_pre_rate_change_callback; - /* Post-rate change callback */ - metal_clock_post_rate_change_callback _post_rate_change_callback; - void *_post_rate_change_callback_priv; + /* Post-rate change callback linked list */ + metal_clock_callback *_post_rate_change_callback; }; /*! @@ -61,7 +107,9 @@ struct metal_clock { * @param clk The handle for the clock * @return The current rate of the clock in Hz */ -inline long metal_clock_get_rate_hz(const struct metal_clock *clk) { return clk->vtable->get_rate_hz(clk); } +__inline__ long metal_clock_get_rate_hz(const struct metal_clock *clk) { + return clk->vtable->get_rate_hz(clk); +} /*! * @brief Set the current rate of a clock @@ -74,18 +122,15 @@ inline long metal_clock_get_rate_hz(const struct metal_clock *clk) { return clk- * to the given rate in Hz. Returns the actual value that's been selected, which * could be anything! * - * Prior to and after the rate change of the clock, this will call the registered - * pre- and post-rate change callbacks. + * Prior to and after the rate change of the clock, this will call the + * registered pre- and post-rate change callbacks. */ -inline long metal_clock_set_rate_hz(struct metal_clock *clk, long hz) -{ - if(clk->_pre_rate_change_callback != NULL) - clk->_pre_rate_change_callback(clk->_pre_rate_change_callback_priv); +__inline__ long metal_clock_set_rate_hz(struct metal_clock *clk, long hz) { + _metal_clock_call_all_callbacks(clk->_pre_rate_change_callback); long out = clk->vtable->set_rate_hz(clk, hz); - if (clk->_post_rate_change_callback != NULL) - clk->_post_rate_change_callback(clk->_post_rate_change_callback_priv); + _metal_clock_call_all_callbacks(clk->_post_rate_change_callback); return out; } @@ -95,12 +140,12 @@ inline long metal_clock_set_rate_hz(struct metal_clock *clk, long hz) * * @param clk The handle for the clock * @param cb The callback to be registered - * @param priv Private data for the callback handler */ -inline void metal_clock_register_pre_rate_change_callback(struct metal_clock *clk, metal_clock_pre_rate_change_callback cb, void *priv) -{ - clk->_pre_rate_change_callback = cb; - clk->_pre_rate_change_callback_priv = priv; +__inline__ void +metal_clock_register_pre_rate_change_callback(struct metal_clock *clk, + metal_clock_callback *cb) { + clk->_pre_rate_change_callback = + _metal_clock_append_to_callbacks(clk->_pre_rate_change_callback, cb); } /*! @@ -108,12 +153,12 @@ inline void metal_clock_register_pre_rate_change_callback(struct metal_clock *cl * * @param clk The handle for the clock * @param cb The callback to be registered - * @param priv Private data for the callback handler */ -inline void metal_clock_register_post_rate_change_callback(struct metal_clock *clk, metal_clock_post_rate_change_callback cb, void *priv) -{ - clk->_post_rate_change_callback = cb; - clk->_post_rate_change_callback_priv = priv; +__inline__ void +metal_clock_register_post_rate_change_callback(struct metal_clock *clk, + metal_clock_callback *cb) { + clk->_post_rate_change_callback = + _metal_clock_append_to_callbacks(clk->_post_rate_change_callback, cb); } #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/compiler.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/compiler.h index 62c0ea975..80ca5fee4 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/compiler.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/compiler.h @@ -4,18 +4,19 @@ #ifndef METAL__COMPILER_H #define METAL__COMPILER_H -#define __METAL_DECLARE_VTABLE(type) \ - extern const struct type type; +#define __METAL_DECLARE_VTABLE(type) extern const struct type type; -#define __METAL_DEFINE_VTABLE(type) \ - const struct type type +#define __METAL_DEFINE_VTABLE(type) const struct type type -#define __METAL_GET_FIELD(reg, mask) \ +#define __METAL_GET_FIELD(reg, mask) \ (((reg) & (mask)) / ((mask) & ~((mask) << 1))) /* Set field with mask for a given value */ -#define __METAL_SET_FIELD(reg, mask, val) \ - (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask))) +#define __METAL_SET_FIELD(reg, mask, val) \ + (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask))) + +#define __METAL_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define __METAL_MAX(a, b) ((a) > (b) ? (a) : (b)) void _metal_trap(int ecode); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cpu.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cpu.h index 453bd12de..98d7e6680 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cpu.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/cpu.h @@ -9,33 +9,35 @@ #ifndef METAL__CPU_H #define METAL__CPU_H -#include <stdint.h> #include <metal/interrupt.h> +#include <stdint.h> struct metal_cpu; /*! * @brief Function signature for exception handlers */ -typedef void (*metal_exception_handler_t) (struct metal_cpu *cpu, int ecode); +typedef void (*metal_exception_handler_t)(struct metal_cpu *cpu, int ecode); struct metal_cpu_vtable { - unsigned long long (*timer_get)(struct metal_cpu *cpu); + unsigned long long (*mcycle_get)(struct metal_cpu *cpu); unsigned long long (*timebase_get)(struct metal_cpu *cpu); unsigned long long (*mtime_get)(struct metal_cpu *cpu); int (*mtimecmp_set)(struct metal_cpu *cpu, unsigned long long time); - struct metal_interrupt* (*tmr_controller_interrupt)(struct metal_cpu *cpu); + struct metal_interrupt *(*tmr_controller_interrupt)(struct metal_cpu *cpu); int (*get_tmr_interrupt_id)(struct metal_cpu *cpu); - struct metal_interrupt* (*sw_controller_interrupt)(struct metal_cpu *cpu); + struct metal_interrupt *(*sw_controller_interrupt)(struct metal_cpu *cpu); int (*get_sw_interrupt_id)(struct metal_cpu *cpu); int (*set_sw_ipi)(struct metal_cpu *cpu, int hartid); int (*clear_sw_ipi)(struct metal_cpu *cpu, int hartid); int (*get_msip)(struct metal_cpu *cpu, int hartid); - struct metal_interrupt* (*controller_interrupt)(struct metal_cpu *cpu); - int (*exception_register)(struct metal_cpu *cpu, int ecode, metal_exception_handler_t handler); + struct metal_interrupt *(*controller_interrupt)(struct metal_cpu *cpu); + int (*exception_register)(struct metal_cpu *cpu, int ecode, + metal_exception_handler_t handler); int (*get_ilen)(struct metal_cpu *cpu, uintptr_t epc); uintptr_t (*get_epc)(struct metal_cpu *cpu); int (*set_epc)(struct metal_cpu *cpu, uintptr_t epc); + struct metal_buserror *(*get_buserror)(struct metal_cpu *cpu); }; /*! @brief A device handle for a CPU hart @@ -49,17 +51,17 @@ struct metal_cpu { * @param hartid The ID of the desired CPU hart * @return A pointer to the CPU device handle */ -struct metal_cpu* metal_cpu_get(int hartid); +struct metal_cpu *metal_cpu_get(unsigned int hartid); /*! @brief Get the hartid of the CPU hart executing this function * * @return The hartid of the current CPU hart */ -int metal_cpu_get_current_hartid(); +int metal_cpu_get_current_hartid(void); /*! @brief Get the number of CPU harts - * + * * @return The number of CPU harts */ -int metal_cpu_get_num_harts(); +int metal_cpu_get_num_harts(void); /*! @brief Get the CPU cycle count timer value * @@ -68,8 +70,9 @@ int metal_cpu_get_num_harts(); * @param cpu The CPU device handle * @return The value of the CPU cycle count timer */ -inline unsigned long long metal_cpu_get_timer(struct metal_cpu *cpu) -{ return cpu->vtable->timer_get(cpu); } +__inline__ unsigned long long metal_cpu_get_timer(struct metal_cpu *cpu) { + return cpu->vtable->mcycle_get(cpu); +} /*! @brief Get the timebase of the CPU * @@ -78,8 +81,9 @@ inline unsigned long long metal_cpu_get_timer(struct metal_cpu *cpu) * @param cpu The CPU device handle * @return The value of the cycle count timer timebase */ -inline unsigned long long metal_cpu_get_timebase(struct metal_cpu *cpu) -{ return cpu->vtable->timebase_get(cpu); } +__inline__ unsigned long long metal_cpu_get_timebase(struct metal_cpu *cpu) { + return cpu->vtable->timebase_get(cpu); +} /*! @brief Get the value of the mtime RTC * @@ -90,8 +94,9 @@ inline unsigned long long metal_cpu_get_timebase(struct metal_cpu *cpu) * @param cpu The CPU device handle * @return The value of mtime, or 0 if failure */ -inline unsigned long long metal_cpu_get_mtime(struct metal_cpu *cpu) -{ return cpu->vtable->mtime_get(cpu); } +__inline__ unsigned long long metal_cpu_get_mtime(struct metal_cpu *cpu) { + return cpu->vtable->mtime_get(cpu); +} /*! @brief Set the value of the RTC mtimecmp RTC * @@ -103,20 +108,24 @@ inline unsigned long long metal_cpu_get_mtime(struct metal_cpu *cpu) * @param time The value to set the compare register to * @return The value of mtimecmp or -1 if error */ -inline int metal_cpu_set_mtimecmp(struct metal_cpu *cpu, unsigned long long time) -{ return cpu->vtable->mtimecmp_set(cpu, time); } +__inline__ int metal_cpu_set_mtimecmp(struct metal_cpu *cpu, + unsigned long long time) { + return cpu->vtable->mtimecmp_set(cpu, time); +} /*! @brief Get a reference to RTC timer interrupt controller * - * Get a reference to the interrupt controller for the real-time clock interrupt. - * The controller returned by this function must be initialized before any interrupts - * are registered or enabled with it. + * Get a reference to the interrupt controller for the real-time clock + * interrupt. The controller returned by this function must be initialized + * before any interrupts are registered or enabled with it. * * @param cpu The CPU device handle * @return A pointer to the timer interrupt handle */ -inline struct metal_interrupt* metal_cpu_timer_interrupt_controller(struct metal_cpu *cpu) -{ return cpu->vtable->tmr_controller_interrupt(cpu); } +__inline__ struct metal_interrupt * +metal_cpu_timer_interrupt_controller(struct metal_cpu *cpu) { + return cpu->vtable->tmr_controller_interrupt(cpu); +} /*! @brief Get the RTC timer interrupt id * @@ -125,20 +134,23 @@ inline struct metal_interrupt* metal_cpu_timer_interrupt_controller(struct metal * @param cpu The CPU device handle * @return The timer interrupt ID */ -inline int metal_cpu_timer_get_interrupt_id(struct metal_cpu *cpu) -{ return cpu->vtable->get_tmr_interrupt_id(cpu); } +__inline__ int metal_cpu_timer_get_interrupt_id(struct metal_cpu *cpu) { + return cpu->vtable->get_tmr_interrupt_id(cpu); +} /*! @brief Get a reference to the software interrupt controller * * Get a reference to the interrupt controller for the software/inter-process - * interrupt. The controller returned by this function must be initialized before - * any interrupts are registered or enabled with it. + * interrupt. The controller returned by this function must be initialized + * before any interrupts are registered or enabled with it. * * @param cpu The CPU device handle * @return A pointer to the software interrupt handle */ -inline struct metal_interrupt* metal_cpu_software_interrupt_controller(struct metal_cpu *cpu) -{ return cpu->vtable->sw_controller_interrupt(cpu); } +__inline__ struct metal_interrupt * +metal_cpu_software_interrupt_controller(struct metal_cpu *cpu) { + return cpu->vtable->sw_controller_interrupt(cpu); +} /*! @brief Get the software interrupt id * @@ -147,8 +159,9 @@ inline struct metal_interrupt* metal_cpu_software_interrupt_controller(struct me * @param cpu The CPU device handle * @return the software interrupt ID */ -inline int metal_cpu_software_get_interrupt_id(struct metal_cpu *cpu) -{ return cpu->vtable->get_sw_interrupt_id(cpu); } +__inline__ int metal_cpu_software_get_interrupt_id(struct metal_cpu *cpu) { + return cpu->vtable->get_sw_interrupt_id(cpu); +} /*! * @brief Set the inter-process interrupt for a hart @@ -161,8 +174,9 @@ inline int metal_cpu_software_get_interrupt_id(struct metal_cpu *cpu) * @param hartid The CPU hart ID to be interrupted * @return 0 upon success */ -inline int metal_cpu_software_set_ipi(struct metal_cpu *cpu, int hartid) -{ return cpu->vtable->set_sw_ipi(cpu, hartid); } +__inline__ int metal_cpu_software_set_ipi(struct metal_cpu *cpu, int hartid) { + return cpu->vtable->set_sw_ipi(cpu, hartid); +} /*! * @brief Clear the inter-process interrupt for a hart @@ -175,8 +189,9 @@ inline int metal_cpu_software_set_ipi(struct metal_cpu *cpu, int hartid) * @param hartid The CPU hart ID to clear * @return 0 upon success */ -inline int metal_cpu_software_clear_ipi(struct metal_cpu *cpu, int hartid) -{ return cpu->vtable->clear_sw_ipi(cpu, hartid); } +__inline__ int metal_cpu_software_clear_ipi(struct metal_cpu *cpu, int hartid) { + return cpu->vtable->clear_sw_ipi(cpu, hartid); +} /*! * @brief Get the value of MSIP for the given hart @@ -190,8 +205,9 @@ inline int metal_cpu_software_clear_ipi(struct metal_cpu *cpu, int hartid) * @param hartid The CPU hart to read * @return 0 upon success */ -inline int metal_cpu_get_msip(struct metal_cpu *cpu, int hartid) -{ return cpu->vtable->get_msip(cpu, hartid); } +__inline__ int metal_cpu_get_msip(struct metal_cpu *cpu, int hartid) { + return cpu->vtable->get_msip(cpu, hartid); +} /*! * @brief Get the interrupt controller for the CPU @@ -204,22 +220,26 @@ inline int metal_cpu_get_msip(struct metal_cpu *cpu, int hartid) * @param cpu The CPU device handle * @return The handle for the CPU interrupt controller */ -inline struct metal_interrupt* metal_cpu_interrupt_controller(struct metal_cpu *cpu) -{ return cpu->vtable->controller_interrupt(cpu); } +__inline__ struct metal_interrupt * +metal_cpu_interrupt_controller(struct metal_cpu *cpu) { + return cpu->vtable->controller_interrupt(cpu); +} /*! * @brief Register an exception handler - * - * Register an exception handler for the CPU. The CPU interrupt controller must be initialized - * before this function is called. + * + * Register an exception handler for the CPU. The CPU interrupt controller must + * be initialized before this function is called. * * @param cpu The CPU device handle * @param ecode The exception code to register a handler for * @param handler Callback function for the exception handler * @return 0 upon success */ -inline int metal_cpu_exception_register(struct metal_cpu *cpu, int ecode, metal_exception_handler_t handler) -{ return cpu->vtable->exception_register(cpu, ecode, handler); } +__inline__ int metal_cpu_exception_register(struct metal_cpu *cpu, int ecode, + metal_exception_handler_t handler) { + return cpu->vtable->exception_register(cpu, ecode, handler); +} /*! * @brief Get the length of an instruction in bytes @@ -237,8 +257,10 @@ inline int metal_cpu_exception_register(struct metal_cpu *cpu, int ecode, metal_ * @param epc The address of the instruction to measure * @return the length of the instruction in bytes */ -inline int metal_cpu_get_instruction_length(struct metal_cpu *cpu, uintptr_t epc) -{ return cpu->vtable->get_ilen(cpu, epc); } +__inline__ int metal_cpu_get_instruction_length(struct metal_cpu *cpu, + uintptr_t epc) { + return cpu->vtable->get_ilen(cpu, epc); +} /*! * @brief Get the program counter of the current exception. @@ -249,8 +271,9 @@ inline int metal_cpu_get_instruction_length(struct metal_cpu *cpu, uintptr_t epc * @param cpu The CPU device handle * @return The value of the program counter at the time of the exception */ -inline uintptr_t metal_cpu_get_exception_pc(struct metal_cpu *cpu) -{ return cpu->vtable->get_epc(cpu); } +__inline__ uintptr_t metal_cpu_get_exception_pc(struct metal_cpu *cpu) { + return cpu->vtable->get_epc(cpu); +} /*! * @brief Set the exception program counter @@ -265,7 +288,20 @@ inline uintptr_t metal_cpu_get_exception_pc(struct metal_cpu *cpu) * @param epc The address to set the exception program counter to * @return 0 upon success */ -inline int metal_cpu_set_exception_pc(struct metal_cpu *cpu, uintptr_t epc) -{ return cpu->vtable->set_epc(cpu, epc); } +__inline__ int metal_cpu_set_exception_pc(struct metal_cpu *cpu, + uintptr_t epc) { + return cpu->vtable->set_epc(cpu, epc); +} + +/*! + * @brief Get the handle for the hart's bus error unit + * + * @param cpu The CPU device handle + * @return A pointer to the bus error unit handle + */ +__inline__ struct metal_buserror * +metal_cpu_get_buserror(struct metal_cpu *cpu) { + return cpu->vtable->get_buserror(cpu); +} #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/csr.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/csr.h new file mode 100644 index 000000000..8375d8a44 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/csr.h @@ -0,0 +1,32 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__CSR_H +#define METAL__CSR_H + +#include <metal/compiler.h> +#include <stddef.h> +#include <stdint.h> + +/*! + * @file csr.h + * @brief A collection of APIs for get and set CSR registers + */ + +/*! + * @brief Read a given CSR register without checking validity of CSR offset + * @param crs Register label or hex value offset to read from + * @param value Variable name of uintprt_t type to get the value + */ +#define METAL_CPU_GET_CSR(reg, value) \ + __asm__ volatile("csrr %0, " #reg : "=r"(value)); + +/*! + * @brief Write to a given CSR register without checking validity of CSR offset + * @param crs Register label or hex value offset to write to + * @param value Variable name of uintprt_t type to set the value + */ +#define METAL_CPU_SET_CSR(reg, value) \ + __asm__ volatile("csrw " #reg ", %0" : : "r"(value)); + +#endif // METAL__CSR_H diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-clock.h index 2647c5981..b25f54144 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-clock.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-clock.h @@ -6,8 +6,8 @@ struct __metal_driver_fixed_clock; -#include <metal/compiler.h> #include <metal/clock.h> +#include <metal/compiler.h> struct __metal_driver_vtable_fixed_clock { struct __metal_clock_vtable clock; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-factor-clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-factor-clock.h index 936ce8d77..84e4fd580 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-factor-clock.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/fixed-factor-clock.h @@ -6,8 +6,8 @@ struct __metal_driver_fixed_factor_clock; -#include <metal/compiler.h> #include <metal/clock.h> +#include <metal/compiler.h> struct __metal_driver_vtable_fixed_factor_clock { struct __metal_clock_vtable clock; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_clint0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_clint0.h index 08d571e1c..ceda473e2 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_clint0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_clint0.h @@ -21,4 +21,7 @@ struct __metal_driver_riscv_clint0 { }; #undef __METAL_MACHINE_MACROS +int __metal_driver_riscv_clint0_command_request( + struct metal_interrupt *controller, int command, void *data); + #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_cpu.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_cpu.h index eb1e5b8ca..f3005f01f 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_cpu.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_cpu.h @@ -4,148 +4,154 @@ #ifndef METAL__DRIVERS__RISCV_CPU_H #define METAL__DRIVERS__RISCV_CPU_H -#include <stdint.h> -#include <metal/cpu.h> #include <metal/compiler.h> +#include <metal/cpu.h> +#include <stdint.h> -#define METAL_MAX_CORES 8 -#define METAL_MAX_MI 32 /* Per ISA MCause interrupts 32+ are Reserved */ -#define METAL_MAX_ME 12 /* Per ISA Exception codes 12+ are Reserved */ -#define METAL_DEFAULT_RTC_FREQ 32768 - -#define METAL_DISABLE 0 -#define METAL_ENABLE 1 - -#define METAL_ISA_A_EXTENSIONS 0x0001 -#define METAL_ISA_C_EXTENSIONS 0x0004 -#define METAL_ISA_D_EXTENSIONS 0x0008 -#define METAL_ISA_E_EXTENSIONS 0x0010 -#define METAL_ISA_F_EXTENSIONS 0x0020 -#define METAL_ISA_G_EXTENSIONS 0x0040 -#define METAL_ISA_I_EXTENSIONS 0x0100 -#define METAL_ISA_M_EXTENSIONS 0x1000 -#define METAL_ISA_N_EXTENSIONS 0x2000 -#define METAL_ISA_Q_EXTENSIONS 0x10000 -#define METAL_ISA_S_EXTENSIONS 0x40000 -#define METAL_ISA_U_EXTENSIONS 0x100000 -#define METAL_ISA_V_EXTENSIONS 0x200000 -#define METAL_ISA_XL32_EXTENSIONS 0x40000000UL -#define METAL_ISA_XL64_EXTENSIONS 0x8000000000000000UL +#define METAL_MAX_CORES 8 +#define METAL_MAX_MI 32 /* Per ISA MCause interrupts 32+ are Reserved */ +#define METAL_MAX_ME 12 /* Per ISA Exception codes 12+ are Reserved */ +#define METAL_DEFAULT_RTC_FREQ 32768 + +#define METAL_DISABLE 0 +#define METAL_ENABLE 1 + +#define METAL_ISA_A_EXTENSIONS 0x0001 +#define METAL_ISA_C_EXTENSIONS 0x0004 +#define METAL_ISA_D_EXTENSIONS 0x0008 +#define METAL_ISA_E_EXTENSIONS 0x0010 +#define METAL_ISA_F_EXTENSIONS 0x0020 +#define METAL_ISA_G_EXTENSIONS 0x0040 +#define METAL_ISA_I_EXTENSIONS 0x0100 +#define METAL_ISA_M_EXTENSIONS 0x1000 +#define METAL_ISA_N_EXTENSIONS 0x2000 +#define METAL_ISA_Q_EXTENSIONS 0x10000 +#define METAL_ISA_S_EXTENSIONS 0x40000 +#define METAL_ISA_U_EXTENSIONS 0x100000 +#define METAL_ISA_V_EXTENSIONS 0x200000 +#define METAL_ISA_XL32_EXTENSIONS 0x40000000UL +#define METAL_ISA_XL64_EXTENSIONS 0x8000000000000000UL #define METAL_ISA_XL128_EXTENSIONS 0xC000000000000000UL -#define METAL_MTVEC_DIRECT 0x00 -#define METAL_MTVEC_VECTORED 0x01 -#define METAL_MTVEC_CLIC 0x02 -#define METAL_MTVEC_CLIC_VECTORED 0x03 -#define METAL_MTVEC_CLIC_RESERVED 0x3C -#define METAL_MTVEC_MASK 0x3F +#define METAL_MTVEC_DIRECT 0x00 +#define METAL_MTVEC_VECTORED 0x01 +#define METAL_MTVEC_CLIC 0x02 +#define METAL_MTVEC_CLIC_VECTORED 0x03 +#define METAL_MTVEC_CLIC_RESERVED 0x3C +#define METAL_MTVEC_MASK 0x3F #if __riscv_xlen == 32 -#define METAL_MCAUSE_INTR 0x80000000UL -#define METAL_MCAUSE_CAUSE 0x000003FFUL +#define METAL_MCAUSE_INTR 0x80000000UL +#define METAL_MCAUSE_CAUSE 0x000003FFUL #else -#define METAL_MCAUSE_INTR 0x8000000000000000UL -#define METAL_MCAUSE_CAUSE 0x00000000000003FFUL +#define METAL_MCAUSE_INTR 0x8000000000000000UL +#define METAL_MCAUSE_CAUSE 0x00000000000003FFUL #endif -#define METAL_MCAUSE_MINHV 0x40000000UL -#define METAL_MCAUSE_MPP 0x30000000UL -#define METAL_MCAUSE_MPIE 0x08000000UL -#define METAL_MCAUSE_MPIL 0x00FF0000UL -#define METAL_MSTATUS_MIE 0x00000008UL -#define METAL_MSTATUS_MPIE 0x00000080UL -#define METAL_MSTATUS_MPP 0x00001800UL -#define METAL_MSTATUS_FS_INIT 0x00002000UL -#define METAL_MSTATUS_FS_CLEAN 0x00004000UL -#define METAL_MSTATUS_FS_DIRTY 0x00006000UL -#define METAL_MSTATUS_MPRV 0x00020000UL -#define METAL_MSTATUS_MXR 0x00080000UL -#define METAL_MINTSTATUS_MIL 0xFF000000UL -#define METAL_MINTSTATUS_SIL 0x0000FF00UL -#define METAL_MINTSTATUS_UIL 0x000000FFUL - -#define METAL_LOCAL_INTR(X) (16 + X) -#define METAL_MCAUSE_EVAL(cause) (cause & METAL_MCAUSE_INTR) -#define METAL_INTERRUPT(cause) (METAL_MCAUSE_EVAL(cause) ? 1 : 0) -#define METAL_EXCEPTION(cause) (METAL_MCAUSE_EVAL(cause) ? 0 : 1) -#define METAL_SW_INTR_EXCEPTION (METAL_MCAUSE_INTR + 3) -#define METAL_TMR_INTR_EXCEPTION (METAL_MCAUSE_INTR + 7) -#define METAL_EXT_INTR_EXCEPTION (METAL_MCAUSE_INTR + 11) +#define METAL_MCAUSE_MINHV 0x40000000UL +#define METAL_MCAUSE_MPP 0x30000000UL +#define METAL_MCAUSE_MPIE 0x08000000UL +#define METAL_MCAUSE_MPIL 0x00FF0000UL +#define METAL_MSTATUS_MIE 0x00000008UL +#define METAL_MSTATUS_MPIE 0x00000080UL +#define METAL_MSTATUS_MPP 0x00001800UL +#define METAL_MSTATUS_FS_INIT 0x00002000UL +#define METAL_MSTATUS_FS_CLEAN 0x00004000UL +#define METAL_MSTATUS_FS_DIRTY 0x00006000UL +#define METAL_MSTATUS_MPRV 0x00020000UL +#define METAL_MSTATUS_MXR 0x00080000UL +#define METAL_MINTSTATUS_MIL 0xFF000000UL +#define METAL_MINTSTATUS_SIL 0x0000FF00UL +#define METAL_MINTSTATUS_UIL 0x000000FFUL + +#define METAL_LOCAL_INTR(X) (16 + X) +#define METAL_MCAUSE_EVAL(cause) (cause & METAL_MCAUSE_INTR) +#define METAL_INTERRUPT(cause) (METAL_MCAUSE_EVAL(cause) ? 1 : 0) +#define METAL_EXCEPTION(cause) (METAL_MCAUSE_EVAL(cause) ? 0 : 1) +#define METAL_SW_INTR_EXCEPTION (METAL_MCAUSE_INTR + 3) +#define METAL_TMR_INTR_EXCEPTION (METAL_MCAUSE_INTR + 7) +#define METAL_EXT_INTR_EXCEPTION (METAL_MCAUSE_INTR + 11) #define METAL_LOCAL_INTR_EXCEPTION(X) (METAL_MCAUSE_INTR + METAL_LOCAL_INTR(X)) -#define METAL_LOCAL_INTR_RESERVE0 1 -#define METAL_LOCAL_INTR_RESERVE1 2 -#define METAL_LOCAL_INTR_RESERVE2 4 -#define METAL_LOCAL_INTERRUPT_SW 8 /* Bit3 0x008 */ -#define METAL_LOCAL_INTR_RESERVE4 16 -#define METAL_LOCAL_INTR_RESERVE5 32 -#define METAL_LOCAL_INTR_RESERVE6 64 -#define METAL_LOCAL_INTERRUPT_TMR 128 /* Bit7 0x080 */ -#define METAL_LOCAL_INTR_RESERVE8 256 -#define METAL_LOCAL_INTR_RESERVE9 512 -#define METAL_LOCAL_INTR_RESERVE10 1024 -#define METAL_LOCAL_INTERRUPT_EXT 2048 /* Bit11 0x800 */ +#define METAL_LOCAL_INTR_RESERVE0 1 +#define METAL_LOCAL_INTR_RESERVE1 2 +#define METAL_LOCAL_INTR_RESERVE2 4 +#define METAL_LOCAL_INTERRUPT_SW 8 /* Bit3 0x008 */ +#define METAL_LOCAL_INTR_RESERVE4 16 +#define METAL_LOCAL_INTR_RESERVE5 32 +#define METAL_LOCAL_INTR_RESERVE6 64 +#define METAL_LOCAL_INTERRUPT_TMR 128 /* Bit7 0x080 */ +#define METAL_LOCAL_INTR_RESERVE8 256 +#define METAL_LOCAL_INTR_RESERVE9 512 +#define METAL_LOCAL_INTR_RESERVE10 1024 +#define METAL_LOCAL_INTERRUPT_EXT 2048 /* Bit11 0x800 */ /* Bit12 to Bit15 are Reserved */ -#define METAL_LOCAL_INTERRUPT(X) (0x10000 << X) /* Bit16+ Start of Custom Local Interrupt */ -#define METAL_MIE_INTERRUPT METAL_MSTATUS_MIE +#define METAL_LOCAL_INTERRUPT(X) \ + (0x10000 << X) /* Bit16+ Start of Custom Local Interrupt */ +#define METAL_MIE_INTERRUPT METAL_MSTATUS_MIE + +#define METAL_INSN_LENGTH_MASK 3 +#define METAL_INSN_NOT_COMPRESSED 3 typedef enum { - METAL_MACHINE_PRIVILEGE_MODE, - METAL_SUPERVISOR_PRIVILEGE_MODE, - METAL_USER_PRIVILEGE_MODE, + METAL_MACHINE_PRIVILEGE_MODE, + METAL_SUPERVISOR_PRIVILEGE_MODE, + METAL_USER_PRIVILEGE_MODE, } metal_privilege_mode_e; typedef enum { - METAL_INTERRUPT_ID_BASE, - METAL_INTERRUPT_ID_SW = (METAL_INTERRUPT_ID_BASE + 3), - METAL_INTERRUPT_ID_TMR = (METAL_INTERRUPT_ID_BASE + 7), - METAL_INTERRUPT_ID_EXT = (METAL_INTERRUPT_ID_BASE + 11), - METAL_INTERRUPT_ID_LC0 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(0)), - METAL_INTERRUPT_ID_LC1 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(1)), - METAL_INTERRUPT_ID_LC2 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(2)), - METAL_INTERRUPT_ID_LC3 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(3)), - METAL_INTERRUPT_ID_LC4 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(4)), - METAL_INTERRUPT_ID_LC5 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(5)), - METAL_INTERRUPT_ID_LC6 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(6)), - METAL_INTERRUPT_ID_LC7 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(7)), - METAL_INTERRUPT_ID_LC8 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(8)), - METAL_INTERRUPT_ID_LC9 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(9)), - METAL_INTERRUPT_ID_LC10 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(10)), - METAL_INTERRUPT_ID_LC11 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(11)), - METAL_INTERRUPT_ID_LC12 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(12)), - METAL_INTERRUPT_ID_LC13 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(13)), - METAL_INTERRUPT_ID_LC14 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(14)), - METAL_INTERRUPT_ID_LC15 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(15)), - METAL_INTERRUPT_ID_LCMX, - METAL_INTERRUPT_ID_GL0 = METAL_INTERRUPT_ID_LCMX, - METAL_INTERRUPT_ID_GLMX = (METAL_MCAUSE_CAUSE + 1), + METAL_INTERRUPT_ID_BASE, + METAL_INTERRUPT_ID_SW = (METAL_INTERRUPT_ID_BASE + 3), + METAL_INTERRUPT_ID_TMR = (METAL_INTERRUPT_ID_BASE + 7), + METAL_INTERRUPT_ID_EXT = (METAL_INTERRUPT_ID_BASE + 11), + METAL_INTERRUPT_ID_CSW = (METAL_INTERRUPT_ID_BASE + 12), + METAL_INTERRUPT_ID_LC0 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(0)), + METAL_INTERRUPT_ID_LC1 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(1)), + METAL_INTERRUPT_ID_LC2 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(2)), + METAL_INTERRUPT_ID_LC3 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(3)), + METAL_INTERRUPT_ID_LC4 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(4)), + METAL_INTERRUPT_ID_LC5 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(5)), + METAL_INTERRUPT_ID_LC6 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(6)), + METAL_INTERRUPT_ID_LC7 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(7)), + METAL_INTERRUPT_ID_LC8 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(8)), + METAL_INTERRUPT_ID_LC9 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(9)), + METAL_INTERRUPT_ID_LC10 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(10)), + METAL_INTERRUPT_ID_LC11 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(11)), + METAL_INTERRUPT_ID_LC12 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(12)), + METAL_INTERRUPT_ID_LC13 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(13)), + METAL_INTERRUPT_ID_LC14 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(14)), + METAL_INTERRUPT_ID_LC15 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(15)), + METAL_INTERRUPT_ID_LCMX, + METAL_INTERRUPT_ID_GL0 = METAL_INTERRUPT_ID_LCMX, + METAL_INTERRUPT_ID_GLMX = (METAL_MCAUSE_CAUSE + 1), + METAL_INTERRUPT_ID_BEU = 128, } metal_interrupt_id_e; typedef enum { - METAL_IAM_EXCEPTION_CODE, /* Instruction address misaligned */ - METAL_IAF_EXCEPTION_CODE, /* Instruction access faultd */ - METAL_II_EXCEPTION_CODE, /* Illegal instruction */ - METAL_BREAK_EXCEPTION_CODE, /* Breakpoint */ - METAL_LAM_EXCEPTION_CODE, /* Load address misaligned */ - METAL_LAF_EXCEPTION_CODE, /* Load access fault */ - METAL_SAMOAM_EXCEPTION_CODE, /* Store/AMO address misaligned */ - METAL_SAMOAF_EXCEPTION_CODE, /* Store/AMO access fault */ - METAL_ECALL_U_EXCEPTION_CODE, /* Environment call from U-mode */ - METAL_R9_EXCEPTION_CODE, /* Reserved */ - METAL_R10_EXCEPTION_CODE, /* Reserved */ - METAL_ECALL_M_EXCEPTION_CODE, /* Environment call from M-mode */ - METAL_MAX_EXCEPTION_CODE, + METAL_IAM_EXCEPTION_CODE, /* Instruction address misaligned */ + METAL_IAF_EXCEPTION_CODE, /* Instruction access faultd */ + METAL_II_EXCEPTION_CODE, /* Illegal instruction */ + METAL_BREAK_EXCEPTION_CODE, /* Breakpoint */ + METAL_LAM_EXCEPTION_CODE, /* Load address misaligned */ + METAL_LAF_EXCEPTION_CODE, /* Load access fault */ + METAL_SAMOAM_EXCEPTION_CODE, /* Store/AMO address misaligned */ + METAL_SAMOAF_EXCEPTION_CODE, /* Store/AMO access fault */ + METAL_ECALL_U_EXCEPTION_CODE, /* Environment call from U-mode */ + METAL_R9_EXCEPTION_CODE, /* Reserved */ + METAL_R10_EXCEPTION_CODE, /* Reserved */ + METAL_ECALL_M_EXCEPTION_CODE, /* Environment call from M-mode */ + METAL_MAX_EXCEPTION_CODE, } metal_exception_code_e; typedef enum { - METAL_TIMER_MTIME_GET = 1, - METAL_SOFTWARE_IPI_CLEAR, - METAL_SOFTWARE_IPI_SET, - METAL_SOFTWARE_MSIP_GET, - METAL_MAX_INTERRUPT_GET, - METAL_INDEX_INTERRUPT_GET, + METAL_TIMER_MTIME_GET = 1, + METAL_SOFTWARE_IPI_CLEAR, + METAL_SOFTWARE_IPI_SET, + METAL_SOFTWARE_MSIP_GET, + METAL_MAX_INTERRUPT_GET, + METAL_INDEX_INTERRUPT_GET, } metal_interrup_cmd_e; typedef struct __metal_interrupt_data { long long pad : 64; - metal_interrupt_handler_t handler; + metal_interrupt_handler_t handler; void *sub_int; void *exint_data; } __metal_interrupt_data; @@ -154,30 +160,15 @@ typedef struct __metal_interrupt_data { uintptr_t __metal_myhart_id(void); -struct __metal_driver_interrupt_controller_vtable { - void (*interrupt_init)(struct metal_interrupt *controller); - int (*interrupt_register)(struct metal_interrupt *controller, - int id, metal_interrupt_handler_t isr, void *priv_data); - int (*interrupt_enable)(struct metal_interrupt *controller, int id); - int (*interrupt_disable)(struct metal_interrupt *controller, int id); - int (*command_request)(struct metal_interrupt *intr, int cmd, void *data); -}; - struct __metal_driver_vtable_riscv_cpu_intc { - struct metal_interrupt_vtable controller_vtable; + struct metal_interrupt_vtable controller_vtable; }; - void __metal_interrupt_global_enable(void); void __metal_interrupt_global_disable(void); -void __metal_controller_interrupt_vector(metal_vector_mode mode, void *vec_table); -inline int __metal_controller_interrupt_is_selective_vectored (void) -{ - uintptr_t val; - - asm volatile ("csrr %0, mtvec" : "=r"(val)); - return ((val & METAL_MTVEC_CLIC_VECTORED) == METAL_MTVEC_CLIC); -} +metal_vector_mode __metal_controller_interrupt_vector_mode(void); +void __metal_controller_interrupt_vector(metal_vector_mode mode, + void *vec_table); __METAL_DECLARE_VTABLE(__metal_driver_vtable_riscv_cpu_intc) @@ -186,18 +177,20 @@ struct __metal_driver_riscv_cpu_intc { int init_done; uintptr_t metal_mtvec_table[METAL_MAX_MI]; __metal_interrupt_data metal_int_table[METAL_MAX_MI]; + __metal_interrupt_data metal_int_beu; metal_exception_handler_t metal_exception_table[METAL_MAX_ME]; }; /* CPU driver*/ struct __metal_driver_vtable_cpu { - struct metal_cpu_vtable cpu_vtable; + struct metal_cpu_vtable cpu_vtable; }; __METAL_DECLARE_VTABLE(__metal_driver_vtable_cpu) struct __metal_driver_cpu { struct metal_cpu cpu; + unsigned int hpm_count; /* Available HPM counters per CPU */ }; #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_plic0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_plic0.h index 159ee6d69..fac76fbc3 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_plic0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/riscv_plic0.h @@ -7,10 +7,10 @@ #include <metal/compiler.h> #include <metal/drivers/riscv_cpu.h> -#define METAL_PLIC_SOURCE_MASK 0x1F -#define METAL_PLIC_SOURCE_SHIFT 5 -#define METAL_PLIC_SOURCE_PRIORITY_SHIFT 2 -#define METAL_PLIC_SOURCE_PENDING_SHIFT 0 +#define METAL_PLIC_SOURCE_MASK 0x1F +#define METAL_PLIC_SOURCE_SHIFT 5 +#define METAL_PLIC_SOURCE_PRIORITY_SHIFT 2 +#define METAL_PLIC_SOURCE_PENDING_SHIFT 0 struct __metal_driver_vtable_riscv_plic0 { struct metal_interrupt_vtable plic_vtable; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_buserror0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_buserror0.h new file mode 100644 index 000000000..20972109b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_buserror0.h @@ -0,0 +1,184 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_BUSERROR0_H +#define METAL__DRIVERS__SIFIVE_BUSERROR0_H + +/*! + * @file sifive_buserror0.h + * + * @brief API for configuring the SiFive Bus Error Unit + */ + +#include <metal/compiler.h> +#include <stdbool.h> +#include <stdint.h> + +/*! + * @brief The set of possible events handled by a SiFive Bus Error Unit + */ +typedef enum { + /*! @brief No event or error has been detected */ + METAL_BUSERROR_EVENT_NONE = 0, + + /*! @brief A correctable ECC error has occurred in the I$ or ITIM */ + METAL_BUSERROR_EVENT_INST_CORRECTABLE_ECC_ERROR = (1 << 2), + /*! @brief An uncorrectable ECC error has occurred in the I$ or ITIM */ + METAL_BUSERROR_EVENT_INST_UNCORRECTABLE_ECC_ERROR = (1 << 3), + /*! @brief A TileLink load or store bus error has occurred */ + METAL_BUSERROR_EVENT_LOAD_STORE_ERROR = (1 << 5), + /*! @brief A correctable ECC error has occurred in the D$ or DTIM */ + METAL_BUSERROR_EVENT_DATA_CORRECTABLE_ECC_ERROR = (1 << 6), + /*! @brief An uncorrectable ECC error has occurred in the D$ or DTIM */ + METAL_BUSERROR_EVENT_DATA_UNCORRECTABLE_ECC_ERROR = (1 << 7), + + /*! @brief Used to set/clear all interrupts or query/clear all accrued + events */ + METAL_BUSERROR_EVENT_ALL = + METAL_BUSERROR_EVENT_INST_CORRECTABLE_ECC_ERROR | + METAL_BUSERROR_EVENT_INST_UNCORRECTABLE_ECC_ERROR | + METAL_BUSERROR_EVENT_LOAD_STORE_ERROR | + METAL_BUSERROR_EVENT_DATA_CORRECTABLE_ECC_ERROR | + METAL_BUSERROR_EVENT_DATA_UNCORRECTABLE_ECC_ERROR, + /*! @brief A synonym of METAL_BUSERROR_EVENT_ALL */ + METAL_BUSERROR_EVENT_ANY = METAL_BUSERROR_EVENT_ALL, + + /*! @brief A value which is impossible for the bus error unit to report. + * Indicates an error has occurred if provided as a return value. */ + METAL_BUSERROR_EVENT_INVALID = (1 << 8), +} metal_buserror_event_t; + +/*! + * @brief The handle for a bus error unit + */ +struct metal_buserror { + uint8_t __no_empty_structs; +}; + +/*! + * @brief Enable bus error events + * + * Enabling bus error events causes them to be registered as accrued and, + * if the corresponding interrupt is inabled, trigger interrupts. + * + * @param beu The bus error unit handle + * @param events A mask of error events to enable + * @param enabled True if the mask should be enabled, false if they should be + * disabled + * @return 0 upon success + */ +int metal_buserror_set_event_enabled(struct metal_buserror *beu, + metal_buserror_event_t events, + bool enabled); + +/*! + * @brief Get enabled bus error events + * @param beu The bus error unit handle + * @return A mask of all enabled events + */ +metal_buserror_event_t +metal_buserror_get_event_enabled(struct metal_buserror *beu); + +/*! + * @brief Enable or disable the platform interrupt + * + * @param beu The bus error unit handle + * @param event The error event which would trigger the interrupt + * @param enabled True if the interrupt should be enabled + * @return 0 upon success + */ +int metal_buserror_set_platform_interrupt(struct metal_buserror *beu, + metal_buserror_event_t events, + bool enabled); + +/*! + * @brief Enable or disable the hart-local interrupt + * + * @param beu The bus error unit handle + * @param event The error event which would trigger the interrupt + * @param enabled True if the interrupt should be enabled + * @return 0 upon success + */ +int metal_buserror_set_local_interrupt(struct metal_buserror *beu, + metal_buserror_event_t events, + bool enabled); + +/*! + * @brief Get the error event which caused the most recent interrupt + * + * This method should be called from within the interrupt handler for the bus + * error unit interrupt + * + * @param beu The bus error unit handle + * @return The event which caused the interrupt + */ +metal_buserror_event_t metal_buserror_get_cause(struct metal_buserror *beu); + +/*! + * @brief Clear the cause register for the bus error unit + * + * This method should be called from within the interrupt handler for the bus + * error unit to un-latch the cause register for the next event + * + * @param beu The bus error unit handle + * @return 0 upon success + */ +int metal_buserror_clear_cause(struct metal_buserror *beu); + +/*! + * @brief Get the physical address of the error event + * + * This method should be called from within the interrupt handler for the bus + * error unit. + * + * @param beu The bus error unit handle + * @return The address of the error event + */ +uintptr_t metal_buserror_get_event_address(struct metal_buserror *beu); + +/*! + * @brief Returns true if the event is set in the accrued register + * + * @param beu The bus error unit handle + * @param event The event to query + * @return True if the event is set in the accrued register + */ +bool metal_buserror_is_event_accrued(struct metal_buserror *beu, + metal_buserror_event_t events); + +/*! + * @brief Clear the given event from the accrued register + * + * @param beu The bus error unit handle + * @param event The event to clear + * @return 0 upon success + */ +int metal_buserror_clear_event_accrued(struct metal_buserror *beu, + metal_buserror_event_t events); + +/*! + * @brief get the platform-level interrupt parent of the bus error unit + * + * @param beu The bus error unit handle + * @return A pointer to the interrupt parent + */ +struct metal_interrupt * +metal_buserror_get_platform_interrupt_parent(struct metal_buserror *beu); + +/*! + * @brief Get the platform-level interrupt id for the bus error unit interrupt + * + * @param beu The bus error unit handle + * @return The interrupt id + */ +int metal_buserror_get_platform_interrupt_id(struct metal_buserror *beu); + +/*! + * @brief Get the hart-local interrupt id for the bus error unit interrupt + * + * @param beu The bus error unit handle + * @return The interrupt id + */ +int metal_buserror_get_local_interrupt_id(struct metal_buserror *beu); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_ccache0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_ccache0.h new file mode 100644 index 000000000..13a47c0b9 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_ccache0.h @@ -0,0 +1,140 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_CCACHE0_H +#define METAL__DRIVERS__SIFIVE_CCACHE0_H + +/*! + * @file sifive_ccache0.h + * + * @brief API for configuring the SiFive L2 cache controller + */ + +#include <metal/interrupt.h> +#include <stdint.h> + +/*! @brief Cache configuration data */ +typedef struct { + uint32_t num_bank; + uint32_t num_ways; + uint32_t num_sets; + uint32_t block_size; +} sifive_ccache0_config; + +/*! @brief Set of values for ECC error type */ +typedef enum { + SIFIVE_CCACHE0_DATA = 0, + SIFIVE_CCACHE0_DIR = 1, +} sifive_ccache0_ecc_errtype_t; + +/*! @brief Initialize cache controller, enables all available + * cache-ways. + * Note: If LIM is in use, corresponding cache ways are not enabled. + * @param None. + * @return 0 If no error.*/ +int sifive_ccache0_init(void); + +/*! @brief Get cache configuration data. + * @param config User specified data buffer. + * @return None.*/ +void sifive_ccache0_get_config(sifive_ccache0_config *config); + +/*! @brief Get currently active cache ways. + * @param None. + * @return Number of cache ways enabled.*/ +uint32_t sifive_ccache0_get_enabled_ways(void); + +/*! @brief Enable specified cache ways. + * @param ways Number of ways to be enabled. + * @return 0 If no error.*/ +int sifive_ccache0_set_enabled_ways(uint32_t ways); + +/*! @brief Inject ECC error into data or meta-data. + * @param bitindex Bit index to be corrupted on next cache operation. + * @param type ECC error target location. + * @return None.*/ +void sifive_ccache0_inject_ecc_error(uint32_t bitindex, + sifive_ccache0_ecc_errtype_t type); + +/*! @brief Flush out entire cache block containing given address. + * @param flush_addr Address for the cache block to be flushed. + * @return None.*/ +void sifive_ccache0_flush(uintptr_t flush_addr); + +/*! @brief Get most recently ECC corrected address. + * @param type ECC error target location. + * @return Last corrected ECC address.*/ +uintptr_t sifive_ccache0_get_ecc_fix_addr(sifive_ccache0_ecc_errtype_t type); + +/*! @brief Get number of times ECC errors were corrected. + * Clears related ECC interrupt signals. + * @param type ECC error target location. + * @return Corrected ECC error count.*/ +uint32_t sifive_ccache0_get_ecc_fix_count(sifive_ccache0_ecc_errtype_t type); + +/*! @brief Get address location of most recent uncorrected ECC error. + * @param type ECC error target location. + * @return Last uncorrected ECC address.*/ +uintptr_t sifive_ccache0_get_ecc_fail_addr(sifive_ccache0_ecc_errtype_t type); + +/*! @brief Get number of times ECC errors were not corrected. + * Clears related ECC interrupt signals. + * @param type ECC error target location. + * @return Uncorrected ECC error count.*/ +uint32_t sifive_ccache0_get_ecc_fail_count(sifive_ccache0_ecc_errtype_t type); + +/*! @brief Get currently active way enable mask value for the given master ID. + * @param master_id Cache controller master ID. + * @return Way enable mask. */ +uint64_t sifive_ccache0_get_way_mask(uint32_t master_id); + +/*! @brief Set way enable mask for the given master ID. + * @param master_id Cache controller master ID. + * @param waymask Specify ways to be enabled. + * @return 0 If no error.*/ +int sifive_ccache0_set_way_mask(uint32_t master_id, uint64_t waymask); + +/*! @brief Select cache performance events to be counted. + * @param counter Cache performance monitor counter index. + * @param mask Event selection mask. + * @return None.*/ +void sifive_ccache0_set_pmevent_selector(uint32_t counter, uint64_t mask); + +/*! @brief Get currently set events for the given counter index. + * @param counter Cache performance monitor counter index. + * @return Event selection mask.*/ +uint64_t sifive_ccache0_get_pmevent_selector(uint32_t counter); + +/*! @brief Clears specified cache performance counter. + * @param counter Cache performance monitor counter index. + * @return None.*/ +void sifive_ccache0_clr_pmevent_counter(uint32_t counter); + +/*! @brief Reads specified cache performance counter. + * @param counter Cache performance monitor counter index. + * @return Counter value.*/ +uint64_t sifive_ccache0_get_pmevent_counter(uint32_t counter); + +/*! @brief Select cache clients to be excluded from performance monitoring. + * @param mask Client disable mask. + * @return None.*/ +void sifive_ccache0_set_client_filter(uint64_t mask); + +/*! @brief Get currently set cache client disable mask. + * @param None. + * @return Client disable mask.*/ +uint64_t sifive_ccache0_get_client_filter(void); + +/*! @brief Get interrupt IDs for the cache controller. + * @param src Interrupt trigger source index. + * @return Interrupt id.*/ +int sifive_ccache0_get_interrupt_id(uint32_t src); + +/*! @brief Get interrupt controller of the cache. + * The interrupt controller must be initialized before any interrupts can be + * registered or enabled with it. + * @param None. + * @return Handle for the interrupt controller.*/ +struct metal_interrupt *sifive_ccache0_interrupt_controller(void); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_clic0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_clic0.h index db9674625..b8ff82271 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_clic0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_clic0.h @@ -7,21 +7,21 @@ #include <metal/compiler.h> #include <metal/drivers/riscv_cpu.h> -#define METAL_CLIC_MAX_NMBITS 2 -#define METAL_CLIC_MAX_NLBITS 8 -#define METAL_CLIC_MAX_NVBITS 1 +#define METAL_CLIC_MAX_NMBITS 2 +#define METAL_CLIC_MAX_NLBITS 8 +#define METAL_CLIC_MAX_NVBITS 1 -#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_MMODE 0x00 -#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_SMODE1 0x20 -#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_SMODE2 0x40 -#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_MASK 0x60 -#define METAL_SIFIVE_CLIC0_CLICCFG_NLBITS_MASK 0x1E -#define METAL_SIFIVE_CLIC0_CLICCFG_NVBIT_MASK 0x01 +#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_MMODE 0x00 +#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_SMODE1 0x20 +#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_SMODE2 0x40 +#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_MASK 0x60 +#define METAL_SIFIVE_CLIC0_CLICCFG_NLBITS_MASK 0x1E +#define METAL_SIFIVE_CLIC0_CLICCFG_NVBIT_MASK 0x01 -#define METAL_CLIC_ICTRL_SMODE1_MASK 0x7F /* b8 set imply M-mode */ -#define METAL_CLIC_ICTRL_SMODE2_MASK 0x3F /* b8 set M-mode, b7 clear U-mode */ +#define METAL_CLIC_ICTRL_SMODE1_MASK 0x7F /* b8 set imply M-mode */ +#define METAL_CLIC_ICTRL_SMODE2_MASK 0x3F /* b8 set M-mode, b7 clear U-mode */ -#define METAL_MAX_INTERRUPT_LEVEL ((1 << METAL_CLIC_MAX_NLBITS) - 1) +#define METAL_MAX_INTERRUPT_LEVEL ((1 << METAL_CLIC_MAX_NLBITS) - 1) struct __metal_driver_vtable_sifive_clic0 { struct metal_interrupt_vtable clic_vtable; @@ -34,9 +34,15 @@ __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_clic0) struct __metal_driver_sifive_clic0 { struct metal_interrupt controller; int init_done; - metal_interrupt_handler_t metal_mtvt_table[__METAL_CLIC_SUBINTERRUPTS]; + struct { + } __attribute__((aligned(64))); + metal_interrupt_vector_handler_t + metal_mtvt_table[__METAL_CLIC_SUBINTERRUPTS]; __metal_interrupt_data metal_exint_table[__METAL_CLIC_SUBINTERRUPTS]; }; #undef __METAL_MACHINE_MACROS +int __metal_driver_sifive_clic0_command_request( + struct metal_interrupt *controller, int command, void *data); + #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfrosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfrosc.h index d311f0cf2..d60d3a3bd 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfrosc.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_hfrosc.h @@ -4,9 +4,9 @@ #ifndef METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H #define METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H -#include <metal/drivers/sifive_fe310-g000_prci.h> -#include <metal/compiler.h> #include <metal/clock.h> +#include <metal/compiler.h> +#include <metal/drivers/sifive_fe310-g000_prci.h> #include <metal/io.h> struct __metal_driver_vtable_sifive_fe310_g000_hfrosc { diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_lfrosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_lfrosc.h new file mode 100644 index 000000000..2650584ad --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_lfrosc.h @@ -0,0 +1,21 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_FE310_G000_LFROSC_H +#define METAL__DRIVERS__SIFIVE_FE310_G000_LFROSC_H + +#include <metal/clock.h> +#include <metal/compiler.h> +#include <metal/io.h> + +struct __metal_driver_vtable_sifive_fe310_g000_lfrosc { + struct __metal_clock_vtable clock; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_lfrosc) + +struct __metal_driver_sifive_fe310_g000_lfrosc { + struct metal_clock clock; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_prci.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_prci.h index 87c9ca985..4fca30167 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_prci.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fe310-g000_prci.h @@ -10,14 +10,16 @@ struct __metal_driver_sifive_fe310_g000_prci; struct __metal_driver_vtable_sifive_fe310_g000_prci { - long (*get_reg)(const struct __metal_driver_sifive_fe310_g000_prci *, long offset); - long (*set_reg)(const struct __metal_driver_sifive_fe310_g000_prci *, long offset, long value); + long (*get_reg)(const struct __metal_driver_sifive_fe310_g000_prci *, + long offset); + long (*set_reg)(const struct __metal_driver_sifive_fe310_g000_prci *, + long offset, long value); }; __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_prci) struct __metal_driver_sifive_fe310_g000_prci { + const struct __metal_driver_vtable_sifive_fe310_g000_prci *vtable; }; #endif - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fu540-c000_l2.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fu540-c000_l2.h deleted file mode 100644 index 8c3cf907e..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_fu540-c000_l2.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_FU540_C000_L2_H -#define METAL__DRIVERS__SIFIVE_FU540_C000_L2_H - -struct __metal_driver_sifive_fu540_c000_l2; - -#include <stdint.h> -#include <metal/cache.h> - -struct __metal_driver_vtable_sifive_fu540_c000_l2 { - struct __metal_cache_vtable cache; -}; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fu540_c000_l2) - -struct __metal_driver_sifive_fu540_c000_l2 { - struct metal_cache cache; -}; - -#endif - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-buttons.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-buttons.h index a0caeaba8..7227eee02 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-buttons.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-buttons.h @@ -4,12 +4,12 @@ #ifndef METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H #define METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H -#include <string.h> #include <metal/button.h> #include <metal/compiler.h> +#include <string.h> struct __metal_driver_vtable_sifive_button { - struct metal_button_vtable button_vtable; + struct metal_button_vtable button_vtable; }; __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_button) diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-leds.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-leds.h index a8dacf116..abfca01c2 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-leds.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-leds.h @@ -4,12 +4,12 @@ #ifndef METAL__DRIVERS__SIFIVE_GPIO_LEDS_H #define METAL__DRIVERS__SIFIVE_GPIO_LEDS_H +#include <metal/compiler.h> #include <metal/drivers/sifive_gpio0.h> #include <metal/led.h> -#include <metal/compiler.h> struct __metal_driver_vtable_sifive_led { - struct metal_led_vtable led_vtable; + struct metal_led_vtable led_vtable; }; __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_led) diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-switches.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-switches.h index c9c7839e9..be55a0446 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-switches.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio-switches.h @@ -4,12 +4,12 @@ #ifndef METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H #define METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H +#include <metal/compiler.h> #include <metal/drivers/sifive_gpio0.h> #include <metal/switch.h> -#include <metal/compiler.h> struct __metal_driver_vtable_sifive_switch { - struct metal_switch_vtable switch_vtable; + struct metal_switch_vtable switch_vtable; }; __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_switch) diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio0.h index cc56dc722..50314222d 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_gpio0.h @@ -11,7 +11,7 @@ struct __metal_driver_vtable_sifive_gpio0 { const struct __metal_gpio_vtable gpio; }; -//struct __metal_driver_sifive_gpio0; +// struct __metal_driver_sifive_gpio0; __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_gpio0) diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_i2c0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_i2c0.h new file mode 100644 index 000000000..8fbbe21e1 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_i2c0.h @@ -0,0 +1,24 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_I2C0_H +#define METAL__DRIVERS__SIFIVE_I2C0_H + +#include <metal/clock.h> +#include <metal/i2c.h> + +struct __metal_driver_vtable_sifive_i2c0 { + const struct metal_i2c_vtable i2c; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_i2c0) + +struct __metal_driver_sifive_i2c0 { + struct metal_i2c i2c; + unsigned int init_done; + unsigned int baud_rate; + metal_clock_callback pre_rate_change_callback; + metal_clock_callback post_rate_change_callback; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_l2pf0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_l2pf0.h new file mode 100644 index 000000000..63c8e6536 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_l2pf0.h @@ -0,0 +1,78 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_L2PF0_H +#define METAL__DRIVERS__SIFIVE_L2PF0_H + +/*! + * @file sifive_l2pf0.h + * + * @brief API for configuring the SiFive L2 prefetcher. + */ + +#include <stdint.h> + +/*! @brief L2 prefetcher configuration */ +typedef struct { + /* Enable L2 hardware prefetcher */ + uint8_t HwPrefetchEnable; + + /* Only works when CrossPageEn === 0. + Cross Page optimization disable: + 0 -> Entry goes into Pause state while crossing Page boundary. + Next time when the demand miss happens on the same page, it doesn’t need + to train again. 1 -> The entry is invalidated in case of a cross page. */ + uint8_t CrossPageOptmDisable; + + /* Enable prefetches to cross pages */ + uint8_t CrossPageEn; + + /* Age-out mechanism enable */ + uint8_t AgeOutEn; + + uint32_t PrefetchDistance; + + uint32_t MaxAllowedDistance; + + /* Linear to exponential threshold */ + uint32_t LinToExpThreshold; + + /* No. of non-matching loads to edge out an entry */ + uint32_t NumLdsToAgeOut; + + /* Threshold no. of Fullness (L2 MSHRs used/ total available) to stop + * sending hits */ + uint32_t QFullnessThreshold; + + /* Threshold no. of CacheHits for evicting SPF entry */ + uint32_t HitCacheThreshold; + + /* Threshold no. of MSHR hits for increasing SPF distance */ + uint32_t hitMSHRThreshold; + + /* Size of the comparison window for address matching */ + uint32_t Window; + +} sifive_l2pf0_config; + +/*! @brief Enable L2 hardware prefetcher unit. + * @param None. + * @return None.*/ +void sifive_l2pf0_enable(void); + +/*! @brief Disable L2 hardware prefetcher unit. + * @param None. + * @return None.*/ +void sifive_l2pf0_disable(void); + +/*! @brief Get currently active L2 prefetcher configuration. + * @param config Pointer to user specified configuration structure. + * @return None.*/ +void sifive_l2pf0_get_config(sifive_l2pf0_config *config); + +/*! @brief Enables fine grain access to L2 prefetcher configuration. + * @param config Pointer to user structure with values to be set. + * @return None.*/ +void sifive_l2pf0_set_config(sifive_l2pf0_config *config); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_local-external-interrupts0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_local-external-interrupts0.h index aa8d63078..320ab10d2 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_local-external-interrupts0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_local-external-interrupts0.h @@ -18,5 +18,4 @@ struct __metal_driver_sifive_local_external_interrupts0 { int init_done; }; - #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_pwm0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_pwm0.h new file mode 100644 index 000000000..caa774401 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_pwm0.h @@ -0,0 +1,29 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_PWM0_H +#define METAL__DRIVERS__SIFIVE_PWM0_H + +#include <metal/clock.h> +#include <metal/pwm.h> + +struct __metal_driver_vtable_sifive_pwm0 { + const struct metal_pwm_vtable pwm; +}; + +/* Max possible PWM channel count */ +#define METAL_MAX_PWM_CHANNELS 16 + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_pwm0) + +struct __metal_driver_sifive_pwm0 { + struct metal_pwm pwm; + unsigned int max_count; + unsigned int count_val; + unsigned int freq; + unsigned int duty[METAL_MAX_PWM_CHANNELS]; + metal_clock_callback pre_rate_change_callback; + metal_clock_callback post_rate_change_callback; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_rtc0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_rtc0.h new file mode 100644 index 000000000..a35ab9a09 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_rtc0.h @@ -0,0 +1,26 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_RTC0_H +#define METAL__DRIVERS__SIFIVE_RTC0_H + +#include <metal/compiler.h> +#include <metal/io.h> + +#include <metal/clock.h> +#include <metal/interrupt.h> +#include <metal/rtc.h> + +struct __metal_driver_vtable_sifive_rtc0 { + const struct metal_rtc_vtable rtc; +}; + +struct __metal_driver_sifive_rtc0; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_rtc0) + +struct __metal_driver_sifive_rtc0 { + const struct metal_rtc rtc; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_simuart0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_simuart0.h new file mode 100644 index 000000000..f6b739143 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_simuart0.h @@ -0,0 +1,29 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_SIMUART0_H +#define METAL__DRIVERS__SIFIVE_SIMUART0_H + +#include <metal/clock.h> +#include <metal/compiler.h> +#include <metal/drivers/riscv_plic0.h> +#include <metal/drivers/sifive_gpio0.h> +#include <metal/io.h> +#include <metal/uart.h> + +struct __metal_driver_vtable_sifive_simuart0 { + const struct metal_uart_vtable uart; +}; + +struct __metal_driver_sifive_simuart0; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_simuart0) + +struct __metal_driver_sifive_simuart0 { + struct metal_uart uart; + unsigned long baud_rate; + metal_clock_callback pre_rate_change_callback; + metal_clock_callback post_rate_change_callback; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_spi0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_spi0.h index 90d4c831e..73527944b 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_spi0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_spi0.h @@ -4,9 +4,9 @@ #ifndef METAL__DRIVERS__SIFIVE_SPI0_H #define METAL__DRIVERS__SIFIVE_SPI0_H -#include <metal/drivers/sifive_gpio0.h> #include <metal/clock.h> #include <metal/compiler.h> +#include <metal/drivers/sifive_gpio0.h> #include <metal/io.h> #include <metal/spi.h> @@ -19,6 +19,8 @@ __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_spi0) struct __metal_driver_sifive_spi0 { struct metal_spi spi; unsigned long baud_rate; + metal_clock_callback pre_rate_change_callback; + metal_clock_callback post_rate_change_callback; }; #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_test0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_test0.h index e87db2c83..debd3fb9d 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_test0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_test0.h @@ -17,5 +17,4 @@ struct __metal_driver_sifive_test0 { struct __metal_shutdown shutdown; }; - #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_trace.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_trace.h new file mode 100644 index 000000000..3c67522f4 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_trace.h @@ -0,0 +1,23 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_TRACE_H +#define METAL__DRIVERS__SIFIVE_TRACE_H + +#include <metal/compiler.h> +#include <metal/io.h> +#include <metal/uart.h> + +struct __metal_driver_vtable_sifive_trace { + const struct metal_uart_vtable uart; +}; + +struct __metal_driver_sifive_trace; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_trace) + +struct __metal_driver_sifive_trace { + struct metal_uart uart; +}; + +#endif /* METAL__DRIVERS__SIFIVE_TRACE_H */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_uart0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_uart0.h index 11d954002..2b38e4631 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_uart0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_uart0.h @@ -4,12 +4,12 @@ #ifndef METAL__DRIVERS__SIFIVE_UART0_H #define METAL__DRIVERS__SIFIVE_UART0_H -#include <metal/drivers/sifive_gpio0.h> -#include <metal/drivers/riscv_plic0.h> #include <metal/clock.h> +#include <metal/compiler.h> +#include <metal/drivers/riscv_plic0.h> +#include <metal/drivers/sifive_gpio0.h> #include <metal/io.h> #include <metal/uart.h> -#include <metal/compiler.h> struct __metal_driver_vtable_sifive_uart0 { const struct metal_uart_vtable uart; @@ -22,7 +22,8 @@ __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_uart0) struct __metal_driver_sifive_uart0 { struct metal_uart uart; unsigned long baud_rate; + metal_clock_callback pre_rate_change_callback; + metal_clock_callback post_rate_change_callback; }; - #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_wdog0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_wdog0.h new file mode 100644 index 000000000..bb3424584 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/sifive_wdog0.h @@ -0,0 +1,26 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_WDOG0_H +#define METAL__DRIVERS__SIFIVE_WDOG0_H + +#include <metal/compiler.h> +#include <metal/io.h> + +#include <metal/clock.h> +#include <metal/interrupt.h> +#include <metal/watchdog.h> + +struct __metal_driver_vtable_sifive_wdog0 { + const struct metal_watchdog_vtable watchdog; +}; + +struct __metal_driver_sifive_wdog0; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_wdog0) + +struct __metal_driver_sifive_wdog0 { + const struct metal_watchdog watchdog; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/ucb_htif0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/ucb_htif0.h new file mode 100644 index 000000000..210d0819b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/drivers/ucb_htif0.h @@ -0,0 +1,48 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__UCB_HTIF0_H +#define METAL__DRIVERS__UCB_HTIF0_H + +#include <metal/compiler.h> +#include <metal/shutdown.h> +#include <metal/uart.h> + +struct __metal_driver_vtable_ucb_htif0_shutdown { + const struct __metal_shutdown_vtable shutdown; +}; + +struct __metal_driver_vtable_ucb_htif0_uart { + const struct metal_uart_vtable uart; +}; + +struct __metal_driver_ucb_htif0; + +void __metal_driver_ucb_htif0_exit(const struct __metal_shutdown *test, + int code) __attribute__((noreturn)); + +void __metal_driver_ucb_htif0_init(struct metal_uart *uart, int baud_rate); +int __metal_driver_ucb_htif0_putc(struct metal_uart *uart, int c); +int __metal_driver_ucb_htif0_getc(struct metal_uart *uart, int *c); +int __metal_driver_ucb_htif0_get_baud_rate(struct metal_uart *guart); +int __metal_driver_ucb_htif0_set_baud_rate(struct metal_uart *guart, + int baud_rate); +struct metal_interrupt * +__metal_driver_ucb_htif0_interrupt_controller(struct metal_uart *uart); +int __metal_driver_ucb_htif0_get_interrupt_id(struct metal_uart *uart); + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_ucb_htif0_shutdown) + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_ucb_htif0_uart) + +struct __metal_driver_ucb_htif0_shutdown { + struct __metal_shutdown shutdown; + const struct __metal_driver_vtable_ucb_htif0_shutdown *vtable; +}; + +struct __metal_driver_ucb_htif0_uart { + struct metal_uart uart; + const struct __metal_driver_vtable_ucb_htif0_uart *vtable; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/gpio.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/gpio.h index 513687dd7..df9adb451 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/gpio.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/gpio.h @@ -5,6 +5,7 @@ #define METAL__GPIO_H #include <metal/compiler.h> +#include <metal/interrupt.h> /*! * @file gpio.h @@ -15,20 +16,37 @@ struct metal_gpio; struct __metal_gpio_vtable { int (*disable_input)(struct metal_gpio *, long pins); + int (*enable_input)(struct metal_gpio *, long pins); + long (*input)(struct metal_gpio *); long (*output)(struct metal_gpio *); + int (*disable_output)(struct metal_gpio *, long pins); int (*enable_output)(struct metal_gpio *, long pins); int (*output_set)(struct metal_gpio *, long value); int (*output_clear)(struct metal_gpio *, long value); int (*output_toggle)(struct metal_gpio *, long value); int (*enable_io)(struct metal_gpio *, long pins, long dest); + int (*disable_io)(struct metal_gpio *, long pins); + int (*config_int)(struct metal_gpio *, long pins, int intr_type); + int (*clear_int)(struct metal_gpio *, long pins, int intr_type); + struct metal_interrupt *(*interrupt_controller)(struct metal_gpio *gpio); + int (*get_interrupt_id)(struct metal_gpio *gpio, int pin); }; +#define METAL_GPIO_INT_DISABLE 0 +#define METAL_GPIO_INT_RISING 1 +#define METAL_GPIO_INT_FALLING 2 +#define METAL_GPIO_INT_BOTH_EDGE 3 +#define METAL_GPIO_INT_LOW 4 +#define METAL_GPIO_INT_HIGH 5 +#define METAL_GPIO_INT_BOTH_LEVEL 6 +#define METAL_GPIO_INT_MAX 7 + /*! * @struct metal_gpio * @brief The handle for a GPIO interface */ struct metal_gpio { - const struct __metal_gpio_vtable *vtable; + const struct __metal_gpio_vtable *vtable; }; /*! @@ -36,7 +54,21 @@ struct metal_gpio { * @param device_num The GPIO device index * @return The GPIO device handle, or NULL if there is no device at that index */ -struct metal_gpio *metal_gpio_get_device(int device_num); +struct metal_gpio *metal_gpio_get_device(unsigned int device_num); + +/*! + * @brief enable input on a pin + * @param gpio The handle for the GPIO interface + * @param pin The pin number indexed from 0 + * @return 0 if the input is successfully enabled + */ +__inline__ int metal_gpio_enable_input(struct metal_gpio *gpio, int pin) { + if (!gpio) { + return 1; + } + + return gpio->vtable->enable_input(gpio, (1 << pin)); +} /*! * @brief Disable input on a pin @@ -44,9 +76,9 @@ struct metal_gpio *metal_gpio_get_device(int device_num); * @param pin The pin number indexed from 0 * @return 0 if the input is successfully disabled */ -inline int metal_gpio_disable_input(struct metal_gpio *gpio, int pin) { - if(!gpio) { - return 1; +__inline__ int metal_gpio_disable_input(struct metal_gpio *gpio, int pin) { + if (!gpio) { + return 1; } return gpio->vtable->disable_input(gpio, (1 << pin)); @@ -58,30 +90,64 @@ inline int metal_gpio_disable_input(struct metal_gpio *gpio, int pin) { * @param pin The pin number indexed from 0 * @return 0 if the output is successfully enabled */ -inline int metal_gpio_enable_output(struct metal_gpio *gpio, int pin) { - if(!gpio) { - return 1; +__inline__ int metal_gpio_enable_output(struct metal_gpio *gpio, int pin) { + if (!gpio) { + return 1; } return gpio->vtable->enable_output(gpio, (1 << pin)); } /*! + * @brief Disable output on a pin + * @param gpio The handle for the GPIO interface + * @param pin The pin number indexed from 0 + * @return 0 if the output is successfully disabled + */ +__inline__ int metal_gpio_disable_output(struct metal_gpio *gpio, int pin) { + if (!gpio) { + return 1; + } + + return gpio->vtable->disable_output(gpio, (1 << pin)); +} + +/*! * @brief Set the output value of a GPIO pin * @param gpio The handle for the GPIO interface * @param pin The pin number indexed from 0 * @param value The value to set the pin to * @return 0 if the output is successfully set */ -inline int metal_gpio_set_pin(struct metal_gpio *gpio, int pin, int value) { - if(!gpio) { - return 1; +__inline__ int metal_gpio_set_pin(struct metal_gpio *gpio, int pin, int value) { + if (!gpio) { + return 1; + } + + if (value == 0) { + return gpio->vtable->output_clear(gpio, (1 << pin)); + } else { + return gpio->vtable->output_set(gpio, (1 << pin)); } +} + +/*! + * @brief Get the value of the GPIO pin + * @param gpio The handle for the GPIO interface + * @param pin The pin number indexed from 0 + * @return The value of the GPIO pin + */ +__inline__ int metal_gpio_get_input_pin(struct metal_gpio *gpio, int pin) { + if (!gpio) { + return 0; + } + + long value = gpio->vtable->input(gpio); - if(value == 0) { - return gpio->vtable->output_clear(gpio, (1 << pin)); + if (value & (1 << pin)) { + return 1; } else { - return gpio->vtable->output_set(gpio, (1 << pin)); + return 0; } } @@ -91,17 +157,17 @@ inline int metal_gpio_set_pin(struct metal_gpio *gpio, int pin, int value) { * @param pin The pin number indexed from 0 * @return The value of the GPIO pin */ -inline int metal_gpio_get_pin(struct metal_gpio *gpio, int pin) { - if(!gpio) { - return 0; +__inline__ int metal_gpio_get_output_pin(struct metal_gpio *gpio, int pin) { + if (!gpio) { + return 0; } long value = gpio->vtable->output(gpio); - if(value & (1 << pin)) { - return 1; + if (value & (1 << pin)) { + return 1; } else { - return 0; + return 0; } } @@ -111,9 +177,9 @@ inline int metal_gpio_get_pin(struct metal_gpio *gpio, int pin) { * @param pin The pin number indexed from 0 * @return 0 if the pin is successfully cleared */ -inline int metal_gpio_clear_pin(struct metal_gpio *gpio, int pin) { - if(!gpio) { - return 1; +__inline__ int metal_gpio_clear_pin(struct metal_gpio *gpio, int pin) { + if (!gpio) { + return 1; } return gpio->vtable->output_clear(gpio, (1 << pin)); @@ -125,9 +191,9 @@ inline int metal_gpio_clear_pin(struct metal_gpio *gpio, int pin) { * @param pin The pin number indexed from 0 * @return 0 if the pin is successfully toggled */ -inline int metal_gpio_toggle_pin(struct metal_gpio *gpio, int pin) { - if(!gpio) { - return 1; +__inline__ int metal_gpio_toggle_pin(struct metal_gpio *gpio, int pin) { + if (!gpio) { + return 1; } return gpio->vtable->output_toggle(gpio, (1 << pin)); @@ -140,12 +206,82 @@ inline int metal_gpio_toggle_pin(struct metal_gpio *gpio, int pin) { * @param io_function The IO function to set * @return 0 if the pinmux is successfully set */ -inline int metal_gpio_enable_pinmux(struct metal_gpio *gpio, int pin, int io_function) { - if(!gpio) { - return 1; +__inline__ int metal_gpio_enable_pinmux(struct metal_gpio *gpio, int pin, + int io_function) { + if (!gpio) { + return 1; } return gpio->vtable->enable_io(gpio, (1 << pin), (io_function << pin)); } +/*! + * @brief Disables the pinmux for a GPIO pin + * @param gpio The handle for the GPIO interface + * @param pin The bitmask for the pin to disable pinmux on + * @return 0 if the pinmux is successfully set + */ +__inline__ int metal_gpio_disable_pinmux(struct metal_gpio *gpio, int pin) { + if (!gpio) { + return 1; + } + + return gpio->vtable->disable_io(gpio, (1 << pin)); +} + +/*! + * @brief Config gpio interrupt type + * @param gpio The handle for the GPIO interface + * @param pin The bitmask for the pin to enable gpio interrupt + * @param intr_type The interrupt type + * @return 0 if the interrupt mode is setup properly + */ +__inline__ int metal_gpio_config_interrupt(struct metal_gpio *gpio, int pin, + int intr_type) { + if (!gpio) { + return 1; + } + + return gpio->vtable->config_int(gpio, (1 << pin), intr_type); +} + +/*! + * @brief Clear gpio interrupt status + * @param gpio The handle for the GPIO interface + * @param pin The bitmask for the pin to clear gpio interrupt + * @param intr_type The interrupt type to be clear + * @return 0 if the interrupt is cleared + */ +__inline__ int metal_gpio_clear_interrupt(struct metal_gpio *gpio, int pin, + int intr_type) { + if (!gpio) { + return 1; + } + + return gpio->vtable->clear_int(gpio, (1 << pin), intr_type); +} + +/*! + * @brief Get the interrupt controller for a gpio + * + * @param gpio The handle for the gpio + * @return A pointer to the interrupt controller responsible for handling + * gpio interrupts. + */ +__inline__ struct metal_interrupt * +metal_gpio_interrupt_controller(struct metal_gpio *gpio) { + return gpio->vtable->interrupt_controller(gpio); +} + +/*! + * @brief Get the interrupt id for a gpio + * + * @param gpio The handle for the gpio + * @param pin The bitmask for the pin to get gpio interrupt id + * @return The interrupt id corresponding to a gpio. + */ +__inline__ int metal_gpio_get_interrupt_id(struct metal_gpio *gpio, int pin) { + return gpio->vtable->get_interrupt_id(gpio, pin); +} + #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/hpm.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/hpm.h new file mode 100644 index 000000000..290f7ec3f --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/hpm.h @@ -0,0 +1,146 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__HPM_H +#define METAL__HPM_H + +#include <metal/cpu.h> + +/*! @brief Macros for valid Event IDs */ +#define METAL_HPM_EVENTID_8 (1UL << 8) +#define METAL_HPM_EVENTID_9 (1UL << 9) +#define METAL_HPM_EVENTID_10 (1UL << 10) +#define METAL_HPM_EVENTID_11 (1UL << 11) +#define METAL_HPM_EVENTID_12 (1UL << 12) +#define METAL_HPM_EVENTID_13 (1UL << 13) +#define METAL_HPM_EVENTID_14 (1UL << 14) +#define METAL_HPM_EVENTID_15 (1UL << 15) +#define METAL_HPM_EVENTID_16 (1UL << 16) +#define METAL_HPM_EVENTID_17 (1UL << 17) +#define METAL_HPM_EVENTID_18 (1UL << 18) +#define METAL_HPM_EVENTID_19 (1UL << 19) +#define METAL_HPM_EVENTID_20 (1UL << 20) +#define METAL_HPM_EVENTID_21 (1UL << 21) +#define METAL_HPM_EVENTID_22 (1UL << 22) +#define METAL_HPM_EVENTID_23 (1UL << 23) +#define METAL_HPM_EVENTID_24 (1UL << 24) +#define METAL_HPM_EVENTID_25 (1UL << 25) +#define METAL_HPM_EVENTID_26 (1UL << 26) +#define METAL_HPM_EVENTID_27 (1UL << 27) +#define METAL_HPM_EVENTID_28 (1UL << 28) +#define METAL_HPM_EVENTID_29 (1UL << 29) +#define METAL_HPM_EVENTID_30 (1UL << 30) +#define METAL_HPM_EVENTID_31 (1UL << 31) + +/*! @brief Macros for valid Event Class */ +#define METAL_HPM_EVENTCLASS_0 (0UL) +#define METAL_HPM_EVENTCLASS_1 (1UL) +#define METAL_HPM_EVENTCLASS_2 (2UL) +#define METAL_HPM_EVENTCLASS_3 (3UL) +#define METAL_HPM_EVENTCLASS_4 (4UL) +#define METAL_HPM_EVENTCLASS_5 (5UL) +#define METAL_HPM_EVENTCLASS_6 (6UL) +#define METAL_HPM_EVENTCLASS_7 (7UL) +#define METAL_HPM_EVENTCLASS_8 (8UL) + +/*! @brief Enums for available HPM counters */ +typedef enum { + METAL_HPM_CYCLE = 0, + METAL_HPM_TIME = 1, + METAL_HPM_INSTRET = 2, + METAL_HPM_COUNTER_3 = 3, + METAL_HPM_COUNTER_4 = 4, + METAL_HPM_COUNTER_5 = 5, + METAL_HPM_COUNTER_6 = 6, + METAL_HPM_COUNTER_7 = 7, + METAL_HPM_COUNTER_8 = 8, + METAL_HPM_COUNTER_9 = 9, + METAL_HPM_COUNTER_10 = 10, + METAL_HPM_COUNTER_11 = 11, + METAL_HPM_COUNTER_12 = 12, + METAL_HPM_COUNTER_13 = 13, + METAL_HPM_COUNTER_14 = 14, + METAL_HPM_COUNTER_15 = 15, + METAL_HPM_COUNTER_16 = 16, + METAL_HPM_COUNTER_17 = 17, + METAL_HPM_COUNTER_18 = 18, + METAL_HPM_COUNTER_19 = 19, + METAL_HPM_COUNTER_20 = 20, + METAL_HPM_COUNTER_21 = 21, + METAL_HPM_COUNTER_22 = 22, + METAL_HPM_COUNTER_23 = 23, + METAL_HPM_COUNTER_24 = 24, + METAL_HPM_COUNTER_25 = 25, + METAL_HPM_COUNTER_26 = 26, + METAL_HPM_COUNTER_27 = 27, + METAL_HPM_COUNTER_28 = 28, + METAL_HPM_COUNTER_29 = 29, + METAL_HPM_COUNTER_30 = 30, + METAL_HPM_COUNTER_31 = 31 +} metal_hpm_counter; + +/*! @brief Initialize hardware performance monitor counters. + * @param cpu The CPU device handle. + * @return 0 If no error.*/ +int metal_hpm_init(struct metal_cpu *cpu); + +/*! @brief Disables hardware performance monitor counters. + * Note - Disabled HPM counters may reduce power consumption. + * @param cpu The CPU device handle. + * @return 0 If no error.*/ +int metal_hpm_disable(struct metal_cpu *cpu); + +/*! @brief Set events which will cause the specified counter to increment. + * Counter will start incrementing from the moment events are set. + * @param cpu The CPU device handle. + * @param counter Hardware counter to be incremented by selected events. + * @param bitmask Bit-mask to select events for a particular counter, + * refer core reference manual for selection of events. + * Event bit mask is partitioned as follows: + * [XLEN-1:8] - Event selection mask [7:0] - Event class + * @return 0 If no error.*/ +int metal_hpm_set_event(struct metal_cpu *cpu, metal_hpm_counter counter, + unsigned int bitmask); + +/*! @brief Get events selection mask set for specified counter. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return Event selection bit mask. refer core reference manual for details.*/ +unsigned int metal_hpm_get_event(struct metal_cpu *cpu, + metal_hpm_counter counter); + +/*! @brief Clear event selector bits as per specified bit-mask. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return 0 If no error.*/ +int metal_hpm_clr_event(struct metal_cpu *cpu, metal_hpm_counter counter, + unsigned int bitmask); + +/*! @brief Enable counter access to next lower privilege mode. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return 0 If no error.*/ +int metal_hpm_enable_access(struct metal_cpu *cpu, metal_hpm_counter counter); + +/*! @brief Disable counter access to next lower privilege mode. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return 0 If no error.*/ +int metal_hpm_disable_access(struct metal_cpu *cpu, metal_hpm_counter counter); + +/*! @brief Reads current value of specified hardware counter. + * Note: 'mtime' register is memory mapped into CLINT block. + * Use CLINT APIs to access this register. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return Current value of hardware counter on success, 0 on failure.*/ +unsigned long long metal_hpm_read_counter(struct metal_cpu *cpu, + metal_hpm_counter counter); + +/*! @brief Clears off specified counter. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return 0 If no error.*/ +int metal_hpm_clear_counter(struct metal_cpu *cpu, metal_hpm_counter counter); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/i2c.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/i2c.h new file mode 100644 index 000000000..baf62e5d6 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/i2c.h @@ -0,0 +1,112 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__I2C_H +#define METAL__I2C_H + +/*! @brief Enums to enable/disable stop condition. */ +typedef enum { + METAL_I2C_STOP_DISABLE = 0, + METAL_I2C_STOP_ENABLE = 1 +} metal_i2c_stop_bit_t; + +/*! @brief Enums to set up I2C device modes. */ +typedef enum { METAL_I2C_SLAVE = 0, METAL_I2C_MASTER = 1 } metal_i2c_mode_t; + +struct metal_i2c; + +struct metal_i2c_vtable { + void (*init)(struct metal_i2c *i2c, unsigned int baud_rate, + metal_i2c_mode_t mode); + int (*write)(struct metal_i2c *i2c, unsigned int addr, unsigned int len, + unsigned char buf[], metal_i2c_stop_bit_t stop_bit); + int (*read)(struct metal_i2c *i2c, unsigned int addr, unsigned int len, + unsigned char buf[], metal_i2c_stop_bit_t stop_bit); + int (*transfer)(struct metal_i2c *i2c, unsigned int addr, + unsigned char txbuf[], unsigned int txlen, + unsigned char rxbuf[], unsigned int rxlen); + int (*get_baud_rate)(struct metal_i2c *i2c); + int (*set_baud_rate)(struct metal_i2c *i2c, unsigned int baud_rate); +}; + +/*! @brief A handle for a I2C device. */ +struct metal_i2c { + const struct metal_i2c_vtable *vtable; +}; + +/*! @brief Get a handle for a I2C device. + * @param device_num The index of the desired I2C device. + * @return A handle to the I2C device, or NULL if the device does not exist.*/ +struct metal_i2c *metal_i2c_get_device(unsigned int device_num); + +/*! @brief Initialize a I2C device with a certain baud rate. + * @param i2c The handle for the I2C device to initialize. + * @param baud_rate The baud rate for the I2C device to operate at. + * @param mode I2C operation mode. + */ +inline void metal_i2c_init(struct metal_i2c *i2c, unsigned int baud_rate, + metal_i2c_mode_t mode) { + i2c->vtable->init(i2c, baud_rate, mode); +} + +/*! @brief Perform a I2C write. + * @param i2c The handle for the I2C device to perform the write operation. + * @param addr The I2C slave address for the write operation. + * @param len The number of bytes to transfer. + * @param buf The buffer to send over the I2C bus. Must be len bytes long. + * @param stop_bit Enable / Disable STOP condition. + * @return 0 if the write succeeds. + */ +inline int metal_i2c_write(struct metal_i2c *i2c, unsigned int addr, + unsigned int len, unsigned char buf[], + metal_i2c_stop_bit_t stop_bit) { + return i2c->vtable->write(i2c, addr, len, buf, stop_bit); +} + +/*! @brief Perform a I2C read. + * @param i2c The handle for the I2C device to perform the read operation. + * @param addr The I2C slave address for the read operation. + * @param len The number of bytes to transfer. + * @param buf The buffer to store data from I2C bus. Must be len bytes long. + * @param stop_bit Enable / Disable STOP condition. + * @return 0 if the read succeeds. + */ +inline int metal_i2c_read(struct metal_i2c *i2c, unsigned int addr, + unsigned int len, unsigned char buf[], + metal_i2c_stop_bit_t stop_bit) { + return i2c->vtable->read(i2c, addr, len, buf, stop_bit); +} + +/*! @brief Performs back to back I2C write and read operations. + * @param i2c The handle for the I2C device to perform the transfer operation. + * @param addr The I2C slave address for the transfer operation. + * @param txbuf The data buffer to be transmitted over I2C bus. + * @param txlen The number of bytes to write over I2C. + * @param rxbuf The buffer to store data received over I2C bus. + * @param rxlen The number of bytes to read over I2C. + * @return 0 if the transfer succeeds. + */ +inline int metal_i2c_transfer(struct metal_i2c *i2c, unsigned int addr, + unsigned char txbuf[], unsigned int txlen, + unsigned char rxbuf[], unsigned int rxlen) { + return i2c->vtable->transfer(i2c, addr, txbuf, txlen, rxbuf, rxlen); +} + +/*! @brief Get the current baud rate of the I2C device. + * @param i2c The handle for the I2C device. + * @return The baud rate in Hz. + */ +inline int metal_i2c_get_baud_rate(struct metal_i2c *i2c) { + return i2c->vtable->get_baud_rate(i2c); +} + +/*! @brief Set the current baud rate of the I2C device. + * @param i2c The handle for the I2C device. + * @param baud_rate The desired baud rate of the I2C device. + * @return 0 If the baud rate is successfully changed. + */ +inline int metal_i2c_set_baud_rate(struct metal_i2c *i2c, int baud_rate) { + return i2c->vtable->set_baud_rate(i2c, baud_rate); +} + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/init.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/init.h new file mode 100644 index 000000000..0214d0add --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/init.h @@ -0,0 +1,130 @@ +/* Copyright 2019 SiFive Inc. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL_INIT +#define METAL_INIT + +/*! + * @file init.h + * API for Metal constructors and destructors + */ + +typedef void (*metal_constructor_t)(void); +typedef void (*metal_destructor_t)(void); + +#define METAL_INIT_HIGHEST_PRIORITY 0 +#define METAL_INIT_DEFAULT_PRIORITY 5000 +#define METAL_INIT_LOWEST_PRIORITY 9999 + +/*! @def METAL_CONSTRUCTOR + * @brief Define a Metal constructor + * + * Functions defined with METAL_CONSTRUCTOR will be added to the list of + * Metal constructors. By default, these functions are called before main by + * the metal_init() function. + */ +#define METAL_CONSTRUCTOR(function_name) \ + METAL_CONSTRUCTOR_PRIO(function_name, METAL_INIT_DEFAULT_PRIORITY) + +/*! @def METAL_CONSTRUCTOR_PRIO + * @brief Define a Metal constructor with a given priority + * + * The priority argument should be an integer between 0 and 9999, where 0 + * is the highest priority (runs first) and 9999 is the lowest priority + * (runs last). + * + * Functions defined with METAL_CONSTRUCTOR_PRIO will be added to the list of + * Metal constructors. By default, these functions are called before main by + * the metal_init() function. + */ +#define METAL_CONSTRUCTOR_PRIO(function_name, priority) \ + __METAL_CONSTRUCTOR_PRIO(function_name, priority) + +/* We use this wrapper for METAL_CONSTRUCTOR_PRIORITY so that macros passed + * as 'priority' are expanded before being stringified by the # operator. + * If we don't do this, then + * METAL_CONSTRUCTOR(my_fn_name, METAL_INIT_DEFAULT_PRIORITY) + * results in .metal.init_array.METAL_INIT_DEFAULT_PRIORITY instead of + * .metal.init_array.5000 */ +#define __METAL_CONSTRUCTOR_PRIO(function_name, priority) \ + __attribute__((section(".metal.ctors"))) void function_name(void); \ + __attribute__((section(".metal.init_array." #priority))) \ + metal_constructor_t _##function_name##_ptr = &function_name; \ + void function_name(void) + +/*! @def METAL_DESTRUCTOR + * @brief Define a Metal destructor + * + * Functions defined with METAL_DESTRUCTOR will be added to the list of + * Metal destructors. By default, these functions are called on exit by + * the metal_fini() function. + */ +#define METAL_DESTRUCTOR(function_name) \ + METAL_DESTRUCTOR_PRIO(function_name, METAL_INIT_DEFAULT_PRIORITY) + +/*! @def METAL_DESTRUCTOR_PRIO + * @brief Define a Metal destructor with a given priority + * + * The priority argument should be an integer between 0 and 9999, where 0 + * is the highest priority (runs first) and 9999 is the lowest priority + * (runs last). + * + * Functions defined with METAL_DESTRUCTOR_PRIO will be added to the list of + * Metal destructors. By default, these functions are called on exit by + * the metal_fini() function. + */ +#define METAL_DESTRUCTOR_PRIO(function_name, priority) \ + __METAL_DESTRUCTOR_PRIO(function_name, priority) +#define __METAL_DESTRUCTOR_PRIO(function_name, priority) \ + __attribute__((section(".metal.dtors"))) void function_name(void); \ + __attribute__((section(".metal.fini_array." #priority))) \ + metal_destructor_t _##function_name##_ptr = &function_name; \ + void function_name(void) + +/*! + * @brief Call all Metal constructors + * + * Devices supported by Metal may define Metal constructors to perform + * initialization before main. This function iterates over the constructors + * and calls them in turn. + * + * You can add your own constructors to the functions called by metal_init() + * by defining functions with the METAL_CONSTRUCTOR() macro. + * + * This function is called before main by default by metal_init_run(). + */ +void metal_init(void); + +/*! + * @brief Call all Metal destructors + * + * Devices supported by Metal may define Metal destructors to perform + * initialization on exit. This function iterates over the destructors + * and calls them in turn. + * + * You can add your own destructors to the functions called by metal_fini() + * by defining functions with the METAL_DESTRUCTOR() macro. + * + * This function is called on exit by default by metal_fini_run(). + */ +void metal_fini(void); + +/*! + * @brief Weak function to call metal_init() before main + * + * This function calls metal_init() before main by default. If you wish to + * replace or augment this call to the Metal constructors, you can redefine + * metal_init_run() + */ +void metal_init_run(void); + +/*! + * @brief Weak function to call metal_fini() before main + * + * This function calls metal_fini() at exit by default. If you wish to + * replace or augment this call to the Metal destructors, you can redefine + * metal_fini_run() + */ +void metal_fini_run(void); + +#endif /* METAL_INIT */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/interrupt.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/interrupt.h index 43f587aca..11df019de 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/interrupt.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/interrupt.h @@ -11,33 +11,104 @@ #include <stddef.h> /*! + * @brief Possible interrupt controllers + */ +typedef enum metal_interrupt_controller_ { + METAL_CPU_CONTROLLER = 0, + METAL_CLINT_CONTROLLER = 1, + METAL_CLIC_CONTROLLER = 2, + METAL_PLIC_CONTROLLER = 3 +} metal_intr_cntrl_type; + +/*! * @brief Possible mode of interrupts to operate */ typedef enum metal_vector_mode_ { METAL_DIRECT_MODE = 0, METAL_VECTOR_MODE = 1, - METAL_SELECTIVE_VECTOR_MODE = 2, - METAL_HARDWARE_VECTOR_MODE = 3 + METAL_SELECTIVE_NONVECTOR_MODE = 2, + METAL_SELECTIVE_VECTOR_MODE = 3, + METAL_HARDWARE_VECTOR_MODE = 4 } metal_vector_mode; /*! + * @brief Possible mode of privilege interrupts to operate + */ +typedef enum metal_intr_priv_mode_ { + METAL_INTR_PRIV_M_MODE = 0, + METAL_INTR_PRIV_MU_MODE = 1, + METAL_INTR_PRIV_MSU_MODE = 2 +} metal_intr_priv_mode; + +/*! + * @brief The bitmask of hart context + */ +typedef struct metal_affinity_ { + unsigned long bitmask; +} metal_affinity; + +#define for_each_metal_affinity(bit, metal_affinity) \ + for (bit = 0; metal_affinity.bitmask; bit++, metal_affinity.bitmask >>= 1) + +#define metal_affinity_set_val(metal_affinity, val) \ + metal_affinity.bitmask = val; + +#define metal_affinity_set_bit(metal_affinity, bit, val) \ + metal_affinity.bitmask |= ((val & 0x1) << bit); + +/*! * @brief Function signature for interrupt callback handlers */ -typedef void (*metal_interrupt_handler_t) (int, void *); +typedef void (*metal_interrupt_handler_t)(int, void *); +typedef void (*metal_interrupt_vector_handler_t)(void); struct metal_interrupt; struct metal_interrupt_vtable { void (*interrupt_init)(struct metal_interrupt *controller); + int (*interrupt_set_vector_mode)(struct metal_interrupt *controller, + metal_vector_mode mode); + metal_vector_mode (*interrupt_get_vector_mode)( + struct metal_interrupt *controller); + int (*interrupt_set_privilege)(struct metal_interrupt *controller, + metal_intr_priv_mode priv); + metal_intr_priv_mode (*interrupt_get_privilege)( + struct metal_interrupt *controller); + int (*interrupt_clear)(struct metal_interrupt *controller, int id); + int (*interrupt_set)(struct metal_interrupt *controller, int id); int (*interrupt_register)(struct metal_interrupt *controller, int id, - metal_interrupt_handler_t isr, void *priv_data); + metal_interrupt_handler_t isr, void *priv_data); + int (*interrupt_vector_register)(struct metal_interrupt *controller, int id, + metal_interrupt_vector_handler_t isr, + void *priv_data); int (*interrupt_enable)(struct metal_interrupt *controller, int id); int (*interrupt_disable)(struct metal_interrupt *controller, int id); - int (*interrupt_vector_enable)(struct metal_interrupt *controller, - int id, metal_vector_mode mode); + int (*interrupt_vector_enable)(struct metal_interrupt *controller, int id); int (*interrupt_vector_disable)(struct metal_interrupt *controller, int id); - int (*command_request)(struct metal_interrupt *controller, int cmd, void *data); - int (*mtimecmp_set)(struct metal_interrupt *controller, int hartid, unsigned long long time); + unsigned int (*interrupt_get_threshold)(struct metal_interrupt *controller); + int (*interrupt_set_threshold)(struct metal_interrupt *controller, + unsigned int threshold); + unsigned int (*interrupt_get_priority)(struct metal_interrupt *controller, + int id); + int (*interrupt_set_priority)(struct metal_interrupt *controller, int id, + unsigned int priority); + unsigned int (*interrupt_get_preemptive_level)( + struct metal_interrupt *controller, int id); + int (*interrupt_set_preemptive_level)(struct metal_interrupt *controller, + int id, unsigned int level); + int (*command_request)(struct metal_interrupt *controller, int cmd, + void *data); + int (*mtimecmp_set)(struct metal_interrupt *controller, int hartid, + unsigned long long time); + metal_affinity (*interrupt_affinity_enable)( + struct metal_interrupt *controller, metal_affinity bitmask, int id); + metal_affinity (*interrupt_affinity_disable)( + struct metal_interrupt *controller, metal_affinity bitmask, int id); + metal_affinity (*interrupt_affinity_set_threshold)( + struct metal_interrupt *controller, metal_affinity bitmask, + unsigned int threshold); + unsigned int (*interrupt_affinity_get_threshold)( + struct metal_interrupt *controller, int context_id); }; /*! @@ -56,11 +127,104 @@ struct metal_interrupt { * * @param controller The handle for the interrupt controller */ -inline void metal_interrupt_init(struct metal_interrupt *controller) -{ - return controller->vtable->interrupt_init(controller); +__inline__ void metal_interrupt_init(struct metal_interrupt *controller) { + controller->vtable->interrupt_init(controller); +} + +/*! + * @brief Get the handle for an given interrupt controller type + * @param cntrl The type ofinterrupt controller + * @param id The instance of the interrupt controller + * @return A handle to the interrupt controller (CLINT, CLIC, PLIC), or + * NULL if none is found for the requested label + */ +struct metal_interrupt * +metal_interrupt_get_controller(metal_intr_cntrl_type cntrl, int id); + +/*! + * @brief Configure vector mode for an interrupt controller + * + * Configure vector mode for an interrupt controller. + * This function must be called after initialization and before + * configuring individual interrupts, registering ISR. + * + * @param controller The handle for the interrupt controller + * @param mode The vector mode of the interrupt controller. + * @return 0 upon success + */ +__inline__ int +metal_interrupt_set_vector_mode(struct metal_interrupt *controller, + metal_vector_mode mode) { + return controller->vtable->interrupt_set_vector_mode(controller, mode); +} + +/*! + * @brief Get vector mode of a given an interrupt controller + * + * Configure vector mode for an interrupt controller. + * This function must be called after initialization and before + * configuring individual interrupts, registering ISR. + * + * @param controller The handle for the interrupt controller + * @param mode The vector mode of the interrupt controller. + * @return The interrupt vector mode + */ +__inline__ metal_vector_mode +metal_interrupt_get_vector_mode(struct metal_interrupt *controller) { + return controller->vtable->interrupt_get_vector_mode(controller); +} + +/*! + * @brief Configure privilege mode a of given interrupt controller + * + * Configure privilege mode for a given interrupt controller. + * This function must be called after initialization and before + * configuring individual interrupts, registering ISR. + * + * @param controller The handle for the interrupt controller + * @param privilege The privilege mode of the interrupt controller. + * @return 0 upon success + */ +__inline__ int metal_interrupt_set_privilege(struct metal_interrupt *controller, + metal_intr_priv_mode privilege) { + return controller->vtable->interrupt_set_privilege(controller, privilege); +} + +/*! + * @brief Get privilege mode a of given interrupt controller + * + * Get privilege mode for a given interrupt controller. + * This function must be called after initialization and before + * configuring individual interrupts, registering ISR. + * + * @param controller The handle for the interrupt controller + * @return The interrupt privilege mode + */ +__inline__ metal_intr_priv_mode +metal_interrupt_get_privilege(struct metal_interrupt *controller) { + return controller->vtable->interrupt_get_privilege(controller); +} + +/*! + * @brief clear an interrupt + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to trigger + * @return 0 upon success + */ +__inline__ int metal_interrupt_clear(struct metal_interrupt *controller, + int id) { + return controller->vtable->interrupt_clear(controller, id); } +/*! + * @brief Set an interrupt + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to trigger + * @return 0 upon success + */ +__inline__ int metal_interrupt_set(struct metal_interrupt *controller, int id) { + return controller->vtable->interrupt_set(controller, id); +} /*! * @brief Register an interrupt handler @@ -70,12 +234,27 @@ inline void metal_interrupt_init(struct metal_interrupt *controller) * @param priv_data Private data for the interrupt handler * @return 0 upon success */ -inline int metal_interrupt_register_handler(struct metal_interrupt *controller, - int id, - metal_interrupt_handler_t handler, - void *priv_data) -{ - return controller->vtable->interrupt_register(controller, id, handler, priv_data); +__inline__ int +metal_interrupt_register_handler(struct metal_interrupt *controller, int id, + metal_interrupt_handler_t handler, + void *priv_data) { + return controller->vtable->interrupt_register(controller, id, handler, + priv_data); +} + +/*! + * @brief Register an interrupt vector handler + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to register + * @param handler The interrupt vector handler callback + * @param priv_data Private data for the interrupt handler + * @return 0 upon success + */ +__inline__ int metal_interrupt_register_vector_handler( + struct metal_interrupt *controller, int id, + metal_interrupt_vector_handler_t handler, void *priv_data) { + return controller->vtable->interrupt_vector_register(controller, id, + handler, priv_data); } /*! @@ -84,8 +263,8 @@ inline int metal_interrupt_register_handler(struct metal_interrupt *controller, * @param id The interrupt ID to enable * @return 0 upon success */ -inline int metal_interrupt_enable(struct metal_interrupt *controller, int id) -{ +__inline__ int metal_interrupt_enable(struct metal_interrupt *controller, + int id) { return controller->vtable->interrupt_enable(controller, id); } @@ -95,22 +274,100 @@ inline int metal_interrupt_enable(struct metal_interrupt *controller, int id) * @param id The interrupt ID to disable * @return 0 upon success */ -inline int metal_interrupt_disable(struct metal_interrupt *controller, int id) -{ +__inline__ int metal_interrupt_disable(struct metal_interrupt *controller, + int id) { return controller->vtable->interrupt_disable(controller, id); } /*! + * @brief Set interrupt threshold level + * @param controller The handle for the interrupt controller + * @param threshold The interrupt threshold level + * @return 0 upon success + */ +__inline__ int metal_interrupt_set_threshold(struct metal_interrupt *controller, + unsigned int level) { + return controller->vtable->interrupt_set_threshold(controller, level); +} + +/*! + * @brief Get an interrupt threshold level + * @param controller The handle for the interrupt controller + * @return The interrupt threshold level + */ +__inline__ unsigned int +metal_interrupt_get_threshold(struct metal_interrupt *controller) { + return controller->vtable->interrupt_get_threshold(controller); +} + +/*! + * @brief Set an interrupt priority level + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to enable + * @param priority The interrupt priority level + * @return 0 upon success + */ +__inline__ int metal_interrupt_set_priority(struct metal_interrupt *controller, + int id, unsigned int priority) { + return controller->vtable->interrupt_set_priority(controller, id, priority); +} + +/*! + * @brief Get an interrupt priority level + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to enable + * @return The interrupt priority level + */ +__inline__ unsigned int +metal_interrupt_get_priority(struct metal_interrupt *controller, int id) { + return controller->vtable->interrupt_get_priority(controller, id); +} + +/*! + * @brief Set preemptive level and priority for a given interrupt ID + * + * Set the preemptive level and priority for a given interrupt ID. + * + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to enable + * @param level The interrupt level and priority are encoded together + * @return 0 upon success + */ +__inline__ int +metal_interrupt_set_preemptive_level(struct metal_interrupt *controller, int id, + unsigned int level) { + if (controller->vtable->interrupt_set_preemptive_level) + return controller->vtable->interrupt_set_preemptive_level(controller, + id, level); + else + return 0; +} + +/*! + * @brief Get an interrupt preemptive level + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to enable + * @return The interrupt level + */ +__inline__ unsigned int +metal_interrupt_get_preemptive_level(struct metal_interrupt *controller, + int id) { + if (controller->vtable->interrupt_get_preemptive_level) + return controller->vtable->interrupt_get_preemptive_level(controller, + id); + else + return 0; +} + +/*! * @brief Enable an interrupt vector * @param controller The handle for the interrupt controller * @param id The interrupt ID to enable - * @param mode The interrupt mode type to enable * @return 0 upon success */ -inline int metal_interrupt_vector_enable(struct metal_interrupt *controller, - int id, metal_vector_mode mode) -{ - return controller->vtable->interrupt_vector_enable(controller, id, mode); +__inline__ int metal_interrupt_vector_enable(struct metal_interrupt *controller, + int id) { + return controller->vtable->interrupt_vector_enable(controller, id); } /*! @@ -119,16 +376,215 @@ inline int metal_interrupt_vector_enable(struct metal_interrupt *controller, * @param id The interrupt ID to disable * @return 0 upon success */ -inline int metal_interrupt_vector_disable(struct metal_interrupt *controller, int id) -{ +__inline__ int +metal_interrupt_vector_disable(struct metal_interrupt *controller, int id) { return controller->vtable->interrupt_vector_disable(controller, id); } -/* Utilities function to controll, manages devices via a given interrupt controller */ -inline int _metal_interrupt_command_request(struct metal_interrupt *controller, - int cmd, void *data) -{ +/*! + * @brief Default interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_interrupt_vector_handler(void); + +/*! + * @brief Metal Software interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) +metal_software_interrupt_vector_handler(void); + +/*! + * @brief Metal Timer interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) +metal_timer_interrupt_vector_handler(void); + +/*! + * @brief Metal External interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) +metal_external_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 0 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc0_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 1 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc1_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 2 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc2_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 3 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc3_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 4 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc4_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 5 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc5_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 6 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc6_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 7 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc7_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 8 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc8_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 9 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc9_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 10 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc10_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 11 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc11_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 12 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc12_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 13 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc13_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 14 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc14_interrupt_vector_handler(void); + +/*! + * @brief Metal Local 15 interrupt vector handler, that can be overriden by user + * @param None + * @return None + */ +void __attribute__((weak, interrupt)) metal_lc15_interrupt_vector_handler(void); + +/* Utilities function to controll, manages devices via a given interrupt + * controller */ +__inline__ int +_metal_interrupt_command_request(struct metal_interrupt *controller, int cmd, + void *data) { return controller->vtable->command_request(controller, cmd, data); } +/*! + * @brief Enable an interrupt for the hart contexts + * @param controller The handle for the interrupt controller + * @param bitmask The bit mask of hart contexts to enable + * @param id The interrupt ID to enable + * @return The result of each hart context. 0 upon success at relevant bit. + */ +__inline__ metal_affinity +metal_interrupt_affinity_enable(struct metal_interrupt *controller, + metal_affinity bitmask, int id) { + return controller->vtable->interrupt_affinity_enable(controller, bitmask, + id); +} + +/*! + * @brief Disable an interrupt for the hart contexts + * @param controller The handle for the interrupt controller + * @param bitmask The bit mask of hart contexts to disable + * @param id The interrupt ID to disable + * @return The result of each hart context. 0 upon success at relevant bit. + */ +__inline__ metal_affinity +metal_interrupt_affinity_disable(struct metal_interrupt *controller, + metal_affinity bitmask, int id) { + return controller->vtable->interrupt_affinity_disable(controller, bitmask, + id); +} + +/*! + * @brief Set interrupt threshold level for the hart contexts + * @param controller The handle for the interrupt controller + * @param bitmask The bit mask of hart contexts to set threshold + * @param threshold The interrupt threshold level + * @return The result of each hart context. 0 upon success at relevant bit. + */ +__inline__ metal_affinity +metal_interrupt_affinity_set_threshold(struct metal_interrupt *controller, + metal_affinity bitmask, + unsigned int level) { + return controller->vtable->interrupt_affinity_set_threshold(controller, + bitmask, level); +} + +/*! + * @brief Get an interrupt threshold level from the hart context + * @param controller The handle for the interrupt controller + * @param context_id The hart context ID to get threshold + * @return The interrupt threshold level + */ +__inline__ unsigned int +metal_interrupt_affinity_get_threshold(struct metal_interrupt *controller, + int context_id) { + return controller->vtable->interrupt_affinity_get_threshold(controller, + context_id); +} #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/io.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/io.h index 450054142..f1df85518 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/io.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/io.h @@ -5,18 +5,19 @@ #define METAL__IO_H /* This macro enforces that the compiler will not elide the given access. */ -#define __METAL_ACCESS_ONCE(x) (*(typeof(*x) volatile *)(x)) +#define __METAL_ACCESS_ONCE(x) (*(__typeof__(*x) volatile *)(x)) /* Allows users to specify arbitrary fences. */ -#define __METAL_IO_FENCE(pred, succ) __asm__ volatile ("fence " #pred "," #succ ::: "memory"); +#define __METAL_IO_FENCE(pred, succ) \ + __asm__ volatile("fence " #pred "," #succ ::: "memory"); /* Types that explicitly describe an address as being used for memory-mapped * IO. These should only be accessed via __METAL_ACCESS_ONCE. */ -typedef unsigned char __metal_io_u8; +typedef unsigned char __metal_io_u8; typedef unsigned short __metal_io_u16; -typedef unsigned int __metal_io_u32; +typedef unsigned int __metal_io_u32; #if __riscv_xlen >= 64 -typedef unsigned long __metal_io_u64; +typedef unsigned long __metal_io_u64; #endif #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/itim.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/itim.h index 1a2a05b8b..3decefff2 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/itim.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/itim.h @@ -9,13 +9,12 @@ * API for manipulating ITIM allocation */ - /*! @def METAL_PLACE_IN_ITIM * @brief Link a function into the ITIM * * Link a function into the ITIM (Instruction Tightly Integrated * Memory) if the ITIM is present on the target device. */ -#define METAL_PLACE_IN_ITIM __attribute__((section(".itim"))) +#define METAL_PLACE_IN_ITIM __attribute__((section(".itim"))) #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/led.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/led.h index a430b84c2..da2555fb8 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/led.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/led.h @@ -31,38 +31,47 @@ struct metal_led { * @param label The DeviceTree label for the desired LED * @return A handle to the LED, or NULL if none is found for the requested label */ -struct metal_led* metal_led_get(char *label); +struct metal_led *metal_led_get(char *label); /*! * @brief Get a handle for a channel of an RGB LED * @param label The DeviceTree label for the desired LED * @param color The color for the LED in the DeviceTree - * @return A handle to the LED, or NULL if none is found for the requested label and color + * @return A handle to the LED, or NULL if none is found for the requested label + * and color */ -struct metal_led* metal_led_get_rgb(char *label, char *color); +struct metal_led *metal_led_get_rgb(char *label, char *color); /*! * @brief Enable an LED * @param led The handle for the LED */ -inline void metal_led_enable(struct metal_led *led) { led->vtable->led_enable(led); } +__inline__ void metal_led_enable(struct metal_led *led) { + led->vtable->led_enable(led); +} /*! * @brief Turn an LED on * @param led The handle for the LED */ -inline void metal_led_on(struct metal_led *led) { led->vtable->led_on(led); } +__inline__ void metal_led_on(struct metal_led *led) { + led->vtable->led_on(led); +} /*! * @brief Turn an LED off * @param led The handle for the LED */ -inline void metal_led_off(struct metal_led *led) { led->vtable->led_off(led); } +__inline__ void metal_led_off(struct metal_led *led) { + led->vtable->led_off(led); +} /*! * @brief Toggle the on/off state of an LED * @param led The handle for the LED */ -inline void metal_led_toggle(struct metal_led *led) { led->vtable->led_toggle(led); } +__inline__ void metal_led_toggle(struct metal_led *led) { + led->vtable->led_toggle(led); +} #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lim.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lim.h new file mode 100644 index 000000000..1e573cad6 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lim.h @@ -0,0 +1,20 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__LIM_H +#define METAL__LIM_H + +/*! @file lim.h + * + * API for manipulating LIM allocation + */ + +/*! @def METAL_PLACE_IN_LIM + * @brief Link a function into the LIM + * + * Link a function into the LIM (Loosely Integrated + * Memory) if the LIM is present on the target device. + */ +#define METAL_PLACE_IN_LIM __attribute__((section(".lim"))) + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lock.h index d863aa96e..e591eaefa 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lock.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/lock.h @@ -4,8 +4,9 @@ #ifndef METAL__LOCK_H #define METAL__LOCK_H -#include <metal/memory.h> #include <metal/compiler.h> +#include <metal/machine.h> +#include <metal/memory.h> /*! * @file lock.h @@ -15,6 +16,9 @@ /* TODO: How can we make the exception code platform-independant? */ #define _METAL_STORE_AMO_ACCESS_FAULT 7 +#define METAL_LOCK_BACKOFF_CYCLES 32 +#define METAL_LOCK_BACKOFF_EXPONENT 2 + /*! * @def METAL_LOCK_DECLARE * @brief Declare a lock @@ -22,35 +26,36 @@ * Locks must be declared with METAL_LOCK_DECLARE to ensure that the lock * is linked into a memory region which supports atomic memory operations. */ -#define METAL_LOCK_DECLARE(name) \ - __attribute__((section(".data.locks"))) \ - struct metal_lock name +#define METAL_LOCK_DECLARE(name) \ + __attribute__((section(".data.locks"))) struct metal_lock name /*! * @brief A handle for a lock */ struct metal_lock { - int _state; + int _state; }; /*! * @brief Initialize a lock * @param lock The handle for a lock - * @return 0 if the lock is successfully initialized. A non-zero code indicates failure. + * @return 0 if the lock is successfully initialized. A non-zero code indicates + * failure. * * If the lock cannot be initialized, attempts to take or give the lock * will result in a Store/AMO access fault. */ -inline int metal_lock_init(struct metal_lock *lock) { +__inline__ int metal_lock_init(struct metal_lock *lock) { #ifdef __riscv_atomic /* Get a handle for the memory which holds the lock state */ - struct metal_memory *lock_mem = metal_get_memory_from_address((uintptr_t) &(lock->_state)); - if(!lock_mem) { + struct metal_memory *lock_mem = + metal_get_memory_from_address((uintptr_t) & (lock->_state)); + if (!lock_mem) { return 1; } /* If the memory doesn't support atomics, report an error */ - if(!metal_memory_supports_atomics(lock_mem)) { + if (!metal_memory_supports_atomics(lock_mem)) { return 2; } @@ -70,23 +75,37 @@ inline int metal_lock_init(struct metal_lock *lock) { * If the lock initialization failed, attempts to take a lock will result in * a Store/AMO access fault. */ -inline int metal_lock_take(struct metal_lock *lock) { +__inline__ int metal_lock_take(struct metal_lock *lock) { #ifdef __riscv_atomic int old = 1; int new = 1; - while(old != 0) { + int backoff = 1; + const int max_backoff = METAL_LOCK_BACKOFF_CYCLES * METAL_MAX_CORES; + + while (1) { __asm__ volatile("amoswap.w.aq %[old], %[new], (%[state])" - : [old] "=r" (old) - : [new] "r" (new), [state] "r" (&(lock->_state)) + : [old] "=r"(old) + : [new] "r"(new), [state] "r"(&(lock->_state)) : "memory"); + + if (old == 0) { + break; + } + + for (int i = 0; i < backoff; i++) { + __asm__ volatile(""); + } + + if (backoff < max_backoff) { + backoff *= METAL_LOCK_BACKOFF_EXPONENT; + } } return 0; #else /* Store the memory address in mtval like a normal store/amo access fault */ - __asm__ ("csrw mtval, %[state]" - :: [state] "r" (&(lock->_state))); + __asm__("csrw mtval, %[state]" ::[state] "r"(&(lock->_state))); /* Trigger a Store/AMO access fault */ _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); @@ -104,17 +123,16 @@ inline int metal_lock_take(struct metal_lock *lock) { * If the lock initialization failed, attempts to give a lock will result in * a Store/AMO access fault. */ -inline int metal_lock_give(struct metal_lock *lock) { +__inline__ int metal_lock_give(struct metal_lock *lock) { #ifdef __riscv_atomic - __asm__ volatile("amoswap.w.rl x0, x0, (%[state])" - :: [state] "r" (&(lock->_state)) - : "memory"); + __asm__ volatile( + "amoswap.w.rl x0, x0, (%[state])" ::[state] "r"(&(lock->_state)) + : "memory"); return 0; #else /* Store the memory address in mtval like a normal store/amo access fault */ - __asm__ ("csrw mtval, %[state]" - :: [state] "r" (&(lock->_state))); + __asm__("csrw mtval, %[state]" ::[state] "r"(&(lock->_state))); /* Trigger a Store/AMO access fault */ _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine.h index f76dbd632..74c361b4b 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine.h @@ -9,15 +9,15 @@ #ifdef __METAL_MACHINE_MACROS -#ifndef MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H -#define MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H +#ifndef MACROS_IF_METAL_H +#define MACROS_IF_METAL_H #define __METAL_CLINT_NUM_PARENTS 2 #ifndef __METAL_CLINT_NUM_PARENTS #define __METAL_CLINT_NUM_PARENTS 0 #endif -#define __METAL_PLIC_SUBINTERRUPTS 27 +#define __METAL_PLIC_SUBINTERRUPTS 53 #define __METAL_PLIC_NUM_PARENTS 1 @@ -31,12 +31,12 @@ #define __METAL_CLIC_SUBINTERRUPTS 0 #endif -#endif /* MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H*/ +#endif /* MACROS_IF_METAL_H*/ #else /* ! __METAL_MACHINE_MACROS */ -#ifndef MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H -#define MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H +#ifndef MACROS_ELSE_METAL_H +#define MACROS_ELSE_METAL_H #define __METAL_CLINT_2000000_INTERRUPTS 2 @@ -46,7 +46,7 @@ #define __METAL_INTERRUPT_CONTROLLER_C000000_INTERRUPTS 1 -#define __METAL_PLIC_SUBINTERRUPTS 27 +#define __METAL_PLIC_SUBINTERRUPTS 53 #define METAL_MAX_PLIC_INTERRUPTS 1 @@ -55,20 +55,36 @@ #define __METAL_CLIC_SUBINTERRUPTS 0 #define METAL_MAX_CLIC_INTERRUPTS 0 -#define __METAL_LOCAL_EXTERNAL_INTERRUPTS_0_INTERRUPTS 16 - -#define METAL_MAX_LOCAL_EXT_INTERRUPTS 16 +#define METAL_MAX_LOCAL_EXT_INTERRUPTS 0 #define METAL_MAX_GLOBAL_EXT_INTERRUPTS 0 -#define __METAL_GPIO_10012000_INTERRUPTS 16 +#define __METAL_GPIO_10012000_INTERRUPTS 32 + +#define METAL_MAX_GPIO_INTERRUPTS 32 + +#define __METAL_I2C_10016000_INTERRUPTS 1 + +#define METAL_MAX_I2C0_INTERRUPTS 1 + +#define __METAL_PWM_10015000_INTERRUPTS 4 -#define METAL_MAX_GPIO_INTERRUPTS 16 +#define __METAL_PWM_10025000_INTERRUPTS 4 + +#define __METAL_PWM_10035000_INTERRUPTS 4 + +#define METAL_MAX_PWM0_INTERRUPTS 4 + +#define METAL_MAX_PWM0_NCMP 4 #define __METAL_SERIAL_10013000_INTERRUPTS 1 +#define __METAL_SERIAL_10023000_INTERRUPTS 1 + #define METAL_MAX_UART_INTERRUPTS 1 +#define METAL_MAX_SIMUART_INTERRUPTS 0 + #include <metal/drivers/fixed-clock.h> #include <metal/memory.h> @@ -76,79 +92,119 @@ #include <metal/drivers/riscv_cpu.h> #include <metal/drivers/riscv_plic0.h> #include <metal/pmp.h> -#include <metal/drivers/sifive_local-external-interrupts0.h> #include <metal/drivers/sifive_gpio0.h> #include <metal/drivers/sifive_gpio-leds.h> +#include <metal/drivers/sifive_i2c0.h> +#include <metal/drivers/sifive_pwm0.h> +#include <metal/drivers/sifive_rtc0.h> #include <metal/drivers/sifive_spi0.h> #include <metal/drivers/sifive_uart0.h> +#include <metal/drivers/sifive_wdog0.h> #include <metal/drivers/sifive_fe310-g000_hfrosc.h> #include <metal/drivers/sifive_fe310-g000_hfxosc.h> +#include <metal/drivers/sifive_fe310-g000_lfrosc.h> #include <metal/drivers/sifive_fe310-g000_pll.h> #include <metal/drivers/sifive_fe310-g000_prci.h> /* From clock@0 */ -struct __metal_driver_fixed_clock __metal_dt_clock_0; +extern struct __metal_driver_fixed_clock __metal_dt_clock_0; /* From clock@2 */ -struct __metal_driver_fixed_clock __metal_dt_clock_2; +extern struct __metal_driver_fixed_clock __metal_dt_clock_2; /* From clock@5 */ -struct __metal_driver_fixed_clock __metal_dt_clock_5; +extern struct __metal_driver_fixed_clock __metal_dt_clock_5; + +/* From clock@6 */ +extern struct __metal_driver_fixed_clock __metal_dt_clock_6; + +extern struct metal_memory __metal_dt_mem_dtim_80000000; + +extern struct metal_memory __metal_dt_mem_itim_8000000; -struct metal_memory __metal_dt_mem_dtim_80000000; +extern struct metal_memory __metal_dt_mem_spi_10014000; -struct metal_memory __metal_dt_mem_spi_10014000; +extern struct metal_memory __metal_dt_mem_spi_10024000; + +extern struct metal_memory __metal_dt_mem_spi_10034000; /* From clint@2000000 */ -struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000; +extern struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000; /* From cpu@0 */ -struct __metal_driver_cpu __metal_dt_cpu_0; +extern struct __metal_driver_cpu __metal_dt_cpu_0; -struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller; +extern struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller; /* From interrupt_controller@c000000 */ -struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000; - -struct metal_pmp __metal_dt_pmp; +extern struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000; -/* From local_external_interrupts_0 */ -struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_0; +extern struct metal_pmp __metal_dt_pmp; /* From gpio@10012000 */ -struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000; +extern struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000; + +/* From led@0 */ +extern struct __metal_driver_sifive_gpio_led __metal_dt_led_0; + +/* From led@1 */ +extern struct __metal_driver_sifive_gpio_led __metal_dt_led_1; -/* From led@0red */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0red; +/* From led@2 */ +extern struct __metal_driver_sifive_gpio_led __metal_dt_led_2; -/* From led@0green */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0green; +/* From i2c@10016000 */ +extern struct __metal_driver_sifive_i2c0 __metal_dt_i2c_10016000; -/* From led@0blue */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue; +/* From pwm@10015000 */ +extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10015000; + +/* From pwm@10025000 */ +extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10025000; + +/* From pwm@10035000 */ +extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10035000; + +/* From aon@10000000 */ +extern struct __metal_driver_sifive_rtc0 __metal_dt_rtc_10000000; /* From spi@10014000 */ -struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000; +extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000; + +/* From spi@10024000 */ +extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10024000; + +/* From spi@10034000 */ +extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10034000; /* From serial@10013000 */ -struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000; +extern struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000; + +/* From serial@10023000 */ +extern struct __metal_driver_sifive_uart0 __metal_dt_serial_10023000; + +/* From aon@10000000 */ +extern struct __metal_driver_sifive_wdog0 __metal_dt_aon_10000000; /* From clock@3 */ -struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3; +extern struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3; /* From clock@1 */ -struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1; +extern struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1; + +/* From clock@7 */ +extern struct __metal_driver_sifive_fe310_g000_lfrosc __metal_dt_clock_7; /* From clock@4 */ -struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4; +extern struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4; /* From prci@10008000 */ -struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000; +extern struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000; /* --------------------- fixed_clock ------------ */ -static inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock) +static __inline__ unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock) { if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_0) { return METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY; @@ -159,6 +215,9 @@ static inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_c else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_5) { return METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY; } + else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_6) { + return METAL_FIXED_CLOCK_6_CLOCK_FREQUENCY; + } else { return 0; } @@ -170,7 +229,7 @@ static inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_c /* --------------------- sifive_clint0 ------------ */ -static inline unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller) +static __inline__ unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller) { if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) { return METAL_RISCV_CLINT0_2000000_BASE_ADDRESS; @@ -180,7 +239,7 @@ static inline unsigned long __metal_driver_sifive_clint0_control_base(struct met } } -static inline unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller) +static __inline__ unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller) { if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) { return METAL_RISCV_CLINT0_2000000_SIZE; @@ -190,7 +249,7 @@ static inline unsigned long __metal_driver_sifive_clint0_control_size(struct met } } -static inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller) +static __inline__ int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller) { if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) { return METAL_MAX_CLINT_INTERRUPTS; @@ -200,7 +259,7 @@ static inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_inter } } -static inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx) +static __inline__ struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx) { if (idx == 0) { return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller; @@ -213,7 +272,7 @@ static inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_pa } } -static inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx) +static __inline__ int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx) { if (idx == 0) { return 3; @@ -229,7 +288,7 @@ static inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_inte /* --------------------- cpu ------------ */ -static inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu) +static __inline__ int __metal_driver_cpu_hartid(struct metal_cpu *cpu) { if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { return 0; @@ -239,17 +298,17 @@ static inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu) } } -static inline int __metal_driver_cpu_timebase(struct metal_cpu *cpu) +static __inline__ int __metal_driver_cpu_timebase(struct metal_cpu *cpu) { if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { - return 1000000; + return 16000000; } else { return 0; } } -static inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu) +static __inline__ struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu) { if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { return &__metal_dt_cpu_0_interrupt_controller.controller; @@ -259,7 +318,7 @@ static inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(s } } -static inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu) +static __inline__ int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu) { if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { return 8; @@ -269,10 +328,20 @@ static inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu) } } +static __inline__ struct metal_buserror * __metal_driver_cpu_buserror(struct metal_cpu *cpu) +{ + if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { + return NULL; + } + else { + return NULL; + } +} + /* --------------------- sifive_plic0 ------------ */ -static inline unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller) +static __inline__ unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller) { if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) { return METAL_RISCV_PLIC0_C000000_BASE_ADDRESS; @@ -282,7 +351,7 @@ static inline unsigned long __metal_driver_sifive_plic0_control_base(struct meta } } -static inline unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller) +static __inline__ unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller) { if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) { return METAL_RISCV_PLIC0_C000000_SIZE; @@ -292,7 +361,7 @@ static inline unsigned long __metal_driver_sifive_plic0_control_size(struct meta } } -static inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller) +static __inline__ int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller) { if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) { return METAL_RISCV_PLIC0_C000000_RISCV_NDEV; @@ -302,7 +371,7 @@ static inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interr } } -static inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller) +static __inline__ int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller) { if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) { return METAL_RISCV_PLIC0_C000000_RISCV_MAX_PRIORITY; @@ -312,108 +381,189 @@ static inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrup } } -static inline struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx) +static __inline__ struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx) { if (idx == 0) { return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller; } - else if (idx == 0) { - return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller; - } else { return NULL; } } -static inline int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx) +static __inline__ int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx) { if (idx == 0) { return 11; } - else if (idx == 0) { - return 11; - } else { return 0; } } +static __inline__ int __metal_driver_sifive_plic0_context_ids(int hartid) +{ + if (hartid == 0) { + return 0; + } + else { + return -1; + } +} + + + +/* --------------------- sifive_buserror0 ------------ */ /* --------------------- sifive_clic0 ------------ */ /* --------------------- sifive_local_external_interrupts0 ------------ */ -static inline struct metal_interrupt * __metal_driver_sifive_local_external_interrupts0_interrupt_parent(struct metal_interrupt *controller) + + +/* --------------------- sifive_global_external_interrupts0 ------------ */ + + +/* --------------------- sifive_gpio0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio) { - if ((uintptr_t)controller == (uintptr_t)&__metal_dt_local_external_interrupts_0) { - return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller; + if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { + return METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS; } else { - return NULL; + return 0; } } -static inline int __metal_driver_sifive_local_external_interrupts0_num_interrupts(struct metal_interrupt *controller) +static __inline__ unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio) { - if ((uintptr_t)controller == (uintptr_t)&__metal_dt_local_external_interrupts_0) { - return METAL_MAX_LOCAL_EXT_INTERRUPTS; + if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { + return METAL_SIFIVE_GPIO0_10012000_SIZE; } else { return 0; } } -static inline int __metal_driver_sifive_local_external_interrupts0_interrupt_lines(struct metal_interrupt *controller, int idx) +static __inline__ int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio) { - if (idx == 0) { + if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { + return METAL_MAX_GPIO_INTERRUPTS; + } + else { + return 0; + } +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio) +{ + if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx) +{ + if (((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 0)) { + return 8; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 1))) { + return 9; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 2))) { + return 10; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) { + return 11; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) { + return 12; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) { + return 13; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) { + return 14; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) { + return 15; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) { return 16; } - else if (idx == 1) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) { return 17; } - else if (idx == 2) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) { return 18; } - else if (idx == 3) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) { return 19; } - else if (idx == 4) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) { return 20; } - else if (idx == 5) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) { return 21; } - else if (idx == 6) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) { return 22; } - else if (idx == 7) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) { return 23; } - else if (idx == 8) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 16))) { return 24; } - else if (idx == 9) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 17))) { return 25; } - else if (idx == 10) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 18))) { return 26; } - else if (idx == 11) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 19))) { return 27; } - else if (idx == 12) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 20))) { return 28; } - else if (idx == 13) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 21))) { return 29; } - else if (idx == 14) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 22))) { return 30; } - else if (idx == 15) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 23))) { return 31; } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 24))) { + return 32; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 25))) { + return 33; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 26))) { + return 34; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 27))) { + return 35; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 28))) { + return 36; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 29))) { + return 27; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 30))) { + return 28; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 31))) { + return 29; + } else { return 0; } @@ -421,203 +571,487 @@ static inline int __metal_driver_sifive_local_external_interrupts0_interrupt_lin -/* --------------------- sifive_global_external_interrupts0 ------------ */ +/* --------------------- sifive_gpio_button ------------ */ -/* --------------------- sifive_gpio0 ------------ */ -static inline unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio) +/* --------------------- sifive_gpio_led ------------ */ +static __inline__ struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led) { - if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { - return METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS; + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) { + return (struct metal_gpio *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) { + return (struct metal_gpio *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) { + return (struct metal_gpio *)&__metal_dt_gpio_10012000; + } + else { + return NULL; + } +} + +static __inline__ int __metal_driver_sifive_gpio_led_pin(struct metal_led *led) +{ + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) { + return 22; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) { + return 19; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) { + return 21; } else { return 0; } } -static inline unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio) +static __inline__ char * __metal_driver_sifive_gpio_led_label(struct metal_led *led) { - if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { - return METAL_SIFIVE_GPIO0_10012000_SIZE; + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) { + return "LD0red"; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) { + return "LD0green"; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) { + return "LD0blue"; + } + else { + return ""; + } +} + + + +/* --------------------- sifive_gpio_switch ------------ */ + + +/* --------------------- sifive_i2c0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_i2c0_control_base(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return METAL_SIFIVE_I2C0_10016000_BASE_ADDRESS; } else { return 0; } } -static inline int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio) +static __inline__ unsigned long __metal_driver_sifive_i2c0_control_size(struct metal_i2c *i2c) { - if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { - return METAL_MAX_GPIO_INTERRUPTS; + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return METAL_SIFIVE_I2C0_10016000_SIZE; } else { return 0; } } -static inline struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio) +static __inline__ struct metal_clock * __metal_driver_sifive_i2c0_clock(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return NULL; + } +} + +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_i2c0_pinmux(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return NULL; + } +} + +static __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_output_selector(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 0; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_source_selector(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 12288; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_i2c0_num_interrupts(struct metal_i2c *i2c) +{ + return METAL_MAX_I2C0_INTERRUPTS; +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_i2c0_interrupt_parent(struct metal_i2c *i2c) { - if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; +} + +static __inline__ int __metal_driver_sifive_i2c0_interrupt_line(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 52; } else { return 0; } } -static inline int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx) + + +/* --------------------- sifive_pwm0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_pwm0_control_base(struct metal_pwm *pwm) { - if (((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 0)) { - return 7; + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return METAL_SIFIVE_PWM0_10015000_BASE_ADDRESS; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 1))) { - return 8; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return METAL_SIFIVE_PWM0_10025000_BASE_ADDRESS; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 2))) { - return 9; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return METAL_SIFIVE_PWM0_10035000_BASE_ADDRESS; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) { - return 10; + else { + return 0; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) { - return 11; +} + +static __inline__ unsigned long __metal_driver_sifive_pwm0_control_size(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return METAL_SIFIVE_PWM0_10015000_SIZE; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) { - return 12; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return METAL_SIFIVE_PWM0_10025000_SIZE; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) { - return 13; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return METAL_SIFIVE_PWM0_10035000_SIZE; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) { - return 14; + else { + return 0; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) { - return 15; +} + +static __inline__ struct metal_clock * __metal_driver_sifive_pwm0_clock(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) { - return 16; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) { - return 17; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) { - return 18; + else { + return NULL; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) { - return 19; +} + +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_pwm0_pinmux(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) { - return 20; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) { - return 21; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) { - return 22; + else { + return NULL; + } +} + +static __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_output_selector(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 15; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 7864320; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 15360; } else { return 0; } } +static __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_source_selector(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 15; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 7864320; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 15360; + } + else { + return 0; + } +} +static __inline__ int __metal_driver_sifive_pwm0_num_interrupts(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return __METAL_PWM_10015000_INTERRUPTS; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return __METAL_PWM_10025000_INTERRUPTS; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return __METAL_PWM_10035000_INTERRUPTS; + } + else { + return 0; + } +} -/* --------------------- sifive_gpio_button ------------ */ +static __inline__ struct metal_interrupt * __metal_driver_sifive_pwm0_interrupt_parent(struct metal_pwm *pwm) +{ + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; +} +static __inline__ int __metal_driver_sifive_pwm0_interrupt_lines(struct metal_pwm *pwm, int idx) +{ + if (((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 0)) { + return 40; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 1))) { + return 41; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 2))) { + return 42; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 3))) { + return 43; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 0))) { + return 44; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 1))) { + return 45; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 2))) { + return 46; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 3))) { + return 47; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 0))) { + return 48; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 1))) { + return 49; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 2))) { + return 50; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 3))) { + return 51; + } + else { + return 0; + } +} -/* --------------------- sifive_gpio_led ------------ */ -static inline struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led) +static __inline__ int __metal_driver_sifive_pwm0_compare_width(struct metal_pwm *pwm) { - if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { - return (struct metal_gpio *)&__metal_dt_gpio_10012000; + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 8; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { - return (struct metal_gpio *)&__metal_dt_gpio_10012000; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 16; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { - return (struct metal_gpio *)&__metal_dt_gpio_10012000; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 16; } else { - return NULL; + return 0; } } -static inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led) +static __inline__ int __metal_driver_sifive_pwm0_comparator_count(struct metal_pwm *pwm) { - if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { - return 22; + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 4; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { - return 19; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 4; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { - return 21; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 4; } else { return 0; } } -static inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led) + + +/* --------------------- sifive_rtc0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_rtc0_control_base(const struct metal_rtc *const rtc) { - if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { - return "LD0red"; + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return METAL_SIFIVE_AON0_10000000_BASE_ADDRESS; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { - return "LD0green"; + else { + return 0; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { - return "LD0blue"; +} + +static __inline__ unsigned long __metal_driver_sifive_rtc0_control_size(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return METAL_SIFIVE_AON0_10000000_SIZE; } else { - return ""; + return 0; } } +static __inline__ struct metal_interrupt * __metal_driver_sifive_rtc0_interrupt_parent(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } + else { + return 0; + } +} +static __inline__ int __metal_driver_sifive_rtc0_interrupt_line(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return 2; + } + else { + return 0; + } +} -/* --------------------- sifive_gpio_switch ------------ */ +static __inline__ struct metal_clock * __metal_driver_sifive_rtc0_clock(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return (struct metal_clock *)&__metal_dt_clock_7.clock; + } + else { + return 0; + } +} -/* --------------------- sifive_spi0 ------------ */ -static inline unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi) +static __inline__ unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi) { if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { return METAL_SIFIVE_SPI0_10014000_BASE_ADDRESS; } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return METAL_SIFIVE_SPI0_10024000_BASE_ADDRESS; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return METAL_SIFIVE_SPI0_10034000_BASE_ADDRESS; + } else { return 0; } } -static inline unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi) +static __inline__ unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi) { if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { return METAL_SIFIVE_SPI0_10014000_SIZE; } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return METAL_SIFIVE_SPI0_10024000_SIZE; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return METAL_SIFIVE_SPI0_10034000_SIZE; + } else { return 0; } } -static inline struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi) +static __inline__ struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi) { + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return 0; + } } -static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi) +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi) { + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return 0; + } } -static inline unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi) +static __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi) { - return 60; + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return 0; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return 0; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return 0; + } + else { + return 0; + } } -static inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi) +static __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi) { + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return 0; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { return 60; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return 4227858432; + } + else { + return 0; + } } @@ -625,91 +1059,201 @@ static inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(st /* --------------------- sifive_test0 ------------ */ +/* --------------------- sifive_trace ------------ */ + /* --------------------- sifive_uart0 ------------ */ -static inline unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart) +static __inline__ unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart) { if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return METAL_SIFIVE_UART0_10013000_BASE_ADDRESS; } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return METAL_SIFIVE_UART0_10023000_BASE_ADDRESS; + } else { return 0; } } -static inline unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart) +static __inline__ unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart) { if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return METAL_SIFIVE_UART0_10013000_SIZE; } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return METAL_SIFIVE_UART0_10023000_SIZE; + } else { return 0; } } -static inline int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart) +static __inline__ int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart) { if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return METAL_MAX_UART_INTERRUPTS; } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return METAL_MAX_UART_INTERRUPTS; + } else { return 0; } } -static inline struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart) +static __inline__ struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart) { if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } else { - return NULL; + return 0; } } -static inline int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart) +static __inline__ int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart) { - return 5; + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return 3; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return 4; + } + else { + return 0; + } } -static inline struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart) +static __inline__ struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart) { + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return 0; + } } -static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart) +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart) { + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return 0; + } } -static inline unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart) +static __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart) { - return 196608; + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return 0; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return 0; + } + else { + return 0; + } } -static inline unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart) +static __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart) { + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return 196608; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return 8650752; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_simuart0 ------------ */ + + +/* --------------------- sifive_wdog0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_wdog0_control_base(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return METAL_SIFIVE_AON0_10000000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_wdog0_control_size(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return METAL_SIFIVE_AON0_10000000_SIZE; + } + else { + return 0; + } +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_wdog0_interrupt_parent(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_wdog0_interrupt_line(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return 1; + } + else { + return 0; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_wdog0_clock(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return (struct metal_clock *)&__metal_dt_clock_7.clock; + } + else { + return 0; + } } /* --------------------- sifive_fe310_g000_hfrosc ------------ */ -static inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock) +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock) { return (struct metal_clock *)&__metal_dt_clock_2.clock; } -static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock) +static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock) { return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000; } -static inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock) +static __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock) { return &__metal_driver_vtable_sifive_fe310_g000_prci; } -static inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock) +static __inline__ long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock) { return METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG; } @@ -717,55 +1261,98 @@ static inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const s /* --------------------- sifive_fe310_g000_hfxosc ------------ */ -static inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock) +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock) { return (struct metal_clock *)&__metal_dt_clock_0.clock; } -static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock) +static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock) { return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000; } -static inline long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock) +static __inline__ long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock) { return METAL_SIFIVE_FE310_G000_PRCI_HFXOSCCFG; } +/* --------------------- sifive_fe310_g000_lfrosc ------------ */ +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return (struct metal_clock *)&__metal_dt_clock_5.clock; + } + else { + return NULL; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return (struct metal_clock *)&__metal_dt_clock_6.clock; + } + else { + return NULL; + } +} + +static __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_config_reg(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return 112; + } + else { + return 0; + } +} + +static __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return 124; + } + else { + return 0; + } +} + + + /* --------------------- sifive_fe310_g000_pll ------------ */ -static inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock) +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock) { return (struct metal_clock *)&__metal_dt_clock_3.clock; } -static inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock) +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock) { return (struct metal_clock *)&__metal_dt_clock_1.clock; } -static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock) +static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock) { return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000; } -static inline long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock) +static __inline__ long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock) { return METAL_SIFIVE_FE310_G000_PRCI_PLLOUTDIV; } -static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( ) +static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( ) { return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000; } -static inline long __metal_driver_sifive_fe310_g000_pll_config_offset( ) +static __inline__ long __metal_driver_sifive_fe310_g000_pll_config_offset( ) { return METAL_SIFIVE_FE310_G000_PRCI_PLLCFG; } -static inline long __metal_driver_sifive_fe310_g000_pll_init_rate( ) +static __inline__ long __metal_driver_sifive_fe310_g000_pll_init_rate( ) { return 16000000; } @@ -773,31 +1360,29 @@ static inline long __metal_driver_sifive_fe310_g000_pll_init_rate( ) /* --------------------- sifive_fe310_g000_prci ------------ */ -static inline long __metal_driver_sifive_fe310_g000_prci_base( ) +static __inline__ long __metal_driver_sifive_fe310_g000_prci_base( ) { return METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS; } -static inline long __metal_driver_sifive_fe310_g000_prci_size( ) +static __inline__ long __metal_driver_sifive_fe310_g000_prci_size( ) { return METAL_SIFIVE_FE310_G000_PRCI_10008000_SIZE; } -static inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( ) +static __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( ) { return &__metal_driver_vtable_sifive_fe310_g000_prci; } -/* --------------------- sifive_fu540_c000_l2 ------------ */ - +#define __METAL_DT_MAX_MEMORIES 3 -#define __METAL_DT_MAX_MEMORIES 2 - -asm (".weak __metal_memory_table"); +__asm__ (".weak __metal_memory_table"); struct metal_memory *__metal_memory_table[] = { &__metal_dt_mem_dtim_80000000, + &__metal_dt_mem_itim_8000000, &__metal_dt_mem_spi_10014000}; /* From serial@10013000 */ @@ -814,7 +1399,9 @@ struct metal_memory *__metal_memory_table[] = { #define __METAL_DT_MAX_HARTS 1 -asm (".weak __metal_cpu_table"); +#define __METAL_CPU_0_ICACHE_HANDLE 1 + +__asm__ (".weak __metal_cpu_table"); struct __metal_driver_cpu *__metal_cpu_table[] = { &__metal_dt_cpu_0}; @@ -825,47 +1412,82 @@ struct __metal_driver_cpu *__metal_cpu_table[] = { #define __METAL_DT_PMP_HANDLE (&__metal_dt_pmp) -/* From local_external_interrupts_0 */ -#define __METAL_DT_SIFIVE_LOCAL_EXINTR0_HANDLE (&__metal_dt_local_external_interrupts_0.irc) - -#define __METAL_DT_LOCAL_EXTERNAL_INTERRUPTS_0_HANDLE (&__metal_dt_local_external_interrupts_0.irc) - #define __MEE_DT_MAX_GPIOS 1 -asm (".weak __metal_gpio_table"); +__asm__ (".weak __metal_gpio_table"); struct __metal_driver_sifive_gpio0 *__metal_gpio_table[] = { &__metal_dt_gpio_10012000}; #define __METAL_DT_MAX_BUTTONS 0 -asm (".weak __metal_button_table"); +__asm__ (".weak __metal_button_table"); struct __metal_driver_sifive_gpio_button *__metal_button_table[] = { NULL }; #define __METAL_DT_MAX_LEDS 3 -asm (".weak __metal_led_table"); +__asm__ (".weak __metal_led_table"); struct __metal_driver_sifive_gpio_led *__metal_led_table[] = { - &__metal_dt_led_0red, - &__metal_dt_led_0green, - &__metal_dt_led_0blue}; + &__metal_dt_led_0, + &__metal_dt_led_1, + &__metal_dt_led_2}; #define __METAL_DT_MAX_SWITCHES 0 -asm (".weak __metal_switch_table"); +__asm__ (".weak __metal_switch_table"); struct __metal_driver_sifive_gpio_switch *__metal_switch_table[] = { NULL }; -#define __METAL_DT_MAX_SPIS 1 +#define __METAL_DT_MAX_I2CS 1 + +__asm__ (".weak __metal_i2c_table"); +struct __metal_driver_sifive_i2c0 *__metal_i2c_table[] = { + &__metal_dt_i2c_10016000}; + +#define __METAL_DT_MAX_PWMS 3 + +__asm__ (".weak __metal_pwm_table"); +struct __metal_driver_sifive_pwm0 *__metal_pwm_table[] = { + &__metal_dt_pwm_10015000, + &__metal_dt_pwm_10025000, + &__metal_dt_pwm_10035000}; + +#define __METAL_DT_MAX_RTCS 1 -asm (".weak __metal_spi_table"); +__asm__ (".weak __metal_rtc_table"); +struct __metal_driver_sifive_rtc0 *__metal_rtc_table[] = { + &__metal_dt_rtc_10000000}; + +#define __METAL_DT_MAX_SPIS 3 + +__asm__ (".weak __metal_spi_table"); struct __metal_driver_sifive_spi0 *__metal_spi_table[] = { - &__metal_dt_spi_10014000}; + &__metal_dt_spi_10014000, + &__metal_dt_spi_10024000, + &__metal_dt_spi_10034000}; + +#define __METAL_DT_MAX_UARTS 2 + +__asm__ (".weak __metal_uart_table"); +struct __metal_driver_sifive_uart0 *__metal_uart_table[] = { + &__metal_dt_serial_10013000, + &__metal_dt_serial_10023000}; + +#define __METAL_DT_MAX_SIMUARTS 0 + +__asm__ (".weak __metal_simuart_table"); +struct __metal_driver_sifive_simuart0 *__metal_simuart_table[] = { + NULL }; +#define __METAL_DT_MAX_WDOGS 1 + +__asm__ (".weak __metal_wdog_table"); +struct __metal_driver_sifive_wdog0 *__metal_wdog_table[] = { + &__metal_dt_aon_10000000}; /* From clock@4 */ #define __METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE (&__metal_dt_clock_4) #define __METAL_DT_CLOCK_4_HANDLE (&__metal_dt_clock_4) -#endif /* MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H*/ +#endif /* MACROS_ELSE_METAL_H*/ #endif /* ! __METAL_MACHINE_MACROS */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/inline.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/inline.h index 8c0cd048b..fd05ab065 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/inline.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/inline.h @@ -5,128 +5,181 @@ #ifndef ASSEMBLY -#ifndef SIFIVE_HIFIVE1_REVB____METAL_INLINE_H -#define SIFIVE_HIFIVE1_REVB____METAL_INLINE_H +#ifndef METAL_INLINE_H +#define METAL_INLINE_H #include <metal/machine.h> /* --------------------- fixed_clock ------------ */ -extern inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock); +extern __inline__ unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock); /* --------------------- fixed_factor_clock ------------ */ /* --------------------- sifive_clint0 ------------ */ -extern inline unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller); -extern inline unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller); -extern inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller); -extern inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx); -extern inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx); +extern __inline__ unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller); +extern __inline__ unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller); +extern __inline__ int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx); +extern __inline__ int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx); /* --------------------- cpu ------------ */ -extern inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu); -extern inline int __metal_driver_cpu_timebase(struct metal_cpu *cpu); -extern inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu); -extern inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu); +extern __inline__ int __metal_driver_cpu_hartid(struct metal_cpu *cpu); +extern __inline__ int __metal_driver_cpu_timebase(struct metal_cpu *cpu); +extern __inline__ struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu); +extern __inline__ int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu); +extern __inline__ struct metal_buserror * __metal_driver_cpu_buserror(struct metal_cpu *cpu); /* --------------------- sifive_plic0 ------------ */ -extern inline unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller); -extern inline unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller); -extern inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller); -extern inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller); -extern inline struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx); -extern inline int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx); +extern __inline__ unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller); +extern __inline__ unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller); +extern __inline__ int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller); +extern __inline__ int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx); +extern __inline__ int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx); +extern __inline__ int __metal_driver_sifive_plic0_context_ids(int hartid); + + +/* --------------------- sifive_buserror0 ------------ */ /* --------------------- sifive_clic0 ------------ */ /* --------------------- sifive_local_external_interrupts0 ------------ */ -extern inline struct metal_interrupt * __metal_driver_sifive_local_external_interrupts0_interrupt_parent(struct metal_interrupt *controller); -extern inline int __metal_driver_sifive_local_external_interrupts0_num_interrupts(struct metal_interrupt *controller); -extern inline int __metal_driver_sifive_local_external_interrupts0_interrupt_lines(struct metal_interrupt *controller, int idx); /* --------------------- sifive_global_external_interrupts0 ------------ */ /* --------------------- sifive_gpio0 ------------ */ -extern inline unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio); -extern inline unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio); -extern inline int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio); -extern inline struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio); -extern inline int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx); +extern __inline__ unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio); +extern __inline__ unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio); +extern __inline__ int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio); +extern __inline__ int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx); /* --------------------- sifive_gpio_button ------------ */ /* --------------------- sifive_gpio_led ------------ */ -extern inline struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led); -extern inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led); -extern inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led); +extern __inline__ struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led); +extern __inline__ int __metal_driver_sifive_gpio_led_pin(struct metal_led *led); +extern __inline__ char * __metal_driver_sifive_gpio_led_label(struct metal_led *led); /* --------------------- sifive_gpio_switch ------------ */ +/* --------------------- sifive_i2c0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_i2c0_control_base(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_control_size(struct metal_i2c *i2c); +extern __inline__ int __metal_driver_sifive_i2c0_num_interrupts(struct metal_i2c *i2c); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_i2c0_interrupt_parent(struct metal_i2c *i2c); +extern __inline__ int __metal_driver_sifive_i2c0_interrupt_line(struct metal_i2c *i2c); +extern __inline__ struct metal_clock * __metal_driver_sifive_i2c0_clock(struct metal_i2c *i2c); +extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_i2c0_pinmux(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_output_selector(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_source_selector(struct metal_i2c *i2c); + + +/* --------------------- sifive_pwm0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_pwm0_control_base(struct metal_pwm *pwm); +extern __inline__ unsigned long __metal_driver_sifive_pwm0_control_size(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_num_interrupts(struct metal_pwm *pwm); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_pwm0_interrupt_parent(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_interrupt_lines(struct metal_pwm *pwm, int idx); +extern __inline__ struct metal_clock * __metal_driver_sifive_pwm0_clock(struct metal_pwm *pwm); +extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_pwm0_pinmux(struct metal_pwm *pwm); +extern __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_output_selector(struct metal_pwm *pwm); +extern __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_source_selector(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_compare_width(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_comparator_count(struct metal_pwm *pwm); + + +/* --------------------- sifive_rtc0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_rtc0_control_base(const struct metal_rtc *const rtc); +extern __inline__ unsigned long __metal_driver_sifive_rtc0_control_size(const struct metal_rtc *const rtc); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_rtc0_interrupt_parent(const struct metal_rtc *const rtc); +extern __inline__ int __metal_driver_sifive_rtc0_interrupt_line(const struct metal_rtc *const rtc); +extern __inline__ struct metal_clock * __metal_driver_sifive_rtc0_clock(const struct metal_rtc *const rtc); + + /* --------------------- sifive_spi0 ------------ */ -extern inline unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi); -extern inline unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi); -extern inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi); -extern inline unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi); -extern inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi); +extern __inline__ unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi); +extern __inline__ unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi); +extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi); +extern __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi); +extern __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi); /* --------------------- sifive_test0 ------------ */ +/* --------------------- sifive_trace ------------ */ + /* --------------------- sifive_uart0 ------------ */ -extern inline unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart); -extern inline unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart); -extern inline int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart); -extern inline struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart); -extern inline int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart); -extern inline struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart); -extern inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart); -extern inline unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart); -extern inline unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart); +extern __inline__ unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart); +extern __inline__ unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart); +extern __inline__ int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart); +extern __inline__ int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart); +extern __inline__ struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart); +extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart); +extern __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart); +extern __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart); + + +/* --------------------- sifive_simuart0 ------------ */ + + +/* --------------------- sifive_wdog0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_wdog0_control_base(const struct metal_watchdog *const watchdog); +extern __inline__ unsigned long __metal_driver_sifive_wdog0_control_size(const struct metal_watchdog *const watchdog); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_wdog0_interrupt_parent(const struct metal_watchdog *const watchdog); +extern __inline__ int __metal_driver_sifive_wdog0_interrupt_line(const struct metal_watchdog *const watchdog); +extern __inline__ struct metal_clock * __metal_driver_sifive_wdog0_clock(const struct metal_watchdog *const watchdog); /* --------------------- sifive_fe310_g000_hfrosc ------------ */ -extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock); -extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock); -extern inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock); -extern inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock); +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock); +extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock); +extern __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock); +extern __inline__ long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock); /* --------------------- sifive_fe310_g000_hfxosc ------------ */ -extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock); -extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock); -extern inline long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock); +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock); +extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock); +extern __inline__ long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock); -/* --------------------- sifive_fe310_g000_pll ------------ */ -extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock); -extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock); -extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( ); -extern inline long __metal_driver_sifive_fe310_g000_pll_config_offset( ); -extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock); -extern inline long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock); -extern inline long __metal_driver_sifive_fe310_g000_pll_init_rate( ); +/* --------------------- sifive_fe310_g000_lfrosc ------------ */ +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(const struct metal_clock *clock); +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(const struct metal_clock *clock); +extern __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_config_reg(const struct metal_clock *clock); +extern __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(const struct metal_clock *clock); -/* --------------------- fe310_g000_prci ------------ */ -extern inline long __metal_driver_sifive_fe310_g000_prci_base( ); -extern inline long __metal_driver_sifive_fe310_g000_prci_size( ); -extern inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( ); +/* --------------------- sifive_fe310_g000_pll ------------ */ +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock); +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock); +extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( ); +extern __inline__ long __metal_driver_sifive_fe310_g000_pll_config_offset( ); +extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock); +extern __inline__ long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock); +extern __inline__ long __metal_driver_sifive_fe310_g000_pll_init_rate( ); -/* --------------------- sifive_fu540_c000_l2 ------------ */ +/* --------------------- fe310_g000_prci ------------ */ +extern __inline__ long __metal_driver_sifive_fe310_g000_prci_base( ); +extern __inline__ long __metal_driver_sifive_fe310_g000_prci_size( ); +extern __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( ); /* From clock@0 */ @@ -144,6 +197,11 @@ struct __metal_driver_fixed_clock __metal_dt_clock_5 = { .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, }; +/* From clock@6 */ +struct __metal_driver_fixed_clock __metal_dt_clock_6 = { + .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, +}; + struct metal_memory __metal_dt_mem_dtim_80000000 = { ._base_address = 2147483648UL, ._size = 16384UL, @@ -155,6 +213,17 @@ struct metal_memory __metal_dt_mem_dtim_80000000 = { .A = 1}, }; +struct metal_memory __metal_dt_mem_itim_8000000 = { + ._base_address = 134217728UL, + ._size = 8192UL, + ._attrs = { + .R = 1, + .W = 1, + .X = 1, + .C = 1, + .A = 1}, +}; + struct metal_memory __metal_dt_mem_spi_10014000 = { ._base_address = 536870912UL, ._size = 500000UL, @@ -166,6 +235,24 @@ struct metal_memory __metal_dt_mem_spi_10014000 = { .A = 1}, }; +struct metal_memory __metal_dt_mem_spi_10024000 = { + ._attrs = { + .R = 1, + .W = 1, + .X = 1, + .C = 1, + .A = 1}, +}; + +struct metal_memory __metal_dt_mem_spi_10034000 = { + ._attrs = { + .R = 1, + .W = 1, + .X = 1, + .C = 1, + .A = 1}, +}; + /* From clint@2000000 */ struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000 = { .controller.vtable = &__metal_driver_vtable_riscv_clint0.clint_vtable, @@ -175,6 +262,7 @@ struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000 = { /* From cpu@0 */ struct __metal_driver_cpu __metal_dt_cpu_0 = { .cpu.vtable = &__metal_driver_vtable_cpu.cpu_vtable, + .hpm_count = 0, }; /* From interrupt_controller */ @@ -189,42 +277,83 @@ struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000 = { .init_done = 0, }; -/* From local_external_interrupts_0 */ -struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_0 = { - .irc.vtable = &__metal_driver_vtable_sifive_local_external_interrupts0.local0_vtable, - .init_done = 0, -}; +struct metal_pmp __metal_dt_pmp; /* From gpio@10012000 */ struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000 = { .gpio.vtable = &__metal_driver_vtable_sifive_gpio0.gpio, }; -/* From led@0red */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0red = { +/* From led@0 */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0 = { .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, }; -/* From led@0green */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0green = { +/* From led@1 */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_1 = { .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, }; -/* From led@0blue */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue = { +/* From led@2 */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_2 = { .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, }; +/* From i2c@10016000 */ +struct __metal_driver_sifive_i2c0 __metal_dt_i2c_10016000 = { + .i2c.vtable = &__metal_driver_vtable_sifive_i2c0.i2c, +}; + +/* From pwm@10015000 */ +struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10015000 = { + .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm, +}; + +/* From pwm@10025000 */ +struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10025000 = { + .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm, +}; + +/* From pwm@10035000 */ +struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10035000 = { + .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm, +}; + +/* From aon@10000000 */ +struct __metal_driver_sifive_rtc0 __metal_dt_rtc_10000000 = { + .rtc.vtable = &__metal_driver_vtable_sifive_rtc0.rtc, +}; + /* From spi@10014000 */ struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000 = { .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi, }; +/* From spi@10024000 */ +struct __metal_driver_sifive_spi0 __metal_dt_spi_10024000 = { + .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi, +}; + +/* From spi@10034000 */ +struct __metal_driver_sifive_spi0 __metal_dt_spi_10034000 = { + .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi, +}; + /* From serial@10013000 */ struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000 = { .uart.vtable = &__metal_driver_vtable_sifive_uart0.uart, }; +/* From serial@10023000 */ +struct __metal_driver_sifive_uart0 __metal_dt_serial_10023000 = { + .uart.vtable = &__metal_driver_vtable_sifive_uart0.uart, +}; + +/* From aon@10000000 */ +struct __metal_driver_sifive_wdog0 __metal_dt_aon_10000000 = { + .watchdog.vtable = &__metal_driver_vtable_sifive_wdog0.watchdog, +}; + /* From clock@3 */ struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3 = { .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfrosc.clock, @@ -235,6 +364,11 @@ struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1 = { .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfxosc.clock, }; +/* From clock@7 */ +struct __metal_driver_sifive_fe310_g000_lfrosc __metal_dt_clock_7 = { + .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_lfrosc.clock, +}; + /* From clock@4 */ struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4 = { .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_pll.clock, @@ -242,8 +376,9 @@ struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4 = { /* From prci@10008000 */ struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000 = { + .vtable = &__metal_driver_vtable_sifive_fe310_g000_prci, }; -#endif /* SIFIVE_HIFIVE1_REVB____METAL_INLINE_H*/ +#endif /* METAL_INLINE_H*/ #endif /* ! ASSEMBLY */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/platform.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/platform.h index 4ecd3e336..d517b5859 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/platform.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/machine/platform.h @@ -3,8 +3,8 @@ /* ----------------------------------- */ /* ----------------------------------- */ -#ifndef SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H -#define SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H +#ifndef METAL_PLATFORM_H +#define METAL_PLATFORM_H /* From clock@0 */ #define METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY 16000000UL @@ -13,7 +13,10 @@ #define METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY 72000000UL /* From clock@5 */ -#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32000000UL +#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32768UL + +/* From clock@6 */ +#define METAL_FIXED_CLOCK_6_CLOCK_FREQUENCY 32768UL #define METAL_FIXED_CLOCK @@ -35,15 +38,18 @@ #define METAL_RISCV_PLIC0_0_SIZE 67108864UL #define METAL_RISCV_PLIC0_C000000_RISCV_MAX_PRIORITY 7UL #define METAL_RISCV_PLIC0_0_RISCV_MAX_PRIORITY 7UL -#define METAL_RISCV_PLIC0_C000000_RISCV_NDEV 27UL -#define METAL_RISCV_PLIC0_0_RISCV_NDEV 27UL +#define METAL_RISCV_PLIC0_C000000_RISCV_NDEV 53UL +#define METAL_RISCV_PLIC0_0_RISCV_NDEV 53UL #define METAL_RISCV_PLIC0 #define METAL_RISCV_PLIC0_PRIORITY_BASE 0UL #define METAL_RISCV_PLIC0_PENDING_BASE 4096UL #define METAL_RISCV_PLIC0_ENABLE_BASE 8192UL -#define METAL_RISCV_PLIC0_THRESHOLD 2097152UL -#define METAL_RISCV_PLIC0_CLAIM 2097156UL +#define METAL_RISCV_PLIC0_ENABLE_PER_HART 128UL +#define METAL_RISCV_PLIC0_CONTEXT_BASE 2097152UL +#define METAL_RISCV_PLIC0_CONTEXT_PER_HART 4096UL +#define METAL_RISCV_PLIC0_CONTEXT_THRESHOLD 0UL +#define METAL_RISCV_PLIC0_CONTEXT_CLAIM 4UL /* From aon@10000000 */ #define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL @@ -111,6 +117,10 @@ #define METAL_SIFIVE_FE310_G000_HFXOSC +/* From clock@7 */ + +#define METAL_SIFIVE_FE310_G000_LFROSC + /* From prci@10008000 */ #define METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS 268468224UL #define METAL_SIFIVE_FE310_G000_PRCI_0_BASE_ADDRESS 268468224UL @@ -153,11 +163,11 @@ #define METAL_SIFIVE_GPIO0_IOF_SEL 60UL #define METAL_SIFIVE_GPIO0_OUT_XOR 64UL -/* From led@0red */ +/* From led@0 */ -/* From led@0green */ +/* From led@1 */ -/* From led@0blue */ +/* From led@2 */ #define METAL_SIFIVE_GPIO_LEDS @@ -176,16 +186,24 @@ #define METAL_SIFIVE_I2C0_COMMAND 16UL #define METAL_SIFIVE_I2C0_STATUS 16UL -/* From local_external_interrupts_0 */ - -#define METAL_SIFIVE_LOCAL_EXTERNAL_INTERRUPTS0 - /* From pwm@10015000 */ #define METAL_SIFIVE_PWM0_10015000_BASE_ADDRESS 268521472UL #define METAL_SIFIVE_PWM0_0_BASE_ADDRESS 268521472UL #define METAL_SIFIVE_PWM0_10015000_SIZE 4096UL #define METAL_SIFIVE_PWM0_0_SIZE 4096UL +/* From pwm@10025000 */ +#define METAL_SIFIVE_PWM0_10025000_BASE_ADDRESS 268587008UL +#define METAL_SIFIVE_PWM0_1_BASE_ADDRESS 268587008UL +#define METAL_SIFIVE_PWM0_10025000_SIZE 4096UL +#define METAL_SIFIVE_PWM0_1_SIZE 4096UL + +/* From pwm@10035000 */ +#define METAL_SIFIVE_PWM0_10035000_BASE_ADDRESS 268652544UL +#define METAL_SIFIVE_PWM0_2_BASE_ADDRESS 268652544UL +#define METAL_SIFIVE_PWM0_10035000_SIZE 4096UL +#define METAL_SIFIVE_PWM0_2_SIZE 4096UL + #define METAL_SIFIVE_PWM0 #define METAL_SIFIVE_PWM0_PWMCFG 0UL #define METAL_SIFIVE_PWM0_PWMCOUNT 8UL @@ -195,12 +213,37 @@ #define METAL_SIFIVE_PWM0_PWMCMP2 40UL #define METAL_SIFIVE_PWM0_PWMCMP3 44UL +/* From aon@10000000 */ +#define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL +#define METAL_SIFIVE_AON0_0_BASE_ADDRESS 268435456UL +#define METAL_SIFIVE_AON0_10000000_SIZE 32768UL +#define METAL_SIFIVE_AON0_0_SIZE 32768UL + +#define METAL_SIFIVE_RTC0 +#define METAL_SIFIVE_RTC0_RTCCFG 64UL +#define METAL_SIFIVE_RTC0_RTCCOUNTLO 72UL +#define METAL_SIFIVE_RTC0_RTCCOUNTHI 76UL +#define METAL_SIFIVE_RTC0_RTCS 80UL +#define METAL_SIFIVE_RTC0_RTCCMP0 96UL + /* From spi@10014000 */ #define METAL_SIFIVE_SPI0_10014000_BASE_ADDRESS 268517376UL #define METAL_SIFIVE_SPI0_0_BASE_ADDRESS 268517376UL #define METAL_SIFIVE_SPI0_10014000_SIZE 4096UL #define METAL_SIFIVE_SPI0_0_SIZE 4096UL +/* From spi@10024000 */ +#define METAL_SIFIVE_SPI0_10024000_BASE_ADDRESS 268582912UL +#define METAL_SIFIVE_SPI0_1_BASE_ADDRESS 268582912UL +#define METAL_SIFIVE_SPI0_10024000_SIZE 4096UL +#define METAL_SIFIVE_SPI0_1_SIZE 4096UL + +/* From spi@10034000 */ +#define METAL_SIFIVE_SPI0_10034000_BASE_ADDRESS 268648448UL +#define METAL_SIFIVE_SPI0_2_BASE_ADDRESS 268648448UL +#define METAL_SIFIVE_SPI0_10034000_SIZE 4096UL +#define METAL_SIFIVE_SPI0_2_SIZE 4096UL + #define METAL_SIFIVE_SPI0 #define METAL_SIFIVE_SPI0_SCKDIV 0UL #define METAL_SIFIVE_SPI0_SCKMODE 4UL @@ -225,6 +268,12 @@ #define METAL_SIFIVE_UART0_10013000_SIZE 4096UL #define METAL_SIFIVE_UART0_0_SIZE 4096UL +/* From serial@10023000 */ +#define METAL_SIFIVE_UART0_10023000_BASE_ADDRESS 268578816UL +#define METAL_SIFIVE_UART0_1_BASE_ADDRESS 268578816UL +#define METAL_SIFIVE_UART0_10023000_SIZE 4096UL +#define METAL_SIFIVE_UART0_1_SIZE 4096UL + #define METAL_SIFIVE_UART0 #define METAL_SIFIVE_UART0_TXDATA 0UL #define METAL_SIFIVE_UART0_RXDATA 4UL @@ -234,4 +283,20 @@ #define METAL_SIFIVE_UART0_IP 20UL #define METAL_SIFIVE_UART0_DIV 24UL -#endif /* SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H*/ +/* From aon@10000000 */ +#define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL +#define METAL_SIFIVE_AON0_0_BASE_ADDRESS 268435456UL +#define METAL_SIFIVE_AON0_10000000_SIZE 32768UL +#define METAL_SIFIVE_AON0_0_SIZE 32768UL + +#define METAL_SIFIVE_WDOG0 +#define METAL_SIFIVE_WDOG0_MAGIC_KEY 5370206UL +#define METAL_SIFIVE_WDOG0_MAGIC_FOOD 218755085UL +#define METAL_SIFIVE_WDOG0_WDOGCFG 0UL +#define METAL_SIFIVE_WDOG0_WDOGCOUNT 8UL +#define METAL_SIFIVE_WDOG0_WDOGS 16UL +#define METAL_SIFIVE_WDOG0_WDOGFEED 24UL +#define METAL_SIFIVE_WDOG0_WDOGKEY 28UL +#define METAL_SIFIVE_WDOG0_WDOGCMP 32UL + +#endif /* METAL_PLATFORM_H*/ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/memory.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/memory.h index b62d8b25a..f009e9ecc 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/memory.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/memory.h @@ -4,8 +4,8 @@ #ifndef METAL__MEMORY_H #define METAL__MEMORY_H -#include <stdint.h> #include <stddef.h> +#include <stdint.h> /*! * @file memory.h @@ -14,20 +14,20 @@ */ struct _metal_memory_attributes { - int R : 1; - int W : 1; - int X : 1; - int C : 1; - int A : 1; + unsigned int R : 1; + unsigned int W : 1; + unsigned int X : 1; + unsigned int C : 1; + unsigned int A : 1; }; /*! * @brief A handle for a memory block */ struct metal_memory { - const uintptr_t _base_address; - const size_t _size; - const struct _metal_memory_attributes _attrs; + const uintptr_t _base_address; + const size_t _size; + const struct _metal_memory_attributes _attrs; }; /*! @@ -37,7 +37,8 @@ struct metal_memory { * that address is mapped. * * @param address The address to query - * @return The memory block handle, or NULL if the address is not mapped to a memory block + * @return The memory block handle, or NULL if the address is not mapped to a + * memory block */ struct metal_memory *metal_get_memory_from_address(const uintptr_t address); @@ -46,8 +47,9 @@ struct metal_memory *metal_get_memory_from_address(const uintptr_t address); * @param memory The handle for the memory block * @return The base address of the memory block */ -inline uintptr_t metal_memory_get_base_address(const struct metal_memory *memory) { - return memory->_base_address; +__inline__ uintptr_t +metal_memory_get_base_address(const struct metal_memory *memory) { + return memory->_base_address; } /*! @@ -55,8 +57,8 @@ inline uintptr_t metal_memory_get_base_address(const struct metal_memory *memory * @param memory The handle for the memory block * @return The size of the memory block */ -inline size_t metal_memory_get_size(const struct metal_memory *memory) { - return memory->_size; +__inline__ size_t metal_memory_get_size(const struct metal_memory *memory) { + return memory->_size; } /*! @@ -64,8 +66,9 @@ inline size_t metal_memory_get_size(const struct metal_memory *memory) { * @param memory The handle for the memory block * @return nonzero if the memory block supports atomic operations */ -inline int metal_memory_supports_atomics(const struct metal_memory *memory) { - return memory->_attrs.A; +__inline__ int +metal_memory_supports_atomics(const struct metal_memory *memory) { + return memory->_attrs.A; } /*! @@ -73,9 +76,8 @@ inline int metal_memory_supports_atomics(const struct metal_memory *memory) { * @param memory The handle for the memory block * @return nonzero if the memory block is cachable */ -inline int metal_memory_is_cachable(const struct metal_memory *memory) { - return memory->_attrs.C; +__inline__ int metal_memory_is_cachable(const struct metal_memory *memory) { + return memory->_attrs.C; } #endif /* METAL__MEMORY_H */ - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pmp.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pmp.h index 9121b10a1..38ab1b9a4 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pmp.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pmp.h @@ -12,14 +12,14 @@ * The Physical Memory Protection (PMP) interface on RISC-V cores * is a form of memory protection unit which allows for a finite number * of physical memory regions to be configured with certain access - * permissions. + * permissions. * * Additional information about the use and configuration rules for PMPs * can be found by reading the RISC-V Privileged Architecture Specification. */ -#include <stddef.h> #include <metal/machine.h> +#include <stddef.h> struct metal_pmp; @@ -28,11 +28,11 @@ struct metal_pmp; */ enum metal_pmp_address_mode { /*! @brief Disable the PMP region */ - METAL_PMP_OFF = 0, + METAL_PMP_OFF = 0, /*! @brief Use Top-of-Range mode */ - METAL_PMP_TOR = 1, + METAL_PMP_TOR = 1, /*! @brief Use naturally-aligned 4-byte region mode */ - METAL_PMP_NA4 = 2, + METAL_PMP_NA4 = 2, /*! @brief Use naturally-aligned power-of-two mode */ METAL_PMP_NAPOT = 3 }; @@ -42,11 +42,11 @@ enum metal_pmp_address_mode { */ struct metal_pmp_config { /*! @brief Sets whether reads to the PMP region succeed */ - int R : 1; + unsigned int R : 1; /*! @brief Sets whether writes to the PMP region succeed */ - int W : 1; + unsigned int W : 1; /*! @brief Sets whether the PMP region is executable */ - int X : 1; + unsigned int X : 1; /*! @brief Sets the addressing mode of the PMP region */ enum metal_pmp_address_mode A : 2; @@ -56,7 +56,7 @@ struct metal_pmp_config { /*! @brief Sets whether the PMP region is locked */ enum metal_pmp_locked { METAL_PMP_UNLOCKED = 0, - METAL_PMP_LOCKED = 1 + METAL_PMP_LOCKED = 1 } L : 1; }; @@ -74,6 +74,11 @@ struct metal_pmp { struct metal_pmp *metal_pmp_get_device(void); /*! + * @brief Get the number of pmp regions for the hartid + */ +int metal_pmp_num_regions(int hartid); + +/*! * @brief Initialize the PMP * @param pmp The PMP device handle to be initialized * @@ -96,9 +101,10 @@ void metal_pmp_init(struct metal_pmp *pmp); * @param address The desired address of the PMP region * @return 0 upon success */ -int metal_pmp_set_region(struct metal_pmp *pmp, unsigned int region, struct metal_pmp_config config, size_t address); +int metal_pmp_set_region(struct metal_pmp *pmp, unsigned int region, + struct metal_pmp_config config, size_t address); -/*! +/*! * @brief Get the configuration for a PMP region * @param pmp The PMP device handle * @param region The PMP region to read @@ -106,7 +112,8 @@ int metal_pmp_set_region(struct metal_pmp *pmp, unsigned int region, struct meta * @param address Variable to store the PMP region address * @return 0 if the region is read successfully */ -int metal_pmp_get_region(struct metal_pmp *pmp, unsigned int region, struct metal_pmp_config *config, size_t *address); +int metal_pmp_get_region(struct metal_pmp *pmp, unsigned int region, + struct metal_pmp_config *config, size_t *address); /*! * @brief Lock a PMP region @@ -123,7 +130,8 @@ int metal_pmp_lock(struct metal_pmp *pmp, unsigned int region); * @param address The desired address of the PMP region * @return 0 if the address is successfully set */ -int metal_pmp_set_address(struct metal_pmp *pmp, unsigned int region, size_t address); +int metal_pmp_set_address(struct metal_pmp *pmp, unsigned int region, + size_t address); /*! * @brief Get the address of a PMP region @@ -140,7 +148,8 @@ size_t metal_pmp_get_address(struct metal_pmp *pmp, unsigned int region); * @param mode The PMP addressing mode to set * @return 0 if the addressing mode is successfully set */ -int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region, enum metal_pmp_address_mode mode); +int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region, + enum metal_pmp_address_mode mode); /*! * @brief Get the addressing mode of a PMP region @@ -148,7 +157,8 @@ int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region, enum * @param region The PMP region to read * @return The address mode of the PMP region */ -enum metal_pmp_address_mode metal_pmp_get_address_mode(struct metal_pmp *pmp, unsigned int region); +enum metal_pmp_address_mode metal_pmp_get_address_mode(struct metal_pmp *pmp, + unsigned int region); /*! * @brief Set the executable bit for a PMP region diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/privilege.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/privilege.h index c5212e5d1..522e7efe0 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/privilege.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/privilege.h @@ -16,9 +16,9 @@ #include <stdint.h> enum metal_privilege_mode { - METAL_PRIVILEGE_USER = 0, - METAL_PRIVILEGE_SUPERVISOR = 1, - METAL_PRIVELEGE_MACHINE = 3, + METAL_PRIVILEGE_USER = 0, + METAL_PRIVILEGE_SUPERVISOR = 1, + METAL_PRIVILEGE_MACHINE = 3, }; #if __riscv_xlen == 32 @@ -34,89 +34,89 @@ typedef uint64_t metal_freg_t; #endif struct metal_register_file { - metal_xreg_t ra; - metal_xreg_t sp; - metal_xreg_t gp; - metal_xreg_t tp; - - metal_xreg_t t0; - metal_xreg_t t1; - metal_xreg_t t2; - - metal_xreg_t s0; - metal_xreg_t s1; - - metal_xreg_t a0; - metal_xreg_t a1; - metal_xreg_t a2; - metal_xreg_t a3; - metal_xreg_t a4; - metal_xreg_t a5; + metal_xreg_t ra; + metal_xreg_t sp; + metal_xreg_t gp; + metal_xreg_t tp; + + metal_xreg_t t0; + metal_xreg_t t1; + metal_xreg_t t2; + + metal_xreg_t s0; + metal_xreg_t s1; + + metal_xreg_t a0; + metal_xreg_t a1; + metal_xreg_t a2; + metal_xreg_t a3; + metal_xreg_t a4; + metal_xreg_t a5; #ifndef __riscv_32e - metal_xreg_t a6; - metal_xreg_t a7; - - metal_xreg_t s2; - metal_xreg_t s3; - metal_xreg_t s4; - metal_xreg_t s5; - metal_xreg_t s6; - metal_xreg_t s7; - metal_xreg_t s8; - metal_xreg_t s9; - metal_xreg_t s10; - metal_xreg_t s11; - - metal_xreg_t t3; - metal_xreg_t t4; - metal_xreg_t t5; - metal_xreg_t t6; + metal_xreg_t a6; + metal_xreg_t a7; + + metal_xreg_t s2; + metal_xreg_t s3; + metal_xreg_t s4; + metal_xreg_t s5; + metal_xreg_t s6; + metal_xreg_t s7; + metal_xreg_t s8; + metal_xreg_t s9; + metal_xreg_t s10; + metal_xreg_t s11; + + metal_xreg_t t3; + metal_xreg_t t4; + metal_xreg_t t5; + metal_xreg_t t6; #endif /* __riscv_32e */ #ifdef __riscv_flen - metal_freg_t ft0; - metal_freg_t ft1; - metal_freg_t ft2; - metal_freg_t ft3; - metal_freg_t ft4; - metal_freg_t ft5; - metal_freg_t ft6; - metal_freg_t ft7; - - metal_freg_t fs0; - metal_freg_t fs1; - - metal_freg_t fa0; - metal_freg_t fa1; - metal_freg_t fa2; - metal_freg_t fa3; - metal_freg_t fa4; - metal_freg_t fa5; - metal_freg_t fa6; - metal_freg_t fa7; - - metal_freg_t fs2; - metal_freg_t fs3; - metal_freg_t fs4; - metal_freg_t fs5; - metal_freg_t fs6; - metal_freg_t fs7; - metal_freg_t fs8; - metal_freg_t fs9; - metal_freg_t fs10; - metal_freg_t fs11; - - metal_freg_t ft8; - metal_freg_t ft9; - metal_freg_t ft10; - metal_freg_t ft11; + metal_freg_t ft0; + metal_freg_t ft1; + metal_freg_t ft2; + metal_freg_t ft3; + metal_freg_t ft4; + metal_freg_t ft5; + metal_freg_t ft6; + metal_freg_t ft7; + + metal_freg_t fs0; + metal_freg_t fs1; + + metal_freg_t fa0; + metal_freg_t fa1; + metal_freg_t fa2; + metal_freg_t fa3; + metal_freg_t fa4; + metal_freg_t fa5; + metal_freg_t fa6; + metal_freg_t fa7; + + metal_freg_t fs2; + metal_freg_t fs3; + metal_freg_t fs4; + metal_freg_t fs5; + metal_freg_t fs6; + metal_freg_t fs7; + metal_freg_t fs8; + metal_freg_t fs9; + metal_freg_t fs10; + metal_freg_t fs11; + + metal_freg_t ft8; + metal_freg_t ft9; + metal_freg_t ft10; + metal_freg_t ft11; #endif /* __riscv_flen */ }; -typedef void (*metal_privilege_entry_point_t)(); +typedef void (*metal_privilege_entry_point_t)(void); void metal_privilege_drop_to_mode(enum metal_privilege_mode mode, - struct metal_register_file regfile, - metal_privilege_entry_point_t entry_point); + struct metal_register_file regfile, + metal_privilege_entry_point_t entry_point); #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pwm.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pwm.h new file mode 100644 index 000000000..600d5a02b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/pwm.h @@ -0,0 +1,162 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__PWM_H +#define METAL__PWM_H + +/*! @brief Enums for PWM running modes. */ +typedef enum { + METAL_PWM_CONTINUOUS = 0, + METAL_PWM_ONE_SHOT = 1 +} metal_pwm_run_mode_t; + +/*! @brief Enums for Phase correct PWM. */ +typedef enum { + METAL_PWM_PHASE_CORRECT_DISABLE = 0, + METAL_PWM_PHASE_CORRECT_ENABLE = 1, +} metal_pwm_phase_correct_t; + +/*! @brief Enums for Interrupts enable/disable. */ +typedef enum { + METAL_PWM_INTERRUPT_DISABLE = 0, + METAL_PWM_INTERRUPT_ENABLE = 1, +} metal_pwm_interrupt_t; + +struct metal_pwm; + +/*! @brief vtable for PWM. */ +struct metal_pwm_vtable { + int (*enable)(struct metal_pwm *pwm); + int (*disable)(struct metal_pwm *pwm); + int (*set_freq)(struct metal_pwm *pwm, unsigned int idx, unsigned int freq); + int (*set_duty)(struct metal_pwm *pwm, unsigned int idx, unsigned int duty, + metal_pwm_phase_correct_t phase_corr); + unsigned int (*get_duty)(struct metal_pwm *pwm, unsigned int idx); + unsigned int (*get_freq)(struct metal_pwm *pwm, unsigned int idx); + int (*trigger)(struct metal_pwm *pwm, unsigned int idx, + metal_pwm_run_mode_t mode); + int (*stop)(struct metal_pwm *pwm, unsigned int idx); + int (*cfg_interrupt)(struct metal_pwm *pwm, metal_pwm_interrupt_t flag); + int (*clr_interrupt)(struct metal_pwm *pwm, unsigned int idx); + struct metal_interrupt *(*get_interrupt_controller)(struct metal_pwm *pwm); + int (*get_interrupt_id)(struct metal_pwm *pwm, unsigned int idx); +}; + +/*! @brief A handle for a PWM device. */ +struct metal_pwm { + const struct metal_pwm_vtable *vtable; +}; + +/*! @brief Gets a PWM device handle. + * @param device_num The index of the desired PWM device. + * @return A handle to the PWM device, or NULL if the device does not exist.*/ +struct metal_pwm *metal_pwm_get_device(unsigned int device_num); + +/*! @brief Enables PWM operation. + * @param pwm The handle for the PWM device to initialize. + * @return 0 If no error.*/ +inline int metal_pwm_enable(struct metal_pwm *pwm) { + return pwm->vtable->enable(pwm); +} + +/*! @brief Disables PWM operation. + * @param pwm The handle for the PWM device to be disabled. + * @return 0 If no error.*/ +inline int metal_pwm_disable(struct metal_pwm *pwm) { + return pwm->vtable->disable(pwm); +} + +/*! @brief Sets frequency in Hz for a given PWM instance. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @param freq PWM frequency in Hz. + * @return 0 If no error.*/ +inline int metal_pwm_set_freq(struct metal_pwm *pwm, unsigned int idx, + unsigned int freq) { + return pwm->vtable->set_freq(pwm, idx, freq); +} + +/*! @brief Sets duty cycle in percent values [0 - 100] for a given PWM instance. + * Phase correct mode provides center aligned PWM waveform output. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @param duty PWM duty cycle value. + * @param phase_corr Enable / Disable phase correct mode. + * @return 0 If no error.*/ +inline int metal_pwm_set_duty(struct metal_pwm *pwm, unsigned int idx, + unsigned int duty, + metal_pwm_phase_correct_t phase_corr) { + return pwm->vtable->set_duty(pwm, idx, duty, phase_corr); +} + +/*! @brief Gets duty cycle in percent values [0 - 100] for a given PWM instance. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return PWM duty cycle value.*/ +inline unsigned int metal_pwm_get_duty(struct metal_pwm *pwm, + unsigned int idx) { + return pwm->vtable->get_duty(pwm, idx); +} + +/*! @brief Gets frequency in Hz for a given PWM instance. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return PWM frequency in Hz.*/ +inline unsigned int metal_pwm_get_freq(struct metal_pwm *pwm, + unsigned int idx) { + return pwm->vtable->get_freq(pwm, idx); +} + +/*! @brief Starts a PWM instance in selected run mode (continuous/one shot). + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return 0 If no error.*/ +inline int metal_pwm_trigger(struct metal_pwm *pwm, unsigned int idx, + metal_pwm_run_mode_t mode) { + return pwm->vtable->trigger(pwm, idx, mode); +} + +/*! @brief Stops a running PWM instance in continuous mode. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return 0 If no error.*/ +inline int metal_pwm_stop(struct metal_pwm *pwm, unsigned int idx) { + return pwm->vtable->stop(pwm, idx); +} + +/*! @brief Enable or Disable PWM interrupts. + * @param pwm PWM device handle. + * @param flag PWM interrupt enable flag. + * @return 0 If no error.*/ +inline int metal_pwm_cfg_interrupt(struct metal_pwm *pwm, + metal_pwm_interrupt_t flag) { + return pwm->vtable->cfg_interrupt(pwm, flag); +} + +/*! @brief Clears pending interrupt flags. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return 0 If no error.*/ +inline int metal_pwm_clr_interrupt(struct metal_pwm *pwm, unsigned int idx) { + return pwm->vtable->clr_interrupt(pwm, idx); +} + +/*! @brief Get the interrupt controller of the PWM peripheral. + * The interrupt controller must be initialized before any interrupts can be + * registered or enabled with it. + * @param pwm PWM device handle. + * @return The handle for the PWM interrupt controller.*/ +inline struct metal_interrupt * +metal_pwm_interrupt_controller(struct metal_pwm *pwm) { + return pwm->vtable->get_interrupt_controller(pwm); +} + +/*! @brief Get the interrupt ID of the PWM peripheral. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return The PWM interrupt id.*/ +inline int metal_pwm_get_interrupt_id(struct metal_pwm *pwm, unsigned int idx) { + return pwm->vtable->get_interrupt_id(pwm, idx); +} + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/rtc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/rtc.h new file mode 100644 index 000000000..e1b798268 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/rtc.h @@ -0,0 +1,137 @@ +/* Copyright 2019 SiFive, Inc. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__RTC_H +#define METAL__RTC_H + +#include <stdint.h> + +/*! + * @file rtc.h + * @brief API for Real-Time Clocks + */ + +struct metal_rtc; + +/*! + * @brief List of RTC run behaviors + */ +enum metal_rtc_run_option { + METAL_RTC_STOP = 0, + METAL_RTC_RUN, +}; + +struct metal_rtc_vtable { + uint64_t (*get_rate)(const struct metal_rtc *const rtc); + uint64_t (*set_rate)(const struct metal_rtc *const rtc, + const uint64_t rate); + uint64_t (*get_compare)(const struct metal_rtc *const rtc); + uint64_t (*set_compare)(const struct metal_rtc *const rtc, + const uint64_t compare); + uint64_t (*get_count)(const struct metal_rtc *const rtc); + uint64_t (*set_count)(const struct metal_rtc *const rtc, + const uint64_t count); + int (*run)(const struct metal_rtc *const rtc, + const enum metal_rtc_run_option option); + struct metal_interrupt *(*get_interrupt)(const struct metal_rtc *const rtc); + int (*get_interrupt_id)(const struct metal_rtc *const rtc); +}; + +/*! + * @brief Handle for a Real-Time Clock + */ +struct metal_rtc { + const struct metal_rtc_vtable *vtable; +}; + +/*! + * @brief Get the rate of the RTC + * @return The rate in Hz + */ +inline uint64_t metal_rtc_get_rate(const struct metal_rtc *const rtc) { + return rtc->vtable->get_rate(rtc); +} + +/*! + * @brief Set (if possible) the rate of the RTC + * @return The new rate of the RTC (not guaranteed to be the same as requested) + */ +inline uint64_t metal_rtc_set_rate(const struct metal_rtc *const rtc, + const uint64_t rate) { + return rtc->vtable->set_rate(rtc, rate); +} + +/*! + * @brief Get the compare value of the RTC + * @return The compare value + */ +inline uint64_t metal_rtc_get_compare(const struct metal_rtc *const rtc) { + return rtc->vtable->get_compare(rtc); +} + +/*! + * @brief Set the compare value of the RTC + * @return The set compare value (not guaranteed to be exactly the requested + * value) + * + * The RTC device might impose limits on the maximum compare value or the + * granularity of the compare value. + */ +inline uint64_t metal_rtc_set_compare(const struct metal_rtc *const rtc, + const uint64_t compare) { + return rtc->vtable->set_compare(rtc, compare); +} + +/*! + * @brief Get the current count of the RTC + * @return The count + */ +inline uint64_t metal_rtc_get_count(const struct metal_rtc *const rtc) { + return rtc->vtable->get_count(rtc); +} + +/*! + * @brief Set the current count of the RTC + * @return The set value of the count (not guaranteed to be exactly the + * requested value) + * + * The RTC device might impose limits on the maximum value of the count + */ +inline uint64_t metal_rtc_set_count(const struct metal_rtc *const rtc, + const uint64_t count) { + return rtc->vtable->set_count(rtc, count); +} + +/*! + * @brief Start or stop the RTC + * @return 0 if the RTC was successfully started/stopped + */ +inline int metal_rtc_run(const struct metal_rtc *const rtc, + const enum metal_rtc_run_option option) { + return rtc->vtable->run(rtc, option); +} + +/*! + * @brief Get the interrupt handle for the RTC compare + * @return The interrupt handle + */ +inline struct metal_interrupt * +metal_rtc_get_interrupt(const struct metal_rtc *const rtc) { + return rtc->vtable->get_interrupt(rtc); +} + +/*! + * @brief Get the interrupt ID for the RTC compare + * @return The interrupt ID + */ +inline int metal_rtc_get_interrupt_id(const struct metal_rtc *const rtc) { + return rtc->vtable->get_interrupt_id(rtc); +} + +/*! + * @brief Get the handle for an RTC by index + * @return The RTC handle, or NULL if none is available at that index + */ +struct metal_rtc *metal_rtc_get_device(int index); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/scrub.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/scrub.h new file mode 100644 index 000000000..51683cc76 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/scrub.h @@ -0,0 +1,13 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__SCRUB_H +#define METAL__SCRUB_H + +/*! @brief Writes specified memory region with zeros. + * @param address Start memory address for zero-scrub. + * @param size Memory region size in bytes. + * @return None.*/ +void metal_mem_scrub(void *address, int size); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/shutdown.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/shutdown.h index 3bebfa742..7a43437b7 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/shutdown.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/shutdown.h @@ -12,15 +12,20 @@ struct __metal_shutdown; struct __metal_shutdown_vtable { - void (*exit)(const struct __metal_shutdown *sd, int code) __attribute__((noreturn)); + void (*exit)(const struct __metal_shutdown *sd, int code) + __attribute__((noreturn)); }; struct __metal_shutdown { const struct __metal_shutdown_vtable *vtable; }; -inline void __metal_shutdown_exit(const struct __metal_shutdown *sd, int code) __attribute__((noreturn)); -inline void __metal_shutdown_exit(const struct __metal_shutdown *sd, int code) { sd->vtable->exit(sd, code); } +__inline__ void __metal_shutdown_exit(const struct __metal_shutdown *sd, + int code) __attribute__((noreturn)); +__inline__ void __metal_shutdown_exit(const struct __metal_shutdown *sd, + int code) { + sd->vtable->exit(sd, code); +} /*! * @brief The public METAL shutdown interface diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/spi.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/spi.h index b011fe3ce..7e4b04ae2 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/spi.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/spi.h @@ -9,11 +9,7 @@ struct metal_spi; /*! @brief The configuration for a SPI transfer */ struct metal_spi_config { /*! @brief The protocol for the SPI transfer */ - enum { - METAL_SPI_SINGLE, - METAL_SPI_DUAL, - METAL_SPI_QUAD - } protocol; + enum { METAL_SPI_SINGLE, METAL_SPI_DUAL, METAL_SPI_QUAD } protocol; /*! @brief The polarity of the SPI transfer, equivalent to CPOL */ unsigned int polarity : 1; @@ -25,11 +21,24 @@ struct metal_spi_config { unsigned int cs_active_high : 1; /*! @brief The chip select ID to activate for the SPI transfer */ unsigned int csid; + /*! @brief The spi command frame number (cycles = num * frame_len) */ + unsigned int cmd_num; + /*! @brief The spi address frame number */ + unsigned int addr_num; + /*! @brief The spi dummy frame number */ + unsigned int dummy_num; + /*! @brief The Dual/Quad spi mode selection.*/ + enum { + MULTI_WIRE_ALL, + MULTI_WIRE_DATA_ONLY, + MULTI_WIRE_ADDR_DATA + } multi_wire; }; struct metal_spi_vtable { void (*init)(struct metal_spi *spi, int baud_rate); - int (*transfer)(struct metal_spi *spi, struct metal_spi_config *config, size_t len, char *tx_buf, char *rx_buf); + int (*transfer)(struct metal_spi *spi, struct metal_spi_config *config, + size_t len, char *tx_buf, char *rx_buf); int (*get_baud_rate)(struct metal_spi *spi); int (*set_baud_rate)(struct metal_spi *spi, int baud_rate); }; @@ -42,23 +51,29 @@ struct metal_spi { /*! @brief Get a handle for a SPI device * @param device_num The index of the desired SPI device * @return A handle to the SPI device, or NULL if the device does not exist*/ -struct metal_spi *metal_spi_get_device(int device_num); +struct metal_spi *metal_spi_get_device(unsigned int device_num); /*! @brief Initialize a SPI device with a certain baud rate * @param spi The handle for the SPI device to initialize * @param baud_rate The baud rate to set the SPI device to */ -inline void metal_spi_init(struct metal_spi *spi, int baud_rate) { spi->vtable->init(spi, baud_rate); } +__inline__ void metal_spi_init(struct metal_spi *spi, int baud_rate) { + spi->vtable->init(spi, baud_rate); +} /*! @brief Perform a SPI transfer * @param spi The handle for the SPI device to perform the transfer * @param config The configuration for the SPI transfer. * @param len The number of bytes to transfer - * @param tx_buf The buffer to send over the SPI bus. Must be len bytes long. If NULL, the SPI will transfer the value 0. - * @param rx_buf The buffer to receive data into. Must be len bytes long. If NULL, the SPI will ignore received bytes. + * @param tx_buf The buffer to send over the SPI bus. Must be len bytes long. If + * NULL, the SPI will transfer the value 0. + * @param rx_buf The buffer to receive data into. Must be len bytes long. If + * NULL, the SPI will ignore received bytes. * @return 0 if the transfer succeeds */ -inline int metal_spi_transfer(struct metal_spi *spi, struct metal_spi_config *config, size_t len, char *tx_buf, char *rx_buf) { +__inline__ int metal_spi_transfer(struct metal_spi *spi, + struct metal_spi_config *config, size_t len, + char *tx_buf, char *rx_buf) { return spi->vtable->transfer(spi, config, len, tx_buf, rx_buf); } @@ -66,13 +81,17 @@ inline int metal_spi_transfer(struct metal_spi *spi, struct metal_spi_config *co * @param spi The handle for the SPI device * @return The baud rate in Hz */ -inline int metal_spi_get_baud_rate(struct metal_spi *spi) { return spi->vtable->get_baud_rate(spi); } +__inline__ int metal_spi_get_baud_rate(struct metal_spi *spi) { + return spi->vtable->get_baud_rate(spi); +} /*! @brief Set the current baud rate of the SPI device * @param spi The handle for the SPI device * @param baud_rate The desired baud rate of the SPI device * @return 0 if the baud rate is successfully changed */ -inline int metal_spi_set_baud_rate(struct metal_spi *spi, int baud_rate) { return spi->vtable->set_baud_rate(spi, baud_rate); } +__inline__ int metal_spi_set_baud_rate(struct metal_spi *spi, int baud_rate) { + return spi->vtable->set_baud_rate(spi, baud_rate); +} #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/switch.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/switch.h index d1c35bc93..695b21ae3 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/switch.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/switch.h @@ -15,7 +15,7 @@ struct metal_switch; struct metal_switch_vtable { int (*switch_exist)(struct metal_switch *sw, char *label); - struct metal_interrupt* (*interrupt_controller)(struct metal_switch *sw); + struct metal_interrupt *(*interrupt_controller)(struct metal_switch *sw); int (*get_interrupt_id)(struct metal_switch *sw); }; @@ -29,23 +29,28 @@ struct metal_switch { /*! * @brief Get a handle for a switch * @param label The DeviceTree label for the desired switch - * @return A handle to the switch, or NULL if none is found for the requested label + * @return A handle to the switch, or NULL if none is found for the requested + * label */ -struct metal_switch* metal_switch_get(char *label); +struct metal_switch *metal_switch_get(char *label); /*! * @brief Get the interrupt controller for a switch * @param sw The handle for the switch * @return The interrupt controller handle */ -inline struct metal_interrupt* - metal_switch_interrupt_controller(struct metal_switch *sw) { return sw->vtable->interrupt_controller(sw); } +__inline__ struct metal_interrupt * +metal_switch_interrupt_controller(struct metal_switch *sw) { + return sw->vtable->interrupt_controller(sw); +} /*! * @brief Get the interrupt id for a switch * @param sw The handle for the switch * @return The interrupt ID for the switch */ -inline int metal_switch_get_interrupt_id(struct metal_switch *sw) { return sw->vtable->get_interrupt_id(sw); } +__inline__ int metal_switch_get_interrupt_id(struct metal_switch *sw) { + return sw->vtable->get_interrupt_id(sw); +} #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/time.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/time.h new file mode 100644 index 000000000..a5a880f0d --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/time.h @@ -0,0 +1,21 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__TIME_H +#define METAL__TIME_H + +#include <time.h> +#ifndef __SEGGER_LIBC__ +#include <sys/time.h> +#endif + +/*! + * @file time.h + * @brief API for dealing with time + */ + +int metal_gettimeofday(struct timeval *tp, void *tzp); + +time_t metal_time(void); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/timer.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/timer.h index eeae1f60b..5d5132de5 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/timer.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/timer.h @@ -23,9 +23,10 @@ int metal_timer_get_cyclecount(int hartid, unsigned long long *cyclecount); * @param timebase The variable to hold the value * @return 0 upon success */ -int metal_timer_get_timebase_frequency(int hartid, unsigned long long *timebase); +int metal_timer_get_timebase_frequency(int hartid, + unsigned long long *timebase); -/*! +/*! * @brief Set the machine timer tick interval in seconds * @param hartid The hart ID to read the timebase of * @param second The number of seconds to set the tick interval to diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/tty.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/tty.h index d2583e3be..5d41783ae 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/tty.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/tty.h @@ -14,10 +14,22 @@ * * Write a character to the default output device, which for most * targets is the UART serial port. - * + * * @param c The character to write to the terminal * @return 0 on success, or -1 on failure. */ -int metal_tty_putc(unsigned char c); +int metal_tty_putc(int c); + +/*! + * @brief Get a byte from the default output device + * + * The default output device, is typically the UART serial port. + * + * This call is non-blocking, if nothing is ready c==-1 + * if something is ready, then c=[0x00 to 0xff] byte value. + * + * @return 0 on success, or -1 on failure. + */ +int metal_tty_getc(int *c); #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/uart.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/uart.h index 611792a6c..856970ac2 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/uart.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/uart.h @@ -12,15 +12,25 @@ #include <metal/interrupt.h> struct metal_uart; - +#undef getc +#undef putc struct metal_uart_vtable { void (*init)(struct metal_uart *uart, int baud_rate); - int (*putc)(struct metal_uart *uart, unsigned char c); - int (*getc)(struct metal_uart *uart, unsigned char *c); + int (*putc)(struct metal_uart *uart, int c); + int (*txready)(struct metal_uart *uart); + int (*getc)(struct metal_uart *uart, int *c); int (*get_baud_rate)(struct metal_uart *uart); int (*set_baud_rate)(struct metal_uart *uart, int baud_rate); - struct metal_interrupt* (*controller_interrupt)(struct metal_uart *uart); + struct metal_interrupt *(*controller_interrupt)(struct metal_uart *uart); int (*get_interrupt_id)(struct metal_uart *uart); + int (*tx_interrupt_enable)(struct metal_uart *uart); + int (*tx_interrupt_disable)(struct metal_uart *uart); + int (*rx_interrupt_enable)(struct metal_uart *uart); + int (*rx_interrupt_disable)(struct metal_uart *uart); + int (*set_tx_watermark)(struct metal_uart *uart, size_t length); + size_t (*get_tx_watermark)(struct metal_uart *uart); + int (*set_rx_watermark)(struct metal_uart *uart, size_t length); + size_t (*get_rx_watermark)(struct metal_uart *uart); }; /*! @@ -30,16 +40,25 @@ struct metal_uart { const struct metal_uart_vtable *vtable; }; +/*! @brief Get a handle for a UART device + * @param device_num The index of the desired UART device + * @return A handle to the UART device, or NULL if the device does not exist*/ +struct metal_uart *metal_uart_get_device(unsigned int device_num); + /*! * @brief Initialize UART device - - * Initialize the UART device described by the UART handle. This function must be called before any - * other method on the UART can be invoked. It is invalid to initialize a UART more than once. + + * Initialize the UART device described by the UART handle. This function must + be called before any + * other method on the UART can be invoked. It is invalid to initialize a UART + more than once. * * @param uart The UART device handle * @param baud_rate the baud rate to set the UART to */ -inline void metal_uart_init(struct metal_uart *uart, int baud_rate) { return uart->vtable->init(uart, baud_rate); } +__inline__ void metal_uart_init(struct metal_uart *uart, int baud_rate) { + uart->vtable->init(uart, baud_rate); +} /*! * @brief Output a character over the UART @@ -47,22 +66,40 @@ inline void metal_uart_init(struct metal_uart *uart, int baud_rate) { return uar * @param c The character to send over the UART * @return 0 upon success */ -inline int metal_uart_putc(struct metal_uart *uart, unsigned char c) { return uart->vtable->putc(uart, c); } +__inline__ int metal_uart_putc(struct metal_uart *uart, int c) { + return uart->vtable->putc(uart, c); +} + +/*! + * @brief Test, determine if tx output is blocked(full/busy) + * @param uart The UART device handle + * @return 0 not blocked + */ +__inline__ int metal_uart_txready(struct metal_uart *uart) { + return uart->vtable->txready(uart); +} /*! * @brief Read a character sent over the UART * @param uart The UART device handle * @param c The varible to hold the read character * @return 0 upon success + * + * If "c == -1" no char was ready. + * If "c != -1" then C == byte value (0x00 to 0xff) */ -inline int metal_uart_getc(struct metal_uart *uart, unsigned char *c) { return uart->vtable->getc(uart, c); } +__inline__ int metal_uart_getc(struct metal_uart *uart, int *c) { + return uart->vtable->getc(uart, c); +} /*! * @brief Get the baud rate of the UART peripheral * @param uart The UART device handle * @return The current baud rate of the UART */ -inline int metal_uart_get_baud_rate(struct metal_uart *uart) { return uart->vtable->get_baud_rate(uart); } +__inline__ int metal_uart_get_baud_rate(struct metal_uart *uart) { + return uart->vtable->get_baud_rate(uart); +} /*! * @brief Set the baud rate of the UART peripheral @@ -70,7 +107,10 @@ inline int metal_uart_get_baud_rate(struct metal_uart *uart) { return uart->vtab * @param baud_rate The baud rate to configure * @return the new baud rate of the UART */ -inline int metal_uart_set_baud_rate(struct metal_uart *uart, int baud_rate) { return uart->vtable->set_baud_rate(uart, baud_rate); } +__inline__ int metal_uart_set_baud_rate(struct metal_uart *uart, + int baud_rate) { + return uart->vtable->set_baud_rate(uart, baud_rate); +} /*! * @brief Get the interrupt controller of the UART peripheral @@ -82,13 +122,94 @@ inline int metal_uart_set_baud_rate(struct metal_uart *uart, int baud_rate) { re * @param uart The UART device handle * @return The handle for the UART interrupt controller */ -inline struct metal_interrupt* metal_uart_interrupt_controller(struct metal_uart *uart) { return uart->vtable->controller_interrupt(uart); } +__inline__ struct metal_interrupt * +metal_uart_interrupt_controller(struct metal_uart *uart) { + return uart->vtable->controller_interrupt(uart); +} /*! * @brief Get the interrupt ID of the UART controller * @param uart The UART device handle * @return The UART interrupt id */ -inline int metal_uart_get_interrupt_id(struct metal_uart *uart) { return uart->vtable->get_interrupt_id(uart); } +__inline__ int metal_uart_get_interrupt_id(struct metal_uart *uart) { + return uart->vtable->get_interrupt_id(uart); +} + +/*! + * @brief Enable the UART transmit interrupt + * @param uart The UART device handle + * @return 0 upon success + */ +__inline__ int metal_uart_transmit_interrupt_enable(struct metal_uart *uart) { + return uart->vtable->tx_interrupt_enable(uart); +} + +/*! + * @brief Disable the UART transmit interrupt + * @param uart The UART device handle + * @return 0 upon success + */ +__inline__ int metal_uart_transmit_interrupt_disable(struct metal_uart *uart) { + return uart->vtable->tx_interrupt_disable(uart); +} + +/*! + * @brief Enable the UART receive interrupt + * @param uart The UART device handle + * @return 0 upon success + */ +__inline__ int metal_uart_receive_interrupt_enable(struct metal_uart *uart) { + return uart->vtable->rx_interrupt_enable(uart); +} + +/*! + * @brief Disable the UART receive interrupt + * @param uart The UART device handle + * @return 0 upon success + */ +__inline__ int metal_uart_receive_interrupt_disable(struct metal_uart *uart) { + return uart->vtable->rx_interrupt_disable(uart); +} + +/*! + * @brief Set the transmit watermark level of the UART controller + * @param uart The UART device handle + * @param level The UART transmit watermark level + * @return 0 upon success + */ +__inline__ int metal_uart_set_transmit_watermark(struct metal_uart *uart, + size_t level) { + return uart->vtable->set_tx_watermark(uart, level); +} + +/*! + * @brief Get the transmit watermark level of the UART controller + * @param uart The UART device handle + * @return The UART transmit watermark level + */ +__inline__ size_t metal_uart_get_transmit_watermark(struct metal_uart *uart) { + return uart->vtable->get_tx_watermark(uart); +} + +/*! + * @brief Set the receive watermark level of the UART controller + * @param uart The UART device handle + * @param level The UART transmit watermark level + * @return 0 upon success + */ +__inline__ int metal_uart_set_receive_watermark(struct metal_uart *uart, + size_t level) { + return uart->vtable->set_rx_watermark(uart, level); +} + +/*! + * @brief Get the receive watermark level of the UART controller + * @param uart The UART device handle + * @return The UART transmit watermark level + */ +__inline__ size_t metal_uart_get_receive_watermark(struct metal_uart *uart) { + return uart->vtable->get_rx_watermark(uart); +} #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/watchdog.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/watchdog.h new file mode 100644 index 000000000..2f84d3b49 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/install/include/metal/watchdog.h @@ -0,0 +1,168 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__WATCHDOG_H +#define METAL__WATCHDOG_H + +/*! + * @file watchdog.h + * + * @brief API for configuring watchdog timers + */ + +#include <metal/interrupt.h> + +struct metal_watchdog; + +/*! + * @brief List of watchdog timer count behaviors + */ +enum metal_watchdog_run_option { + METAL_WATCHDOG_STOP = 0, /*!< Stop the watchdog */ + METAL_WATCHDOG_RUN_ALWAYS, /*!< Run the watchdog continuously, even during + sleep */ + METAL_WATCHDOG_RUN_AWAKE, /*!< Run the watchdog only while the CPU is awake + */ +}; + +/*! + * @brief List of behaviors when a watchdog triggers + */ +enum metal_watchdog_result { + METAL_WATCHDOG_NO_RESULT = 0, /*!< When the watchdog triggers, do nothing */ + METAL_WATCHDOG_INTERRUPT, /*!< When the watchdog triggers, fire an interrupt + */ + METAL_WATCHDOG_FULL_RESET, /*!< When the watchdog triggers, cause a full + system reset */ +}; + +struct metal_watchdog_vtable { + int (*feed)(const struct metal_watchdog *const wdog); + long int (*get_rate)(const struct metal_watchdog *const wdog); + long int (*set_rate)(const struct metal_watchdog *const wdog, + const long int rate); + long int (*get_timeout)(const struct metal_watchdog *const wdog); + long int (*set_timeout)(const struct metal_watchdog *const wdog, + const long int timeout); + int (*set_result)(const struct metal_watchdog *const wdog, + const enum metal_watchdog_result result); + int (*run)(const struct metal_watchdog *const wdog, + const enum metal_watchdog_run_option option); + struct metal_interrupt *(*get_interrupt)( + const struct metal_watchdog *const wdog); + int (*get_interrupt_id)(const struct metal_watchdog *const wdog); + int (*clear_interrupt)(const struct metal_watchdog *const wdog); +}; + +/*! + * @brief Handle for a Watchdog Timer + */ +struct metal_watchdog { + const struct metal_watchdog_vtable *vtable; +}; + +/*! + * @brief Feed the watchdog timer + */ +inline int metal_watchdog_feed(const struct metal_watchdog *const wdog) { + return wdog->vtable->feed(wdog); +} + +/*! + * @brief Get the rate of the watchdog timer in Hz + * + * @return the rate of the watchdog timer + */ +inline long int +metal_watchdog_get_rate(const struct metal_watchdog *const wdog) { + return wdog->vtable->get_rate(wdog); +} + +/*! + * @brief Set the rate of the watchdog timer in Hz + * + * There is no guarantee that the new rate will match the requested rate. + * + * @return the new rate of the watchdog timer + */ +inline long int metal_watchdog_set_rate(const struct metal_watchdog *const wdog, + const long int rate) { + return wdog->vtable->set_rate(wdog, rate); +} + +/*! + * @brief Get the timeout of the watchdog timer + * + * @return the watchdog timeout value + */ +inline long int +metal_watchdog_get_timeout(const struct metal_watchdog *const wdog) { + return wdog->vtable->get_timeout(wdog); +} + +/*! + * @brief Set the timeout of the watchdog timer + * + * The set rate will be the minimimum of the requested and maximum supported + * rates. + * + * @return the new watchdog timeout value + */ +inline long int +metal_watchdog_set_timeout(const struct metal_watchdog *const wdog, + const long int timeout) { + return wdog->vtable->set_timeout(wdog, timeout); +} + +/*! + * @brief Sets the result behavior of a watchdog timer timeout + * + * @return 0 if the requested result behavior is supported + */ +inline int metal_watchdog_set_result(const struct metal_watchdog *const wdog, + const enum metal_watchdog_result result) { + return wdog->vtable->set_result(wdog, result); +} + +/*! + * @brief Set the run behavior of the watchdog + * + * Used to enable/disable the watchdog timer + * + * @return 0 if the watchdog was successfully started/stopped + */ +inline int metal_watchdog_run(const struct metal_watchdog *const wdog, + const enum metal_watchdog_run_option option) { + return wdog->vtable->run(wdog, option); +} + +/*! + * @brief Get the interrupt controller for the watchdog interrupt + */ +inline struct metal_interrupt * +metal_watchdog_get_interrupt(const struct metal_watchdog *const wdog) { + return wdog->vtable->get_interrupt(wdog); +} + +/*! + * @Brief Get the interrupt id for the watchdog interrupt + */ +inline int +metal_watchdog_get_interrupt_id(const struct metal_watchdog *const wdog) { + return wdog->vtable->get_interrupt_id(wdog); +} + +/*! + * @brief Clear the watchdog interrupt + */ +inline int +metal_watchdog_clear_interrupt(const struct metal_watchdog *const wdog) { + return wdog->vtable->clear_interrupt(wdog); +} + +/*! + * @brief Get a watchdog handle + */ +struct metal_watchdog *metal_watchdog_get_device(const int index); + +#endif /* METAL__WATCHDOG_H */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-inline.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-inline.h index 8c0cd048b..fd05ab065 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-inline.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-inline.h @@ -5,128 +5,181 @@ #ifndef ASSEMBLY -#ifndef SIFIVE_HIFIVE1_REVB____METAL_INLINE_H -#define SIFIVE_HIFIVE1_REVB____METAL_INLINE_H +#ifndef METAL_INLINE_H +#define METAL_INLINE_H #include <metal/machine.h> /* --------------------- fixed_clock ------------ */ -extern inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock); +extern __inline__ unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock); /* --------------------- fixed_factor_clock ------------ */ /* --------------------- sifive_clint0 ------------ */ -extern inline unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller); -extern inline unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller); -extern inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller); -extern inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx); -extern inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx); +extern __inline__ unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller); +extern __inline__ unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller); +extern __inline__ int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx); +extern __inline__ int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx); /* --------------------- cpu ------------ */ -extern inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu); -extern inline int __metal_driver_cpu_timebase(struct metal_cpu *cpu); -extern inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu); -extern inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu); +extern __inline__ int __metal_driver_cpu_hartid(struct metal_cpu *cpu); +extern __inline__ int __metal_driver_cpu_timebase(struct metal_cpu *cpu); +extern __inline__ struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu); +extern __inline__ int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu); +extern __inline__ struct metal_buserror * __metal_driver_cpu_buserror(struct metal_cpu *cpu); /* --------------------- sifive_plic0 ------------ */ -extern inline unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller); -extern inline unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller); -extern inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller); -extern inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller); -extern inline struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx); -extern inline int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx); +extern __inline__ unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller); +extern __inline__ unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller); +extern __inline__ int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller); +extern __inline__ int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx); +extern __inline__ int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx); +extern __inline__ int __metal_driver_sifive_plic0_context_ids(int hartid); + + +/* --------------------- sifive_buserror0 ------------ */ /* --------------------- sifive_clic0 ------------ */ /* --------------------- sifive_local_external_interrupts0 ------------ */ -extern inline struct metal_interrupt * __metal_driver_sifive_local_external_interrupts0_interrupt_parent(struct metal_interrupt *controller); -extern inline int __metal_driver_sifive_local_external_interrupts0_num_interrupts(struct metal_interrupt *controller); -extern inline int __metal_driver_sifive_local_external_interrupts0_interrupt_lines(struct metal_interrupt *controller, int idx); /* --------------------- sifive_global_external_interrupts0 ------------ */ /* --------------------- sifive_gpio0 ------------ */ -extern inline unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio); -extern inline unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio); -extern inline int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio); -extern inline struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio); -extern inline int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx); +extern __inline__ unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio); +extern __inline__ unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio); +extern __inline__ int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio); +extern __inline__ int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx); /* --------------------- sifive_gpio_button ------------ */ /* --------------------- sifive_gpio_led ------------ */ -extern inline struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led); -extern inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led); -extern inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led); +extern __inline__ struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led); +extern __inline__ int __metal_driver_sifive_gpio_led_pin(struct metal_led *led); +extern __inline__ char * __metal_driver_sifive_gpio_led_label(struct metal_led *led); /* --------------------- sifive_gpio_switch ------------ */ +/* --------------------- sifive_i2c0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_i2c0_control_base(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_control_size(struct metal_i2c *i2c); +extern __inline__ int __metal_driver_sifive_i2c0_num_interrupts(struct metal_i2c *i2c); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_i2c0_interrupt_parent(struct metal_i2c *i2c); +extern __inline__ int __metal_driver_sifive_i2c0_interrupt_line(struct metal_i2c *i2c); +extern __inline__ struct metal_clock * __metal_driver_sifive_i2c0_clock(struct metal_i2c *i2c); +extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_i2c0_pinmux(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_output_selector(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_source_selector(struct metal_i2c *i2c); + + +/* --------------------- sifive_pwm0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_pwm0_control_base(struct metal_pwm *pwm); +extern __inline__ unsigned long __metal_driver_sifive_pwm0_control_size(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_num_interrupts(struct metal_pwm *pwm); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_pwm0_interrupt_parent(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_interrupt_lines(struct metal_pwm *pwm, int idx); +extern __inline__ struct metal_clock * __metal_driver_sifive_pwm0_clock(struct metal_pwm *pwm); +extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_pwm0_pinmux(struct metal_pwm *pwm); +extern __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_output_selector(struct metal_pwm *pwm); +extern __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_source_selector(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_compare_width(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_comparator_count(struct metal_pwm *pwm); + + +/* --------------------- sifive_rtc0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_rtc0_control_base(const struct metal_rtc *const rtc); +extern __inline__ unsigned long __metal_driver_sifive_rtc0_control_size(const struct metal_rtc *const rtc); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_rtc0_interrupt_parent(const struct metal_rtc *const rtc); +extern __inline__ int __metal_driver_sifive_rtc0_interrupt_line(const struct metal_rtc *const rtc); +extern __inline__ struct metal_clock * __metal_driver_sifive_rtc0_clock(const struct metal_rtc *const rtc); + + /* --------------------- sifive_spi0 ------------ */ -extern inline unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi); -extern inline unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi); -extern inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi); -extern inline unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi); -extern inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi); +extern __inline__ unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi); +extern __inline__ unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi); +extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi); +extern __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi); +extern __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi); /* --------------------- sifive_test0 ------------ */ +/* --------------------- sifive_trace ------------ */ + /* --------------------- sifive_uart0 ------------ */ -extern inline unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart); -extern inline unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart); -extern inline int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart); -extern inline struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart); -extern inline int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart); -extern inline struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart); -extern inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart); -extern inline unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart); -extern inline unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart); +extern __inline__ unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart); +extern __inline__ unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart); +extern __inline__ int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart); +extern __inline__ int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart); +extern __inline__ struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart); +extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart); +extern __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart); +extern __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart); + + +/* --------------------- sifive_simuart0 ------------ */ + + +/* --------------------- sifive_wdog0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_wdog0_control_base(const struct metal_watchdog *const watchdog); +extern __inline__ unsigned long __metal_driver_sifive_wdog0_control_size(const struct metal_watchdog *const watchdog); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_wdog0_interrupt_parent(const struct metal_watchdog *const watchdog); +extern __inline__ int __metal_driver_sifive_wdog0_interrupt_line(const struct metal_watchdog *const watchdog); +extern __inline__ struct metal_clock * __metal_driver_sifive_wdog0_clock(const struct metal_watchdog *const watchdog); /* --------------------- sifive_fe310_g000_hfrosc ------------ */ -extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock); -extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock); -extern inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock); -extern inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock); +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock); +extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock); +extern __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock); +extern __inline__ long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock); /* --------------------- sifive_fe310_g000_hfxosc ------------ */ -extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock); -extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock); -extern inline long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock); +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock); +extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock); +extern __inline__ long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock); -/* --------------------- sifive_fe310_g000_pll ------------ */ -extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock); -extern inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock); -extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( ); -extern inline long __metal_driver_sifive_fe310_g000_pll_config_offset( ); -extern inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock); -extern inline long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock); -extern inline long __metal_driver_sifive_fe310_g000_pll_init_rate( ); +/* --------------------- sifive_fe310_g000_lfrosc ------------ */ +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(const struct metal_clock *clock); +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(const struct metal_clock *clock); +extern __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_config_reg(const struct metal_clock *clock); +extern __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(const struct metal_clock *clock); -/* --------------------- fe310_g000_prci ------------ */ -extern inline long __metal_driver_sifive_fe310_g000_prci_base( ); -extern inline long __metal_driver_sifive_fe310_g000_prci_size( ); -extern inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( ); +/* --------------------- sifive_fe310_g000_pll ------------ */ +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock); +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock); +extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( ); +extern __inline__ long __metal_driver_sifive_fe310_g000_pll_config_offset( ); +extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock); +extern __inline__ long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock); +extern __inline__ long __metal_driver_sifive_fe310_g000_pll_init_rate( ); -/* --------------------- sifive_fu540_c000_l2 ------------ */ +/* --------------------- fe310_g000_prci ------------ */ +extern __inline__ long __metal_driver_sifive_fe310_g000_prci_base( ); +extern __inline__ long __metal_driver_sifive_fe310_g000_prci_size( ); +extern __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( ); /* From clock@0 */ @@ -144,6 +197,11 @@ struct __metal_driver_fixed_clock __metal_dt_clock_5 = { .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, }; +/* From clock@6 */ +struct __metal_driver_fixed_clock __metal_dt_clock_6 = { + .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, +}; + struct metal_memory __metal_dt_mem_dtim_80000000 = { ._base_address = 2147483648UL, ._size = 16384UL, @@ -155,6 +213,17 @@ struct metal_memory __metal_dt_mem_dtim_80000000 = { .A = 1}, }; +struct metal_memory __metal_dt_mem_itim_8000000 = { + ._base_address = 134217728UL, + ._size = 8192UL, + ._attrs = { + .R = 1, + .W = 1, + .X = 1, + .C = 1, + .A = 1}, +}; + struct metal_memory __metal_dt_mem_spi_10014000 = { ._base_address = 536870912UL, ._size = 500000UL, @@ -166,6 +235,24 @@ struct metal_memory __metal_dt_mem_spi_10014000 = { .A = 1}, }; +struct metal_memory __metal_dt_mem_spi_10024000 = { + ._attrs = { + .R = 1, + .W = 1, + .X = 1, + .C = 1, + .A = 1}, +}; + +struct metal_memory __metal_dt_mem_spi_10034000 = { + ._attrs = { + .R = 1, + .W = 1, + .X = 1, + .C = 1, + .A = 1}, +}; + /* From clint@2000000 */ struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000 = { .controller.vtable = &__metal_driver_vtable_riscv_clint0.clint_vtable, @@ -175,6 +262,7 @@ struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000 = { /* From cpu@0 */ struct __metal_driver_cpu __metal_dt_cpu_0 = { .cpu.vtable = &__metal_driver_vtable_cpu.cpu_vtable, + .hpm_count = 0, }; /* From interrupt_controller */ @@ -189,42 +277,83 @@ struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000 = { .init_done = 0, }; -/* From local_external_interrupts_0 */ -struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_0 = { - .irc.vtable = &__metal_driver_vtable_sifive_local_external_interrupts0.local0_vtable, - .init_done = 0, -}; +struct metal_pmp __metal_dt_pmp; /* From gpio@10012000 */ struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000 = { .gpio.vtable = &__metal_driver_vtable_sifive_gpio0.gpio, }; -/* From led@0red */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0red = { +/* From led@0 */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0 = { .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, }; -/* From led@0green */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0green = { +/* From led@1 */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_1 = { .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, }; -/* From led@0blue */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue = { +/* From led@2 */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_2 = { .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, }; +/* From i2c@10016000 */ +struct __metal_driver_sifive_i2c0 __metal_dt_i2c_10016000 = { + .i2c.vtable = &__metal_driver_vtable_sifive_i2c0.i2c, +}; + +/* From pwm@10015000 */ +struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10015000 = { + .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm, +}; + +/* From pwm@10025000 */ +struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10025000 = { + .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm, +}; + +/* From pwm@10035000 */ +struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10035000 = { + .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm, +}; + +/* From aon@10000000 */ +struct __metal_driver_sifive_rtc0 __metal_dt_rtc_10000000 = { + .rtc.vtable = &__metal_driver_vtable_sifive_rtc0.rtc, +}; + /* From spi@10014000 */ struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000 = { .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi, }; +/* From spi@10024000 */ +struct __metal_driver_sifive_spi0 __metal_dt_spi_10024000 = { + .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi, +}; + +/* From spi@10034000 */ +struct __metal_driver_sifive_spi0 __metal_dt_spi_10034000 = { + .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi, +}; + /* From serial@10013000 */ struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000 = { .uart.vtable = &__metal_driver_vtable_sifive_uart0.uart, }; +/* From serial@10023000 */ +struct __metal_driver_sifive_uart0 __metal_dt_serial_10023000 = { + .uart.vtable = &__metal_driver_vtable_sifive_uart0.uart, +}; + +/* From aon@10000000 */ +struct __metal_driver_sifive_wdog0 __metal_dt_aon_10000000 = { + .watchdog.vtable = &__metal_driver_vtable_sifive_wdog0.watchdog, +}; + /* From clock@3 */ struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3 = { .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfrosc.clock, @@ -235,6 +364,11 @@ struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1 = { .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfxosc.clock, }; +/* From clock@7 */ +struct __metal_driver_sifive_fe310_g000_lfrosc __metal_dt_clock_7 = { + .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_lfrosc.clock, +}; + /* From clock@4 */ struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4 = { .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_pll.clock, @@ -242,8 +376,9 @@ struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4 = { /* From prci@10008000 */ struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000 = { + .vtable = &__metal_driver_vtable_sifive_fe310_g000_prci, }; -#endif /* SIFIVE_HIFIVE1_REVB____METAL_INLINE_H*/ +#endif /* METAL_INLINE_H*/ #endif /* ! ASSEMBLY */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-platform.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-platform.h index 4ecd3e336..d517b5859 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-platform.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal-platform.h @@ -3,8 +3,8 @@ /* ----------------------------------- */ /* ----------------------------------- */ -#ifndef SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H -#define SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H +#ifndef METAL_PLATFORM_H +#define METAL_PLATFORM_H /* From clock@0 */ #define METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY 16000000UL @@ -13,7 +13,10 @@ #define METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY 72000000UL /* From clock@5 */ -#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32000000UL +#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32768UL + +/* From clock@6 */ +#define METAL_FIXED_CLOCK_6_CLOCK_FREQUENCY 32768UL #define METAL_FIXED_CLOCK @@ -35,15 +38,18 @@ #define METAL_RISCV_PLIC0_0_SIZE 67108864UL #define METAL_RISCV_PLIC0_C000000_RISCV_MAX_PRIORITY 7UL #define METAL_RISCV_PLIC0_0_RISCV_MAX_PRIORITY 7UL -#define METAL_RISCV_PLIC0_C000000_RISCV_NDEV 27UL -#define METAL_RISCV_PLIC0_0_RISCV_NDEV 27UL +#define METAL_RISCV_PLIC0_C000000_RISCV_NDEV 53UL +#define METAL_RISCV_PLIC0_0_RISCV_NDEV 53UL #define METAL_RISCV_PLIC0 #define METAL_RISCV_PLIC0_PRIORITY_BASE 0UL #define METAL_RISCV_PLIC0_PENDING_BASE 4096UL #define METAL_RISCV_PLIC0_ENABLE_BASE 8192UL -#define METAL_RISCV_PLIC0_THRESHOLD 2097152UL -#define METAL_RISCV_PLIC0_CLAIM 2097156UL +#define METAL_RISCV_PLIC0_ENABLE_PER_HART 128UL +#define METAL_RISCV_PLIC0_CONTEXT_BASE 2097152UL +#define METAL_RISCV_PLIC0_CONTEXT_PER_HART 4096UL +#define METAL_RISCV_PLIC0_CONTEXT_THRESHOLD 0UL +#define METAL_RISCV_PLIC0_CONTEXT_CLAIM 4UL /* From aon@10000000 */ #define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL @@ -111,6 +117,10 @@ #define METAL_SIFIVE_FE310_G000_HFXOSC +/* From clock@7 */ + +#define METAL_SIFIVE_FE310_G000_LFROSC + /* From prci@10008000 */ #define METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS 268468224UL #define METAL_SIFIVE_FE310_G000_PRCI_0_BASE_ADDRESS 268468224UL @@ -153,11 +163,11 @@ #define METAL_SIFIVE_GPIO0_IOF_SEL 60UL #define METAL_SIFIVE_GPIO0_OUT_XOR 64UL -/* From led@0red */ +/* From led@0 */ -/* From led@0green */ +/* From led@1 */ -/* From led@0blue */ +/* From led@2 */ #define METAL_SIFIVE_GPIO_LEDS @@ -176,16 +186,24 @@ #define METAL_SIFIVE_I2C0_COMMAND 16UL #define METAL_SIFIVE_I2C0_STATUS 16UL -/* From local_external_interrupts_0 */ - -#define METAL_SIFIVE_LOCAL_EXTERNAL_INTERRUPTS0 - /* From pwm@10015000 */ #define METAL_SIFIVE_PWM0_10015000_BASE_ADDRESS 268521472UL #define METAL_SIFIVE_PWM0_0_BASE_ADDRESS 268521472UL #define METAL_SIFIVE_PWM0_10015000_SIZE 4096UL #define METAL_SIFIVE_PWM0_0_SIZE 4096UL +/* From pwm@10025000 */ +#define METAL_SIFIVE_PWM0_10025000_BASE_ADDRESS 268587008UL +#define METAL_SIFIVE_PWM0_1_BASE_ADDRESS 268587008UL +#define METAL_SIFIVE_PWM0_10025000_SIZE 4096UL +#define METAL_SIFIVE_PWM0_1_SIZE 4096UL + +/* From pwm@10035000 */ +#define METAL_SIFIVE_PWM0_10035000_BASE_ADDRESS 268652544UL +#define METAL_SIFIVE_PWM0_2_BASE_ADDRESS 268652544UL +#define METAL_SIFIVE_PWM0_10035000_SIZE 4096UL +#define METAL_SIFIVE_PWM0_2_SIZE 4096UL + #define METAL_SIFIVE_PWM0 #define METAL_SIFIVE_PWM0_PWMCFG 0UL #define METAL_SIFIVE_PWM0_PWMCOUNT 8UL @@ -195,12 +213,37 @@ #define METAL_SIFIVE_PWM0_PWMCMP2 40UL #define METAL_SIFIVE_PWM0_PWMCMP3 44UL +/* From aon@10000000 */ +#define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL +#define METAL_SIFIVE_AON0_0_BASE_ADDRESS 268435456UL +#define METAL_SIFIVE_AON0_10000000_SIZE 32768UL +#define METAL_SIFIVE_AON0_0_SIZE 32768UL + +#define METAL_SIFIVE_RTC0 +#define METAL_SIFIVE_RTC0_RTCCFG 64UL +#define METAL_SIFIVE_RTC0_RTCCOUNTLO 72UL +#define METAL_SIFIVE_RTC0_RTCCOUNTHI 76UL +#define METAL_SIFIVE_RTC0_RTCS 80UL +#define METAL_SIFIVE_RTC0_RTCCMP0 96UL + /* From spi@10014000 */ #define METAL_SIFIVE_SPI0_10014000_BASE_ADDRESS 268517376UL #define METAL_SIFIVE_SPI0_0_BASE_ADDRESS 268517376UL #define METAL_SIFIVE_SPI0_10014000_SIZE 4096UL #define METAL_SIFIVE_SPI0_0_SIZE 4096UL +/* From spi@10024000 */ +#define METAL_SIFIVE_SPI0_10024000_BASE_ADDRESS 268582912UL +#define METAL_SIFIVE_SPI0_1_BASE_ADDRESS 268582912UL +#define METAL_SIFIVE_SPI0_10024000_SIZE 4096UL +#define METAL_SIFIVE_SPI0_1_SIZE 4096UL + +/* From spi@10034000 */ +#define METAL_SIFIVE_SPI0_10034000_BASE_ADDRESS 268648448UL +#define METAL_SIFIVE_SPI0_2_BASE_ADDRESS 268648448UL +#define METAL_SIFIVE_SPI0_10034000_SIZE 4096UL +#define METAL_SIFIVE_SPI0_2_SIZE 4096UL + #define METAL_SIFIVE_SPI0 #define METAL_SIFIVE_SPI0_SCKDIV 0UL #define METAL_SIFIVE_SPI0_SCKMODE 4UL @@ -225,6 +268,12 @@ #define METAL_SIFIVE_UART0_10013000_SIZE 4096UL #define METAL_SIFIVE_UART0_0_SIZE 4096UL +/* From serial@10023000 */ +#define METAL_SIFIVE_UART0_10023000_BASE_ADDRESS 268578816UL +#define METAL_SIFIVE_UART0_1_BASE_ADDRESS 268578816UL +#define METAL_SIFIVE_UART0_10023000_SIZE 4096UL +#define METAL_SIFIVE_UART0_1_SIZE 4096UL + #define METAL_SIFIVE_UART0 #define METAL_SIFIVE_UART0_TXDATA 0UL #define METAL_SIFIVE_UART0_RXDATA 4UL @@ -234,4 +283,20 @@ #define METAL_SIFIVE_UART0_IP 20UL #define METAL_SIFIVE_UART0_DIV 24UL -#endif /* SIFIVE_HIFIVE1_REVB____METAL_PLATFORM_H*/ +/* From aon@10000000 */ +#define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL +#define METAL_SIFIVE_AON0_0_BASE_ADDRESS 268435456UL +#define METAL_SIFIVE_AON0_10000000_SIZE 32768UL +#define METAL_SIFIVE_AON0_0_SIZE 32768UL + +#define METAL_SIFIVE_WDOG0 +#define METAL_SIFIVE_WDOG0_MAGIC_KEY 5370206UL +#define METAL_SIFIVE_WDOG0_MAGIC_FOOD 218755085UL +#define METAL_SIFIVE_WDOG0_WDOGCFG 0UL +#define METAL_SIFIVE_WDOG0_WDOGCOUNT 8UL +#define METAL_SIFIVE_WDOG0_WDOGS 16UL +#define METAL_SIFIVE_WDOG0_WDOGFEED 24UL +#define METAL_SIFIVE_WDOG0_WDOGKEY 28UL +#define METAL_SIFIVE_WDOG0_WDOGCMP 32UL + +#endif /* METAL_PLATFORM_H*/ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.default.lds b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.default.lds index 7070af7e8..be7f84c71 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.default.lds +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.default.lds @@ -1,236 +1,302 @@ -/* Copyright 2019 SiFive, Inc */ +/* Copyright (c) 2020 SiFive Inc. */ /* SPDX-License-Identifier: Apache-2.0 */ -/* ----------------------------------- */ -/* ----------------------------------- */ - OUTPUT_ARCH("riscv") +/* Default Linker Script + * + * This is the default linker script for all Freedom Metal applications. + */ + ENTRY(_enter) MEMORY { - ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 0x4000 - flash (rxai!w) : ORIGIN = 0x20010000, LENGTH = 0x6a120 + itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000 + ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000 + rom (irx!wa) : ORIGIN = 0x20010000, LENGTH = 0x6a120 } PHDRS { - flash PT_LOAD; - ram_init PT_LOAD; - itim_init PT_LOAD; - ram PT_NULL; - itim PT_NULL; + rom PT_LOAD; + ram_init PT_LOAD; + tls PT_TLS; + ram PT_LOAD; + itim_init PT_LOAD; + text PT_LOAD; + lim_init PT_LOAD; } SECTIONS { - __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400; - PROVIDE(__stack_size = __stack_size); - __heap_size = DEFINED(__heap_size) ? __heap_size : 0x4; - PROVIDE(__metal_boot_hart = 0); - PROVIDE(__metal_chicken_bit = 0); - - - .init : - { - KEEP (*(.text.metal.init.enter)) - KEEP (*(SORT_NONE(.init))) - KEEP (*(.text.libgloss.start)) - } >flash AT>flash :flash - - - .text : - { - *(.text.unlikely .text.unlikely.*) - *(.text.startup .text.startup.*) - *(.text .text.*) - *(.itim .itim.*) - *(.gnu.linkonce.t.*) - } >flash AT>flash :flash - - - .fini : - { - KEEP (*(SORT_NONE(.fini))) - } >flash AT>flash :flash - - - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - - - .rodata : - { - *(.rdata) - *(.rodata .rodata.*) - *(.gnu.linkonce.r.*) - . = ALIGN(8); - *(.srodata.cst16) - *(.srodata.cst8) - *(.srodata.cst4) - *(.srodata.cst2) - *(.srodata .srodata.*) - } >flash AT>flash :flash - - - . = ALIGN(4); - - - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >flash AT>flash :flash - - - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) - KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) - PROVIDE_HIDDEN (__init_array_end = .); - } >flash AT>flash :flash - - - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) - KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) - PROVIDE_HIDDEN (__fini_array_end = .); - } >flash AT>flash :flash - - - .ctors : - { - /* gcc uses crtbegin.o to find the start of - the constructors, so we make sure it is - first. Because this is a wildcard, it - doesn't matter if the user does not - actually link against crtbegin.o; the - linker won't look for a file to match a - wildcard. The wildcard also means that it - doesn't matter which directory crtbegin.o - is in. */ - KEEP (*crtbegin.o(.ctors)) - KEEP (*crtbegin?.o(.ctors)) - /* We don't want to include the .ctor section from - the crtend.o file until after the sorted ctors. - The .ctor section from the crtend file contains the - end of ctors marker and it must be last */ - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - } >flash AT>flash :flash - - - .dtors : - { - KEEP (*crtbegin.o(.dtors)) - KEEP (*crtbegin?.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - } >flash AT>flash :flash - - - .litimalign : - { - . = ALIGN(4); - PROVIDE( metal_segment_itim_source_start = . ); - } >flash AT>flash :flash - - - .ditimalign : - { - . = ALIGN(4); - PROVIDE( metal_segment_itim_target_start = . ); - } >ram AT>flash :ram_init - - - .itim : - { - *(.itim .itim.*) - } >flash AT>flash :flash - - - . = ALIGN(8); - PROVIDE( metal_segment_itim_target_end = . ); - - - .lalign : - { - . = ALIGN(4); - PROVIDE( _data_lma = . ); - PROVIDE( metal_segment_data_source_start = . ); - } >flash AT>flash :flash - - - .dalign : - { - . = ALIGN(4); - PROVIDE( metal_segment_data_target_start = . ); - } >ram AT>flash :ram_init - - - .data : - { - *(.data .data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - PROVIDE( __global_pointer$ = . + 0x800 ); - *(.sdata .sdata.* .sdata2.*) - *(.gnu.linkonce.s.*) - } >ram AT>flash :ram_init - - - . = ALIGN(4); - PROVIDE( _edata = . ); - PROVIDE( edata = . ); - PROVIDE( metal_segment_data_target_end = . ); - PROVIDE( _fbss = . ); - PROVIDE( __bss_start = . ); - PROVIDE( metal_segment_bss_target_start = . ); - - - .bss : - { - *(.sbss*) - *(.gnu.linkonce.sb.*) - *(.bss .bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN(4); - } >ram AT>ram :ram - - - . = ALIGN(8); - PROVIDE( _end = . ); - PROVIDE( end = . ); - PROVIDE( metal_segment_bss_target_end = . ); - - .stack : - { - . = ALIGN(16); - metal_segment_stack_begin = .; - . += __stack_size; - . = ALIGN(16); - _sp = .; - PROVIDE(metal_segment_stack_end = .); - __freertos_irq_stack_top = .; - } >ram AT>ram :ram - - - .heap : - { - PROVIDE( metal_segment_heap_target_start = . ); - . = __heap_size; - PROVIDE( metal_segment_heap_target_end = . ); - PROVIDE( _heap_end = . ); - } >ram AT>ram :ram - - -} - + /* Each hart is allocated its own stack of size __stack_size. This value + * can be overriden at build-time by adding the following to CFLAGS: + * + * -Xlinker --defsym=__stack_size=0xf00 + * + * where 0xf00 can be replaced with a multiple of 16 of your choice. + * + * __stack_size is PROVIDE-ed as a symbol so that initialization code + * initializes the stack pointers for each hart at the right offset from + * the _sp symbol. + */ + __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400; + PROVIDE(__stack_size = __stack_size); + + /* The size of the heap can be overriden at build-time by adding the + * following to CFLAGS: + * + * -Xlinker --defsym=__heap_size=0xf00 + * + * where 0xf00 can be replaced with the value of your choice. + * + * Altertatively, the heap can be grown to fill the entire remaining region + * of RAM by adding the following to CFLAGS: + * + * -Xlinker --defsym=__heap_max=1 + * + * Note that depending on the memory layout, the bitness (32/64bit) of the + * target, and the code model in use, this might cause a relocation error. + */ + __heap_size = DEFINED(__heap_size) ? __heap_size : 0x800; + + /* The boot hart sets which hart runs the pre-main initialization routines, + * including copying .data into RAM, zeroing the BSS region, running + * constructors, etc. After initialization, the boot hart is also the only + * hart which runs application code unless the application overrides the + * secondary_main() function to start execution on secondary harts. + */ + PROVIDE(__metal_boot_hart = 0); + + /* The chicken bit is used by pre-main initialization to enable/disable + * certain core features */ + PROVIDE(__metal_chicken_bit = 1); + + /* The memory_ecc_scrub bit is used by _entry code to enable/disable + * memories scrubbing to zero */ + PROVIDE(__metal_eccscrub_bit = 0); + + /* The RAM memories map for ECC scrubbing */ + PROVIDE( metal_dtim_0_memory_start = 0x80000000 ); + PROVIDE( metal_dtim_0_memory_end = 0x80000000 + 0x4000 ); + PROVIDE( metal_itim_0_memory_start = 0x8000000 ); + PROVIDE( metal_itim_0_memory_end = 0x8000000 + 0x2000 ); + + /* ROM SECTION + * + * The following sections contain data which lives in read-only memory, if + * such memory is present in the design, for the entire duration of program + * execution. + */ + + .init : { + /* The _enter symbol is placed in the .text.metal.init.enter section + * and must be placed at the beginning of the program */ + KEEP (*(.text.metal.init.enter)) + KEEP (*(.text.metal.init.*)) + KEEP (*(SORT_NONE(.init))) + KEEP (*(.text.libgloss.start)) + } >rom :rom + + .fini : { + KEEP (*(SORT_NONE(.fini))) + } >rom :rom + + .preinit_array : ALIGN(8) { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >rom :rom + + .init_array : ALIGN(8) { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE_HIDDEN ( metal_constructors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.metal.init_array.*))); + KEEP (*(.metal.init_array)); + PROVIDE_HIDDEN ( metal_constructors_end = .); + } >rom :rom + + .fini_array : ALIGN(8) { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + PROVIDE_HIDDEN ( metal_destructors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.metal.fini_array.*))); + KEEP (*(.metal.fini_array)); + PROVIDE_HIDDEN ( metal_destructors_end = .); + } >rom :rom + + + + .ctors : { + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + KEEP (*(.metal.ctors .metal.ctors.*)) + } >rom :rom + + .dtors : { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + KEEP (*(.metal.dtors .metal.dtors.*)) + } >rom : rom + + .rodata : { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >rom :rom + + /* ITIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into an instruction tightly-integrated memory (ITIM), if one + * is present in the design, during pre-main program initialization. + * + * Generally, the data copied into the ITIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ + + .itim : ALIGN(8) { + *(.itim .itim.*) + } >itim AT>rom :itim_init + + PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) ); + PROVIDE( metal_segment_itim_target_start = ADDR(.itim) ); + PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) ); + + /* LIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a loosely integrated memory (LIM), which is shared with L2 + * cache, during pre-main program initialization. + * + * Generally, the data copied into the LIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ + + .lim : ALIGN(8) { + *(.lim .lim.*) + } >ram AT>rom :lim_init + + PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) ); + PROVIDE( metal_segment_lim_target_start = ADDR(.lim) ); + PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) ); + + /* TEXT SECTION + * + * The following section contains the code of the program, excluding + * everything that's been allocated into the ITIM/LIM already + */ + + .text : { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >rom :text + + /* RAM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a read-write-capable memory such as data tightly-integrated + * memory (DTIM) or another main memory, as well as the BSS, stack, and + * heap. + * + * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all + * have an apparently unnecessary ALIGN at their top. This is because + * the implementation of _start in Freedom Metal libgloss depends on the + * ADDR and LOADADDR being 8-byte aligned. + */ + + .data : ALIGN(8) { + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.s.*) + } >ram AT>rom :ram_init + + .tdata : ALIGN(8) { + PROVIDE( __tls_base = . ); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } >ram AT>rom :tls :ram_init + + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tdata_size = SIZEOF(.tdata) ); + + PROVIDE( metal_segment_data_source_start = LOADADDR(.data) ); + PROVIDE( metal_segment_data_target_start = ADDR(.data) ); + PROVIDE( metal_segment_data_target_end = ADDR(.tdata) + SIZEOF(.tdata) ); + + .tbss : ALIGN(8) { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon .tcommon.*) + PROVIDE( __tls_end = . ); + } >ram AT>ram :tls :ram + PROVIDE( __tbss_size = SIZEOF(.tbss) ); + PROVIDE( __tls_size = __tls_end - __tls_base ); + + .tbss_space : ALIGN(8) { + . = . + __tbss_size; + } >ram :ram + + .bss (NOLOAD): ALIGN(8) { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + } >ram :ram + + PROVIDE( metal_segment_bss_source_start = LOADADDR(.tbss) ); + PROVIDE( metal_segment_bss_target_start = ADDR(.tbss) ); + PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) ); + + + + .stack (NOLOAD) : ALIGN(16) { + PROVIDE(metal_segment_stack_begin = .); + . += __stack_size; /* Hart 0 */ + PROVIDE( _sp = . ); + __freertos_irq_stack_top = .; + PROVIDE(metal_segment_stack_end = .); + } >ram :ram + + .heap (NOLOAD) : ALIGN(8) { + PROVIDE( __end = . ); + PROVIDE( __heap_start = . ); + PROVIDE( metal_segment_heap_target_start = . ); + /* If __heap_max is defined, grow the heap to use the rest of RAM, + * otherwise set the heap size to __heap_size */ + . = DEFINED(__heap_max) ? MIN( LENGTH(ram) - ( . - ORIGIN(ram)) , 0x10000000) : __heap_size; + PROVIDE( metal_segment_heap_target_end = . ); + PROVIDE( _heap_end = . ); + PROVIDE( __heap_end = . ); + } >ram :ram + + /* C++ exception handling information is + * not useful with our current runtime environment, + * and it consumes flash space. Discard it until + * we have something that can use it + */ + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + } +}
\ No newline at end of file diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.freertos.lds b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.freertos.lds new file mode 100644 index 000000000..4798504ed --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.freertos.lds @@ -0,0 +1,327 @@ +/* Copyright (c) 2020 SiFive Inc. */ +/* SPDX-License-Identifier: Apache-2.0 */ +OUTPUT_ARCH("riscv") + +/* Privileged mode Linker Script + * + * This linker script is based on metal.default.lds. It introduce specific + * section to isolate (acessible only from machine mode) and others that can be + * used in every execution mode. This linker script it tailored for FreeRTOS + * applications. + */ + +ENTRY(_enter) + +MEMORY +{ + itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000 + ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000 + rom (irx!wa) : ORIGIN = 0x20010000, LENGTH = 0x6a120 +} + +PHDRS +{ + rom PT_LOAD; + ram_init PT_LOAD; + tls PT_TLS; + ram PT_LOAD; + itim_init PT_LOAD; + text PT_LOAD; + lim_init PT_LOAD; +} + +SECTIONS +{ + /* Each hart is allocated its own stack of size __stack_size. This value + * can be overriden at build-time by adding the following to CFLAGS: + * + * -Xlinker --defsym=__stack_size=0xf00 + * + * where 0xf00 can be replaced with a multiple of 16 of your choice. + * + * __stack_size is PROVIDE-ed as a symbol so that initialization code + * initializes the stack pointers for each hart at the right offset from + * the _sp symbol. + */ + __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400; + PROVIDE(__stack_size = __stack_size); + + /* The size of the heap can be overriden at build-time by adding the + * following to CFLAGS: + * + * -Xlinker --defsym=__heap_size=0xf00 + * + * where 0xf00 can be replaced with the value of your choice. + * + * Altertatively, the heap can be grown to fill the entire remaining region + * of RAM by adding the following to CFLAGS: + * + * -Xlinker --defsym=__heap_max=1 + * + * Note that depending on the memory layout, the bitness (32/64bit) of the + * target, and the code model in use, this might cause a relocation error. + */ + __heap_size = DEFINED(__heap_size) ? __heap_size : 0x800; + + /* The boot hart sets which hart runs the pre-main initialization routines, + * including copying .data into RAM, zeroing the BSS region, running + * constructors, etc. After initialization, the boot hart is also the only + * hart which runs application code unless the application overrides the + * secondary_main() function to start execution on secondary harts. + */ + PROVIDE(__metal_boot_hart = 0); + + /* The chicken bit is used by pre-main initialization to enable/disable + * certain core features */ + PROVIDE(__metal_chicken_bit = 1); + + /* The memory_ecc_scrub bit is used by _entry code to enable/disable + * memories scrubbing to zero */ + PROVIDE(__metal_eccscrub_bit = 0); + + /* The RAM memories map for ECC scrubbing */ + PROVIDE( metal_dtim_0_memory_start = 0x80000000 ); + PROVIDE( metal_dtim_0_memory_end = 0x80000000 + 0x4000 ); + PROVIDE( metal_itim_0_memory_start = 0x8000000 ); + PROVIDE( metal_itim_0_memory_end = 0x8000000 + 0x2000 ); + + /* ROM SECTION + * + * The following sections contain data which lives in read-only memory, if + * such memory is present in the design, for the entire duration of program + * execution. + */ + + .init : { + /* The _enter symbol is placed in the .text.metal.init.enter section + * and must be placed at the beginning of the program */ + KEEP (*(.text.metal.init.enter)) + KEEP (*(.text.metal.init.*)) + KEEP (*(SORT_NONE(.init))) + KEEP (*(.text.libgloss.start)) + } >rom :rom + + .fini : { + KEEP (*(SORT_NONE(.fini))) + } >rom :rom + + .preinit_array : ALIGN(8) { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >rom :rom + + .init_array : ALIGN(8) { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE_HIDDEN ( metal_constructors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.metal.init_array.*))); + KEEP (*(.metal.init_array)); + PROVIDE_HIDDEN ( metal_constructors_end = .); + } >rom :rom + + .fini_array : ALIGN(8) { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + PROVIDE_HIDDEN ( metal_destructors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.metal.fini_array.*))); + KEEP (*(.metal.fini_array)); + PROVIDE_HIDDEN ( metal_destructors_end = .); + } >rom :rom + + .privileged_functions : ALIGN (32) { + __privileged_functions_start__ = .; + KEEP(*(privileged_functions)) + . = ALIGN(32); + __privileged_functions_end__ = .; + } >rom + + + .ctors : { + . = ALIGN(32); + __unprivileged_section_start__ = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + KEEP (*(.metal.ctors .metal.ctors.*)) + } >rom :rom + + .dtors : { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + KEEP (*(.metal.dtors .metal.dtors.*)) + } >rom : rom + + .rodata : { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >rom :rom + + /* ITIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into an instruction tightly-integrated memory (ITIM), if one + * is present in the design, during pre-main program initialization. + * + * Generally, the data copied into the ITIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ + + .itim : ALIGN(8) { + *(.itim .itim.*) + } >itim AT>rom :itim_init + + PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) ); + PROVIDE( metal_segment_itim_target_start = ADDR(.itim) ); + PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) ); + + /* LIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a loosely integrated memory (LIM), which is shared with L2 + * cache, during pre-main program initialization. + * + * Generally, the data copied into the LIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ + + .lim : ALIGN(8) { + *(.lim .lim.*) + } >ram AT>rom :lim_init + + PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) ); + PROVIDE( metal_segment_lim_target_start = ADDR(.lim) ); + PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) ); + + /* TEXT SECTION + * + * The following section contains the code of the program, excluding + * everything that's been allocated into the ITIM/LIM already + */ + + .text : { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + *(freertos_system_calls) + . = ALIGN(32); + __unprivileged_section_end__ = .; + } >rom :text + + /* RAM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a read-write-capable memory such as data tightly-integrated + * memory (DTIM) or another main memory, as well as the BSS, stack, and + * heap. + * + * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all + * have an apparently unnecessary ALIGN at their top. This is because + * the implementation of _start in Freedom Metal libgloss depends on the + * ADDR and LOADADDR being 8-byte aligned. + */ + + .data : ALIGN(8) { + . = ALIGN(32); + __unprivileged_data_section_start__ = .; + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.s.*) + } >ram AT>rom :ram_init + + .tdata : ALIGN(8) { + PROVIDE( __tls_base = . ); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } >ram AT>rom :tls :ram_init + + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tdata_size = SIZEOF(.tdata) ); + + PROVIDE( metal_segment_data_source_start = LOADADDR(.data) ); + PROVIDE( metal_segment_data_target_start = ADDR(.data) ); + PROVIDE( metal_segment_data_target_end = ADDR(.tdata) + SIZEOF(.tdata) ); + + .tbss : ALIGN(8) { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon .tcommon.*) + PROVIDE( __tls_end = . ); + } >ram AT>ram :tls :ram + PROVIDE( __tbss_size = SIZEOF(.tbss) ); + PROVIDE( __tls_size = __tls_end - __tls_base ); + + .tbss_space : ALIGN(8) { + . = . + __tbss_size; + } >ram :ram + + .bss (NOLOAD): ALIGN(8) { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(32); + __unprivileged_data_section_end__ = .; + } >ram :ram + + PROVIDE( metal_segment_bss_source_start = LOADADDR(.tbss) ); + PROVIDE( metal_segment_bss_target_start = ADDR(.tbss) ); + PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) ); + + .privileged_data (NOLOAD) : ALIGN(32) { + __privileged_data_start__ = .; + *(privileged_data) + /* Non kernel data is kept out of the first _Privileged_Data_Region_Size + bytes of SRAM. */ + . = ALIGN(32); + __privileged_data_end__ = .; + } >ram + + + .stack (NOLOAD) : ALIGN(16) { + PROVIDE(metal_segment_stack_begin = .); + . += __stack_size; /* Hart 0 */ + PROVIDE( _sp = . ); + PROVIDE(metal_segment_stack_end = .); + } >ram :ram + + .heap (NOLOAD) : ALIGN(8) { + PROVIDE( __end = . ); + PROVIDE( __heap_start = . ); + PROVIDE( metal_segment_heap_target_start = . ); + /* If __heap_max is defined, grow the heap to use the rest of RAM, + * otherwise set the heap size to __heap_size */ + . = DEFINED(__heap_max) ? MIN( LENGTH(ram) - ( . - ORIGIN(ram)) , 0x10000000) : __heap_size; + PROVIDE( metal_segment_heap_target_end = . ); + PROVIDE( _heap_end = . ); + PROVIDE( __heap_end = . ); + } >ram :ram + + /* C++ exception handling information is + * not useful with our current runtime environment, + * and it consumes flash space. Discard it until + * we have something that can use it + */ + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + } +}
\ No newline at end of file diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.h index f76dbd632..74c361b4b 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.h @@ -9,15 +9,15 @@ #ifdef __METAL_MACHINE_MACROS -#ifndef MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H -#define MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H +#ifndef MACROS_IF_METAL_H +#define MACROS_IF_METAL_H #define __METAL_CLINT_NUM_PARENTS 2 #ifndef __METAL_CLINT_NUM_PARENTS #define __METAL_CLINT_NUM_PARENTS 0 #endif -#define __METAL_PLIC_SUBINTERRUPTS 27 +#define __METAL_PLIC_SUBINTERRUPTS 53 #define __METAL_PLIC_NUM_PARENTS 1 @@ -31,12 +31,12 @@ #define __METAL_CLIC_SUBINTERRUPTS 0 #endif -#endif /* MACROS_IF_SIFIVE_HIFIVE1_REVB____METAL_H*/ +#endif /* MACROS_IF_METAL_H*/ #else /* ! __METAL_MACHINE_MACROS */ -#ifndef MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H -#define MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H +#ifndef MACROS_ELSE_METAL_H +#define MACROS_ELSE_METAL_H #define __METAL_CLINT_2000000_INTERRUPTS 2 @@ -46,7 +46,7 @@ #define __METAL_INTERRUPT_CONTROLLER_C000000_INTERRUPTS 1 -#define __METAL_PLIC_SUBINTERRUPTS 27 +#define __METAL_PLIC_SUBINTERRUPTS 53 #define METAL_MAX_PLIC_INTERRUPTS 1 @@ -55,20 +55,36 @@ #define __METAL_CLIC_SUBINTERRUPTS 0 #define METAL_MAX_CLIC_INTERRUPTS 0 -#define __METAL_LOCAL_EXTERNAL_INTERRUPTS_0_INTERRUPTS 16 - -#define METAL_MAX_LOCAL_EXT_INTERRUPTS 16 +#define METAL_MAX_LOCAL_EXT_INTERRUPTS 0 #define METAL_MAX_GLOBAL_EXT_INTERRUPTS 0 -#define __METAL_GPIO_10012000_INTERRUPTS 16 +#define __METAL_GPIO_10012000_INTERRUPTS 32 + +#define METAL_MAX_GPIO_INTERRUPTS 32 + +#define __METAL_I2C_10016000_INTERRUPTS 1 + +#define METAL_MAX_I2C0_INTERRUPTS 1 + +#define __METAL_PWM_10015000_INTERRUPTS 4 -#define METAL_MAX_GPIO_INTERRUPTS 16 +#define __METAL_PWM_10025000_INTERRUPTS 4 + +#define __METAL_PWM_10035000_INTERRUPTS 4 + +#define METAL_MAX_PWM0_INTERRUPTS 4 + +#define METAL_MAX_PWM0_NCMP 4 #define __METAL_SERIAL_10013000_INTERRUPTS 1 +#define __METAL_SERIAL_10023000_INTERRUPTS 1 + #define METAL_MAX_UART_INTERRUPTS 1 +#define METAL_MAX_SIMUART_INTERRUPTS 0 + #include <metal/drivers/fixed-clock.h> #include <metal/memory.h> @@ -76,79 +92,119 @@ #include <metal/drivers/riscv_cpu.h> #include <metal/drivers/riscv_plic0.h> #include <metal/pmp.h> -#include <metal/drivers/sifive_local-external-interrupts0.h> #include <metal/drivers/sifive_gpio0.h> #include <metal/drivers/sifive_gpio-leds.h> +#include <metal/drivers/sifive_i2c0.h> +#include <metal/drivers/sifive_pwm0.h> +#include <metal/drivers/sifive_rtc0.h> #include <metal/drivers/sifive_spi0.h> #include <metal/drivers/sifive_uart0.h> +#include <metal/drivers/sifive_wdog0.h> #include <metal/drivers/sifive_fe310-g000_hfrosc.h> #include <metal/drivers/sifive_fe310-g000_hfxosc.h> +#include <metal/drivers/sifive_fe310-g000_lfrosc.h> #include <metal/drivers/sifive_fe310-g000_pll.h> #include <metal/drivers/sifive_fe310-g000_prci.h> /* From clock@0 */ -struct __metal_driver_fixed_clock __metal_dt_clock_0; +extern struct __metal_driver_fixed_clock __metal_dt_clock_0; /* From clock@2 */ -struct __metal_driver_fixed_clock __metal_dt_clock_2; +extern struct __metal_driver_fixed_clock __metal_dt_clock_2; /* From clock@5 */ -struct __metal_driver_fixed_clock __metal_dt_clock_5; +extern struct __metal_driver_fixed_clock __metal_dt_clock_5; + +/* From clock@6 */ +extern struct __metal_driver_fixed_clock __metal_dt_clock_6; + +extern struct metal_memory __metal_dt_mem_dtim_80000000; + +extern struct metal_memory __metal_dt_mem_itim_8000000; -struct metal_memory __metal_dt_mem_dtim_80000000; +extern struct metal_memory __metal_dt_mem_spi_10014000; -struct metal_memory __metal_dt_mem_spi_10014000; +extern struct metal_memory __metal_dt_mem_spi_10024000; + +extern struct metal_memory __metal_dt_mem_spi_10034000; /* From clint@2000000 */ -struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000; +extern struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000; /* From cpu@0 */ -struct __metal_driver_cpu __metal_dt_cpu_0; +extern struct __metal_driver_cpu __metal_dt_cpu_0; -struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller; +extern struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller; /* From interrupt_controller@c000000 */ -struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000; - -struct metal_pmp __metal_dt_pmp; +extern struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000; -/* From local_external_interrupts_0 */ -struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_0; +extern struct metal_pmp __metal_dt_pmp; /* From gpio@10012000 */ -struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000; +extern struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000; + +/* From led@0 */ +extern struct __metal_driver_sifive_gpio_led __metal_dt_led_0; + +/* From led@1 */ +extern struct __metal_driver_sifive_gpio_led __metal_dt_led_1; -/* From led@0red */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0red; +/* From led@2 */ +extern struct __metal_driver_sifive_gpio_led __metal_dt_led_2; -/* From led@0green */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0green; +/* From i2c@10016000 */ +extern struct __metal_driver_sifive_i2c0 __metal_dt_i2c_10016000; -/* From led@0blue */ -struct __metal_driver_sifive_gpio_led __metal_dt_led_0blue; +/* From pwm@10015000 */ +extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10015000; + +/* From pwm@10025000 */ +extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10025000; + +/* From pwm@10035000 */ +extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10035000; + +/* From aon@10000000 */ +extern struct __metal_driver_sifive_rtc0 __metal_dt_rtc_10000000; /* From spi@10014000 */ -struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000; +extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000; + +/* From spi@10024000 */ +extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10024000; + +/* From spi@10034000 */ +extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10034000; /* From serial@10013000 */ -struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000; +extern struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000; + +/* From serial@10023000 */ +extern struct __metal_driver_sifive_uart0 __metal_dt_serial_10023000; + +/* From aon@10000000 */ +extern struct __metal_driver_sifive_wdog0 __metal_dt_aon_10000000; /* From clock@3 */ -struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3; +extern struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3; /* From clock@1 */ -struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1; +extern struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1; + +/* From clock@7 */ +extern struct __metal_driver_sifive_fe310_g000_lfrosc __metal_dt_clock_7; /* From clock@4 */ -struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4; +extern struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4; /* From prci@10008000 */ -struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000; +extern struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000; /* --------------------- fixed_clock ------------ */ -static inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock) +static __inline__ unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock) { if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_0) { return METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY; @@ -159,6 +215,9 @@ static inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_c else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_5) { return METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY; } + else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_6) { + return METAL_FIXED_CLOCK_6_CLOCK_FREQUENCY; + } else { return 0; } @@ -170,7 +229,7 @@ static inline unsigned long __metal_driver_fixed_clock_rate(const struct metal_c /* --------------------- sifive_clint0 ------------ */ -static inline unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller) +static __inline__ unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller) { if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) { return METAL_RISCV_CLINT0_2000000_BASE_ADDRESS; @@ -180,7 +239,7 @@ static inline unsigned long __metal_driver_sifive_clint0_control_base(struct met } } -static inline unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller) +static __inline__ unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller) { if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) { return METAL_RISCV_CLINT0_2000000_SIZE; @@ -190,7 +249,7 @@ static inline unsigned long __metal_driver_sifive_clint0_control_size(struct met } } -static inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller) +static __inline__ int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller) { if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) { return METAL_MAX_CLINT_INTERRUPTS; @@ -200,7 +259,7 @@ static inline int __metal_driver_sifive_clint0_num_interrupts(struct metal_inter } } -static inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx) +static __inline__ struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx) { if (idx == 0) { return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller; @@ -213,7 +272,7 @@ static inline struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_pa } } -static inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx) +static __inline__ int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx) { if (idx == 0) { return 3; @@ -229,7 +288,7 @@ static inline int __metal_driver_sifive_clint0_interrupt_lines(struct metal_inte /* --------------------- cpu ------------ */ -static inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu) +static __inline__ int __metal_driver_cpu_hartid(struct metal_cpu *cpu) { if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { return 0; @@ -239,17 +298,17 @@ static inline int __metal_driver_cpu_hartid(struct metal_cpu *cpu) } } -static inline int __metal_driver_cpu_timebase(struct metal_cpu *cpu) +static __inline__ int __metal_driver_cpu_timebase(struct metal_cpu *cpu) { if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { - return 1000000; + return 16000000; } else { return 0; } } -static inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu) +static __inline__ struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu) { if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { return &__metal_dt_cpu_0_interrupt_controller.controller; @@ -259,7 +318,7 @@ static inline struct metal_interrupt * __metal_driver_cpu_interrupt_controller(s } } -static inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu) +static __inline__ int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu) { if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { return 8; @@ -269,10 +328,20 @@ static inline int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu) } } +static __inline__ struct metal_buserror * __metal_driver_cpu_buserror(struct metal_cpu *cpu) +{ + if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { + return NULL; + } + else { + return NULL; + } +} + /* --------------------- sifive_plic0 ------------ */ -static inline unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller) +static __inline__ unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller) { if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) { return METAL_RISCV_PLIC0_C000000_BASE_ADDRESS; @@ -282,7 +351,7 @@ static inline unsigned long __metal_driver_sifive_plic0_control_base(struct meta } } -static inline unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller) +static __inline__ unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller) { if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) { return METAL_RISCV_PLIC0_C000000_SIZE; @@ -292,7 +361,7 @@ static inline unsigned long __metal_driver_sifive_plic0_control_size(struct meta } } -static inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller) +static __inline__ int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller) { if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) { return METAL_RISCV_PLIC0_C000000_RISCV_NDEV; @@ -302,7 +371,7 @@ static inline int __metal_driver_sifive_plic0_num_interrupts(struct metal_interr } } -static inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller) +static __inline__ int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller) { if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) { return METAL_RISCV_PLIC0_C000000_RISCV_MAX_PRIORITY; @@ -312,108 +381,189 @@ static inline int __metal_driver_sifive_plic0_max_priority(struct metal_interrup } } -static inline struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx) +static __inline__ struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx) { if (idx == 0) { return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller; } - else if (idx == 0) { - return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller; - } else { return NULL; } } -static inline int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx) +static __inline__ int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx) { if (idx == 0) { return 11; } - else if (idx == 0) { - return 11; - } else { return 0; } } +static __inline__ int __metal_driver_sifive_plic0_context_ids(int hartid) +{ + if (hartid == 0) { + return 0; + } + else { + return -1; + } +} + + + +/* --------------------- sifive_buserror0 ------------ */ /* --------------------- sifive_clic0 ------------ */ /* --------------------- sifive_local_external_interrupts0 ------------ */ -static inline struct metal_interrupt * __metal_driver_sifive_local_external_interrupts0_interrupt_parent(struct metal_interrupt *controller) + + +/* --------------------- sifive_global_external_interrupts0 ------------ */ + + +/* --------------------- sifive_gpio0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio) { - if ((uintptr_t)controller == (uintptr_t)&__metal_dt_local_external_interrupts_0) { - return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller; + if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { + return METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS; } else { - return NULL; + return 0; } } -static inline int __metal_driver_sifive_local_external_interrupts0_num_interrupts(struct metal_interrupt *controller) +static __inline__ unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio) { - if ((uintptr_t)controller == (uintptr_t)&__metal_dt_local_external_interrupts_0) { - return METAL_MAX_LOCAL_EXT_INTERRUPTS; + if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { + return METAL_SIFIVE_GPIO0_10012000_SIZE; } else { return 0; } } -static inline int __metal_driver_sifive_local_external_interrupts0_interrupt_lines(struct metal_interrupt *controller, int idx) +static __inline__ int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio) { - if (idx == 0) { + if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { + return METAL_MAX_GPIO_INTERRUPTS; + } + else { + return 0; + } +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio) +{ + if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx) +{ + if (((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 0)) { + return 8; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 1))) { + return 9; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 2))) { + return 10; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) { + return 11; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) { + return 12; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) { + return 13; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) { + return 14; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) { + return 15; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) { return 16; } - else if (idx == 1) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) { return 17; } - else if (idx == 2) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) { return 18; } - else if (idx == 3) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) { return 19; } - else if (idx == 4) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) { return 20; } - else if (idx == 5) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) { return 21; } - else if (idx == 6) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) { return 22; } - else if (idx == 7) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) { return 23; } - else if (idx == 8) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 16))) { return 24; } - else if (idx == 9) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 17))) { return 25; } - else if (idx == 10) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 18))) { return 26; } - else if (idx == 11) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 19))) { return 27; } - else if (idx == 12) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 20))) { return 28; } - else if (idx == 13) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 21))) { return 29; } - else if (idx == 14) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 22))) { return 30; } - else if (idx == 15) { + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 23))) { return 31; } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 24))) { + return 32; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 25))) { + return 33; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 26))) { + return 34; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 27))) { + return 35; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 28))) { + return 36; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 29))) { + return 27; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 30))) { + return 28; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 31))) { + return 29; + } else { return 0; } @@ -421,203 +571,487 @@ static inline int __metal_driver_sifive_local_external_interrupts0_interrupt_lin -/* --------------------- sifive_global_external_interrupts0 ------------ */ +/* --------------------- sifive_gpio_button ------------ */ -/* --------------------- sifive_gpio0 ------------ */ -static inline unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio) +/* --------------------- sifive_gpio_led ------------ */ +static __inline__ struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led) { - if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { - return METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS; + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) { + return (struct metal_gpio *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) { + return (struct metal_gpio *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) { + return (struct metal_gpio *)&__metal_dt_gpio_10012000; + } + else { + return NULL; + } +} + +static __inline__ int __metal_driver_sifive_gpio_led_pin(struct metal_led *led) +{ + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) { + return 22; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) { + return 19; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) { + return 21; } else { return 0; } } -static inline unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio) +static __inline__ char * __metal_driver_sifive_gpio_led_label(struct metal_led *led) { - if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { - return METAL_SIFIVE_GPIO0_10012000_SIZE; + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) { + return "LD0red"; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_1) { + return "LD0green"; + } + else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_2) { + return "LD0blue"; + } + else { + return ""; + } +} + + + +/* --------------------- sifive_gpio_switch ------------ */ + + +/* --------------------- sifive_i2c0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_i2c0_control_base(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return METAL_SIFIVE_I2C0_10016000_BASE_ADDRESS; } else { return 0; } } -static inline int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio) +static __inline__ unsigned long __metal_driver_sifive_i2c0_control_size(struct metal_i2c *i2c) { - if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { - return METAL_MAX_GPIO_INTERRUPTS; + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return METAL_SIFIVE_I2C0_10016000_SIZE; } else { return 0; } } -static inline struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio) +static __inline__ struct metal_clock * __metal_driver_sifive_i2c0_clock(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return NULL; + } +} + +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_i2c0_pinmux(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return NULL; + } +} + +static __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_output_selector(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 0; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_source_selector(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 12288; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_i2c0_num_interrupts(struct metal_i2c *i2c) +{ + return METAL_MAX_I2C0_INTERRUPTS; +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_i2c0_interrupt_parent(struct metal_i2c *i2c) { - if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; +} + +static __inline__ int __metal_driver_sifive_i2c0_interrupt_line(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 52; } else { return 0; } } -static inline int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx) + + +/* --------------------- sifive_pwm0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_pwm0_control_base(struct metal_pwm *pwm) { - if (((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 0)) { - return 7; + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return METAL_SIFIVE_PWM0_10015000_BASE_ADDRESS; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 1))) { - return 8; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return METAL_SIFIVE_PWM0_10025000_BASE_ADDRESS; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 2))) { - return 9; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return METAL_SIFIVE_PWM0_10035000_BASE_ADDRESS; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) { - return 10; + else { + return 0; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) { - return 11; +} + +static __inline__ unsigned long __metal_driver_sifive_pwm0_control_size(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return METAL_SIFIVE_PWM0_10015000_SIZE; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) { - return 12; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return METAL_SIFIVE_PWM0_10025000_SIZE; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) { - return 13; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return METAL_SIFIVE_PWM0_10035000_SIZE; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) { - return 14; + else { + return 0; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) { - return 15; +} + +static __inline__ struct metal_clock * __metal_driver_sifive_pwm0_clock(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) { - return 16; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) { - return 17; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) { - return 18; + else { + return NULL; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) { - return 19; +} + +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_pwm0_pinmux(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) { - return 20; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) { - return 21; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; } - else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) { - return 22; + else { + return NULL; + } +} + +static __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_output_selector(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 15; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 7864320; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 15360; } else { return 0; } } +static __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_source_selector(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 15; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 7864320; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 15360; + } + else { + return 0; + } +} +static __inline__ int __metal_driver_sifive_pwm0_num_interrupts(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return __METAL_PWM_10015000_INTERRUPTS; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return __METAL_PWM_10025000_INTERRUPTS; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return __METAL_PWM_10035000_INTERRUPTS; + } + else { + return 0; + } +} -/* --------------------- sifive_gpio_button ------------ */ +static __inline__ struct metal_interrupt * __metal_driver_sifive_pwm0_interrupt_parent(struct metal_pwm *pwm) +{ + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; +} +static __inline__ int __metal_driver_sifive_pwm0_interrupt_lines(struct metal_pwm *pwm, int idx) +{ + if (((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 0)) { + return 40; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 1))) { + return 41; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 2))) { + return 42; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 3))) { + return 43; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 0))) { + return 44; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 1))) { + return 45; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 2))) { + return 46; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 3))) { + return 47; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 0))) { + return 48; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 1))) { + return 49; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 2))) { + return 50; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 3))) { + return 51; + } + else { + return 0; + } +} -/* --------------------- sifive_gpio_led ------------ */ -static inline struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led) +static __inline__ int __metal_driver_sifive_pwm0_compare_width(struct metal_pwm *pwm) { - if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { - return (struct metal_gpio *)&__metal_dt_gpio_10012000; + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 8; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { - return (struct metal_gpio *)&__metal_dt_gpio_10012000; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 16; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { - return (struct metal_gpio *)&__metal_dt_gpio_10012000; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 16; } else { - return NULL; + return 0; } } -static inline int __metal_driver_sifive_gpio_led_pin(struct metal_led *led) +static __inline__ int __metal_driver_sifive_pwm0_comparator_count(struct metal_pwm *pwm) { - if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { - return 22; + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 4; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { - return 19; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 4; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { - return 21; + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 4; } else { return 0; } } -static inline char * __metal_driver_sifive_gpio_led_label(struct metal_led *led) + + +/* --------------------- sifive_rtc0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_rtc0_control_base(const struct metal_rtc *const rtc) { - if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0red) { - return "LD0red"; + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return METAL_SIFIVE_AON0_10000000_BASE_ADDRESS; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0green) { - return "LD0green"; + else { + return 0; } - else if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0blue) { - return "LD0blue"; +} + +static __inline__ unsigned long __metal_driver_sifive_rtc0_control_size(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return METAL_SIFIVE_AON0_10000000_SIZE; } else { - return ""; + return 0; } } +static __inline__ struct metal_interrupt * __metal_driver_sifive_rtc0_interrupt_parent(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } + else { + return 0; + } +} +static __inline__ int __metal_driver_sifive_rtc0_interrupt_line(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return 2; + } + else { + return 0; + } +} -/* --------------------- sifive_gpio_switch ------------ */ +static __inline__ struct metal_clock * __metal_driver_sifive_rtc0_clock(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return (struct metal_clock *)&__metal_dt_clock_7.clock; + } + else { + return 0; + } +} -/* --------------------- sifive_spi0 ------------ */ -static inline unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi) +static __inline__ unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi) { if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { return METAL_SIFIVE_SPI0_10014000_BASE_ADDRESS; } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return METAL_SIFIVE_SPI0_10024000_BASE_ADDRESS; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return METAL_SIFIVE_SPI0_10034000_BASE_ADDRESS; + } else { return 0; } } -static inline unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi) +static __inline__ unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi) { if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { return METAL_SIFIVE_SPI0_10014000_SIZE; } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return METAL_SIFIVE_SPI0_10024000_SIZE; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return METAL_SIFIVE_SPI0_10034000_SIZE; + } else { return 0; } } -static inline struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi) +static __inline__ struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi) { + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return 0; + } } -static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi) +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi) { + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return 0; + } } -static inline unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi) +static __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi) { - return 60; + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return 0; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return 0; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return 0; + } + else { + return 0; + } } -static inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi) +static __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi) { + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return 0; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { return 60; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return 4227858432; + } + else { + return 0; + } } @@ -625,91 +1059,201 @@ static inline unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(st /* --------------------- sifive_test0 ------------ */ +/* --------------------- sifive_trace ------------ */ + /* --------------------- sifive_uart0 ------------ */ -static inline unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart) +static __inline__ unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart) { if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return METAL_SIFIVE_UART0_10013000_BASE_ADDRESS; } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return METAL_SIFIVE_UART0_10023000_BASE_ADDRESS; + } else { return 0; } } -static inline unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart) +static __inline__ unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart) { if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return METAL_SIFIVE_UART0_10013000_SIZE; } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return METAL_SIFIVE_UART0_10023000_SIZE; + } else { return 0; } } -static inline int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart) +static __inline__ int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart) { if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return METAL_MAX_UART_INTERRUPTS; } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return METAL_MAX_UART_INTERRUPTS; + } else { return 0; } } -static inline struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart) +static __inline__ struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart) { if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } else { - return NULL; + return 0; } } -static inline int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart) +static __inline__ int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart) { - return 5; + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return 3; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return 4; + } + else { + return 0; + } } -static inline struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart) +static __inline__ struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart) { + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return 0; + } } -static inline struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart) +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart) { + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return 0; + } } -static inline unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart) +static __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart) { - return 196608; + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return 0; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return 0; + } + else { + return 0; + } } -static inline unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart) +static __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart) { + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { return 196608; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return 8650752; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_simuart0 ------------ */ + + +/* --------------------- sifive_wdog0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_wdog0_control_base(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return METAL_SIFIVE_AON0_10000000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_wdog0_control_size(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return METAL_SIFIVE_AON0_10000000_SIZE; + } + else { + return 0; + } +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_wdog0_interrupt_parent(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_wdog0_interrupt_line(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return 1; + } + else { + return 0; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_wdog0_clock(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return (struct metal_clock *)&__metal_dt_clock_7.clock; + } + else { + return 0; + } } /* --------------------- sifive_fe310_g000_hfrosc ------------ */ -static inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock) +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock) { return (struct metal_clock *)&__metal_dt_clock_2.clock; } -static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock) +static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock) { return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000; } -static inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock) +static __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock) { return &__metal_driver_vtable_sifive_fe310_g000_prci; } -static inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock) +static __inline__ long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock) { return METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG; } @@ -717,55 +1261,98 @@ static inline long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const s /* --------------------- sifive_fe310_g000_hfxosc ------------ */ -static inline struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock) +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock) { return (struct metal_clock *)&__metal_dt_clock_0.clock; } -static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock) +static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock) { return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000; } -static inline long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock) +static __inline__ long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock) { return METAL_SIFIVE_FE310_G000_PRCI_HFXOSCCFG; } +/* --------------------- sifive_fe310_g000_lfrosc ------------ */ +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return (struct metal_clock *)&__metal_dt_clock_5.clock; + } + else { + return NULL; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return (struct metal_clock *)&__metal_dt_clock_6.clock; + } + else { + return NULL; + } +} + +static __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_config_reg(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return 112; + } + else { + return 0; + } +} + +static __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return 124; + } + else { + return 0; + } +} + + + /* --------------------- sifive_fe310_g000_pll ------------ */ -static inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock) +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock) { return (struct metal_clock *)&__metal_dt_clock_3.clock; } -static inline struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock) +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock) { return (struct metal_clock *)&__metal_dt_clock_1.clock; } -static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock) +static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock) { return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000; } -static inline long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock) +static __inline__ long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock) { return METAL_SIFIVE_FE310_G000_PRCI_PLLOUTDIV; } -static inline struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( ) +static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( ) { return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000; } -static inline long __metal_driver_sifive_fe310_g000_pll_config_offset( ) +static __inline__ long __metal_driver_sifive_fe310_g000_pll_config_offset( ) { return METAL_SIFIVE_FE310_G000_PRCI_PLLCFG; } -static inline long __metal_driver_sifive_fe310_g000_pll_init_rate( ) +static __inline__ long __metal_driver_sifive_fe310_g000_pll_init_rate( ) { return 16000000; } @@ -773,31 +1360,29 @@ static inline long __metal_driver_sifive_fe310_g000_pll_init_rate( ) /* --------------------- sifive_fe310_g000_prci ------------ */ -static inline long __metal_driver_sifive_fe310_g000_prci_base( ) +static __inline__ long __metal_driver_sifive_fe310_g000_prci_base( ) { return METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS; } -static inline long __metal_driver_sifive_fe310_g000_prci_size( ) +static __inline__ long __metal_driver_sifive_fe310_g000_prci_size( ) { return METAL_SIFIVE_FE310_G000_PRCI_10008000_SIZE; } -static inline const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( ) +static __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( ) { return &__metal_driver_vtable_sifive_fe310_g000_prci; } -/* --------------------- sifive_fu540_c000_l2 ------------ */ - +#define __METAL_DT_MAX_MEMORIES 3 -#define __METAL_DT_MAX_MEMORIES 2 - -asm (".weak __metal_memory_table"); +__asm__ (".weak __metal_memory_table"); struct metal_memory *__metal_memory_table[] = { &__metal_dt_mem_dtim_80000000, + &__metal_dt_mem_itim_8000000, &__metal_dt_mem_spi_10014000}; /* From serial@10013000 */ @@ -814,7 +1399,9 @@ struct metal_memory *__metal_memory_table[] = { #define __METAL_DT_MAX_HARTS 1 -asm (".weak __metal_cpu_table"); +#define __METAL_CPU_0_ICACHE_HANDLE 1 + +__asm__ (".weak __metal_cpu_table"); struct __metal_driver_cpu *__metal_cpu_table[] = { &__metal_dt_cpu_0}; @@ -825,47 +1412,82 @@ struct __metal_driver_cpu *__metal_cpu_table[] = { #define __METAL_DT_PMP_HANDLE (&__metal_dt_pmp) -/* From local_external_interrupts_0 */ -#define __METAL_DT_SIFIVE_LOCAL_EXINTR0_HANDLE (&__metal_dt_local_external_interrupts_0.irc) - -#define __METAL_DT_LOCAL_EXTERNAL_INTERRUPTS_0_HANDLE (&__metal_dt_local_external_interrupts_0.irc) - #define __MEE_DT_MAX_GPIOS 1 -asm (".weak __metal_gpio_table"); +__asm__ (".weak __metal_gpio_table"); struct __metal_driver_sifive_gpio0 *__metal_gpio_table[] = { &__metal_dt_gpio_10012000}; #define __METAL_DT_MAX_BUTTONS 0 -asm (".weak __metal_button_table"); +__asm__ (".weak __metal_button_table"); struct __metal_driver_sifive_gpio_button *__metal_button_table[] = { NULL }; #define __METAL_DT_MAX_LEDS 3 -asm (".weak __metal_led_table"); +__asm__ (".weak __metal_led_table"); struct __metal_driver_sifive_gpio_led *__metal_led_table[] = { - &__metal_dt_led_0red, - &__metal_dt_led_0green, - &__metal_dt_led_0blue}; + &__metal_dt_led_0, + &__metal_dt_led_1, + &__metal_dt_led_2}; #define __METAL_DT_MAX_SWITCHES 0 -asm (".weak __metal_switch_table"); +__asm__ (".weak __metal_switch_table"); struct __metal_driver_sifive_gpio_switch *__metal_switch_table[] = { NULL }; -#define __METAL_DT_MAX_SPIS 1 +#define __METAL_DT_MAX_I2CS 1 + +__asm__ (".weak __metal_i2c_table"); +struct __metal_driver_sifive_i2c0 *__metal_i2c_table[] = { + &__metal_dt_i2c_10016000}; + +#define __METAL_DT_MAX_PWMS 3 + +__asm__ (".weak __metal_pwm_table"); +struct __metal_driver_sifive_pwm0 *__metal_pwm_table[] = { + &__metal_dt_pwm_10015000, + &__metal_dt_pwm_10025000, + &__metal_dt_pwm_10035000}; + +#define __METAL_DT_MAX_RTCS 1 -asm (".weak __metal_spi_table"); +__asm__ (".weak __metal_rtc_table"); +struct __metal_driver_sifive_rtc0 *__metal_rtc_table[] = { + &__metal_dt_rtc_10000000}; + +#define __METAL_DT_MAX_SPIS 3 + +__asm__ (".weak __metal_spi_table"); struct __metal_driver_sifive_spi0 *__metal_spi_table[] = { - &__metal_dt_spi_10014000}; + &__metal_dt_spi_10014000, + &__metal_dt_spi_10024000, + &__metal_dt_spi_10034000}; + +#define __METAL_DT_MAX_UARTS 2 + +__asm__ (".weak __metal_uart_table"); +struct __metal_driver_sifive_uart0 *__metal_uart_table[] = { + &__metal_dt_serial_10013000, + &__metal_dt_serial_10023000}; + +#define __METAL_DT_MAX_SIMUARTS 0 + +__asm__ (".weak __metal_simuart_table"); +struct __metal_driver_sifive_simuart0 *__metal_simuart_table[] = { + NULL }; +#define __METAL_DT_MAX_WDOGS 1 + +__asm__ (".weak __metal_wdog_table"); +struct __metal_driver_sifive_wdog0 *__metal_wdog_table[] = { + &__metal_dt_aon_10000000}; /* From clock@4 */ #define __METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE (&__metal_dt_clock_4) #define __METAL_DT_CLOCK_4_HANDLE (&__metal_dt_clock_4) -#endif /* MACROS_ELSE_SIFIVE_HIFIVE1_REVB____METAL_H*/ +#endif /* MACROS_ELSE_METAL_H*/ #endif /* ! __METAL_MACHINE_MACROS */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.ramrodata.lds b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.ramrodata.lds new file mode 100644 index 000000000..6803873ce --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.ramrodata.lds @@ -0,0 +1,306 @@ +/* Copyright (c) 2020 SiFive Inc. */ +/* SPDX-License-Identifier: Apache-2.0 */ +OUTPUT_ARCH("riscv") + +/* RAM Read-Only Data Linker Script + * + * This linker script places application code and read-only data into writable + * memories in an attempt to improve performance, since writable memories + * are generally lower-latency. This linker script may cause your application + * to overflow RAM, since it dramatically increases the quantity of data vying + * for space there. + */ + +ENTRY(_enter) + +MEMORY +{ + itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000 + ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000 + rom (irx!wa) : ORIGIN = 0x20010000, LENGTH = 0x6a120 +} + +PHDRS +{ + rom PT_LOAD; + ram_init PT_LOAD; + tls PT_TLS; + ram PT_LOAD; + itim_init PT_LOAD; + text PT_LOAD; + lim_init PT_LOAD; +} + +SECTIONS +{ + /* Each hart is allocated its own stack of size __stack_size. This value + * can be overriden at build-time by adding the following to CFLAGS: + * + * -Xlinker --defsym=__stack_size=0xf00 + * + * where 0xf00 can be replaced with a multiple of 16 of your choice. + * + * __stack_size is PROVIDE-ed as a symbol so that initialization code + * initializes the stack pointers for each hart at the right offset from + * the _sp symbol. + */ + __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400; + PROVIDE(__stack_size = __stack_size); + + /* The size of the heap can be overriden at build-time by adding the + * following to CFLAGS: + * + * -Xlinker --defsym=__heap_size=0xf00 + * + * where 0xf00 can be replaced with the value of your choice. + * + * Altertatively, the heap can be grown to fill the entire remaining region + * of RAM by adding the following to CFLAGS: + * + * -Xlinker --defsym=__heap_max=1 + * + * Note that depending on the memory layout, the bitness (32/64bit) of the + * target, and the code model in use, this might cause a relocation error. + */ + __heap_size = DEFINED(__heap_size) ? __heap_size : 0x800; + + /* The boot hart sets which hart runs the pre-main initialization routines, + * including copying .data into RAM, zeroing the BSS region, running + * constructors, etc. After initialization, the boot hart is also the only + * hart which runs application code unless the application overrides the + * secondary_main() function to start execution on secondary harts. + */ + PROVIDE(__metal_boot_hart = 0); + + /* The chicken bit is used by pre-main initialization to enable/disable + * certain core features */ + PROVIDE(__metal_chicken_bit = 1); + + /* The memory_ecc_scrub bit is used by _entry code to enable/disable + * memories scrubbing to zero */ + PROVIDE(__metal_eccscrub_bit = 0); + + /* The RAM memories map for ECC scrubbing */ + PROVIDE( metal_dtim_0_memory_start = 0x80000000 ); + PROVIDE( metal_dtim_0_memory_end = 0x80000000 + 0x4000 ); + PROVIDE( metal_itim_0_memory_start = 0x8000000 ); + PROVIDE( metal_itim_0_memory_end = 0x8000000 + 0x2000 ); + + /* ROM SECTION + * + * The following sections contain data which lives in read-only memory, if + * such memory is present in the design, for the entire duration of program + * execution. + */ + + .init : { + /* The _enter symbol is placed in the .text.metal.init.enter section + * and must be placed at the beginning of the program */ + KEEP (*(.text.metal.init.enter)) + KEEP (*(.text.metal.init.*)) + KEEP (*(SORT_NONE(.init))) + KEEP (*(.text.libgloss.start)) + } >rom :rom + + .fini : { + KEEP (*(SORT_NONE(.fini))) + } >rom :rom + + .preinit_array : ALIGN(8) { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >rom :rom + + .init_array : ALIGN(8) { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE_HIDDEN ( metal_constructors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.metal.init_array.*))); + KEEP (*(.metal.init_array)); + PROVIDE_HIDDEN ( metal_constructors_end = .); + } >rom :rom + + .fini_array : ALIGN(8) { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + PROVIDE_HIDDEN ( metal_destructors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.metal.fini_array.*))); + KEEP (*(.metal.fini_array)); + PROVIDE_HIDDEN ( metal_destructors_end = .); + } >rom :rom + + + + .ctors : { + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + KEEP (*(.metal.ctors .metal.ctors.*)) + } >rom :rom + + .dtors : { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + KEEP (*(.metal.dtors .metal.dtors.*)) + } >rom : rom + + + /* ITIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into an instruction tightly-integrated memory (ITIM), if one + * is present in the design, during pre-main program initialization. + * + * Generally, the data copied into the ITIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ + + .itim : ALIGN(8) { + *(.itim .itim.*) + } >itim AT>rom :itim_init + + PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) ); + PROVIDE( metal_segment_itim_target_start = ADDR(.itim) ); + PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) ); + + /* LIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a loosely integrated memory (LIM), which is shared with L2 + * cache, during pre-main program initialization. + * + * Generally, the data copied into the LIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ + + .lim : ALIGN(8) { + *(.lim .lim.*) + } >ram AT>rom :lim_init + + PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) ); + PROVIDE( metal_segment_lim_target_start = ADDR(.lim) ); + PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) ); + + /* TEXT SECTION + * + * The following section contains the code of the program, excluding + * everything that's been allocated into the ITIM/LIM already + */ + + .text : { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >rom :text + + /* RAM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a read-write-capable memory such as data tightly-integrated + * memory (DTIM) or another main memory, as well as the BSS, stack, and + * heap. + * + * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all + * have an apparently unnecessary ALIGN at their top. This is because + * the implementation of _start in Freedom Metal libgloss depends on the + * ADDR and LOADADDR being 8-byte aligned. + */ + + .data : ALIGN(8) { + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.s.*) + /* Read-only data is placed in RAM to improve performance, since + * read-only memory generally has higher latency than RAM */ + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + . = ALIGN(8); + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + } >ram AT>rom :ram_init + + .tdata : ALIGN(8) { + PROVIDE( __tls_base = . ); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } >ram AT>rom :tls :ram_init + + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tdata_size = SIZEOF(.tdata) ); + + PROVIDE( metal_segment_data_source_start = LOADADDR(.data) ); + PROVIDE( metal_segment_data_target_start = ADDR(.data) ); + PROVIDE( metal_segment_data_target_end = ADDR(.tdata) + SIZEOF(.tdata) ); + + .tbss : ALIGN(8) { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon .tcommon.*) + PROVIDE( __tls_end = . ); + } >ram AT>ram :tls :ram + PROVIDE( __tbss_size = SIZEOF(.tbss) ); + PROVIDE( __tls_size = __tls_end - __tls_base ); + + .tbss_space : ALIGN(8) { + . = . + __tbss_size; + } >ram :ram + + .bss (NOLOAD): ALIGN(8) { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + } >ram :ram + + PROVIDE( metal_segment_bss_source_start = LOADADDR(.tbss) ); + PROVIDE( metal_segment_bss_target_start = ADDR(.tbss) ); + PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) ); + + + + .stack (NOLOAD) : ALIGN(16) { + PROVIDE(metal_segment_stack_begin = .); + . += __stack_size; /* Hart 0 */ + PROVIDE( _sp = . ); + PROVIDE(metal_segment_stack_end = .); + } >ram :ram + + .heap (NOLOAD) : ALIGN(8) { + PROVIDE( __end = . ); + PROVIDE( __heap_start = . ); + PROVIDE( metal_segment_heap_target_start = . ); + /* If __heap_max is defined, grow the heap to use the rest of RAM, + * otherwise set the heap size to __heap_size */ + . = DEFINED(__heap_max) ? MIN( LENGTH(ram) - ( . - ORIGIN(ram)) , 0x10000000) : __heap_size; + PROVIDE( metal_segment_heap_target_end = . ); + PROVIDE( _heap_end = . ); + PROVIDE( __heap_end = . ); + } >ram :ram + + /* C++ exception handling information is + * not useful with our current runtime environment, + * and it consumes flash space. Discard it until + * we have something that can use it + */ + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + } +}
\ No newline at end of file diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.scratchpad.lds b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.scratchpad.lds new file mode 100644 index 000000000..356726912 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/metal.scratchpad.lds @@ -0,0 +1,294 @@ +/* Copyright (c) 2020 SiFive Inc. */ +/* SPDX-License-Identifier: Apache-2.0 */ +OUTPUT_ARCH("riscv") + +/* Scratchpad Linker Script + * + * This linker script is for executing in "scratchpad" mode, where all + * application code and data is placed in writable memory. + */ + +ENTRY(_enter) + +MEMORY +{ + itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000 + ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000 + rom (irx!wa) : ORIGIN = 0x20010000, LENGTH = 0x6a120 +} + +PHDRS +{ + rom PT_LOAD; + ram_init PT_LOAD; + tls PT_TLS; + ram PT_LOAD; + itim_init PT_LOAD; + text PT_LOAD; + lim_init PT_LOAD; +} + +SECTIONS +{ + /* Each hart is allocated its own stack of size __stack_size. This value + * can be overriden at build-time by adding the following to CFLAGS: + * + * -Xlinker --defsym=__stack_size=0xf00 + * + * where 0xf00 can be replaced with a multiple of 16 of your choice. + * + * __stack_size is PROVIDE-ed as a symbol so that initialization code + * initializes the stack pointers for each hart at the right offset from + * the _sp symbol. + */ + __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400; + PROVIDE(__stack_size = __stack_size); + + /* The size of the heap can be overriden at build-time by adding the + * following to CFLAGS: + * + * -Xlinker --defsym=__heap_size=0xf00 + * + * where 0xf00 can be replaced with the value of your choice. + * + * Altertatively, the heap can be grown to fill the entire remaining region + * of RAM by adding the following to CFLAGS: + * + * -Xlinker --defsym=__heap_max=1 + * + * Note that depending on the memory layout, the bitness (32/64bit) of the + * target, and the code model in use, this might cause a relocation error. + */ + __heap_size = DEFINED(__heap_size) ? __heap_size : 0x800; + + /* The boot hart sets which hart runs the pre-main initialization routines, + * including copying .data into RAM, zeroing the BSS region, running + * constructors, etc. After initialization, the boot hart is also the only + * hart which runs application code unless the application overrides the + * secondary_main() function to start execution on secondary harts. + */ + PROVIDE(__metal_boot_hart = 0); + + /* The chicken bit is used by pre-main initialization to enable/disable + * certain core features */ + PROVIDE(__metal_chicken_bit = 1); + + PROVIDE(__metal_eccscrub_bit = 0); + + /* ROM SECTION + * + * The following sections contain data which lives in read-only memory, if + * such memory is present in the design, for the entire duration of program + * execution. + */ + + .init : { + /* The _enter symbol is placed in the .text.metal.init.enter section + * and must be placed at the beginning of the program */ + KEEP (*(.text.metal.init.enter)) + KEEP (*(.text.metal.init.*)) + KEEP (*(SORT_NONE(.init))) + KEEP (*(.text.libgloss.start)) + } >ram :rom + + .fini : { + KEEP (*(SORT_NONE(.fini))) + } >ram :rom + + .preinit_array : ALIGN(8) { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >ram :rom + + .init_array : ALIGN(8) { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + PROVIDE_HIDDEN ( metal_constructors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.metal.init_array.*))); + KEEP (*(.metal.init_array)); + PROVIDE_HIDDEN ( metal_constructors_end = .); + } >ram :rom + + .fini_array : ALIGN(8) { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + PROVIDE_HIDDEN ( metal_destructors_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.metal.fini_array.*))); + KEEP (*(.metal.fini_array)); + PROVIDE_HIDDEN ( metal_destructors_end = .); + } >ram :rom + + + + .ctors : { + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + KEEP (*(.metal.ctors .metal.ctors.*)) + } >ram :rom + + .dtors : { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + KEEP (*(.metal.dtors .metal.dtors.*)) + } >ram : rom + + .rodata : { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram :rom + + /* ITIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into an instruction tightly-integrated memory (ITIM), if one + * is present in the design, during pre-main program initialization. + * + * Generally, the data copied into the ITIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ + + .itim : ALIGN(8) { + *(.itim .itim.*) + } >itim AT>ram :itim_init + + PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) ); + PROVIDE( metal_segment_itim_target_start = ADDR(.itim) ); + PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) ); + + /* LIM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a loosely integrated memory (LIM), which is shared with L2 + * cache, during pre-main program initialization. + * + * Generally, the data copied into the LIM should be performance-critical + * functions which benefit from low instruction-fetch latency. + */ + + .lim : ALIGN(8) { + *(.lim .lim.*) + } >ram AT>ram :lim_init + + PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) ); + PROVIDE( metal_segment_lim_target_start = ADDR(.lim) ); + PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) ); + + /* TEXT SECTION + * + * The following section contains the code of the program, excluding + * everything that's been allocated into the ITIM/LIM already + */ + + .text : { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >ram :text + + /* RAM SECTION + * + * The following sections contain data which is copied from read-only + * memory into a read-write-capable memory such as data tightly-integrated + * memory (DTIM) or another main memory, as well as the BSS, stack, and + * heap. + * + * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all + * have an apparently unnecessary ALIGN at their top. This is because + * the implementation of _start in Freedom Metal libgloss depends on the + * ADDR and LOADADDR being 8-byte aligned. + */ + + .data : ALIGN(8) { + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.s.*) + } >ram AT>ram :ram_init + + .tdata : ALIGN(8) { + PROVIDE( __tls_base = . ); + *(.tdata .tdata.* .gnu.linkonce.td.*) + } >ram AT>ram :tls :ram_init + + PROVIDE( __tdata_source = LOADADDR(.tdata) ); + PROVIDE( __tdata_size = SIZEOF(.tdata) ); + + PROVIDE( metal_segment_data_source_start = LOADADDR(.data) ); + PROVIDE( metal_segment_data_target_start = ADDR(.data) ); + PROVIDE( metal_segment_data_target_end = ADDR(.tdata) + SIZEOF(.tdata) ); + + .tbss : ALIGN(8) { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon .tcommon.*) + PROVIDE( __tls_end = . ); + } >ram AT>ram :tls :ram + PROVIDE( __tbss_size = SIZEOF(.tbss) ); + PROVIDE( __tls_size = __tls_end - __tls_base ); + + .tbss_space : ALIGN(8) { + . = . + __tbss_size; + } >ram :ram + + .bss (NOLOAD): ALIGN(8) { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + } >ram :ram + + PROVIDE( metal_segment_bss_source_start = LOADADDR(.tbss) ); + PROVIDE( metal_segment_bss_target_start = ADDR(.tbss) ); + PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) ); + + + + .stack (NOLOAD) : ALIGN(16) { + PROVIDE(metal_segment_stack_begin = .); + . += __stack_size; /* Hart 0 */ + PROVIDE( _sp = . ); + PROVIDE(metal_segment_stack_end = .); + } >ram :ram + + .heap (NOLOAD) : ALIGN(8) { + PROVIDE( __end = . ); + PROVIDE( __heap_start = . ); + PROVIDE( metal_segment_heap_target_start = . ); + /* If __heap_max is defined, grow the heap to use the rest of RAM, + * otherwise set the heap size to __heap_size */ + . = DEFINED(__heap_max) ? MIN( LENGTH(ram) - ( . - ORIGIN(ram)) , 0x10000000) : __heap_size; + PROVIDE( metal_segment_heap_target_end = . ); + PROVIDE( _heap_end = . ); + PROVIDE( __heap_end = . ); + } >ram :ram + + /* C++ exception handling information is + * not useful with our current runtime environment, + * and it consumes flash space. Discard it until + * we have something that can use it + */ + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + } +}
\ No newline at end of file diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/settings.mk b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/settings.mk new file mode 100644 index 000000000..a8ddd99f2 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/bsp/settings.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2020 SiFive Inc +# SPDX-License-Identifier: Apache-2.0 + +RISCV_ARCH = rv32imac +RISCV_ABI = ilp32 +RISCV_CMODEL = medlow +RISCV_SERIES = sifive-3-series + +TARGET_TAGS = board jlink +TARGET_DHRY_ITERS = 20000000 +TARGET_CORE_ITERS = 5000 +TARGET_FREERTOS_WAIT_MS = 1000 +TARGET_INTR_WAIT_CYCLE = 0
\ No newline at end of file diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.clang-format b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.clang-format new file mode 100644 index 000000000..f9d627fe6 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.clang-format @@ -0,0 +1,5 @@ +BasedOnStyle: LLVM +Language: Cpp + +IndentWidth: 4 + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.travis.yml b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.travis.yml new file mode 100644 index 000000000..04ce26935 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/.travis.yml @@ -0,0 +1,35 @@ +sudo: required + +# Travis doesn't provide a wide variety of host environments to run on, so we +# rely on Docker to provide these instead. +services: + - docker + +# It is not really needed, other than for showing correct language tag in +# Travis CI build log. +language: c + +# The matrix of targets that we're interested in. +env: + - HOST="ubuntu:16.04" + +# Before running the install phase we need to set up docker container that runs +# the target machine. +before_install: + - docker run -d --name host -v $(pwd):/travis $HOST tail -f /dev/null + - docker ps + +# Update the container and install dependencies +install: + - docker exec -t host bash -c "yes | apt-get update" + - docker exec -t host bash -c "yes | apt-get upgrade" + - docker exec -t host bash -c "yes | apt-get install git clang-format-6.0" + - sudo curl -L -o /tmp/wake.deb https://github.com/sifive/wake/releases/download/v0.19.0/ubuntu-16-04-wake_0.19.0-1_amd64.deb + - sudo apt install /tmp/wake.deb + +# Here's where we actually run the test. +script: +# Check source code formatting + - docker exec -t host bash -c "cd /travis && ./scripts/check-format" +# Run dummy Wake program in order to run Wake type checker. + - wake --init . && wake -x Unit diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Doxyfile b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Doxyfile new file mode 100644 index 000000000..22c8f7845 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Doxyfile @@ -0,0 +1,2537 @@ +# Doxyfile 1.8.15 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "Freedom Metal" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "Bare Metal Compatibility Library for the Freedom Platform" + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = "doc" + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all generated output in the proper direction. +# Possible values are: None, LTR, RTL and Context. +# The default value is: None. + +OUTPUT_TEXT_DIRECTION = None + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines (in the resulting output). You can put ^^ in the value part of an +# alias to insert a newline as if a physical newline was in the original file. +# When you need a literal { or } or , in the value part of an alias you have to +# escape them by means of a backslash (\), this can lead to conflicts with the +# commands \{ and \} for these it is advised to use the version @{ and @} or use +# a double escape (\\{ and \\}) + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, +# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat +# .inc files as Fortran files (default is PHP), and .f files as C (default is +# Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 0. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 0 + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if <section_label> ... \endif and \cond <section_label> +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. If +# EXTRACT_ALL is set to YES then this flag will automatically be disabled. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = metal + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: https://www.gnu.org/software/libiconv/) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.pyw \ + *.f90 \ + *.f95 \ + *.f03 \ + *.f08 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.ice + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = metal/compiler.h metal/io.h metal/machine.h + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = _* __* *vtable + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# <filter> <input-file> +# +# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = NO + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via Javascript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have Javascript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: https://developer.apple.com/xcode/), introduced with OSX +# 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. +# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/ + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use <access key> + S +# (what the <access key> is depends on the OS and browser, but it is typically +# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down +# key> to jump into the search results window, the results can be navigated +# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel +# the search. The filter options can be selected when the cursor is inside the +# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> +# to select a filter and <Enter> or <escape> to activate or cancel the filter +# option. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a web server instead of a web client using Javascript. There +# are two flavors of web server based searching depending on the EXTERNAL_SEARCH +# setting. When disabled, doxygen will generate a PHP script for searching and +# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing +# and searching needs to be provided by external tools. See the section +# "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SERVER_BASED_SEARCH = NO + +# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP +# script for searching. Instead the search results are written to an XML file +# which needs to be processed by an external indexer. Doxygen will invoke an +# external search engine pointed to by the SEARCHENGINE_URL option to obtain the +# search results. +# +# Doxygen ships with an example indexer (doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: https://xapian.org/). +# +# See the section "External Indexing and Searching" for details. +# The default value is: NO. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH = NO + +# The SEARCHENGINE_URL should point to a search engine hosted by a web server +# which will return the search results when EXTERNAL_SEARCH is enabled. +# +# Doxygen ships with an example indexer (doxyindexer) and search engine +# (doxysearch.cgi) which are based on the open source search engine library +# Xapian (see: https://xapian.org/). See the section "External Indexing and +# Searching" for details. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHENGINE_URL = + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed +# search data is written to a file for indexing by an external tool. With the +# SEARCHDATA_FILE tag the name of this file can be specified. +# The default file is: searchdata.xml. +# This tag requires that the tag SEARCHENGINE is set to YES. + +SEARCHDATA_FILE = searchdata.xml + +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple +# projects and redirect the results back to the right project. +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTERNAL_SEARCH_ID = + +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen +# projects other than the one defined by this configuration file, but that are +# all added to the same external search index. Each project needs to have a +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of +# to a relative location where the documentation can be found. The format is: +# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... +# This tag requires that the tag SEARCHENGINE is set to YES. + +EXTRA_SEARCH_MAPPINGS = + +#--------------------------------------------------------------------------- +# Configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. +# The default value is: YES. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: latex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. +# +# Note that when not enabling USE_PDFLATEX the default is latex when enabling +# USE_PDFLATEX the default is pdflatex and when in the later case latex is +# chosen this is overwritten by pdflatex. For specific output languages the +# default can have been set differently, this depends on the implementation of +# the output language. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_CMD_NAME = + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate +# index for LaTeX. +# Note: This tag is used in the Makefile / make.bat. +# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file +# (.tex). +# The default file is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +MAKEINDEX_CMD_NAME = makeindex + +# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to +# generate index for LaTeX. In case there is no backslash (\) as first character +# it will be automatically added in the LaTeX code. +# Note: This tag is used in the generated output file (.tex). +# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. +# The default value is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_MAKEINDEX_CMD = makeindex + +# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used by the +# printer. +# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x +# 14 inches) and executive (7.25 x 10.5 inches). +# The default value is: a4. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names +# that should be included in the LaTeX output. The package can be specified just +# by its name or with the correct syntax as to be used with the LaTeX +# \usepackage command. To get the times font for instance you can specify : +# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} +# To use the option intlimits with the amsmath package you can specify: +# EXTRA_PACKAGES=[intlimits]{amsmath} +# If left blank no extra packages will be included. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the +# generated LaTeX document. The header should contain everything until the first +# chapter. If it is left blank doxygen will generate a standard header. See +# section "Doxygen usage" for information on how to let doxygen write the +# default header to a separate file. +# +# Note: Only use a user-defined header if you know what you are doing! The +# following commands have a special meaning inside the header: $title, +# $datetime, $date, $doxygenversion, $projectname, $projectnumber, +# $projectbrief, $projectlogo. Doxygen will replace $title with the empty +# string, for the replacement values of the other commands the user is referred +# to HTML_HEADER. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the +# generated LaTeX document. The footer should contain everything after the last +# chapter. If it is left blank doxygen will generate a standard footer. See +# LATEX_HEADER for more information on how to generate a default footer and what +# special commands can be used inside the footer. +# +# Note: Only use a user-defined footer if you know what you are doing! +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_FOOTER = + +# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# LaTeX style sheets that are included after the standard style sheets created +# by doxygen. Using this option one can overrule certain style aspects. Doxygen +# will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_STYLESHEET = + +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the LATEX_OUTPUT output +# directory. Note that the files will be copied as-is; there are no commands or +# markers available. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_FILES = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is +# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will +# contain links (just like the HTML output) instead of page references. This +# makes the output suitable for online browsing using a PDF viewer. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate +# the PDF file directly from the LaTeX files. Set this option to YES, to get a +# higher quality PDF documentation. +# The default value is: YES. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode +# command to the generated LaTeX files. This will instruct LaTeX to keep running +# if errors occur, instead of asking the user for help. This option is also used +# when generating formulas in HTML. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BATCHMODE = NO + +# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the +# index chapters (such as File Index, Compound Index, etc.) in the output. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_HIDE_INDICES = NO + +# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source +# code with syntax highlighting in the LaTeX output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. See +# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. +# The default value is: plain. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_BIB_STYLE = plain + +# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_TIMESTAMP = NO + +# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) +# path from which the emoji images will be read. If a relative path is entered, +# it will be relative to the LATEX_OUTPUT directory. If left blank the +# LATEX_OUTPUT directory will be used. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EMOJI_DIRECTORY = + +#--------------------------------------------------------------------------- +# Configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The +# RTF output is optimized for Word 97 and may not look too pretty with other RTF +# readers/editors. +# The default value is: NO. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: rtf. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF +# documents. This may be useful for small projects and may help to save some +# trees in general. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will +# contain hyperlink fields. The RTF file will contain links (just like the HTML +# output) instead of page references. This makes the output suitable for online +# browsing using Word or some other Word compatible readers that support those +# fields. +# +# Note: WordPad (write) and others do not support links. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# configuration file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. +# +# See also section "Doxygen usage" for information on how to generate the +# default style sheet that doxygen normally uses. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an RTF document. Syntax is +# similar to doxygen's configuration file. A template extensions file can be +# generated using doxygen -e rtf extensionFile. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_EXTENSIONS_FILE = + +# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code +# with syntax highlighting in the RTF output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for +# classes and files. +# The default value is: NO. + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. A directory man3 will be created inside the directory specified by +# MAN_OUTPUT. +# The default directory is: man. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to the generated +# man pages. In case the manual section does not start with a number, the number +# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is +# optional. +# The default value is: .3. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_EXTENSION = .3 + +# The MAN_SUBDIR tag determines the name of the directory created within +# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by +# MAN_EXTENSION with the initial . removed. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_SUBDIR = + +# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it +# will generate one additional man file for each entity documented in the real +# man page(s). These additional files only source the real man page, but without +# them the man command would be unable to find the correct page. +# The default value is: NO. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that +# captures the structure of the code including all documentation. +# The default value is: NO. + +GENERATE_XML = YES + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: xml. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_OUTPUT = xml + +# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program +# listings (including syntax highlighting and cross-referencing information) to +# the XML output. Note that enabling this will significantly increase the size +# of the XML output. +# The default value is: YES. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_PROGRAMLISTING = YES + +# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include +# namespace members in file scope as well, matching the HTML output. +# The default value is: NO. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_NS_MEMB_FILE_SCOPE = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the DOCBOOK output +#--------------------------------------------------------------------------- + +# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files +# that can be used to generate PDF. +# The default value is: NO. + +GENERATE_DOCBOOK = NO + +# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in +# front of it. +# The default directory is: docbook. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_OUTPUT = docbook + +# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the +# program listings (including syntax highlighting and cross-referencing +# information) to the DOCBOOK output. Note that enabling this will significantly +# increase the size of the DOCBOOK output. +# The default value is: NO. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_PROGRAMLISTING = NO + +#--------------------------------------------------------------------------- +# Configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an +# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures +# the structure of the code including all documentation. Note that this feature +# is still experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module +# file that captures the structure of the code including all documentation. +# +# Note that this feature is still experimental and incomplete at the moment. +# The default value is: NO. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary +# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI +# output from the Perl module output. +# The default value is: NO. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely +# formatted so it can be parsed by a human reader. This is useful if you want to +# understand what is going on. On the other hand, if this tag is set to NO, the +# size of the Perl module output will be much smaller and Perl will parse it +# just the same. +# The default value is: YES. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file are +# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful +# so different doxyrules.make files included by the same Makefile don't +# overwrite each other's variables. +# This tag requires that the tag GENERATE_PERLMOD is set to YES. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all +# C-preprocessor directives found in the sources and include files. +# The default value is: YES. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names +# in the source code. If set to NO, only conditional compilation will be +# performed. Macro expansion can be done in a controlled way by setting +# EXPAND_ONLY_PREDEF to YES. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then +# the macro expansion is limited to the macros specified with the PREDEFINED and +# EXPAND_AS_DEFINED tags. +# The default value is: NO. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES, the include files in the +# INCLUDE_PATH will be searched if a #include is found. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by the +# preprocessor. +# This tag requires that the tag SEARCH_INCLUDES is set to YES. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will be +# used. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that are +# defined before the preprocessor is started (similar to the -D option of e.g. +# gcc). The argument of the tag is a list of macros of the form: name or +# name=definition (no spaces). If the definition and the "=" are omitted, "=1" +# is assumed. To prevent a macro definition from being undefined via #undef or +# recursively expanded use the := operator instead of the = operator. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this +# tag can be used to specify a list of macro names that should be expanded. The +# macro definition that is found in the sources will be used. Use the PREDEFINED +# tag if you want to use a different macro definition that overrules the +# definition found in the source code. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will +# remove all references to function-like macros that are alone on a line, have +# an all uppercase name, and do not end with a semicolon. Such function macros +# are typically used for boiler-plate code, and will confuse the parser if not +# removed. +# The default value is: YES. +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tag files. For each tag +# file the location of the external documentation should be added. The format of +# a tag file without this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where loc1 and loc2 can be relative or absolute paths or URLs. See the +# section "Linking to external documentation" for more information about the use +# of tag files. +# Note: Each tag file must have a unique name (where the name does NOT include +# the path). If a tag file is not located in the directory in which doxygen is +# run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create a +# tag file that is based on the input files it reads. See section "Linking to +# external documentation" for more information about the usage of tag files. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES, all external class will be listed in +# the class index. If set to NO, only the inherited external classes will be +# listed. +# The default value is: NO. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will be +# listed. +# The default value is: YES. + +EXTERNAL_GROUPS = YES + +# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in +# the related pages index. If set to NO, only the current project's pages will +# be listed. +# The default value is: YES. + +EXTERNAL_PAGES = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of 'which perl'). +# The default file (with absolute path) is: /usr/bin/perl. + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram +# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to +# NO turns the diagrams off. Note that this option also works with HAVE_DOT +# disabled, but it is recommended to install and use dot, since it yields more +# powerful graphs. +# The default value is: YES. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see: +# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. + +DIA_PATH = + +# If set to YES the inheritance and collaboration graphs will hide inheritance +# and usage relations if the target is undocumented or is not a class. +# The default value is: YES. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz (see: +# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# Bell Labs. The other options in this section have no effect if this option is +# set to NO +# The default value is: NO. + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed +# to run in parallel. When set to 0 doxygen will base this on the number of +# processors available in the system. You can set it explicitly to a value +# larger than 0 to get control over the balance between CPU load and processing +# speed. +# Minimum value: 0, maximum value: 32, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_NUM_THREADS = 0 + +# When you want a differently looking font in the dot files that doxygen +# generates you can specify the font name using DOT_FONTNAME. You need to make +# sure dot is able to find the font, which can be done by putting it in a +# standard location or by setting the DOTFONTPATH environment variable or by +# setting DOT_FONTPATH to the directory containing the font. +# The default value is: Helvetica. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of +# dot graphs. +# Minimum value: 4, maximum value: 24, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the default font as specified with +# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set +# the path where dot can find it using this tag. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_FONTPATH = + +# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for +# each documented class showing the direct and indirect inheritance relations. +# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a +# graph for each documented class showing the direct and indirect implementation +# dependencies (inheritance, containment, and class references variables) of the +# class with other documented classes. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for +# groups, showing the direct groups dependencies. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside the +# class node. If there are many fields or methods and many nodes the graph may +# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the +# number of items for each type to make the size more manageable. Set this to 0 +# for no limit. Note that the threshold may be exceeded by 50% before the limit +# is enforced. So when you set the threshold to 10, up to 15 fields may appear, +# but if the number exceeds 15, the total amount of fields shown is limited to +# 10. +# Minimum value: 0, maximum value: 100, default value: 10. +# This tag requires that the tag HAVE_DOT is set to YES. + +UML_LIMIT_NUM_FIELDS = 10 + +# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and +# collaboration graphs will show the relations between templates and their +# instances. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +TEMPLATE_RELATIONS = NO + +# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to +# YES then doxygen will generate a graph for each documented file showing the +# direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDE_GRAPH = YES + +# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are +# set to YES then doxygen will generate a graph for each documented file showing +# the direct and indirect include dependencies of the file with other documented +# files. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH tag is set to YES then doxygen will generate a call +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. Disabling a call graph can be +# accomplished by means of the command \hidecallgraph. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller +# dependency graph for every global function or class method. +# +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. Disabling a caller graph can be +# accomplished by means of the command \hidecallergraph. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical +# hierarchy of all classes instead of a textual one. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the +# dependencies a directory has on other directories in a graphical way. The +# dependency relations are determined by the #include relations between the +# files in the directories. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. For an explanation of the image formats see the section +# output formats in the documentation of the dot tool (Graphviz (see: +# http://www.graphviz.org/)). +# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order +# to make the SVG files visible in IE 9+ (other browsers do not have this +# requirement). +# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, +# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and +# png:gdiplus:gdiplus. +# The default value is: png. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# +# Note that this requires a modern browser other than Internet Explorer. Tested +# and working are Firefox, Chrome, Safari, and Opera. +# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make +# the SVG files visible. Older versions of IE do not have SVG support. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +INTERACTIVE_SVG = NO + +# The DOT_PATH tag can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the \dotfile +# command). +# This tag requires that the tag HAVE_DOT is set to YES. + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = + +# The DIAFILE_DIRS tag can be used to specify one or more directories that +# contain dia files that are included in the documentation (see the \diafile +# command). + +DIAFILE_DIRS = + +# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the +# path where java can find the plantuml.jar file. If left blank, it is assumed +# PlantUML is not used or called during a preprocessing step. Doxygen will +# generate a warning when it encounters a \startuml command in this case and +# will not generate output for the diagram. + +PLANTUML_JAR_PATH = + +# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a +# configuration file for plantuml. + +PLANTUML_CFG_FILE = + +# When using plantuml, the specified paths are searched for files specified by +# the !include statement in a plantuml block. + +PLANTUML_INCLUDE_PATH = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes +# that will be shown in the graph. If the number of nodes in a graph becomes +# larger than this value, doxygen will truncate the graph, which is visualized +# by representing a node as a red box. Note that doxygen if the number of direct +# children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that +# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. +# Minimum value: 0, maximum value: 10000, default value: 50. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs +# generated by dot. A depth value of 3 means that only nodes reachable from the +# root by following a path via at most 3 edges will be shown. Nodes that lay +# further from the root node will be omitted. Note that setting this option to 1 +# or 2 may greatly reduce the computation time needed for large code bases. Also +# note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. +# Minimum value: 0, maximum value: 1000, default value: 0. +# This tag requires that the tag HAVE_DOT is set to YES. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not seem +# to support this out of the box. +# +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) support +# this, this feature is disabled by default. +# The default value is: NO. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page +# explaining the meaning of the various boxes and arrows in the dot generated +# graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot +# files that are used to generate the various graphs. +# The default value is: YES. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_CLEANUP = YES diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/LICENSE b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/LICENSE new file mode 100644 index 000000000..201a5c0fd --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/LICENSE @@ -0,0 +1,3 @@ +This source repository is release under Apache2 and MIT licenses. + +See LICENSE.Apache2 and LICENSE.MIT for details. diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/LICENSE.Apache2 b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/LICENSE.Apache2 new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/LICENSE.Apache2 @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/LICENSE.MIT b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/LICENSE.MIT new file mode 100644 index 000000000..3a7e422b6 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/LICENSE.MIT @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2019 SiFive, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Makefile.am b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Makefile.am new file mode 100644 index 000000000..0166e2828 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Makefile.am @@ -0,0 +1,238 @@ +# Copyright 2018-2019 SiFive, Inc +# SPDX-License-Identifier: Apache-2.0 + +######################################################## +# Sources passed in by configure +######################################################## + +metal/machine.h: @MACHINE_HEADER@ + @mkdir -p $(dir $@) + cp $< $@ + +metal/machine/inline.h: @MACHINE_INLINE@ + @mkdir -p $(dir $@) + cp $< $@ + +metal/machine/platform.h: @PLATFORM_HEADER@ + @mkdir -p $(dir $@) + cp $< $@ + +nobase_include_HEADERS = \ + metal/machine.h \ + metal/machine/inline.h \ + metal/machine/platform.h + +# This will generate these sources before the compilation step +BUILT_SOURCES = \ + metal/machine.h \ + metal/machine/inline.h \ + metal/machine/platform.h + +######################################################## +# Metal header files +######################################################## + +nobase_include_HEADERS += \ + metal/drivers/fixed-clock.h \ + metal/drivers/fixed-factor-clock.h \ + metal/drivers/riscv_clint0.h \ + metal/drivers/riscv_cpu.h \ + metal/drivers/riscv_plic0.h \ + metal/drivers/sifive_buserror0.h \ + metal/drivers/sifive_ccache0.h \ + metal/drivers/sifive_clic0.h \ + metal/drivers/sifive_fe310-g000_hfrosc.h \ + metal/drivers/sifive_fe310-g000_hfxosc.h \ + metal/drivers/sifive_fe310-g000_lfrosc.h \ + metal/drivers/sifive_fe310-g000_pll.h \ + metal/drivers/sifive_fe310-g000_prci.h \ + metal/drivers/sifive_global-external-interrupts0.h \ + metal/drivers/sifive_gpio-buttons.h \ + metal/drivers/sifive_gpio-leds.h \ + metal/drivers/sifive_gpio-switches.h \ + metal/drivers/sifive_gpio0.h \ + metal/drivers/sifive_i2c0.h \ + metal/drivers/sifive_l2pf0.h \ + metal/drivers/sifive_local-external-interrupts0.h \ + metal/drivers/sifive_pwm0.h \ + metal/drivers/sifive_rtc0.h \ + metal/drivers/sifive_spi0.h \ + metal/drivers/sifive_test0.h \ + metal/drivers/sifive_trace.h \ + metal/drivers/sifive_uart0.h \ + metal/drivers/sifive_simuart0.h \ + metal/drivers/sifive_wdog0.h \ + metal/drivers/ucb_htif0.h \ + metal/atomic.h \ + metal/button.h \ + metal/cache.h \ + metal/clock.h \ + metal/compiler.h \ + metal/cpu.h \ + metal/csr.h \ + metal/gpio.h \ + metal/hpm.h \ + metal/i2c.h \ + metal/init.h \ + metal/interrupt.h \ + metal/io.h \ + metal/itim.h \ + metal/led.h \ + metal/lim.h \ + metal/lock.h \ + metal/memory.h \ + metal/pmp.h \ + metal/privilege.h \ + metal/pwm.h\ + metal/rtc.h \ + metal/shutdown.h \ + metal/scrub.h \ + metal/spi.h \ + metal/switch.h \ + metal/timer.h \ + metal/time.h \ + metal/tty.h \ + metal/uart.h \ + metal/watchdog.h + +######################################################## +# libmetal +######################################################## + +lib_LIBRARIES = libmetal.a + +libmetal_a_SOURCES = \ + src/drivers/fixed-clock.c \ + src/drivers/fixed-factor-clock.c \ + src/drivers/inline.c \ + src/drivers/riscv_clint0.c \ + src/drivers/riscv_cpu.c \ + src/drivers/riscv_plic0.c \ + src/drivers/sifive_buserror0.c \ + src/drivers/sifive_ccache0.c \ + src/drivers/sifive_clic0.c \ + src/drivers/sifive_fe310-g000_hfrosc.c \ + src/drivers/sifive_fe310-g000_hfxosc.c \ + src/drivers/sifive_fe310-g000_lfrosc.c \ + src/drivers/sifive_fe310-g000_pll.c \ + src/drivers/sifive_fe310-g000_prci.c \ + src/drivers/sifive_global-external-interrupts0.c \ + src/drivers/sifive_gpio-buttons.c \ + src/drivers/sifive_gpio-leds.c \ + src/drivers/sifive_gpio-switches.c \ + src/drivers/sifive_gpio0.c \ + src/drivers/sifive_i2c0.c \ + src/drivers/sifive_l2pf0.c \ + src/drivers/sifive_local-external-interrupts0.c \ + src/drivers/sifive_pwm0.c \ + src/drivers/sifive_rtc0.c \ + src/drivers/sifive_spi0.c \ + src/drivers/sifive_test0.c \ + src/drivers/sifive_trace.c \ + src/drivers/sifive_uart0.c \ + src/drivers/sifive_simuart0.c \ + src/drivers/sifive_wdog0.c \ + src/drivers/ucb_htif0.c \ + src/atomic.c \ + src/button.c \ + src/cache.c \ + src/clock.c \ + src/cpu.c \ + src/entry.S \ + src/scrub.S \ + src/trap.S \ + src/gpio.c \ + src/hpm.c \ + src/i2c.c \ + src/init.c \ + src/interrupt.c \ + src/led.c \ + src/lock.c \ + src/memory.c \ + src/pmp.c \ + src/privilege.c \ + src/pwm.c\ + src/rtc.c \ + src/shutdown.c \ + src/spi.c \ + src/switch.c \ + src/synchronize_harts.c \ + src/timer.c \ + src/time.c \ + src/trap.S \ + src/tty.c \ + src/uart.c \ + src/vector.S \ + src/watchdog.c + +######################################################## +# libsegger +######################################################## + +# Provide segger hook with Freedom Metal that is built when +# --with-builtin-libmetal-segger is passed to configure +if WITH_BUILTIN_LIBMETAL_SEGGER + +lib_LIBRARIES += libmetal-segger.a + +libmetal_segger_a_SOURCES = \ + gloss/crt0.S \ + segger/SEGGER_target_metal.c + +endif # WITH_BUILTIN_LIBMETAL_SEGGER + +######################################################## +# libgloss +######################################################## + +# Freedom Metal has its own libgloss implementation that is only built when +# --with-builtin-libgloss is passed to configure. +if WITH_BUILTIN_LIBGLOSS + +lib_LIBRARIES += libmetal-gloss.a + +libmetal_gloss_a_SOURCES = \ + gloss/crt0.S \ + gloss/nanosleep.c \ + gloss/sys_access.c \ + gloss/sys_chdir.c \ + gloss/sys_chmod.c \ + gloss/sys_chown.c \ + gloss/sys_clock_gettime.c \ + gloss/sys_close.c \ + gloss/sys_execve.c \ + gloss/sys_exit.c \ + gloss/sys_faccessat.c \ + gloss/sys_fork.c \ + gloss/sys_fstat.c \ + gloss/sys_fstatat.c \ + gloss/sys_ftime.c \ + gloss/sys_getcwd.c \ + gloss/sys_getpid.c \ + gloss/sys_gettimeofday.c \ + gloss/sys_isatty.c \ + gloss/sys_kill.c \ + gloss/sys_link.c \ + gloss/sys_lseek.c \ + gloss/sys_lstat.c \ + gloss/sys_open.c \ + gloss/sys_openat.c \ + gloss/sys_read.c \ + gloss/sys_sbrk.c \ + gloss/sys_stat.c \ + gloss/sys_sysconf.c \ + gloss/sys_times.c \ + gloss/sys_unlink.c \ + gloss/sys_utime.c \ + gloss/sys_wait.c \ + gloss/sys_write.c + +endif + +######################################################## +# Clean +######################################################## + +clean-local: + -rm -rf metal/machine.h metal/machine/inline.h + -rm -rf metal/machine/platform.h diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Makefile.in b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Makefile.in new file mode 100644 index 000000000..8bba3983b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/Makefile.in @@ -0,0 +1,1443 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Copyright 2018-2019 SiFive, Inc +# SPDX-License-Identifier: Apache-2.0 + +######################################################## +# Sources passed in by configure +######################################################## + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ + +######################################################## +# libsegger +######################################################## + +# Provide segger hook with Freedom Metal that is built when +# --with-builtin-libmetal-segger is passed to configure +@WITH_BUILTIN_LIBMETAL_SEGGER_TRUE@am__append_1 = libmetal-segger.a + +######################################################## +# libgloss +######################################################## + +# Freedom Metal has its own libgloss implementation that is only built when +# --with-builtin-libgloss is passed to configure. +@WITH_BUILTIN_LIBGLOSS_TRUE@am__append_2 = libmetal-gloss.a +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(nobase_include_HEADERS) \ + $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" +LIBRARIES = $(lib_LIBRARIES) +ARFLAGS = cru +AM_V_AR = $(am__v_AR_@AM_V@) +am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) +am__v_AR_0 = @echo " AR " $@; +am__v_AR_1 = +libmetal_gloss_a_AR = $(AR) $(ARFLAGS) +libmetal_gloss_a_LIBADD = +am__libmetal_gloss_a_SOURCES_DIST = gloss/crt0.S gloss/nanosleep.c \ + gloss/sys_access.c gloss/sys_chdir.c gloss/sys_chmod.c \ + gloss/sys_chown.c gloss/sys_clock_gettime.c gloss/sys_close.c \ + gloss/sys_execve.c gloss/sys_exit.c gloss/sys_faccessat.c \ + gloss/sys_fork.c gloss/sys_fstat.c gloss/sys_fstatat.c \ + gloss/sys_ftime.c gloss/sys_getcwd.c gloss/sys_getpid.c \ + gloss/sys_gettimeofday.c gloss/sys_isatty.c gloss/sys_kill.c \ + gloss/sys_link.c gloss/sys_lseek.c gloss/sys_lstat.c \ + gloss/sys_open.c gloss/sys_openat.c gloss/sys_read.c \ + gloss/sys_sbrk.c gloss/sys_stat.c gloss/sys_sysconf.c \ + gloss/sys_times.c gloss/sys_unlink.c gloss/sys_utime.c \ + gloss/sys_wait.c gloss/sys_write.c +am__dirstamp = $(am__leading_dot)dirstamp +@WITH_BUILTIN_LIBGLOSS_TRUE@am_libmetal_gloss_a_OBJECTS = \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/crt0.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/nanosleep.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_access.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_chdir.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_chmod.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_chown.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_clock_gettime.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_close.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_execve.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_exit.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_faccessat.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_fork.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_fstat.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_fstatat.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_ftime.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_getcwd.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_getpid.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_gettimeofday.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_isatty.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_kill.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_link.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_lseek.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_lstat.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_open.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_openat.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_read.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_sbrk.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_stat.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_sysconf.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_times.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_unlink.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_utime.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_wait.$(OBJEXT) \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_write.$(OBJEXT) +libmetal_gloss_a_OBJECTS = $(am_libmetal_gloss_a_OBJECTS) +libmetal_segger_a_AR = $(AR) $(ARFLAGS) +libmetal_segger_a_LIBADD = +am__libmetal_segger_a_SOURCES_DIST = gloss/crt0.S \ + segger/SEGGER_target_metal.c +@WITH_BUILTIN_LIBMETAL_SEGGER_TRUE@am_libmetal_segger_a_OBJECTS = \ +@WITH_BUILTIN_LIBMETAL_SEGGER_TRUE@ gloss/crt0.$(OBJEXT) \ +@WITH_BUILTIN_LIBMETAL_SEGGER_TRUE@ segger/SEGGER_target_metal.$(OBJEXT) +libmetal_segger_a_OBJECTS = $(am_libmetal_segger_a_OBJECTS) +libmetal_a_AR = $(AR) $(ARFLAGS) +libmetal_a_LIBADD = +am_libmetal_a_OBJECTS = src/drivers/fixed-clock.$(OBJEXT) \ + src/drivers/fixed-factor-clock.$(OBJEXT) \ + src/drivers/inline.$(OBJEXT) \ + src/drivers/riscv_clint0.$(OBJEXT) \ + src/drivers/riscv_cpu.$(OBJEXT) \ + src/drivers/riscv_plic0.$(OBJEXT) \ + src/drivers/sifive_buserror0.$(OBJEXT) \ + src/drivers/sifive_ccache0.$(OBJEXT) \ + src/drivers/sifive_clic0.$(OBJEXT) \ + src/drivers/sifive_fe310-g000_hfrosc.$(OBJEXT) \ + src/drivers/sifive_fe310-g000_hfxosc.$(OBJEXT) \ + src/drivers/sifive_fe310-g000_lfrosc.$(OBJEXT) \ + src/drivers/sifive_fe310-g000_pll.$(OBJEXT) \ + src/drivers/sifive_fe310-g000_prci.$(OBJEXT) \ + src/drivers/sifive_global-external-interrupts0.$(OBJEXT) \ + src/drivers/sifive_gpio-buttons.$(OBJEXT) \ + src/drivers/sifive_gpio-leds.$(OBJEXT) \ + src/drivers/sifive_gpio-switches.$(OBJEXT) \ + src/drivers/sifive_gpio0.$(OBJEXT) \ + src/drivers/sifive_i2c0.$(OBJEXT) \ + src/drivers/sifive_l2pf0.$(OBJEXT) \ + src/drivers/sifive_local-external-interrupts0.$(OBJEXT) \ + src/drivers/sifive_pwm0.$(OBJEXT) \ + src/drivers/sifive_rtc0.$(OBJEXT) \ + src/drivers/sifive_spi0.$(OBJEXT) \ + src/drivers/sifive_test0.$(OBJEXT) \ + src/drivers/sifive_trace.$(OBJEXT) \ + src/drivers/sifive_uart0.$(OBJEXT) \ + src/drivers/sifive_simuart0.$(OBJEXT) \ + src/drivers/sifive_wdog0.$(OBJEXT) \ + src/drivers/ucb_htif0.$(OBJEXT) src/atomic.$(OBJEXT) \ + src/button.$(OBJEXT) src/cache.$(OBJEXT) src/clock.$(OBJEXT) \ + src/cpu.$(OBJEXT) src/entry.$(OBJEXT) src/scrub.$(OBJEXT) \ + src/trap.$(OBJEXT) src/gpio.$(OBJEXT) src/hpm.$(OBJEXT) \ + src/i2c.$(OBJEXT) src/init.$(OBJEXT) src/interrupt.$(OBJEXT) \ + src/led.$(OBJEXT) src/lock.$(OBJEXT) src/memory.$(OBJEXT) \ + src/pmp.$(OBJEXT) src/privilege.$(OBJEXT) src/pwm.$(OBJEXT) \ + src/rtc.$(OBJEXT) src/shutdown.$(OBJEXT) src/spi.$(OBJEXT) \ + src/switch.$(OBJEXT) src/synchronize_harts.$(OBJEXT) \ + src/timer.$(OBJEXT) src/time.$(OBJEXT) src/trap.$(OBJEXT) \ + src/tty.$(OBJEXT) src/uart.$(OBJEXT) src/vector.$(OBJEXT) \ + src/watchdog.$(OBJEXT) +libmetal_a_OBJECTS = $(am_libmetal_a_OBJECTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) +AM_V_CPPAS = $(am__v_CPPAS_@AM_V@) +am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@) +am__v_CPPAS_0 = @echo " CPPAS " $@; +am__v_CPPAS_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libmetal_gloss_a_SOURCES) $(libmetal_segger_a_SOURCES) \ + $(libmetal_a_SOURCES) +DIST_SOURCES = $(am__libmetal_gloss_a_SOURCES_DIST) \ + $(am__libmetal_segger_a_SOURCES_DIST) $(libmetal_a_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(nobase_include_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +AM_RECURSIVE_TARGETS = cscope +am__DIST_COMMON = $(srcdir)/Makefile.in ar-lib compile config.guess \ + config.sub depcomp install-sh missing +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +DIST_TARGETS = dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EXEEXT = @EXEEXT@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MACHINE_HEADER = @MACHINE_HEADER@ +MACHINE_INLINE = @MACHINE_INLINE@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PLATFORM_HEADER = @PLATFORM_HEADER@ +RANLIB = @RANLIB@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +######################################################## +# Metal header files +######################################################## +nobase_include_HEADERS = metal/machine.h metal/machine/inline.h \ + metal/machine/platform.h metal/drivers/fixed-clock.h \ + metal/drivers/fixed-factor-clock.h \ + metal/drivers/riscv_clint0.h metal/drivers/riscv_cpu.h \ + metal/drivers/riscv_plic0.h metal/drivers/sifive_buserror0.h \ + metal/drivers/sifive_ccache0.h metal/drivers/sifive_clic0.h \ + metal/drivers/sifive_fe310-g000_hfrosc.h \ + metal/drivers/sifive_fe310-g000_hfxosc.h \ + metal/drivers/sifive_fe310-g000_lfrosc.h \ + metal/drivers/sifive_fe310-g000_pll.h \ + metal/drivers/sifive_fe310-g000_prci.h \ + metal/drivers/sifive_global-external-interrupts0.h \ + metal/drivers/sifive_gpio-buttons.h \ + metal/drivers/sifive_gpio-leds.h \ + metal/drivers/sifive_gpio-switches.h \ + metal/drivers/sifive_gpio0.h metal/drivers/sifive_i2c0.h \ + metal/drivers/sifive_l2pf0.h \ + metal/drivers/sifive_local-external-interrupts0.h \ + metal/drivers/sifive_pwm0.h metal/drivers/sifive_rtc0.h \ + metal/drivers/sifive_spi0.h metal/drivers/sifive_test0.h \ + metal/drivers/sifive_trace.h metal/drivers/sifive_uart0.h \ + metal/drivers/sifive_simuart0.h metal/drivers/sifive_wdog0.h \ + metal/drivers/ucb_htif0.h metal/atomic.h metal/button.h \ + metal/cache.h metal/clock.h metal/compiler.h metal/cpu.h \ + metal/csr.h metal/gpio.h metal/hpm.h metal/i2c.h metal/init.h \ + metal/interrupt.h metal/io.h metal/itim.h metal/led.h \ + metal/lim.h metal/lock.h metal/memory.h metal/pmp.h \ + metal/privilege.h metal/pwm.h metal/rtc.h metal/shutdown.h \ + metal/scrub.h metal/spi.h metal/switch.h metal/timer.h \ + metal/time.h metal/tty.h metal/uart.h metal/watchdog.h + +# This will generate these sources before the compilation step +BUILT_SOURCES = \ + metal/machine.h \ + metal/machine/inline.h \ + metal/machine/platform.h + + +######################################################## +# libmetal +######################################################## +lib_LIBRARIES = libmetal.a $(am__append_1) $(am__append_2) +libmetal_a_SOURCES = \ + src/drivers/fixed-clock.c \ + src/drivers/fixed-factor-clock.c \ + src/drivers/inline.c \ + src/drivers/riscv_clint0.c \ + src/drivers/riscv_cpu.c \ + src/drivers/riscv_plic0.c \ + src/drivers/sifive_buserror0.c \ + src/drivers/sifive_ccache0.c \ + src/drivers/sifive_clic0.c \ + src/drivers/sifive_fe310-g000_hfrosc.c \ + src/drivers/sifive_fe310-g000_hfxosc.c \ + src/drivers/sifive_fe310-g000_lfrosc.c \ + src/drivers/sifive_fe310-g000_pll.c \ + src/drivers/sifive_fe310-g000_prci.c \ + src/drivers/sifive_global-external-interrupts0.c \ + src/drivers/sifive_gpio-buttons.c \ + src/drivers/sifive_gpio-leds.c \ + src/drivers/sifive_gpio-switches.c \ + src/drivers/sifive_gpio0.c \ + src/drivers/sifive_i2c0.c \ + src/drivers/sifive_l2pf0.c \ + src/drivers/sifive_local-external-interrupts0.c \ + src/drivers/sifive_pwm0.c \ + src/drivers/sifive_rtc0.c \ + src/drivers/sifive_spi0.c \ + src/drivers/sifive_test0.c \ + src/drivers/sifive_trace.c \ + src/drivers/sifive_uart0.c \ + src/drivers/sifive_simuart0.c \ + src/drivers/sifive_wdog0.c \ + src/drivers/ucb_htif0.c \ + src/atomic.c \ + src/button.c \ + src/cache.c \ + src/clock.c \ + src/cpu.c \ + src/entry.S \ + src/scrub.S \ + src/trap.S \ + src/gpio.c \ + src/hpm.c \ + src/i2c.c \ + src/init.c \ + src/interrupt.c \ + src/led.c \ + src/lock.c \ + src/memory.c \ + src/pmp.c \ + src/privilege.c \ + src/pwm.c\ + src/rtc.c \ + src/shutdown.c \ + src/spi.c \ + src/switch.c \ + src/synchronize_harts.c \ + src/timer.c \ + src/time.c \ + src/trap.S \ + src/tty.c \ + src/uart.c \ + src/vector.S \ + src/watchdog.c + +@WITH_BUILTIN_LIBMETAL_SEGGER_TRUE@libmetal_segger_a_SOURCES = \ +@WITH_BUILTIN_LIBMETAL_SEGGER_TRUE@ gloss/crt0.S \ +@WITH_BUILTIN_LIBMETAL_SEGGER_TRUE@ segger/SEGGER_target_metal.c + +@WITH_BUILTIN_LIBGLOSS_TRUE@libmetal_gloss_a_SOURCES = \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/crt0.S \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/nanosleep.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_access.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_chdir.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_chmod.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_chown.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_clock_gettime.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_close.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_execve.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_exit.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_faccessat.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_fork.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_fstat.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_fstatat.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_ftime.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_getcwd.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_getpid.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_gettimeofday.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_isatty.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_kill.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_link.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_lseek.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_lstat.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_open.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_openat.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_read.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_sbrk.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_stat.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_sysconf.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_times.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_unlink.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_utime.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_wait.c \ +@WITH_BUILTIN_LIBGLOSS_TRUE@ gloss/sys_write.c + +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .S .c .o .obj +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): +install-libLIBRARIES: $(lib_LIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(INSTALL_DATA) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(INSTALL_DATA) $$list2 "$(DESTDIR)$(libdir)" || exit $$?; } + @$(POST_INSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + if test -f $$p; then \ + $(am__strip_dir) \ + echo " ( cd '$(DESTDIR)$(libdir)' && $(RANLIB) $$f )"; \ + ( cd "$(DESTDIR)$(libdir)" && $(RANLIB) $$f ) || exit $$?; \ + else :; fi; \ + done + +uninstall-libLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(libdir)'; $(am__uninstall_files_from_dir) + +clean-libLIBRARIES: + -test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES) +gloss/$(am__dirstamp): + @$(MKDIR_P) gloss + @: > gloss/$(am__dirstamp) +gloss/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) gloss/$(DEPDIR) + @: > gloss/$(DEPDIR)/$(am__dirstamp) +gloss/crt0.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/nanosleep.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_access.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_chdir.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_chmod.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_chown.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_clock_gettime.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_close.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_execve.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_exit.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_faccessat.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_fork.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_fstat.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_fstatat.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_ftime.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_getcwd.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_getpid.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_gettimeofday.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_isatty.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_kill.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_link.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_lseek.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_lstat.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_open.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_openat.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_read.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_sbrk.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_stat.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_sysconf.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_times.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_unlink.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_utime.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_wait.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) +gloss/sys_write.$(OBJEXT): gloss/$(am__dirstamp) \ + gloss/$(DEPDIR)/$(am__dirstamp) + +libmetal-gloss.a: $(libmetal_gloss_a_OBJECTS) $(libmetal_gloss_a_DEPENDENCIES) $(EXTRA_libmetal_gloss_a_DEPENDENCIES) + $(AM_V_at)-rm -f libmetal-gloss.a + $(AM_V_AR)$(libmetal_gloss_a_AR) libmetal-gloss.a $(libmetal_gloss_a_OBJECTS) $(libmetal_gloss_a_LIBADD) + $(AM_V_at)$(RANLIB) libmetal-gloss.a +segger/$(am__dirstamp): + @$(MKDIR_P) segger + @: > segger/$(am__dirstamp) +segger/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) segger/$(DEPDIR) + @: > segger/$(DEPDIR)/$(am__dirstamp) +segger/SEGGER_target_metal.$(OBJEXT): segger/$(am__dirstamp) \ + segger/$(DEPDIR)/$(am__dirstamp) + +libmetal-segger.a: $(libmetal_segger_a_OBJECTS) $(libmetal_segger_a_DEPENDENCIES) $(EXTRA_libmetal_segger_a_DEPENDENCIES) + $(AM_V_at)-rm -f libmetal-segger.a + $(AM_V_AR)$(libmetal_segger_a_AR) libmetal-segger.a $(libmetal_segger_a_OBJECTS) $(libmetal_segger_a_LIBADD) + $(AM_V_at)$(RANLIB) libmetal-segger.a +src/drivers/$(am__dirstamp): + @$(MKDIR_P) src/drivers + @: > src/drivers/$(am__dirstamp) +src/drivers/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/drivers/$(DEPDIR) + @: > src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/fixed-clock.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/fixed-factor-clock.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/inline.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/riscv_clint0.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/riscv_cpu.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/riscv_plic0.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_buserror0.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_ccache0.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_clic0.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_fe310-g000_hfrosc.$(OBJEXT): \ + src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_fe310-g000_hfxosc.$(OBJEXT): \ + src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_fe310-g000_lfrosc.$(OBJEXT): \ + src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_fe310-g000_pll.$(OBJEXT): \ + src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_fe310-g000_prci.$(OBJEXT): \ + src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_global-external-interrupts0.$(OBJEXT): \ + src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_gpio-buttons.$(OBJEXT): \ + src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_gpio-leds.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_gpio-switches.$(OBJEXT): \ + src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_gpio0.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_i2c0.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_l2pf0.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_local-external-interrupts0.$(OBJEXT): \ + src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_pwm0.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_rtc0.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_spi0.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_test0.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_trace.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_uart0.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_simuart0.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/sifive_wdog0.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/drivers/ucb_htif0.$(OBJEXT): src/drivers/$(am__dirstamp) \ + src/drivers/$(DEPDIR)/$(am__dirstamp) +src/$(am__dirstamp): + @$(MKDIR_P) src + @: > src/$(am__dirstamp) +src/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/$(DEPDIR) + @: > src/$(DEPDIR)/$(am__dirstamp) +src/atomic.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/button.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/cache.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/clock.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/cpu.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/entry.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/scrub.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/trap.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/gpio.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/hpm.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/i2c.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/init.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/interrupt.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/led.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/lock.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/memory.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/pmp.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/privilege.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/pwm.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/rtc.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/shutdown.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/spi.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/switch.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/synchronize_harts.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/timer.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/time.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/tty.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/uart.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/vector.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/watchdog.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) + +libmetal.a: $(libmetal_a_OBJECTS) $(libmetal_a_DEPENDENCIES) $(EXTRA_libmetal_a_DEPENDENCIES) + $(AM_V_at)-rm -f libmetal.a + $(AM_V_AR)$(libmetal_a_AR) libmetal.a $(libmetal_a_OBJECTS) $(libmetal_a_LIBADD) + $(AM_V_at)$(RANLIB) libmetal.a + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f gloss/*.$(OBJEXT) + -rm -f segger/*.$(OBJEXT) + -rm -f src/*.$(OBJEXT) + -rm -f src/drivers/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/crt0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/nanosleep.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_access.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_chdir.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_chmod.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_chown.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_clock_gettime.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_close.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_execve.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_exit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_faccessat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_fork.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_fstat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_fstatat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_ftime.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_getcwd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_getpid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_gettimeofday.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_isatty.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_kill.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_link.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_lseek.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_lstat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_open.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_openat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_read.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_sbrk.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_stat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_sysconf.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_times.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_unlink.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_utime.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_wait.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@gloss/$(DEPDIR)/sys_write.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@segger/$(DEPDIR)/SEGGER_target_metal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/atomic.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/button.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/cache.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/clock.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/cpu.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/entry.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gpio.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/hpm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/i2c.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/init.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/interrupt.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/led.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/lock.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/memory.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pmp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/privilege.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/pwm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/rtc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/scrub.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/shutdown.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/spi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/switch.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/synchronize_harts.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/time.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/timer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/trap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/tty.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/uart.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/vector.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/watchdog.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/fixed-clock.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/fixed-factor-clock.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/inline.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/riscv_clint0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/riscv_cpu.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/riscv_plic0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_buserror0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_ccache0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_clic0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_fe310-g000_hfrosc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_fe310-g000_hfxosc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_fe310-g000_lfrosc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_fe310-g000_pll.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_fe310-g000_prci.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_global-external-interrupts0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_gpio-buttons.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_gpio-leds.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_gpio-switches.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_gpio0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_i2c0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_l2pf0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_local-external-interrupts0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_pwm0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_rtc0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_simuart0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_spi0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_test0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_trace.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_uart0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/sifive_wdog0.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/drivers/$(DEPDIR)/ucb_htif0.Po@am__quote@ + +.S.o: +@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCCAS_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ $< + +.S.obj: +@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCCAS_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +install-nobase_includeHEADERS: $(nobase_include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \ + echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \ + $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --srcdir=../.. --prefix="$$dc_install_base" \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(LIBRARIES) $(HEADERS) +installdirs: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f gloss/$(DEPDIR)/$(am__dirstamp) + -rm -f gloss/$(am__dirstamp) + -rm -f segger/$(DEPDIR)/$(am__dirstamp) + -rm -f segger/$(am__dirstamp) + -rm -f src/$(DEPDIR)/$(am__dirstamp) + -rm -f src/$(am__dirstamp) + -rm -f src/drivers/$(DEPDIR)/$(am__dirstamp) + -rm -f src/drivers/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-generic clean-libLIBRARIES clean-local mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf gloss/$(DEPDIR) segger/$(DEPDIR) src/$(DEPDIR) src/drivers/$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-nobase_includeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-libLIBRARIES + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf gloss/$(DEPDIR) segger/$(DEPDIR) src/$(DEPDIR) src/drivers/$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-libLIBRARIES uninstall-nobase_includeHEADERS + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-am clean \ + clean-cscope clean-generic clean-libLIBRARIES clean-local \ + cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ + dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ + distcheck distclean distclean-compile distclean-generic \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-libLIBRARIES install-man \ + install-nobase_includeHEADERS install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-libLIBRARIES \ + uninstall-nobase_includeHEADERS + +.PRECIOUS: Makefile + + +metal/machine.h: @MACHINE_HEADER@ + @mkdir -p $(dir $@) + cp $< $@ + +metal/machine/inline.h: @MACHINE_INLINE@ + @mkdir -p $(dir $@) + cp $< $@ + +metal/machine/platform.h: @PLATFORM_HEADER@ + @mkdir -p $(dir $@) + cp $< $@ + +######################################################## +# Clean +######################################################## + +clean-local: + -rm -rf metal/machine.h metal/machine/inline.h + -rm -rf metal/machine/platform.h + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/README.md b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/README.md new file mode 100644 index 000000000..e8237d04c --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/README.md @@ -0,0 +1,4 @@ +# Freedom Metal Machine Compatibility Library + +Documentation for the Freedom Metal library [can be found here](https://sifive.github.io/freedom-metal-docs/). + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/aclocal.m4 b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/aclocal.m4 new file mode 100644 index 000000000..42ec7eedc --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/aclocal.m4 @@ -0,0 +1,1268 @@ +# generated automatically by aclocal 1.15 -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. + +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically 'autoreconf'.])]) + +# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.15' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.15], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.15])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# Copyright (C) 2011-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_AR([ACT-IF-FAIL]) +# ------------------------- +# Try to determine the archiver interface, and trigger the ar-lib wrapper +# if it is needed. If the detection of archiver interface fails, run +# ACT-IF-FAIL (default is to abort configure with a proper error message). +AC_DEFUN([AM_PROG_AR], +[AC_BEFORE([$0], [LT_INIT])dnl +AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([ar-lib])dnl +AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) +: ${AR=ar} + +AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], + [AC_LANG_PUSH([C]) + am_cv_ar_interface=ar + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], + [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([am_ar_try]) + if test "$ac_status" -eq 0; then + am_cv_ar_interface=ar + else + am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([am_ar_try]) + if test "$ac_status" -eq 0; then + am_cv_ar_interface=lib + else + am_cv_ar_interface=unknown + fi + fi + rm -f conftest.lib libconftest.a + ]) + AC_LANG_POP([C])]) + +case $am_cv_ar_interface in +ar) + ;; +lib) + # Microsoft lib, so override with the ar-lib wrapper script. + # FIXME: It is wrong to rewrite AR. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__AR in this case, + # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something + # similar. + AR="$am_aux_dir/ar-lib $AR" + ;; +unknown) + m4_default([$1], + [AC_MSG_ERROR([could not determine $AR interface])]) + ;; +esac +AC_SUBST([AR])dnl +]) + +# Figure out how to run the assembler. -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_AS +# ---------- +AC_DEFUN([AM_PROG_AS], +[# By default we simply use the C compiler to build assembly code. +AC_REQUIRE([AC_PROG_CC]) +test "${CCAS+set}" = set || CCAS=$CC +test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS +AC_ARG_VAR([CCAS], [assembler compiler command (defaults to CC)]) +AC_ARG_VAR([CCASFLAGS], [assembler compiler flags (defaults to CFLAGS)]) +_AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl +]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each '.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: <http://www.gnu.org/software/coreutils/>. + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless 'enable' is passed literally. +# For symmetry, 'disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], + [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], + am_maintainer_other[ make rules and dependencies not useful + (and sometimes confusing) to the casual installer])], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken + alias in your environment]) + fi + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar <conftest.tar]) + AM_RUN_LOG([cat conftest.dir/file]) + grep GrepMe conftest.dir/file >/dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/ar-lib b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/ar-lib new file mode 100755 index 000000000..463b9ec02 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/ar-lib @@ -0,0 +1,270 @@ +#! /bin/sh +# Wrapper for Microsoft lib.exe + +me=ar-lib +scriptversion=2012-03-01.08; # UTC + +# Copyright (C) 2010-2014 Free Software Foundation, Inc. +# Written by Peter Rosin <peda@lysator.liu.se>. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to <bug-automake@gnu.org> or send patches to +# <automake-patches@gnu.org>. + + +# func_error message +func_error () +{ + echo "$me: $1" 1>&2 + exit 1 +} + +file_conv= + +# func_file_conv build_file +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv in + mingw) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_at_file at_file operation archive +# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE +# for each of them. +# When interpreting the content of the @FILE, do NOT use func_file_conv, +# since the user would need to supply preconverted file names to +# binutils ar, at least for MinGW. +func_at_file () +{ + operation=$2 + archive=$3 + at_file_contents=`cat "$1"` + eval set x "$at_file_contents" + shift + + for member + do + $AR -NOLOGO $operation:"$member" "$archive" || exit $? + done +} + +case $1 in + '') + func_error "no command. Try '$0 --help' for more information." + ;; + -h | --h*) + cat <<EOF +Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...] + +Members may be specified in a file named with @FILE. +EOF + exit $? + ;; + -v | --v*) + echo "$me, version $scriptversion" + exit $? + ;; +esac + +if test $# -lt 3; then + func_error "you must specify a program, an action and an archive" +fi + +AR=$1 +shift +while : +do + if test $# -lt 2; then + func_error "you must specify a program, an action and an archive" + fi + case $1 in + -lib | -LIB \ + | -ltcg | -LTCG \ + | -machine* | -MACHINE* \ + | -subsystem* | -SUBSYSTEM* \ + | -verbose | -VERBOSE \ + | -wx* | -WX* ) + AR="$AR $1" + shift + ;; + *) + action=$1 + shift + break + ;; + esac +done +orig_archive=$1 +shift +func_file_conv "$orig_archive" +archive=$file + +# strip leading dash in $action +action=${action#-} + +delete= +extract= +list= +quick= +replace= +index= +create= + +while test -n "$action" +do + case $action in + d*) delete=yes ;; + x*) extract=yes ;; + t*) list=yes ;; + q*) quick=yes ;; + r*) replace=yes ;; + s*) index=yes ;; + S*) ;; # the index is always updated implicitly + c*) create=yes ;; + u*) ;; # TODO: don't ignore the update modifier + v*) ;; # TODO: don't ignore the verbose modifier + *) + func_error "unknown action specified" + ;; + esac + action=${action#?} +done + +case $delete$extract$list$quick$replace,$index in + yes,* | ,yes) + ;; + yesyes*) + func_error "more than one action specified" + ;; + *) + func_error "no action specified" + ;; +esac + +if test -n "$delete"; then + if test ! -f "$orig_archive"; then + func_error "archive not found" + fi + for member + do + case $1 in + @*) + func_at_file "${1#@}" -REMOVE "$archive" + ;; + *) + func_file_conv "$1" + $AR -NOLOGO -REMOVE:"$file" "$archive" || exit $? + ;; + esac + done + +elif test -n "$extract"; then + if test ! -f "$orig_archive"; then + func_error "archive not found" + fi + if test $# -gt 0; then + for member + do + case $1 in + @*) + func_at_file "${1#@}" -EXTRACT "$archive" + ;; + *) + func_file_conv "$1" + $AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $? + ;; + esac + done + else + $AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member + do + $AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $? + done + fi + +elif test -n "$quick$replace"; then + if test ! -f "$orig_archive"; then + if test -z "$create"; then + echo "$me: creating $orig_archive" + fi + orig_archive= + else + orig_archive=$archive + fi + + for member + do + case $1 in + @*) + func_file_conv "${1#@}" + set x "$@" "@$file" + ;; + *) + func_file_conv "$1" + set x "$@" "$file" + ;; + esac + shift + shift + done + + if test -n "$orig_archive"; then + $AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $? + else + $AR -NOLOGO -OUT:"$archive" "$@" || exit $? + fi + +elif test -n "$list"; then + if test ! -f "$orig_archive"; then + func_error "archive not found" + fi + $AR -NOLOGO -LIST "$archive" || exit $? +fi diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/build.wake b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/build.wake new file mode 100644 index 000000000..21edd636f --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/build.wake @@ -0,0 +1,150 @@ +tuple MachineExecutionEnvironment = + Job_: Job + IncludeDir_: String + LibDir_: String + LibMetal_: Path + LibMetalGloss_: Path + ConfigOptions: FreedomMetalConfigureOptions + AllOutputs_: List Path + +global def getMachineExecutionEnvironmentJob = getMachineExecutionEnvironmentJob_ +global def getMachineExecutionEnvironmentLibMetal = getMachineExecutionEnvironmentLibMetal_ +global def getMachineExecutionEnvironmentLibMetalGloss = getMachineExecutionEnvironmentLibMetalGloss_ +global def getMachineExecutionEnvironmentIncludeDir = getMachineExecutionEnvironmentIncludeDir_ +global def getMachineExecutionEnvironmentLibDir = getMachineExecutionEnvironmentLibDir_ +global def getMachineExecutionEnvironmentAllOutputs = getMachineExecutionEnvironmentAllOutputs_ + +global def getMachineExecutionEnvironmentRISCV_ARCH = _.getMachineExecutionEnvironmentConfigOptions.getFreedomMetalConfigureOptionsRISCV_ARCH +global def getMachineExecutionEnvironmentRISCV_ABI = _.getMachineExecutionEnvironmentConfigOptions.getFreedomMetalConfigureOptionsRISCV_ABI +global def getMachineExecutionEnvironmentRISCV_CMODEL = _.getMachineExecutionEnvironmentConfigOptions.getFreedomMetalConfigureOptionsRISCV_CMODEL +global def getMachineExecutionEnvironmentHost = _.getMachineExecutionEnvironmentConfigOptions.getFreedomMetalConfigureOptionsHost +global def getMachineExecutionEnvironmentPrefix = _.getMachineExecutionEnvironmentConfigOptions.getFreedomMetalConfigureOptionsOutputDir +global def getMachineExecutionEnvironmentName = _.getMachineExecutionEnvironmentConfigOptions.getFreedomMetalConfigureOptionsMachineName +global def getMachineExecutionEnvironmentHeader = _.getMachineExecutionEnvironmentConfigOptions.getFreedomMetalConfigureOptionsMachineHeader +global def getMachineExecutionEnvironmentLdScript = _.getMachineExecutionEnvironmentConfigOptions.getFreedomMetalConfigureOptionsMachineLdScript + +tuple FreedomMetalConfigureOptions = + global Resources: List String + global RISCV_ARCH: String + global RISCV_ABI: String + global RISCV_CMODEL: String + global Host: String + global OutputDir: String + global MachineName: String + global MachineHeader: Path + global MachineInlineHeader: Path + global PlatformHeader: Path + global MachineLdScript: Path + +global def defaultSiFiveRISCVResources = "riscv-tools/2019.05.0", Nil + +global def makeFreedomMetalConfigureOptions arch abi cmodel host outputDir name header inlineHeader platformHeader ldScript = + def resources = defaultSiFiveRISCVResources + FreedomMetalConfigureOptions resources arch abi cmodel host outputDir name header inlineHeader platformHeader ldScript + +global tuple MakeElfOptions = + global MEE: MachineExecutionEnvironment + global ProgramSrcs: List Path + global CFlags: List String + global LFlags: List String + global IncludeDirs: List String + global ElfFile: String + +global def runFreedomMetalInstall options = + def outputDir = options.getFreedomMetalConfigureOptionsOutputDir + def metalHeader = options.getFreedomMetalConfigureOptionsMachineHeader + def metalInline = options.getFreedomMetalConfigureOptionsMachineInlineHeader + def platformHeader = options.getFreedomMetalConfigureOptionsPlatformHeader + + def metalInstallDir = outputDir + + def installedFreedomMetal = + def inputs = + sources "freedom-metal" `.*` + | filter (!matches `freedom-metal/doc/.*` _.getPathName) + def cmdline = + "rsync", + "-r", + "--exclude", "freedom-metal/doc", + "--exclude", "freedom-metal/.git", + "--exclude", "*.wake", + "freedom-metal", + outputDir, + Nil + def fnOutputs _ = + files "freedom-metal" `.*` + | filter (!matches `freedom-metal/(\.git|doc)/.*` _) + | filter (!matches `.*\.(in|am|m4|wake)` _) # exclude these because autoconf modfies them + | filter (!matches `(.*/)?(configure)` _) + | map ("{metalInstallDir}/{_}") + + makePlan cmdline inputs + | setPlanFnOutputs fnOutputs + | setPlanLocalOnly True + | runJob + | getJobOutputs + + + def runDir = "{metalInstallDir}/freedom-metal" + def cmdline = "bash", "-c", "% + set -eo pipefail + machine_header=$(pwd)/%{metalHeader.getPathName} + machine_inline=$(pwd)/%{metalInline.getPathName} + platform_header=$(pwd)/%{platformHeader.getPathName} + install_dir=$(pwd)/%{outputDir} + export RISCV_PATH=$RISCV + cd %{runDir} + ./configure \ + --host=%{options.getFreedomMetalConfigureOptionsHost} \ + --with-builtin-libgloss \ + --with-machine-header=$machine_header \ + --with-machine-inline=$machine_inline \ + --with-platform-header=$platform_header \ + --prefix= + make \ + RANLIB="riscv64-unknown-elf-ranlib -D" \ + ARFLAGS=Dcr + make \ + RANLIB="riscv64-unknown-elf-ranlib -D" \ + ARFLAGS=Dcr \ + DESTDIR=$install_dir \ + install + %", Nil + + def inputs = mkdir outputDir, metalHeader, installedFreedomMetal + def foutputs _ = + files "{outputDir}/include" `.*` + ++ files "{outputDir}/lib" `.*` + def withCFlags = + def march = options.getFreedomMetalConfigureOptionsRISCV_ARCH + def mabi = options.getFreedomMetalConfigureOptionsRISCV_ABI + def cmodel = options.getFreedomMetalConfigureOptionsRISCV_CMODEL + "CFLAGS=-march={march} -mabi={mabi} -g -mcmodel={cmodel}", _ + + def job = + makePlan cmdline inputs + | setPlanLocalOnly True + | setPlanFnOutputs foutputs + | setPlanResources options.getFreedomMetalConfigureOptionsResources + | editPlanEnvironment withCFlags + | runJob + def makeOutputs = job.getJobOutputs + + def getFile f msg = match (makeOutputs | map getPathResult | findFail) + Fail e = makeBadPath e + Pass _ = + filter (simplify f ==~ _.getPathName) makeOutputs + | head + | getOrElse msg.makeError.makeBadPath + + def libmetal = + def fileName = "{outputDir}/lib/libmetal.a" + getFile fileName "Failed to compile libmetal: {fileName}" + + def libmetalGloss = + def fileName = "{outputDir}/lib/libmetal-gloss.a" + getFile fileName "Failed to compile libgloss: {fileName}" + + def includeDir = "{outputDir}/include" + def libDir = "{outputDir}/lib" + MachineExecutionEnvironment job includeDir libDir libmetal libmetalGloss options makeOutputs diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/compile b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/compile new file mode 100755 index 000000000..a85b723c7 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/compile @@ -0,0 +1,347 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2012-10-14.11; # UTC + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Written by Tom Tromey <tromey@cygnus.com>. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to <bug-automake@gnu.org> or send patches to +# <automake-patches@gnu.org>. + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to <bug-automake@gnu.org>. +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/config.guess b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/config.guess new file mode 100755 index 000000000..16592509d --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/config.guess @@ -0,0 +1,1441 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2015 Free Software Foundation, Inc. + +timestamp='2015-08-20' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches to <config-patches@gnu.org>. + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2015 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include <features.h> + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || \ + echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case "${UNAME_MACHINE_ARCH}" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}${abi}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:Sortix:*:*) + echo ${UNAME_MACHINE}-unknown-sortix + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <sys/systemcfg.h> + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include <stdlib.h> + #include <unistd.h> + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include <unistd.h> + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + *:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + e2k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` + echo ${UNAME_MACHINE}-pc-isc$UNAME_REL + elif /bin/uname -X 2>/dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says <Richard.M.Bartel@ccMail.Census.GOV> + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes <hewes@openmarket.com>. + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +cat >&2 <<EOF +$0: unable to guess system type + +This script, last modified $timestamp, has failed to recognize +the operating system you are using. It is advised that you +download the most up to date version of the config scripts from + + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +and + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +If the version you run ($0) is already up to date, please +send the following data and any information you think might be +pertinent to <config-patches@gnu.org> in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/config.sub b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/config.sub new file mode 100755 index 000000000..1acc966a3 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/config.sub @@ -0,0 +1,1813 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2015 Free Software Foundation, Inc. + +timestamp='2015-08-20' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see <http://www.gnu.org/licenses/>. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to <config-patches@gnu.org>. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to <config-patches@gnu.org>." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2015 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | ba \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | epiphany \ + | fido | fr30 | frv | ft32 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 | or1k | or1knd | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | riscv32 | riscv64 \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | ba-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | e2k-* | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | or1k*-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | riscv32-* | riscv64-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | visium-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + asmjs) + basic_machine=asmjs-unknown + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/configure b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/configure new file mode 100755 index 000000000..9bf715929 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/configure @@ -0,0 +1,5491 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for freedom-metal v0.1.2. +# +# Report bugs to <https://github.com/sifive/freedom-metal/issues>. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: https://github.com/sifive/freedom-metal/issues about +$0: your system, including any error possibly output before +$0: this message. Then install a modern shell, or manually +$0: run the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 </dev/null +exec 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='freedom-metal' +PACKAGE_TARNAME='freedom-metal' +PACKAGE_VERSION='v0.1.2' +PACKAGE_STRING='freedom-metal v0.1.2' +PACKAGE_BUGREPORT='https://github.com/sifive/freedom-metal/issues' +PACKAGE_URL='https://github.com/sifive/freedom-metal' + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +PLATFORM_HEADER +MACHINE_INLINE +MACHINE_HEADER +WITH_BUILTIN_LIBMETAL_SEGGER_FALSE +WITH_BUILTIN_LIBMETAL_SEGGER_TRUE +WITH_BUILTIN_LIBMETAL_PICO_FALSE +WITH_BUILTIN_LIBMETAL_PICO_TRUE +WITH_BUILTIN_LIBGLOSS_FALSE +WITH_BUILTIN_LIBGLOSS_TRUE +am__fastdepCCAS_FALSE +am__fastdepCCAS_TRUE +CCASDEPMODE +CCASFLAGS +CCAS +ac_ct_AR +AR +RANLIB +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +runstatedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_maintainer_mode +enable_dependency_tracking +with_builtin_libgloss +with_builtin_libmetal_pico +with_builtin_libmetal_segger +with_machine_header +with_machine_inline +with_platform_header +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CCAS +CCASFLAGS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir runstatedir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures freedom-metal v0.1.2 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/freedom-metal] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of freedom-metal v0.1.2:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-maintainer-mode + enable make rules and dependencies not useful (and + sometimes confusing) to the casual installer + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-bultin-libgloss Build libgloss along with Metal + --with-bultin-libmetal-pico + Build libmetal-pico along with Metal + --with-bultin-libmetal-segger + Build libmetal-segger along with Metal + --with-machine-header=PATH + Path to the machine header file + --with-machine-inline=PATH + Path to the machine inline file + --with-platform-header=PATH + Path to the platform header file + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CCAS assembler compiler command (defaults to CC) + CCASFLAGS assembler compiler flags (defaults to CFLAGS) + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to <https://github.com/sifive/freedom-metal/issues>. +freedom-metal home page: <https://github.com/sifive/freedom-metal>. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +freedom-metal configure v0.1.2 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by freedom-metal $as_me v0.1.2, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +# Initializes automake, enabling maintainer mode by default (which should be +# disabled by the archive generated by "make dist"). +am__api_version='1.15' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# Do 'set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='freedom-metal' + VERSION='v0.1.2' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: <http://www.gnu.org/software/coreutils/>. + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then : + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + +# Probe for tools that we need in order to build. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from 'make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar lib "link -lib" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar lib "link -lib" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 +$as_echo_n "checking the archiver ($AR) interface... " >&6; } +if ${am_cv_ar_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + am_cv_ar_interface=ar + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int some_variable = 0; +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 + (eval $am_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + am_cv_ar_interface=ar + else + am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 + (eval $am_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test "$ac_status" -eq 0; then + am_cv_ar_interface=lib + else + am_cv_ar_interface=unknown + fi + fi + rm -f conftest.lib libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 +$as_echo "$am_cv_ar_interface" >&6; } + +case $am_cv_ar_interface in +ar) + ;; +lib) + # Microsoft lib, so override with the ar-lib wrapper script. + # FIXME: It is wrong to rewrite AR. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__AR in this case, + # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something + # similar. + AR="$am_aux_dir/ar-lib $AR" + ;; +unknown) + as_fn_error $? "could not determine $AR interface" "$LINENO" 5 + ;; +esac + +# By default we simply use the C compiler to build assembly code. + +test "${CCAS+set}" = set || CCAS=$CC +test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS + + + +depcc="$CCAS" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CCAS_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CCAS_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CCAS_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CCAS_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CCAS_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CCAS_dependencies_compiler_type" >&6; } +CCASDEPMODE=depmode=$am_cv_CCAS_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CCAS_dependencies_compiler_type" = gcc3; then + am__fastdepCCAS_TRUE= + am__fastdepCCAS_FALSE='#' +else + am__fastdepCCAS_TRUE='#' + am__fastdepCCAS_FALSE= +fi + + + +# autoconf tries very hard to avoid failing, so it'll even go ahead and try to +# build the project using "gcc" if it can't find a suitable C compiler prefixed +# by the host system. This doesn't work when cross compiling, but it's a +# common error for users so we explicitly check for this right here to quickly +# provide an error message. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#ifndef __riscv +# error "A RISC-V compiler is required to build Freedom Metal" +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The C compiler doesn't define __riscv, which means it's probably not a RISC-V compiler. You should specify something like --host=riscv64-sifive-elf when building this, as it will only work on RISC-V systems. +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +######################################################## +# Options +######################################################## + + +# Check whether --with-builtin-libgloss was given. +if test "${with_builtin_libgloss+set}" = set; then : + withval=$with_builtin_libgloss; with_builtin_libgloss="yes" +else + with_builtin_libgloss="no" + +fi + + + +# Check whether --with-builtin-libmetal-pico was given. +if test "${with_builtin_libmetal_pico+set}" = set; then : + withval=$with_builtin_libmetal_pico; with_builtin_libmetal_pico="yes" +else + with_builtin_libmetal_pico="no" + +fi + + + +# Check whether --with-builtin-libmetal-segger was given. +if test "${with_builtin_libmetal_segger+set}" = set; then : + withval=$with_builtin_libmetal_segger; with_builtin_libmetal_segger="yes" +else + with_builtin_libmetal_segger="no" + +fi + + + +# Check whether --with-machine-header was given. +if test "${with_machine_header+set}" = set; then : + withval=$with_machine_header; +else + with_machine_header="no" + +fi + + + +# Check whether --with-machine-inline was given. +if test "${with_machine_inline+set}" = set; then : + withval=$with_machine_inline; +else + with_machine_inline="no" + +fi + + + +# Check whether --with-platform-header was given. +if test "${with_platform_header+set}" = set; then : + withval=$with_platform_header; +else + with_platform_header="no" + +fi + + +######################################################## +# Process Options +######################################################## + + if test "x$with_builtin_libgloss" = "xyes"; then + WITH_BUILTIN_LIBGLOSS_TRUE= + WITH_BUILTIN_LIBGLOSS_FALSE='#' +else + WITH_BUILTIN_LIBGLOSS_TRUE='#' + WITH_BUILTIN_LIBGLOSS_FALSE= +fi + + + if test "x$with_builtin_libmetal_pico" = "xyes"; then + WITH_BUILTIN_LIBMETAL_PICO_TRUE= + WITH_BUILTIN_LIBMETAL_PICO_FALSE='#' +else + WITH_BUILTIN_LIBMETAL_PICO_TRUE='#' + WITH_BUILTIN_LIBMETAL_PICO_FALSE= +fi + + + if test "x$with_builtin_libmetal_segger" = "xyes"; then + WITH_BUILTIN_LIBMETAL_SEGGER_TRUE= + WITH_BUILTIN_LIBMETAL_SEGGER_FALSE='#' +else + WITH_BUILTIN_LIBMETAL_SEGGER_TRUE='#' + WITH_BUILTIN_LIBMETAL_SEGGER_FALSE= +fi + + +# Configure the build system to pass in the preconfigured machine support files +if test "x$with_machine_header" != "xno"; then : + MACHINE_HEADER="$with_machine_header" + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "--with-machine-header is required +See \`config.log' for more details" "$LINENO" 5; } + +fi + +if test "x$with_machine_inline" != "xno"; then : + MACHINE_INLINE="$with_machine_inline" + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "--with-machine-inline is required +See \`config.log' for more details" "$LINENO" 5; } + +fi + +if test "x$with_platform_header" != "xno"; then : + PLATFORM_HEADER="$with_platform_header" + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "--with-platform-header is required +See \`config.log' for more details" "$LINENO" 5; } + +fi + +# Generates the remainder of the build system. +ac_config_files="$ac_config_files Makefile" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_BUILTIN_LIBGLOSS_TRUE}" && test -z "${WITH_BUILTIN_LIBGLOSS_FALSE}"; then + as_fn_error $? "conditional \"WITH_BUILTIN_LIBGLOSS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_BUILTIN_LIBMETAL_PICO_TRUE}" && test -z "${WITH_BUILTIN_LIBMETAL_PICO_FALSE}"; then + as_fn_error $? "conditional \"WITH_BUILTIN_LIBMETAL_PICO\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_BUILTIN_LIBMETAL_SEGGER_TRUE}" && test -z "${WITH_BUILTIN_LIBMETAL_SEGGER_FALSE}"; then + as_fn_error $? "conditional \"WITH_BUILTIN_LIBMETAL_SEGGER\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by freedom-metal $as_me v0.1.2, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Configuration commands: +$config_commands + +Report bugs to <https://github.com/sifive/freedom-metal/issues>. +freedom-metal home page: <https://github.com/sifive/freedom-metal>." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +freedom-metal config.status v0.1.2 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' <conf$$subs.awk | sed ' +/^[^""]/{ + N + s/\n// +} +' >>$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + + +eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named 'Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running 'make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "$am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/configure.ac b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/configure.ac new file mode 100644 index 000000000..3feebede0 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/configure.ac @@ -0,0 +1,97 @@ +# The name, version, and maintainer of this package +AC_INIT([freedom-metal], [m4_esyscmd_s([./scripts/git-version])], [https://github.com/sifive/freedom-metal/issues], [freedom-metal], [https://github.com/sifive/freedom-metal]) + +# Initializes automake, enabling maintainer mode by default (which should be +# disabled by the archive generated by "make dist"). +AM_INIT_AUTOMAKE([foreign subdir-objects]) +AM_MAINTAINER_MODE([disable]) +AC_CONFIG_MACRO_DIRS([m4]) + +AC_CANONICAL_HOST + +# Probe for tools that we need in order to build. +AC_PROG_CC +AC_PROG_RANLIB +AM_PROG_AR +AM_PROG_AS + +# autoconf tries very hard to avoid failing, so it'll even go ahead and try to +# build the project using "gcc" if it can't find a suitable C compiler prefixed +# by the host system. This doesn't work when cross compiling, but it's a +# common error for users so we explicitly check for this right here to quickly +# provide an error message. +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[ +#ifndef __riscv +# error "A RISC-V compiler is required to build Freedom Metal" +#endif +])], [], [AC_MSG_FAILURE([The C compiler doesn't define __riscv, which means it's probably not a RISC-V compiler. You should specify something like --host=riscv64-sifive-elf when building this, as it will only work on RISC-V systems.])]) + +######################################################## +# Options +######################################################## + +AC_ARG_WITH([builtin-libgloss], + [AS_HELP_STRING([--with-bultin-libgloss], [Build libgloss along with Metal])], + [with_builtin_libgloss="yes"], + [with_builtin_libgloss="no"] +) + +AC_ARG_WITH([builtin-libmetal-pico], + [AS_HELP_STRING([--with-bultin-libmetal-pico], [Build libmetal-pico along with Metal])], + [with_builtin_libmetal_pico="yes"], + [with_builtin_libmetal_pico="no"] +) + +AC_ARG_WITH([builtin-libmetal-segger], + [AS_HELP_STRING([--with-bultin-libmetal-segger], [Build libmetal-segger along with Metal])], + [with_builtin_libmetal_segger="yes"], + [with_builtin_libmetal_segger="no"] +) + +AC_ARG_WITH([machine-header], + [AS_HELP_STRING([--with-machine-header=PATH], [Path to the machine header file])], + [], + [with_machine_header="no"] +) + +AC_ARG_WITH([machine-inline], + [AS_HELP_STRING([--with-machine-inline=PATH], [Path to the machine inline file])], + [], + [with_machine_inline="no"] +) + +AC_ARG_WITH([platform-header], + [AS_HELP_STRING([--with-platform-header=PATH], [Path to the platform header file])], + [], + [with_platform_header="no"] +) + +######################################################## +# Process Options +######################################################## + +AM_CONDITIONAL([WITH_BUILTIN_LIBGLOSS], [test "x$with_builtin_libgloss" = "xyes"]) + +AM_CONDITIONAL([WITH_BUILTIN_LIBMETAL_PICO], [test "x$with_builtin_libmetal_pico" = "xyes"]) + +AM_CONDITIONAL([WITH_BUILTIN_LIBMETAL_SEGGER], [test "x$with_builtin_libmetal_segger" = "xyes"]) + +# Configure the build system to pass in the preconfigured machine support files +AS_IF([test "x$with_machine_header" != "xno"], + [AC_SUBST([MACHINE_HEADER], "$with_machine_header")], + [AC_MSG_FAILURE([--with-machine-header is required])] +) + +AS_IF([test "x$with_machine_inline" != "xno"], + [AC_SUBST([MACHINE_INLINE], "$with_machine_inline")], + [AC_MSG_FAILURE([--with-machine-inline is required])] +) + +AS_IF([test "x$with_platform_header" != "xno"], + [AC_SUBST([PLATFORM_HEADER], "$with_platform_header")], + [AC_MSG_FAILURE([--with-platform-header is required])] +) + +# Generates the remainder of the build system. +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/depcomp b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/depcomp new file mode 100755 index 000000000..fc98710e2 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2013-05-30.07; # UTC + +# Copyright (C) 1999-2014 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>. + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to <bug-automake@gnu.org>. +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/doc/link_to_docs_in_github.url b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/doc/link_to_docs_in_github.url deleted file mode 100644 index f59b1cedd..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/doc/link_to_docs_in_github.url +++ /dev/null @@ -1,5 +0,0 @@ -[{000214A0-0000-0000-C000-000000000046}]
-Prop3=19,11
-[InternetShortcut]
-IDList=
-URL=https://github.com/sifive/freedom-metal-docs
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/crt0.S b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/crt0.S index 920ee4b9f..20afcc0c1 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/crt0.S +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/crt0.S @@ -44,22 +44,7 @@ _start: la gp, __global_pointer$ .option pop - /* The METAL is designed for a bare-metal environment and therefor is expected - * to define its own stack pointer. We also align the stack pointer here - * because the only RISC-V ABI that's currently defined mandates 16-byte - * stack alignment. */ - la sp, _sp - - /* Increment by hartid number of stack sizes */ - li t0, 0 - la t1, __stack_size -1: - beq t0, a0, 1f - add sp, sp, t1 - addi t0, t0, 1 - j 1b -1: - andi sp, sp, -16 + /* Stack pointer is expected to be initialized before _start */ /* If we're not hart 0, skip the initialization work */ la t0, __metal_boot_hart @@ -123,6 +108,36 @@ _start: complete */ fence.i +2: + + /* Copy the LIM section */ + la t0, metal_segment_lim_source_start + la t1, metal_segment_lim_target_start + la t2, metal_segment_lim_target_end + + beq t0, t1, 2f + bge t1, t2, 2f + +1: +#if __riscv_xlen == 32 + lw a0, 0(t0) + addi t0, t0, 4 + sw a0, 0(t1) + addi t1, t1, 4 + blt t1, t2, 1b +#else + ld a0, 0(t0) + addi t0, t0, 8 + sd a0, 0(t1) + addi t1, t1, 8 + blt t1, t2, 1b +#endif +2: + + /* Fence all subsequent instruction fetches until after the LIM writes + complete */ + fence.i + /* Zero the BSS segment. */ la t1, metal_segment_bss_target_start la t2, metal_segment_bss_target_end @@ -141,6 +156,10 @@ _start: #endif 2: + /* Set TLS pointer */ + .weak __tls_base + la tp, __tls_base + /* At this point we're in an environment that can execute C code. The first * thing to do is to make the callback to the parent environment if it's been * requested to do so. */ @@ -153,14 +172,41 @@ _start: call atexit call __libc_init_array + /* Register metal_fini_run as a destructor and call metal_init_run to + * run and setup Metal constructors */ + la a0, metal_fini_run + call atexit + call metal_init_run + _skip_init: /* Synchronize harts so that secondary harts wait until hart 0 finishes initializing */ call __metal_synchronize_harts - /* Check RISC-V isa and enable FS bits if Floating Point architecture. */ + /* Disable and clear all interrupt sources */ + li a3, -1 + csrc mie, a3 + csrc mip, a3 + + /* The delegation CSRs exist if user mode interrupts (N extension) or + * supervisor mode (S extension) are supported */ csrr a5, misa + lui a4, 0x42 + and a4, a4, a5 + beqz a4, 1f + csrc mideleg, a3 + csrc medeleg, a3 +1: + + /* The satp CSR exists if supervisor mode (S extension) is supported */ + lui a4, 0x40 + and a4, a4, a5 + beqz a4, 1f + csrc satp, a3 +1: + + /* Check RISC-V isa and enable FS bits if Floating Point architecture. */ li a4, 0x10028 and a5, a5, a4 beqz a5, 1f @@ -171,6 +217,16 @@ _skip_init: csrwi fcsr, 0 1: + /* Check for vector extension support and enable it if found */ + csrr a5, misa + li a4, 0x200000 + and a5, a5, a4 + beqz a5, 1f + csrr a5, mstatus + ori a5, a5, 0x200 + csrw mstatus, a5 +1: + /* This is a C runtime, so main() is defined to have some arguments. Since * there's nothing sane the METAL can pass we don't bother with that but * instead just setup as close to a NOP as we can. */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/nanosleep.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/nanosleep.c index 8be22104e..d40d2f892 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/nanosleep.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/nanosleep.c @@ -1,9 +1,7 @@ #include <errno.h> #include <sys/time.h> -int -nanosleep(const struct timespec *rqtp, struct timespec *rmtp) -{ - errno = ENOSYS; - return -1; +int nanosleep(const struct timespec *rqtp, struct timespec *rmtp) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/synchronize_harts.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/synchronize_harts.c deleted file mode 100644 index 3e857d1df..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/synchronize_harts.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2019 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include <metal/machine.h> -#include <metal/machine/platform.h> -#include <metal/io.h> -#include <metal/cpu.h> - -#define METAL_REG(base, offset) (((unsigned long)(base) + (offset))) -#define METAL_REGW(base, offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)METAL_REG((base), (offset)))) -#define METAL_MSIP(base, hart) (METAL_REGW((base),4*(hart))) - -/* - * _synchronize_harts() is called by crt0.S to cause harts > 0 to wait for - * hart 0 to finish copying the datat section, zeroing the BSS, and running - * the libc contstructors. - */ -void _synchronize_harts() { -#if __METAL_DT_MAX_HARTS > 1 - - int hart = metal_cpu_get_current_hartid(); - uintptr_t msip_base = 0; - - /* Get the base address of the MSIP registers */ -#ifdef __METAL_DT_RISCV_CLINT0_HANDLE - msip_base = __metal_driver_sifive_clint0_control_base(__METAL_DT_RISCV_CLINT0_HANDLE); - msip_base += METAL_RISCV_CLINT0_MSIP_BASE; -#elif __METAL_DT_RISCV_CLIC0_HANDLE - msip_base = __metal_driver_sifive_clic0_control_base(__METAL_DT_RISCV_CLIC0_HANDLE); - msip_base += METAL_RISCV_CLIC0_MSIP_BASE; -#else -#warning No handle for CLINT or CLIC found, harts may be unsynchronized after init! -#endif - - /* Disable machine interrupts as a precaution */ - __asm__ volatile("csrc mstatus, %0" :: "r" (METAL_MSTATUS_MIE)); - - if (hart == 0) { - /* Hart 0 waits for all harts to set their MSIP bit */ - for (int i = 1 ; i < __METAL_DT_MAX_HARTS; i++) { - while (METAL_MSIP(msip_base, i) == 0) ; - } - - /* Hart 0 clears everyone's MSIP bit */ - for (int i = 1 ; i < __METAL_DT_MAX_HARTS; i++) { - METAL_MSIP(msip_base, i) = 0; - } - } else { - /* Other harts set their MSIP bit to indicate they're ready */ - METAL_MSIP(msip_base, hart) = 1; - __asm__ volatile ("fence w,rw"); - - /* Wait for hart 0 to clear the MSIP bit */ - while (METAL_MSIP(msip_base, hart) == 1) ; - } - -#endif /* __METAL_DT_MAX_HARTS > 1 */ -} - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_access.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_access.c index c0bc1534d..6aa5ccbd4 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_access.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_access.c @@ -1,8 +1,6 @@ #include <errno.h> -int -_access(const char *file, int mode) -{ - errno = ENOSYS; - return -1; +int _access(const char *file, int mode) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chdir.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chdir.c index f33d26a44..b1daf1c6c 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chdir.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chdir.c @@ -1,8 +1,6 @@ #include <errno.h> -int -_chdir(const char *path) -{ - errno = ENOSYS; - return -1; +int _chdir(const char *path) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chmod.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chmod.c index 67412bf7d..1711f582f 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chmod.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chmod.c @@ -1,9 +1,7 @@ #include <errno.h> #include <sys/types.h> -int -_chmod(const char *path, mode_t mode) -{ - errno = ENOSYS; - return -1; +int _chmod(const char *path, mode_t mode) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chown.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chown.c index 302952eb1..f7edc91ce 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chown.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_chown.c @@ -1,9 +1,7 @@ -#include <sys/types.h> #include <errno.h> +#include <sys/types.h> -int -_chown(const char *path, uid_t owner, gid_t group) -{ - errno = ENOSYS; - return -1; +int _chown(const char *path, uid_t owner, gid_t group) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_clock_gettime.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_clock_gettime.c new file mode 100644 index 000000000..7feb695b3 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_clock_gettime.c @@ -0,0 +1,60 @@ +#define _POSIX_MONOTONIC_CLOCK 200809L +#define _POSIX_TIMERS +#include <errno.h> +#include <metal/drivers/riscv_cpu.h> +#include <metal/machine.h> +#include <time.h> + +#ifdef MTIME_RATE_HZ_DEF +#undef MTIME_RATE_HZ +#define MTIME_RATE_HZ MTIME_RATE_HZ_DEF +#endif + +#ifndef MTIME_RATE_HZ +#define MTIME_RATE_HZ 32768 +#endif + +#if !defined(mtime_interrupt_controller) && \ + defined(__METAL_DT_RISCV_CLINT0_HANDLE) +#define mtime_interrupt_controller __METAL_DT_RISCV_CLINT0_HANDLE +#endif + +#if !defined(mtime_interrupt_controller) && \ + defined(__METAL_DT_SIFIVE_CLIC0_HANDLE) +#define mtime_interrupt_controller __METAL_DT_SIFIVE_CLIC0_HANDLE +#endif + +int clock_getres(clockid_t clk_id, struct timespec *res) { + switch (clk_id) { + case CLOCK_MONOTONIC: + res->tv_sec = 0; + res->tv_nsec = 1000000000 / MTIME_RATE_HZ; + return 0; + break; + default: + errno = EINVAL; + return -1; + } +} + +int clock_gettime(clockid_t clk_id, struct timespec *tp) { + unsigned long long ticks; + + switch (clk_id) { + case CLOCK_MONOTONIC: + mtime_interrupt_controller->vtable->command_request( + mtime_interrupt_controller, METAL_TIMER_MTIME_GET, &ticks); + tp->tv_sec = ticks / MTIME_RATE_HZ; + tp->tv_nsec = ((ticks % (MTIME_RATE_HZ)) * 1000000000) / MTIME_RATE_HZ; + return 0; + break; + default: + errno = EINVAL; + return -1; + } +} + +int clock_settime(clockid_t clk_id, const struct timespec *tp) { + errno = EINVAL; + return -1; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_close.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_close.c index 26dd6a59e..c09e66dc5 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_close.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_close.c @@ -1,8 +1,6 @@ #include <errno.h> -int -_close(int file) -{ - errno = ENOSYS; - return -1; +int _close(int file) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_execve.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_execve.c index 9ae9f7e50..05d87ea77 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_execve.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_execve.c @@ -1,8 +1,6 @@ #include <errno.h> -int -_execve(const char *name, char *const argv[], char *const env[]) -{ - errno = ENOMEM; - return -1; +int _execve(const char *name, char *const argv[], char *const env[]) { + errno = ENOMEM; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_exit.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_exit.c index 35f5f1a16..71883a67b 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_exit.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_exit.c @@ -1,8 +1,7 @@ #include <metal/shutdown.h> -void -_exit(int exit_status) -{ - metal_shutdown(exit_status); - while (1); +void _exit(int exit_status) { + metal_shutdown(exit_status); + while (1) + ; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_faccessat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_faccessat.c index 873d52c2e..eb18b04d5 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_faccessat.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_faccessat.c @@ -1,8 +1,6 @@ #include <errno.h> -int -_faccessat(int dirfd, const char *file, int mode, int flags) -{ - errno = ENOSYS; - return -1; +int _faccessat(int dirfd, const char *file, int mode, int flags) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fork.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fork.c index 64e67569f..4a7974f48 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fork.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fork.c @@ -1,8 +1,6 @@ #include <errno.h> -int -_fork() -{ - errno = ENOSYS; - return -1; +int _fork() { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fstat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fstat.c index fedc28977..bf4ad144b 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fstat.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fstat.c @@ -1,9 +1,7 @@ #include <errno.h> #include <sys/stat.h> -int -_fstat(int file, struct stat *st) -{ - errno = -ENOSYS; - return -1; +int _fstat(int file, struct stat *st) { + errno = -ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fstatat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fstatat.c index f2f43bd9e..22b825594 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fstatat.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_fstatat.c @@ -1,9 +1,7 @@ #include <errno.h> #include <sys/stat.h> -int -_fstatat(int dirfd, const char *file, struct stat *st, int flags) -{ - errno = ENOSYS; - return -1; +int _fstatat(int dirfd, const char *file, struct stat *st, int flags) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_ftime.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_ftime.c index 65c156398..b5ffa7c19 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_ftime.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_ftime.c @@ -1,9 +1,7 @@ #include <errno.h> #include <sys/timeb.h> -int -_ftime(struct timeb *tp) -{ - errno = ENOSYS; - return -1; +int _ftime(struct timeb *tp) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_getcwd.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_getcwd.c index 82e8404ee..d8e73de6d 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_getcwd.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_getcwd.c @@ -1,8 +1,7 @@ #include <errno.h> +#include <stddef.h> -char * -_getcwd(char *buf, size_t size) -{ - errno = -ENOSYS; - return NULL; +char *_getcwd(char *buf, size_t size) { + errno = -ENOSYS; + return NULL; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_getpid.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_getpid.c index 589ad117c..13b48e142 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_getpid.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_getpid.c @@ -1,7 +1,3 @@ #include <errno.h> -int -_getpid() -{ - return 1; -} +int _getpid() { return 1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_gettimeofday.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_gettimeofday.c index 409b2ce2f..22ba5c0cd 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_gettimeofday.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_gettimeofday.c @@ -2,9 +2,7 @@ #include <metal/timer.h> #include <sys/time.h> -int -_gettimeofday(struct timeval *tp, void *tzp) -{ +int _gettimeofday(struct timeval *tp, void *tzp) { int rv; unsigned long long mcc, timebase; rv = metal_timer_get_cyclecount(0, &mcc); @@ -19,3 +17,6 @@ _gettimeofday(struct timeval *tp, void *tzp) tp->tv_usec = mcc % timebase * 1000000 / timebase; return 0; } + +extern __typeof(_gettimeofday) gettimeofday + __attribute__((__weak__, __alias__("_gettimeofday"))); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_isatty.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_isatty.c index dd4f1461b..851bc1494 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_isatty.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_isatty.c @@ -1,7 +1,3 @@ #include <unistd.h> -int -_isatty(int file) -{ - return (file == STDOUT_FILENO); -} +int _isatty(int file) { return (file == STDOUT_FILENO); } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_kill.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_kill.c index 9003f266f..6f439744a 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_kill.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_kill.c @@ -1,8 +1,6 @@ #include <errno.h> -int -_kill(int pid, int sig) -{ - errno = ENOSYS; - return -1; +int _kill(int pid, int sig) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_link.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_link.c index 40d5912bc..c3d7c2bcb 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_link.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_link.c @@ -1,7 +1,6 @@ #include <errno.h> -int _link(const char *old_name, const char *new_name) -{ - errno = ENOSYS; - return -1; +int _link(const char *old_name, const char *new_name) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_lseek.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_lseek.c index d28a781f8..6dab8c3f7 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_lseek.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_lseek.c @@ -1,9 +1,7 @@ -#include <sys/types.h> #include <errno.h> +#include <sys/types.h> -off_t -_lseek(int file, off_t ptr, int dir) -{ - errno = ENOSYS; - return -1; +off_t _lseek(int file, off_t ptr, int dir) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_lstat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_lstat.c index 97a45855f..76b66a9ba 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_lstat.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_lstat.c @@ -1,8 +1,7 @@ #include <errno.h> #include <sys/stat.h> -int _lstat(const char *file, struct stat *st) -{ - errno = ENOSYS; - return -1; +int _lstat(const char *file, struct stat *st) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_open.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_open.c index a59f627f0..df13edb11 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_open.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_open.c @@ -1,8 +1,6 @@ #include <errno.h> -int -_open(const char *name, int flags, int mode) -{ - errno = ENOSYS; - return -1; +int _open(const char *name, int flags, int mode) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_openat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_openat.c index 206de3bde..15fad8f7f 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_openat.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_openat.c @@ -1,8 +1,6 @@ #include <errno.h> -int -_openat(int dirfd, const char *name, int flags, int mode) -{ - errno = ENOSYS; - return -1; +int _openat(int dirfd, const char *name, int flags, int mode) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_read.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_read.c index 15833cabb..147ee30d7 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_read.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_read.c @@ -1,9 +1,7 @@ -#include <sys/types.h> #include <errno.h> +#include <sys/types.h> -ssize_t -_read(int file, void *ptr, size_t len) -{ - errno = ENOSYS; - return -1; +ssize_t _read(int file, void *ptr, size_t len) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_sbrk.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_sbrk.c index cc01c8ffb..9cb42aecb 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_sbrk.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_sbrk.c @@ -1,39 +1,43 @@ +#include <metal/scrub.h> #include <sys/types.h> -/* brk is handled entirely within the C library. This limits METAL programs that - * use the C library to be disallowed from dynamically allocating memory +/* brk is handled entirely within the C library. This limits METAL programs + * that use the C library to be disallowed from dynamically allocating memory * without talking to the C library, but that sounds like a sane way to go * about it. Note that there is no error checking anywhere in this file, users * will simply get the relevant error when actually trying to use the memory * that's been allocated. */ extern char metal_segment_heap_target_start; extern char metal_segment_heap_target_end; -static char *brk = &metal_segment_heap_target_start; +static char *__brk = &metal_segment_heap_target_start; -int -_brk(void *addr) -{ - brk = addr; - return 0; +#ifdef _PICOLIBC__ +#define _brk brk +#define _sbrk sbrk +#endif + +int _brk(void *addr) { + __brk = addr; + return 0; } -char * -_sbrk(ptrdiff_t incr) -{ - char *old = brk; +char *_sbrk(ptrdiff_t incr) { + char *old = __brk; - /* If __heap_size == 0, we can't allocate memory on the heap */ - if(&metal_segment_heap_target_start == &metal_segment_heap_target_end) { - return (void *)-1; - } + /* If __heap_size == 0, we can't allocate memory on the heap */ + if (&metal_segment_heap_target_start == &metal_segment_heap_target_end) { + return (void *)-1; + } - /* Don't move the break past the end of the heap */ - if ((brk + incr) < &metal_segment_heap_target_end) { - brk += incr; - } else { - brk = &metal_segment_heap_target_end; - return (void *)-1; - } + /* Don't move the break past the end of the heap */ + if ((__brk + incr) < &metal_segment_heap_target_end) { + __brk += incr; + } else { + __brk = &metal_segment_heap_target_end; + return (void *)-1; + } + /* Scrub out allocated memory to avoid spurious ECC errors */ + metal_mem_scrub(old, incr); - return old; + return old; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_stat.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_stat.c index 3c2e41910..89d6b8b42 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_stat.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_stat.c @@ -1,9 +1,7 @@ #include <errno.h> #include <sys/stat.h> -int -_stat(const char *file, struct stat *st) -{ - errno = ENOSYS; - return -1; +int _stat(const char *file, struct stat *st) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_sysconf.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_sysconf.c index 452a252ae..8d7ddcf1b 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_sysconf.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_sysconf.c @@ -1,16 +1,16 @@ -#include <unistd.h> #include <time.h> +#include <unistd.h> /* Get configurable system variables. */ -long -_sysconf(int name) -{ - switch (name) - { +long _sysconf(int name) { + switch (name) { case _SC_CLK_TCK: - return CLOCKS_PER_SEC; + return CLOCKS_PER_SEC; } - return -1; + return -1; } + +extern __typeof(_sysconf) sysconf + __attribute__((__weak__, __alias__("_sysconf"))); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_times.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_times.c index 6beedcb30..f8f3e140b 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_times.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_times.c @@ -1,9 +1,32 @@ -#include <sys/times.h> -#include <sys/time.h> -#include <metal/timer.h> #include <errno.h> +#include <metal/cpu.h> +#include <metal/timer.h> +#include <sys/time.h> +#include <sys/times.h> -extern int _gettimeofday(struct timeval *, void *); +/* v * num / den while avoiding overflow + * + * Modulus on unsigned values is defined as: + * + * v % den = v - (v / den) * den + * v = v % den + (v / den) * den + * + * This lets us break the computation down as follows: + * + * r = (v * num) / den + * = ((v % den + (v / den) * den) * num) / den + * = ((v % den) * num) / den + ((v / den) * den) * num / den + * = ((v % den) * num) / den + ((v / den) * num + * + * As long as num * den fits in 64 bits, then this computation will fit + * in 64 bits. CLOCKS_PER_SEC is defined as 1,000,000, so we just need + * timebase to be less than about 4,000,000,000,000 (4 trillion). + */ + +static inline unsigned long long +muldiv(unsigned long long v, unsigned long long num, unsigned long long den) { + return (((v % den) * num) / den) + ((v / den) * num); +} /* Timing information for current process. From newlib/libc/include/sys/times.h the tms struct fields are as follows: @@ -17,26 +40,28 @@ extern int _gettimeofday(struct timeval *, void *); children's times to zero. Eventually we might want to separately account for user vs system time, but for now we just return the total number of cycles since starting the program. */ -clock_t -_times(struct tms *buf) -{ - int rv; - // when called for the first time, initialize t0 - static struct timeval t0; - if (t0.tv_sec == 0 && t0.tv_usec == 0) - _gettimeofday (&t0, 0); - - struct timeval t; - _gettimeofday (&t, 0); - +clock_t _times(struct tms *buf) { + unsigned long long mcc; unsigned long long timebase; - rv = metal_timer_get_timebase_frequency(0, &timebase); - if (rv != 0) { - return -1; - } - - long long utime = (t.tv_sec - t0.tv_sec) * 1000000 + (t.tv_usec - t0.tv_usec); - buf->tms_utime = utime * timebase / 1000000; - buf->tms_stime = buf->tms_cstime = buf->tms_cutime = 0; - return 0; + int hartid = metal_cpu_get_current_hartid(); + + metal_timer_get_timebase_frequency(hartid, &timebase); + metal_timer_get_cyclecount(hartid, &mcc); + + /* + * Convert from native resolution to published resolution. + * + * Truncating this to 64 bits works because a change of 'c' in + * cyclecount will change the return value by + * c * CLOCKS_PER_SEC / timebase, so applications will see + * time marching forward. + */ + mcc = muldiv(mcc, CLOCKS_PER_SEC, timebase); + + buf->tms_stime = 0; + buf->tms_cutime = 0; + buf->tms_cstime = 0; + return buf->tms_utime = mcc; } + +extern __typeof(_times) times __attribute__((__weak__, __alias__("_times"))); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_unlink.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_unlink.c index b369d2017..546039a61 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_unlink.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_unlink.c @@ -1,8 +1,6 @@ #include <errno.h> -int -_unlink(const char *name) -{ - errno = ENOSYS; - return -1; +int _unlink(const char *name) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_utime.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_utime.c index 33d557aa7..5e7389cd1 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_utime.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_utime.c @@ -1,9 +1,7 @@ #include <errno.h> struct utimbuf; -int -_utime(const char *path, const struct utimbuf *times) -{ - errno = ENOSYS; - return -1; +int _utime(const char *path, const struct utimbuf *times) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_wait.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_wait.c index 9d459f14c..304f941b4 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_wait.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_wait.c @@ -1,7 +1,6 @@ #include <errno.h> -int _wait(int *status) -{ - errno = ENOSYS; - return -1; +int _wait(int *status) { + errno = ENOSYS; + return -1; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_write.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_write.c index bfcf0cb2b..10881023d 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_write.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/gloss/sys_write.c @@ -1,19 +1,20 @@ +#include <errno.h> #include <metal/tty.h> #include <sys/types.h> -#include <errno.h> #include <unistd.h> /* Write to a file. */ -ssize_t -_write(int file, const void *ptr, size_t len) -{ - if (file != STDOUT_FILENO) { - errno = ENOSYS; - return -1; - } +ssize_t _write(int file, const void *ptr, size_t len) { + if (file != STDOUT_FILENO) { + errno = ENOSYS; + return -1; + } - const char *bptr = ptr; - for (size_t i = 0; i < len; ++i) - metal_tty_putc(bptr[i]); - return 0; + const char *bptr = ptr; + for (size_t i = 0; i < len; ++i) + metal_tty_putc(bptr[i]); + return 0; } + +extern __typeof(_write) write + __attribute__((__weak__, __weak__, __alias__("_write"))); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/install-git-hooks b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/install-git-hooks new file mode 100755 index 000000000..bc6df8702 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/install-git-hooks @@ -0,0 +1,9 @@ +#!/bin/bash + +mkdir -p .git/hooks +cat >.git/hooks/post-commit <<EOF +#!/bin/bash +# Generated by $0 +touch -c configure.ac +EOF +chmod +x .git/hooks/post-commit diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/install-sh b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/install-sh new file mode 100755 index 000000000..c143b8655 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/install-sh @@ -0,0 +1,508 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2016-01-11.22; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# 'make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + # $RANDOM is not portable (e.g. dash); use it when possible to + # lower collision chance + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 + + # As "mkdir -p" follows symlinks and we work in /tmp possibly; so + # create the $tmpdir first (and fail if unsuccessful) to make sure + # that nobody tries to guess the $tmpdir name. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/m4/ax_check_compile_flag.m4 b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/m4/ax_check_compile_flag.m4 new file mode 100644 index 000000000..bd753b34d --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/m4/ax_check_compile_flag.m4 @@ -0,0 +1,53 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> +# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 6 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/atomic.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/atomic.h new file mode 100644 index 000000000..32a33abd7 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/atomic.h @@ -0,0 +1,259 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__ATOMIC_H +#define METAL__ATOMIC_H + +#include <stdint.h> + +#include <metal/compiler.h> + +typedef volatile int32_t metal_atomic_t; + +#define METAL_ATOMIC_DECLARE(name) \ + __attribute((section(".data.atomics"))) metal_atomic_t name + +#define _METAL_STORE_AMO_ACCESS_FAULT 7 + +/* This macro stores the memory address in mtval like a normal store/amo access + * fault, triggers a trap, and then if execution returns, returns 0 as an + * arbitrary choice */ +#define _METAL_TRAP_AMO_ACCESS(addr) \ + __asm__("csrw mtval, %[atomic]" ::[atomic] "r"(a)); \ + _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); \ + return 0; + +/*! + * @brief Check if the platform supports atomic operations + * + * @return 1 if atomic operations are supported, 0 if not + */ +__inline__ int32_t metal_atomic_available(void) { +#ifdef __riscv_atomic + return 1; +#else + return 0; +#endif +} + +/*! + * @brief Atomically increment a metal_atomic_t and return its old value + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to increment + * @param increment the amount to increment the value + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_add(metal_atomic_t *a, int32_t increment) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amoadd.w %[old], %[increment], (%[atomic])" + : [old] "=r"(old) + : [increment] "r"(increment), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically bitwise-AND a metal_atomic_t and return its old value + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to bitwise-AND + * @param mask the bitmask to AND + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_and(metal_atomic_t *a, int32_t mask) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amoand.w %[old], %[mask], (%[atomic])" + : [old] "=r"(old) + : [mask] "r"(mask), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically bitwise-OR a metal_atomic_t and return its old value + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to bitwise-OR + * @param mask the bitmask to OR + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_or(metal_atomic_t *a, int32_t mask) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amoor.w %[old], %[mask], (%[atomic])" + : [old] "=r"(old) + : [mask] "r"(mask), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically swap a metal_atomic_t and return its old value + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to swap + * @param new_value the value to store in the metal_atomic_t + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_swap(metal_atomic_t *a, int32_t new_value) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amoswap.w %[old], %[newval], (%[atomic])" + : [old] "=r"(old) + : [newval] "r"(new_value), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically bitwise-XOR a metal_atomic_t and return its old value + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to bitwise-XOR + * @param mask the bitmask to XOR + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_xor(metal_atomic_t *a, int32_t mask) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amoxor.w %[old], %[mask], (%[atomic])" + : [old] "=r"(old) + : [mask] "r"(mask), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically set the value of a memory location to the greater of + * its current value or a value to compare it with. + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to swap + * @param compare the value to compare with the value in memory + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_max(metal_atomic_t *a, int32_t compare) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amomax.w %[old], %[compare], (%[atomic])" + : [old] "=r"(old) + : [compare] "r"(compare), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically set the value of a memory location to the (unsigned) + * greater of its current value or a value to compare it with. + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to swap + * @param compare the value to compare with the value in memory + * + * @return The previous value of the metal_atomic_t + */ +__inline__ uint32_t metal_atomic_max_u(metal_atomic_t *a, uint32_t compare) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amomaxu.w %[old], %[compare], (%[atomic])" + : [old] "=r"(old) + : [compare] "r"(compare), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically set the value of a memory location to the lesser of + * its current value or a value to compare it with. + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to swap + * @param compare the value to compare with the value in memory + * + * @return The previous value of the metal_atomic_t + */ +__inline__ int32_t metal_atomic_min(metal_atomic_t *a, int32_t compare) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amomin.w %[old], %[compare], (%[atomic])" + : [old] "=r"(old) + : [compare] "r"(compare), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +/*! + * @brief Atomically set the value of a memory location to the (unsigned) lesser + * of its current value or a value to compare it with. + * + * If atomics are not supported on the platform, this function will trap with + * a Store/AMO access fault. + * + * @param a The pointer to the value to swap + * @param compare the value to compare with the value in memory + * + * @return The previous value of the metal_atomic_t + */ +__inline__ uint32_t metal_atomic_min_u(metal_atomic_t *a, uint32_t compare) { +#ifdef __riscv_atomic + int32_t old; + __asm__ volatile("amominu.w %[old], %[compare], (%[atomic])" + : [old] "=r"(old) + : [compare] "r"(compare), [atomic] "r"(a) + : "memory"); + return old; +#else + _METAL_TRAP_AMO_ACCESS(a); +#endif +} + +#endif /* METAL__ATOMIC_H */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/button.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/button.h index 3ae1c143e..bef645967 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/button.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/button.h @@ -15,7 +15,8 @@ struct metal_button; struct metal_button_vtable { int (*button_exist)(struct metal_button *button, char *label); - struct metal_interrupt* (*interrupt_controller)(struct metal_button *button); + struct metal_interrupt *(*interrupt_controller)( + struct metal_button *button); int (*get_interrupt_id)(struct metal_button *button); }; @@ -35,8 +36,7 @@ struct metal_button { * @param label The DeviceTree label for the button * @return A handle for the button */ -struct metal_button* metal_button_get(char *label); - +struct metal_button *metal_button_get(char *label); /*! * @brief Get the interrupt controller for a button @@ -45,8 +45,10 @@ struct metal_button* metal_button_get(char *label); * @return A pointer to the interrupt controller responsible for handling * button interrupts. */ -__inline__ struct metal_interrupt* - metal_button_interrupt_controller(struct metal_button *button) { return button->vtable->interrupt_controller(button); } +__inline__ struct metal_interrupt * +metal_button_interrupt_controller(struct metal_button *button) { + return button->vtable->interrupt_controller(button); +} /*! * @brief Get the interrupt id for a button @@ -54,6 +56,8 @@ __inline__ struct metal_interrupt* * @param button The handle for the button * @return The interrupt id corresponding to a button. */ -__inline__ int metal_button_get_interrupt_id(struct metal_button *button) { return button->vtable->get_interrupt_id(button); } +__inline__ int metal_button_get_interrupt_id(struct metal_button *button) { + return button->vtable->get_interrupt_id(button); +} #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/cache.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/cache.h index bad026480..673a8b13e 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/cache.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/cache.h @@ -1,4 +1,4 @@ -/* Copyright 2018 SiFive, Inc */ +/* Copyright 2020 SiFive, Inc */ /* SPDX-License-Identifier: Apache-2.0 */ #ifndef METAL__CACHE_H @@ -11,39 +11,56 @@ */ #include <stdint.h> -struct metal_cache; - -struct __metal_cache_vtable { - void (*init)(struct metal_cache *cache, int ways); - int (*get_enabled_ways)(struct metal_cache *cache); - int (*set_enabled_ways)(struct metal_cache *cache, int ways); -}; - /*! * @brief a handle for a cache + * Note: To be deprecated in next release. */ struct metal_cache { - const struct __metal_cache_vtable *vtable; + uint8_t __no_empty_structs; }; /*! + * @brief Initialize L2 cache controller. + * Enables all available cache ways. + * @param None + * @return 0 If no error + */ +int metal_l2cache_init(void); + +/*! + * @brief Get the current number of enabled L2 cache ways + * @param None + * @return The current number of enabled L2 cache ways + */ +int metal_l2cache_get_enabled_ways(void); + +/*! + * @brief Enable the requested number of L2 cache ways + * @param ways Number of ways to enable + * @return 0 if the ways are successfully enabled + */ +int metal_l2cache_set_enabled_ways(int ways); + +/*! * @brief Initialize a cache * @param cache The handle for the cache to initialize * @param ways The number of ways to enable * * Initializes a cache with the requested number of ways enabled. + * Note: API to be deprecated in next release. */ __inline__ void metal_cache_init(struct metal_cache *cache, int ways) { - cache->vtable->init(cache, ways); + metal_l2cache_init(); } /*! * @brief Get the current number of enabled cache ways * @param cache The handle for the cache * @return The current number of enabled cache ways + * Note: API to be deprecated in next release. */ __inline__ int metal_cache_get_enabled_ways(struct metal_cache *cache) { - return cache->vtable->get_enabled_ways(cache); + return metal_l2cache_get_enabled_ways(); } /*! @@ -51,9 +68,11 @@ __inline__ int metal_cache_get_enabled_ways(struct metal_cache *cache) { * @param cache The handle for the cache * @param ways The number of ways to enabled * @return 0 if the ways are successfully enabled + * Note: API to be deprecated in next release. */ -__inline__ int metal_cache_set_enabled_ways(struct metal_cache *cache, int ways) { - return cache->vtable->set_enabled_ways(cache, ways); +__inline__ int metal_cache_set_enabled_ways(struct metal_cache *cache, + int ways) { + return metal_l2cache_set_enabled_ways(ways); } /*! @@ -86,11 +105,4 @@ void metal_dcache_l1_discard(int hartid, uintptr_t address); */ int metal_icache_l1_available(int hartid); -/*! - * @brief Flush icache for L1 on the requested core - * @param hartid The core to flush - * @return None - */ -void metal_icache_l1_flush(int hartid); - #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/clock.h index 622fc9470..cfe29f6b7 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/clock.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/clock.h @@ -4,11 +4,12 @@ #ifndef METAL__CLOCK_H #define METAL__CLOCK_H -/*! +/*! * @file clock.h * @brief API for manipulating clock sources * - * The clock interface allows for controlling the rate of various clocks in the system. + * The clock interface allows for controlling the rate of various clocks in the + * system. */ struct metal_clock; @@ -45,7 +46,8 @@ typedef struct _metal_clock_callback_t metal_clock_callback; /*! * @brief Call all callbacks in the linked list, if any are registered */ -__inline__ void _metal_clock_call_all_callbacks(const metal_clock_callback *const list) { +__inline__ void +_metal_clock_call_all_callbacks(const metal_clock_callback *const list) { const metal_clock_callback *current = list; while (current) { current->callback(current->priv); @@ -56,7 +58,9 @@ __inline__ void _metal_clock_call_all_callbacks(const metal_clock_callback *cons /*! * @brief Append a callback to the linked list and return the head of the list */ -__inline__ metal_clock_callback *_metal_clock_append_to_callbacks(metal_clock_callback *list, metal_clock_callback *const cb) { +__inline__ metal_clock_callback * +_metal_clock_append_to_callbacks(metal_clock_callback *list, + metal_clock_callback *const cb) { cb->_next = NULL; if (!list) { @@ -78,13 +82,14 @@ __inline__ metal_clock_callback *_metal_clock_append_to_callbacks(metal_clock_ca * @struct metal_clock * @brief The handle for a clock * - * Clocks are defined as a pointer to a `struct metal_clock`, the contents of which - * are implementation defined. Users of the clock interface must call functions - * which accept a `struct metal_clock *` as an argument to interract with the clock. + * Clocks are defined as a pointer to a `struct metal_clock`, the contents of + * which are implementation defined. Users of the clock interface must call + * functions which accept a `struct metal_clock *` as an argument to interract + * with the clock. * - * Note that no mechanism for obtaining a pointer to a `struct metal_clock` has been - * defined, making it impossible to call any of these functions without invoking - * implementation-defined behavior. + * Note that no mechanism for obtaining a pointer to a `struct metal_clock` has + * been defined, making it impossible to call any of these functions without + * invoking implementation-defined behavior. */ struct metal_clock { const struct __metal_clock_vtable *vtable; @@ -102,7 +107,9 @@ struct metal_clock { * @param clk The handle for the clock * @return The current rate of the clock in Hz */ -__inline__ long metal_clock_get_rate_hz(const struct metal_clock *clk) { return clk->vtable->get_rate_hz(clk); } +__inline__ long metal_clock_get_rate_hz(const struct metal_clock *clk) { + return clk->vtable->get_rate_hz(clk); +} /*! * @brief Set the current rate of a clock @@ -115,11 +122,10 @@ __inline__ long metal_clock_get_rate_hz(const struct metal_clock *clk) { return * to the given rate in Hz. Returns the actual value that's been selected, which * could be anything! * - * Prior to and after the rate change of the clock, this will call the registered - * pre- and post-rate change callbacks. + * Prior to and after the rate change of the clock, this will call the + * registered pre- and post-rate change callbacks. */ -__inline__ long metal_clock_set_rate_hz(struct metal_clock *clk, long hz) -{ +__inline__ long metal_clock_set_rate_hz(struct metal_clock *clk, long hz) { _metal_clock_call_all_callbacks(clk->_pre_rate_change_callback); long out = clk->vtable->set_rate_hz(clk, hz); @@ -135,9 +141,11 @@ __inline__ long metal_clock_set_rate_hz(struct metal_clock *clk, long hz) * @param clk The handle for the clock * @param cb The callback to be registered */ -__inline__ void metal_clock_register_pre_rate_change_callback(struct metal_clock *clk, metal_clock_callback *cb) -{ - clk->_pre_rate_change_callback = _metal_clock_append_to_callbacks(clk->_pre_rate_change_callback, cb); +__inline__ void +metal_clock_register_pre_rate_change_callback(struct metal_clock *clk, + metal_clock_callback *cb) { + clk->_pre_rate_change_callback = + _metal_clock_append_to_callbacks(clk->_pre_rate_change_callback, cb); } /*! @@ -146,9 +154,11 @@ __inline__ void metal_clock_register_pre_rate_change_callback(struct metal_clock * @param clk The handle for the clock * @param cb The callback to be registered */ -__inline__ void metal_clock_register_post_rate_change_callback(struct metal_clock *clk, metal_clock_callback *cb) -{ - clk->_post_rate_change_callback = _metal_clock_append_to_callbacks(clk->_post_rate_change_callback, cb); +__inline__ void +metal_clock_register_post_rate_change_callback(struct metal_clock *clk, + metal_clock_callback *cb) { + clk->_post_rate_change_callback = + _metal_clock_append_to_callbacks(clk->_post_rate_change_callback, cb); } #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/compiler.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/compiler.h index 62c0ea975..80ca5fee4 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/compiler.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/compiler.h @@ -4,18 +4,19 @@ #ifndef METAL__COMPILER_H #define METAL__COMPILER_H -#define __METAL_DECLARE_VTABLE(type) \ - extern const struct type type; +#define __METAL_DECLARE_VTABLE(type) extern const struct type type; -#define __METAL_DEFINE_VTABLE(type) \ - const struct type type +#define __METAL_DEFINE_VTABLE(type) const struct type type -#define __METAL_GET_FIELD(reg, mask) \ +#define __METAL_GET_FIELD(reg, mask) \ (((reg) & (mask)) / ((mask) & ~((mask) << 1))) /* Set field with mask for a given value */ -#define __METAL_SET_FIELD(reg, mask, val) \ - (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask))) +#define __METAL_SET_FIELD(reg, mask, val) \ + (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask))) + +#define __METAL_MIN(a, b) ((a) < (b) ? (a) : (b)) +#define __METAL_MAX(a, b) ((a) > (b) ? (a) : (b)) void _metal_trap(int ecode); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/cpu.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/cpu.h index dbd3dbfb5..98d7e6680 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/cpu.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/cpu.h @@ -9,33 +9,35 @@ #ifndef METAL__CPU_H #define METAL__CPU_H -#include <stdint.h> #include <metal/interrupt.h> +#include <stdint.h> struct metal_cpu; /*! * @brief Function signature for exception handlers */ -typedef void (*metal_exception_handler_t) (struct metal_cpu *cpu, int ecode); +typedef void (*metal_exception_handler_t)(struct metal_cpu *cpu, int ecode); struct metal_cpu_vtable { unsigned long long (*mcycle_get)(struct metal_cpu *cpu); unsigned long long (*timebase_get)(struct metal_cpu *cpu); unsigned long long (*mtime_get)(struct metal_cpu *cpu); int (*mtimecmp_set)(struct metal_cpu *cpu, unsigned long long time); - struct metal_interrupt* (*tmr_controller_interrupt)(struct metal_cpu *cpu); + struct metal_interrupt *(*tmr_controller_interrupt)(struct metal_cpu *cpu); int (*get_tmr_interrupt_id)(struct metal_cpu *cpu); - struct metal_interrupt* (*sw_controller_interrupt)(struct metal_cpu *cpu); + struct metal_interrupt *(*sw_controller_interrupt)(struct metal_cpu *cpu); int (*get_sw_interrupt_id)(struct metal_cpu *cpu); int (*set_sw_ipi)(struct metal_cpu *cpu, int hartid); int (*clear_sw_ipi)(struct metal_cpu *cpu, int hartid); int (*get_msip)(struct metal_cpu *cpu, int hartid); - struct metal_interrupt* (*controller_interrupt)(struct metal_cpu *cpu); - int (*exception_register)(struct metal_cpu *cpu, int ecode, metal_exception_handler_t handler); + struct metal_interrupt *(*controller_interrupt)(struct metal_cpu *cpu); + int (*exception_register)(struct metal_cpu *cpu, int ecode, + metal_exception_handler_t handler); int (*get_ilen)(struct metal_cpu *cpu, uintptr_t epc); uintptr_t (*get_epc)(struct metal_cpu *cpu); int (*set_epc)(struct metal_cpu *cpu, uintptr_t epc); + struct metal_buserror *(*get_buserror)(struct metal_cpu *cpu); }; /*! @brief A device handle for a CPU hart @@ -49,7 +51,7 @@ struct metal_cpu { * @param hartid The ID of the desired CPU hart * @return A pointer to the CPU device handle */ -struct metal_cpu* metal_cpu_get(unsigned int hartid); +struct metal_cpu *metal_cpu_get(unsigned int hartid); /*! @brief Get the hartid of the CPU hart executing this function * @@ -57,7 +59,7 @@ struct metal_cpu* metal_cpu_get(unsigned int hartid); int metal_cpu_get_current_hartid(void); /*! @brief Get the number of CPU harts - * + * * @return The number of CPU harts */ int metal_cpu_get_num_harts(void); @@ -68,8 +70,9 @@ int metal_cpu_get_num_harts(void); * @param cpu The CPU device handle * @return The value of the CPU cycle count timer */ -__inline__ unsigned long long metal_cpu_get_timer(struct metal_cpu *cpu) -{ return cpu->vtable->mcycle_get(cpu); } +__inline__ unsigned long long metal_cpu_get_timer(struct metal_cpu *cpu) { + return cpu->vtable->mcycle_get(cpu); +} /*! @brief Get the timebase of the CPU * @@ -78,8 +81,9 @@ __inline__ unsigned long long metal_cpu_get_timer(struct metal_cpu *cpu) * @param cpu The CPU device handle * @return The value of the cycle count timer timebase */ -__inline__ unsigned long long metal_cpu_get_timebase(struct metal_cpu *cpu) -{ return cpu->vtable->timebase_get(cpu); } +__inline__ unsigned long long metal_cpu_get_timebase(struct metal_cpu *cpu) { + return cpu->vtable->timebase_get(cpu); +} /*! @brief Get the value of the mtime RTC * @@ -90,8 +94,9 @@ __inline__ unsigned long long metal_cpu_get_timebase(struct metal_cpu *cpu) * @param cpu The CPU device handle * @return The value of mtime, or 0 if failure */ -__inline__ unsigned long long metal_cpu_get_mtime(struct metal_cpu *cpu) -{ return cpu->vtable->mtime_get(cpu); } +__inline__ unsigned long long metal_cpu_get_mtime(struct metal_cpu *cpu) { + return cpu->vtable->mtime_get(cpu); +} /*! @brief Set the value of the RTC mtimecmp RTC * @@ -103,20 +108,24 @@ __inline__ unsigned long long metal_cpu_get_mtime(struct metal_cpu *cpu) * @param time The value to set the compare register to * @return The value of mtimecmp or -1 if error */ -__inline__ int metal_cpu_set_mtimecmp(struct metal_cpu *cpu, unsigned long long time) -{ return cpu->vtable->mtimecmp_set(cpu, time); } +__inline__ int metal_cpu_set_mtimecmp(struct metal_cpu *cpu, + unsigned long long time) { + return cpu->vtable->mtimecmp_set(cpu, time); +} /*! @brief Get a reference to RTC timer interrupt controller * - * Get a reference to the interrupt controller for the real-time clock interrupt. - * The controller returned by this function must be initialized before any interrupts - * are registered or enabled with it. + * Get a reference to the interrupt controller for the real-time clock + * interrupt. The controller returned by this function must be initialized + * before any interrupts are registered or enabled with it. * * @param cpu The CPU device handle * @return A pointer to the timer interrupt handle */ -__inline__ struct metal_interrupt* metal_cpu_timer_interrupt_controller(struct metal_cpu *cpu) -{ return cpu->vtable->tmr_controller_interrupt(cpu); } +__inline__ struct metal_interrupt * +metal_cpu_timer_interrupt_controller(struct metal_cpu *cpu) { + return cpu->vtable->tmr_controller_interrupt(cpu); +} /*! @brief Get the RTC timer interrupt id * @@ -125,20 +134,23 @@ __inline__ struct metal_interrupt* metal_cpu_timer_interrupt_controller(struct m * @param cpu The CPU device handle * @return The timer interrupt ID */ -__inline__ int metal_cpu_timer_get_interrupt_id(struct metal_cpu *cpu) -{ return cpu->vtable->get_tmr_interrupt_id(cpu); } +__inline__ int metal_cpu_timer_get_interrupt_id(struct metal_cpu *cpu) { + return cpu->vtable->get_tmr_interrupt_id(cpu); +} /*! @brief Get a reference to the software interrupt controller * * Get a reference to the interrupt controller for the software/inter-process - * interrupt. The controller returned by this function must be initialized before - * any interrupts are registered or enabled with it. + * interrupt. The controller returned by this function must be initialized + * before any interrupts are registered or enabled with it. * * @param cpu The CPU device handle * @return A pointer to the software interrupt handle */ -__inline__ struct metal_interrupt* metal_cpu_software_interrupt_controller(struct metal_cpu *cpu) -{ return cpu->vtable->sw_controller_interrupt(cpu); } +__inline__ struct metal_interrupt * +metal_cpu_software_interrupt_controller(struct metal_cpu *cpu) { + return cpu->vtable->sw_controller_interrupt(cpu); +} /*! @brief Get the software interrupt id * @@ -147,8 +159,9 @@ __inline__ struct metal_interrupt* metal_cpu_software_interrupt_controller(struc * @param cpu The CPU device handle * @return the software interrupt ID */ -__inline__ int metal_cpu_software_get_interrupt_id(struct metal_cpu *cpu) -{ return cpu->vtable->get_sw_interrupt_id(cpu); } +__inline__ int metal_cpu_software_get_interrupt_id(struct metal_cpu *cpu) { + return cpu->vtable->get_sw_interrupt_id(cpu); +} /*! * @brief Set the inter-process interrupt for a hart @@ -161,8 +174,9 @@ __inline__ int metal_cpu_software_get_interrupt_id(struct metal_cpu *cpu) * @param hartid The CPU hart ID to be interrupted * @return 0 upon success */ -__inline__ int metal_cpu_software_set_ipi(struct metal_cpu *cpu, int hartid) -{ return cpu->vtable->set_sw_ipi(cpu, hartid); } +__inline__ int metal_cpu_software_set_ipi(struct metal_cpu *cpu, int hartid) { + return cpu->vtable->set_sw_ipi(cpu, hartid); +} /*! * @brief Clear the inter-process interrupt for a hart @@ -175,8 +189,9 @@ __inline__ int metal_cpu_software_set_ipi(struct metal_cpu *cpu, int hartid) * @param hartid The CPU hart ID to clear * @return 0 upon success */ -__inline__ int metal_cpu_software_clear_ipi(struct metal_cpu *cpu, int hartid) -{ return cpu->vtable->clear_sw_ipi(cpu, hartid); } +__inline__ int metal_cpu_software_clear_ipi(struct metal_cpu *cpu, int hartid) { + return cpu->vtable->clear_sw_ipi(cpu, hartid); +} /*! * @brief Get the value of MSIP for the given hart @@ -190,8 +205,9 @@ __inline__ int metal_cpu_software_clear_ipi(struct metal_cpu *cpu, int hartid) * @param hartid The CPU hart to read * @return 0 upon success */ -__inline__ int metal_cpu_get_msip(struct metal_cpu *cpu, int hartid) -{ return cpu->vtable->get_msip(cpu, hartid); } +__inline__ int metal_cpu_get_msip(struct metal_cpu *cpu, int hartid) { + return cpu->vtable->get_msip(cpu, hartid); +} /*! * @brief Get the interrupt controller for the CPU @@ -204,22 +220,26 @@ __inline__ int metal_cpu_get_msip(struct metal_cpu *cpu, int hartid) * @param cpu The CPU device handle * @return The handle for the CPU interrupt controller */ -__inline__ struct metal_interrupt* metal_cpu_interrupt_controller(struct metal_cpu *cpu) -{ return cpu->vtable->controller_interrupt(cpu); } +__inline__ struct metal_interrupt * +metal_cpu_interrupt_controller(struct metal_cpu *cpu) { + return cpu->vtable->controller_interrupt(cpu); +} /*! * @brief Register an exception handler - * - * Register an exception handler for the CPU. The CPU interrupt controller must be initialized - * before this function is called. + * + * Register an exception handler for the CPU. The CPU interrupt controller must + * be initialized before this function is called. * * @param cpu The CPU device handle * @param ecode The exception code to register a handler for * @param handler Callback function for the exception handler * @return 0 upon success */ -__inline__ int metal_cpu_exception_register(struct metal_cpu *cpu, int ecode, metal_exception_handler_t handler) -{ return cpu->vtable->exception_register(cpu, ecode, handler); } +__inline__ int metal_cpu_exception_register(struct metal_cpu *cpu, int ecode, + metal_exception_handler_t handler) { + return cpu->vtable->exception_register(cpu, ecode, handler); +} /*! * @brief Get the length of an instruction in bytes @@ -237,8 +257,10 @@ __inline__ int metal_cpu_exception_register(struct metal_cpu *cpu, int ecode, me * @param epc The address of the instruction to measure * @return the length of the instruction in bytes */ -__inline__ int metal_cpu_get_instruction_length(struct metal_cpu *cpu, uintptr_t epc) -{ return cpu->vtable->get_ilen(cpu, epc); } +__inline__ int metal_cpu_get_instruction_length(struct metal_cpu *cpu, + uintptr_t epc) { + return cpu->vtable->get_ilen(cpu, epc); +} /*! * @brief Get the program counter of the current exception. @@ -249,8 +271,9 @@ __inline__ int metal_cpu_get_instruction_length(struct metal_cpu *cpu, uintptr_t * @param cpu The CPU device handle * @return The value of the program counter at the time of the exception */ -__inline__ uintptr_t metal_cpu_get_exception_pc(struct metal_cpu *cpu) -{ return cpu->vtable->get_epc(cpu); } +__inline__ uintptr_t metal_cpu_get_exception_pc(struct metal_cpu *cpu) { + return cpu->vtable->get_epc(cpu); +} /*! * @brief Set the exception program counter @@ -265,7 +288,20 @@ __inline__ uintptr_t metal_cpu_get_exception_pc(struct metal_cpu *cpu) * @param epc The address to set the exception program counter to * @return 0 upon success */ -__inline__ int metal_cpu_set_exception_pc(struct metal_cpu *cpu, uintptr_t epc) -{ return cpu->vtable->set_epc(cpu, epc); } +__inline__ int metal_cpu_set_exception_pc(struct metal_cpu *cpu, + uintptr_t epc) { + return cpu->vtable->set_epc(cpu, epc); +} + +/*! + * @brief Get the handle for the hart's bus error unit + * + * @param cpu The CPU device handle + * @return A pointer to the bus error unit handle + */ +__inline__ struct metal_buserror * +metal_cpu_get_buserror(struct metal_cpu *cpu) { + return cpu->vtable->get_buserror(cpu); +} #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/csr.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/csr.h new file mode 100644 index 000000000..8375d8a44 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/csr.h @@ -0,0 +1,32 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__CSR_H +#define METAL__CSR_H + +#include <metal/compiler.h> +#include <stddef.h> +#include <stdint.h> + +/*! + * @file csr.h + * @brief A collection of APIs for get and set CSR registers + */ + +/*! + * @brief Read a given CSR register without checking validity of CSR offset + * @param crs Register label or hex value offset to read from + * @param value Variable name of uintprt_t type to get the value + */ +#define METAL_CPU_GET_CSR(reg, value) \ + __asm__ volatile("csrr %0, " #reg : "=r"(value)); + +/*! + * @brief Write to a given CSR register without checking validity of CSR offset + * @param crs Register label or hex value offset to write to + * @param value Variable name of uintprt_t type to set the value + */ +#define METAL_CPU_SET_CSR(reg, value) \ + __asm__ volatile("csrw " #reg ", %0" : : "r"(value)); + +#endif // METAL__CSR_H diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/fixed-clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/fixed-clock.h index 2647c5981..b25f54144 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/fixed-clock.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/fixed-clock.h @@ -6,8 +6,8 @@ struct __metal_driver_fixed_clock; -#include <metal/compiler.h> #include <metal/clock.h> +#include <metal/compiler.h> struct __metal_driver_vtable_fixed_clock { struct __metal_clock_vtable clock; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/fixed-factor-clock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/fixed-factor-clock.h index 936ce8d77..84e4fd580 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/fixed-factor-clock.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/fixed-factor-clock.h @@ -6,8 +6,8 @@ struct __metal_driver_fixed_factor_clock; -#include <metal/compiler.h> #include <metal/clock.h> +#include <metal/compiler.h> struct __metal_driver_vtable_fixed_factor_clock { struct __metal_clock_vtable clock; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_clint0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_clint0.h index 08d571e1c..ceda473e2 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_clint0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_clint0.h @@ -21,4 +21,7 @@ struct __metal_driver_riscv_clint0 { }; #undef __METAL_MACHINE_MACROS +int __metal_driver_riscv_clint0_command_request( + struct metal_interrupt *controller, int command, void *data); + #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_cpu.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_cpu.h index ca91e0a95..f3005f01f 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_cpu.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_cpu.h @@ -4,152 +4,154 @@ #ifndef METAL__DRIVERS__RISCV_CPU_H #define METAL__DRIVERS__RISCV_CPU_H -#include <stdint.h> -#include <metal/cpu.h> #include <metal/compiler.h> +#include <metal/cpu.h> +#include <stdint.h> -#define METAL_MAX_CORES 8 -#define METAL_MAX_MI 32 /* Per ISA MCause interrupts 32+ are Reserved */ -#define METAL_MAX_ME 12 /* Per ISA Exception codes 12+ are Reserved */ -#define METAL_DEFAULT_RTC_FREQ 32768 - -#define METAL_DISABLE 0 -#define METAL_ENABLE 1 - -#define METAL_ISA_A_EXTENSIONS 0x0001 -#define METAL_ISA_C_EXTENSIONS 0x0004 -#define METAL_ISA_D_EXTENSIONS 0x0008 -#define METAL_ISA_E_EXTENSIONS 0x0010 -#define METAL_ISA_F_EXTENSIONS 0x0020 -#define METAL_ISA_G_EXTENSIONS 0x0040 -#define METAL_ISA_I_EXTENSIONS 0x0100 -#define METAL_ISA_M_EXTENSIONS 0x1000 -#define METAL_ISA_N_EXTENSIONS 0x2000 -#define METAL_ISA_Q_EXTENSIONS 0x10000 -#define METAL_ISA_S_EXTENSIONS 0x40000 -#define METAL_ISA_U_EXTENSIONS 0x100000 -#define METAL_ISA_V_EXTENSIONS 0x200000 -#define METAL_ISA_XL32_EXTENSIONS 0x40000000UL -#define METAL_ISA_XL64_EXTENSIONS 0x8000000000000000UL +#define METAL_MAX_CORES 8 +#define METAL_MAX_MI 32 /* Per ISA MCause interrupts 32+ are Reserved */ +#define METAL_MAX_ME 12 /* Per ISA Exception codes 12+ are Reserved */ +#define METAL_DEFAULT_RTC_FREQ 32768 + +#define METAL_DISABLE 0 +#define METAL_ENABLE 1 + +#define METAL_ISA_A_EXTENSIONS 0x0001 +#define METAL_ISA_C_EXTENSIONS 0x0004 +#define METAL_ISA_D_EXTENSIONS 0x0008 +#define METAL_ISA_E_EXTENSIONS 0x0010 +#define METAL_ISA_F_EXTENSIONS 0x0020 +#define METAL_ISA_G_EXTENSIONS 0x0040 +#define METAL_ISA_I_EXTENSIONS 0x0100 +#define METAL_ISA_M_EXTENSIONS 0x1000 +#define METAL_ISA_N_EXTENSIONS 0x2000 +#define METAL_ISA_Q_EXTENSIONS 0x10000 +#define METAL_ISA_S_EXTENSIONS 0x40000 +#define METAL_ISA_U_EXTENSIONS 0x100000 +#define METAL_ISA_V_EXTENSIONS 0x200000 +#define METAL_ISA_XL32_EXTENSIONS 0x40000000UL +#define METAL_ISA_XL64_EXTENSIONS 0x8000000000000000UL #define METAL_ISA_XL128_EXTENSIONS 0xC000000000000000UL -#define METAL_MTVEC_DIRECT 0x00 -#define METAL_MTVEC_VECTORED 0x01 -#define METAL_MTVEC_CLIC 0x02 -#define METAL_MTVEC_CLIC_VECTORED 0x03 -#define METAL_MTVEC_CLIC_RESERVED 0x3C -#define METAL_MTVEC_MASK 0x3F +#define METAL_MTVEC_DIRECT 0x00 +#define METAL_MTVEC_VECTORED 0x01 +#define METAL_MTVEC_CLIC 0x02 +#define METAL_MTVEC_CLIC_VECTORED 0x03 +#define METAL_MTVEC_CLIC_RESERVED 0x3C +#define METAL_MTVEC_MASK 0x3F #if __riscv_xlen == 32 -#define METAL_MCAUSE_INTR 0x80000000UL -#define METAL_MCAUSE_CAUSE 0x000003FFUL +#define METAL_MCAUSE_INTR 0x80000000UL +#define METAL_MCAUSE_CAUSE 0x000003FFUL #else -#define METAL_MCAUSE_INTR 0x8000000000000000UL -#define METAL_MCAUSE_CAUSE 0x00000000000003FFUL +#define METAL_MCAUSE_INTR 0x8000000000000000UL +#define METAL_MCAUSE_CAUSE 0x00000000000003FFUL #endif -#define METAL_MCAUSE_MINHV 0x40000000UL -#define METAL_MCAUSE_MPP 0x30000000UL -#define METAL_MCAUSE_MPIE 0x08000000UL -#define METAL_MCAUSE_MPIL 0x00FF0000UL -#define METAL_MSTATUS_MIE 0x00000008UL -#define METAL_MSTATUS_MPIE 0x00000080UL -#define METAL_MSTATUS_MPP 0x00001800UL -#define METAL_MSTATUS_FS_INIT 0x00002000UL -#define METAL_MSTATUS_FS_CLEAN 0x00004000UL -#define METAL_MSTATUS_FS_DIRTY 0x00006000UL -#define METAL_MSTATUS_MPRV 0x00020000UL -#define METAL_MSTATUS_MXR 0x00080000UL -#define METAL_MINTSTATUS_MIL 0xFF000000UL -#define METAL_MINTSTATUS_SIL 0x0000FF00UL -#define METAL_MINTSTATUS_UIL 0x000000FFUL - -#define METAL_LOCAL_INTR(X) (16 + X) -#define METAL_MCAUSE_EVAL(cause) (cause & METAL_MCAUSE_INTR) -#define METAL_INTERRUPT(cause) (METAL_MCAUSE_EVAL(cause) ? 1 : 0) -#define METAL_EXCEPTION(cause) (METAL_MCAUSE_EVAL(cause) ? 0 : 1) -#define METAL_SW_INTR_EXCEPTION (METAL_MCAUSE_INTR + 3) -#define METAL_TMR_INTR_EXCEPTION (METAL_MCAUSE_INTR + 7) -#define METAL_EXT_INTR_EXCEPTION (METAL_MCAUSE_INTR + 11) +#define METAL_MCAUSE_MINHV 0x40000000UL +#define METAL_MCAUSE_MPP 0x30000000UL +#define METAL_MCAUSE_MPIE 0x08000000UL +#define METAL_MCAUSE_MPIL 0x00FF0000UL +#define METAL_MSTATUS_MIE 0x00000008UL +#define METAL_MSTATUS_MPIE 0x00000080UL +#define METAL_MSTATUS_MPP 0x00001800UL +#define METAL_MSTATUS_FS_INIT 0x00002000UL +#define METAL_MSTATUS_FS_CLEAN 0x00004000UL +#define METAL_MSTATUS_FS_DIRTY 0x00006000UL +#define METAL_MSTATUS_MPRV 0x00020000UL +#define METAL_MSTATUS_MXR 0x00080000UL +#define METAL_MINTSTATUS_MIL 0xFF000000UL +#define METAL_MINTSTATUS_SIL 0x0000FF00UL +#define METAL_MINTSTATUS_UIL 0x000000FFUL + +#define METAL_LOCAL_INTR(X) (16 + X) +#define METAL_MCAUSE_EVAL(cause) (cause & METAL_MCAUSE_INTR) +#define METAL_INTERRUPT(cause) (METAL_MCAUSE_EVAL(cause) ? 1 : 0) +#define METAL_EXCEPTION(cause) (METAL_MCAUSE_EVAL(cause) ? 0 : 1) +#define METAL_SW_INTR_EXCEPTION (METAL_MCAUSE_INTR + 3) +#define METAL_TMR_INTR_EXCEPTION (METAL_MCAUSE_INTR + 7) +#define METAL_EXT_INTR_EXCEPTION (METAL_MCAUSE_INTR + 11) #define METAL_LOCAL_INTR_EXCEPTION(X) (METAL_MCAUSE_INTR + METAL_LOCAL_INTR(X)) -#define METAL_LOCAL_INTR_RESERVE0 1 -#define METAL_LOCAL_INTR_RESERVE1 2 -#define METAL_LOCAL_INTR_RESERVE2 4 -#define METAL_LOCAL_INTERRUPT_SW 8 /* Bit3 0x008 */ -#define METAL_LOCAL_INTR_RESERVE4 16 -#define METAL_LOCAL_INTR_RESERVE5 32 -#define METAL_LOCAL_INTR_RESERVE6 64 -#define METAL_LOCAL_INTERRUPT_TMR 128 /* Bit7 0x080 */ -#define METAL_LOCAL_INTR_RESERVE8 256 -#define METAL_LOCAL_INTR_RESERVE9 512 -#define METAL_LOCAL_INTR_RESERVE10 1024 -#define METAL_LOCAL_INTERRUPT_EXT 2048 /* Bit11 0x800 */ +#define METAL_LOCAL_INTR_RESERVE0 1 +#define METAL_LOCAL_INTR_RESERVE1 2 +#define METAL_LOCAL_INTR_RESERVE2 4 +#define METAL_LOCAL_INTERRUPT_SW 8 /* Bit3 0x008 */ +#define METAL_LOCAL_INTR_RESERVE4 16 +#define METAL_LOCAL_INTR_RESERVE5 32 +#define METAL_LOCAL_INTR_RESERVE6 64 +#define METAL_LOCAL_INTERRUPT_TMR 128 /* Bit7 0x080 */ +#define METAL_LOCAL_INTR_RESERVE8 256 +#define METAL_LOCAL_INTR_RESERVE9 512 +#define METAL_LOCAL_INTR_RESERVE10 1024 +#define METAL_LOCAL_INTERRUPT_EXT 2048 /* Bit11 0x800 */ /* Bit12 to Bit15 are Reserved */ -#define METAL_LOCAL_INTERRUPT(X) (0x10000 << X) /* Bit16+ Start of Custom Local Interrupt */ -#define METAL_MIE_INTERRUPT METAL_MSTATUS_MIE +#define METAL_LOCAL_INTERRUPT(X) \ + (0x10000 << X) /* Bit16+ Start of Custom Local Interrupt */ +#define METAL_MIE_INTERRUPT METAL_MSTATUS_MIE -#define METAL_INSN_LENGTH_MASK 3 -#define METAL_INSN_NOT_COMPRESSED 3 +#define METAL_INSN_LENGTH_MASK 3 +#define METAL_INSN_NOT_COMPRESSED 3 typedef enum { - METAL_MACHINE_PRIVILEGE_MODE, - METAL_SUPERVISOR_PRIVILEGE_MODE, - METAL_USER_PRIVILEGE_MODE, + METAL_MACHINE_PRIVILEGE_MODE, + METAL_SUPERVISOR_PRIVILEGE_MODE, + METAL_USER_PRIVILEGE_MODE, } metal_privilege_mode_e; typedef enum { - METAL_INTERRUPT_ID_BASE, - METAL_INTERRUPT_ID_SW = (METAL_INTERRUPT_ID_BASE + 3), - METAL_INTERRUPT_ID_TMR = (METAL_INTERRUPT_ID_BASE + 7), - METAL_INTERRUPT_ID_EXT = (METAL_INTERRUPT_ID_BASE + 11), - METAL_INTERRUPT_ID_CSW = (METAL_INTERRUPT_ID_BASE + 12), - METAL_INTERRUPT_ID_LC0 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(0)), - METAL_INTERRUPT_ID_LC1 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(1)), - METAL_INTERRUPT_ID_LC2 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(2)), - METAL_INTERRUPT_ID_LC3 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(3)), - METAL_INTERRUPT_ID_LC4 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(4)), - METAL_INTERRUPT_ID_LC5 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(5)), - METAL_INTERRUPT_ID_LC6 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(6)), - METAL_INTERRUPT_ID_LC7 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(7)), - METAL_INTERRUPT_ID_LC8 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(8)), - METAL_INTERRUPT_ID_LC9 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(9)), - METAL_INTERRUPT_ID_LC10 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(10)), - METAL_INTERRUPT_ID_LC11 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(11)), - METAL_INTERRUPT_ID_LC12 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(12)), - METAL_INTERRUPT_ID_LC13 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(13)), - METAL_INTERRUPT_ID_LC14 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(14)), - METAL_INTERRUPT_ID_LC15 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(15)), - METAL_INTERRUPT_ID_LCMX, - METAL_INTERRUPT_ID_GL0 = METAL_INTERRUPT_ID_LCMX, - METAL_INTERRUPT_ID_GLMX = (METAL_MCAUSE_CAUSE + 1), + METAL_INTERRUPT_ID_BASE, + METAL_INTERRUPT_ID_SW = (METAL_INTERRUPT_ID_BASE + 3), + METAL_INTERRUPT_ID_TMR = (METAL_INTERRUPT_ID_BASE + 7), + METAL_INTERRUPT_ID_EXT = (METAL_INTERRUPT_ID_BASE + 11), + METAL_INTERRUPT_ID_CSW = (METAL_INTERRUPT_ID_BASE + 12), + METAL_INTERRUPT_ID_LC0 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(0)), + METAL_INTERRUPT_ID_LC1 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(1)), + METAL_INTERRUPT_ID_LC2 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(2)), + METAL_INTERRUPT_ID_LC3 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(3)), + METAL_INTERRUPT_ID_LC4 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(4)), + METAL_INTERRUPT_ID_LC5 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(5)), + METAL_INTERRUPT_ID_LC6 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(6)), + METAL_INTERRUPT_ID_LC7 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(7)), + METAL_INTERRUPT_ID_LC8 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(8)), + METAL_INTERRUPT_ID_LC9 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(9)), + METAL_INTERRUPT_ID_LC10 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(10)), + METAL_INTERRUPT_ID_LC11 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(11)), + METAL_INTERRUPT_ID_LC12 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(12)), + METAL_INTERRUPT_ID_LC13 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(13)), + METAL_INTERRUPT_ID_LC14 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(14)), + METAL_INTERRUPT_ID_LC15 = (METAL_INTERRUPT_ID_BASE + METAL_LOCAL_INTR(15)), + METAL_INTERRUPT_ID_LCMX, + METAL_INTERRUPT_ID_GL0 = METAL_INTERRUPT_ID_LCMX, + METAL_INTERRUPT_ID_GLMX = (METAL_MCAUSE_CAUSE + 1), + METAL_INTERRUPT_ID_BEU = 128, } metal_interrupt_id_e; typedef enum { - METAL_IAM_EXCEPTION_CODE, /* Instruction address misaligned */ - METAL_IAF_EXCEPTION_CODE, /* Instruction access faultd */ - METAL_II_EXCEPTION_CODE, /* Illegal instruction */ - METAL_BREAK_EXCEPTION_CODE, /* Breakpoint */ - METAL_LAM_EXCEPTION_CODE, /* Load address misaligned */ - METAL_LAF_EXCEPTION_CODE, /* Load access fault */ - METAL_SAMOAM_EXCEPTION_CODE, /* Store/AMO address misaligned */ - METAL_SAMOAF_EXCEPTION_CODE, /* Store/AMO access fault */ - METAL_ECALL_U_EXCEPTION_CODE, /* Environment call from U-mode */ - METAL_R9_EXCEPTION_CODE, /* Reserved */ - METAL_R10_EXCEPTION_CODE, /* Reserved */ - METAL_ECALL_M_EXCEPTION_CODE, /* Environment call from M-mode */ - METAL_MAX_EXCEPTION_CODE, + METAL_IAM_EXCEPTION_CODE, /* Instruction address misaligned */ + METAL_IAF_EXCEPTION_CODE, /* Instruction access faultd */ + METAL_II_EXCEPTION_CODE, /* Illegal instruction */ + METAL_BREAK_EXCEPTION_CODE, /* Breakpoint */ + METAL_LAM_EXCEPTION_CODE, /* Load address misaligned */ + METAL_LAF_EXCEPTION_CODE, /* Load access fault */ + METAL_SAMOAM_EXCEPTION_CODE, /* Store/AMO address misaligned */ + METAL_SAMOAF_EXCEPTION_CODE, /* Store/AMO access fault */ + METAL_ECALL_U_EXCEPTION_CODE, /* Environment call from U-mode */ + METAL_R9_EXCEPTION_CODE, /* Reserved */ + METAL_R10_EXCEPTION_CODE, /* Reserved */ + METAL_ECALL_M_EXCEPTION_CODE, /* Environment call from M-mode */ + METAL_MAX_EXCEPTION_CODE, } metal_exception_code_e; typedef enum { - METAL_TIMER_MTIME_GET = 1, - METAL_SOFTWARE_IPI_CLEAR, - METAL_SOFTWARE_IPI_SET, - METAL_SOFTWARE_MSIP_GET, - METAL_MAX_INTERRUPT_GET, - METAL_INDEX_INTERRUPT_GET, + METAL_TIMER_MTIME_GET = 1, + METAL_SOFTWARE_IPI_CLEAR, + METAL_SOFTWARE_IPI_SET, + METAL_SOFTWARE_MSIP_GET, + METAL_MAX_INTERRUPT_GET, + METAL_INDEX_INTERRUPT_GET, } metal_interrup_cmd_e; typedef struct __metal_interrupt_data { long long pad : 64; - metal_interrupt_handler_t handler; + metal_interrupt_handler_t handler; void *sub_int; void *exint_data; } __metal_interrupt_data; @@ -159,14 +161,14 @@ typedef struct __metal_interrupt_data { uintptr_t __metal_myhart_id(void); struct __metal_driver_vtable_riscv_cpu_intc { - struct metal_interrupt_vtable controller_vtable; + struct metal_interrupt_vtable controller_vtable; }; - void __metal_interrupt_global_enable(void); void __metal_interrupt_global_disable(void); metal_vector_mode __metal_controller_interrupt_vector_mode(void); -void __metal_controller_interrupt_vector(metal_vector_mode mode, void *vec_table); +void __metal_controller_interrupt_vector(metal_vector_mode mode, + void *vec_table); __METAL_DECLARE_VTABLE(__metal_driver_vtable_riscv_cpu_intc) @@ -175,18 +177,20 @@ struct __metal_driver_riscv_cpu_intc { int init_done; uintptr_t metal_mtvec_table[METAL_MAX_MI]; __metal_interrupt_data metal_int_table[METAL_MAX_MI]; + __metal_interrupt_data metal_int_beu; metal_exception_handler_t metal_exception_table[METAL_MAX_ME]; }; /* CPU driver*/ struct __metal_driver_vtable_cpu { - struct metal_cpu_vtable cpu_vtable; + struct metal_cpu_vtable cpu_vtable; }; __METAL_DECLARE_VTABLE(__metal_driver_vtable_cpu) struct __metal_driver_cpu { struct metal_cpu cpu; + unsigned int hpm_count; /* Available HPM counters per CPU */ }; #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_plic0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_plic0.h index 159ee6d69..fac76fbc3 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_plic0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/riscv_plic0.h @@ -7,10 +7,10 @@ #include <metal/compiler.h> #include <metal/drivers/riscv_cpu.h> -#define METAL_PLIC_SOURCE_MASK 0x1F -#define METAL_PLIC_SOURCE_SHIFT 5 -#define METAL_PLIC_SOURCE_PRIORITY_SHIFT 2 -#define METAL_PLIC_SOURCE_PENDING_SHIFT 0 +#define METAL_PLIC_SOURCE_MASK 0x1F +#define METAL_PLIC_SOURCE_SHIFT 5 +#define METAL_PLIC_SOURCE_PRIORITY_SHIFT 2 +#define METAL_PLIC_SOURCE_PENDING_SHIFT 0 struct __metal_driver_vtable_riscv_plic0 { struct metal_interrupt_vtable plic_vtable; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_buserror0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_buserror0.h new file mode 100644 index 000000000..20972109b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_buserror0.h @@ -0,0 +1,184 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_BUSERROR0_H +#define METAL__DRIVERS__SIFIVE_BUSERROR0_H + +/*! + * @file sifive_buserror0.h + * + * @brief API for configuring the SiFive Bus Error Unit + */ + +#include <metal/compiler.h> +#include <stdbool.h> +#include <stdint.h> + +/*! + * @brief The set of possible events handled by a SiFive Bus Error Unit + */ +typedef enum { + /*! @brief No event or error has been detected */ + METAL_BUSERROR_EVENT_NONE = 0, + + /*! @brief A correctable ECC error has occurred in the I$ or ITIM */ + METAL_BUSERROR_EVENT_INST_CORRECTABLE_ECC_ERROR = (1 << 2), + /*! @brief An uncorrectable ECC error has occurred in the I$ or ITIM */ + METAL_BUSERROR_EVENT_INST_UNCORRECTABLE_ECC_ERROR = (1 << 3), + /*! @brief A TileLink load or store bus error has occurred */ + METAL_BUSERROR_EVENT_LOAD_STORE_ERROR = (1 << 5), + /*! @brief A correctable ECC error has occurred in the D$ or DTIM */ + METAL_BUSERROR_EVENT_DATA_CORRECTABLE_ECC_ERROR = (1 << 6), + /*! @brief An uncorrectable ECC error has occurred in the D$ or DTIM */ + METAL_BUSERROR_EVENT_DATA_UNCORRECTABLE_ECC_ERROR = (1 << 7), + + /*! @brief Used to set/clear all interrupts or query/clear all accrued + events */ + METAL_BUSERROR_EVENT_ALL = + METAL_BUSERROR_EVENT_INST_CORRECTABLE_ECC_ERROR | + METAL_BUSERROR_EVENT_INST_UNCORRECTABLE_ECC_ERROR | + METAL_BUSERROR_EVENT_LOAD_STORE_ERROR | + METAL_BUSERROR_EVENT_DATA_CORRECTABLE_ECC_ERROR | + METAL_BUSERROR_EVENT_DATA_UNCORRECTABLE_ECC_ERROR, + /*! @brief A synonym of METAL_BUSERROR_EVENT_ALL */ + METAL_BUSERROR_EVENT_ANY = METAL_BUSERROR_EVENT_ALL, + + /*! @brief A value which is impossible for the bus error unit to report. + * Indicates an error has occurred if provided as a return value. */ + METAL_BUSERROR_EVENT_INVALID = (1 << 8), +} metal_buserror_event_t; + +/*! + * @brief The handle for a bus error unit + */ +struct metal_buserror { + uint8_t __no_empty_structs; +}; + +/*! + * @brief Enable bus error events + * + * Enabling bus error events causes them to be registered as accrued and, + * if the corresponding interrupt is inabled, trigger interrupts. + * + * @param beu The bus error unit handle + * @param events A mask of error events to enable + * @param enabled True if the mask should be enabled, false if they should be + * disabled + * @return 0 upon success + */ +int metal_buserror_set_event_enabled(struct metal_buserror *beu, + metal_buserror_event_t events, + bool enabled); + +/*! + * @brief Get enabled bus error events + * @param beu The bus error unit handle + * @return A mask of all enabled events + */ +metal_buserror_event_t +metal_buserror_get_event_enabled(struct metal_buserror *beu); + +/*! + * @brief Enable or disable the platform interrupt + * + * @param beu The bus error unit handle + * @param event The error event which would trigger the interrupt + * @param enabled True if the interrupt should be enabled + * @return 0 upon success + */ +int metal_buserror_set_platform_interrupt(struct metal_buserror *beu, + metal_buserror_event_t events, + bool enabled); + +/*! + * @brief Enable or disable the hart-local interrupt + * + * @param beu The bus error unit handle + * @param event The error event which would trigger the interrupt + * @param enabled True if the interrupt should be enabled + * @return 0 upon success + */ +int metal_buserror_set_local_interrupt(struct metal_buserror *beu, + metal_buserror_event_t events, + bool enabled); + +/*! + * @brief Get the error event which caused the most recent interrupt + * + * This method should be called from within the interrupt handler for the bus + * error unit interrupt + * + * @param beu The bus error unit handle + * @return The event which caused the interrupt + */ +metal_buserror_event_t metal_buserror_get_cause(struct metal_buserror *beu); + +/*! + * @brief Clear the cause register for the bus error unit + * + * This method should be called from within the interrupt handler for the bus + * error unit to un-latch the cause register for the next event + * + * @param beu The bus error unit handle + * @return 0 upon success + */ +int metal_buserror_clear_cause(struct metal_buserror *beu); + +/*! + * @brief Get the physical address of the error event + * + * This method should be called from within the interrupt handler for the bus + * error unit. + * + * @param beu The bus error unit handle + * @return The address of the error event + */ +uintptr_t metal_buserror_get_event_address(struct metal_buserror *beu); + +/*! + * @brief Returns true if the event is set in the accrued register + * + * @param beu The bus error unit handle + * @param event The event to query + * @return True if the event is set in the accrued register + */ +bool metal_buserror_is_event_accrued(struct metal_buserror *beu, + metal_buserror_event_t events); + +/*! + * @brief Clear the given event from the accrued register + * + * @param beu The bus error unit handle + * @param event The event to clear + * @return 0 upon success + */ +int metal_buserror_clear_event_accrued(struct metal_buserror *beu, + metal_buserror_event_t events); + +/*! + * @brief get the platform-level interrupt parent of the bus error unit + * + * @param beu The bus error unit handle + * @return A pointer to the interrupt parent + */ +struct metal_interrupt * +metal_buserror_get_platform_interrupt_parent(struct metal_buserror *beu); + +/*! + * @brief Get the platform-level interrupt id for the bus error unit interrupt + * + * @param beu The bus error unit handle + * @return The interrupt id + */ +int metal_buserror_get_platform_interrupt_id(struct metal_buserror *beu); + +/*! + * @brief Get the hart-local interrupt id for the bus error unit interrupt + * + * @param beu The bus error unit handle + * @return The interrupt id + */ +int metal_buserror_get_local_interrupt_id(struct metal_buserror *beu); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_ccache0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_ccache0.h index 2153cf384..13a47c0b9 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_ccache0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_ccache0.h @@ -1,23 +1,140 @@ -/* Copyright 2019 SiFive, Inc */ +/* Copyright 2020 SiFive, Inc */ /* SPDX-License-Identifier: Apache-2.0 */ #ifndef METAL__DRIVERS__SIFIVE_CCACHE0_H #define METAL__DRIVERS__SIFIVE_CCACHE0_H -#include <metal/cache.h> -#include <metal/compiler.h> +/*! + * @file sifive_ccache0.h + * + * @brief API for configuring the SiFive L2 cache controller + */ -struct __metal_driver_vtable_sifive_ccache0 { - struct __metal_cache_vtable cache; -}; +#include <metal/interrupt.h> +#include <stdint.h> -struct __metal_driver_sifive_ccache0; +/*! @brief Cache configuration data */ +typedef struct { + uint32_t num_bank; + uint32_t num_ways; + uint32_t num_sets; + uint32_t block_size; +} sifive_ccache0_config; -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_ccache0) +/*! @brief Set of values for ECC error type */ +typedef enum { + SIFIVE_CCACHE0_DATA = 0, + SIFIVE_CCACHE0_DIR = 1, +} sifive_ccache0_ecc_errtype_t; -struct __metal_driver_sifive_ccache0 { - struct metal_cache cache; -}; +/*! @brief Initialize cache controller, enables all available + * cache-ways. + * Note: If LIM is in use, corresponding cache ways are not enabled. + * @param None. + * @return 0 If no error.*/ +int sifive_ccache0_init(void); -#endif +/*! @brief Get cache configuration data. + * @param config User specified data buffer. + * @return None.*/ +void sifive_ccache0_get_config(sifive_ccache0_config *config); + +/*! @brief Get currently active cache ways. + * @param None. + * @return Number of cache ways enabled.*/ +uint32_t sifive_ccache0_get_enabled_ways(void); + +/*! @brief Enable specified cache ways. + * @param ways Number of ways to be enabled. + * @return 0 If no error.*/ +int sifive_ccache0_set_enabled_ways(uint32_t ways); + +/*! @brief Inject ECC error into data or meta-data. + * @param bitindex Bit index to be corrupted on next cache operation. + * @param type ECC error target location. + * @return None.*/ +void sifive_ccache0_inject_ecc_error(uint32_t bitindex, + sifive_ccache0_ecc_errtype_t type); + +/*! @brief Flush out entire cache block containing given address. + * @param flush_addr Address for the cache block to be flushed. + * @return None.*/ +void sifive_ccache0_flush(uintptr_t flush_addr); + +/*! @brief Get most recently ECC corrected address. + * @param type ECC error target location. + * @return Last corrected ECC address.*/ +uintptr_t sifive_ccache0_get_ecc_fix_addr(sifive_ccache0_ecc_errtype_t type); + +/*! @brief Get number of times ECC errors were corrected. + * Clears related ECC interrupt signals. + * @param type ECC error target location. + * @return Corrected ECC error count.*/ +uint32_t sifive_ccache0_get_ecc_fix_count(sifive_ccache0_ecc_errtype_t type); + +/*! @brief Get address location of most recent uncorrected ECC error. + * @param type ECC error target location. + * @return Last uncorrected ECC address.*/ +uintptr_t sifive_ccache0_get_ecc_fail_addr(sifive_ccache0_ecc_errtype_t type); + +/*! @brief Get number of times ECC errors were not corrected. + * Clears related ECC interrupt signals. + * @param type ECC error target location. + * @return Uncorrected ECC error count.*/ +uint32_t sifive_ccache0_get_ecc_fail_count(sifive_ccache0_ecc_errtype_t type); + +/*! @brief Get currently active way enable mask value for the given master ID. + * @param master_id Cache controller master ID. + * @return Way enable mask. */ +uint64_t sifive_ccache0_get_way_mask(uint32_t master_id); +/*! @brief Set way enable mask for the given master ID. + * @param master_id Cache controller master ID. + * @param waymask Specify ways to be enabled. + * @return 0 If no error.*/ +int sifive_ccache0_set_way_mask(uint32_t master_id, uint64_t waymask); + +/*! @brief Select cache performance events to be counted. + * @param counter Cache performance monitor counter index. + * @param mask Event selection mask. + * @return None.*/ +void sifive_ccache0_set_pmevent_selector(uint32_t counter, uint64_t mask); + +/*! @brief Get currently set events for the given counter index. + * @param counter Cache performance monitor counter index. + * @return Event selection mask.*/ +uint64_t sifive_ccache0_get_pmevent_selector(uint32_t counter); + +/*! @brief Clears specified cache performance counter. + * @param counter Cache performance monitor counter index. + * @return None.*/ +void sifive_ccache0_clr_pmevent_counter(uint32_t counter); + +/*! @brief Reads specified cache performance counter. + * @param counter Cache performance monitor counter index. + * @return Counter value.*/ +uint64_t sifive_ccache0_get_pmevent_counter(uint32_t counter); + +/*! @brief Select cache clients to be excluded from performance monitoring. + * @param mask Client disable mask. + * @return None.*/ +void sifive_ccache0_set_client_filter(uint64_t mask); + +/*! @brief Get currently set cache client disable mask. + * @param None. + * @return Client disable mask.*/ +uint64_t sifive_ccache0_get_client_filter(void); + +/*! @brief Get interrupt IDs for the cache controller. + * @param src Interrupt trigger source index. + * @return Interrupt id.*/ +int sifive_ccache0_get_interrupt_id(uint32_t src); + +/*! @brief Get interrupt controller of the cache. + * The interrupt controller must be initialized before any interrupts can be + * registered or enabled with it. + * @param None. + * @return Handle for the interrupt controller.*/ +struct metal_interrupt *sifive_ccache0_interrupt_controller(void); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_clic0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_clic0.h index 7fef38d19..b8ff82271 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_clic0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_clic0.h @@ -7,21 +7,21 @@ #include <metal/compiler.h> #include <metal/drivers/riscv_cpu.h> -#define METAL_CLIC_MAX_NMBITS 2 -#define METAL_CLIC_MAX_NLBITS 8 -#define METAL_CLIC_MAX_NVBITS 1 +#define METAL_CLIC_MAX_NMBITS 2 +#define METAL_CLIC_MAX_NLBITS 8 +#define METAL_CLIC_MAX_NVBITS 1 -#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_MMODE 0x00 -#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_SMODE1 0x20 -#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_SMODE2 0x40 -#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_MASK 0x60 -#define METAL_SIFIVE_CLIC0_CLICCFG_NLBITS_MASK 0x1E -#define METAL_SIFIVE_CLIC0_CLICCFG_NVBIT_MASK 0x01 +#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_MMODE 0x00 +#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_SMODE1 0x20 +#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_SMODE2 0x40 +#define METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_MASK 0x60 +#define METAL_SIFIVE_CLIC0_CLICCFG_NLBITS_MASK 0x1E +#define METAL_SIFIVE_CLIC0_CLICCFG_NVBIT_MASK 0x01 -#define METAL_CLIC_ICTRL_SMODE1_MASK 0x7F /* b8 set imply M-mode */ -#define METAL_CLIC_ICTRL_SMODE2_MASK 0x3F /* b8 set M-mode, b7 clear U-mode */ +#define METAL_CLIC_ICTRL_SMODE1_MASK 0x7F /* b8 set imply M-mode */ +#define METAL_CLIC_ICTRL_SMODE2_MASK 0x3F /* b8 set M-mode, b7 clear U-mode */ -#define METAL_MAX_INTERRUPT_LEVEL ((1 << METAL_CLIC_MAX_NLBITS) - 1) +#define METAL_MAX_INTERRUPT_LEVEL ((1 << METAL_CLIC_MAX_NLBITS) - 1) struct __metal_driver_vtable_sifive_clic0 { struct metal_interrupt_vtable clic_vtable; @@ -34,10 +34,15 @@ __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_clic0) struct __metal_driver_sifive_clic0 { struct metal_interrupt controller; int init_done; - int pad[14]; - metal_interrupt_vector_handler_t metal_mtvt_table[__METAL_CLIC_SUBINTERRUPTS]; + struct { + } __attribute__((aligned(64))); + metal_interrupt_vector_handler_t + metal_mtvt_table[__METAL_CLIC_SUBINTERRUPTS]; __metal_interrupt_data metal_exint_table[__METAL_CLIC_SUBINTERRUPTS]; }; #undef __METAL_MACHINE_MACROS +int __metal_driver_sifive_clic0_command_request( + struct metal_interrupt *controller, int command, void *data); + #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_hfrosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_hfrosc.h index d311f0cf2..d60d3a3bd 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_hfrosc.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_hfrosc.h @@ -4,9 +4,9 @@ #ifndef METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H #define METAL__DRIVERS__SIFIVE_FE310_G000_HFROSC_H -#include <metal/drivers/sifive_fe310-g000_prci.h> -#include <metal/compiler.h> #include <metal/clock.h> +#include <metal/compiler.h> +#include <metal/drivers/sifive_fe310-g000_prci.h> #include <metal/io.h> struct __metal_driver_vtable_sifive_fe310_g000_hfrosc { diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_lfrosc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_lfrosc.h index 64985c6bb..2650584ad 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_lfrosc.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_lfrosc.h @@ -4,8 +4,8 @@ #ifndef METAL__DRIVERS__SIFIVE_FE310_G000_LFROSC_H #define METAL__DRIVERS__SIFIVE_FE310_G000_LFROSC_H -#include <metal/compiler.h> #include <metal/clock.h> +#include <metal/compiler.h> #include <metal/io.h> struct __metal_driver_vtable_sifive_fe310_g000_lfrosc { diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_prci.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_prci.h index 387130be5..4fca30167 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_prci.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fe310-g000_prci.h @@ -10,8 +10,10 @@ struct __metal_driver_sifive_fe310_g000_prci; struct __metal_driver_vtable_sifive_fe310_g000_prci { - long (*get_reg)(const struct __metal_driver_sifive_fe310_g000_prci *, long offset); - long (*set_reg)(const struct __metal_driver_sifive_fe310_g000_prci *, long offset, long value); + long (*get_reg)(const struct __metal_driver_sifive_fe310_g000_prci *, + long offset); + long (*set_reg)(const struct __metal_driver_sifive_fe310_g000_prci *, + long offset, long value); }; __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_prci) @@ -21,4 +23,3 @@ struct __metal_driver_sifive_fe310_g000_prci { }; #endif - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fu540-c000_l2.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fu540-c000_l2.h deleted file mode 100644 index bb98f169e..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_fu540-c000_l2.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#ifndef METAL__DRIVERS__SIFIVE_FU540_C000_L2_H -#define METAL__DRIVERS__SIFIVE_FU540_C000_L2_H - -#include <metal/cache.h> -#include <metal/compiler.h> - -struct __metal_driver_vtable_sifive_fu540_c000_l2 { - struct __metal_cache_vtable cache; -}; - -struct __metal_driver_sifive_fu540_c000_l2; - -__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_fu540_c000_l2) - -struct __metal_driver_sifive_fu540_c000_l2 { - struct metal_cache cache; -}; - -#endif - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-buttons.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-buttons.h index a0caeaba8..7227eee02 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-buttons.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-buttons.h @@ -4,12 +4,12 @@ #ifndef METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H #define METAL__DRIVERS__SIFIVE_GPIO_BUTTONS_H -#include <string.h> #include <metal/button.h> #include <metal/compiler.h> +#include <string.h> struct __metal_driver_vtable_sifive_button { - struct metal_button_vtable button_vtable; + struct metal_button_vtable button_vtable; }; __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_button) diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-leds.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-leds.h index a8dacf116..abfca01c2 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-leds.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-leds.h @@ -4,12 +4,12 @@ #ifndef METAL__DRIVERS__SIFIVE_GPIO_LEDS_H #define METAL__DRIVERS__SIFIVE_GPIO_LEDS_H +#include <metal/compiler.h> #include <metal/drivers/sifive_gpio0.h> #include <metal/led.h> -#include <metal/compiler.h> struct __metal_driver_vtable_sifive_led { - struct metal_led_vtable led_vtable; + struct metal_led_vtable led_vtable; }; __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_led) diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-switches.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-switches.h index c9c7839e9..be55a0446 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-switches.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio-switches.h @@ -4,12 +4,12 @@ #ifndef METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H #define METAL__DRIVERS__SIFIVE_GPIO_SWITCHES_H +#include <metal/compiler.h> #include <metal/drivers/sifive_gpio0.h> #include <metal/switch.h> -#include <metal/compiler.h> struct __metal_driver_vtable_sifive_switch { - struct metal_switch_vtable switch_vtable; + struct metal_switch_vtable switch_vtable; }; __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_switch) diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio0.h index cc56dc722..50314222d 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_gpio0.h @@ -11,7 +11,7 @@ struct __metal_driver_vtable_sifive_gpio0 { const struct __metal_gpio_vtable gpio; }; -//struct __metal_driver_sifive_gpio0; +// struct __metal_driver_sifive_gpio0; __METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_gpio0) diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_i2c0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_i2c0.h new file mode 100644 index 000000000..8fbbe21e1 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_i2c0.h @@ -0,0 +1,24 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_I2C0_H +#define METAL__DRIVERS__SIFIVE_I2C0_H + +#include <metal/clock.h> +#include <metal/i2c.h> + +struct __metal_driver_vtable_sifive_i2c0 { + const struct metal_i2c_vtable i2c; +}; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_i2c0) + +struct __metal_driver_sifive_i2c0 { + struct metal_i2c i2c; + unsigned int init_done; + unsigned int baud_rate; + metal_clock_callback pre_rate_change_callback; + metal_clock_callback post_rate_change_callback; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_l2pf0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_l2pf0.h new file mode 100644 index 000000000..63c8e6536 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_l2pf0.h @@ -0,0 +1,78 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_L2PF0_H +#define METAL__DRIVERS__SIFIVE_L2PF0_H + +/*! + * @file sifive_l2pf0.h + * + * @brief API for configuring the SiFive L2 prefetcher. + */ + +#include <stdint.h> + +/*! @brief L2 prefetcher configuration */ +typedef struct { + /* Enable L2 hardware prefetcher */ + uint8_t HwPrefetchEnable; + + /* Only works when CrossPageEn === 0. + Cross Page optimization disable: + 0 -> Entry goes into Pause state while crossing Page boundary. + Next time when the demand miss happens on the same page, it doesn’t need + to train again. 1 -> The entry is invalidated in case of a cross page. */ + uint8_t CrossPageOptmDisable; + + /* Enable prefetches to cross pages */ + uint8_t CrossPageEn; + + /* Age-out mechanism enable */ + uint8_t AgeOutEn; + + uint32_t PrefetchDistance; + + uint32_t MaxAllowedDistance; + + /* Linear to exponential threshold */ + uint32_t LinToExpThreshold; + + /* No. of non-matching loads to edge out an entry */ + uint32_t NumLdsToAgeOut; + + /* Threshold no. of Fullness (L2 MSHRs used/ total available) to stop + * sending hits */ + uint32_t QFullnessThreshold; + + /* Threshold no. of CacheHits for evicting SPF entry */ + uint32_t HitCacheThreshold; + + /* Threshold no. of MSHR hits for increasing SPF distance */ + uint32_t hitMSHRThreshold; + + /* Size of the comparison window for address matching */ + uint32_t Window; + +} sifive_l2pf0_config; + +/*! @brief Enable L2 hardware prefetcher unit. + * @param None. + * @return None.*/ +void sifive_l2pf0_enable(void); + +/*! @brief Disable L2 hardware prefetcher unit. + * @param None. + * @return None.*/ +void sifive_l2pf0_disable(void); + +/*! @brief Get currently active L2 prefetcher configuration. + * @param config Pointer to user specified configuration structure. + * @return None.*/ +void sifive_l2pf0_get_config(sifive_l2pf0_config *config); + +/*! @brief Enables fine grain access to L2 prefetcher configuration. + * @param config Pointer to user structure with values to be set. + * @return None.*/ +void sifive_l2pf0_set_config(sifive_l2pf0_config *config); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_local-external-interrupts0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_local-external-interrupts0.h index aa8d63078..320ab10d2 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_local-external-interrupts0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_local-external-interrupts0.h @@ -18,5 +18,4 @@ struct __metal_driver_sifive_local_external_interrupts0 { int init_done; }; - #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_pwm0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_pwm0.h new file mode 100644 index 000000000..caa774401 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_pwm0.h @@ -0,0 +1,29 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_PWM0_H +#define METAL__DRIVERS__SIFIVE_PWM0_H + +#include <metal/clock.h> +#include <metal/pwm.h> + +struct __metal_driver_vtable_sifive_pwm0 { + const struct metal_pwm_vtable pwm; +}; + +/* Max possible PWM channel count */ +#define METAL_MAX_PWM_CHANNELS 16 + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_pwm0) + +struct __metal_driver_sifive_pwm0 { + struct metal_pwm pwm; + unsigned int max_count; + unsigned int count_val; + unsigned int freq; + unsigned int duty[METAL_MAX_PWM_CHANNELS]; + metal_clock_callback pre_rate_change_callback; + metal_clock_callback post_rate_change_callback; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_rtc0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_rtc0.h index b0ed143bf..a35ab9a09 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_rtc0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_rtc0.h @@ -4,8 +4,8 @@ #ifndef METAL__DRIVERS__SIFIVE_RTC0_H #define METAL__DRIVERS__SIFIVE_RTC0_H -#include <metal/io.h> #include <metal/compiler.h> +#include <metal/io.h> #include <metal/clock.h> #include <metal/interrupt.h> @@ -24,4 +24,3 @@ struct __metal_driver_sifive_rtc0 { }; #endif - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_simuart0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_simuart0.h new file mode 100644 index 000000000..f6b739143 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_simuart0.h @@ -0,0 +1,29 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__SIFIVE_SIMUART0_H +#define METAL__DRIVERS__SIFIVE_SIMUART0_H + +#include <metal/clock.h> +#include <metal/compiler.h> +#include <metal/drivers/riscv_plic0.h> +#include <metal/drivers/sifive_gpio0.h> +#include <metal/io.h> +#include <metal/uart.h> + +struct __metal_driver_vtable_sifive_simuart0 { + const struct metal_uart_vtable uart; +}; + +struct __metal_driver_sifive_simuart0; + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_sifive_simuart0) + +struct __metal_driver_sifive_simuart0 { + struct metal_uart uart; + unsigned long baud_rate; + metal_clock_callback pre_rate_change_callback; + metal_clock_callback post_rate_change_callback; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_spi0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_spi0.h index c4a6848e7..73527944b 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_spi0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_spi0.h @@ -4,9 +4,9 @@ #ifndef METAL__DRIVERS__SIFIVE_SPI0_H #define METAL__DRIVERS__SIFIVE_SPI0_H -#include <metal/drivers/sifive_gpio0.h> #include <metal/clock.h> #include <metal/compiler.h> +#include <metal/drivers/sifive_gpio0.h> #include <metal/io.h> #include <metal/spi.h> diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_test0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_test0.h index e87db2c83..debd3fb9d 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_test0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_test0.h @@ -17,5 +17,4 @@ struct __metal_driver_sifive_test0 { struct __metal_shutdown shutdown; }; - #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_uart0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_uart0.h index 5d585e783..2b38e4631 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_uart0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_uart0.h @@ -4,12 +4,12 @@ #ifndef METAL__DRIVERS__SIFIVE_UART0_H #define METAL__DRIVERS__SIFIVE_UART0_H -#include <metal/drivers/sifive_gpio0.h> -#include <metal/drivers/riscv_plic0.h> #include <metal/clock.h> +#include <metal/compiler.h> +#include <metal/drivers/riscv_plic0.h> +#include <metal/drivers/sifive_gpio0.h> #include <metal/io.h> #include <metal/uart.h> -#include <metal/compiler.h> struct __metal_driver_vtable_sifive_uart0 { const struct metal_uart_vtable uart; @@ -26,5 +26,4 @@ struct __metal_driver_sifive_uart0 { metal_clock_callback post_rate_change_callback; }; - #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_wdog0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_wdog0.h index 12b143d58..bb3424584 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_wdog0.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/sifive_wdog0.h @@ -4,12 +4,12 @@ #ifndef METAL__DRIVERS__SIFIVE_WDOG0_H #define METAL__DRIVERS__SIFIVE_WDOG0_H -#include <metal/io.h> #include <metal/compiler.h> +#include <metal/io.h> -#include <metal/watchdog.h> #include <metal/clock.h> #include <metal/interrupt.h> +#include <metal/watchdog.h> struct __metal_driver_vtable_sifive_wdog0 { const struct metal_watchdog_vtable watchdog; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/ucb_htif0.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/ucb_htif0.h new file mode 100644 index 000000000..210d0819b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/drivers/ucb_htif0.h @@ -0,0 +1,48 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__DRIVERS__UCB_HTIF0_H +#define METAL__DRIVERS__UCB_HTIF0_H + +#include <metal/compiler.h> +#include <metal/shutdown.h> +#include <metal/uart.h> + +struct __metal_driver_vtable_ucb_htif0_shutdown { + const struct __metal_shutdown_vtable shutdown; +}; + +struct __metal_driver_vtable_ucb_htif0_uart { + const struct metal_uart_vtable uart; +}; + +struct __metal_driver_ucb_htif0; + +void __metal_driver_ucb_htif0_exit(const struct __metal_shutdown *test, + int code) __attribute__((noreturn)); + +void __metal_driver_ucb_htif0_init(struct metal_uart *uart, int baud_rate); +int __metal_driver_ucb_htif0_putc(struct metal_uart *uart, int c); +int __metal_driver_ucb_htif0_getc(struct metal_uart *uart, int *c); +int __metal_driver_ucb_htif0_get_baud_rate(struct metal_uart *guart); +int __metal_driver_ucb_htif0_set_baud_rate(struct metal_uart *guart, + int baud_rate); +struct metal_interrupt * +__metal_driver_ucb_htif0_interrupt_controller(struct metal_uart *uart); +int __metal_driver_ucb_htif0_get_interrupt_id(struct metal_uart *uart); + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_ucb_htif0_shutdown) + +__METAL_DECLARE_VTABLE(__metal_driver_vtable_ucb_htif0_uart) + +struct __metal_driver_ucb_htif0_shutdown { + struct __metal_shutdown shutdown; + const struct __metal_driver_vtable_ucb_htif0_shutdown *vtable; +}; + +struct __metal_driver_ucb_htif0_uart { + struct metal_uart uart; + const struct __metal_driver_vtable_ucb_htif0_uart *vtable; +}; + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/gpio.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/gpio.h index 7645494ff..df9adb451 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/gpio.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/gpio.h @@ -28,25 +28,25 @@ struct __metal_gpio_vtable { int (*disable_io)(struct metal_gpio *, long pins); int (*config_int)(struct metal_gpio *, long pins, int intr_type); int (*clear_int)(struct metal_gpio *, long pins, int intr_type); - struct metal_interrupt* (*interrupt_controller)(struct metal_gpio *gpio); + struct metal_interrupt *(*interrupt_controller)(struct metal_gpio *gpio); int (*get_interrupt_id)(struct metal_gpio *gpio, int pin); }; -#define METAL_GPIO_INT_DISABLE 0 -#define METAL_GPIO_INT_RISING 1 -#define METAL_GPIO_INT_FALLING 2 -#define METAL_GPIO_INT_BOTH_EDGE 3 -#define METAL_GPIO_INT_LOW 4 -#define METAL_GPIO_INT_HIGH 5 -#define METAL_GPIO_INT_BOTH_LEVEL 6 -#define METAL_GPIO_INT_MAX 7 +#define METAL_GPIO_INT_DISABLE 0 +#define METAL_GPIO_INT_RISING 1 +#define METAL_GPIO_INT_FALLING 2 +#define METAL_GPIO_INT_BOTH_EDGE 3 +#define METAL_GPIO_INT_LOW 4 +#define METAL_GPIO_INT_HIGH 5 +#define METAL_GPIO_INT_BOTH_LEVEL 6 +#define METAL_GPIO_INT_MAX 7 /*! * @struct metal_gpio * @brief The handle for a GPIO interface */ struct metal_gpio { - const struct __metal_gpio_vtable *vtable; + const struct __metal_gpio_vtable *vtable; }; /*! @@ -63,8 +63,8 @@ struct metal_gpio *metal_gpio_get_device(unsigned int device_num); * @return 0 if the input is successfully enabled */ __inline__ int metal_gpio_enable_input(struct metal_gpio *gpio, int pin) { - if(!gpio) { - return 1; + if (!gpio) { + return 1; } return gpio->vtable->enable_input(gpio, (1 << pin)); @@ -77,8 +77,8 @@ __inline__ int metal_gpio_enable_input(struct metal_gpio *gpio, int pin) { * @return 0 if the input is successfully disabled */ __inline__ int metal_gpio_disable_input(struct metal_gpio *gpio, int pin) { - if(!gpio) { - return 1; + if (!gpio) { + return 1; } return gpio->vtable->disable_input(gpio, (1 << pin)); @@ -91,8 +91,8 @@ __inline__ int metal_gpio_disable_input(struct metal_gpio *gpio, int pin) { * @return 0 if the output is successfully enabled */ __inline__ int metal_gpio_enable_output(struct metal_gpio *gpio, int pin) { - if(!gpio) { - return 1; + if (!gpio) { + return 1; } return gpio->vtable->enable_output(gpio, (1 << pin)); @@ -105,8 +105,8 @@ __inline__ int metal_gpio_enable_output(struct metal_gpio *gpio, int pin) { * @return 0 if the output is successfully disabled */ __inline__ int metal_gpio_disable_output(struct metal_gpio *gpio, int pin) { - if(!gpio) { - return 1; + if (!gpio) { + return 1; } return gpio->vtable->disable_output(gpio, (1 << pin)); @@ -120,14 +120,14 @@ __inline__ int metal_gpio_disable_output(struct metal_gpio *gpio, int pin) { * @return 0 if the output is successfully set */ __inline__ int metal_gpio_set_pin(struct metal_gpio *gpio, int pin, int value) { - if(!gpio) { - return 1; + if (!gpio) { + return 1; } - if(value == 0) { - return gpio->vtable->output_clear(gpio, (1 << pin)); + if (value == 0) { + return gpio->vtable->output_clear(gpio, (1 << pin)); } else { - return gpio->vtable->output_set(gpio, (1 << pin)); + return gpio->vtable->output_set(gpio, (1 << pin)); } } @@ -138,16 +138,16 @@ __inline__ int metal_gpio_set_pin(struct metal_gpio *gpio, int pin, int value) { * @return The value of the GPIO pin */ __inline__ int metal_gpio_get_input_pin(struct metal_gpio *gpio, int pin) { - if(!gpio) { - return 0; + if (!gpio) { + return 0; } long value = gpio->vtable->input(gpio); - if(value & (1 << pin)) { - return 1; + if (value & (1 << pin)) { + return 1; } else { - return 0; + return 0; } } @@ -158,16 +158,16 @@ __inline__ int metal_gpio_get_input_pin(struct metal_gpio *gpio, int pin) { * @return The value of the GPIO pin */ __inline__ int metal_gpio_get_output_pin(struct metal_gpio *gpio, int pin) { - if(!gpio) { - return 0; + if (!gpio) { + return 0; } long value = gpio->vtable->output(gpio); - if(value & (1 << pin)) { - return 1; + if (value & (1 << pin)) { + return 1; } else { - return 0; + return 0; } } @@ -178,8 +178,8 @@ __inline__ int metal_gpio_get_output_pin(struct metal_gpio *gpio, int pin) { * @return 0 if the pin is successfully cleared */ __inline__ int metal_gpio_clear_pin(struct metal_gpio *gpio, int pin) { - if(!gpio) { - return 1; + if (!gpio) { + return 1; } return gpio->vtable->output_clear(gpio, (1 << pin)); @@ -192,8 +192,8 @@ __inline__ int metal_gpio_clear_pin(struct metal_gpio *gpio, int pin) { * @return 0 if the pin is successfully toggled */ __inline__ int metal_gpio_toggle_pin(struct metal_gpio *gpio, int pin) { - if(!gpio) { - return 1; + if (!gpio) { + return 1; } return gpio->vtable->output_toggle(gpio, (1 << pin)); @@ -206,9 +206,10 @@ __inline__ int metal_gpio_toggle_pin(struct metal_gpio *gpio, int pin) { * @param io_function The IO function to set * @return 0 if the pinmux is successfully set */ -__inline__ int metal_gpio_enable_pinmux(struct metal_gpio *gpio, int pin, int io_function) { - if(!gpio) { - return 1; +__inline__ int metal_gpio_enable_pinmux(struct metal_gpio *gpio, int pin, + int io_function) { + if (!gpio) { + return 1; } return gpio->vtable->enable_io(gpio, (1 << pin), (io_function << pin)); @@ -221,8 +222,8 @@ __inline__ int metal_gpio_enable_pinmux(struct metal_gpio *gpio, int pin, int io * @return 0 if the pinmux is successfully set */ __inline__ int metal_gpio_disable_pinmux(struct metal_gpio *gpio, int pin) { - if(!gpio) { - return 1; + if (!gpio) { + return 1; } return gpio->vtable->disable_io(gpio, (1 << pin)); @@ -235,9 +236,10 @@ __inline__ int metal_gpio_disable_pinmux(struct metal_gpio *gpio, int pin) { * @param intr_type The interrupt type * @return 0 if the interrupt mode is setup properly */ -__inline__ int metal_gpio_config_interrupt(struct metal_gpio *gpio, int pin, int intr_type) { - if(!gpio) { - return 1; +__inline__ int metal_gpio_config_interrupt(struct metal_gpio *gpio, int pin, + int intr_type) { + if (!gpio) { + return 1; } return gpio->vtable->config_int(gpio, (1 << pin), intr_type); @@ -250,9 +252,10 @@ __inline__ int metal_gpio_config_interrupt(struct metal_gpio *gpio, int pin, int * @param intr_type The interrupt type to be clear * @return 0 if the interrupt is cleared */ -__inline__ int metal_gpio_clear_interrupt(struct metal_gpio *gpio, int pin, int intr_type) { - if(!gpio) { - return 1; +__inline__ int metal_gpio_clear_interrupt(struct metal_gpio *gpio, int pin, + int intr_type) { + if (!gpio) { + return 1; } return gpio->vtable->clear_int(gpio, (1 << pin), intr_type); @@ -265,8 +268,8 @@ __inline__ int metal_gpio_clear_interrupt(struct metal_gpio *gpio, int pin, int * @return A pointer to the interrupt controller responsible for handling * gpio interrupts. */ -__inline__ struct metal_interrupt* - metal_gpio_interrupt_controller(struct metal_gpio *gpio) { +__inline__ struct metal_interrupt * +metal_gpio_interrupt_controller(struct metal_gpio *gpio) { return gpio->vtable->interrupt_controller(gpio); } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/hpm.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/hpm.h new file mode 100644 index 000000000..290f7ec3f --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/hpm.h @@ -0,0 +1,146 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__HPM_H +#define METAL__HPM_H + +#include <metal/cpu.h> + +/*! @brief Macros for valid Event IDs */ +#define METAL_HPM_EVENTID_8 (1UL << 8) +#define METAL_HPM_EVENTID_9 (1UL << 9) +#define METAL_HPM_EVENTID_10 (1UL << 10) +#define METAL_HPM_EVENTID_11 (1UL << 11) +#define METAL_HPM_EVENTID_12 (1UL << 12) +#define METAL_HPM_EVENTID_13 (1UL << 13) +#define METAL_HPM_EVENTID_14 (1UL << 14) +#define METAL_HPM_EVENTID_15 (1UL << 15) +#define METAL_HPM_EVENTID_16 (1UL << 16) +#define METAL_HPM_EVENTID_17 (1UL << 17) +#define METAL_HPM_EVENTID_18 (1UL << 18) +#define METAL_HPM_EVENTID_19 (1UL << 19) +#define METAL_HPM_EVENTID_20 (1UL << 20) +#define METAL_HPM_EVENTID_21 (1UL << 21) +#define METAL_HPM_EVENTID_22 (1UL << 22) +#define METAL_HPM_EVENTID_23 (1UL << 23) +#define METAL_HPM_EVENTID_24 (1UL << 24) +#define METAL_HPM_EVENTID_25 (1UL << 25) +#define METAL_HPM_EVENTID_26 (1UL << 26) +#define METAL_HPM_EVENTID_27 (1UL << 27) +#define METAL_HPM_EVENTID_28 (1UL << 28) +#define METAL_HPM_EVENTID_29 (1UL << 29) +#define METAL_HPM_EVENTID_30 (1UL << 30) +#define METAL_HPM_EVENTID_31 (1UL << 31) + +/*! @brief Macros for valid Event Class */ +#define METAL_HPM_EVENTCLASS_0 (0UL) +#define METAL_HPM_EVENTCLASS_1 (1UL) +#define METAL_HPM_EVENTCLASS_2 (2UL) +#define METAL_HPM_EVENTCLASS_3 (3UL) +#define METAL_HPM_EVENTCLASS_4 (4UL) +#define METAL_HPM_EVENTCLASS_5 (5UL) +#define METAL_HPM_EVENTCLASS_6 (6UL) +#define METAL_HPM_EVENTCLASS_7 (7UL) +#define METAL_HPM_EVENTCLASS_8 (8UL) + +/*! @brief Enums for available HPM counters */ +typedef enum { + METAL_HPM_CYCLE = 0, + METAL_HPM_TIME = 1, + METAL_HPM_INSTRET = 2, + METAL_HPM_COUNTER_3 = 3, + METAL_HPM_COUNTER_4 = 4, + METAL_HPM_COUNTER_5 = 5, + METAL_HPM_COUNTER_6 = 6, + METAL_HPM_COUNTER_7 = 7, + METAL_HPM_COUNTER_8 = 8, + METAL_HPM_COUNTER_9 = 9, + METAL_HPM_COUNTER_10 = 10, + METAL_HPM_COUNTER_11 = 11, + METAL_HPM_COUNTER_12 = 12, + METAL_HPM_COUNTER_13 = 13, + METAL_HPM_COUNTER_14 = 14, + METAL_HPM_COUNTER_15 = 15, + METAL_HPM_COUNTER_16 = 16, + METAL_HPM_COUNTER_17 = 17, + METAL_HPM_COUNTER_18 = 18, + METAL_HPM_COUNTER_19 = 19, + METAL_HPM_COUNTER_20 = 20, + METAL_HPM_COUNTER_21 = 21, + METAL_HPM_COUNTER_22 = 22, + METAL_HPM_COUNTER_23 = 23, + METAL_HPM_COUNTER_24 = 24, + METAL_HPM_COUNTER_25 = 25, + METAL_HPM_COUNTER_26 = 26, + METAL_HPM_COUNTER_27 = 27, + METAL_HPM_COUNTER_28 = 28, + METAL_HPM_COUNTER_29 = 29, + METAL_HPM_COUNTER_30 = 30, + METAL_HPM_COUNTER_31 = 31 +} metal_hpm_counter; + +/*! @brief Initialize hardware performance monitor counters. + * @param cpu The CPU device handle. + * @return 0 If no error.*/ +int metal_hpm_init(struct metal_cpu *cpu); + +/*! @brief Disables hardware performance monitor counters. + * Note - Disabled HPM counters may reduce power consumption. + * @param cpu The CPU device handle. + * @return 0 If no error.*/ +int metal_hpm_disable(struct metal_cpu *cpu); + +/*! @brief Set events which will cause the specified counter to increment. + * Counter will start incrementing from the moment events are set. + * @param cpu The CPU device handle. + * @param counter Hardware counter to be incremented by selected events. + * @param bitmask Bit-mask to select events for a particular counter, + * refer core reference manual for selection of events. + * Event bit mask is partitioned as follows: + * [XLEN-1:8] - Event selection mask [7:0] - Event class + * @return 0 If no error.*/ +int metal_hpm_set_event(struct metal_cpu *cpu, metal_hpm_counter counter, + unsigned int bitmask); + +/*! @brief Get events selection mask set for specified counter. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return Event selection bit mask. refer core reference manual for details.*/ +unsigned int metal_hpm_get_event(struct metal_cpu *cpu, + metal_hpm_counter counter); + +/*! @brief Clear event selector bits as per specified bit-mask. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return 0 If no error.*/ +int metal_hpm_clr_event(struct metal_cpu *cpu, metal_hpm_counter counter, + unsigned int bitmask); + +/*! @brief Enable counter access to next lower privilege mode. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return 0 If no error.*/ +int metal_hpm_enable_access(struct metal_cpu *cpu, metal_hpm_counter counter); + +/*! @brief Disable counter access to next lower privilege mode. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return 0 If no error.*/ +int metal_hpm_disable_access(struct metal_cpu *cpu, metal_hpm_counter counter); + +/*! @brief Reads current value of specified hardware counter. + * Note: 'mtime' register is memory mapped into CLINT block. + * Use CLINT APIs to access this register. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return Current value of hardware counter on success, 0 on failure.*/ +unsigned long long metal_hpm_read_counter(struct metal_cpu *cpu, + metal_hpm_counter counter); + +/*! @brief Clears off specified counter. + * @param cpu The CPU device handle. + * @param counter Hardware counter. + * @return 0 If no error.*/ +int metal_hpm_clear_counter(struct metal_cpu *cpu, metal_hpm_counter counter); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/i2c.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/i2c.h new file mode 100644 index 000000000..baf62e5d6 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/i2c.h @@ -0,0 +1,112 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__I2C_H +#define METAL__I2C_H + +/*! @brief Enums to enable/disable stop condition. */ +typedef enum { + METAL_I2C_STOP_DISABLE = 0, + METAL_I2C_STOP_ENABLE = 1 +} metal_i2c_stop_bit_t; + +/*! @brief Enums to set up I2C device modes. */ +typedef enum { METAL_I2C_SLAVE = 0, METAL_I2C_MASTER = 1 } metal_i2c_mode_t; + +struct metal_i2c; + +struct metal_i2c_vtable { + void (*init)(struct metal_i2c *i2c, unsigned int baud_rate, + metal_i2c_mode_t mode); + int (*write)(struct metal_i2c *i2c, unsigned int addr, unsigned int len, + unsigned char buf[], metal_i2c_stop_bit_t stop_bit); + int (*read)(struct metal_i2c *i2c, unsigned int addr, unsigned int len, + unsigned char buf[], metal_i2c_stop_bit_t stop_bit); + int (*transfer)(struct metal_i2c *i2c, unsigned int addr, + unsigned char txbuf[], unsigned int txlen, + unsigned char rxbuf[], unsigned int rxlen); + int (*get_baud_rate)(struct metal_i2c *i2c); + int (*set_baud_rate)(struct metal_i2c *i2c, unsigned int baud_rate); +}; + +/*! @brief A handle for a I2C device. */ +struct metal_i2c { + const struct metal_i2c_vtable *vtable; +}; + +/*! @brief Get a handle for a I2C device. + * @param device_num The index of the desired I2C device. + * @return A handle to the I2C device, or NULL if the device does not exist.*/ +struct metal_i2c *metal_i2c_get_device(unsigned int device_num); + +/*! @brief Initialize a I2C device with a certain baud rate. + * @param i2c The handle for the I2C device to initialize. + * @param baud_rate The baud rate for the I2C device to operate at. + * @param mode I2C operation mode. + */ +inline void metal_i2c_init(struct metal_i2c *i2c, unsigned int baud_rate, + metal_i2c_mode_t mode) { + i2c->vtable->init(i2c, baud_rate, mode); +} + +/*! @brief Perform a I2C write. + * @param i2c The handle for the I2C device to perform the write operation. + * @param addr The I2C slave address for the write operation. + * @param len The number of bytes to transfer. + * @param buf The buffer to send over the I2C bus. Must be len bytes long. + * @param stop_bit Enable / Disable STOP condition. + * @return 0 if the write succeeds. + */ +inline int metal_i2c_write(struct metal_i2c *i2c, unsigned int addr, + unsigned int len, unsigned char buf[], + metal_i2c_stop_bit_t stop_bit) { + return i2c->vtable->write(i2c, addr, len, buf, stop_bit); +} + +/*! @brief Perform a I2C read. + * @param i2c The handle for the I2C device to perform the read operation. + * @param addr The I2C slave address for the read operation. + * @param len The number of bytes to transfer. + * @param buf The buffer to store data from I2C bus. Must be len bytes long. + * @param stop_bit Enable / Disable STOP condition. + * @return 0 if the read succeeds. + */ +inline int metal_i2c_read(struct metal_i2c *i2c, unsigned int addr, + unsigned int len, unsigned char buf[], + metal_i2c_stop_bit_t stop_bit) { + return i2c->vtable->read(i2c, addr, len, buf, stop_bit); +} + +/*! @brief Performs back to back I2C write and read operations. + * @param i2c The handle for the I2C device to perform the transfer operation. + * @param addr The I2C slave address for the transfer operation. + * @param txbuf The data buffer to be transmitted over I2C bus. + * @param txlen The number of bytes to write over I2C. + * @param rxbuf The buffer to store data received over I2C bus. + * @param rxlen The number of bytes to read over I2C. + * @return 0 if the transfer succeeds. + */ +inline int metal_i2c_transfer(struct metal_i2c *i2c, unsigned int addr, + unsigned char txbuf[], unsigned int txlen, + unsigned char rxbuf[], unsigned int rxlen) { + return i2c->vtable->transfer(i2c, addr, txbuf, txlen, rxbuf, rxlen); +} + +/*! @brief Get the current baud rate of the I2C device. + * @param i2c The handle for the I2C device. + * @return The baud rate in Hz. + */ +inline int metal_i2c_get_baud_rate(struct metal_i2c *i2c) { + return i2c->vtable->get_baud_rate(i2c); +} + +/*! @brief Set the current baud rate of the I2C device. + * @param i2c The handle for the I2C device. + * @param baud_rate The desired baud rate of the I2C device. + * @return 0 If the baud rate is successfully changed. + */ +inline int metal_i2c_set_baud_rate(struct metal_i2c *i2c, int baud_rate) { + return i2c->vtable->set_baud_rate(i2c, baud_rate); +} + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/init.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/init.h new file mode 100644 index 000000000..0214d0add --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/init.h @@ -0,0 +1,130 @@ +/* Copyright 2019 SiFive Inc. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL_INIT +#define METAL_INIT + +/*! + * @file init.h + * API for Metal constructors and destructors + */ + +typedef void (*metal_constructor_t)(void); +typedef void (*metal_destructor_t)(void); + +#define METAL_INIT_HIGHEST_PRIORITY 0 +#define METAL_INIT_DEFAULT_PRIORITY 5000 +#define METAL_INIT_LOWEST_PRIORITY 9999 + +/*! @def METAL_CONSTRUCTOR + * @brief Define a Metal constructor + * + * Functions defined with METAL_CONSTRUCTOR will be added to the list of + * Metal constructors. By default, these functions are called before main by + * the metal_init() function. + */ +#define METAL_CONSTRUCTOR(function_name) \ + METAL_CONSTRUCTOR_PRIO(function_name, METAL_INIT_DEFAULT_PRIORITY) + +/*! @def METAL_CONSTRUCTOR_PRIO + * @brief Define a Metal constructor with a given priority + * + * The priority argument should be an integer between 0 and 9999, where 0 + * is the highest priority (runs first) and 9999 is the lowest priority + * (runs last). + * + * Functions defined with METAL_CONSTRUCTOR_PRIO will be added to the list of + * Metal constructors. By default, these functions are called before main by + * the metal_init() function. + */ +#define METAL_CONSTRUCTOR_PRIO(function_name, priority) \ + __METAL_CONSTRUCTOR_PRIO(function_name, priority) + +/* We use this wrapper for METAL_CONSTRUCTOR_PRIORITY so that macros passed + * as 'priority' are expanded before being stringified by the # operator. + * If we don't do this, then + * METAL_CONSTRUCTOR(my_fn_name, METAL_INIT_DEFAULT_PRIORITY) + * results in .metal.init_array.METAL_INIT_DEFAULT_PRIORITY instead of + * .metal.init_array.5000 */ +#define __METAL_CONSTRUCTOR_PRIO(function_name, priority) \ + __attribute__((section(".metal.ctors"))) void function_name(void); \ + __attribute__((section(".metal.init_array." #priority))) \ + metal_constructor_t _##function_name##_ptr = &function_name; \ + void function_name(void) + +/*! @def METAL_DESTRUCTOR + * @brief Define a Metal destructor + * + * Functions defined with METAL_DESTRUCTOR will be added to the list of + * Metal destructors. By default, these functions are called on exit by + * the metal_fini() function. + */ +#define METAL_DESTRUCTOR(function_name) \ + METAL_DESTRUCTOR_PRIO(function_name, METAL_INIT_DEFAULT_PRIORITY) + +/*! @def METAL_DESTRUCTOR_PRIO + * @brief Define a Metal destructor with a given priority + * + * The priority argument should be an integer between 0 and 9999, where 0 + * is the highest priority (runs first) and 9999 is the lowest priority + * (runs last). + * + * Functions defined with METAL_DESTRUCTOR_PRIO will be added to the list of + * Metal destructors. By default, these functions are called on exit by + * the metal_fini() function. + */ +#define METAL_DESTRUCTOR_PRIO(function_name, priority) \ + __METAL_DESTRUCTOR_PRIO(function_name, priority) +#define __METAL_DESTRUCTOR_PRIO(function_name, priority) \ + __attribute__((section(".metal.dtors"))) void function_name(void); \ + __attribute__((section(".metal.fini_array." #priority))) \ + metal_destructor_t _##function_name##_ptr = &function_name; \ + void function_name(void) + +/*! + * @brief Call all Metal constructors + * + * Devices supported by Metal may define Metal constructors to perform + * initialization before main. This function iterates over the constructors + * and calls them in turn. + * + * You can add your own constructors to the functions called by metal_init() + * by defining functions with the METAL_CONSTRUCTOR() macro. + * + * This function is called before main by default by metal_init_run(). + */ +void metal_init(void); + +/*! + * @brief Call all Metal destructors + * + * Devices supported by Metal may define Metal destructors to perform + * initialization on exit. This function iterates over the destructors + * and calls them in turn. + * + * You can add your own destructors to the functions called by metal_fini() + * by defining functions with the METAL_DESTRUCTOR() macro. + * + * This function is called on exit by default by metal_fini_run(). + */ +void metal_fini(void); + +/*! + * @brief Weak function to call metal_init() before main + * + * This function calls metal_init() before main by default. If you wish to + * replace or augment this call to the Metal constructors, you can redefine + * metal_init_run() + */ +void metal_init_run(void); + +/*! + * @brief Weak function to call metal_fini() before main + * + * This function calls metal_fini() at exit by default. If you wish to + * replace or augment this call to the Metal destructors, you can redefine + * metal_fini_run() + */ +void metal_fini_run(void); + +#endif /* METAL_INIT */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/interrupt.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/interrupt.h index 4f59bd36b..11df019de 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/interrupt.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/interrupt.h @@ -41,35 +41,74 @@ typedef enum metal_intr_priv_mode_ { } metal_intr_priv_mode; /*! + * @brief The bitmask of hart context + */ +typedef struct metal_affinity_ { + unsigned long bitmask; +} metal_affinity; + +#define for_each_metal_affinity(bit, metal_affinity) \ + for (bit = 0; metal_affinity.bitmask; bit++, metal_affinity.bitmask >>= 1) + +#define metal_affinity_set_val(metal_affinity, val) \ + metal_affinity.bitmask = val; + +#define metal_affinity_set_bit(metal_affinity, bit, val) \ + metal_affinity.bitmask |= ((val & 0x1) << bit); + +/*! * @brief Function signature for interrupt callback handlers */ -typedef void (*metal_interrupt_handler_t) (int, void *); -typedef void (*metal_interrupt_vector_handler_t) (void); +typedef void (*metal_interrupt_handler_t)(int, void *); +typedef void (*metal_interrupt_vector_handler_t)(void); struct metal_interrupt; struct metal_interrupt_vtable { void (*interrupt_init)(struct metal_interrupt *controller); - int (*interrupt_set_vector_mode)(struct metal_interrupt *controller, metal_vector_mode mode); - metal_vector_mode (*interrupt_get_vector_mode)(struct metal_interrupt *controller); - int (*interrupt_set_privilege)(struct metal_interrupt *controller, metal_intr_priv_mode priv); - metal_intr_priv_mode (*interrupt_get_privilege)(struct metal_interrupt *controller); + int (*interrupt_set_vector_mode)(struct metal_interrupt *controller, + metal_vector_mode mode); + metal_vector_mode (*interrupt_get_vector_mode)( + struct metal_interrupt *controller); + int (*interrupt_set_privilege)(struct metal_interrupt *controller, + metal_intr_priv_mode priv); + metal_intr_priv_mode (*interrupt_get_privilege)( + struct metal_interrupt *controller); int (*interrupt_clear)(struct metal_interrupt *controller, int id); int (*interrupt_set)(struct metal_interrupt *controller, int id); int (*interrupt_register)(struct metal_interrupt *controller, int id, - metal_interrupt_handler_t isr, void *priv_data); + metal_interrupt_handler_t isr, void *priv_data); int (*interrupt_vector_register)(struct metal_interrupt *controller, int id, - metal_interrupt_vector_handler_t isr, void *priv_data); + metal_interrupt_vector_handler_t isr, + void *priv_data); int (*interrupt_enable)(struct metal_interrupt *controller, int id); int (*interrupt_disable)(struct metal_interrupt *controller, int id); int (*interrupt_vector_enable)(struct metal_interrupt *controller, int id); int (*interrupt_vector_disable)(struct metal_interrupt *controller, int id); unsigned int (*interrupt_get_threshold)(struct metal_interrupt *controller); - int (*interrupt_set_threshold)(struct metal_interrupt *controller, unsigned int threshold); - unsigned int (*interrupt_get_priority)(struct metal_interrupt *controller, int id); - int (*interrupt_set_priority)(struct metal_interrupt *controller, int id, unsigned int priority); - int (*command_request)(struct metal_interrupt *controller, int cmd, void *data); - int (*mtimecmp_set)(struct metal_interrupt *controller, int hartid, unsigned long long time); + int (*interrupt_set_threshold)(struct metal_interrupt *controller, + unsigned int threshold); + unsigned int (*interrupt_get_priority)(struct metal_interrupt *controller, + int id); + int (*interrupt_set_priority)(struct metal_interrupt *controller, int id, + unsigned int priority); + unsigned int (*interrupt_get_preemptive_level)( + struct metal_interrupt *controller, int id); + int (*interrupt_set_preemptive_level)(struct metal_interrupt *controller, + int id, unsigned int level); + int (*command_request)(struct metal_interrupt *controller, int cmd, + void *data); + int (*mtimecmp_set)(struct metal_interrupt *controller, int hartid, + unsigned long long time); + metal_affinity (*interrupt_affinity_enable)( + struct metal_interrupt *controller, metal_affinity bitmask, int id); + metal_affinity (*interrupt_affinity_disable)( + struct metal_interrupt *controller, metal_affinity bitmask, int id); + metal_affinity (*interrupt_affinity_set_threshold)( + struct metal_interrupt *controller, metal_affinity bitmask, + unsigned int threshold); + unsigned int (*interrupt_affinity_get_threshold)( + struct metal_interrupt *controller, int context_id); }; /*! @@ -88,8 +127,7 @@ struct metal_interrupt { * * @param controller The handle for the interrupt controller */ -__inline__ void metal_interrupt_init(struct metal_interrupt *controller) -{ +__inline__ void metal_interrupt_init(struct metal_interrupt *controller) { controller->vtable->interrupt_init(controller); } @@ -100,8 +138,8 @@ __inline__ void metal_interrupt_init(struct metal_interrupt *controller) * @return A handle to the interrupt controller (CLINT, CLIC, PLIC), or * NULL if none is found for the requested label */ -struct metal_interrupt* metal_interrupt_get_controller(metal_intr_cntrl_type cntrl, - int id); +struct metal_interrupt * +metal_interrupt_get_controller(metal_intr_cntrl_type cntrl, int id); /*! * @brief Configure vector mode for an interrupt controller @@ -114,9 +152,9 @@ struct metal_interrupt* metal_interrupt_get_controller(metal_intr_cntrl_type cnt * @param mode The vector mode of the interrupt controller. * @return 0 upon success */ -__inline__ int metal_interrupt_set_vector_mode(struct metal_interrupt *controller, - metal_vector_mode mode) -{ +__inline__ int +metal_interrupt_set_vector_mode(struct metal_interrupt *controller, + metal_vector_mode mode) { return controller->vtable->interrupt_set_vector_mode(controller, mode); } @@ -131,8 +169,8 @@ __inline__ int metal_interrupt_set_vector_mode(struct metal_interrupt *controlle * @param mode The vector mode of the interrupt controller. * @return The interrupt vector mode */ -__inline__ metal_vector_mode metal_interrupt_get_vector_mode(struct metal_interrupt *controller) -{ +__inline__ metal_vector_mode +metal_interrupt_get_vector_mode(struct metal_interrupt *controller) { return controller->vtable->interrupt_get_vector_mode(controller); } @@ -148,8 +186,7 @@ __inline__ metal_vector_mode metal_interrupt_get_vector_mode(struct metal_interr * @return 0 upon success */ __inline__ int metal_interrupt_set_privilege(struct metal_interrupt *controller, - metal_intr_priv_mode privilege) -{ + metal_intr_priv_mode privilege) { return controller->vtable->interrupt_set_privilege(controller, privilege); } @@ -163,8 +200,8 @@ __inline__ int metal_interrupt_set_privilege(struct metal_interrupt *controller, * @param controller The handle for the interrupt controller * @return The interrupt privilege mode */ -__inline__ metal_intr_priv_mode metal_interrupt_get_privilege(struct metal_interrupt *controller) -{ +__inline__ metal_intr_priv_mode +metal_interrupt_get_privilege(struct metal_interrupt *controller) { return controller->vtable->interrupt_get_privilege(controller); } @@ -174,10 +211,10 @@ __inline__ metal_intr_priv_mode metal_interrupt_get_privilege(struct metal_inter * @param id The interrupt ID to trigger * @return 0 upon success */ -__inline__ int metal_interrupt_clear(struct metal_interrupt *controller, int id) -{ +__inline__ int metal_interrupt_clear(struct metal_interrupt *controller, + int id) { return controller->vtable->interrupt_clear(controller, id); -} +} /*! * @brief Set an interrupt @@ -185,8 +222,7 @@ __inline__ int metal_interrupt_clear(struct metal_interrupt *controller, int id) * @param id The interrupt ID to trigger * @return 0 upon success */ -__inline__ int metal_interrupt_set(struct metal_interrupt *controller, int id) -{ +__inline__ int metal_interrupt_set(struct metal_interrupt *controller, int id) { return controller->vtable->interrupt_set(controller, id); } @@ -198,12 +234,12 @@ __inline__ int metal_interrupt_set(struct metal_interrupt *controller, int id) * @param priv_data Private data for the interrupt handler * @return 0 upon success */ -__inline__ int metal_interrupt_register_handler(struct metal_interrupt *controller, - int id, - metal_interrupt_handler_t handler, - void *priv_data) -{ - return controller->vtable->interrupt_register(controller, id, handler, priv_data); +__inline__ int +metal_interrupt_register_handler(struct metal_interrupt *controller, int id, + metal_interrupt_handler_t handler, + void *priv_data) { + return controller->vtable->interrupt_register(controller, id, handler, + priv_data); } /*! @@ -214,12 +250,11 @@ __inline__ int metal_interrupt_register_handler(struct metal_interrupt *controll * @param priv_data Private data for the interrupt handler * @return 0 upon success */ -__inline__ int metal_interrupt_register_vector_handler(struct metal_interrupt *controller, - int id, - metal_interrupt_vector_handler_t handler, - void *priv_data) -{ - return controller->vtable->interrupt_vector_register(controller, id, handler, priv_data); +__inline__ int metal_interrupt_register_vector_handler( + struct metal_interrupt *controller, int id, + metal_interrupt_vector_handler_t handler, void *priv_data) { + return controller->vtable->interrupt_vector_register(controller, id, + handler, priv_data); } /*! @@ -228,8 +263,8 @@ __inline__ int metal_interrupt_register_vector_handler(struct metal_interrupt *c * @param id The interrupt ID to enable * @return 0 upon success */ -__inline__ int metal_interrupt_enable(struct metal_interrupt *controller, int id) -{ +__inline__ int metal_interrupt_enable(struct metal_interrupt *controller, + int id) { return controller->vtable->interrupt_enable(controller, id); } @@ -239,8 +274,8 @@ __inline__ int metal_interrupt_enable(struct metal_interrupt *controller, int id * @param id The interrupt ID to disable * @return 0 upon success */ -__inline__ int metal_interrupt_disable(struct metal_interrupt *controller, int id) -{ +__inline__ int metal_interrupt_disable(struct metal_interrupt *controller, + int id) { return controller->vtable->interrupt_disable(controller, id); } @@ -250,8 +285,8 @@ __inline__ int metal_interrupt_disable(struct metal_interrupt *controller, int i * @param threshold The interrupt threshold level * @return 0 upon success */ -inline int metal_interrupt_set_threshold(struct metal_interrupt *controller, unsigned int level) -{ +__inline__ int metal_interrupt_set_threshold(struct metal_interrupt *controller, + unsigned int level) { return controller->vtable->interrupt_set_threshold(controller, level); } @@ -260,9 +295,9 @@ inline int metal_interrupt_set_threshold(struct metal_interrupt *controller, uns * @param controller The handle for the interrupt controller * @return The interrupt threshold level */ -inline unsigned int metal_interrupt_get_threshold(struct metal_interrupt *controller) -{ - return controller->vtable->interrupt_get_threshold(controller); +__inline__ unsigned int +metal_interrupt_get_threshold(struct metal_interrupt *controller) { + return controller->vtable->interrupt_get_threshold(controller); } /*! @@ -272,9 +307,8 @@ inline unsigned int metal_interrupt_get_threshold(struct metal_interrupt *contro * @param priority The interrupt priority level * @return 0 upon success */ -inline int metal_interrupt_set_priority(struct metal_interrupt *controller, - int id, unsigned int priority) -{ +__inline__ int metal_interrupt_set_priority(struct metal_interrupt *controller, + int id, unsigned int priority) { return controller->vtable->interrupt_set_priority(controller, id, priority); } @@ -284,9 +318,45 @@ inline int metal_interrupt_set_priority(struct metal_interrupt *controller, * @param id The interrupt ID to enable * @return The interrupt priority level */ -inline unsigned int metal_interrupt_get_priority(struct metal_interrupt *controller, int id) -{ - return controller->vtable->interrupt_get_priority(controller, id); +__inline__ unsigned int +metal_interrupt_get_priority(struct metal_interrupt *controller, int id) { + return controller->vtable->interrupt_get_priority(controller, id); +} + +/*! + * @brief Set preemptive level and priority for a given interrupt ID + * + * Set the preemptive level and priority for a given interrupt ID. + * + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to enable + * @param level The interrupt level and priority are encoded together + * @return 0 upon success + */ +__inline__ int +metal_interrupt_set_preemptive_level(struct metal_interrupt *controller, int id, + unsigned int level) { + if (controller->vtable->interrupt_set_preemptive_level) + return controller->vtable->interrupt_set_preemptive_level(controller, + id, level); + else + return 0; +} + +/*! + * @brief Get an interrupt preemptive level + * @param controller The handle for the interrupt controller + * @param id The interrupt ID to enable + * @return The interrupt level + */ +__inline__ unsigned int +metal_interrupt_get_preemptive_level(struct metal_interrupt *controller, + int id) { + if (controller->vtable->interrupt_get_preemptive_level) + return controller->vtable->interrupt_get_preemptive_level(controller, + id); + else + return 0; } /*! @@ -295,8 +365,8 @@ inline unsigned int metal_interrupt_get_priority(struct metal_interrupt *control * @param id The interrupt ID to enable * @return 0 upon success */ -__inline__ int metal_interrupt_vector_enable(struct metal_interrupt *controller, int id) -{ +__inline__ int metal_interrupt_vector_enable(struct metal_interrupt *controller, + int id) { return controller->vtable->interrupt_vector_enable(controller, id); } @@ -306,8 +376,8 @@ __inline__ int metal_interrupt_vector_enable(struct metal_interrupt *controller, * @param id The interrupt ID to disable * @return 0 upon success */ -__inline__ int metal_interrupt_vector_disable(struct metal_interrupt *controller, int id) -{ +__inline__ int +metal_interrupt_vector_disable(struct metal_interrupt *controller, int id) { return controller->vtable->interrupt_vector_disable(controller, id); } @@ -323,21 +393,24 @@ void __attribute__((weak, interrupt)) metal_interrupt_vector_handler(void); * @param None * @return None */ -void __attribute__((weak, interrupt)) metal_software_interrupt_vector_handler(void); +void __attribute__((weak, interrupt)) +metal_software_interrupt_vector_handler(void); /*! * @brief Metal Timer interrupt vector handler, that can be overriden by user * @param None * @return None */ -void __attribute__((weak, interrupt)) metal_timer_interrupt_vector_handler(void); +void __attribute__((weak, interrupt)) +metal_timer_interrupt_vector_handler(void); /*! * @brief Metal External interrupt vector handler, that can be overriden by user * @param None * @return None */ -void __attribute__((weak, interrupt)) metal_external_interrupt_vector_handler(void); +void __attribute__((weak, interrupt)) +metal_external_interrupt_vector_handler(void); /*! * @brief Metal Local 0 interrupt vector handler, that can be overriden by user @@ -387,7 +460,7 @@ void __attribute__((weak, interrupt)) metal_lc5_interrupt_vector_handler(void); * @return None */ void __attribute__((weak, interrupt)) metal_lc6_interrupt_vector_handler(void); - + /*! * @brief Metal Local 7 interrupt vector handler, that can be overriden by user * @param None @@ -451,11 +524,67 @@ void __attribute__((weak, interrupt)) metal_lc14_interrupt_vector_handler(void); */ void __attribute__((weak, interrupt)) metal_lc15_interrupt_vector_handler(void); -/* Utilities function to controll, manages devices via a given interrupt controller */ -__inline__ int _metal_interrupt_command_request(struct metal_interrupt *controller, - int cmd, void *data) -{ +/* Utilities function to controll, manages devices via a given interrupt + * controller */ +__inline__ int +_metal_interrupt_command_request(struct metal_interrupt *controller, int cmd, + void *data) { return controller->vtable->command_request(controller, cmd, data); } +/*! + * @brief Enable an interrupt for the hart contexts + * @param controller The handle for the interrupt controller + * @param bitmask The bit mask of hart contexts to enable + * @param id The interrupt ID to enable + * @return The result of each hart context. 0 upon success at relevant bit. + */ +__inline__ metal_affinity +metal_interrupt_affinity_enable(struct metal_interrupt *controller, + metal_affinity bitmask, int id) { + return controller->vtable->interrupt_affinity_enable(controller, bitmask, + id); +} + +/*! + * @brief Disable an interrupt for the hart contexts + * @param controller The handle for the interrupt controller + * @param bitmask The bit mask of hart contexts to disable + * @param id The interrupt ID to disable + * @return The result of each hart context. 0 upon success at relevant bit. + */ +__inline__ metal_affinity +metal_interrupt_affinity_disable(struct metal_interrupt *controller, + metal_affinity bitmask, int id) { + return controller->vtable->interrupt_affinity_disable(controller, bitmask, + id); +} + +/*! + * @brief Set interrupt threshold level for the hart contexts + * @param controller The handle for the interrupt controller + * @param bitmask The bit mask of hart contexts to set threshold + * @param threshold The interrupt threshold level + * @return The result of each hart context. 0 upon success at relevant bit. + */ +__inline__ metal_affinity +metal_interrupt_affinity_set_threshold(struct metal_interrupt *controller, + metal_affinity bitmask, + unsigned int level) { + return controller->vtable->interrupt_affinity_set_threshold(controller, + bitmask, level); +} + +/*! + * @brief Get an interrupt threshold level from the hart context + * @param controller The handle for the interrupt controller + * @param context_id The hart context ID to get threshold + * @return The interrupt threshold level + */ +__inline__ unsigned int +metal_interrupt_affinity_get_threshold(struct metal_interrupt *controller, + int context_id) { + return controller->vtable->interrupt_affinity_get_threshold(controller, + context_id); +} #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/io.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/io.h index d55b4520a..f1df85518 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/io.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/io.h @@ -8,15 +8,16 @@ #define __METAL_ACCESS_ONCE(x) (*(__typeof__(*x) volatile *)(x)) /* Allows users to specify arbitrary fences. */ -#define __METAL_IO_FENCE(pred, succ) __asm__ volatile ("fence " #pred "," #succ ::: "memory"); +#define __METAL_IO_FENCE(pred, succ) \ + __asm__ volatile("fence " #pred "," #succ ::: "memory"); /* Types that explicitly describe an address as being used for memory-mapped * IO. These should only be accessed via __METAL_ACCESS_ONCE. */ -typedef unsigned char __metal_io_u8; +typedef unsigned char __metal_io_u8; typedef unsigned short __metal_io_u16; -typedef unsigned int __metal_io_u32; +typedef unsigned int __metal_io_u32; #if __riscv_xlen >= 64 -typedef unsigned long __metal_io_u64; +typedef unsigned long __metal_io_u64; #endif #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/itim.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/itim.h index 1a2a05b8b..3decefff2 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/itim.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/itim.h @@ -9,13 +9,12 @@ * API for manipulating ITIM allocation */ - /*! @def METAL_PLACE_IN_ITIM * @brief Link a function into the ITIM * * Link a function into the ITIM (Instruction Tightly Integrated * Memory) if the ITIM is present on the target device. */ -#define METAL_PLACE_IN_ITIM __attribute__((section(".itim"))) +#define METAL_PLACE_IN_ITIM __attribute__((section(".itim"))) #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/led.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/led.h index f2aa39ceb..da2555fb8 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/led.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/led.h @@ -31,38 +31,47 @@ struct metal_led { * @param label The DeviceTree label for the desired LED * @return A handle to the LED, or NULL if none is found for the requested label */ -struct metal_led* metal_led_get(char *label); +struct metal_led *metal_led_get(char *label); /*! * @brief Get a handle for a channel of an RGB LED * @param label The DeviceTree label for the desired LED * @param color The color for the LED in the DeviceTree - * @return A handle to the LED, or NULL if none is found for the requested label and color + * @return A handle to the LED, or NULL if none is found for the requested label + * and color */ -struct metal_led* metal_led_get_rgb(char *label, char *color); +struct metal_led *metal_led_get_rgb(char *label, char *color); /*! * @brief Enable an LED * @param led The handle for the LED */ -__inline__ void metal_led_enable(struct metal_led *led) { led->vtable->led_enable(led); } +__inline__ void metal_led_enable(struct metal_led *led) { + led->vtable->led_enable(led); +} /*! * @brief Turn an LED on * @param led The handle for the LED */ -__inline__ void metal_led_on(struct metal_led *led) { led->vtable->led_on(led); } +__inline__ void metal_led_on(struct metal_led *led) { + led->vtable->led_on(led); +} /*! * @brief Turn an LED off * @param led The handle for the LED */ -__inline__ void metal_led_off(struct metal_led *led) { led->vtable->led_off(led); } +__inline__ void metal_led_off(struct metal_led *led) { + led->vtable->led_off(led); +} /*! * @brief Toggle the on/off state of an LED * @param led The handle for the LED */ -__inline__ void metal_led_toggle(struct metal_led *led) { led->vtable->led_toggle(led); } +__inline__ void metal_led_toggle(struct metal_led *led) { + led->vtable->led_toggle(led); +} #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/lim.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/lim.h new file mode 100644 index 000000000..1e573cad6 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/lim.h @@ -0,0 +1,20 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__LIM_H +#define METAL__LIM_H + +/*! @file lim.h + * + * API for manipulating LIM allocation + */ + +/*! @def METAL_PLACE_IN_LIM + * @brief Link a function into the LIM + * + * Link a function into the LIM (Loosely Integrated + * Memory) if the LIM is present on the target device. + */ +#define METAL_PLACE_IN_LIM __attribute__((section(".lim"))) + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/lock.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/lock.h index 0702cbf16..e591eaefa 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/lock.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/lock.h @@ -4,9 +4,9 @@ #ifndef METAL__LOCK_H #define METAL__LOCK_H +#include <metal/compiler.h> #include <metal/machine.h> #include <metal/memory.h> -#include <metal/compiler.h> /*! * @file lock.h @@ -26,21 +26,21 @@ * Locks must be declared with METAL_LOCK_DECLARE to ensure that the lock * is linked into a memory region which supports atomic memory operations. */ -#define METAL_LOCK_DECLARE(name) \ - __attribute__((section(".data.locks"))) \ - struct metal_lock name +#define METAL_LOCK_DECLARE(name) \ + __attribute__((section(".data.locks"))) struct metal_lock name /*! * @brief A handle for a lock */ struct metal_lock { - int _state; + int _state; }; /*! * @brief Initialize a lock * @param lock The handle for a lock - * @return 0 if the lock is successfully initialized. A non-zero code indicates failure. + * @return 0 if the lock is successfully initialized. A non-zero code indicates + * failure. * * If the lock cannot be initialized, attempts to take or give the lock * will result in a Store/AMO access fault. @@ -48,13 +48,14 @@ struct metal_lock { __inline__ int metal_lock_init(struct metal_lock *lock) { #ifdef __riscv_atomic /* Get a handle for the memory which holds the lock state */ - struct metal_memory *lock_mem = metal_get_memory_from_address((uintptr_t) &(lock->_state)); - if(!lock_mem) { + struct metal_memory *lock_mem = + metal_get_memory_from_address((uintptr_t) & (lock->_state)); + if (!lock_mem) { return 1; } /* If the memory doesn't support atomics, report an error */ - if(!metal_memory_supports_atomics(lock_mem)) { + if (!metal_memory_supports_atomics(lock_mem)) { return 2; } @@ -82,10 +83,10 @@ __inline__ int metal_lock_take(struct metal_lock *lock) { int backoff = 1; const int max_backoff = METAL_LOCK_BACKOFF_CYCLES * METAL_MAX_CORES; - while(1) { + while (1) { __asm__ volatile("amoswap.w.aq %[old], %[new], (%[state])" - : [old] "=r" (old) - : [new] "r" (new), [state] "r" (&(lock->_state)) + : [old] "=r"(old) + : [new] "r"(new), [state] "r"(&(lock->_state)) : "memory"); if (old == 0) { @@ -104,8 +105,7 @@ __inline__ int metal_lock_take(struct metal_lock *lock) { return 0; #else /* Store the memory address in mtval like a normal store/amo access fault */ - __asm__ ("csrw mtval, %[state]" - :: [state] "r" (&(lock->_state))); + __asm__("csrw mtval, %[state]" ::[state] "r"(&(lock->_state))); /* Trigger a Store/AMO access fault */ _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); @@ -125,15 +125,14 @@ __inline__ int metal_lock_take(struct metal_lock *lock) { */ __inline__ int metal_lock_give(struct metal_lock *lock) { #ifdef __riscv_atomic - __asm__ volatile("amoswap.w.rl x0, x0, (%[state])" - :: [state] "r" (&(lock->_state)) - : "memory"); + __asm__ volatile( + "amoswap.w.rl x0, x0, (%[state])" ::[state] "r"(&(lock->_state)) + : "memory"); return 0; #else /* Store the memory address in mtval like a normal store/amo access fault */ - __asm__ ("csrw mtval, %[state]" - :: [state] "r" (&(lock->_state))); + __asm__("csrw mtval, %[state]" ::[state] "r"(&(lock->_state))); /* Trigger a Store/AMO access fault */ _metal_trap(_METAL_STORE_AMO_ACCESS_FAULT); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/memory.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/memory.h index 9de7d6162..f009e9ecc 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/memory.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/memory.h @@ -4,8 +4,8 @@ #ifndef METAL__MEMORY_H #define METAL__MEMORY_H -#include <stdint.h> #include <stddef.h> +#include <stdint.h> /*! * @file memory.h @@ -14,20 +14,20 @@ */ struct _metal_memory_attributes { - unsigned int R : 1; - unsigned int W : 1; - unsigned int X : 1; - unsigned int C : 1; - unsigned int A : 1; + unsigned int R : 1; + unsigned int W : 1; + unsigned int X : 1; + unsigned int C : 1; + unsigned int A : 1; }; /*! * @brief A handle for a memory block */ struct metal_memory { - const uintptr_t _base_address; - const size_t _size; - const struct _metal_memory_attributes _attrs; + const uintptr_t _base_address; + const size_t _size; + const struct _metal_memory_attributes _attrs; }; /*! @@ -37,7 +37,8 @@ struct metal_memory { * that address is mapped. * * @param address The address to query - * @return The memory block handle, or NULL if the address is not mapped to a memory block + * @return The memory block handle, or NULL if the address is not mapped to a + * memory block */ struct metal_memory *metal_get_memory_from_address(const uintptr_t address); @@ -46,8 +47,9 @@ struct metal_memory *metal_get_memory_from_address(const uintptr_t address); * @param memory The handle for the memory block * @return The base address of the memory block */ -__inline__ uintptr_t metal_memory_get_base_address(const struct metal_memory *memory) { - return memory->_base_address; +__inline__ uintptr_t +metal_memory_get_base_address(const struct metal_memory *memory) { + return memory->_base_address; } /*! @@ -56,7 +58,7 @@ __inline__ uintptr_t metal_memory_get_base_address(const struct metal_memory *me * @return The size of the memory block */ __inline__ size_t metal_memory_get_size(const struct metal_memory *memory) { - return memory->_size; + return memory->_size; } /*! @@ -64,8 +66,9 @@ __inline__ size_t metal_memory_get_size(const struct metal_memory *memory) { * @param memory The handle for the memory block * @return nonzero if the memory block supports atomic operations */ -__inline__ int metal_memory_supports_atomics(const struct metal_memory *memory) { - return memory->_attrs.A; +__inline__ int +metal_memory_supports_atomics(const struct metal_memory *memory) { + return memory->_attrs.A; } /*! @@ -74,8 +77,7 @@ __inline__ int metal_memory_supports_atomics(const struct metal_memory *memory) * @return nonzero if the memory block is cachable */ __inline__ int metal_memory_is_cachable(const struct metal_memory *memory) { - return memory->_attrs.C; + return memory->_attrs.C; } #endif /* METAL__MEMORY_H */ - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/pmp.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/pmp.h index d948656c8..38ab1b9a4 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/pmp.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/pmp.h @@ -12,14 +12,14 @@ * The Physical Memory Protection (PMP) interface on RISC-V cores * is a form of memory protection unit which allows for a finite number * of physical memory regions to be configured with certain access - * permissions. + * permissions. * * Additional information about the use and configuration rules for PMPs * can be found by reading the RISC-V Privileged Architecture Specification. */ -#include <stddef.h> #include <metal/machine.h> +#include <stddef.h> struct metal_pmp; @@ -28,11 +28,11 @@ struct metal_pmp; */ enum metal_pmp_address_mode { /*! @brief Disable the PMP region */ - METAL_PMP_OFF = 0, + METAL_PMP_OFF = 0, /*! @brief Use Top-of-Range mode */ - METAL_PMP_TOR = 1, + METAL_PMP_TOR = 1, /*! @brief Use naturally-aligned 4-byte region mode */ - METAL_PMP_NA4 = 2, + METAL_PMP_NA4 = 2, /*! @brief Use naturally-aligned power-of-two mode */ METAL_PMP_NAPOT = 3 }; @@ -56,7 +56,7 @@ struct metal_pmp_config { /*! @brief Sets whether the PMP region is locked */ enum metal_pmp_locked { METAL_PMP_UNLOCKED = 0, - METAL_PMP_LOCKED = 1 + METAL_PMP_LOCKED = 1 } L : 1; }; @@ -101,9 +101,10 @@ void metal_pmp_init(struct metal_pmp *pmp); * @param address The desired address of the PMP region * @return 0 upon success */ -int metal_pmp_set_region(struct metal_pmp *pmp, unsigned int region, struct metal_pmp_config config, size_t address); +int metal_pmp_set_region(struct metal_pmp *pmp, unsigned int region, + struct metal_pmp_config config, size_t address); -/*! +/*! * @brief Get the configuration for a PMP region * @param pmp The PMP device handle * @param region The PMP region to read @@ -111,7 +112,8 @@ int metal_pmp_set_region(struct metal_pmp *pmp, unsigned int region, struct meta * @param address Variable to store the PMP region address * @return 0 if the region is read successfully */ -int metal_pmp_get_region(struct metal_pmp *pmp, unsigned int region, struct metal_pmp_config *config, size_t *address); +int metal_pmp_get_region(struct metal_pmp *pmp, unsigned int region, + struct metal_pmp_config *config, size_t *address); /*! * @brief Lock a PMP region @@ -128,7 +130,8 @@ int metal_pmp_lock(struct metal_pmp *pmp, unsigned int region); * @param address The desired address of the PMP region * @return 0 if the address is successfully set */ -int metal_pmp_set_address(struct metal_pmp *pmp, unsigned int region, size_t address); +int metal_pmp_set_address(struct metal_pmp *pmp, unsigned int region, + size_t address); /*! * @brief Get the address of a PMP region @@ -145,7 +148,8 @@ size_t metal_pmp_get_address(struct metal_pmp *pmp, unsigned int region); * @param mode The PMP addressing mode to set * @return 0 if the addressing mode is successfully set */ -int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region, enum metal_pmp_address_mode mode); +int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region, + enum metal_pmp_address_mode mode); /*! * @brief Get the addressing mode of a PMP region @@ -153,7 +157,8 @@ int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region, enum * @param region The PMP region to read * @return The address mode of the PMP region */ -enum metal_pmp_address_mode metal_pmp_get_address_mode(struct metal_pmp *pmp, unsigned int region); +enum metal_pmp_address_mode metal_pmp_get_address_mode(struct metal_pmp *pmp, + unsigned int region); /*! * @brief Set the executable bit for a PMP region diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/privilege.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/privilege.h index 928a936b1..522e7efe0 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/privilege.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/privilege.h @@ -16,9 +16,9 @@ #include <stdint.h> enum metal_privilege_mode { - METAL_PRIVILEGE_USER = 0, - METAL_PRIVILEGE_SUPERVISOR = 1, - METAL_PRIVILEGE_MACHINE = 3, + METAL_PRIVILEGE_USER = 0, + METAL_PRIVILEGE_SUPERVISOR = 1, + METAL_PRIVILEGE_MACHINE = 3, }; #if __riscv_xlen == 32 @@ -34,89 +34,89 @@ typedef uint64_t metal_freg_t; #endif struct metal_register_file { - metal_xreg_t ra; - metal_xreg_t sp; - metal_xreg_t gp; - metal_xreg_t tp; - - metal_xreg_t t0; - metal_xreg_t t1; - metal_xreg_t t2; - - metal_xreg_t s0; - metal_xreg_t s1; - - metal_xreg_t a0; - metal_xreg_t a1; - metal_xreg_t a2; - metal_xreg_t a3; - metal_xreg_t a4; - metal_xreg_t a5; + metal_xreg_t ra; + metal_xreg_t sp; + metal_xreg_t gp; + metal_xreg_t tp; + + metal_xreg_t t0; + metal_xreg_t t1; + metal_xreg_t t2; + + metal_xreg_t s0; + metal_xreg_t s1; + + metal_xreg_t a0; + metal_xreg_t a1; + metal_xreg_t a2; + metal_xreg_t a3; + metal_xreg_t a4; + metal_xreg_t a5; #ifndef __riscv_32e - metal_xreg_t a6; - metal_xreg_t a7; - - metal_xreg_t s2; - metal_xreg_t s3; - metal_xreg_t s4; - metal_xreg_t s5; - metal_xreg_t s6; - metal_xreg_t s7; - metal_xreg_t s8; - metal_xreg_t s9; - metal_xreg_t s10; - metal_xreg_t s11; - - metal_xreg_t t3; - metal_xreg_t t4; - metal_xreg_t t5; - metal_xreg_t t6; + metal_xreg_t a6; + metal_xreg_t a7; + + metal_xreg_t s2; + metal_xreg_t s3; + metal_xreg_t s4; + metal_xreg_t s5; + metal_xreg_t s6; + metal_xreg_t s7; + metal_xreg_t s8; + metal_xreg_t s9; + metal_xreg_t s10; + metal_xreg_t s11; + + metal_xreg_t t3; + metal_xreg_t t4; + metal_xreg_t t5; + metal_xreg_t t6; #endif /* __riscv_32e */ #ifdef __riscv_flen - metal_freg_t ft0; - metal_freg_t ft1; - metal_freg_t ft2; - metal_freg_t ft3; - metal_freg_t ft4; - metal_freg_t ft5; - metal_freg_t ft6; - metal_freg_t ft7; - - metal_freg_t fs0; - metal_freg_t fs1; - - metal_freg_t fa0; - metal_freg_t fa1; - metal_freg_t fa2; - metal_freg_t fa3; - metal_freg_t fa4; - metal_freg_t fa5; - metal_freg_t fa6; - metal_freg_t fa7; - - metal_freg_t fs2; - metal_freg_t fs3; - metal_freg_t fs4; - metal_freg_t fs5; - metal_freg_t fs6; - metal_freg_t fs7; - metal_freg_t fs8; - metal_freg_t fs9; - metal_freg_t fs10; - metal_freg_t fs11; - - metal_freg_t ft8; - metal_freg_t ft9; - metal_freg_t ft10; - metal_freg_t ft11; + metal_freg_t ft0; + metal_freg_t ft1; + metal_freg_t ft2; + metal_freg_t ft3; + metal_freg_t ft4; + metal_freg_t ft5; + metal_freg_t ft6; + metal_freg_t ft7; + + metal_freg_t fs0; + metal_freg_t fs1; + + metal_freg_t fa0; + metal_freg_t fa1; + metal_freg_t fa2; + metal_freg_t fa3; + metal_freg_t fa4; + metal_freg_t fa5; + metal_freg_t fa6; + metal_freg_t fa7; + + metal_freg_t fs2; + metal_freg_t fs3; + metal_freg_t fs4; + metal_freg_t fs5; + metal_freg_t fs6; + metal_freg_t fs7; + metal_freg_t fs8; + metal_freg_t fs9; + metal_freg_t fs10; + metal_freg_t fs11; + + metal_freg_t ft8; + metal_freg_t ft9; + metal_freg_t ft10; + metal_freg_t ft11; #endif /* __riscv_flen */ }; typedef void (*metal_privilege_entry_point_t)(void); void metal_privilege_drop_to_mode(enum metal_privilege_mode mode, - struct metal_register_file regfile, - metal_privilege_entry_point_t entry_point); + struct metal_register_file regfile, + metal_privilege_entry_point_t entry_point); #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/pwm.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/pwm.h new file mode 100644 index 000000000..600d5a02b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/pwm.h @@ -0,0 +1,162 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__PWM_H +#define METAL__PWM_H + +/*! @brief Enums for PWM running modes. */ +typedef enum { + METAL_PWM_CONTINUOUS = 0, + METAL_PWM_ONE_SHOT = 1 +} metal_pwm_run_mode_t; + +/*! @brief Enums for Phase correct PWM. */ +typedef enum { + METAL_PWM_PHASE_CORRECT_DISABLE = 0, + METAL_PWM_PHASE_CORRECT_ENABLE = 1, +} metal_pwm_phase_correct_t; + +/*! @brief Enums for Interrupts enable/disable. */ +typedef enum { + METAL_PWM_INTERRUPT_DISABLE = 0, + METAL_PWM_INTERRUPT_ENABLE = 1, +} metal_pwm_interrupt_t; + +struct metal_pwm; + +/*! @brief vtable for PWM. */ +struct metal_pwm_vtable { + int (*enable)(struct metal_pwm *pwm); + int (*disable)(struct metal_pwm *pwm); + int (*set_freq)(struct metal_pwm *pwm, unsigned int idx, unsigned int freq); + int (*set_duty)(struct metal_pwm *pwm, unsigned int idx, unsigned int duty, + metal_pwm_phase_correct_t phase_corr); + unsigned int (*get_duty)(struct metal_pwm *pwm, unsigned int idx); + unsigned int (*get_freq)(struct metal_pwm *pwm, unsigned int idx); + int (*trigger)(struct metal_pwm *pwm, unsigned int idx, + metal_pwm_run_mode_t mode); + int (*stop)(struct metal_pwm *pwm, unsigned int idx); + int (*cfg_interrupt)(struct metal_pwm *pwm, metal_pwm_interrupt_t flag); + int (*clr_interrupt)(struct metal_pwm *pwm, unsigned int idx); + struct metal_interrupt *(*get_interrupt_controller)(struct metal_pwm *pwm); + int (*get_interrupt_id)(struct metal_pwm *pwm, unsigned int idx); +}; + +/*! @brief A handle for a PWM device. */ +struct metal_pwm { + const struct metal_pwm_vtable *vtable; +}; + +/*! @brief Gets a PWM device handle. + * @param device_num The index of the desired PWM device. + * @return A handle to the PWM device, or NULL if the device does not exist.*/ +struct metal_pwm *metal_pwm_get_device(unsigned int device_num); + +/*! @brief Enables PWM operation. + * @param pwm The handle for the PWM device to initialize. + * @return 0 If no error.*/ +inline int metal_pwm_enable(struct metal_pwm *pwm) { + return pwm->vtable->enable(pwm); +} + +/*! @brief Disables PWM operation. + * @param pwm The handle for the PWM device to be disabled. + * @return 0 If no error.*/ +inline int metal_pwm_disable(struct metal_pwm *pwm) { + return pwm->vtable->disable(pwm); +} + +/*! @brief Sets frequency in Hz for a given PWM instance. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @param freq PWM frequency in Hz. + * @return 0 If no error.*/ +inline int metal_pwm_set_freq(struct metal_pwm *pwm, unsigned int idx, + unsigned int freq) { + return pwm->vtable->set_freq(pwm, idx, freq); +} + +/*! @brief Sets duty cycle in percent values [0 - 100] for a given PWM instance. + * Phase correct mode provides center aligned PWM waveform output. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @param duty PWM duty cycle value. + * @param phase_corr Enable / Disable phase correct mode. + * @return 0 If no error.*/ +inline int metal_pwm_set_duty(struct metal_pwm *pwm, unsigned int idx, + unsigned int duty, + metal_pwm_phase_correct_t phase_corr) { + return pwm->vtable->set_duty(pwm, idx, duty, phase_corr); +} + +/*! @brief Gets duty cycle in percent values [0 - 100] for a given PWM instance. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return PWM duty cycle value.*/ +inline unsigned int metal_pwm_get_duty(struct metal_pwm *pwm, + unsigned int idx) { + return pwm->vtable->get_duty(pwm, idx); +} + +/*! @brief Gets frequency in Hz for a given PWM instance. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return PWM frequency in Hz.*/ +inline unsigned int metal_pwm_get_freq(struct metal_pwm *pwm, + unsigned int idx) { + return pwm->vtable->get_freq(pwm, idx); +} + +/*! @brief Starts a PWM instance in selected run mode (continuous/one shot). + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return 0 If no error.*/ +inline int metal_pwm_trigger(struct metal_pwm *pwm, unsigned int idx, + metal_pwm_run_mode_t mode) { + return pwm->vtable->trigger(pwm, idx, mode); +} + +/*! @brief Stops a running PWM instance in continuous mode. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return 0 If no error.*/ +inline int metal_pwm_stop(struct metal_pwm *pwm, unsigned int idx) { + return pwm->vtable->stop(pwm, idx); +} + +/*! @brief Enable or Disable PWM interrupts. + * @param pwm PWM device handle. + * @param flag PWM interrupt enable flag. + * @return 0 If no error.*/ +inline int metal_pwm_cfg_interrupt(struct metal_pwm *pwm, + metal_pwm_interrupt_t flag) { + return pwm->vtable->cfg_interrupt(pwm, flag); +} + +/*! @brief Clears pending interrupt flags. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return 0 If no error.*/ +inline int metal_pwm_clr_interrupt(struct metal_pwm *pwm, unsigned int idx) { + return pwm->vtable->clr_interrupt(pwm, idx); +} + +/*! @brief Get the interrupt controller of the PWM peripheral. + * The interrupt controller must be initialized before any interrupts can be + * registered or enabled with it. + * @param pwm PWM device handle. + * @return The handle for the PWM interrupt controller.*/ +inline struct metal_interrupt * +metal_pwm_interrupt_controller(struct metal_pwm *pwm) { + return pwm->vtable->get_interrupt_controller(pwm); +} + +/*! @brief Get the interrupt ID of the PWM peripheral. + * @param pwm PWM device handle. + * @param idx PWM channel id. + * @return The PWM interrupt id.*/ +inline int metal_pwm_get_interrupt_id(struct metal_pwm *pwm, unsigned int idx) { + return pwm->vtable->get_interrupt_id(pwm, idx); +} + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/rtc.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/rtc.h index 2e742ea38..e1b798268 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/rtc.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/rtc.h @@ -23,12 +23,16 @@ enum metal_rtc_run_option { struct metal_rtc_vtable { uint64_t (*get_rate)(const struct metal_rtc *const rtc); - uint64_t (*set_rate)(const struct metal_rtc *const rtc, const uint64_t rate); + uint64_t (*set_rate)(const struct metal_rtc *const rtc, + const uint64_t rate); uint64_t (*get_compare)(const struct metal_rtc *const rtc); - uint64_t (*set_compare)(const struct metal_rtc *const rtc, const uint64_t compare); + uint64_t (*set_compare)(const struct metal_rtc *const rtc, + const uint64_t compare); uint64_t (*get_count)(const struct metal_rtc *const rtc); - uint64_t (*set_count)(const struct metal_rtc *const rtc, const uint64_t count); - int (*run)(const struct metal_rtc *const rtc, const enum metal_rtc_run_option option); + uint64_t (*set_count)(const struct metal_rtc *const rtc, + const uint64_t count); + int (*run)(const struct metal_rtc *const rtc, + const enum metal_rtc_run_option option); struct metal_interrupt *(*get_interrupt)(const struct metal_rtc *const rtc); int (*get_interrupt_id)(const struct metal_rtc *const rtc); }; @@ -52,7 +56,8 @@ inline uint64_t metal_rtc_get_rate(const struct metal_rtc *const rtc) { * @brief Set (if possible) the rate of the RTC * @return The new rate of the RTC (not guaranteed to be the same as requested) */ -inline uint64_t metal_rtc_set_rate(const struct metal_rtc *const rtc, const uint64_t rate) { +inline uint64_t metal_rtc_set_rate(const struct metal_rtc *const rtc, + const uint64_t rate) { return rtc->vtable->set_rate(rtc, rate); } @@ -66,12 +71,14 @@ inline uint64_t metal_rtc_get_compare(const struct metal_rtc *const rtc) { /*! * @brief Set the compare value of the RTC - * @return The set compare value (not guaranteed to be exactly the requested value) + * @return The set compare value (not guaranteed to be exactly the requested + * value) * - * The RTC device might impose limits on the maximum compare value or the granularity - * of the compare value. + * The RTC device might impose limits on the maximum compare value or the + * granularity of the compare value. */ -inline uint64_t metal_rtc_set_compare(const struct metal_rtc *const rtc, const uint64_t compare) { +inline uint64_t metal_rtc_set_compare(const struct metal_rtc *const rtc, + const uint64_t compare) { return rtc->vtable->set_compare(rtc, compare); } @@ -85,11 +92,13 @@ inline uint64_t metal_rtc_get_count(const struct metal_rtc *const rtc) { /*! * @brief Set the current count of the RTC - * @return The set value of the count (not guaranteed to be exactly the requested value) + * @return The set value of the count (not guaranteed to be exactly the + * requested value) * * The RTC device might impose limits on the maximum value of the count */ -inline uint64_t metal_rtc_set_count(const struct metal_rtc *const rtc, const uint64_t count) { +inline uint64_t metal_rtc_set_count(const struct metal_rtc *const rtc, + const uint64_t count) { return rtc->vtable->set_count(rtc, count); } @@ -97,7 +106,8 @@ inline uint64_t metal_rtc_set_count(const struct metal_rtc *const rtc, const uin * @brief Start or stop the RTC * @return 0 if the RTC was successfully started/stopped */ -inline int metal_rtc_run(const struct metal_rtc *const rtc, const enum metal_rtc_run_option option) { +inline int metal_rtc_run(const struct metal_rtc *const rtc, + const enum metal_rtc_run_option option) { return rtc->vtable->run(rtc, option); } @@ -105,7 +115,8 @@ inline int metal_rtc_run(const struct metal_rtc *const rtc, const enum metal_rtc * @brief Get the interrupt handle for the RTC compare * @return The interrupt handle */ -inline struct metal_interrupt *metal_rtc_get_interrupt(const struct metal_rtc *const rtc) { +inline struct metal_interrupt * +metal_rtc_get_interrupt(const struct metal_rtc *const rtc) { return rtc->vtable->get_interrupt(rtc); } @@ -124,4 +135,3 @@ inline int metal_rtc_get_interrupt_id(const struct metal_rtc *const rtc) { struct metal_rtc *metal_rtc_get_device(int index); #endif - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/scrub.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/scrub.h new file mode 100644 index 000000000..51683cc76 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/scrub.h @@ -0,0 +1,13 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#ifndef METAL__SCRUB_H +#define METAL__SCRUB_H + +/*! @brief Writes specified memory region with zeros. + * @param address Start memory address for zero-scrub. + * @param size Memory region size in bytes. + * @return None.*/ +void metal_mem_scrub(void *address, int size); + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/shutdown.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/shutdown.h index 8d4020b5c..7a43437b7 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/shutdown.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/shutdown.h @@ -12,15 +12,20 @@ struct __metal_shutdown; struct __metal_shutdown_vtable { - void (*exit)(const struct __metal_shutdown *sd, int code) __attribute__((noreturn)); + void (*exit)(const struct __metal_shutdown *sd, int code) + __attribute__((noreturn)); }; struct __metal_shutdown { const struct __metal_shutdown_vtable *vtable; }; -__inline__ void __metal_shutdown_exit(const struct __metal_shutdown *sd, int code) __attribute__((noreturn)); -__inline__ void __metal_shutdown_exit(const struct __metal_shutdown *sd, int code) { sd->vtable->exit(sd, code); } +__inline__ void __metal_shutdown_exit(const struct __metal_shutdown *sd, + int code) __attribute__((noreturn)); +__inline__ void __metal_shutdown_exit(const struct __metal_shutdown *sd, + int code) { + sd->vtable->exit(sd, code); +} /*! * @brief The public METAL shutdown interface diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/spi.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/spi.h index 635e3c151..7e4b04ae2 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/spi.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/spi.h @@ -9,11 +9,7 @@ struct metal_spi; /*! @brief The configuration for a SPI transfer */ struct metal_spi_config { /*! @brief The protocol for the SPI transfer */ - enum { - METAL_SPI_SINGLE, - METAL_SPI_DUAL, - METAL_SPI_QUAD - } protocol; + enum { METAL_SPI_SINGLE, METAL_SPI_DUAL, METAL_SPI_QUAD } protocol; /*! @brief The polarity of the SPI transfer, equivalent to CPOL */ unsigned int polarity : 1; @@ -41,7 +37,8 @@ struct metal_spi_config { struct metal_spi_vtable { void (*init)(struct metal_spi *spi, int baud_rate); - int (*transfer)(struct metal_spi *spi, struct metal_spi_config *config, size_t len, char *tx_buf, char *rx_buf); + int (*transfer)(struct metal_spi *spi, struct metal_spi_config *config, + size_t len, char *tx_buf, char *rx_buf); int (*get_baud_rate)(struct metal_spi *spi); int (*set_baud_rate)(struct metal_spi *spi, int baud_rate); }; @@ -60,17 +57,23 @@ struct metal_spi *metal_spi_get_device(unsigned int device_num); * @param spi The handle for the SPI device to initialize * @param baud_rate The baud rate to set the SPI device to */ -__inline__ void metal_spi_init(struct metal_spi *spi, int baud_rate) { spi->vtable->init(spi, baud_rate); } +__inline__ void metal_spi_init(struct metal_spi *spi, int baud_rate) { + spi->vtable->init(spi, baud_rate); +} /*! @brief Perform a SPI transfer * @param spi The handle for the SPI device to perform the transfer * @param config The configuration for the SPI transfer. * @param len The number of bytes to transfer - * @param tx_buf The buffer to send over the SPI bus. Must be len bytes long. If NULL, the SPI will transfer the value 0. - * @param rx_buf The buffer to receive data into. Must be len bytes long. If NULL, the SPI will ignore received bytes. + * @param tx_buf The buffer to send over the SPI bus. Must be len bytes long. If + * NULL, the SPI will transfer the value 0. + * @param rx_buf The buffer to receive data into. Must be len bytes long. If + * NULL, the SPI will ignore received bytes. * @return 0 if the transfer succeeds */ -__inline__ int metal_spi_transfer(struct metal_spi *spi, struct metal_spi_config *config, size_t len, char *tx_buf, char *rx_buf) { +__inline__ int metal_spi_transfer(struct metal_spi *spi, + struct metal_spi_config *config, size_t len, + char *tx_buf, char *rx_buf) { return spi->vtable->transfer(spi, config, len, tx_buf, rx_buf); } @@ -78,13 +81,17 @@ __inline__ int metal_spi_transfer(struct metal_spi *spi, struct metal_spi_config * @param spi The handle for the SPI device * @return The baud rate in Hz */ -__inline__ int metal_spi_get_baud_rate(struct metal_spi *spi) { return spi->vtable->get_baud_rate(spi); } +__inline__ int metal_spi_get_baud_rate(struct metal_spi *spi) { + return spi->vtable->get_baud_rate(spi); +} /*! @brief Set the current baud rate of the SPI device * @param spi The handle for the SPI device * @param baud_rate The desired baud rate of the SPI device * @return 0 if the baud rate is successfully changed */ -__inline__ int metal_spi_set_baud_rate(struct metal_spi *spi, int baud_rate) { return spi->vtable->set_baud_rate(spi, baud_rate); } +__inline__ int metal_spi_set_baud_rate(struct metal_spi *spi, int baud_rate) { + return spi->vtable->set_baud_rate(spi, baud_rate); +} #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/switch.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/switch.h index 61f0efe56..695b21ae3 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/switch.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/switch.h @@ -15,7 +15,7 @@ struct metal_switch; struct metal_switch_vtable { int (*switch_exist)(struct metal_switch *sw, char *label); - struct metal_interrupt* (*interrupt_controller)(struct metal_switch *sw); + struct metal_interrupt *(*interrupt_controller)(struct metal_switch *sw); int (*get_interrupt_id)(struct metal_switch *sw); }; @@ -29,23 +29,28 @@ struct metal_switch { /*! * @brief Get a handle for a switch * @param label The DeviceTree label for the desired switch - * @return A handle to the switch, or NULL if none is found for the requested label + * @return A handle to the switch, or NULL if none is found for the requested + * label */ -struct metal_switch* metal_switch_get(char *label); +struct metal_switch *metal_switch_get(char *label); /*! * @brief Get the interrupt controller for a switch * @param sw The handle for the switch * @return The interrupt controller handle */ -__inline__ struct metal_interrupt* - metal_switch_interrupt_controller(struct metal_switch *sw) { return sw->vtable->interrupt_controller(sw); } +__inline__ struct metal_interrupt * +metal_switch_interrupt_controller(struct metal_switch *sw) { + return sw->vtable->interrupt_controller(sw); +} /*! * @brief Get the interrupt id for a switch * @param sw The handle for the switch * @return The interrupt ID for the switch */ -__inline__ int metal_switch_get_interrupt_id(struct metal_switch *sw) { return sw->vtable->get_interrupt_id(sw); } +__inline__ int metal_switch_get_interrupt_id(struct metal_switch *sw) { + return sw->vtable->get_interrupt_id(sw); +} #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/time.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/time.h index 5c33b6f1b..a5a880f0d 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/time.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/time.h @@ -5,6 +5,9 @@ #define METAL__TIME_H #include <time.h> +#ifndef __SEGGER_LIBC__ +#include <sys/time.h> +#endif /*! * @file time.h diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/timer.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/timer.h index eeae1f60b..5d5132de5 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/timer.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/timer.h @@ -23,9 +23,10 @@ int metal_timer_get_cyclecount(int hartid, unsigned long long *cyclecount); * @param timebase The variable to hold the value * @return 0 upon success */ -int metal_timer_get_timebase_frequency(int hartid, unsigned long long *timebase); +int metal_timer_get_timebase_frequency(int hartid, + unsigned long long *timebase); -/*! +/*! * @brief Set the machine timer tick interval in seconds * @param hartid The hart ID to read the timebase of * @param second The number of seconds to set the tick interval to diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/tty.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/tty.h index fe4c000db..5d41783ae 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/tty.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/tty.h @@ -15,29 +15,12 @@ * Write a character to the default output device, which for most * targets is the UART serial port. * - * putc() does CR/LF mapping. - * putc_raw() does not. - * * @param c The character to write to the terminal * @return 0 on success, or -1 on failure. */ int metal_tty_putc(int c); /*! - * @brief Write a raw character to the default output device - * - * Write a character to the default output device, which for most - * targets is the UART serial port. - * - * putc() does CR/LF mapping. - * putc_raw() does not. - * - * @param c The character to write to the terminal - * @return 0 on success, or -1 on failure. - */ -int metal_tty_putc_raw(int c); - -/*! * @brief Get a byte from the default output device * * The default output device, is typically the UART serial port. diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/uart.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/uart.h index e9e4d0436..856970ac2 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/uart.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/uart.h @@ -21,8 +21,16 @@ struct metal_uart_vtable { int (*getc)(struct metal_uart *uart, int *c); int (*get_baud_rate)(struct metal_uart *uart); int (*set_baud_rate)(struct metal_uart *uart, int baud_rate); - struct metal_interrupt* (*controller_interrupt)(struct metal_uart *uart); + struct metal_interrupt *(*controller_interrupt)(struct metal_uart *uart); int (*get_interrupt_id)(struct metal_uart *uart); + int (*tx_interrupt_enable)(struct metal_uart *uart); + int (*tx_interrupt_disable)(struct metal_uart *uart); + int (*rx_interrupt_enable)(struct metal_uart *uart); + int (*rx_interrupt_disable)(struct metal_uart *uart); + int (*set_tx_watermark)(struct metal_uart *uart, size_t length); + size_t (*get_tx_watermark)(struct metal_uart *uart); + int (*set_rx_watermark)(struct metal_uart *uart, size_t length); + size_t (*get_rx_watermark)(struct metal_uart *uart); }; /*! @@ -32,16 +40,25 @@ struct metal_uart { const struct metal_uart_vtable *vtable; }; +/*! @brief Get a handle for a UART device + * @param device_num The index of the desired UART device + * @return A handle to the UART device, or NULL if the device does not exist*/ +struct metal_uart *metal_uart_get_device(unsigned int device_num); + /*! * @brief Initialize UART device - - * Initialize the UART device described by the UART handle. This function must be called before any - * other method on the UART can be invoked. It is invalid to initialize a UART more than once. + + * Initialize the UART device described by the UART handle. This function must + be called before any + * other method on the UART can be invoked. It is invalid to initialize a UART + more than once. * * @param uart The UART device handle * @param baud_rate the baud rate to set the UART to */ -__inline__ void metal_uart_init(struct metal_uart *uart, int baud_rate) { uart->vtable->init(uart, baud_rate); } +__inline__ void metal_uart_init(struct metal_uart *uart, int baud_rate) { + uart->vtable->init(uart, baud_rate); +} /*! * @brief Output a character over the UART @@ -49,14 +66,18 @@ __inline__ void metal_uart_init(struct metal_uart *uart, int baud_rate) { uart-> * @param c The character to send over the UART * @return 0 upon success */ -__inline__ int metal_uart_putc(struct metal_uart *uart, int c) { return uart->vtable->putc(uart, c); } +__inline__ int metal_uart_putc(struct metal_uart *uart, int c) { + return uart->vtable->putc(uart, c); +} /*! * @brief Test, determine if tx output is blocked(full/busy) * @param uart The UART device handle * @return 0 not blocked */ -__inline__ int metal_uart_txready(struct metal_uart *uart) { return uart->vtable->txready(uart); } +__inline__ int metal_uart_txready(struct metal_uart *uart) { + return uart->vtable->txready(uart); +} /*! * @brief Read a character sent over the UART @@ -67,14 +88,18 @@ __inline__ int metal_uart_txready(struct metal_uart *uart) { return uart->vtable * If "c == -1" no char was ready. * If "c != -1" then C == byte value (0x00 to 0xff) */ -__inline__ int metal_uart_getc(struct metal_uart *uart, int *c) { return uart->vtable->getc(uart, c); } +__inline__ int metal_uart_getc(struct metal_uart *uart, int *c) { + return uart->vtable->getc(uart, c); +} /*! * @brief Get the baud rate of the UART peripheral * @param uart The UART device handle * @return The current baud rate of the UART */ -__inline__ int metal_uart_get_baud_rate(struct metal_uart *uart) { return uart->vtable->get_baud_rate(uart); } +__inline__ int metal_uart_get_baud_rate(struct metal_uart *uart) { + return uart->vtable->get_baud_rate(uart); +} /*! * @brief Set the baud rate of the UART peripheral @@ -82,7 +107,10 @@ __inline__ int metal_uart_get_baud_rate(struct metal_uart *uart) { return uart-> * @param baud_rate The baud rate to configure * @return the new baud rate of the UART */ -__inline__ int metal_uart_set_baud_rate(struct metal_uart *uart, int baud_rate) { return uart->vtable->set_baud_rate(uart, baud_rate); } +__inline__ int metal_uart_set_baud_rate(struct metal_uart *uart, + int baud_rate) { + return uart->vtable->set_baud_rate(uart, baud_rate); +} /*! * @brief Get the interrupt controller of the UART peripheral @@ -94,13 +122,94 @@ __inline__ int metal_uart_set_baud_rate(struct metal_uart *uart, int baud_rate) * @param uart The UART device handle * @return The handle for the UART interrupt controller */ -__inline__ struct metal_interrupt* metal_uart_interrupt_controller(struct metal_uart *uart) { return uart->vtable->controller_interrupt(uart); } +__inline__ struct metal_interrupt * +metal_uart_interrupt_controller(struct metal_uart *uart) { + return uart->vtable->controller_interrupt(uart); +} /*! * @brief Get the interrupt ID of the UART controller * @param uart The UART device handle * @return The UART interrupt id */ -__inline__ int metal_uart_get_interrupt_id(struct metal_uart *uart) { return uart->vtable->get_interrupt_id(uart); } +__inline__ int metal_uart_get_interrupt_id(struct metal_uart *uart) { + return uart->vtable->get_interrupt_id(uart); +} + +/*! + * @brief Enable the UART transmit interrupt + * @param uart The UART device handle + * @return 0 upon success + */ +__inline__ int metal_uart_transmit_interrupt_enable(struct metal_uart *uart) { + return uart->vtable->tx_interrupt_enable(uart); +} + +/*! + * @brief Disable the UART transmit interrupt + * @param uart The UART device handle + * @return 0 upon success + */ +__inline__ int metal_uart_transmit_interrupt_disable(struct metal_uart *uart) { + return uart->vtable->tx_interrupt_disable(uart); +} + +/*! + * @brief Enable the UART receive interrupt + * @param uart The UART device handle + * @return 0 upon success + */ +__inline__ int metal_uart_receive_interrupt_enable(struct metal_uart *uart) { + return uart->vtable->rx_interrupt_enable(uart); +} + +/*! + * @brief Disable the UART receive interrupt + * @param uart The UART device handle + * @return 0 upon success + */ +__inline__ int metal_uart_receive_interrupt_disable(struct metal_uart *uart) { + return uart->vtable->rx_interrupt_disable(uart); +} + +/*! + * @brief Set the transmit watermark level of the UART controller + * @param uart The UART device handle + * @param level The UART transmit watermark level + * @return 0 upon success + */ +__inline__ int metal_uart_set_transmit_watermark(struct metal_uart *uart, + size_t level) { + return uart->vtable->set_tx_watermark(uart, level); +} + +/*! + * @brief Get the transmit watermark level of the UART controller + * @param uart The UART device handle + * @return The UART transmit watermark level + */ +__inline__ size_t metal_uart_get_transmit_watermark(struct metal_uart *uart) { + return uart->vtable->get_tx_watermark(uart); +} + +/*! + * @brief Set the receive watermark level of the UART controller + * @param uart The UART device handle + * @param level The UART transmit watermark level + * @return 0 upon success + */ +__inline__ int metal_uart_set_receive_watermark(struct metal_uart *uart, + size_t level) { + return uart->vtable->set_rx_watermark(uart, level); +} + +/*! + * @brief Get the receive watermark level of the UART controller + * @param uart The UART device handle + * @return The UART transmit watermark level + */ +__inline__ size_t metal_uart_get_receive_watermark(struct metal_uart *uart) { + return uart->vtable->get_rx_watermark(uart); +} #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/watchdog.h b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/watchdog.h index b5ff48697..2f84d3b49 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/watchdog.h +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/metal/watchdog.h @@ -18,49 +18,54 @@ struct metal_watchdog; * @brief List of watchdog timer count behaviors */ enum metal_watchdog_run_option { - METAL_WATCHDOG_STOP = 0, /*!< Stop the watchdog */ - METAL_WATCHDOG_RUN_ALWAYS, /*!< Run the watchdog continuously, even during sleep */ - METAL_WATCHDOG_RUN_AWAKE, /*!< Run the watchdog only while the CPU is awake */ + METAL_WATCHDOG_STOP = 0, /*!< Stop the watchdog */ + METAL_WATCHDOG_RUN_ALWAYS, /*!< Run the watchdog continuously, even during + sleep */ + METAL_WATCHDOG_RUN_AWAKE, /*!< Run the watchdog only while the CPU is awake + */ }; /*! * @brief List of behaviors when a watchdog triggers */ enum metal_watchdog_result { - METAL_WATCHDOG_NO_RESULT = 0, /*!< When the watchdog triggers, do nothing */ - METAL_WATCHDOG_INTERRUPT, /*!< When the watchdog triggers, fire an interrupt */ - METAL_WATCHDOG_FULL_RESET, /*!< When the watchdog triggers, cause a full system reset */ + METAL_WATCHDOG_NO_RESULT = 0, /*!< When the watchdog triggers, do nothing */ + METAL_WATCHDOG_INTERRUPT, /*!< When the watchdog triggers, fire an interrupt + */ + METAL_WATCHDOG_FULL_RESET, /*!< When the watchdog triggers, cause a full + system reset */ }; - struct metal_watchdog_vtable { - int (*feed)(const struct metal_watchdog *const wdog); - long int (*get_rate)(const struct metal_watchdog *const wdog); - long int (*set_rate)(const struct metal_watchdog *const wdog, const long int rate); - long int (*get_timeout)(const struct metal_watchdog *const wdog); - long int (*set_timeout)(const struct metal_watchdog *const wdog, const long int timeout); - int (*set_result)(const struct metal_watchdog *const wdog, - const enum metal_watchdog_result result); - int (*run)(const struct metal_watchdog *const wdog, - const enum metal_watchdog_run_option option); - struct metal_interrupt *(*get_interrupt)(const struct metal_watchdog *const wdog); - int (*get_interrupt_id)(const struct metal_watchdog *const wdog); - int (*clear_interrupt)(const struct metal_watchdog *const wdog); + int (*feed)(const struct metal_watchdog *const wdog); + long int (*get_rate)(const struct metal_watchdog *const wdog); + long int (*set_rate)(const struct metal_watchdog *const wdog, + const long int rate); + long int (*get_timeout)(const struct metal_watchdog *const wdog); + long int (*set_timeout)(const struct metal_watchdog *const wdog, + const long int timeout); + int (*set_result)(const struct metal_watchdog *const wdog, + const enum metal_watchdog_result result); + int (*run)(const struct metal_watchdog *const wdog, + const enum metal_watchdog_run_option option); + struct metal_interrupt *(*get_interrupt)( + const struct metal_watchdog *const wdog); + int (*get_interrupt_id)(const struct metal_watchdog *const wdog); + int (*clear_interrupt)(const struct metal_watchdog *const wdog); }; /*! * @brief Handle for a Watchdog Timer */ struct metal_watchdog { - const struct metal_watchdog_vtable *vtable; + const struct metal_watchdog_vtable *vtable; }; /*! * @brief Feed the watchdog timer */ -inline int metal_watchdog_feed(const struct metal_watchdog *const wdog) -{ - return wdog->vtable->feed(wdog); +inline int metal_watchdog_feed(const struct metal_watchdog *const wdog) { + return wdog->vtable->feed(wdog); } /*! @@ -68,9 +73,9 @@ inline int metal_watchdog_feed(const struct metal_watchdog *const wdog) * * @return the rate of the watchdog timer */ -inline long int metal_watchdog_get_rate(const struct metal_watchdog *const wdog) -{ - return wdog->vtable->get_rate(wdog); +inline long int +metal_watchdog_get_rate(const struct metal_watchdog *const wdog) { + return wdog->vtable->get_rate(wdog); } /*! @@ -80,9 +85,9 @@ inline long int metal_watchdog_get_rate(const struct metal_watchdog *const wdog) * * @return the new rate of the watchdog timer */ -inline long int metal_watchdog_set_rate(const struct metal_watchdog *const wdog, const long int rate) -{ - return wdog->vtable->set_rate(wdog, rate); +inline long int metal_watchdog_set_rate(const struct metal_watchdog *const wdog, + const long int rate) { + return wdog->vtable->set_rate(wdog, rate); } /*! @@ -90,21 +95,23 @@ inline long int metal_watchdog_set_rate(const struct metal_watchdog *const wdog, * * @return the watchdog timeout value */ -inline long int metal_watchdog_get_timeout(const struct metal_watchdog *const wdog) -{ - return wdog->vtable->get_timeout(wdog); +inline long int +metal_watchdog_get_timeout(const struct metal_watchdog *const wdog) { + return wdog->vtable->get_timeout(wdog); } /*! * @brief Set the timeout of the watchdog timer * - * The set rate will be the minimimum of the requested and maximum supported rates. + * The set rate will be the minimimum of the requested and maximum supported + * rates. * * @return the new watchdog timeout value */ -inline long int metal_watchdog_set_timeout(const struct metal_watchdog *const wdog, const long int timeout) -{ - return wdog->vtable->set_timeout(wdog, timeout); +inline long int +metal_watchdog_set_timeout(const struct metal_watchdog *const wdog, + const long int timeout) { + return wdog->vtable->set_timeout(wdog, timeout); } /*! @@ -113,9 +120,8 @@ inline long int metal_watchdog_set_timeout(const struct metal_watchdog *const wd * @return 0 if the requested result behavior is supported */ inline int metal_watchdog_set_result(const struct metal_watchdog *const wdog, - const enum metal_watchdog_result result) -{ - return wdog->vtable->set_result(wdog, result); + const enum metal_watchdog_result result) { + return wdog->vtable->set_result(wdog, result); } /*! @@ -126,33 +132,32 @@ inline int metal_watchdog_set_result(const struct metal_watchdog *const wdog, * @return 0 if the watchdog was successfully started/stopped */ inline int metal_watchdog_run(const struct metal_watchdog *const wdog, - const enum metal_watchdog_run_option option) -{ - return wdog->vtable->run(wdog, option); + const enum metal_watchdog_run_option option) { + return wdog->vtable->run(wdog, option); } /*! * @brief Get the interrupt controller for the watchdog interrupt */ -inline struct metal_interrupt *metal_watchdog_get_interrupt(const struct metal_watchdog *const wdog) -{ - return wdog->vtable->get_interrupt(wdog); +inline struct metal_interrupt * +metal_watchdog_get_interrupt(const struct metal_watchdog *const wdog) { + return wdog->vtable->get_interrupt(wdog); } /*! * @Brief Get the interrupt id for the watchdog interrupt */ -inline int metal_watchdog_get_interrupt_id(const struct metal_watchdog *const wdog) -{ - return wdog->vtable->get_interrupt_id(wdog); +inline int +metal_watchdog_get_interrupt_id(const struct metal_watchdog *const wdog) { + return wdog->vtable->get_interrupt_id(wdog); } /*! * @brief Clear the watchdog interrupt */ -inline int metal_watchdog_clear_interrupt(const struct metal_watchdog *const wdog) -{ - return wdog->vtable->clear_interrupt(wdog); +inline int +metal_watchdog_clear_interrupt(const struct metal_watchdog *const wdog) { + return wdog->vtable->clear_interrupt(wdog); } /*! diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/missing b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/missing new file mode 100755 index 000000000..f62bbae30 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/missing @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2013-10-28.13; # UTC + +# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to <bug-automake@gnu.org>." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=http://www.perl.org/ +flex_URL=http://flex.sourceforge.net/ +gnu_software_URL=http://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/scripts/check-format b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/scripts/check-format new file mode 100755 index 000000000..1447fe43c --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/scripts/check-format @@ -0,0 +1,19 @@ +#!/bin/sh + +CLANG_FORMAT=clang-format-6.0 + +TOP_LEVEL=$(git rev-parse --show-toplevel) + +# Run clang-format in-place on all *.c and *.h files in the repository +cd $TOP_LEVEL && $CLANG_FORMAT -i $(git ls-tree -r HEAD --name-only | grep -E "^\S+\.[ch]*$") + +DIFF=$(git diff) + +if [ "${DIFF}" != "" ] ; then + echo "Formatting errors found! Please run ./scripts/format or apply the" + echo "following diff to fix them!" + echo "" + echo "${DIFF}" + exit 1 +fi + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/scripts/format b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/scripts/format new file mode 100755 index 000000000..a07c363da --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/scripts/format @@ -0,0 +1,8 @@ +#!/bin/sh + +CLANG_FORMAT=clang-format-6.0 + +TOP_LEVEL=$(git rev-parse --show-toplevel) + +# Run clang-format in-place on all *.c and *.h files in the repository +cd $TOP_LEVEL && $CLANG_FORMAT -i $(git ls-tree -r HEAD --name-only | grep -E "^\S+\.[ch]$") diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/scripts/git-version b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/scripts/git-version new file mode 100755 index 000000000..de0529b9d --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/scripts/git-version @@ -0,0 +1,21 @@ +#!/bin/bash + +version='v0.1.2' + +if test -d .git +then + gv=`git describe` + if [[ "$?" == "0" ]] + then + if [[ "$(echo "${gv}" | cut -d'-' -f1)" != "$version" ]] + then + echo "$0 has mismatched version" >&2 + echo "${gv}-ERROR" + exit 1 + fi + + version="$(echo ${gv} | cut -c2-)" + fi +fi + +echo "${version}" diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/atomic.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/atomic.c new file mode 100644 index 000000000..326568e37 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/atomic.c @@ -0,0 +1,19 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include <metal/atomic.h> + +extern __inline__ int32_t metal_atomic_available(void); +extern __inline__ int32_t metal_atomic_add(metal_atomic_t *a, + int32_t increment); +extern __inline__ int32_t metal_atomic_and(metal_atomic_t *a, int32_t mask); +extern __inline__ int32_t metal_atomic_or(metal_atomic_t *a, int32_t mask); +extern __inline__ int32_t metal_atomic_swap(metal_atomic_t *a, + int32_t new_value); +extern __inline__ int32_t metal_atomic_xor(metal_atomic_t *a, int32_t mask); +extern __inline__ int32_t metal_atomic_max(metal_atomic_t *a, int32_t compare); +extern __inline__ uint32_t metal_atomic_max_u(metal_atomic_t *a, + uint32_t compare); +extern __inline__ int32_t metal_atomic_min(metal_atomic_t *a, int32_t compare); +extern __inline__ uint32_t metal_atomic_min_u(metal_atomic_t *a, + uint32_t compare); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/button.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/button.c index efd645334..5831945c2 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/button.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/button.c @@ -4,8 +4,7 @@ #include <metal/button.h> #include <metal/machine.h> -struct metal_button* metal_button_get (char *label) -{ +struct metal_button *metal_button_get(char *label) { int i; struct metal_button *button; @@ -14,7 +13,7 @@ struct metal_button* metal_button_get (char *label) } for (i = 0; i < __METAL_DT_MAX_BUTTONS; i++) { - button = (struct metal_button*)__metal_button_table[i]; + button = (struct metal_button *)__metal_button_table[i]; if (button->vtable->button_exist(button, label)) { return button; } @@ -22,6 +21,7 @@ struct metal_button* metal_button_get (char *label) return NULL; } -extern __inline__ struct metal_interrupt* - metal_button_interrupt_controller(struct metal_button *button); -extern __inline__ int metal_button_get_interrupt_id(struct metal_button *button); +extern __inline__ struct metal_interrupt * +metal_button_interrupt_controller(struct metal_button *button); +extern __inline__ int +metal_button_get_interrupt_id(struct metal_button *button); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/cache.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/cache.c index 024ba52ad..09c270e47 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/cache.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/cache.c @@ -1,19 +1,51 @@ -/* Copyright 2018 SiFive, Inc */ +/* Copyright 2020 SiFive, Inc */ /* SPDX-License-Identifier: Apache-2.0 */ #include <metal/cache.h> #include <metal/machine.h> +/* Macros to generate driver prefix string */ +#ifdef METAL_CACHE_DRIVER_PREFIX +#define METAL_FUNC_STR(a, b) a##_##b +#define METAL_FUNC_STR_(a, b) METAL_FUNC_STR(a, b) +#define METAL_FUNC(x) METAL_FUNC_STR_(METAL_CACHE_DRIVER_PREFIX, x) +#endif + extern __inline__ void metal_cache_init(struct metal_cache *cache, int ways); extern __inline__ int metal_cache_get_enabled_ways(struct metal_cache *cache); -extern __inline__ int metal_cache_set_enabled_ways(struct metal_cache *cache, int ways); +extern __inline__ int metal_cache_set_enabled_ways(struct metal_cache *cache, + int ways); + +int metal_l2cache_init(void) { +#ifdef METAL_CACHE_DRIVER_PREFIX + return METAL_FUNC(init)(); +#else + return -1; +#endif +} + +int metal_l2cache_get_enabled_ways(void) { +#ifdef METAL_CACHE_DRIVER_PREFIX + return METAL_FUNC(get_enabled_ways)(); +#else + return -1; +#endif +} + +int metal_l2cache_set_enabled_ways(int ways) { +#ifdef METAL_CACHE_DRIVER_PREFIX + return METAL_FUNC(set_enabled_ways)(ways); +#else + return -1; +#endif +} int metal_dcache_l1_available(int hartid) { switch (hartid) { case 0: #ifdef __METAL_CPU_0_DCACHE_HANDLE return __METAL_CPU_0_DCACHE_HANDLE; -#endif +#endif break; case 1: #ifdef __METAL_CPU_1_DCACHE_HANDLE @@ -112,76 +144,78 @@ int metal_icache_l1_available(int hartid) { /*! * @brief CFlush.D.L1 instruction is a custom instruction implemented as a - * state machine in L1 Data Cache (D$) with funct3=0, (for core with data caches) - * It is an I type: .insn i opcode, func3, rd, rs1, simm12(signed immediate 12bs) - * 31 28 27 24 23 20 19 16 15 12 11 8 7 4 3 0 + * state machine in L1 Data Cache (D$) with funct3=0, (for core with data + * caches) It is an I type: .insn i opcode, func3, rd, rs1, simm12(signed + * immediate 12bs) + * 31 28 27 24 23 20 19 16 15 12 11 8 7 4 3 0 * |--------|--------|--------|--------|--------|--------|--------|--------| * +-------------+------------+----------+------+--------+-----------------+ * |sign immediate12b (simm12)| rs1 | func3| rd | opcode | * |-1-1-1-1 -1-1-0-0 -0-0-0-0|-x-x-x-x-x|0-0-0-|-0-0-0-0|-0-1-1-1 -0-0-1-1| * +--------------------------+----------+------+--------+-----------------+ - * 31 -0x40 20 15 0 12 x0 7 0x73 0 + * 31 -0x40 20 15 0 12 x0 7 0x73 0 * +--------+--------+--------+----------+------+--------+--------+--------+ * where, - * rs1 = 0x0, CFLUSH.D.L1 writes back and invalidates all lines in the L1 D$ + * rs1 = x0, CFLUSH.D.L1 writes back and invalidates all lines in the L1 D$ * rs1 != x0, CFLUSH.D.L1 writes back and invalidates the L1 D$ line containing * the virtual address in integer register rs1. */ -void metal_dcache_l1_flush(int hartid, uintptr_t address) -{ - if (metal_dcache_l1_available(hartid)) { - // Using ‘.insn’ pseudo directive: '.insn i opcode, func3, rd, rs1, simm12' - __asm__ __volatile__ (".insn i 0x73, 0, x0, %0, -0x40" : : "r" (address)); - __asm__ __volatile__ ("fence.i"); // FENCE +void metal_dcache_l1_flush(int hartid, uintptr_t address) { + if (metal_dcache_l1_available(hartid)) { + if (address) { + uintptr_t ms1 = 0, ms2 = 0; + __asm__ __volatile__("csrr %0, mtvec \n\t" + "la %1, 1f \n\t" + "csrw mtvec, %1 \n\t" + ".insn i 0x73, 0, x0, %2, -0x40 \n\t" + ".align 2\n\t" + "1: \n\t" + "csrw mtvec, %0 \n\t" + : "+r"(ms1), "+r"(ms2) + : "r"(address)); + // Using ‘.insn’ pseudo directive: + // '.insn i opcode, func3, rd, rs1, simm12' + } else { + __asm__ __volatile__(".word 0xfc000073" : : : "memory"); + } } } /*! * @brief CDiscard.D.L1 instruction is a custom instruction implemented as a - * state machine in L1 Data Cache (D$) with funct3=0, (for core with data caches) - * It is an I type: .insn i opcode, func3, rd, rs1, simm12(signed immediate 12bs) - * 31 28 27 24 23 20 19 16 15 12 11 8 7 4 3 0 + * state machine in L1 Data Cache (D$) with funct3=0, (for core with data + * caches) It is an I type: .insn i opcode, func3, rd, rs1, simm12(signed + * immediate 12bs) + * 31 28 27 24 23 20 19 16 15 12 11 8 7 4 3 0 * |--------|--------|--------|--------|--------|--------|--------|--------| * +-------------+------------+----------+------+--------+-----------------+ * |sign immediate12b (simm12)| rs1 | func3| rd | opcode | - * |-1-1-1-1 -1-1-0-0 -0-0-0-0|-x-x-x-x-x|0-0-0-|-0-0-0-0|-0-1-1-1 -0-0-1-1| + * |-1-1-1-1 -1-1-0-0 -0-0-1-0|-x-x-x-x-x|0-0-0-|-0-0-0-0|-0-1-1-1 -0-0-1-1| * +--------------------------+----------+------+--------+-----------------+ - * 31 -0x3E 20 15 0 12 x0 7 0x73 0 + * 31 -0x3E 20 15 0 12 x0 7 0x73 0 * +--------+--------+--------+----------+------+--------+--------+--------+ * where, - * rs1 = 0x0, CDISCARD.D.L1 invalidates all lines in the L1 D$ with no writes back. - * rs1 != x0, CDISCARD.D.L1 invalidates the L1 D$ line containing the virtual address - * in integer register rs1, with no writes back. - */ -void metal_dcache_l1_discard(int hartid, uintptr_t address) -{ - if (metal_dcache_l1_available(hartid)) { - // Using ‘.insn’ pseudo directive: '.insn i opcode, func3, rd, rs1, simm12' - __asm__ __volatile__ (".insn i 0x73, 0, x0, %0, -0x3E" : : "r" (address)); - __asm__ __volatile__ ("fence.i"); // FENCE - } -} - -/*! - * @brief CFlush.I.L1 instruction is a custom instruction implemented as a state - * machine in L1 Instruction Cache (I$) with funct3=0, (for core with data caches) - * It is an I type: .insn i opcode, func3, rd, rs1, simm12(signed immediate 12bs) - * 31 28 27 24 23 20 19 16 15 12 11 8 7 4 3 0 - * |--------|--------|--------|--------|--------|--------|--------|--------| - * +-------------+------------+----------+------+--------+-----------------+ - * |sign immediate12b (simm12)| rs1 | func3| rd | opcode | - * |-1-1-1-1 -1-1-0-0 -0-0-0-0|-0-0-0-0-0|0-0-0-|-0-0-0-0|-0-1-1-1 -0-0-1-1| - * +--------------------------+----------+------+--------+-----------------+ - * 31 -0x3F 20 15 0 12 x0 7 0x73 0 - * +--------+--------+--------+----------+------+--------+--------+--------+ - * CFLUSH.I.L1 invalidates all lines in the L1 I$. + * rs1 = x0, CDISCARD.D.L1 invalidates all lines in the L1 D$ with no writes + * back. rs1 != x0, CDISCARD.D.L1 invalidates the L1 D$ line containing the + * virtual address in integer register rs1, with no writes back. */ -void metal_icache_l1_flush(int hartid) -{ - if (metal_icache_l1_available(hartid)) { - // Using ‘.insn’ pseudo directive: '.insn i opcode, func3, rd, rs1, simm12' - __asm__ __volatile__ (".insn i 0x73, 0, x0, x0, -0x3F" : : ); - __asm__ __volatile__ ("fence.i"); // FENCE +void metal_dcache_l1_discard(int hartid, uintptr_t address) { + if (metal_dcache_l1_available(hartid)) { + if (address) { + uintptr_t ms1 = 0, ms2 = 0; + __asm__ __volatile__("csrr %0, mtvec \n\t" + "la %1, 1f \n\t" + "csrw mtvec, %1 \n\t" + ".insn i 0x73, 0, x0, %2, -0x3E \n\t" + ".align 2\n\t" + "1: \n\t" + "csrw mtvec, %0 \n\t" + : "+r"(ms1), "+r"(ms2) + : "r"(address)); + // Using ‘.insn’ pseudo directive: + // '.insn i opcode, func3, rd, rs1, simm12' + } else { + __asm__ __volatile__(".word 0xfc200073" : : : "memory"); + } } } - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/clock.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/clock.c index cc3f4dcf3..a2a11231c 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/clock.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/clock.c @@ -3,10 +3,18 @@ #include <metal/clock.h> -extern __inline__ void _metal_clock_call_all_callbacks(const metal_clock_callback *const list); -extern __inline__ metal_clock_callback *_metal_clock_append_to_callbacks(metal_clock_callback *list, metal_clock_callback *const cb); +extern __inline__ void +_metal_clock_call_all_callbacks(const metal_clock_callback *const list); +extern __inline__ metal_clock_callback * +_metal_clock_append_to_callbacks(metal_clock_callback *list, + metal_clock_callback *const cb); extern __inline__ long metal_clock_get_rate_hz(const struct metal_clock *clk); -extern __inline__ long metal_clock_set_rate_hz(struct metal_clock *clk, long hz); -extern __inline__ void metal_clock_register_post_rate_change_callback(struct metal_clock *clk, metal_clock_callback *cb); -extern __inline__ void metal_clock_register_pre_rate_change_callback(struct metal_clock *clk, metal_clock_callback *cb); +extern __inline__ long metal_clock_set_rate_hz(struct metal_clock *clk, + long hz); +extern __inline__ void +metal_clock_register_post_rate_change_callback(struct metal_clock *clk, + metal_clock_callback *cb); +extern __inline__ void +metal_clock_register_pre_rate_change_callback(struct metal_clock *clk, + metal_clock_callback *cb); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/cpu.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/cpu.c index 25fda5de7..8e28c8979 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/cpu.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/cpu.c @@ -4,56 +4,66 @@ #include <metal/cpu.h> #include <metal/machine.h> -struct metal_cpu* metal_cpu_get(unsigned int hartid) -{ +struct metal_cpu *metal_cpu_get(unsigned int hartid) { if (hartid < __METAL_DT_MAX_HARTS) { return (struct metal_cpu *)__metal_cpu_table[hartid]; - } + } return NULL; } -int metal_cpu_get_current_hartid() -{ +int metal_cpu_get_current_hartid() { #ifdef __riscv int mhartid; - __asm__ volatile("csrr %0, mhartid" : "=r" (mhartid)); + __asm__ volatile("csrr %0, mhartid" : "=r"(mhartid)); return mhartid; #endif } -int metal_cpu_get_num_harts() -{ - return __METAL_DT_MAX_HARTS; -} +int metal_cpu_get_num_harts() { return __METAL_DT_MAX_HARTS; } extern __inline__ unsigned long long metal_cpu_get_timer(struct metal_cpu *cpu); -extern __inline__ unsigned long long metal_cpu_get_timebase(struct metal_cpu *cpu); +extern __inline__ unsigned long long +metal_cpu_get_timebase(struct metal_cpu *cpu); extern __inline__ unsigned long long metal_cpu_get_mtime(struct metal_cpu *cpu); -extern __inline__ int metal_cpu_set_mtimecmp(struct metal_cpu *cpu, unsigned long long time); +extern __inline__ int metal_cpu_set_mtimecmp(struct metal_cpu *cpu, + unsigned long long time); -extern __inline__ struct metal_interrupt* metal_cpu_timer_interrupt_controller(struct metal_cpu *cpu); +extern __inline__ struct metal_interrupt * +metal_cpu_timer_interrupt_controller(struct metal_cpu *cpu); extern __inline__ int metal_cpu_timer_get_interrupt_id(struct metal_cpu *cpu); -extern __inline__ struct metal_interrupt* metal_cpu_software_interrupt_controller(struct metal_cpu *cpu); +extern __inline__ struct metal_interrupt * +metal_cpu_software_interrupt_controller(struct metal_cpu *cpu); -extern __inline__ int metal_cpu_software_get_interrupt_id(struct metal_cpu *cpu); +extern __inline__ int +metal_cpu_software_get_interrupt_id(struct metal_cpu *cpu); -extern __inline__ int metal_cpu_software_set_ipi(struct metal_cpu *cpu, int hartid); +extern __inline__ int metal_cpu_software_set_ipi(struct metal_cpu *cpu, + int hartid); -extern __inline__ int metal_cpu_software_clear_ipi(struct metal_cpu *cpu, int hartid); +extern __inline__ int metal_cpu_software_clear_ipi(struct metal_cpu *cpu, + int hartid); extern __inline__ int metal_cpu_get_msip(struct metal_cpu *cpu, int hartid); -extern __inline__ struct metal_interrupt* metal_cpu_interrupt_controller(struct metal_cpu *cpu); +extern __inline__ struct metal_interrupt * +metal_cpu_interrupt_controller(struct metal_cpu *cpu); -extern __inline__ int metal_cpu_exception_register(struct metal_cpu *cpu, int ecode, metal_exception_handler_t handler); +extern __inline__ int +metal_cpu_exception_register(struct metal_cpu *cpu, int ecode, + metal_exception_handler_t handler); -extern __inline__ int metal_cpu_get_instruction_length(struct metal_cpu *cpu, uintptr_t epc); +extern __inline__ int metal_cpu_get_instruction_length(struct metal_cpu *cpu, + uintptr_t epc); extern __inline__ uintptr_t metal_cpu_get_exception_pc(struct metal_cpu *cpu); -extern __inline__ int metal_cpu_set_exception_pc(struct metal_cpu *cpu, uintptr_t epc); +extern __inline__ int metal_cpu_set_exception_pc(struct metal_cpu *cpu, + uintptr_t epc); + +extern __inline__ struct metal_buserror * +metal_cpu_get_buserror(struct metal_cpu *cpu); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/fixed-clock.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/fixed-clock.c index 92c61d023..395197071 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/fixed-clock.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/fixed-clock.c @@ -6,16 +6,15 @@ #ifdef METAL_FIXED_CLOCK #include <metal/drivers/fixed-clock.h> -#include <stddef.h> #include <metal/machine.h> +#include <stddef.h> -long __metal_driver_fixed_clock_get_rate_hz(const struct metal_clock *gclk) -{ +long __metal_driver_fixed_clock_get_rate_hz(const struct metal_clock *gclk) { return __metal_driver_fixed_clock_rate(gclk); } -long __metal_driver_fixed_clock_set_rate_hz(struct metal_clock *gclk, long target_hz) -{ +long __metal_driver_fixed_clock_set_rate_hz(struct metal_clock *gclk, + long target_hz) { return __metal_driver_fixed_clock_get_rate_hz(gclk); } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/fixed-factor-clock.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/fixed-factor-clock.c index 57d83af87..4e8223bf5 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/fixed-factor-clock.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/fixed-factor-clock.c @@ -6,22 +6,23 @@ #ifdef METAL_FIXED_FACTOR_CLOCK #include <metal/drivers/fixed-factor-clock.h> -#include <stddef.h> #include <metal/machine.h> +#include <stddef.h> -long __metal_driver_fixed_factor_clock_get_rate_hz(const struct metal_clock *gclk) -{ +long __metal_driver_fixed_factor_clock_get_rate_hz( + const struct metal_clock *gclk) { struct metal_clock *parent = __metal_driver_fixed_factor_clock_parent(gclk); long parent_rate = 1; - if(parent) { + if (parent) { parent_rate = parent->vtable->get_rate_hz(parent); } - return __metal_driver_fixed_factor_clock_mult(gclk) * parent_rate / __metal_driver_fixed_factor_clock_div(gclk); + return __metal_driver_fixed_factor_clock_mult(gclk) * parent_rate / + __metal_driver_fixed_factor_clock_div(gclk); } -long __metal_driver_fixed_factor_clock_set_rate_hz(struct metal_clock *gclk, long target_hz) -{ +long __metal_driver_fixed_factor_clock_set_rate_hz(struct metal_clock *gclk, + long target_hz) { return __metal_driver_fixed_factor_clock_get_rate_hz(gclk); } @@ -31,4 +32,4 @@ __METAL_DEFINE_VTABLE(__metal_driver_vtable_fixed_factor_clock) = { }; #endif /* METAL_FIXED_FACTOR_CLOCK */ -typedef int no_empty_translation_units; +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/inline.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/inline.c index 50c0c5c21..a87c056ba 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/inline.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/inline.c @@ -2,4 +2,3 @@ /* SPDX-License-Identifier: Apache-2.0 */ #include <metal/machine/inline.h> - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_clint0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_clint0.c index d0488b317..3dd7c0eb1 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_clint0.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_clint0.c @@ -5,93 +5,106 @@ #ifdef METAL_RISCV_CLINT0 -#include <metal/io.h> #include <metal/cpu.h> #include <metal/drivers/riscv_clint0.h> +#include <metal/io.h> #include <metal/machine.h> -unsigned long long __metal_clint0_mtime_get (struct __metal_driver_riscv_clint0 *clint) -{ +unsigned long long +__metal_clint0_mtime_get(struct __metal_driver_riscv_clint0 *clint) { __metal_io_u32 lo, hi; - unsigned long control_base = __metal_driver_sifive_clint0_control_base(&clint->controller); + unsigned long control_base = + __metal_driver_sifive_clint0_control_base(&clint->controller); /* Guard against rollover when reading */ do { - hi = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_RISCV_CLINT0_MTIME + 4)); - lo = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_RISCV_CLINT0_MTIME)); - } while (__METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_RISCV_CLINT0_MTIME + 4)) != hi); + hi = __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(control_base + METAL_RISCV_CLINT0_MTIME + 4)); + lo = __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(control_base + METAL_RISCV_CLINT0_MTIME)); + } while (__METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + + METAL_RISCV_CLINT0_MTIME + + 4)) != hi); return (((unsigned long long)hi) << 32) | lo; } int __metal_driver_riscv_clint0_mtimecmp_set(struct metal_interrupt *controller, int hartid, - unsigned long long time) -{ + unsigned long long time) { struct __metal_driver_riscv_clint0 *clint = - (struct __metal_driver_riscv_clint0 *)(controller); - unsigned long control_base = __metal_driver_sifive_clint0_control_base(&clint->controller); + (struct __metal_driver_riscv_clint0 *)(controller); + unsigned long control_base = + __metal_driver_sifive_clint0_control_base(&clint->controller); /* Per spec, the RISC-V MTIME/MTIMECMP registers are 64 bit, * and are NOT internally latched for multiword transfers. * Need to be careful about sequencing to avoid triggering * spurious interrupts: For that set the high word to a max * value first. */ - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_RISCV_CLINT0_MTIMECMP_BASE + 4)) = 0xFFFFFFFF; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_RISCV_CLINT0_MTIMECMP_BASE)) = (__metal_io_u32)time; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_RISCV_CLINT0_MTIMECMP_BASE + 4)) = (__metal_io_u32)(time >> 32); + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + + METAL_RISCV_CLINT0_MTIMECMP_BASE + + 4)) = 0xFFFFFFFF; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + + METAL_RISCV_CLINT0_MTIMECMP_BASE)) = + (__metal_io_u32)time; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + + METAL_RISCV_CLINT0_MTIMECMP_BASE + + 4)) = (__metal_io_u32)(time >> 32); return 0; } -static struct metal_interrupt *_get_cpu_intc() -{ +static struct metal_interrupt *_get_cpu_intc() { int hartid = 0; __asm__ volatile("csrr %[hartid], mhartid" - : [hartid] "=r" (hartid) :: "memory"); + : [hartid] "=r"(hartid)::"memory"); struct metal_cpu *cpu = metal_cpu_get(hartid); return metal_cpu_interrupt_controller(cpu); } -void __metal_driver_riscv_clint0_init (struct metal_interrupt *controller) -{ - int num_interrupts = __metal_driver_sifive_clint0_num_interrupts(controller); +void __metal_driver_riscv_clint0_init(struct metal_interrupt *controller) { + int num_interrupts = + __metal_driver_sifive_clint0_num_interrupts(controller); struct __metal_driver_riscv_clint0 *clint = - (struct __metal_driver_riscv_clint0 *)(controller); + (struct __metal_driver_riscv_clint0 *)(controller); - if ( !clint->init_done ) { - /* Register its interrupts with with parent controller, aka sw and timerto its default isr */ + if (!clint->init_done) { + /* Register its interrupts with with parent controller, aka sw and + * timerto its default isr */ for (int i = 0; i < num_interrupts; i++) { - struct metal_interrupt *intc = __metal_driver_sifive_clint0_interrupt_parents(controller, i); - int line = __metal_driver_sifive_clint0_interrupt_lines(controller, i); + struct metal_interrupt *intc = + __metal_driver_sifive_clint0_interrupt_parents(controller, i); + int line = + __metal_driver_sifive_clint0_interrupt_lines(controller, i); intc->vtable->interrupt_register(intc, line, NULL, controller); - } - clint->init_done = 1; - } + } + clint->init_done = 1; + } } -int __metal_driver_riscv_clint0_register (struct metal_interrupt *controller, - int id, metal_interrupt_handler_t isr, - void *priv) -{ +int __metal_driver_riscv_clint0_register(struct metal_interrupt *controller, + int id, metal_interrupt_handler_t isr, + void *priv) { int rc = -1; metal_vector_mode mode = __metal_controller_interrupt_vector_mode(); struct metal_interrupt *intc = NULL; struct metal_interrupt *cpu_intc = _get_cpu_intc(); - int num_interrupts = __metal_driver_sifive_clint0_num_interrupts(controller); + int num_interrupts = + __metal_driver_sifive_clint0_num_interrupts(controller); - if ( (mode != METAL_VECTOR_MODE) && (mode != METAL_DIRECT_MODE) ) { + if ((mode != METAL_VECTOR_MODE) && (mode != METAL_DIRECT_MODE)) { return rc; } - for(int i = 0; i < num_interrupts; i++) { - int line = __metal_driver_sifive_clint0_interrupt_lines(controller, i); + for (int i = 0; i < num_interrupts; i++) { + int line = __metal_driver_sifive_clint0_interrupt_lines(controller, i); intc = __metal_driver_sifive_clint0_interrupt_parents(controller, i); if (cpu_intc == intc && id == line) { break; } - intc = NULL; + intc = NULL; } /* Register its interrupts with parent controller */ @@ -101,59 +114,60 @@ int __metal_driver_riscv_clint0_register (struct metal_interrupt *controller, return rc; } -int __metal_driver_riscv_clint0_vector_register (struct metal_interrupt *controller, - int id, metal_interrupt_vector_handler_t isr, - void *priv) -{ +int __metal_driver_riscv_clint0_vector_register( + struct metal_interrupt *controller, int id, + metal_interrupt_vector_handler_t isr, void *priv) { /* Not supported. User can override the 'weak' handler with their own */ int rc = -1; return rc; } -metal_vector_mode __metal_driver_riscv_clint0_get_vector_mode (struct metal_interrupt *controller) -{ +metal_vector_mode __metal_driver_riscv_clint0_get_vector_mode( + struct metal_interrupt *controller) { return __metal_controller_interrupt_vector_mode(); } -int __metal_driver_riscv_clint0_set_vector_mode (struct metal_interrupt *controller, metal_vector_mode mode) -{ +int __metal_driver_riscv_clint0_set_vector_mode( + struct metal_interrupt *controller, metal_vector_mode mode) { int rc = -1; struct metal_interrupt *intc = _get_cpu_intc(); if (intc) { - /* Valid vector modes are VECTOR and DIRECT, anything else is invalid (-1) */ + /* Valid vector modes are VECTOR and DIRECT, anything else is invalid + * (-1) */ switch (mode) { case METAL_VECTOR_MODE: case METAL_DIRECT_MODE: rc = intc->vtable->interrupt_set_vector_mode(intc, mode); break; - case METAL_HARDWARE_VECTOR_MODE: - case METAL_SELECTIVE_NONVECTOR_MODE: - case METAL_SELECTIVE_VECTOR_MODE: - break; + default: + break; } } return rc; } -int __metal_driver_riscv_clint0_enable (struct metal_interrupt *controller, int id) -{ +int __metal_driver_riscv_clint0_enable(struct metal_interrupt *controller, + int id) { int rc = -1; - if ( id ) { + if (id) { struct metal_interrupt *intc = NULL; struct metal_interrupt *cpu_intc = _get_cpu_intc(); - int num_interrupts = __metal_driver_sifive_clint0_num_interrupts(controller); + int num_interrupts = + __metal_driver_sifive_clint0_num_interrupts(controller); - for(int i = 0; i < num_interrupts; i++) { - int line = __metal_driver_sifive_clint0_interrupt_lines(controller, i); - intc = __metal_driver_sifive_clint0_interrupt_parents(controller, i); - if(cpu_intc == intc && id == line) { + for (int i = 0; i < num_interrupts; i++) { + int line = + __metal_driver_sifive_clint0_interrupt_lines(controller, i); + intc = + __metal_driver_sifive_clint0_interrupt_parents(controller, i); + if (cpu_intc == intc && id == line) { break; } - intc = NULL; + intc = NULL; } - + /* Enable its interrupts with parent controller */ if (intc) { rc = intc->vtable->interrupt_enable(intc, id); @@ -163,24 +177,27 @@ int __metal_driver_riscv_clint0_enable (struct metal_interrupt *controller, int return rc; } -int __metal_driver_riscv_clint0_disable (struct metal_interrupt *controller, int id) -{ +int __metal_driver_riscv_clint0_disable(struct metal_interrupt *controller, + int id) { int rc = -1; - if ( id ) { + if (id) { struct metal_interrupt *intc = NULL; struct metal_interrupt *cpu_intc = _get_cpu_intc(); - int num_interrupts = __metal_driver_sifive_clint0_num_interrupts(controller); + int num_interrupts = + __metal_driver_sifive_clint0_num_interrupts(controller); - for(int i = 0; i < num_interrupts; i++) { - int line = __metal_driver_sifive_clint0_interrupt_lines(controller, i); - intc = __metal_driver_sifive_clint0_interrupt_parents(controller, i); - if(cpu_intc == intc && id == line) { + for (int i = 0; i < num_interrupts; i++) { + int line = + __metal_driver_sifive_clint0_interrupt_lines(controller, i); + intc = + __metal_driver_sifive_clint0_interrupt_parents(controller, i); + if (cpu_intc == intc && id == line) { break; } - intc = NULL; + intc = NULL; } - + /* Disable its interrupts with parent controller */ if (intc) { rc = intc->vtable->interrupt_disable(intc, id); @@ -190,92 +207,94 @@ int __metal_driver_riscv_clint0_disable (struct metal_interrupt *controller, int return rc; } -int __metal_driver_riscv_clint0_command_request (struct metal_interrupt *controller, - int command, void *data) -{ +int __metal_driver_riscv_clint0_command_request( + struct metal_interrupt *controller, int command, void *data) { int hartid; int rc = -1; struct __metal_driver_riscv_clint0 *clint = - (struct __metal_driver_riscv_clint0 *)(controller); - unsigned long control_base = __metal_driver_sifive_clint0_control_base(controller); + (struct __metal_driver_riscv_clint0 *)(controller); + unsigned long control_base = + __metal_driver_sifive_clint0_control_base(controller); switch (command) { case METAL_TIMER_MTIME_GET: if (data) { - *(unsigned long long *)data = __metal_clint0_mtime_get(clint); + *(unsigned long long *)data = __metal_clint0_mtime_get(clint); rc = 0; } break; case METAL_SOFTWARE_IPI_CLEAR: - if (data) { - hartid = *(int *)data; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - (hartid * 4))) = METAL_DISABLE; + if (data) { + hartid = *(int *)data; + __METAL_ACCESS_ONCE(( + __metal_io_u32 *)(control_base + (hartid * 4))) = METAL_DISABLE; rc = 0; } break; case METAL_SOFTWARE_IPI_SET: - if (data) { - hartid = *(int *)data; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - (hartid * 4))) = METAL_ENABLE; - /* Callers of this function assume it's blocking, in the sense that - * the IPI is guarnteed to have been delivered before the function - * returns. We can't really guarnteed it's delivered, but we can - * read back the control register after writing it in at least an - * attempt to provide some semblence of ordering here. The fence - * ensures the read is order after the write -- it wouldn't be - * necessary under RVWMO because this is the same address, but we - * don't have an IO memory model so I'm being a bit overkill here. - */ - __METAL_IO_FENCE(o,i); - rc = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - (hartid * 4))); + if (data) { + hartid = *(int *)data; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(control_base + (hartid * 4))) = METAL_ENABLE; + /* Callers of this function assume it's blocking, in the sense that + * the IPI is guarnteed to have been delivered before the function + * returns. We can't really guarnteed it's delivered, but we can + * read back the control register after writing it in at least an + * attempt to provide some semblence of ordering here. The fence + * ensures the read is order after the write -- it wouldn't be + * necessary under RVWMO because this is the same address, but we + * don't have an IO memory model so I'm being a bit overkill here. + */ + __METAL_IO_FENCE(o, i); + rc = __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(control_base + (hartid * 4))); rc = 0; } break; case METAL_SOFTWARE_MSIP_GET: rc = 0; - if (data) { - hartid = *(int *)data; - rc = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - (hartid * 4))); + if (data) { + hartid = *(int *)data; + rc = __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(control_base + (hartid * 4))); } break; default: - break; + break; } return rc; } -int __metal_driver_riscv_clint0_clear_interrupt (struct metal_interrupt *controller, int id) -{ +int __metal_driver_riscv_clint0_clear_interrupt( + struct metal_interrupt *controller, int id) { int hartid = metal_cpu_get_current_hartid(); - return __metal_driver_riscv_clint0_command_request(controller, - METAL_SOFTWARE_IPI_CLEAR, &hartid); + return __metal_driver_riscv_clint0_command_request( + controller, METAL_SOFTWARE_IPI_CLEAR, &hartid); } -int __metal_driver_riscv_clint0_set_interrupt (struct metal_interrupt *controller, int id) -{ +int __metal_driver_riscv_clint0_set_interrupt( + struct metal_interrupt *controller, int id) { int hartid = metal_cpu_get_current_hartid(); - return __metal_driver_riscv_clint0_command_request(controller, - METAL_SOFTWARE_IPI_SET, &hartid); + return __metal_driver_riscv_clint0_command_request( + controller, METAL_SOFTWARE_IPI_SET, &hartid); } - __METAL_DEFINE_VTABLE(__metal_driver_vtable_riscv_clint0) = { - .clint_vtable.interrupt_init = __metal_driver_riscv_clint0_init, + .clint_vtable.interrupt_init = __metal_driver_riscv_clint0_init, .clint_vtable.interrupt_register = __metal_driver_riscv_clint0_register, - .clint_vtable.interrupt_vector_register = __metal_driver_riscv_clint0_vector_register, - .clint_vtable.interrupt_enable = __metal_driver_riscv_clint0_enable, - .clint_vtable.interrupt_disable = __metal_driver_riscv_clint0_disable, - .clint_vtable.interrupt_get_vector_mode = __metal_driver_riscv_clint0_get_vector_mode, - .clint_vtable.interrupt_set_vector_mode = __metal_driver_riscv_clint0_set_vector_mode, - .clint_vtable.interrupt_clear = __metal_driver_riscv_clint0_clear_interrupt, - .clint_vtable.interrupt_set = __metal_driver_riscv_clint0_set_interrupt, - .clint_vtable.command_request = __metal_driver_riscv_clint0_command_request, - .clint_vtable.mtimecmp_set = __metal_driver_riscv_clint0_mtimecmp_set, + .clint_vtable.interrupt_vector_register = + __metal_driver_riscv_clint0_vector_register, + .clint_vtable.interrupt_enable = __metal_driver_riscv_clint0_enable, + .clint_vtable.interrupt_disable = __metal_driver_riscv_clint0_disable, + .clint_vtable.interrupt_get_vector_mode = + __metal_driver_riscv_clint0_get_vector_mode, + .clint_vtable.interrupt_set_vector_mode = + __metal_driver_riscv_clint0_set_vector_mode, + .clint_vtable.interrupt_clear = __metal_driver_riscv_clint0_clear_interrupt, + .clint_vtable.interrupt_set = __metal_driver_riscv_clint0_set_interrupt, + .clint_vtable.command_request = __metal_driver_riscv_clint0_command_request, + .clint_vtable.mtimecmp_set = __metal_driver_riscv_clint0_mtimecmp_set, }; #endif /* METAL_RISCV_CLINT0 */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_cpu.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_cpu.c index b693f312a..dda13b934 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_cpu.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_cpu.c @@ -1,145 +1,157 @@ /* Copyright 2018 SiFive, Inc */ /* SPDX-License-Identifier: Apache-2.0 */ -#include <stdint.h> #include <metal/io.h> -#include <metal/shutdown.h> #include <metal/machine.h> +#include <metal/shutdown.h> +#include <stdint.h> + +#define __METAL_IRQ_VECTOR_HANDLER(id) \ + void *priv; \ + struct __metal_driver_riscv_cpu_intc *intc; \ + struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; \ + if (cpu) { \ + intc = (struct __metal_driver_riscv_cpu_intc *) \ + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); \ + priv = intc->metal_int_table[id].exint_data; \ + intc->metal_int_table[id].handler(id, priv); \ + } extern void __metal_vector_table(); unsigned long long __metal_driver_cpu_mtime_get(struct metal_cpu *cpu); -int __metal_driver_cpu_mtimecmp_set(struct metal_cpu *cpu, unsigned long long time); +int __metal_driver_cpu_mtimecmp_set(struct metal_cpu *cpu, + unsigned long long time); -struct metal_cpu *__metal_driver_cpu_get(int hartid) -{ +struct metal_cpu *__metal_driver_cpu_get(int hartid) { if (hartid < __METAL_DT_MAX_HARTS) { return &(__metal_cpu_table[hartid]->cpu); } return (struct metal_cpu *)NULL; } -uintptr_t __metal_myhart_id (void) -{ +uintptr_t __metal_myhart_id(void) { uintptr_t myhart; - __asm__ volatile ("csrr %0, mhartid" : "=r"(myhart)); + __asm__ volatile("csrr %0, mhartid" : "=r"(myhart)); return myhart; } -void __metal_zero_memory (unsigned char *base, unsigned int size) -{ +void __metal_zero_memory(unsigned char *base, unsigned int size) { volatile unsigned char *ptr; - for (ptr = base; ptr < (base + size); ptr++){ + for (ptr = base; ptr < (base + size); ptr++) { *ptr = 0; } } -void __metal_interrupt_global_enable (void) { +void __metal_interrupt_global_enable(void) { uintptr_t m; - __asm__ volatile ("csrrs %0, mstatus, %1" : "=r"(m) : "r"(METAL_MIE_INTERRUPT)); + __asm__ volatile("csrrs %0, mstatus, %1" + : "=r"(m) + : "r"(METAL_MIE_INTERRUPT)); } -void __metal_interrupt_global_disable (void) { +void __metal_interrupt_global_disable(void) { uintptr_t m; - __asm__ volatile ("csrrc %0, mstatus, %1" : "=r"(m) : "r"(METAL_MIE_INTERRUPT)); + __asm__ volatile("csrrc %0, mstatus, %1" + : "=r"(m) + : "r"(METAL_MIE_INTERRUPT)); } -void __metal_interrupt_software_enable (void) { +void __metal_interrupt_software_enable(void) { uintptr_t m; - __asm__ volatile ("csrrs %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_SW)); + __asm__ volatile("csrrs %0, mie, %1" + : "=r"(m) + : "r"(METAL_LOCAL_INTERRUPT_SW)); } -void __metal_interrupt_software_disable (void) { +void __metal_interrupt_software_disable(void) { uintptr_t m; - __asm__ volatile ("csrrc %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_SW)); + __asm__ volatile("csrrc %0, mie, %1" + : "=r"(m) + : "r"(METAL_LOCAL_INTERRUPT_SW)); } -void __metal_interrupt_timer_enable (void) { +void __metal_interrupt_timer_enable(void) { uintptr_t m; - __asm__ volatile ("csrrs %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_TMR)); + __asm__ volatile("csrrs %0, mie, %1" + : "=r"(m) + : "r"(METAL_LOCAL_INTERRUPT_TMR)); } -void __metal_interrupt_timer_disable (void) { +void __metal_interrupt_timer_disable(void) { uintptr_t m; - __asm__ volatile ("csrrc %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_TMR)); + __asm__ volatile("csrrc %0, mie, %1" + : "=r"(m) + : "r"(METAL_LOCAL_INTERRUPT_TMR)); } -void __metal_interrupt_external_enable (void) { +void __metal_interrupt_external_enable(void) { uintptr_t m; - __asm__ volatile ("csrrs %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_EXT)); + __asm__ volatile("csrrs %0, mie, %1" + : "=r"(m) + : "r"(METAL_LOCAL_INTERRUPT_EXT)); } -void __metal_interrupt_external_disable (void) { +void __metal_interrupt_external_disable(void) { unsigned long m; - __asm__ volatile ("csrrc %0, mie, %1" : "=r"(m) : "r"(METAL_LOCAL_INTERRUPT_EXT)); + __asm__ volatile("csrrc %0, mie, %1" + : "=r"(m) + : "r"(METAL_LOCAL_INTERRUPT_EXT)); } -void __metal_interrupt_local_enable (int id) { +void __metal_interrupt_local_enable(int id) { uintptr_t b = 1 << id; uintptr_t m; - __asm__ volatile ("csrrs %0, mie, %1" : "=r"(m) : "r"(b)); + __asm__ volatile("csrrs %0, mie, %1" : "=r"(m) : "r"(b)); } -void __metal_interrupt_local_disable (int id) { +void __metal_interrupt_local_disable(int id) { uintptr_t b = 1 << id; uintptr_t m; - __asm__ volatile ("csrrc %0, mie, %1" : "=r"(m) : "r"(b)); + __asm__ volatile("csrrc %0, mie, %1" : "=r"(m) : "r"(b)); } -void __metal_default_exception_handler (struct metal_cpu *cpu, int ecode) { +void __metal_default_exception_handler(struct metal_cpu *cpu, int ecode) { metal_shutdown(100); } -void __metal_default_interrupt_handler (int id, void *priv) { +void __metal_default_interrupt_handler(int id, void *priv) { metal_shutdown(200); } /* The metal_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_interrupt_vector_handler (void) { +void __attribute__((weak, interrupt)) metal_interrupt_vector_handler(void) { metal_shutdown(300); } /* The metal_software_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_software_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_SW].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_SW].handler(METAL_INTERRUPT_ID_SW, priv); - } +void __attribute__((weak, interrupt)) +metal_software_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_SW); } -void __metal_default_sw_handler (int id, void *priv) { +void __metal_default_sw_handler(int id, void *priv) { uintptr_t mcause; struct __metal_driver_riscv_cpu_intc *intc; struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - __asm__ volatile ("csrr %0, mcause" : "=r"(mcause)); - if ( cpu ) { + __asm__ volatile("csrr %0, mcause" : "=r"(mcause)); + if (cpu) { intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - intc->metal_exception_table[mcause & METAL_MCAUSE_CAUSE]((struct metal_cpu *)cpu, id); + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + intc->metal_exception_table[mcause & METAL_MCAUSE_CAUSE]( + (struct metal_cpu *)cpu, id); } } /* The metal_timer_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_timer_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_TMR].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_TMR].handler(METAL_INTERRUPT_ID_TMR, priv); - } +void __attribute__((weak, interrupt)) +metal_timer_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_TMR); } -void __metal_default_timer_handler (int id, void *priv) { +void __metal_default_beu_handler(int id, void *priv) {} + +void __metal_default_timer_handler(int id, void *priv) { struct metal_cpu *cpu = __metal_driver_cpu_get(__metal_myhart_id()); unsigned long long time = __metal_driver_cpu_mtime_get(cpu); @@ -148,52 +160,49 @@ void __metal_default_timer_handler (int id, void *priv) { } /* The metal_external_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_external_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_EXT].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_EXT].handler(METAL_INTERRUPT_ID_EXT, priv); - } +void __attribute__((weak, interrupt)) +metal_external_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_EXT); } void __metal_exception_handler(void) __attribute__((interrupt, aligned(128))); -void __metal_exception_handler (void) { +void __metal_exception_handler(void) { int id; void *priv; uintptr_t mcause, mepc, mtval, mtvec; struct __metal_driver_riscv_cpu_intc *intc; struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - __asm__ volatile ("csrr %0, mcause" : "=r"(mcause)); - __asm__ volatile ("csrr %0, mepc" : "=r"(mepc)); - __asm__ volatile ("csrr %0, mtval" : "=r"(mtval)); - __asm__ volatile ("csrr %0, mtvec" : "=r"(mtvec)); + __asm__ volatile("csrr %0, mcause" : "=r"(mcause)); + __asm__ volatile("csrr %0, mepc" : "=r"(mepc)); + __asm__ volatile("csrr %0, mtval" : "=r"(mtval)); + __asm__ volatile("csrr %0, mtvec" : "=r"(mtvec)); - if ( cpu ) { + if (cpu) { intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); + __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); id = mcause & METAL_MCAUSE_CAUSE; if (mcause & METAL_MCAUSE_INTR) { + if (id == METAL_INTERRUPT_ID_BEU) { + priv = intc->metal_int_beu.exint_data; + intc->metal_int_beu.handler(id, priv); + return; + } if ((id < METAL_INTERRUPT_ID_CSW) || - ((mtvec & METAL_MTVEC_MASK) == METAL_MTVEC_DIRECT)) { + ((mtvec & METAL_MTVEC_MASK) == METAL_MTVEC_DIRECT)) { priv = intc->metal_int_table[id].exint_data; intc->metal_int_table[id].handler(id, priv); - return; + return; } if ((mtvec & METAL_MTVEC_MASK) == METAL_MTVEC_CLIC) { - uintptr_t mtvt; - metal_interrupt_handler_t mtvt_handler; - - __asm__ volatile ("csrr %0, 0x307" : "=r"(mtvt)); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int; - mtvt_handler = (metal_interrupt_handler_t)*(uintptr_t *)mtvt; - mtvt_handler(id, priv); - return; + uintptr_t mtvt; + metal_interrupt_handler_t mtvt_handler; + + __asm__ volatile("csrr %0, 0x307" : "=r"(mtvt)); + priv = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int; + mtvt_handler = (metal_interrupt_handler_t) * (uintptr_t *)mtvt; + mtvt_handler(id, priv); + return; } } else { intc->metal_exception_table[id]((struct metal_cpu *)cpu, id); @@ -202,234 +211,95 @@ void __metal_exception_handler (void) { } /* The metal_lc0_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc0_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC0].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC0].handler(METAL_INTERRUPT_ID_LC0, priv); - } +void __attribute__((weak, interrupt)) metal_lc0_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC0); } /* The metal_lc1_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc1_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC1].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC1].handler(METAL_INTERRUPT_ID_LC1, priv); - } +void __attribute__((weak, interrupt)) metal_lc1_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC1); } /* The metal_lc2_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc2_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC2].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC2].handler(METAL_INTERRUPT_ID_LC2, priv); - } +void __attribute__((weak, interrupt)) metal_lc2_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC2); } /* The metal_lc3_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc3_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC3].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC3].handler(METAL_INTERRUPT_ID_LC3, priv); - } +void __attribute__((weak, interrupt)) metal_lc3_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC3); } /* The metal_lc4_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc4_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC4].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC4].handler(METAL_INTERRUPT_ID_LC4, priv); - } +void __attribute__((weak, interrupt)) metal_lc4_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC4); } /* The metal_lc5_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc5_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC5].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC5].handler(METAL_INTERRUPT_ID_LC5, priv); - } +void __attribute__((weak, interrupt)) metal_lc5_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC5); } /* The metal_lc6_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc6_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC6].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC6].handler(METAL_INTERRUPT_ID_LC6, priv); - } +void __attribute__((weak, interrupt)) metal_lc6_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC6); } /* The metal_lc7_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc7_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC7].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC7].handler(METAL_INTERRUPT_ID_LC7, priv); - } +void __attribute__((weak, interrupt)) metal_lc7_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC7); } /* The metal_lc8_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc8_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC8].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC8].handler(METAL_INTERRUPT_ID_LC8, priv); - } +void __attribute__((weak, interrupt)) metal_lc8_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC8); } /* The metal_lc9_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc9_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC9].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC9].handler(METAL_INTERRUPT_ID_LC9, priv); - } +void __attribute__((weak, interrupt)) metal_lc9_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC9); } /* The metal_lc10_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc10_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC10].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC10].handler(METAL_INTERRUPT_ID_LC10, priv); - } +void __attribute__((weak, interrupt)) +metal_lc10_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC10); } /* The metal_lc11_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc11_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC11].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC11].handler(METAL_INTERRUPT_ID_LC11, priv); - } +void __attribute__((weak, interrupt)) +metal_lc11_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC11); } /* The metal_lc12_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc12_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC12].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC12].handler(METAL_INTERRUPT_ID_LC12, priv); - } +void __attribute__((weak, interrupt)) +metal_lc12_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC12); } /* The metal_lc13_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc13_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC13].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC13].handler(METAL_INTERRUPT_ID_LC13, priv); - } +void __attribute__((weak, interrupt)) +metal_lc13_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC13); } /* The metal_lc14_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc14_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC14].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC14].handler(METAL_INTERRUPT_ID_LC14, priv); - } +void __attribute__((weak, interrupt)) +metal_lc14_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC14); } /* The metal_lc15_interrupt_vector_handler() function can be redefined. */ -void __attribute__((weak, interrupt)) metal_lc15_interrupt_vector_handler (void) { - void *priv; - struct __metal_driver_riscv_cpu_intc *intc; - struct __metal_driver_cpu *cpu = __metal_cpu_table[__metal_myhart_id()]; - - if ( cpu ) { - intc = (struct __metal_driver_riscv_cpu_intc *) - __metal_driver_cpu_interrupt_controller((struct metal_cpu *)cpu); - priv = intc->metal_int_table[METAL_INTERRUPT_ID_LC15].exint_data; - intc->metal_int_table[METAL_INTERRUPT_ID_LC15].handler(METAL_INTERRUPT_ID_LC15, priv); - } +void __attribute__((weak, interrupt)) +metal_lc15_interrupt_vector_handler(void) { + __METAL_IRQ_VECTOR_HANDLER(METAL_INTERRUPT_ID_LC15); } -metal_vector_mode __metal_controller_interrupt_vector_mode (void) -{ +metal_vector_mode __metal_controller_interrupt_vector_mode(void) { uintptr_t val; - asm volatile ("csrr %0, mtvec" : "=r"(val)); + __asm__ volatile("csrr %0, mtvec" : "=r"(val)); val &= METAL_MTVEC_MASK; switch (val) { @@ -443,35 +313,37 @@ metal_vector_mode __metal_controller_interrupt_vector_mode (void) return METAL_DIRECT_MODE; } -void __metal_controller_interrupt_vector (metal_vector_mode mode, void *vec_table) -{ +void __metal_controller_interrupt_vector(metal_vector_mode mode, + void *vec_table) { uintptr_t trap_entry, val; - __asm__ volatile ("csrr %0, mtvec" : "=r"(val)); + __asm__ volatile("csrr %0, mtvec" : "=r"(val)); val &= ~(METAL_MTVEC_CLIC_VECTORED | METAL_MTVEC_CLIC_RESERVED); trap_entry = (uintptr_t)vec_table; switch (mode) { case METAL_SELECTIVE_NONVECTOR_MODE: case METAL_SELECTIVE_VECTOR_MODE: - __asm__ volatile ("csrw 0x307, %0" :: "r"(trap_entry)); - __asm__ volatile ("csrw mtvec, %0" :: "r"(val | METAL_MTVEC_CLIC)); + __asm__ volatile("csrw 0x307, %0" ::"r"(trap_entry)); + __asm__ volatile("csrw mtvec, %0" ::"r"(val | METAL_MTVEC_CLIC)); break; case METAL_HARDWARE_VECTOR_MODE: - __asm__ volatile ("csrw 0x307, %0" :: "r"(trap_entry)); - __asm__ volatile ("csrw mtvec, %0" :: "r"(val | METAL_MTVEC_CLIC_VECTORED)); + __asm__ volatile("csrw 0x307, %0" ::"r"(trap_entry)); + __asm__ volatile( + "csrw mtvec, %0" ::"r"(val | METAL_MTVEC_CLIC_VECTORED)); break; case METAL_VECTOR_MODE: - __asm__ volatile ("csrw mtvec, %0" :: "r"(trap_entry | METAL_MTVEC_VECTORED)); + __asm__ volatile( + "csrw mtvec, %0" ::"r"(trap_entry | METAL_MTVEC_VECTORED)); break; case METAL_DIRECT_MODE: - __asm__ volatile ("csrw mtvec, %0" :: "r"(trap_entry & ~METAL_MTVEC_CLIC_VECTORED)); + __asm__ volatile( + "csrw mtvec, %0" ::"r"(trap_entry & ~METAL_MTVEC_CLIC_VECTORED)); break; } } -int __metal_valid_interrupt_id (int id) -{ +int __metal_valid_interrupt_id(int id) { switch (id) { case METAL_INTERRUPT_ID_SW: case METAL_INTERRUPT_ID_TMR: @@ -492,6 +364,7 @@ int __metal_valid_interrupt_id (int id) case METAL_INTERRUPT_ID_LC13: case METAL_INTERRUPT_ID_LC14: case METAL_INTERRUPT_ID_LC15: + case METAL_INTERRUPT_ID_BEU: return 1; default: break; @@ -500,13 +373,11 @@ int __metal_valid_interrupt_id (int id) return 0; } - -int __metal_local_interrupt_enable (struct metal_interrupt *controller, - metal_interrupt_id_e id, int enable) -{ +int __metal_local_interrupt_enable(struct metal_interrupt *controller, + metal_interrupt_id_e id, int enable) { int rc = 0; - - if ( !controller) { + + if (!controller) { return -1; } @@ -527,11 +398,11 @@ int __metal_local_interrupt_enable (struct metal_interrupt *controller, break; case METAL_INTERRUPT_ID_TMR: if (enable) { - __metal_interrupt_timer_enable(); - } else { - __metal_interrupt_timer_disable(); - } - break; + __metal_interrupt_timer_enable(); + } else { + __metal_interrupt_timer_disable(); + } + break; case METAL_INTERRUPT_ID_EXT: if (enable) { __metal_interrupt_external_enable(); @@ -567,9 +438,8 @@ int __metal_local_interrupt_enable (struct metal_interrupt *controller, return rc; } -int __metal_exception_register (struct metal_interrupt *controller, - int ecode, metal_exception_handler_t isr) -{ +int __metal_exception_register(struct metal_interrupt *controller, int ecode, + metal_exception_handler_t isr) { struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller); if ((ecode < METAL_MAX_EXCEPTION_CODE) && isr) { @@ -579,199 +449,198 @@ int __metal_exception_register (struct metal_interrupt *controller, return -1; } -void __metal_driver_riscv_cpu_controller_interrupt_init (struct metal_interrupt *controller) -{ +extern void early_trap_vector(void); +void __metal_driver_riscv_cpu_controller_interrupt_init( + struct metal_interrupt *controller) { struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller); - uintptr_t val; - - if ( !intc->init_done ) { - /* Disable and clear all interrupt sources */ - __asm__ volatile ("csrc mie, %0" :: "r"(-1)); - __asm__ volatile ("csrc mip, %0" :: "r"(-1)); - - /* Read the misa CSR to determine if the delegation registers exist */ - uintptr_t misa; - __asm__ volatile ("csrr %0, misa" : "=r" (misa)); - - /* The delegation CSRs exist if user mode interrupts (N extension) or - * supervisor mode (S extension) are supported */ - if((misa & METAL_ISA_N_EXTENSIONS) || (misa & METAL_ISA_S_EXTENSIONS)) { - /* Disable interrupt and exception delegation */ - __asm__ volatile ("csrc mideleg, %0" :: "r"(-1)); - __asm__ volatile ("csrc medeleg, %0" :: "r"(-1)); - } - - /* The satp CSR exists if supervisor mode (S extension) is supported */ - if(misa & METAL_ISA_S_EXTENSIONS) { - /* Clear the entire CSR to make sure that satp.MODE = 0 */ - __asm__ volatile ("csrc satp, %0" :: "r"(-1)); - } + if (!intc->init_done) { /* Default to use direct interrupt, setup sw cb table*/ for (int i = 0; i < METAL_MAX_MI; i++) { intc->metal_int_table[i].handler = NULL; intc->metal_int_table[i].sub_int = NULL; intc->metal_int_table[i].exint_data = NULL; - } - for (int i = 0; i < METAL_MAX_ME; i++) { - intc->metal_exception_table[i] = __metal_default_exception_handler; - } - __metal_controller_interrupt_vector(METAL_DIRECT_MODE, (void *)(uintptr_t)&__metal_exception_handler); - __asm__ volatile ("csrr %0, misa" : "=r"(val)); - if (val & (METAL_ISA_D_EXTENSIONS | METAL_ISA_F_EXTENSIONS | METAL_ISA_Q_EXTENSIONS)) { - /* Floating point architecture, so turn on FP register saving*/ - __asm__ volatile ("csrr %0, mstatus" : "=r"(val)); - __asm__ volatile ("csrw mstatus, %0" :: "r"(val | METAL_MSTATUS_FS_INIT)); - } - intc->init_done = 1; + } + + for (int i = 0; i < METAL_MAX_ME; i++) { + intc->metal_exception_table[i] = __metal_default_exception_handler; + } + + /* + * Set the real trap handler if the value of mtvec is equal to + * early_trap_vector. If mtvec is not equal to early_trap_vector, + * that means user has own trap handler, then we don't overwrite it. + */ + uintptr_t mtvec; + __asm__ volatile("csrr %0, mtvec" : "=r"(mtvec)); + if (mtvec == (uintptr_t)&early_trap_vector) { + __metal_controller_interrupt_vector( + METAL_DIRECT_MODE, + (void *)(uintptr_t)&__metal_exception_handler); + } + intc->init_done = 1; } } -int __metal_driver_riscv_cpu_controller_interrupt_register(struct metal_interrupt *controller, - int id, metal_interrupt_handler_t isr, - void *priv) -{ +int __metal_driver_riscv_cpu_controller_interrupt_register( + struct metal_interrupt *controller, int id, metal_interrupt_handler_t isr, + void *priv) { int rc = 0; struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller); - - if ( !__metal_valid_interrupt_id(id) ) { + + if (!__metal_valid_interrupt_id(id)) { return -11; } + if ((id == METAL_INTERRUPT_ID_BEU) && + (__metal_controller_interrupt_vector_mode() != METAL_DIRECT_MODE)) { + /* Only allow registration of the bus error unit interrupt if + * interrupt vectoring if off */ + return -13; + } if (isr) { - intc->metal_int_table[id].handler = isr; - intc->metal_int_table[id].exint_data = priv; + if (id == METAL_INTERRUPT_ID_BEU) { + intc->metal_int_beu.handler = isr; + intc->metal_int_beu.exint_data = priv; + } else { + intc->metal_int_table[id].handler = isr; + intc->metal_int_table[id].exint_data = priv; + } } else { - switch (id) { - case METAL_INTERRUPT_ID_SW: + switch (id) { + case METAL_INTERRUPT_ID_SW: intc->metal_int_table[id].handler = __metal_default_sw_handler; intc->metal_int_table[id].sub_int = priv; - break; - case METAL_INTERRUPT_ID_TMR: + break; + case METAL_INTERRUPT_ID_TMR: intc->metal_int_table[id].handler = __metal_default_timer_handler; intc->metal_int_table[id].sub_int = priv; - break; - case METAL_INTERRUPT_ID_EXT: - case METAL_INTERRUPT_ID_LC0: - case METAL_INTERRUPT_ID_LC1: - case METAL_INTERRUPT_ID_LC2: - case METAL_INTERRUPT_ID_LC3: - case METAL_INTERRUPT_ID_LC4: - case METAL_INTERRUPT_ID_LC5: - case METAL_INTERRUPT_ID_LC6: - case METAL_INTERRUPT_ID_LC7: - case METAL_INTERRUPT_ID_LC8: - case METAL_INTERRUPT_ID_LC9: - case METAL_INTERRUPT_ID_LC10: - case METAL_INTERRUPT_ID_LC11: - case METAL_INTERRUPT_ID_LC12: - case METAL_INTERRUPT_ID_LC13: - case METAL_INTERRUPT_ID_LC14: - case METAL_INTERRUPT_ID_LC15: - intc->metal_int_table[id].handler = __metal_default_interrupt_handler; + break; + case METAL_INTERRUPT_ID_BEU: + intc->metal_int_beu.handler = __metal_default_beu_handler; + intc->metal_int_beu.exint_data = priv; + break; + case METAL_INTERRUPT_ID_EXT: + case METAL_INTERRUPT_ID_LC0: + case METAL_INTERRUPT_ID_LC1: + case METAL_INTERRUPT_ID_LC2: + case METAL_INTERRUPT_ID_LC3: + case METAL_INTERRUPT_ID_LC4: + case METAL_INTERRUPT_ID_LC5: + case METAL_INTERRUPT_ID_LC6: + case METAL_INTERRUPT_ID_LC7: + case METAL_INTERRUPT_ID_LC8: + case METAL_INTERRUPT_ID_LC9: + case METAL_INTERRUPT_ID_LC10: + case METAL_INTERRUPT_ID_LC11: + case METAL_INTERRUPT_ID_LC12: + case METAL_INTERRUPT_ID_LC13: + case METAL_INTERRUPT_ID_LC14: + case METAL_INTERRUPT_ID_LC15: + intc->metal_int_table[id].handler = + __metal_default_interrupt_handler; intc->metal_int_table[id].sub_int = priv; - break; - default: - rc = -12; - } + break; + default: + rc = -12; + } } return rc; } -int __metal_driver_riscv_cpu_controller_interrupt_enable (struct metal_interrupt *controller, - int id) -{ +int __metal_driver_riscv_cpu_controller_interrupt_enable( + struct metal_interrupt *controller, int id) { return __metal_local_interrupt_enable(controller, id, METAL_ENABLE); } -int __metal_driver_riscv_cpu_controller_interrupt_disable (struct metal_interrupt *controller, - int id) -{ +int __metal_driver_riscv_cpu_controller_interrupt_disable( + struct metal_interrupt *controller, int id) { return __metal_local_interrupt_enable(controller, id, METAL_DISABLE); } -int __metal_driver_riscv_cpu_controller_interrupt_enable_vector(struct metal_interrupt *controller, - int id, metal_vector_mode mode) -{ +int __metal_driver_riscv_cpu_controller_interrupt_enable_vector( + struct metal_interrupt *controller, int id, metal_vector_mode mode) { struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller); if (id == METAL_INTERRUPT_ID_BASE) { if (mode == METAL_DIRECT_MODE) { - __metal_controller_interrupt_vector(mode, (void *)(uintptr_t)&__metal_exception_handler); + __metal_controller_interrupt_vector( + mode, (void *)(uintptr_t)&__metal_exception_handler); return 0; - } + } if (mode == METAL_VECTOR_MODE) { - __metal_controller_interrupt_vector(mode, (void *)&intc->metal_mtvec_table); + __metal_controller_interrupt_vector( + mode, (void *)&intc->metal_mtvec_table); return 0; } } return -1; } -int __metal_driver_riscv_cpu_controller_interrupt_disable_vector(struct metal_interrupt *controller, - int id) -{ +int __metal_driver_riscv_cpu_controller_interrupt_disable_vector( + struct metal_interrupt *controller, int id) { if (id == METAL_INTERRUPT_ID_BASE) { - __metal_controller_interrupt_vector(METAL_DIRECT_MODE, (void *)(uintptr_t)&__metal_exception_handler); + __metal_controller_interrupt_vector( + METAL_DIRECT_MODE, (void *)(uintptr_t)&__metal_exception_handler); return 0; } return -1; } -metal_vector_mode __metal_driver_riscv_cpu_controller_get_vector_mode (struct metal_interrupt *controller) -{ +metal_vector_mode __metal_driver_riscv_cpu_controller_get_vector_mode( + struct metal_interrupt *controller) { return __metal_controller_interrupt_vector_mode(); } -int __metal_driver_riscv_cpu_controller_set_vector_mode (struct metal_interrupt *controller, - metal_vector_mode mode) -{ - struct __metal_driver_riscv_cpu_intc *intc = (void *)(controller); - ( void ) intc; +int __metal_driver_riscv_cpu_controller_set_vector_mode( + struct metal_interrupt *controller, metal_vector_mode mode) { if (mode == METAL_DIRECT_MODE) { - __metal_controller_interrupt_vector(mode, (void *)(uintptr_t)&__metal_exception_handler); - return 0; + __metal_controller_interrupt_vector( + mode, (void *)(uintptr_t)&__metal_exception_handler); + return 0; } if (mode == METAL_VECTOR_MODE) { - __metal_controller_interrupt_vector(mode, (void *)__metal_vector_table); + __metal_controller_interrupt_vector( + mode, (void *)(uintptr_t)__metal_vector_table); return 0; } return -1; } -int __metal_driver_riscv_cpu_controller_command_request (struct metal_interrupt *controller, - int cmd, void *data) -{ - /* NOP for now, unless local interrupt lines the like of clic, clint, plic */ +int __metal_driver_riscv_cpu_controller_command_request( + struct metal_interrupt *controller, int cmd, void *data) { + /* NOP for now, unless local interrupt lines the like of clic, clint, plic + */ return 0; } /* CPU driver !!! */ -unsigned long long __metal_driver_cpu_mcycle_get(struct metal_cpu *cpu) -{ +unsigned long long __metal_driver_cpu_mcycle_get(struct metal_cpu *cpu) { unsigned long long val = 0; #if __riscv_xlen == 32 unsigned long hi, hi1, lo; - __asm__ volatile ("csrr %0, mcycleh" : "=r"(hi)); - __asm__ volatile ("csrr %0, mcycle" : "=r"(lo)); - __asm__ volatile ("csrr %0, mcycleh" : "=r"(hi1)); - if (hi == hi1) { - val = ((unsigned long long)hi << 32) | lo; - } + do { + __asm__ volatile("csrr %0, mcycleh" : "=r"(hi)); + __asm__ volatile("csrr %0, mcycle" : "=r"(lo)); + __asm__ volatile("csrr %0, mcycleh" : "=r"(hi1)); + /* hi != hi1 means mcycle overflow during we get value, + * so we must retry. */ + } while (hi != hi1); + + val = ((unsigned long long)hi << 32) | lo; #else - __asm__ volatile ("csrr %0, mcycle" : "=r"(val)); + __asm__ volatile("csrr %0, mcycle" : "=r"(val)); #endif return val; } -unsigned long long __metal_driver_cpu_timebase_get(struct metal_cpu *cpu) -{ - int timebase; +unsigned long long __metal_driver_cpu_timebase_get(struct metal_cpu *cpu) { + int timebase; if (!cpu) { return 0; } @@ -780,44 +649,43 @@ unsigned long long __metal_driver_cpu_timebase_get(struct metal_cpu *cpu) return timebase; } -unsigned long long __metal_driver_cpu_mtime_get (struct metal_cpu *cpu) -{ +unsigned long long __metal_driver_cpu_mtime_get(struct metal_cpu *cpu) { unsigned long long time = 0; struct metal_interrupt *tmr_intc; struct __metal_driver_riscv_cpu_intc *intc = - (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); + (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller(cpu); if (intc) { tmr_intc = intc->metal_int_table[METAL_INTERRUPT_ID_TMR].sub_int; if (tmr_intc) { - tmr_intc->vtable->command_request(tmr_intc, - METAL_TIMER_MTIME_GET, &time); + tmr_intc->vtable->command_request(tmr_intc, METAL_TIMER_MTIME_GET, + &time); } } return time; } -int __metal_driver_cpu_mtimecmp_set (struct metal_cpu *cpu, unsigned long long time) -{ +int __metal_driver_cpu_mtimecmp_set(struct metal_cpu *cpu, + unsigned long long time) { int rc = -1; struct metal_interrupt *tmr_intc; struct __metal_driver_riscv_cpu_intc *intc = - (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); + (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller(cpu); if (intc) { tmr_intc = intc->metal_int_table[METAL_INTERRUPT_ID_TMR].sub_int; if (tmr_intc) { - rc = tmr_intc->vtable->mtimecmp_set(tmr_intc, - __metal_driver_cpu_hartid(cpu), - time); + rc = tmr_intc->vtable->mtimecmp_set( + tmr_intc, __metal_driver_cpu_hartid(cpu), time); } } return rc; } struct metal_interrupt * -__metal_driver_cpu_timer_controller_interrupt(struct metal_cpu *cpu) -{ +__metal_driver_cpu_timer_controller_interrupt(struct metal_cpu *cpu) { #ifdef __METAL_DT_RISCV_CLINT0_HANDLE return __METAL_DT_RISCV_CLINT0_HANDLE; #else @@ -830,14 +698,12 @@ __metal_driver_cpu_timer_controller_interrupt(struct metal_cpu *cpu) #endif } -int __metal_driver_cpu_get_timer_interrupt_id(struct metal_cpu *cpu) -{ +int __metal_driver_cpu_get_timer_interrupt_id(struct metal_cpu *cpu) { return METAL_INTERRUPT_ID_TMR; } struct metal_interrupt * -__metal_driver_cpu_sw_controller_interrupt(struct metal_cpu *cpu) -{ +__metal_driver_cpu_sw_controller_interrupt(struct metal_cpu *cpu) { #ifdef __METAL_DT_RISCV_CLINT0_HANDLE return __METAL_DT_RISCV_CLINT0_HANDLE; #else @@ -850,142 +716,153 @@ __metal_driver_cpu_sw_controller_interrupt(struct metal_cpu *cpu) #endif } -int __metal_driver_cpu_get_sw_interrupt_id(struct metal_cpu *cpu) -{ +int __metal_driver_cpu_get_sw_interrupt_id(struct metal_cpu *cpu) { return METAL_INTERRUPT_ID_SW; } -int __metal_driver_cpu_set_sw_ipi (struct metal_cpu *cpu, int hartid) -{ +int __metal_driver_cpu_set_sw_ipi(struct metal_cpu *cpu, int hartid) { int rc = -1; struct metal_interrupt *sw_intc; - struct __metal_driver_riscv_cpu_intc *intc = - (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); + struct __metal_driver_riscv_cpu_intc *intc = + (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller(cpu); if (intc) { sw_intc = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int; if (sw_intc) { - rc = sw_intc->vtable->command_request(sw_intc, - METAL_SOFTWARE_IPI_SET, &hartid); + rc = sw_intc->vtable->command_request( + sw_intc, METAL_SOFTWARE_IPI_SET, &hartid); } } return rc; } -int __metal_driver_cpu_clear_sw_ipi (struct metal_cpu *cpu, int hartid) -{ +int __metal_driver_cpu_clear_sw_ipi(struct metal_cpu *cpu, int hartid) { int rc = -1; struct metal_interrupt *sw_intc; struct __metal_driver_riscv_cpu_intc *intc = - (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); + (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller(cpu); if (intc) { sw_intc = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int; if (sw_intc) { - rc = sw_intc->vtable->command_request(sw_intc, - METAL_SOFTWARE_IPI_CLEAR, &hartid); + rc = sw_intc->vtable->command_request( + sw_intc, METAL_SOFTWARE_IPI_CLEAR, &hartid); } } return rc; } -int __metal_driver_cpu_get_msip (struct metal_cpu *cpu, int hartid) -{ +int __metal_driver_cpu_get_msip(struct metal_cpu *cpu, int hartid) { int rc = 0; struct metal_interrupt *sw_intc; struct __metal_driver_riscv_cpu_intc *intc = - (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); + (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller(cpu); if (intc) { sw_intc = intc->metal_int_table[METAL_INTERRUPT_ID_SW].sub_int; if (sw_intc) { - rc = sw_intc->vtable->command_request(sw_intc, - METAL_SOFTWARE_MSIP_GET, &hartid); + rc = sw_intc->vtable->command_request( + sw_intc, METAL_SOFTWARE_MSIP_GET, &hartid); } } return rc; } struct metal_interrupt * -__metal_driver_cpu_controller_interrupt(struct metal_cpu *cpu) -{ +__metal_driver_cpu_controller_interrupt(struct metal_cpu *cpu) { return __metal_driver_cpu_interrupt_controller(cpu); } -int __metal_driver_cpu_enable_interrupt(struct metal_cpu *cpu, void *priv) -{ - if ( __metal_driver_cpu_interrupt_controller(cpu) ) { +int __metal_driver_cpu_enable_interrupt(struct metal_cpu *cpu, void *priv) { + if (__metal_driver_cpu_interrupt_controller(cpu)) { /* Only support machine mode for now */ __metal_interrupt_global_enable(); - return 0; + return 0; } return -1; } -int __metal_driver_cpu_disable_interrupt(struct metal_cpu *cpu, void *priv) -{ - if ( __metal_driver_cpu_interrupt_controller(cpu) ) { +int __metal_driver_cpu_disable_interrupt(struct metal_cpu *cpu, void *priv) { + if (__metal_driver_cpu_interrupt_controller(cpu)) { /* Only support machine mode for now */ __metal_interrupt_global_disable(); - return 0; + return 0; } return -1; } int __metal_driver_cpu_exception_register(struct metal_cpu *cpu, int ecode, - metal_exception_handler_t isr) -{ + metal_exception_handler_t isr) { struct __metal_driver_riscv_cpu_intc *intc = - (struct __metal_driver_riscv_cpu_intc *)__metal_driver_cpu_interrupt_controller(cpu); + (struct __metal_driver_riscv_cpu_intc *) + __metal_driver_cpu_interrupt_controller(cpu); if (intc) { - return __metal_exception_register((struct metal_interrupt *)intc, ecode, isr); + return __metal_exception_register((struct metal_interrupt *)intc, ecode, + isr); } return -1; } -int __metal_driver_cpu_get_instruction_length(struct metal_cpu *cpu, uintptr_t epc) -{ +int __metal_driver_cpu_get_instruction_length(struct metal_cpu *cpu, + uintptr_t epc) { /** * Per ISA compressed instruction has last two bits of opcode set. * The encoding '00' '01' '10' are used for compressed instruction. * Only enconding '11' isn't regarded as compressed instruction (>16b). */ - return ((*(unsigned short*)epc & METAL_INSN_LENGTH_MASK) - == METAL_INSN_NOT_COMPRESSED) ? 4 : 2; + return ((*(unsigned short *)epc & METAL_INSN_LENGTH_MASK) == + METAL_INSN_NOT_COMPRESSED) + ? 4 + : 2; } -uintptr_t __metal_driver_cpu_get_exception_pc(struct metal_cpu *cpu) -{ +uintptr_t __metal_driver_cpu_get_exception_pc(struct metal_cpu *cpu) { uintptr_t mepc; - __asm__ volatile ("csrr %0, mepc" : "=r"(mepc)); + __asm__ volatile("csrr %0, mepc" : "=r"(mepc)); return mepc; } -int __metal_driver_cpu_set_exception_pc(struct metal_cpu *cpu, uintptr_t mepc) -{ - __asm__ volatile ("csrw mepc, %0" :: "r"(mepc)); +int __metal_driver_cpu_set_exception_pc(struct metal_cpu *cpu, uintptr_t mepc) { + __asm__ volatile("csrw mepc, %0" ::"r"(mepc)); return 0; } +struct metal_buserror *__metal_driver_cpu_get_buserror(struct metal_cpu *cpu) { + return __metal_driver_cpu_buserror(cpu); +} + __METAL_DEFINE_VTABLE(__metal_driver_vtable_riscv_cpu_intc) = { - .controller_vtable.interrupt_init = __metal_driver_riscv_cpu_controller_interrupt_init, - .controller_vtable.interrupt_register = __metal_driver_riscv_cpu_controller_interrupt_register, - .controller_vtable.interrupt_enable = __metal_driver_riscv_cpu_controller_interrupt_enable, - .controller_vtable.interrupt_disable = __metal_driver_riscv_cpu_controller_interrupt_disable, - .controller_vtable.interrupt_get_vector_mode = __metal_driver_riscv_cpu_controller_get_vector_mode, - .controller_vtable.interrupt_set_vector_mode = __metal_driver_riscv_cpu_controller_set_vector_mode, - .controller_vtable.command_request = __metal_driver_riscv_cpu_controller_command_request, + .controller_vtable.interrupt_init = + __metal_driver_riscv_cpu_controller_interrupt_init, + .controller_vtable.interrupt_register = + __metal_driver_riscv_cpu_controller_interrupt_register, + .controller_vtable.interrupt_enable = + __metal_driver_riscv_cpu_controller_interrupt_enable, + .controller_vtable.interrupt_disable = + __metal_driver_riscv_cpu_controller_interrupt_disable, + .controller_vtable.interrupt_get_vector_mode = + __metal_driver_riscv_cpu_controller_get_vector_mode, + .controller_vtable.interrupt_set_vector_mode = + __metal_driver_riscv_cpu_controller_set_vector_mode, + .controller_vtable.command_request = + __metal_driver_riscv_cpu_controller_command_request, }; __METAL_DEFINE_VTABLE(__metal_driver_vtable_cpu) = { - .cpu_vtable.mcycle_get = __metal_driver_cpu_mcycle_get, - .cpu_vtable.timebase_get = __metal_driver_cpu_timebase_get, + .cpu_vtable.mcycle_get = __metal_driver_cpu_mcycle_get, + .cpu_vtable.timebase_get = __metal_driver_cpu_timebase_get, .cpu_vtable.mtime_get = __metal_driver_cpu_mtime_get, .cpu_vtable.mtimecmp_set = __metal_driver_cpu_mtimecmp_set, - .cpu_vtable.tmr_controller_interrupt = __metal_driver_cpu_timer_controller_interrupt, - .cpu_vtable.get_tmr_interrupt_id = __metal_driver_cpu_get_timer_interrupt_id, - .cpu_vtable.sw_controller_interrupt = __metal_driver_cpu_sw_controller_interrupt, + .cpu_vtable.tmr_controller_interrupt = + __metal_driver_cpu_timer_controller_interrupt, + .cpu_vtable.get_tmr_interrupt_id = + __metal_driver_cpu_get_timer_interrupt_id, + .cpu_vtable.sw_controller_interrupt = + __metal_driver_cpu_sw_controller_interrupt, .cpu_vtable.get_sw_interrupt_id = __metal_driver_cpu_get_sw_interrupt_id, .cpu_vtable.set_sw_ipi = __metal_driver_cpu_set_sw_ipi, .cpu_vtable.clear_sw_ipi = __metal_driver_cpu_clear_sw_ipi, @@ -995,5 +872,5 @@ __METAL_DEFINE_VTABLE(__metal_driver_vtable_cpu) = { .cpu_vtable.get_ilen = __metal_driver_cpu_get_instruction_length, .cpu_vtable.get_epc = __metal_driver_cpu_get_exception_pc, .cpu_vtable.set_epc = __metal_driver_cpu_set_exception_pc, + .cpu_vtable.get_buserror = __metal_driver_cpu_get_buserror, }; - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_plic0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_plic0.c index 3272f1c66..21d16ab1c 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_plic0.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/riscv_plic0.c @@ -5,189 +5,308 @@ #ifdef METAL_RISCV_PLIC0 -#include <metal/io.h> -#include <metal/shutdown.h> +#define PLIC0_MAX_INTERRUPTS 1024 + #include <metal/drivers/riscv_plic0.h> +#include <metal/interrupt.h> +#include <metal/io.h> #include <metal/machine.h> +#include <metal/shutdown.h> -unsigned int __metal_plic0_claim_interrupt (struct __metal_driver_riscv_plic0 *plic) -{ - unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)plic); - return __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - METAL_RISCV_PLIC0_CLAIM)); +unsigned int +__metal_plic0_claim_interrupt(struct __metal_driver_riscv_plic0 *plic, + int context_id) { + unsigned long control_base = __metal_driver_sifive_plic0_control_base( + (struct metal_interrupt *)plic); + return __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(control_base + METAL_RISCV_PLIC0_CONTEXT_BASE + + (context_id * METAL_RISCV_PLIC0_CONTEXT_PER_HART) + + METAL_RISCV_PLIC0_CONTEXT_CLAIM)); } void __metal_plic0_complete_interrupt(struct __metal_driver_riscv_plic0 *plic, - unsigned int id) -{ - unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)plic); - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - METAL_RISCV_PLIC0_CLAIM)) = id; -} - -int __metal_plic0_set_threshold(struct metal_interrupt *controller, unsigned int threshold) -{ - unsigned long control_base = __metal_driver_sifive_plic0_control_base(controller); - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - METAL_RISCV_PLIC0_THRESHOLD)) = threshold; - return 0; + int context_id, unsigned int id) { + unsigned long control_base = __metal_driver_sifive_plic0_control_base( + (struct metal_interrupt *)plic); + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(control_base + METAL_RISCV_PLIC0_CONTEXT_BASE + + (context_id * METAL_RISCV_PLIC0_CONTEXT_PER_HART) + + METAL_RISCV_PLIC0_CONTEXT_CLAIM)) = id; } -unsigned int __metal_plic0_get_threshold(struct metal_interrupt *controller) -{ - unsigned long control_base = __metal_driver_sifive_plic0_control_base(controller); +int __metal_plic0_set_threshold(struct metal_interrupt *controller, + int context_id, unsigned int threshold) { + unsigned long control_base = + __metal_driver_sifive_plic0_control_base(controller); + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(control_base + METAL_RISCV_PLIC0_CONTEXT_BASE + + (context_id * METAL_RISCV_PLIC0_CONTEXT_PER_HART) + + METAL_RISCV_PLIC0_CONTEXT_THRESHOLD)) = threshold; + return 0; +} - return __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - METAL_RISCV_PLIC0_THRESHOLD)); +unsigned int __metal_plic0_get_threshold(struct metal_interrupt *controller, + int context_id) { + unsigned long control_base = + __metal_driver_sifive_plic0_control_base(controller); + return __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(control_base + METAL_RISCV_PLIC0_CONTEXT_BASE + + (context_id * METAL_RISCV_PLIC0_CONTEXT_PER_HART) + + METAL_RISCV_PLIC0_CONTEXT_THRESHOLD)); } -int __metal_plic0_set_priority(struct metal_interrupt *controller, int id, unsigned int priority) -{ - unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)controller); - unsigned int max_priority = __metal_driver_sifive_plic0_max_priority((struct metal_interrupt *)controller); - if ( (max_priority) && (priority < max_priority) ) { - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - METAL_RISCV_PLIC0_PRIORITY_BASE + - (id << METAL_PLIC_SOURCE_PRIORITY_SHIFT))) = priority; +int __metal_driver_riscv_plic0_set_priority(struct metal_interrupt *controller, + int id, unsigned int priority) { + unsigned long control_base = __metal_driver_sifive_plic0_control_base( + (struct metal_interrupt *)controller); + unsigned int max_priority = __metal_driver_sifive_plic0_max_priority( + (struct metal_interrupt *)controller); + if ((max_priority) && (priority < max_priority)) { + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(control_base + METAL_RISCV_PLIC0_PRIORITY_BASE + + (id << METAL_PLIC_SOURCE_PRIORITY_SHIFT))) = + priority; return 0; } return -1; } -unsigned int __metal_plic0_get_priority(struct metal_interrupt *controller, int id) -{ - unsigned long control_base = __metal_driver_sifive_plic0_control_base(controller); +unsigned int +__metal_driver_riscv_plic0_get_priority(struct metal_interrupt *controller, + int id) { + unsigned long control_base = + __metal_driver_sifive_plic0_control_base(controller); - return __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - METAL_RISCV_PLIC0_PRIORITY_BASE + - (id << METAL_PLIC_SOURCE_PRIORITY_SHIFT))); + return __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(control_base + METAL_RISCV_PLIC0_PRIORITY_BASE + + (id << METAL_PLIC_SOURCE_PRIORITY_SHIFT))); } -void __metal_plic0_enable(struct __metal_driver_riscv_plic0 *plic, int id, int enable) -{ +int __metal_plic0_enable(struct __metal_driver_riscv_plic0 *plic, + int context_id, int id, int enable) { unsigned int current; - unsigned long control_base = __metal_driver_sifive_plic0_control_base((struct metal_interrupt *)plic); + unsigned long control_base = __metal_driver_sifive_plic0_control_base( + (struct metal_interrupt *)plic); + + current = __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(control_base + METAL_RISCV_PLIC0_ENABLE_BASE + + (context_id * METAL_RISCV_PLIC0_ENABLE_PER_HART) + + (id >> METAL_PLIC_SOURCE_SHIFT) * 4)); + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(control_base + METAL_RISCV_PLIC0_ENABLE_BASE + + (context_id * METAL_RISCV_PLIC0_ENABLE_PER_HART) + + ((id >> METAL_PLIC_SOURCE_SHIFT) * 4))) = + enable ? (current | (1 << (id & METAL_PLIC_SOURCE_MASK))) + : (current & ~(1 << (id & METAL_PLIC_SOURCE_MASK))); - current = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - METAL_RISCV_PLIC0_ENABLE_BASE + - (id >> METAL_PLIC_SOURCE_SHIFT) * 4)); - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - METAL_RISCV_PLIC0_ENABLE_BASE + - ((id >> METAL_PLIC_SOURCE_SHIFT) * 4))) = - enable ? (current | (1 << (id & METAL_PLIC_SOURCE_MASK))) - : (current & ~(1 << (id & METAL_PLIC_SOURCE_MASK))); + return 0; } -void __metal_plic0_default_handler (int id, void *priv) { - metal_shutdown(300); -} +void __metal_plic0_default_handler(int id, void *priv) { metal_shutdown(300); } -void __metal_plic0_handler (int id, void *priv) -{ +void __metal_plic0_handler(int id, void *priv) { struct __metal_driver_riscv_plic0 *plic = priv; - unsigned int idx = __metal_plic0_claim_interrupt(plic); - unsigned int num_interrupts = __metal_driver_sifive_plic0_num_interrupts((struct metal_interrupt *)plic); - - if ( (idx < num_interrupts) && (plic->metal_exint_table[idx]) ) { - plic->metal_exint_table[idx](idx, - plic->metal_exdata_table[idx].exint_data); + int contextid = + __metal_driver_sifive_plic0_context_ids(__metal_myhart_id()); + unsigned int idx = __metal_plic0_claim_interrupt(plic, contextid); + unsigned int num_interrupts = __metal_driver_sifive_plic0_num_interrupts( + (struct metal_interrupt *)plic); + + if ((idx < num_interrupts) && (plic->metal_exint_table[idx])) { + plic->metal_exint_table[idx](idx, + plic->metal_exdata_table[idx].exint_data); } - __metal_plic0_complete_interrupt(plic, idx); + __metal_plic0_complete_interrupt(plic, contextid, idx); } -void __metal_driver_riscv_plic0_init (struct metal_interrupt *controller) -{ +void __metal_driver_riscv_plic0_init(struct metal_interrupt *controller) { struct __metal_driver_riscv_plic0 *plic = (void *)(controller); - if ( !plic->init_done ) { + if (!plic->init_done) { int num_interrupts, line; struct metal_interrupt *intc; - for(int parent = 0; parent < __METAL_PLIC_NUM_PARENTS; parent++) { - num_interrupts = __metal_driver_sifive_plic0_num_interrupts(controller); - intc = __metal_driver_sifive_plic0_interrupt_parents(controller, parent); - line = __metal_driver_sifive_plic0_interrupt_lines(controller, parent); - - /* Initialize ist parent controller, aka cpu_intc. */ - intc->vtable->interrupt_init(intc); - - for (int i = 0; i < num_interrupts; i++) { - __metal_plic0_enable(plic, i, METAL_DISABLE); - __metal_plic0_set_priority(controller, i, 0); - plic->metal_exint_table[i] = NULL; - plic->metal_exdata_table[i].sub_int = NULL; - plic->metal_exdata_table[i].exint_data = NULL; - } - - __metal_plic0_set_threshold(controller, 0); - - /* Register plic (ext) interrupt with with parent controller */ - intc->vtable->interrupt_register(intc, line, NULL, plic); - /* Register plic handler for dispatching its device interrupts */ - intc->vtable->interrupt_register(intc, line, __metal_plic0_handler, plic); - /* Enable plic (ext) interrupt with with parent controller */ - intc->vtable->interrupt_enable(intc, line); - } + for (int parent = 0; parent < __METAL_PLIC_NUM_PARENTS; parent++) { + num_interrupts = + __metal_driver_sifive_plic0_num_interrupts(controller); + intc = __metal_driver_sifive_plic0_interrupt_parents(controller, + parent); + line = + __metal_driver_sifive_plic0_interrupt_lines(controller, parent); + + /* Initialize ist parent controller, aka cpu_intc. */ + intc->vtable->interrupt_init(intc); + + for (int i = 0; i < PLIC0_MAX_INTERRUPTS; i++) { + __metal_plic0_enable(plic, parent, i, METAL_DISABLE); + if (i < num_interrupts) { + __metal_driver_riscv_plic0_set_priority(controller, i, 0); + plic->metal_exint_table[i] = NULL; + plic->metal_exdata_table[i].sub_int = NULL; + plic->metal_exdata_table[i].exint_data = NULL; + } + } + + __metal_plic0_set_threshold(controller, parent, 0); + + /* Register plic (ext) interrupt with with parent controller */ + intc->vtable->interrupt_register(intc, line, NULL, plic); + /* Register plic handler for dispatching its device interrupts */ + intc->vtable->interrupt_register(intc, line, __metal_plic0_handler, + plic); + /* Enable plic (ext) interrupt with with parent controller */ + intc->vtable->interrupt_enable(intc, line); + } plic->init_done = 1; } } -int __metal_driver_riscv_plic0_register (struct metal_interrupt *controller, - int id, metal_interrupt_handler_t isr, - void *priv) -{ +int __metal_driver_riscv_plic0_register(struct metal_interrupt *controller, + int id, metal_interrupt_handler_t isr, + void *priv) { struct __metal_driver_riscv_plic0 *plic = (void *)(controller); if (id >= __metal_driver_sifive_plic0_num_interrupts(controller)) { return -1; } - + if (isr) { - __metal_plic0_set_priority(controller, id, 2); - plic->metal_exint_table[id] = isr; - plic->metal_exdata_table[id].exint_data = priv; + __metal_driver_riscv_plic0_set_priority(controller, id, 2); + plic->metal_exint_table[id] = isr; + plic->metal_exdata_table[id].exint_data = priv; } else { - __metal_plic0_set_priority(controller, id, 1); - plic->metal_exint_table[id] = __metal_plic0_default_handler; - plic->metal_exdata_table[id].sub_int = priv; + __metal_driver_riscv_plic0_set_priority(controller, id, 1); + plic->metal_exint_table[id] = __metal_plic0_default_handler; + plic->metal_exdata_table[id].sub_int = priv; } return 0; } -int __metal_driver_riscv_plic0_enable (struct metal_interrupt *controller, int id) -{ +int __metal_driver_riscv_plic0_enable(struct metal_interrupt *controller, + int id) { struct __metal_driver_riscv_plic0 *plic = (void *)(controller); if (id >= __metal_driver_sifive_plic0_num_interrupts(controller)) { return -1; } - __metal_plic0_enable(plic, id, METAL_ENABLE); + __metal_plic0_enable(plic, __metal_myhart_id(), id, METAL_ENABLE); return 0; } -int __metal_driver_riscv_plic0_disable (struct metal_interrupt *controller, int id) -{ +int __metal_driver_riscv_plic0_disable(struct metal_interrupt *controller, + int id) { struct __metal_driver_riscv_plic0 *plic = (void *)(controller); if (id >= __metal_driver_sifive_plic0_num_interrupts(controller)) { return -1; } - __metal_plic0_enable(plic, id, METAL_DISABLE); + __metal_plic0_enable(plic, __metal_myhart_id(), id, METAL_DISABLE); + return 0; +} + +int __metal_driver_riscv_plic0_set_threshold(struct metal_interrupt *controller, + unsigned int threshold) { + return __metal_plic0_set_threshold(controller, __metal_myhart_id(), + threshold); +} + +unsigned int +__metal_driver_riscv_plic0_get_threshold(struct metal_interrupt *controller) { + return __metal_plic0_get_threshold(controller, __metal_myhart_id()); +} + +metal_affinity +__metal_driver_riscv_plic0_affinity_enable(struct metal_interrupt *controller, + metal_affinity bitmask, int id) { + metal_affinity ret = {0}; + int context; + + struct __metal_driver_riscv_plic0 *plic = (void *)(controller); + + if (id >= __metal_driver_sifive_plic0_num_interrupts(controller)) { + metal_affinity_set_val(ret, -1); + return ret; + } + + for_each_metal_affinity(context, bitmask) { + if (context != 0) + metal_affinity_set_bit( + ret, context, + __metal_plic0_enable(plic, context, id, METAL_ENABLE)); + } + + return ret; +} + +metal_affinity +__metal_driver_riscv_plic0_affinity_disable(struct metal_interrupt *controller, + metal_affinity bitmask, int id) { + metal_affinity ret = {0}; + int context; + + struct __metal_driver_riscv_plic0 *plic = (void *)(controller); + + if (id >= __metal_driver_sifive_plic0_num_interrupts(controller)) { + metal_affinity_set_val(ret, -1); + return ret; + } + + for_each_metal_affinity(context, bitmask) { + if (context != 0) + metal_affinity_set_bit( + ret, context, + __metal_plic0_enable(plic, context, id, METAL_DISABLE)); + } + + return ret; +} + +metal_affinity __metal_driver_riscv_plic0_affinity_set_threshold( + struct metal_interrupt *controller, metal_affinity bitmask, + unsigned int threshold) { + metal_affinity ret = {0}; + int context; + + for_each_metal_affinity(context, bitmask) { + if (context != 0) + metal_affinity_set_bit( + ret, context, + __metal_plic0_set_threshold(controller, context, threshold)); + } + + return ret; +} + +unsigned int __metal_driver_riscv_plic0_affinity_get_threshold( + struct metal_interrupt *controller, int context_id) { + __metal_plic0_get_threshold(controller, context_id); return 0; } __METAL_DEFINE_VTABLE(__metal_driver_vtable_riscv_plic0) = { .plic_vtable.interrupt_init = __metal_driver_riscv_plic0_init, .plic_vtable.interrupt_register = __metal_driver_riscv_plic0_register, - .plic_vtable.interrupt_enable = __metal_driver_riscv_plic0_enable, - .plic_vtable.interrupt_disable = __metal_driver_riscv_plic0_disable, - .plic_vtable.interrupt_get_threshold = __metal_plic0_get_threshold, - .plic_vtable.interrupt_set_threshold = __metal_plic0_set_threshold, - .plic_vtable.interrupt_get_priority = __metal_plic0_get_priority, - .plic_vtable.interrupt_set_priority = __metal_plic0_set_priority, + .plic_vtable.interrupt_enable = __metal_driver_riscv_plic0_enable, + .plic_vtable.interrupt_disable = __metal_driver_riscv_plic0_disable, + .plic_vtable.interrupt_get_threshold = + __metal_driver_riscv_plic0_get_threshold, + .plic_vtable.interrupt_set_threshold = + __metal_driver_riscv_plic0_set_threshold, + .plic_vtable.interrupt_get_priority = + __metal_driver_riscv_plic0_get_priority, + .plic_vtable.interrupt_set_priority = + __metal_driver_riscv_plic0_set_priority, + .plic_vtable.interrupt_affinity_enable = + __metal_driver_riscv_plic0_affinity_enable, + .plic_vtable.interrupt_affinity_disable = + __metal_driver_riscv_plic0_affinity_disable, + .plic_vtable.interrupt_affinity_get_threshold = + __metal_driver_riscv_plic0_affinity_get_threshold, + .plic_vtable.interrupt_affinity_set_threshold = + __metal_driver_riscv_plic0_affinity_set_threshold, }; #endif /* METAL_RISCV_PLIC0 */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_buserror0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_buserror0.c new file mode 100644 index 000000000..3a68fef44 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_buserror0.c @@ -0,0 +1,257 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include <metal/drivers/sifive_buserror0.h> +#include <metal/machine/platform.h> +#include <stddef.h> +#include <stdint.h> + +#ifdef METAL_SIFIVE_BUSERROR0 + +#include <metal/cpu.h> +#include <metal/init.h> +#include <metal/io.h> +#include <metal/machine.h> + +/* Enable all events on all hart bus error units */ +METAL_CONSTRUCTOR(metal_driver_sifive_buserror_init) { + for (int hart = 0; hart < metal_cpu_get_num_harts(); hart++) { + struct metal_cpu *cpu = metal_cpu_get(hart); + if (cpu != NULL) { + struct metal_buserror *beu = metal_cpu_get_buserror(cpu); + if (beu != NULL) { + metal_buserror_set_event_enabled(beu, METAL_BUSERROR_EVENT_ALL, + true); + } + } + } +} + +int metal_buserror_set_event_enabled(struct metal_buserror *beu, + metal_buserror_event_t events, + bool enabled) { + uintptr_t base = __metal_driver_sifive_buserror0_control_base(beu); + if (base == (uintptr_t)NULL) { + return 1; + } + if (!(events & METAL_BUSERROR_EVENT_ANY)) { + return 2; + } + + uintptr_t reg_enable = base + METAL_SIFIVE_BUSERROR0_ENABLE; + + if (enabled) { + __METAL_ACCESS_ONCE((__metal_io_u8 *)reg_enable) |= events; + } else { + __METAL_ACCESS_ONCE((__metal_io_u8 *)reg_enable) &= ~events; + } + + if (!(events & __METAL_ACCESS_ONCE((__metal_io_u8 *)reg_enable))) { + return __METAL_ACCESS_ONCE((__metal_io_u8 *)reg_enable); + } + + return 0; +} + +metal_buserror_event_t +metal_buserror_get_event_enabled(struct metal_buserror *beu) { + uintptr_t base = __metal_driver_sifive_buserror0_control_base(beu); + if (base == (uintptr_t)NULL) { + return 1; + } + + uintptr_t reg_enable = base + METAL_SIFIVE_BUSERROR0_ENABLE; + + return __METAL_ACCESS_ONCE((__metal_io_u8 *)reg_enable); +} + +int metal_buserror_set_platform_interrupt(struct metal_buserror *beu, + metal_buserror_event_t events, + bool enabled) { + uintptr_t base = __metal_driver_sifive_buserror0_control_base(beu); + if (base == (uintptr_t)NULL) { + return 1; + } + if (!(events & METAL_BUSERROR_EVENT_ANY)) { + return 2; + } + + uintptr_t platform_interrupt = + base + METAL_SIFIVE_BUSERROR0_PLATFORM_INTERRUPT; + + if (enabled) { + __METAL_ACCESS_ONCE((__metal_io_u8 *)platform_interrupt) |= events; + } else { + __METAL_ACCESS_ONCE((__metal_io_u8 *)platform_interrupt) &= ~events; + } + + return 0; +} + +int metal_buserror_set_local_interrupt(struct metal_buserror *beu, + metal_buserror_event_t events, + bool enabled) { + uintptr_t base = __metal_driver_sifive_buserror0_control_base(beu); + if (base == (uintptr_t)NULL) { + return 1; + } + if (!(events & METAL_BUSERROR_EVENT_ANY)) { + return 2; + } + + uintptr_t local_interrupt = base + METAL_SIFIVE_BUSERROR0_LOCAL_INTERRUPT; + + if (enabled) { + __METAL_ACCESS_ONCE((__metal_io_u8 *)local_interrupt) |= events; + } else { + __METAL_ACCESS_ONCE((__metal_io_u8 *)local_interrupt) &= ~events; + } + + return 0; +} + +metal_buserror_event_t metal_buserror_get_cause(struct metal_buserror *beu) { + uintptr_t base = __metal_driver_sifive_buserror0_control_base(beu); + if (base == (uintptr_t)NULL) { + return METAL_BUSERROR_EVENT_INVALID; + } + + uintptr_t cause = base + METAL_SIFIVE_BUSERROR0_CAUSE; + + return (metal_buserror_event_t)( + 1 << __METAL_ACCESS_ONCE((__metal_io_u8 *)cause)); +} + +int metal_buserror_clear_cause(struct metal_buserror *beu) { + uintptr_t base = __metal_driver_sifive_buserror0_control_base(beu); + if (base == (uintptr_t)NULL) { + /* We return (1 << 8) because the value of the cause register + * can never equal that value */ + return (1 << 8); + } + + uintptr_t cause = base + METAL_SIFIVE_BUSERROR0_CAUSE; + __METAL_ACCESS_ONCE((__metal_io_u8 *)cause) = METAL_BUSERROR_EVENT_NONE; + + return __METAL_ACCESS_ONCE((__metal_io_u8 *)cause); +} + +uintptr_t metal_buserror_get_event_address(struct metal_buserror *beu) { + uintptr_t base = __metal_driver_sifive_buserror0_control_base(beu); + if (base == (uintptr_t)NULL) { + return 0; + } + + uintptr_t value = base + METAL_SIFIVE_BUSERROR0_VALUE; + + return __METAL_ACCESS_ONCE((__metal_io_u8 *)value); +} + +bool metal_buserror_is_event_accrued(struct metal_buserror *beu, + metal_buserror_event_t events) { + uintptr_t base = __metal_driver_sifive_buserror0_control_base(beu); + if (base == (uintptr_t)NULL) { + return false; + } + + uintptr_t accrued = base + METAL_SIFIVE_BUSERROR0_ACCRUED; + + if (!(events & METAL_BUSERROR_EVENT_ANY)) { + return false; + } + + return !!(events & __METAL_ACCESS_ONCE((__metal_io_u8 *)accrued)); +} + +int metal_buserror_clear_event_accrued(struct metal_buserror *beu, + metal_buserror_event_t events) { + uintptr_t base = __metal_driver_sifive_buserror0_control_base(beu); + if (base == (uintptr_t)NULL) { + /* We return (1 << 8) because the value of the accrued register + * can never equal that value */ + return (1 << 8); + } + + uintptr_t accrued = base + METAL_SIFIVE_BUSERROR0_ACCRUED; + + if (!(events & METAL_BUSERROR_EVENT_ANY)) { + /* We return (1 << 9) because the value of the accrued register + * can never equal that value */ + return (1 << 9); + } else { + __METAL_ACCESS_ONCE((__metal_io_u8 *)accrued) &= ~events; + if (events & __METAL_ACCESS_ONCE((__metal_io_u8 *)accrued)) { + return __METAL_ACCESS_ONCE((__metal_io_u8 *)accrued); + } + } + + return 0; +} + +struct metal_interrupt * +metal_buserror_get_platform_interrupt_parent(struct metal_buserror *beu) { + return __metal_driver_sifive_buserror0_interrupt_parent(beu); +} + +int metal_buserror_get_platform_interrupt_id(struct metal_buserror *beu) { + return __metal_driver_sifive_buserror0_interrupt_id(beu); +} + +int metal_buserror_get_local_interrupt_id(struct metal_buserror *beu) { + return 128; +} + +#else + +int metal_buserror_set_event_enabled(struct metal_buserror *beu, + metal_buserror_event_t event, + bool enabled) { + return 1; +} + +int metal_buserror_set_platform_interrupt(struct metal_buserror *beu, + metal_buserror_event_t event, + bool enabled) { + return 1; +} + +int metal_buserror_set_local_interrupt(struct metal_buserror *beu, + metal_buserror_event_t event, + bool enabled) { + return 1; +} + +metal_buserror_event_t metal_buserror_get_cause(struct metal_buserror *beu) { + return METAL_BUSERROR_EVENT_INVALID; +} + +int metal_buserror_clear_cause(struct metal_buserror *beu) { return (1 << 9); } + +uintptr_t metal_buserror_get_event_address(struct metal_buserror *beu) { + return 0; +} + +bool metal_buserror_is_event_accrued(struct metal_buserror *beu, + metal_buserror_event_t event) { + return false; +} + +int metal_buserror_clear_event_accrued(struct metal_buserror *beu, + metal_buserror_event_t event) { + return (1 << 8); +} + +struct metal_interrupt * +metal_buserror_get_platform_interrupt_parent(struct metal_buserror *beu) { + return NULL; +} + +int metal_buserror_get_platform_interrupt_id(struct metal_buserror *beu) { + return 0; +} + +int metal_buserror_get_local_interrupt_id(struct metal_buserror *beu) { + return 0; +} + +#endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_ccache0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_ccache0.c index 6f8723735..76aeb25cc 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_ccache0.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_ccache0.c @@ -1,83 +1,311 @@ -/* Copyright 2019 SiFive, Inc */ +/* Copyright 2020 SiFive, Inc */ /* SPDX-License-Identifier: Apache-2.0 */ #include <metal/machine/platform.h> #ifdef METAL_SIFIVE_CCACHE0 -#include <stdint.h> -#include <metal/io.h> #include <metal/drivers/sifive_ccache0.h> +#include <metal/init.h> #include <metal/machine.h> +#include <stdint.h> + +/* Macros to access memory mapped registers */ +#define REGW(x) *(volatile uint32_t *)(METAL_SIFIVE_CCACHE0_0_BASE_ADDRESS + x) + +#define REGD(x) *(volatile uint64_t *)(METAL_SIFIVE_CCACHE0_0_BASE_ADDRESS + x) + +/* Macros to specify register bit shift */ +#define REG_SHIFT_4 4 +#define REG_SHIFT_8 8 +#define REG_SHIFT_16 16 +#define REG_SHIFT_24 24 + +#define SIFIVE_CCACHE0_BYTE_MASK 0xFFUL -#define L2_CONFIG_WAYS_SHIFT 8 -#define L2_CONFIG_WAYS_MASK (0xFF << L2_CONFIG_WAYS_SHIFT) +static int sifive_ccache0_interrupts[] = METAL_SIFIVE_CCACHE0_INTERRUPTS; -void __metal_driver_sifive_ccache0_init(struct metal_cache *l2, int ways); +/* Initialize cache at start-up via metal constructors */ +METAL_CONSTRUCTOR(_sifive_ccache0_init) { sifive_ccache0_init(); } -static void metal_driver_sifive_ccache0_init(void) __attribute__((constructor)); -static void metal_driver_sifive_ccache0_init(void) -{ -#ifdef __METAL_DT_SIFIVE_CCACHE0_HANDLE - /* Get the handle for the L2 cache controller */ - struct metal_cache *l2 = __METAL_DT_SIFIVE_CCACHE0_HANDLE; - if(!l2) { - return; +/* Linker symbols to calculate LIM allocated size */ +extern char metal_segment_lim_target_start, metal_segment_lim_target_end; + +int sifive_ccache0_init(void) { + int ret; + + sifive_ccache0_config config; + + /* Get cache configuration data */ + sifive_ccache0_get_config(&config); + + int lim_size = + &metal_segment_lim_target_end - &metal_segment_lim_target_start; + + if (lim_size) { /* Do not enable cache ways, corresponding to LIM area in + use. */ + while (lim_size > 0) { + lim_size -= (config.block_size * config.num_sets * config.num_bank); + config.num_ways--; + } } - /* Get the number of available ways per bank */ - unsigned long control_base = __metal_driver_sifive_ccache0_control_base(l2); - uint32_t ways = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CCACHE0_CONFIG)); - ways = ((ways & L2_CONFIG_WAYS_MASK) >> L2_CONFIG_WAYS_SHIFT); + /* Enable ways */ + ret = sifive_ccache0_set_enabled_ways(config.num_ways); - /* Enable all the ways */ - __metal_driver_sifive_ccache0_init(l2, ways); -#endif + return ret; } -void __metal_driver_sifive_ccache0_init(struct metal_cache *l2, int ways) -{ - metal_cache_set_enabled_ways(l2, ways); +void sifive_ccache0_get_config(sifive_ccache0_config *config) { + uint32_t val; + + if (config) /* Check for NULL */ + { + val = REGW(METAL_SIFIVE_CCACHE0_CONFIG); + + /* Populate cache configuration data */ + config->num_bank = (val & SIFIVE_CCACHE0_BYTE_MASK); + config->num_ways = ((val >> REG_SHIFT_8) & SIFIVE_CCACHE0_BYTE_MASK); + config->num_sets = + 2 << (((val >> REG_SHIFT_16) & SIFIVE_CCACHE0_BYTE_MASK) - 1); + config->block_size = + 2 << (((val >> REG_SHIFT_24) & SIFIVE_CCACHE0_BYTE_MASK) - 1); + } } -int __metal_driver_sifive_ccache0_get_enabled_ways(struct metal_cache *cache) -{ - unsigned long control_base = __metal_driver_sifive_ccache0_control_base(cache); +uint32_t sifive_ccache0_get_enabled_ways(void) { - uint32_t way_enable = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CCACHE0_WAYENABLE)); + uint32_t val = 0; - /* The stored number is the index, so add one */ - return (0xFF & way_enable) + 1; + val = SIFIVE_CCACHE0_BYTE_MASK & REGW(METAL_SIFIVE_CCACHE0_WAYENABLE); + + /* The stored number is the way index, so increment by 1 */ + val++; + + return val; } -int __metal_driver_sifive_ccache0_set_enabled_ways(struct metal_cache *cache, int ways) -{ - unsigned long control_base = __metal_driver_sifive_ccache0_control_base(cache); +int sifive_ccache0_set_enabled_ways(uint32_t ways) { + + int ret = 0; /* We can't decrease the number of enabled ways */ - if(metal_cache_get_enabled_ways(cache) > ways) { - return -2; + if (sifive_ccache0_get_enabled_ways() > ways) { + ret = -1; + } else { + /* The stored value is the index, so subtract one */ + uint32_t value = 0xFF & (ways - 1); + + /* Set the number of enabled ways */ + REGW(METAL_SIFIVE_CCACHE0_WAYENABLE) = value; + + /* Make sure the number of ways was set correctly */ + if (sifive_ccache0_get_enabled_ways() != ways) { + ret = -2; + } } - /* The stored value is the index, so subtract one */ - uint32_t value = 0xFF & (ways - 1); + return ret; +} + +void sifive_ccache0_inject_ecc_error(uint32_t bitindex, + sifive_ccache0_ecc_errtype_t type) { + /* Induce ECC error at given bit index and location */ + REGW(METAL_SIFIVE_CCACHE0_ECCINJECTERROR) = + (uint32_t)(((type & 0x01) << REG_SHIFT_16) | (bitindex & 0xFF)); +} + +void sifive_ccache0_flush(uintptr_t flush_addr) { + /* Block memory access until operation completed */ + __asm volatile("fence rw, io" : : : "memory"); + +#if __riscv_xlen == 32 + REGW(METAL_SIFIVE_CCACHE0_FLUSH32) = flush_addr >> REG_SHIFT_4; +#else + REGD(METAL_SIFIVE_CCACHE0_FLUSH64) = flush_addr; +#endif + + __asm volatile("fence io, rw" : : : "memory"); +} + +uintptr_t sifive_ccache0_get_ecc_fix_addr(sifive_ccache0_ecc_errtype_t type) { + uintptr_t addr = 0; + + switch (type) { + /* Get most recently ECC corrected address */ + case SIFIVE_CCACHE0_DATA: + addr = (uintptr_t)REGD(METAL_SIFIVE_CCACHE0_DATECCFIXLOW); + break; + + case SIFIVE_CCACHE0_DIR: + addr = (uintptr_t)REGD(METAL_SIFIVE_CCACHE0_DIRECCFIXLOW); + break; + } + + return addr; +} + +uint32_t sifive_ccache0_get_ecc_fix_count(sifive_ccache0_ecc_errtype_t type) { + uint32_t count = 0; + + switch (type) { + /* Get number of times ECC errors were corrected */ + case SIFIVE_CCACHE0_DATA: + count = REGW(METAL_SIFIVE_CCACHE0_DATECCFIXCOUNT); + break; + + case SIFIVE_CCACHE0_DIR: + count = REGW(METAL_SIFIVE_CCACHE0_DIRECCFIXCOUNT); + break; + } + + return count; +} + +uintptr_t sifive_ccache0_get_ecc_fail_addr(sifive_ccache0_ecc_errtype_t type) { + uintptr_t addr = 0; + + switch (type) { + /* Get address location of most recent uncorrected ECC error */ + case SIFIVE_CCACHE0_DATA: + addr = (uintptr_t)REGD(METAL_SIFIVE_CCACHE0_DATECCFAILLOW); + break; + + case SIFIVE_CCACHE0_DIR: + addr = (uintptr_t)REGD(METAL_SIFIVE_CCACHE0_DIRECCFAILLOW); + break; + } + + return addr; +} + +uint32_t sifive_ccache0_get_ecc_fail_count(sifive_ccache0_ecc_errtype_t type) { + uint32_t count = 0; - /* Set the number of enabled ways */ - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CCACHE0_WAYENABLE)) = value; + switch (type) { + /* Get number of times ECC errors were not corrected */ + case SIFIVE_CCACHE0_DATA: + count = REGW(METAL_SIFIVE_CCACHE0_DATECCFAILCOUNT); + break; - /* Make sure the number of ways was set correctly */ - if(metal_cache_get_enabled_ways(cache) != ways) { - return -3; + case SIFIVE_CCACHE0_DIR: + count = REGW(METAL_SIFIVE_CCACHE0_DIRECCFAILCOUNT); + break; } + return count; +} + +uint64_t sifive_ccache0_get_way_mask(uint32_t master_id) { + uint64_t val = 0; + + /* Get way mask for given master ID */ + val = REGD(METAL_SIFIVE_CCACHE0_WAYMASK0 + master_id * 8); + + return val; +} + +int sifive_ccache0_set_way_mask(uint32_t master_id, uint64_t waymask) { + + /* Set way mask for given master ID */ + REGD(METAL_SIFIVE_CCACHE0_WAYMASK0 + master_id * 8) = waymask; + return 0; } -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_ccache0) = { - .cache.init = __metal_driver_sifive_ccache0_init, - .cache.get_enabled_ways = __metal_driver_sifive_ccache0_get_enabled_ways, - .cache.set_enabled_ways = __metal_driver_sifive_ccache0_set_enabled_ways, -}; +void sifive_ccache0_set_pmevent_selector(uint32_t counter, uint64_t mask) { + +#if METAL_SIFIVE_CCACHE0_PERFMON_COUNTERS > 0 + if (counter < METAL_SIFIVE_CCACHE0_PERFMON_COUNTERS) { + + /* Set event selector for specified L2 event counter */ + REGD(METAL_SIFIVE_CCACHE0_PMEVENTSELECT0 + counter * 8) = mask; + } +#endif + return; +} + +uint64_t sifive_ccache0_get_pmevent_selector(uint32_t counter) { + uint64_t val = 0; + +#if METAL_SIFIVE_CCACHE0_PERFMON_COUNTERS > 0 + if (counter < METAL_SIFIVE_CCACHE0_PERFMON_COUNTERS) { + + /* Get event selector for specified L2 event counter */ + val = REGD(METAL_SIFIVE_CCACHE0_PMEVENTSELECT0 + counter * 8); + } +#endif + return val; +} + +void sifive_ccache0_clr_pmevent_counter(uint32_t counter) { + +#if METAL_SIFIVE_CCACHE0_PERFMON_COUNTERS > 0 + if (counter < METAL_SIFIVE_CCACHE0_PERFMON_COUNTERS) { + /* Clear specified L2 event counter */ + REGD(METAL_SIFIVE_CCACHE0_PMEVENTCOUNTER0 + counter * 8) = 0; + } +#endif + return; +} + +uint64_t sifive_ccache0_get_pmevent_counter(uint32_t counter) { +#if __riscv_xlen == 32 + uint32_t vh = 0, vh1 = 0, vl = 0; +#else + uint64_t val = 0; +#endif +#if METAL_SIFIVE_CCACHE0_PERFMON_COUNTERS > 0 + if (counter < METAL_SIFIVE_CCACHE0_PERFMON_COUNTERS) { + /* Set counter register offset */ + counter *= 8; + +#if __riscv_xlen == 32 + do { + vh = REGW(METAL_SIFIVE_CCACHE0_PMEVENTCOUNTER0 + counter + 4); + vl = REGW(METAL_SIFIVE_CCACHE0_PMEVENTCOUNTER0 + counter); + vh1 = REGW(METAL_SIFIVE_CCACHE0_PMEVENTCOUNTER0 + counter + 4); + } while (vh != vh1); +#else + val = REGD(METAL_SIFIVE_CCACHE0_PMEVENTCOUNTER0 + counter); +#endif + } +#endif +#if __riscv_xlen == 32 + return ((((unsigned long long)vh) << 32) | vl); +#else + return val; +#endif +} + +void sifive_ccache0_set_client_filter(uint64_t mask) { + + /* Set clients to be excluded from performance monitoring */ + REGD(METAL_SIFIVE_CCACHE0_PMCLIENTFILTER) = mask; +} + +uint64_t sifive_ccache0_get_client_filter(void) { + uint64_t val = 0; + + /* Get currently active client filter mask */ + val = REGD(METAL_SIFIVE_CCACHE0_PMCLIENTFILTER); + + return val; +} + +int sifive_ccache0_get_interrupt_id(uint32_t src) { + int ret = 0; + + if (src < (uint32_t)sizeof(sifive_ccache0_interrupts) / sizeof(int)) { + ret = sifive_ccache0_interrupts[src]; + } + + return ret; +} + +struct metal_interrupt *sifive_ccache0_interrupt_controller(void) { + return METAL_SIFIVE_CCACHE0_INTERRUPT_PARENT; +} #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_clic0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_clic0.c index 12c3dac06..bf8fa16a0 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_clic0.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_clic0.c @@ -5,123 +5,135 @@ #ifdef METAL_SIFIVE_CLIC0 -#include <stdint.h> -#include <metal/io.h> -#include <metal/shutdown.h> #include <metal/drivers/sifive_clic0.h> +#include <metal/io.h> #include <metal/machine.h> +#include <metal/shutdown.h> +#include <stdint.h> + +#define CLIC0_MAX_INTERRUPTS 4096 -typedef enum metal_clic_vector_{ +typedef enum metal_clic_vector_ { METAL_CLIC_NONVECTOR = 0, - METAL_CLIC_VECTORED = 1 + METAL_CLIC_VECTORED = 1 } metal_clic_vector; struct __metal_clic_cfg { - unsigned char : 1, - nmbits : 2, - nlbits : 4, - nvbit : 1; + unsigned char : 1, nmbits : 2, nlbits : 4, nvbit : 1; }; const struct __metal_clic_cfg __metal_clic_defaultcfg = { - .nmbits = METAL_INTR_PRIV_M_MODE, - .nlbits = 0, - .nvbit = METAL_CLIC_NONVECTOR - }; + .nmbits = METAL_INTR_PRIV_M_MODE, + .nlbits = 0, + .nvbit = METAL_CLIC_NONVECTOR}; void __metal_clic0_handler(int id, void *priv) __attribute__((aligned(64))); -void __metal_clic0_default_vector_handler (void) __attribute__((interrupt, aligned(64))); +void __metal_clic0_default_vector_handler(void) + __attribute__((interrupt, aligned(64))); -struct __metal_clic_cfg __metal_clic0_configuration (struct __metal_driver_sifive_clic0 *clic, - struct __metal_clic_cfg *cfg) -{ +struct __metal_clic_cfg +__metal_clic0_configuration(struct __metal_driver_sifive_clic0 *clic, + struct __metal_clic_cfg *cfg) { volatile unsigned char val; struct __metal_clic_cfg cliccfg; - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + unsigned long control_base = __metal_driver_sifive_clic0_control_base( + (struct metal_interrupt *)clic); - if ( cfg ) { + if (cfg) { val = cfg->nmbits << 5 | cfg->nlbits << 1 | cfg->nvbit; - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICCFG)) = val; + __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICCFG)) = val; } - val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICCFG)); + val = __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICCFG)); cliccfg.nmbits = (val & METAL_SIFIVE_CLIC0_CLICCFG_NMBITS_MASK) >> 5; cliccfg.nlbits = (val & METAL_SIFIVE_CLIC0_CLICCFG_NLBITS_MASK) >> 1; cliccfg.nvbit = val & METAL_SIFIVE_CLIC0_CLICCFG_NVBIT_MASK; return cliccfg; } -int __metal_clic0_interrupt_set_mode (struct __metal_driver_sifive_clic0 *clic, int id, int mode) -{ +int __metal_clic0_interrupt_set_mode(struct __metal_driver_sifive_clic0 *clic, + int id, int mode) { uint8_t mask, val; struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - + unsigned long control_base = __metal_driver_sifive_clic0_control_base( + (struct metal_interrupt *)clic); + if (mode >= (cfg.nmbits << 1)) { /* Do nothing, mode request same or exceed what configured in CLIC */ return 0; } - + /* Mask out nmbits and retain other values */ mask = ((uint8_t)(-1)) >> cfg.nmbits; - val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) & mask; - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) = val | (mode << (8 - cfg.nmbits)); + val = + __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) & + mask; + __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) = + val | (mode << (8 - cfg.nmbits)); return 0; } -int __metal_clic0_interrupt_set_level (struct __metal_driver_sifive_clic0 *clic, int id, unsigned int level) -{ +int __metal_clic0_interrupt_set_level(struct __metal_driver_sifive_clic0 *clic, + int id, unsigned int level) { + uint8_t mask, nmmask, nlmask, val; struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + unsigned long control_base = __metal_driver_sifive_clic0_control_base( + (struct metal_interrupt *)clic); /* Drop the LSBs that don't fit in nlbits */ - level = level >> (METAL_CLIC_MAX_NLBITS - cfg.nlbits); - - nmmask = ~( ((uint8_t)(-1)) >> (cfg.nmbits) ); - nlmask = ((uint8_t)(-1)) >> (cfg.nmbits + cfg.nlbits); + nlmask = (uint8_t)(-1) >> (cfg.nmbits + cfg.nlbits); + nmmask = ~((uint8_t)(-1) >> (cfg.nmbits)); mask = ~(nlmask | nmmask); - - val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) = __METAL_SET_FIELD(val, mask, level); + + level &= mask; + val = __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); + val &= ~mask; + __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) = + (val | level); + return 0; } -unsigned int __metal_clic0_interrupt_get_level (struct __metal_driver_sifive_clic0 *clic, int id) -{ +unsigned int +__metal_clic0_interrupt_get_level(struct __metal_driver_sifive_clic0 *clic, + int id) { int level; uint8_t mask, val, freebits, nlbits; struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_intbits = __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); + unsigned long control_base = __metal_driver_sifive_clic0_control_base( + (struct metal_interrupt *)clic); + int num_intbits = + __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); if ((cfg.nmbits + cfg.nlbits) >= num_intbits) { - nlbits = num_intbits - cfg.nmbits; + nlbits = (num_intbits >= cfg.nmbits) ? (num_intbits - cfg.nmbits) : 0; } else { - nlbits = cfg.nlbits; + nlbits = __METAL_MIN((num_intbits - cfg.nmbits), cfg.nlbits); } - mask = ((1 << nlbits) - 1) << (8 - (cfg.nmbits + nlbits)); + mask = ((1 << nlbits) - 1) + << (METAL_CLIC_MAX_NLBITS - (cfg.nmbits + nlbits)); freebits = ((1 << METAL_CLIC_MAX_NLBITS) - 1) >> nlbits; - + if (mask == 0) { level = (1 << METAL_CLIC_MAX_NLBITS) - 1; } else { - val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); + val = __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); val = __METAL_GET_FIELD(val, mask); level = (val << (METAL_CLIC_MAX_NLBITS - nlbits)) | freebits; } @@ -129,38 +141,45 @@ unsigned int __metal_clic0_interrupt_get_level (struct __metal_driver_sifive_cli return level; } -int __metal_clic0_interrupt_set_priority (struct __metal_driver_sifive_clic0 *clic, int id, int priority) -{ - uint8_t mask, npmask, val, npbits; +int __metal_clic0_interrupt_set_priority( + struct __metal_driver_sifive_clic0 *clic, int id, int priority) { + + uint8_t mask, nlmask, val, npbits; struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_intbits = __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); + unsigned long control_base = __metal_driver_sifive_clic0_control_base( + (struct metal_interrupt *)clic); + int num_intbits = + __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); - if ((cfg.nmbits + cfg.nlbits) < num_intbits) { + if ((cfg.nmbits + cfg.nlbits) <= num_intbits) { npbits = num_intbits - (cfg.nmbits + cfg.nlbits); - priority = priority >> (8 - npbits); - - mask = ((uint8_t)(-1)) >> (cfg.nmbits + cfg.nlbits + npbits); - npmask = ~(((uint8_t)(-1)) >> (cfg.nmbits + cfg.nlbits)); - mask = ~(mask | npmask); - - val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) = __METAL_SET_FIELD(val, mask, priority); + + mask = (uint8_t)(-1) >> (cfg.nmbits + cfg.nlbits + npbits); + nlmask = ~((uint8_t)(-1) >> (cfg.nmbits + cfg.nlbits)); + mask = ~(mask | nlmask); + + priority &= mask; + val = __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); + val &= ~mask; + __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) = + (val | priority); } return 0; } -int __metal_clic0_interrupt_get_priority (struct __metal_driver_sifive_clic0 *clic, int id) -{ +int __metal_clic0_interrupt_get_priority( + struct __metal_driver_sifive_clic0 *clic, int id) { int priority; uint8_t mask, val, freebits, nlbits; struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_intbits = __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); + unsigned long control_base = __metal_driver_sifive_clic0_control_base( + (struct metal_interrupt *)clic); + int num_intbits = + __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); if ((cfg.nmbits + cfg.nlbits) >= num_intbits) { nlbits = num_intbits - cfg.nmbits; @@ -170,133 +189,148 @@ int __metal_clic0_interrupt_get_priority (struct __metal_driver_sifive_clic0 *cl mask = ((1 << nlbits) - 1) << (8 - (cfg.nmbits + nlbits)); freebits = ((1 << METAL_CLIC_MAX_NLBITS) - 1) >> nlbits; - + if (mask == 0) { priority = (1 << METAL_CLIC_MAX_NLBITS) - 1; - } else { - val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); + } else { + val = __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); priority = __METAL_GET_FIELD(val, freebits); } return priority; } -int __metal_clic0_interrupt_set_vector_mode (struct __metal_driver_sifive_clic0 *clic, int id, int enable) -{ +int __metal_clic0_interrupt_set_vector_mode( + struct __metal_driver_sifive_clic0 *clic, int id, int enable) { uint8_t mask, val; - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_intbits = __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); + unsigned long control_base = __metal_driver_sifive_clic0_control_base( + (struct metal_interrupt *)clic); + int num_intbits = + __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); mask = 1 << (8 - num_intbits); - val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); - /* Ensure its value is 1 bit wide */ - enable &= 0x1; - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) = __METAL_SET_FIELD(val, mask, enable); + val = __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); + if (enable) { + val |= mask; + } else { + val &= ~mask; + } + __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)) = val; return 0; } -int __metal_clic0_interrupt_is_vectored (struct __metal_driver_sifive_clic0 *clic, int id) -{ +int __metal_clic0_interrupt_is_vectored( + struct __metal_driver_sifive_clic0 *clic, int id) { uint8_t mask, val; - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_intbits = __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); + unsigned long control_base = __metal_driver_sifive_clic0_control_base( + (struct metal_interrupt *)clic); + int num_intbits = + __metal_driver_sifive_clic0_num_intbits((struct metal_interrupt *)clic); mask = 1 << (8 - num_intbits); - val = __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); + val = __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTCTL_BASE + id)); return __METAL_GET_FIELD(val, mask); } -int __metal_clic0_interrupt_enable (struct __metal_driver_sifive_clic0 *clic, int id) -{ - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); +int __metal_clic0_interrupt_enable(struct __metal_driver_sifive_clic0 *clic, + int id) { + unsigned long control_base = __metal_driver_sifive_clic0_control_base( + (struct metal_interrupt *)clic); + int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts( + (struct metal_interrupt *)clic); - if (id >= num_subinterrupts) { - return -1; - } - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTIE_BASE + id)) = METAL_ENABLE; + __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTIE_BASE + id)) = + METAL_ENABLE; return 0; } -int __metal_clic0_interrupt_disable (struct __metal_driver_sifive_clic0 *clic, int id) -{ - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); +int __metal_clic0_interrupt_disable(struct __metal_driver_sifive_clic0 *clic, + int id) { + unsigned long control_base = __metal_driver_sifive_clic0_control_base( + (struct metal_interrupt *)clic); + int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts( + (struct metal_interrupt *)clic); - if (id >= num_subinterrupts) { - return -1; - } - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTIE_BASE + id)) = METAL_DISABLE; + __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTIE_BASE + id)) = + METAL_DISABLE; return 0; } -int __metal_clic0_interrupt_is_enabled (struct __metal_driver_sifive_clic0 *clic, int id) -{ - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); +int __metal_clic0_interrupt_is_enabled(struct __metal_driver_sifive_clic0 *clic, + int id) { + unsigned long control_base = __metal_driver_sifive_clic0_control_base( + (struct metal_interrupt *)clic); + int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts( + (struct metal_interrupt *)clic); if (id >= num_subinterrupts) { return 0; } - return __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTIE_BASE + id)); + return __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTIE_BASE + id)); } -int __metal_clic0_interrupt_is_pending (struct __metal_driver_sifive_clic0 *clic, int id) -{ - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); +int __metal_clic0_interrupt_is_pending(struct __metal_driver_sifive_clic0 *clic, + int id) { + unsigned long control_base = __metal_driver_sifive_clic0_control_base( + (struct metal_interrupt *)clic); + int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts( + (struct metal_interrupt *)clic); if (id >= num_subinterrupts) { return 0; } - return __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTIP_BASE + id)); + return __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTIP_BASE + id)); } -int __metal_clic0_interrupt_set (struct __metal_driver_sifive_clic0 *clic, int id) -{ - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); +int __metal_clic0_interrupt_set(struct __metal_driver_sifive_clic0 *clic, + int id) { + unsigned long control_base = __metal_driver_sifive_clic0_control_base( + (struct metal_interrupt *)clic); + int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts( + (struct metal_interrupt *)clic); if (id < num_subinterrupts) { - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTIP_BASE + id)) = METAL_ENABLE; - return 0; + __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTIP_BASE + id)) = + METAL_ENABLE; } - return -1; + return 0; } -int __metal_clic0_interrupt_clear (struct __metal_driver_sifive_clic0 *clic, int id) -{ - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); +int __metal_clic0_interrupt_clear(struct __metal_driver_sifive_clic0 *clic, + int id) { + unsigned long control_base = __metal_driver_sifive_clic0_control_base( + (struct metal_interrupt *)clic); + int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts( + (struct metal_interrupt *)clic); if (id < num_subinterrupts) { - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTIP_BASE + id)) = METAL_DISABLE; - return 0; + __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTIP_BASE + id)) = + METAL_DISABLE; } - return -1; + return 0; } -int __metal_clic0_configure_set_vector_mode (struct __metal_driver_sifive_clic0 *clic, metal_vector_mode mode) -{ +int __metal_clic0_configure_set_vector_mode( + struct __metal_driver_sifive_clic0 *clic, metal_vector_mode mode) { struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); switch (mode) { @@ -319,12 +353,12 @@ int __metal_clic0_configure_set_vector_mode (struct __metal_driver_sifive_clic0 return 0; } -metal_vector_mode __metal_clic0_configure_get_vector_mode (struct __metal_driver_sifive_clic0 *clic) -{ +metal_vector_mode __metal_clic0_configure_get_vector_mode( + struct __metal_driver_sifive_clic0 *clic) { struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); metal_vector_mode mode = __metal_controller_interrupt_vector_mode(); - if (mode == METAL_SELECTIVE_VECTOR_MODE) { + if (mode == METAL_SELECTIVE_VECTOR_MODE) { if (cfg.nvbit) { return METAL_SELECTIVE_VECTOR_MODE; } else { @@ -335,8 +369,8 @@ metal_vector_mode __metal_clic0_configure_get_vector_mode (struct __metal_driver } } -int __metal_clic0_configure_set_privilege (struct __metal_driver_sifive_clic0 *clic, metal_intr_priv_mode priv) -{ +int __metal_clic0_configure_set_privilege( + struct __metal_driver_sifive_clic0 *clic, metal_intr_priv_mode priv) { struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); cfg.nmbits = priv; @@ -344,15 +378,15 @@ int __metal_clic0_configure_set_privilege (struct __metal_driver_sifive_clic0 *c return 0; } -metal_intr_priv_mode __metal_clic0_configure_get_privilege (struct __metal_driver_sifive_clic0 *clic) -{ +metal_intr_priv_mode __metal_clic0_configure_get_privilege( + struct __metal_driver_sifive_clic0 *clic) { struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); return cfg.nmbits; } -int __metal_clic0_configure_set_level (struct __metal_driver_sifive_clic0 *clic, int level) -{ +int __metal_clic0_configure_set_level(struct __metal_driver_sifive_clic0 *clic, + int level) { struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); cfg.nlbits = level & 0xF; @@ -360,75 +394,82 @@ int __metal_clic0_configure_set_level (struct __metal_driver_sifive_clic0 *clic, return 0; } -int __metal_clic0_configure_get_level (struct __metal_driver_sifive_clic0 *clic) -{ +int __metal_clic0_configure_get_level( + struct __metal_driver_sifive_clic0 *clic) { struct __metal_clic_cfg cfg = __metal_clic0_configuration(clic, NULL); return cfg.nlbits; } -unsigned long long __metal_clic0_mtime_get (struct __metal_driver_sifive_clic0 *clic) -{ +unsigned long long +__metal_clic0_mtime_get(struct __metal_driver_sifive_clic0 *clic) { __metal_io_u32 lo, hi; - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + unsigned long control_base = __metal_driver_sifive_clic0_control_base( + (struct metal_interrupt *)clic); /* Guard against rollover when reading */ do { - hi = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CLIC0_MTIME + 4)); - lo = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CLIC0_MTIME)); - } while (__METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_CLIC0_MTIME + 4)) != hi); + hi = __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(control_base + METAL_SIFIVE_CLIC0_MTIME + 4)); + lo = __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(control_base + METAL_SIFIVE_CLIC0_MTIME)); + } while (__METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + + METAL_SIFIVE_CLIC0_MTIME + + 4)) != hi); return (((unsigned long long)hi) << 32) | lo; } int __metal_driver_sifive_clic0_mtimecmp_set(struct metal_interrupt *controller, int hartid, - unsigned long long time) -{ + unsigned long long time) { struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); - unsigned long control_base = __metal_driver_sifive_clic0_control_base((struct metal_interrupt *)clic); + unsigned long control_base = __metal_driver_sifive_clic0_control_base( + (struct metal_interrupt *)clic); /* Per spec, the RISC-V MTIME/MTIMECMP registers are 64 bit, * and are NOT internally latched for multiword transfers. * Need to be careful about sequencing to avoid triggering * spurious interrupts: For that set the high word to a max * value first. */ - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_SIFIVE_CLIC0_MTIMECMP_BASE + 4)) = 0xFFFFFFFF; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_SIFIVE_CLIC0_MTIMECMP_BASE)) = (__metal_io_u32)time; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + METAL_SIFIVE_CLIC0_MTIMECMP_BASE + 4)) = (__metal_io_u32)(time >> 32); + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + + METAL_SIFIVE_CLIC0_MTIMECMP_BASE + + 4)) = 0xFFFFFFFF; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + + METAL_SIFIVE_CLIC0_MTIMECMP_BASE)) = + (__metal_io_u32)time; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + (8 * hartid) + + METAL_SIFIVE_CLIC0_MTIMECMP_BASE + + 4)) = (__metal_io_u32)(time >> 32); return 0; } -void __metal_clic0_handler (int id, void *priv) -{ +void __metal_clic0_handler(int id, void *priv) { struct __metal_driver_sifive_clic0 *clic = priv; - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts((struct metal_interrupt *)clic); + int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts( + (struct metal_interrupt *)clic); - if ( (id < num_subinterrupts) && (clic->metal_exint_table[id].handler) ) { - clic->metal_exint_table[id].handler(id, clic->metal_exint_table[id].exint_data); + if ((id < num_subinterrupts) && (clic->metal_exint_table[id].handler)) { + clic->metal_exint_table[id].handler( + id, clic->metal_exint_table[id].exint_data); } } -void __metal_clic0_default_handler (int id, void *priv) { - metal_shutdown(300); -} +void __metal_clic0_default_handler(int id, void *priv) { metal_shutdown(300); } -void __metal_clic0_default_vector_handler (void) { - metal_shutdown(400); -} +void __metal_clic0_default_vector_handler(void) { metal_shutdown(400); } -void __metal_driver_sifive_clic0_init (struct metal_interrupt *controller) -{ +void __metal_driver_sifive_clic0_init(struct metal_interrupt *controller) { struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); - if ( !clic->init_done ) { + if (!clic->init_done) { int level, max_levels, line, num_interrupts, num_subinterrupts; struct __metal_clic_cfg cfg = __metal_clic_defaultcfg; struct metal_interrupt *intc = - __metal_driver_sifive_clic0_interrupt_parent(controller); + __metal_driver_sifive_clic0_interrupt_parent(controller); /* Initialize ist parent controller, aka cpu_intc. */ intc->vtable->interrupt_init(intc); @@ -439,50 +480,54 @@ void __metal_driver_sifive_clic0_init (struct metal_interrupt *controller) * Register its interrupts with with parent controller, * aka sw, timer and ext to its default isr */ - num_interrupts = __metal_driver_sifive_clic0_num_interrupts(controller); + num_interrupts = __metal_driver_sifive_clic0_num_interrupts(controller); for (int i = 0; i < num_interrupts; i++) { - line = __metal_driver_sifive_clic0_interrupt_lines(controller, i); + line = __metal_driver_sifive_clic0_interrupt_lines(controller, i); intc->vtable->interrupt_register(intc, line, NULL, clic); } /* Default CLIC mode to per dts */ - max_levels = __metal_driver_sifive_clic0_max_levels(controller); - cfg.nlbits = (max_levels > METAL_CLIC_MAX_NLBITS) ? - METAL_CLIC_MAX_NLBITS : max_levels; + max_levels = __metal_driver_sifive_clic0_max_levels(controller); + cfg.nlbits = (max_levels > METAL_CLIC_MAX_NLBITS) + ? METAL_CLIC_MAX_NLBITS + : max_levels; __metal_clic0_configuration(clic, &cfg); level = (1 << cfg.nlbits) - 1; - num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts(controller); + num_subinterrupts = + __metal_driver_sifive_clic0_num_subinterrupts(controller); clic->metal_mtvt_table[0] = &__metal_clic0_handler; - for (int i = 1; i < num_subinterrupts; i++) { - clic->metal_mtvt_table[i] = NULL; - clic->metal_exint_table[i].handler = NULL; - clic->metal_exint_table[i].sub_int = NULL; - clic->metal_exint_table[i].exint_data = NULL; + __metal_clic0_interrupt_disable(clic, 0); + __metal_clic0_interrupt_set_level(clic, 0, level); + for (int i = 1; i < CLIC0_MAX_INTERRUPTS; i++) { + if (i < num_subinterrupts) { + clic->metal_mtvt_table[i] = NULL; + clic->metal_exint_table[i].handler = NULL; + clic->metal_exint_table[i].sub_int = NULL; + clic->metal_exint_table[i].exint_data = NULL; + __metal_clic0_interrupt_set_level(clic, i, level); + } __metal_clic0_interrupt_disable(clic, i); - __metal_clic0_interrupt_set_level(clic, i, level); } - clic->init_done = 1; - } + clic->init_done = 1; + } } -int __metal_driver_sifive_clic0_register (struct metal_interrupt *controller, - int id, metal_interrupt_handler_t isr, - void *priv) -{ +int __metal_driver_sifive_clic0_register(struct metal_interrupt *controller, + int id, metal_interrupt_handler_t isr, + void *priv) { int rc = -1; int num_subinterrupts; struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); struct metal_interrupt *intc = - __metal_driver_sifive_clic0_interrupt_parent(controller); + __metal_driver_sifive_clic0_interrupt_parent(controller); metal_vector_mode mode = __metal_clic0_configure_get_vector_mode(clic); - - if ( ( (mode == METAL_SELECTIVE_VECTOR_MODE) && - (__metal_clic0_interrupt_is_vectored(clic, id)) ) || - (mode == METAL_HARDWARE_VECTOR_MODE) || - (mode == METAL_VECTOR_MODE) || - (mode == METAL_DIRECT_MODE) ) { + + if (((mode == METAL_SELECTIVE_VECTOR_MODE) && + (__metal_clic0_interrupt_is_vectored(clic, id))) || + (mode == METAL_HARDWARE_VECTOR_MODE) || (mode == METAL_VECTOR_MODE) || + (mode == METAL_DIRECT_MODE)) { return rc; } @@ -490,14 +535,15 @@ int __metal_driver_sifive_clic0_register (struct metal_interrupt *controller, if (id < METAL_INTERRUPT_ID_CSW) { return intc->vtable->interrupt_register(intc, id, isr, priv); } - - /* + + /* * CLIC (sub-interrupts) devices interrupts start at 16 but offset from 0 * Reset the IDs to reflects this. */ - num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts(controller); + num_subinterrupts = + __metal_driver_sifive_clic0_num_subinterrupts(controller); if (id < num_subinterrupts) { - if ( isr) { + if (isr) { clic->metal_exint_table[id].handler = isr; clic->metal_exint_table[id].exint_data = priv; } else { @@ -509,29 +555,30 @@ int __metal_driver_sifive_clic0_register (struct metal_interrupt *controller, return rc; } -int __metal_driver_sifive_clic0_vector_register (struct metal_interrupt *controller, - int id, metal_interrupt_vector_handler_t isr, - void *priv) -{ +int __metal_driver_sifive_clic0_vector_register( + struct metal_interrupt *controller, int id, + metal_interrupt_vector_handler_t isr, void *priv) { int rc = -1; struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); struct metal_interrupt *intc = - __metal_driver_sifive_clic0_interrupt_parent(controller); - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts(controller); + __metal_driver_sifive_clic0_interrupt_parent(controller); + int num_subinterrupts = + __metal_driver_sifive_clic0_num_subinterrupts(controller); metal_vector_mode mode = __metal_clic0_configure_get_vector_mode(clic); - if ((mode != METAL_SELECTIVE_VECTOR_MODE) && (mode != METAL_HARDWARE_VECTOR_MODE)) { + if ((mode != METAL_SELECTIVE_VECTOR_MODE) && + (mode != METAL_HARDWARE_VECTOR_MODE)) { return rc; } if ((mode == METAL_SELECTIVE_VECTOR_MODE) && - (__metal_clic0_interrupt_is_vectored(clic, id) == 0) ) { + (__metal_clic0_interrupt_is_vectored(clic, id) == 0)) { return rc; } if (id < num_subinterrupts) { - if ( isr) { + if (isr) { clic->metal_mtvt_table[id] = isr; - clic->metal_exint_table[id].exint_data = priv; + clic->metal_exint_table[id].exint_data = priv; } else { clic->metal_mtvt_table[id] = __metal_clic0_default_vector_handler; clic->metal_exint_table[id].sub_int = priv; @@ -541,29 +588,31 @@ int __metal_driver_sifive_clic0_vector_register (struct metal_interrupt *control return rc; } -int __metal_driver_sifive_clic0_enable (struct metal_interrupt *controller, int id) -{ +int __metal_driver_sifive_clic0_enable(struct metal_interrupt *controller, + int id) { struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); return __metal_clic0_interrupt_enable(clic, id); } -int __metal_driver_sifive_clic0_disable (struct metal_interrupt *controller, int id) -{ +int __metal_driver_sifive_clic0_disable(struct metal_interrupt *controller, + int id) { struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); return __metal_clic0_interrupt_disable(clic, id); } -int __metal_driver_sifive_clic0_enable_interrupt_vector(struct metal_interrupt *controller, int id) -{ +int __metal_driver_sifive_clic0_enable_interrupt_vector( + struct metal_interrupt *controller, int id) { int rc = -1; - int num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts(controller); + int num_subinterrupts = + __metal_driver_sifive_clic0_num_subinterrupts(controller); struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); metal_vector_mode mode = __metal_clic0_configure_get_vector_mode(clic); - if ((mode != METAL_SELECTIVE_VECTOR_MODE) && (mode != METAL_HARDWARE_VECTOR_MODE)) { + if ((mode != METAL_SELECTIVE_VECTOR_MODE) && + (mode != METAL_HARDWARE_VECTOR_MODE)) { return rc; } if (id < num_subinterrupts) { @@ -573,13 +622,14 @@ int __metal_driver_sifive_clic0_enable_interrupt_vector(struct metal_interrupt * return -1; } -int __metal_driver_sifive_clic0_disable_interrupt_vector(struct metal_interrupt *controller, int id) -{ +int __metal_driver_sifive_clic0_disable_interrupt_vector( + struct metal_interrupt *controller, int id) { int num_subinterrupts; struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); - num_subinterrupts = __metal_driver_sifive_clic0_num_subinterrupts(controller); + num_subinterrupts = + __metal_driver_sifive_clic0_num_subinterrupts(controller); if (id < num_subinterrupts) { __metal_clic0_interrupt_set_vector_mode(clic, id, METAL_DISABLE); return 0; @@ -587,148 +637,183 @@ int __metal_driver_sifive_clic0_disable_interrupt_vector(struct metal_interrupt return -1; } -metal_vector_mode __metal_driver_sifive_clic0_get_vector_mode (struct metal_interrupt *controller) -{ +metal_vector_mode __metal_driver_sifive_clic0_get_vector_mode( + struct metal_interrupt *controller) { struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); return __metal_clic0_configure_get_vector_mode(clic); } -int __metal_driver_sifive_clic0_set_vector_mode (struct metal_interrupt *controller, metal_vector_mode mode) -{ +int __metal_driver_sifive_clic0_set_vector_mode( + struct metal_interrupt *controller, metal_vector_mode mode) { struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); return __metal_clic0_configure_set_vector_mode(clic, mode); } -metal_intr_priv_mode __metal_driver_sifive_clic0_get_privilege (struct metal_interrupt *controller) -{ +metal_intr_priv_mode +__metal_driver_sifive_clic0_get_privilege(struct metal_interrupt *controller) { struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); return __metal_clic0_configure_get_privilege(clic); } -int __metal_driver_sifive_clic0_set_privilege (struct metal_interrupt *controller, metal_intr_priv_mode priv) -{ +int __metal_driver_sifive_clic0_set_privilege( + struct metal_interrupt *controller, metal_intr_priv_mode priv) { struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); return __metal_clic0_configure_set_privilege(clic, priv); } -unsigned int __metal_driver_sifive_clic0_get_threshold (struct metal_interrupt *controller) -{ +unsigned int +__metal_driver_sifive_clic0_get_threshold(struct metal_interrupt *controller) { struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); return __metal_clic0_configure_get_level(clic); } -int __metal_driver_sifive_clic0_set_threshold (struct metal_interrupt *controller, unsigned int level) -{ +int __metal_driver_sifive_clic0_set_threshold( + struct metal_interrupt *controller, unsigned int level) { struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); return __metal_clic0_configure_set_level(clic, level); } -unsigned int __metal_driver_sifive_clic0_get_priority (struct metal_interrupt *controller, int id) -{ +unsigned int +__metal_driver_sifive_clic0_get_priority(struct metal_interrupt *controller, + int id) { struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); return __metal_clic0_interrupt_get_priority(clic, id); } -int __metal_driver_sifive_clic0_set_priority (struct metal_interrupt *controller, int id, unsigned int priority) -{ +int __metal_driver_sifive_clic0_set_priority(struct metal_interrupt *controller, + int id, unsigned int priority) { struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); return __metal_clic0_interrupt_set_priority(clic, id, priority); } -int __metal_driver_sifive_clic0_clear_interrupt (struct metal_interrupt *controller, int id) -{ +unsigned int __metal_driver_sifive_clic0_get_preemptive_level( + struct metal_interrupt *controller, int id) { + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + return __metal_clic0_interrupt_get_level(clic, id); +} + +int __metal_driver_sifive_clic0_set_preemptive_level( + struct metal_interrupt *controller, int id, unsigned int level) { + struct __metal_driver_sifive_clic0 *clic = + (struct __metal_driver_sifive_clic0 *)(controller); + __metal_clic0_interrupt_set_level(clic, id, level); + return (__metal_clic0_interrupt_set_priority(clic, id, level)); +} + +int __metal_driver_sifive_clic0_clear_interrupt( + struct metal_interrupt *controller, int id) { struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); return __metal_clic0_interrupt_clear(clic, id); } -int __metal_driver_sifive_clic0_set_interrupt (struct metal_interrupt *controller, int id) -{ +int __metal_driver_sifive_clic0_set_interrupt( + struct metal_interrupt *controller, int id) { struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); + (struct __metal_driver_sifive_clic0 *)(controller); return __metal_clic0_interrupt_set(clic, id); } -int __metal_driver_sifive_clic0_command_request (struct metal_interrupt *controller, - int command, void *data) -{ +int __metal_driver_sifive_clic0_command_request( + struct metal_interrupt *controller, int command, void *data) { int hartid; int rc = -1; struct __metal_driver_sifive_clic0 *clic = - (struct __metal_driver_sifive_clic0 *)(controller); - unsigned long control_base = __metal_driver_sifive_clic0_control_base(controller); + (struct __metal_driver_sifive_clic0 *)(controller); + unsigned long control_base = + __metal_driver_sifive_clic0_control_base(controller); switch (command) { case METAL_TIMER_MTIME_GET: if (data) { - *(unsigned long long *)data = __metal_clic0_mtime_get(clic); + *(unsigned long long *)data = __metal_clic0_mtime_get(clic); rc = 0; } break; case METAL_SOFTWARE_IPI_CLEAR: - if (data) { - hartid = *(int *)data; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - (hartid * 4))) = METAL_DISABLE; - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTIP_BASE)) = METAL_DISABLE; + if (data) { + hartid = *(int *)data; + __METAL_ACCESS_ONCE(( + __metal_io_u32 *)(control_base + (hartid * 4))) = METAL_DISABLE; + __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTIP_BASE)) = + METAL_DISABLE; rc = 0; } break; case METAL_SOFTWARE_IPI_SET: - if (data) { - hartid = *(int *)data; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - (hartid * 4))) = METAL_ENABLE; - __METAL_ACCESS_ONCE((__metal_io_u8 *)(control_base + - METAL_SIFIVE_CLIC0_MMODE_APERTURE + - METAL_SIFIVE_CLIC0_CLICINTIP_BASE)) = METAL_ENABLE; + if (data) { + hartid = *(int *)data; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(control_base + (hartid * 4))) = METAL_ENABLE; + __METAL_ACCESS_ONCE( + (__metal_io_u8 *)(control_base + + METAL_SIFIVE_CLIC0_MMODE_APERTURE + + METAL_SIFIVE_CLIC0_CLICINTIP_BASE)) = + METAL_ENABLE; rc = 0; } break; case METAL_SOFTWARE_MSIP_GET: rc = 0; - if (data) { - hartid = *(int *)data; - rc = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + - (hartid * 4))); + if (data) { + hartid = *(int *)data; + rc = __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(control_base + (hartid * 4))); } break; default: - break; + break; } return rc; } __METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_clic0) = { - .clic_vtable.interrupt_init = __metal_driver_sifive_clic0_init, + .clic_vtable.interrupt_init = __metal_driver_sifive_clic0_init, .clic_vtable.interrupt_register = __metal_driver_sifive_clic0_register, - .clic_vtable.interrupt_vector_register = __metal_driver_sifive_clic0_vector_register, - .clic_vtable.interrupt_enable = __metal_driver_sifive_clic0_enable, - .clic_vtable.interrupt_disable = __metal_driver_sifive_clic0_disable, - .clic_vtable.interrupt_vector_enable = __metal_driver_sifive_clic0_enable_interrupt_vector, - .clic_vtable.interrupt_vector_disable = __metal_driver_sifive_clic0_disable_interrupt_vector, - .clic_vtable.interrupt_get_vector_mode = __metal_driver_sifive_clic0_get_vector_mode, - .clic_vtable.interrupt_set_vector_mode = __metal_driver_sifive_clic0_set_vector_mode, - .clic_vtable.interrupt_get_privilege = __metal_driver_sifive_clic0_get_privilege, - .clic_vtable.interrupt_set_privilege = __metal_driver_sifive_clic0_set_privilege, - .clic_vtable.interrupt_get_threshold = __metal_driver_sifive_clic0_get_threshold, - .clic_vtable.interrupt_set_threshold = __metal_driver_sifive_clic0_set_threshold, - .clic_vtable.interrupt_get_priority = __metal_driver_sifive_clic0_get_priority, - .clic_vtable.interrupt_set_priority = __metal_driver_sifive_clic0_set_priority, - .clic_vtable.interrupt_clear = __metal_driver_sifive_clic0_clear_interrupt, - .clic_vtable.interrupt_set = __metal_driver_sifive_clic0_set_interrupt, - .clic_vtable.command_request = __metal_driver_sifive_clic0_command_request, - .clic_vtable.mtimecmp_set = __metal_driver_sifive_clic0_mtimecmp_set, + .clic_vtable.interrupt_vector_register = + __metal_driver_sifive_clic0_vector_register, + .clic_vtable.interrupt_enable = __metal_driver_sifive_clic0_enable, + .clic_vtable.interrupt_disable = __metal_driver_sifive_clic0_disable, + .clic_vtable.interrupt_vector_enable = + __metal_driver_sifive_clic0_enable_interrupt_vector, + .clic_vtable.interrupt_vector_disable = + __metal_driver_sifive_clic0_disable_interrupt_vector, + .clic_vtable.interrupt_get_vector_mode = + __metal_driver_sifive_clic0_get_vector_mode, + .clic_vtable.interrupt_set_vector_mode = + __metal_driver_sifive_clic0_set_vector_mode, + .clic_vtable.interrupt_get_privilege = + __metal_driver_sifive_clic0_get_privilege, + .clic_vtable.interrupt_set_privilege = + __metal_driver_sifive_clic0_set_privilege, + .clic_vtable.interrupt_get_threshold = + __metal_driver_sifive_clic0_get_threshold, + .clic_vtable.interrupt_set_threshold = + __metal_driver_sifive_clic0_set_threshold, + .clic_vtable.interrupt_get_priority = + __metal_driver_sifive_clic0_get_priority, + .clic_vtable.interrupt_set_priority = + __metal_driver_sifive_clic0_set_priority, + .clic_vtable.interrupt_get_preemptive_level = + __metal_driver_sifive_clic0_get_preemptive_level, + .clic_vtable.interrupt_set_preemptive_level = + __metal_driver_sifive_clic0_set_preemptive_level, + .clic_vtable.interrupt_clear = __metal_driver_sifive_clic0_clear_interrupt, + .clic_vtable.interrupt_set = __metal_driver_sifive_clic0_set_interrupt, + .clic_vtable.command_request = __metal_driver_sifive_clic0_command_request, + .clic_vtable.mtimecmp_set = __metal_driver_sifive_clic0_mtimecmp_set, }; #endif /* METAL_SIFIVE_CLIC0 */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfrosc.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfrosc.c index 61af8d314..d4df0402e 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfrosc.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfrosc.c @@ -9,18 +9,20 @@ #include <metal/machine.h> #define CONFIG_DIVIDER 0x0000003FUL -#define CONFIG_TRIM 0x001F0000UL -#define CONFIG_ENABLE 0x40000000UL -#define CONFIG_READY 0x80000000UL - -long __metal_driver_sifive_fe310_g000_hfrosc_get_rate_hz(const struct metal_clock *clock) -{ - struct metal_clock *ref = __metal_driver_sifive_fe310_g000_hfrosc_ref(clock); - long config_offset = __metal_driver_sifive_fe310_g000_hfrosc_config_offset(clock); +#define CONFIG_TRIM 0x001F0000UL +#define CONFIG_ENABLE 0x40000000UL +#define CONFIG_READY 0x80000000UL + +long __metal_driver_sifive_fe310_g000_hfrosc_get_rate_hz( + const struct metal_clock *clock) { + struct metal_clock *ref = + __metal_driver_sifive_fe310_g000_hfrosc_ref(clock); + long config_offset = + __metal_driver_sifive_fe310_g000_hfrosc_config_offset(clock); struct __metal_driver_sifive_fe310_g000_prci *config_base = - __metal_driver_sifive_fe310_g000_hfrosc_config_base(clock); + __metal_driver_sifive_fe310_g000_hfrosc_config_base(clock); const struct __metal_driver_vtable_sifive_fe310_g000_prci *vtable = - __metal_driver_sifive_fe310_g000_prci_vtable(); + __metal_driver_sifive_fe310_g000_prci_vtable(); long cfg = vtable->get_reg(config_base, config_offset); if ((cfg & CONFIG_ENABLE) == 0) @@ -30,8 +32,8 @@ long __metal_driver_sifive_fe310_g000_hfrosc_get_rate_hz(const struct metal_cloc return metal_clock_get_rate_hz(ref) / ((cfg & CONFIG_DIVIDER) + 1); } -long __metal_driver_sifive_fe310_g000_hfrosc_set_rate_hz(struct metal_clock *clock, long rate) -{ +long __metal_driver_sifive_fe310_g000_hfrosc_set_rate_hz( + struct metal_clock *clock, long rate) { return __metal_driver_sifive_fe310_g000_hfrosc_get_rate_hz(clock); } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfxosc.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfxosc.c index 9ed7a0bf3..b8a9c6dda 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfxosc.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_hfxosc.c @@ -8,17 +8,19 @@ #include <metal/drivers/sifive_fe310-g000_hfxosc.h> #include <metal/machine.h> -#define CONFIG_ENABLE 0x40000000UL -#define CONFIG_READY 0x80000000UL - -long __metal_driver_sifive_fe310_g000_hfxosc_get_rate_hz(const struct metal_clock *clock) -{ - struct metal_clock *ref = __metal_driver_sifive_fe310_g000_hfxosc_ref(clock); - long config_offset = __metal_driver_sifive_fe310_g000_hfxosc_config_offset(clock); +#define CONFIG_ENABLE 0x40000000UL +#define CONFIG_READY 0x80000000UL + +long __metal_driver_sifive_fe310_g000_hfxosc_get_rate_hz( + const struct metal_clock *clock) { + struct metal_clock *ref = + __metal_driver_sifive_fe310_g000_hfxosc_ref(clock); + long config_offset = + __metal_driver_sifive_fe310_g000_hfxosc_config_offset(clock); struct __metal_driver_sifive_fe310_g000_prci *config_base = - __metal_driver_sifive_fe310_g000_hfxosc_config_base(clock); + __metal_driver_sifive_fe310_g000_hfxosc_config_base(clock); const struct __metal_driver_vtable_sifive_fe310_g000_prci *vtable = - __metal_driver_sifive_fe310_g000_prci_vtable(); + __metal_driver_sifive_fe310_g000_prci_vtable(); long cfg = vtable->get_reg(config_base, config_offset); if ((cfg & CONFIG_ENABLE) == 0) @@ -28,8 +30,8 @@ long __metal_driver_sifive_fe310_g000_hfxosc_get_rate_hz(const struct metal_cloc return metal_clock_get_rate_hz(ref); } -long __metal_driver_sifive_fe310_g000_hfxosc_set_rate_hz(struct metal_clock *clock, long rate) -{ +long __metal_driver_sifive_fe310_g000_hfxosc_set_rate_hz( + struct metal_clock *clock, long rate) { return __metal_driver_sifive_fe310_g000_hfxosc_get_rate_hz(clock); } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_lfrosc.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_lfrosc.c index 324382b9d..926ad9de8 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_lfrosc.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_lfrosc.c @@ -21,25 +21,30 @@ #define LFROSC_REGW(addr) (__METAL_ACCESS_ONCE((__metal_io_u32 *)addr)) -long __metal_driver_sifive_fe310_g000_lfrosc_get_rate_hz(const struct metal_clock *clock) -{ - struct metal_clock *internal_ref = __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(clock); - struct metal_clock *external_ref = __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(clock); - - unsigned long int cfg_reg = __metal_driver_sifive_fe310_g000_lfrosc_config_reg(clock); - unsigned long int mux_reg = __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(clock); - - if(LFROSC_REGW(mux_reg) & METAL_LFCLKMUX_EXT_MUX_STATUS) { +long __metal_driver_sifive_fe310_g000_lfrosc_get_rate_hz( + const struct metal_clock *clock) { + struct metal_clock *internal_ref = + __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(clock); + struct metal_clock *external_ref = + __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(clock); + + unsigned long int cfg_reg = + __metal_driver_sifive_fe310_g000_lfrosc_config_reg(clock); + unsigned long int mux_reg = + __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(clock); + + if (LFROSC_REGW(mux_reg) & METAL_LFCLKMUX_EXT_MUX_STATUS) { return metal_clock_get_rate_hz(external_ref); } - const unsigned long int div = (LFROSC_REGW(cfg_reg) & METAL_LFROSCCFG_DIV_MASK) + 1; + const unsigned long int div = + (LFROSC_REGW(cfg_reg) & METAL_LFROSCCFG_DIV_MASK) + 1; return metal_clock_get_rate_hz(internal_ref) / div; } -long __metal_driver_sifive_fe310_g000_lfrosc_set_rate_hz(struct metal_clock *clock, long rate) -{ +long __metal_driver_sifive_fe310_g000_lfrosc_set_rate_hz( + struct metal_clock *clock, long rate) { return __metal_driver_sifive_fe310_g000_lfrosc_get_rate_hz(clock); } @@ -50,4 +55,3 @@ __METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_fe310_g000_lfrosc) = { #endif /* METAL_SIFIVE_FE310_G000_LFROSC */ typedef int no_empty_translation_units; - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_pll.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_pll.c index 2ca468f43..5f26d32d2 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_pll.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_pll.c @@ -5,28 +5,31 @@ #ifdef METAL_SIFIVE_FE310_G000_PLL -#include <stdio.h> #include <limits.h> +#include <stdio.h> +#include <metal/init.h> #include <metal/machine.h> +#include <metal/machine/platform.h> + #include <metal/drivers/sifive_fe310-g000_pll.h> #include <stdlib.h> -#define PLL_R 0x00000007UL -#define PLL_F 0x000003F0UL -#define PLL_Q 0x00000C00UL -#define PLL_SEL 0x00010000UL -#define PLL_REFSEL 0x00020000UL -#define PLL_BYPASS 0x00040000UL -#define PLL_LOCK 0x80000000UL +#define PLL_R 0x00000007UL +#define PLL_F 0x000003F0UL +#define PLL_Q 0x00000C00UL +#define PLL_SEL 0x00010000UL +#define PLL_REFSEL 0x00020000UL +#define PLL_BYPASS 0x00040000UL +#define PLL_LOCK 0x80000000UL -#define DIV_DIV 0x0000003FUL -#define DIV_1 0x00000100UL +#define DIV_DIV 0x0000003FUL +#define DIV_1 0x00000100UL -#define PLL_R_SHIFT(r) ((r << 0) & PLL_R) -#define PLL_F_SHIFT(f) ((f << 4) & PLL_F) -#define PLL_Q_SHIFT(q) ((q << 10) & PLL_Q) -#define PLL_DIV_SHIFT(d) ((d << 0) & DIV_DIV) +#define PLL_R_SHIFT(r) ((r << 0) & PLL_R) +#define PLL_F_SHIFT(f) ((f << 4) & PLL_F) +#define PLL_Q_SHIFT(q) ((q << 10) & PLL_Q) +#define PLL_DIV_SHIFT(d) ((d << 0) & DIV_DIV) struct pll_config_t { unsigned long multiplier; @@ -51,79 +54,79 @@ static const struct pll_config_t pll_configs[] = { * | | | | | | ^ d * | | | | | | | ^ * | | | | | | | | */ - { 1, 32, 12000000, 24000000, 1, 31, 3, 63}, - { 1, 32, 24000000, 48000000, 3, 31, 2, 63}, - { 1, 16, 6000000, 12000000, 0, 31, 3, 63}, - { 1, 16, 12000000, 24000000, 1, 31, 2, 63}, - { 1, 16, 24000000, 48000000, 3, 31, 2, 31}, - { 1, 8, 6000000, 12000000, 0, 31, 3, 31}, - { 1, 8, 12000000, 24000000, 1, 31, 2, 31}, - { 1, 8, 24000000, 48000000, 3, 31, 2, 15}, - { 1, 4, 6000000, 12000000, 0, 31, 3, 15}, - { 1, 4, 12000000, 24000000, 1, 31, 2, 15}, - { 1, 4, 24000000, 48000000, 3, 31, 2, 7}, - { 1, 2, 6000000, 12000000, 0, 31, 2, 15}, - { 1, 2, 12000000, 24000000, 1, 31, 1, 15}, - { 1, 2, 24000000, 48000000, 3, 31, 1, 7}, - { 2, 1, 6000000, 12000000, 0, 31, 1, 7}, - { 2, 1, 12000000, 24000000, 1, 31, 1, 3}, - { 2, 1, 24000000, 48000000, 3, 31, 3, -1}, - { 4, 1, 6000000, 12000000, 0, 31, 3, 0}, - { 4, 1, 12000000, 24000000, 1, 31, 3, -1}, - { 4, 1, 24000000, 48000000, 3, 31, 2, -1}, - { 6, 1, 6000000, 10666666, 0, 35, 1, 2}, - { 6, 1, 10666666, 12000000, 0, 23, 3, -1}, - { 6, 1, 12000000, 16000000, 1, 47, 3, -1}, - { 6, 1, 16000000, 18000000, 1, 23, 2, -1}, - { 6, 1, 18000000, 21333333, 2, 35, 2, -1}, - { 8, 1, 6000000, 12000000, 0, 31, 3, -1}, - { 8, 1, 12000000, 24000000, 1, 31, 2, -1}, - { 8, 1, 24000000, 48000000, 3, 31, 1, -1}, - {10, 1, 6000000, 9600000, 0, 39, 3, -1}, - {10, 1, 9600000, 12000000, 0, 19, 2, -1}, - {10, 1, 12000000, 19200000, 1, 39, 2, -1}, - {10, 1, 19200000, 24000000, 1, 19, 1, -1}, - {10, 1, 24000000, 38400000, 3, 39, 1, -1}, - {12, 1, 6000000, 8000000, 0, 47, 3, -1}, - {12, 1, 8000000, 12000000, 0, 23, 2, -1}, - {12, 1, 12000000, 16000000, 1, 47, 2, -1}, - {12, 1, 16000000, 24000000, 1, 23, 1, -1}, - {12, 1, 24000000, 30000000, 3, 47, 1, -1}, - {12, 1, 30000000, 32000000, 3, 47, 1, -1}, - {14, 1, 6000000, 6857142, 0, 55, 3, -1}, - {14, 1, 6857143, 12000000, 0, 27, 2, -1}, - {14, 1, 12000000, 13714285, 1, 55, 2, -1}, - {14, 1, 13714286, 24000000, 1, 27, 1, -1}, - {14, 1, 24000000, 27428571, 3, 55, 1, -1}, - {16, 1, 6000000, 12000000, 0, 31, 2, -1}, - {16, 1, 12000000, 24000000, 1, 31, 1, -1}, - {18, 1, 6000000, 10666666, 0, 35, 2, -1}, - {18, 1, 10666667, 12000000, 0, 17, 1, -1}, - {18, 1, 12000000, 21333333, 1, 35, 1, -1}, - {20, 1, 6000000, 9600000, 0, 39, 2, -1}, - {20, 1, 9600000, 12000000, 0, 19, 1, -1}, - {20, 1, 12000000, 19200000, 1, 39, 1, -1}, - {22, 1, 6000000, 8727272, 0, 43, 2, -1}, - {22, 1, 8727273, 12000000, 0, 21, 1, -1}, - {22, 1, 12000000, 17454545, 1, 43, 1, -1}, - {24, 1, 6000000, 8000000, 0, 47, 2, -1}, - {24, 1, 8000000, 12000000, 0, 23, 1, -1}, - {24, 1, 12000000, 16000000, 1, 47, 1, -1}, - {26, 1, 6000000, 7384615, 0, 51, 2, -1}, - {26, 1, 7384616, 12000000, 0, 25, 1, -1}, - {26, 1, 12000000, 14768230, 1, 51, 1, -1}, - {28, 1, 6000000, 6857142, 0, 55, 2, -1}, - {28, 1, 6857143, 12000000, 0, 27, 1, -1}, - {28, 1, 12000000, 13714285, 1, 55, 1, -1}, - {30, 1, 6000000, 6400000, 0, 59, 2, -1}, - {30, 1, 6400000, 12000000, 0, 29, 1, -1}, - {30, 1, 12000000, 12800000, 1, 59, 1, -1}, - {32, 1, 6000000, 12000000, 0, 31, 1, -1} -}; + {1, 32, 12000000, 24000000, 1, 31, 3, 63}, + {1, 32, 24000000, 48000000, 3, 31, 2, 63}, + {1, 16, 6000000, 12000000, 0, 31, 3, 63}, + {1, 16, 12000000, 24000000, 1, 31, 2, 63}, + {1, 16, 24000000, 48000000, 3, 31, 2, 31}, + {1, 8, 6000000, 12000000, 0, 31, 3, 31}, + {1, 8, 12000000, 24000000, 1, 31, 2, 31}, + {1, 8, 24000000, 48000000, 3, 31, 2, 15}, + {1, 4, 6000000, 12000000, 0, 31, 3, 15}, + {1, 4, 12000000, 24000000, 1, 31, 2, 15}, + {1, 4, 24000000, 48000000, 3, 31, 2, 7}, + {1, 2, 6000000, 12000000, 0, 31, 2, 15}, + {1, 2, 12000000, 24000000, 1, 31, 1, 15}, + {1, 2, 24000000, 48000000, 3, 31, 1, 7}, + {2, 1, 6000000, 12000000, 0, 31, 1, 7}, + {2, 1, 12000000, 24000000, 1, 31, 1, 3}, + {2, 1, 24000000, 48000000, 3, 31, 3, -1}, + {4, 1, 6000000, 12000000, 0, 31, 3, 0}, + {4, 1, 12000000, 24000000, 1, 31, 3, -1}, + {4, 1, 24000000, 48000000, 3, 31, 2, -1}, + {6, 1, 6000000, 10666666, 0, 35, 1, 2}, + {6, 1, 10666666, 12000000, 0, 23, 3, -1}, + {6, 1, 12000000, 16000000, 1, 47, 3, -1}, + {6, 1, 16000000, 18000000, 1, 23, 2, -1}, + {6, 1, 18000000, 21333333, 2, 35, 2, -1}, + {8, 1, 6000000, 12000000, 0, 31, 3, -1}, + {8, 1, 12000000, 24000000, 1, 31, 2, -1}, + {8, 1, 24000000, 48000000, 3, 31, 1, -1}, + {10, 1, 6000000, 9600000, 0, 39, 3, -1}, + {10, 1, 9600000, 12000000, 0, 19, 2, -1}, + {10, 1, 12000000, 19200000, 1, 39, 2, -1}, + {10, 1, 19200000, 24000000, 1, 19, 1, -1}, + {10, 1, 24000000, 38400000, 3, 39, 1, -1}, + {12, 1, 6000000, 8000000, 0, 47, 3, -1}, + {12, 1, 8000000, 12000000, 0, 23, 2, -1}, + {12, 1, 12000000, 16000000, 1, 47, 2, -1}, + {12, 1, 16000000, 24000000, 1, 23, 1, -1}, + {12, 1, 24000000, 30000000, 3, 47, 1, -1}, + {12, 1, 30000000, 32000000, 3, 47, 1, -1}, + {14, 1, 6000000, 6857142, 0, 55, 3, -1}, + {14, 1, 6857143, 12000000, 0, 27, 2, -1}, + {14, 1, 12000000, 13714285, 1, 55, 2, -1}, + {14, 1, 13714286, 24000000, 1, 27, 1, -1}, + {14, 1, 24000000, 27428571, 3, 55, 1, -1}, + {16, 1, 6000000, 12000000, 0, 31, 2, -1}, + {16, 1, 12000000, 24000000, 1, 31, 1, -1}, + {18, 1, 6000000, 10666666, 0, 35, 2, -1}, + {18, 1, 10666667, 12000000, 0, 17, 1, -1}, + {18, 1, 12000000, 21333333, 1, 35, 1, -1}, + {20, 1, 6000000, 9600000, 0, 39, 2, -1}, + {20, 1, 9600000, 12000000, 0, 19, 1, -1}, + {20, 1, 12000000, 19200000, 1, 39, 1, -1}, + {22, 1, 6000000, 8727272, 0, 43, 2, -1}, + {22, 1, 8727273, 12000000, 0, 21, 1, -1}, + {22, 1, 12000000, 17454545, 1, 43, 1, -1}, + {24, 1, 6000000, 8000000, 0, 47, 2, -1}, + {24, 1, 8000000, 12000000, 0, 23, 1, -1}, + {24, 1, 12000000, 16000000, 1, 47, 1, -1}, + {26, 1, 6000000, 7384615, 0, 51, 2, -1}, + {26, 1, 7384616, 12000000, 0, 25, 1, -1}, + {26, 1, 12000000, 14768230, 1, 51, 1, -1}, + {28, 1, 6000000, 6857142, 0, 55, 2, -1}, + {28, 1, 6857143, 12000000, 0, 27, 1, -1}, + {28, 1, 12000000, 13714285, 1, 55, 1, -1}, + {30, 1, 6000000, 6400000, 0, 59, 2, -1}, + {30, 1, 6400000, 12000000, 0, 29, 1, -1}, + {30, 1, 12000000, 12800000, 1, 59, 1, -1}, + {32, 1, 6000000, 12000000, 0, 31, 1, -1}}; #define PLL_CONFIG_NOT_VALID -1 -void __metal_driver_sifive_fe310_g000_pll_init(struct __metal_driver_sifive_fe310_g000_pll *pll); +void __metal_driver_sifive_fe310_g000_pll_init( + struct __metal_driver_sifive_fe310_g000_pll *pll); /* Given the rate of the PLL input frequency and a PLL configuration, what * will the resulting PLL output frequency be? @@ -131,11 +134,13 @@ void __metal_driver_sifive_fe310_g000_pll_init(struct __metal_driver_sifive_fe31 * - pll_input_rate the PLL input frequency in hertz * - config the PLL configuration * Returns: - * - PLL_CONFIG_NOT_VALID if the configuration is not valid for the input frequency + * - PLL_CONFIG_NOT_VALID if the configuration is not valid for the input + * frequency * - the output frequency, in hertz */ -static long get_pll_config_freq(unsigned long pll_input_rate, const struct pll_config_t *config) -{ - if(pll_input_rate < config->min_input_rate || pll_input_rate > config->max_input_rate) +static long get_pll_config_freq(unsigned long pll_input_rate, + const struct pll_config_t *config) { + if (pll_input_rate < config->min_input_rate || + pll_input_rate > config->max_input_rate) return PLL_CONFIG_NOT_VALID; return pll_input_rate * config->multiplier / config->divisor; @@ -143,33 +148,37 @@ static long get_pll_config_freq(unsigned long pll_input_rate, const struct pll_c #ifdef __METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE -static void metal_sifive_fe310_g000_pll_init(void) __attribute__((constructor)); -static void metal_sifive_fe310_g000_pll_init(void) { +METAL_CONSTRUCTOR(metal_sifive_fe310_g000_pll_init) { long init_rate = __metal_driver_sifive_fe310_g000_pll_init_rate(); /* If the PLL init_rate is zero, don't initialize the PLL */ - if(init_rate != 0) - __metal_driver_sifive_fe310_g000_pll_init(__METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE); + if (init_rate != 0) + __metal_driver_sifive_fe310_g000_pll_init( + __METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE); } #endif /* __METAL_DT_SIFIVE_FE310_G000__PLL_HANDLE */ -void __metal_driver_sifive_fe310_g000_pll_init(struct __metal_driver_sifive_fe310_g000_pll *pll) { - struct metal_clock *pllref = __metal_driver_sifive_fe310_g000_pll_pllref(&(pll->clock)); +void __metal_driver_sifive_fe310_g000_pll_init( + struct __metal_driver_sifive_fe310_g000_pll *pll) { + struct metal_clock *pllref = + __metal_driver_sifive_fe310_g000_pll_pllref(&(pll->clock)); long init_rate = __metal_driver_sifive_fe310_g000_pll_init_rate(); long config_offset = __metal_driver_sifive_fe310_g000_pll_config_offset(); long base = __metal_driver_sifive_fe310_g000_prci_base(); - __metal_io_u32 *pllcfg = (__metal_io_u32 *) (base + config_offset); + __metal_io_u32 *pllcfg = (__metal_io_u32 *)(base + config_offset); - /* If the PLL clock has had a _pre_rate_change_callback configured, call it */ + /* If the PLL clock has had a _pre_rate_change_callback configured, call it + */ _metal_clock_call_all_callbacks(pll->clock._pre_rate_change_callback); - /* If we're running off of the PLL, switch off before we start configuring it*/ - if((__METAL_ACCESS_ONCE(pllcfg) & PLL_SEL) == 0) + /* If we're running off of the PLL, switch off before we start configuring + * it*/ + if ((__METAL_ACCESS_ONCE(pllcfg) & PLL_SEL) != 0) __METAL_ACCESS_ONCE(pllcfg) &= ~(PLL_SEL); /* Make sure we're running off of the external oscillator for stability */ - if(pllref != NULL) + if (pllref != NULL) __METAL_ACCESS_ONCE(pllcfg) |= PLL_REFSEL; /* Configure the PLL to run at the requested init frequency. @@ -181,18 +190,22 @@ void __metal_driver_sifive_fe310_g000_pll_init(struct __metal_driver_sifive_fe31 _metal_clock_call_all_callbacks(pll->clock._post_rate_change_callback); } -long __metal_driver_sifive_fe310_g000_pll_get_rate_hz(const struct metal_clock *clock) -{ - struct metal_clock *pllref = __metal_driver_sifive_fe310_g000_pll_pllref(clock); - struct metal_clock *pllsel0 = __metal_driver_sifive_fe310_g000_pll_pllsel0(clock); - long config_offset = __metal_driver_sifive_fe310_g000_pll_config_offset(clock); +long __metal_driver_sifive_fe310_g000_pll_get_rate_hz( + const struct metal_clock *clock) { + struct metal_clock *pllref = + __metal_driver_sifive_fe310_g000_pll_pllref(clock); + struct metal_clock *pllsel0 = + __metal_driver_sifive_fe310_g000_pll_pllsel0(clock); + long config_offset = + __metal_driver_sifive_fe310_g000_pll_config_offset(clock); struct __metal_driver_sifive_fe310_g000_prci *config_base = - __metal_driver_sifive_fe310_g000_pll_config_base(clock); - long divider_offset = __metal_driver_sifive_fe310_g000_pll_divider_offset(clock); + __metal_driver_sifive_fe310_g000_pll_config_base(clock); + long divider_offset = + __metal_driver_sifive_fe310_g000_pll_divider_offset(clock); struct __metal_driver_sifive_fe310_g000_prci *divider_base = - __metal_driver_sifive_fe310_g000_pll_divider_base(clock); + __metal_driver_sifive_fe310_g000_pll_divider_base(clock); const struct __metal_driver_vtable_sifive_fe310_g000_prci *vtable = - __metal_driver_sifive_fe310_g000_prci_vtable(); + __metal_driver_sifive_fe310_g000_prci_vtable(); long cfg = vtable->get_reg(config_base, config_offset); long div = vtable->get_reg(divider_base, divider_offset); @@ -204,7 +217,8 @@ long __metal_driver_sifive_fe310_g000_pll_get_rate_hz(const struct metal_clock * /* There's a clock mux before the PLL that selects between the HFROSC adn * the HFXOSC as the PLL's input clock. */ - long ref_hz = metal_clock_get_rate_hz(__METAL_GET_FIELD(cfg, PLL_REFSEL) ? pllref : pllsel0); + long ref_hz = metal_clock_get_rate_hz( + __METAL_GET_FIELD(cfg, PLL_REFSEL) ? pllref : pllsel0); /* It's possible to bypass the PLL, which is an internal bpyass. This * still obays the PLL's input clock mu. */ @@ -236,21 +250,19 @@ long __metal_driver_sifive_fe310_g000_pll_get_rate_hz(const struct metal_clock * * Returns: * -1 if no valid configuration is available * the index into pll_configs of a valid configuration */ -static int find_closest_config(long ref_hz, long rate) -{ +static int find_closest_config(long ref_hz, long rate) { int closest_index = -1; long closest_diff = LONG_MAX; /* We're probably trying for a fast output frequency, so start from * the high end of the configs. */ - for(int i = (sizeof(pll_configs) / sizeof(pll_configs[0])) - 1; i >= 0; i--) - { + for (int i = (sizeof(pll_configs) / sizeof(pll_configs[0])) - 1; i >= 0; + i--) { long config_freq = get_pll_config_freq(ref_hz, &(pll_configs[i])); - if(config_freq != PLL_CONFIG_NOT_VALID) - { - long freq_diff = abs(config_freq - rate); - if(freq_diff < closest_diff) - { + if (config_freq != PLL_CONFIG_NOT_VALID) { + long freq_diff = labs(config_freq - rate); + + if (freq_diff < closest_diff) { closest_index = i; closest_diff = freq_diff; } @@ -260,9 +272,22 @@ static int find_closest_config(long ref_hz, long rate) return closest_index; } +/* The PLL needs 100 usec to stabilize before we test PLL_LOCK. Since LFROSC + * on all targets with the FE310-G000 PLL runs at 32768 Hz, we need to wait + * at least + * + * ceil(100 usec * 32768 ticks/sec * 1 sec / 1000000 usec) = 4 ticks + * + * of mtime before we test PLL_LOCK. + * + * TODO: Determine the mtime timebase at compile or runtime and use that + * here. + */ +#define PLL_LOCK_WAIT_TICKS 4 + /* Configure the PLL and wait for it to lock */ -static void configure_pll(__metal_io_u32 *pllcfg, __metal_io_u32 *plloutdiv, const struct pll_config_t *config) -{ +static void configure_pll(__metal_io_u32 *pllcfg, __metal_io_u32 *plloutdiv, + const struct pll_config_t *config) { __METAL_ACCESS_ONCE(pllcfg) &= ~(PLL_R); __METAL_ACCESS_ONCE(pllcfg) |= PLL_R_SHIFT(config->r); @@ -272,16 +297,13 @@ static void configure_pll(__metal_io_u32 *pllcfg, __metal_io_u32 *plloutdiv, con __METAL_ACCESS_ONCE(pllcfg) &= ~(PLL_Q); __METAL_ACCESS_ONCE(pllcfg) |= PLL_Q_SHIFT(config->q); - if(config->d < 0) - { + if (config->d < 0) { /* disable final divider */ __METAL_ACCESS_ONCE(plloutdiv) |= DIV_1; __METAL_ACCESS_ONCE(plloutdiv) &= ~(DIV_DIV); __METAL_ACCESS_ONCE(plloutdiv) |= PLL_DIV_SHIFT(1); - } - else - { + } else { __METAL_ACCESS_ONCE(plloutdiv) &= ~(DIV_1); __METAL_ACCESS_ONCE(plloutdiv) &= ~(DIV_DIV); @@ -290,20 +312,49 @@ static void configure_pll(__metal_io_u32 *pllcfg, __metal_io_u32 *plloutdiv, con __METAL_ACCESS_ONCE(pllcfg) &= ~(PLL_BYPASS); + /* Wait for the PLL to stabilize before testing it for lock */ +#ifdef __METAL_DT_RISCV_CLINT0_HANDLE + unsigned long long mtime, mtime_end; + __metal_driver_riscv_clint0_command_request(__METAL_DT_RISCV_CLINT0_HANDLE, + METAL_TIMER_MTIME_GET, &mtime); + mtime_end = mtime + PLL_LOCK_WAIT_TICKS; + while (mtime <= mtime_end) { + __metal_driver_riscv_clint0_command_request( + __METAL_DT_RISCV_CLINT0_HANDLE, METAL_TIMER_MTIME_GET, &mtime); + } +#elif __METAL_DT_RISCV_CLIC0_HANDLE + unsigned long long mtime, mtime_end; + __metal_driver_sifive_clic0_command_request(__METAL_DT_RISCV_CLIC0_HANDLE, + METAL_TIMER_MTIME_GET, &mtime); + mtime_end = mtime + PLL_LOCK_WAIT_TICKS; + while (mtime <= mtime_end) { + __metal_driver_sifive_clic0_command_request( + __METAL_DT_RISCV_CLIC0_HANDLE, METAL_TIMER_MTIME_GET, &mtime); + } +#else +#pragma message( \ + No handle for CLINT or CLIC found, PLL might race with lock signal !) +#endif + /* Wait for PLL to lock */ - while((__METAL_ACCESS_ONCE(pllcfg) & PLL_LOCK) == 0) ; + while ((__METAL_ACCESS_ONCE(pllcfg) & PLL_LOCK) == 0) + ; } -long __metal_driver_sifive_fe310_g000_pll_set_rate_hz(struct metal_clock *clock, long rate) -{ - struct metal_clock *pllref = __metal_driver_sifive_fe310_g000_pll_pllref(clock); - struct metal_clock *pllsel0 = __metal_driver_sifive_fe310_g000_pll_pllsel0(clock); - long config_offset = __metal_driver_sifive_fe310_g000_pll_config_offset(clock); - long divider_offset = __metal_driver_sifive_fe310_g000_pll_divider_offset(clock); +long __metal_driver_sifive_fe310_g000_pll_set_rate_hz(struct metal_clock *clock, + long rate) { + struct metal_clock *pllref = + __metal_driver_sifive_fe310_g000_pll_pllref(clock); + struct metal_clock *pllsel0 = + __metal_driver_sifive_fe310_g000_pll_pllsel0(clock); + long config_offset = + __metal_driver_sifive_fe310_g000_pll_config_offset(clock); + long divider_offset = + __metal_driver_sifive_fe310_g000_pll_divider_offset(clock); long base = __metal_driver_sifive_fe310_g000_prci_base(); - __metal_io_u32 *pllcfg = (__metal_io_u32 *) (base + config_offset); - __metal_io_u32 *plloutdiv = (__metal_io_u32 *) (base + divider_offset); + __metal_io_u32 *pllcfg = (__metal_io_u32 *)(base + config_offset); + __metal_io_u32 *plloutdiv = (__metal_io_u32 *)(base + divider_offset); /* We can't modify the PLL if coreclk is driven by it, so switch it off */ if (__METAL_ACCESS_ONCE(pllcfg) & PLL_SEL) @@ -311,22 +362,18 @@ long __metal_driver_sifive_fe310_g000_pll_set_rate_hz(struct metal_clock *clock, /* There's a clock mux before the PLL that selects between the HFROSC and * the HFXOSC as the PLL's input clock. */ - long ref_hz = metal_clock_get_rate_hz(__METAL_ACCESS_ONCE(pllcfg) & PLL_REFSEL ? pllref : pllsel0); + long ref_hz = metal_clock_get_rate_hz( + __METAL_ACCESS_ONCE(pllcfg) & PLL_REFSEL ? pllref : pllsel0); - /* if the desired rate is within 75%-125% of the input clock, bypass the PLL */ - if((ref_hz * 3 / 4) <= rate && (ref_hz * 5 / 4) >= rate) - { + /* if the desired rate is within 75%-125% of the input clock, bypass the PLL + */ + if ((ref_hz * 3 / 4) <= rate && (ref_hz * 5 / 4) >= rate) { __METAL_ACCESS_ONCE(pllcfg) |= PLL_BYPASS; - } - else - { + } else { int config_index = find_closest_config(ref_hz, rate); - if(config_index != -1) - { + if (config_index != -1) { configure_pll(pllcfg, plloutdiv, &(pll_configs[config_index])); - } - else - { + } else { /* unable to find a valid configuration */ __METAL_ACCESS_ONCE(pllcfg) |= PLL_BYPASS; } @@ -339,13 +386,10 @@ long __metal_driver_sifive_fe310_g000_pll_set_rate_hz(struct metal_clock *clock, } #ifdef __METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE -static void use_hfxosc(void) __attribute__((constructor)); -static void use_hfxosc(void) -{ +METAL_CONSTRUCTOR(use_hfxosc) { long init_rate = __metal_driver_sifive_fe310_g000_pll_init_rate(); - metal_clock_set_rate_hz( - &__METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE->clock, init_rate - ); + metal_clock_set_rate_hz(&__METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE->clock, + init_rate); } #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_prci.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_prci.c index 1236eca3b..f863feb3d 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_prci.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fe310-g000_prci.c @@ -8,12 +8,15 @@ #include <metal/drivers/sifive_fe310-g000_prci.h> #include <metal/machine.h> -long __metal_driver_sifive_fe310_g000_prci_get_reg(const struct __metal_driver_sifive_fe310_g000_prci *prci, long offset) { +long __metal_driver_sifive_fe310_g000_prci_get_reg( + const struct __metal_driver_sifive_fe310_g000_prci *prci, long offset) { unsigned long base = __metal_driver_sifive_fe310_g000_prci_base(); return __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + offset)); } -long __metal_driver_sifive_fe310_g000_prci_set_reg(const struct __metal_driver_sifive_fe310_g000_prci *prci, long offset, long value) { +long __metal_driver_sifive_fe310_g000_prci_set_reg( + const struct __metal_driver_sifive_fe310_g000_prci *prci, long offset, + long value) { unsigned long base = __metal_driver_sifive_fe310_g000_prci_base(); return __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + offset)) = value; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fu540-c000_l2.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fu540-c000_l2.c deleted file mode 100644 index aafc6e5e3..000000000 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_fu540-c000_l2.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright 2018 SiFive, Inc */ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include <metal/machine/platform.h> - -#ifdef METAL_SIFIVE_FU540_C000_L2 - -#include <stdint.h> -#include <metal/io.h> -#include <metal/drivers/sifive_fu540-c000_l2.h> -#include <metal/machine.h> - -#define L2_CONFIG_WAYS_SHIFT 8 -#define L2_CONFIG_WAYS_MASK (0xFF << L2_CONFIG_WAYS_SHIFT) - -void __metal_driver_sifive_fu540_c000_l2_init(struct metal_cache *l2, int ways); - -static void metal_driver_sifive_fu540_c000_l2_init(void) __attribute__((constructor)); -static void metal_driver_sifive_fu540_c000_l2_init(void) -{ -#ifdef __METAL_DT_SIFIVE_FU540_C000_L2_HANDLE - /* Get the handle for the L2 cache controller */ - struct metal_cache *l2 = __METAL_DT_SIFIVE_FU540_C000_L2_HANDLE; - if(!l2) { - return; - } - - /* Get the number of available ways per bank */ - unsigned long control_base = __metal_driver_sifive_fu540_c000_l2_control_base(l2); - uint32_t ways = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_FU540_C000_L2_CONFIG)); - ways = ((ways & L2_CONFIG_WAYS_MASK) >> L2_CONFIG_WAYS_SHIFT); - - /* Enable all the ways */ - __metal_driver_sifive_fu540_c000_l2_init(l2, ways); -#endif -} - -void __metal_driver_sifive_fu540_c000_l2_init(struct metal_cache *l2, int ways) -{ - metal_cache_set_enabled_ways(l2, ways); -} - -int __metal_driver_sifive_fu540_c000_l2_get_enabled_ways(struct metal_cache *cache) -{ - unsigned long control_base = __metal_driver_sifive_fu540_c000_l2_control_base(cache); - - uint32_t way_enable = __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_FU540_C000_L2_WAYENABLE)); - - /* The stored number is the index, so add one */ - return (0xFF & way_enable) + 1; -} - -int __metal_driver_sifive_fu540_c000_l2_set_enabled_ways(struct metal_cache *cache, int ways) -{ - unsigned long control_base = __metal_driver_sifive_fu540_c000_l2_control_base(cache); - - /* We can't decrease the number of enabled ways */ - if(metal_cache_get_enabled_ways(cache) > ways) { - return -2; - } - - /* The stored value is the index, so subtract one */ - uint32_t value = 0xFF & (ways - 1); - - /* Set the number of enabled ways */ - __METAL_ACCESS_ONCE((__metal_io_u32 *)(control_base + METAL_SIFIVE_FU540_C000_L2_WAYENABLE)) = value; - - /* Make sure the number of ways was set correctly */ - if(metal_cache_get_enabled_ways(cache) != ways) { - return -3; - } - - return 0; -} - -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_fu540_c000_l2) = { - .cache.init = __metal_driver_sifive_fu540_c000_l2_init, - .cache.get_enabled_ways = __metal_driver_sifive_fu540_c000_l2_get_enabled_ways, - .cache.set_enabled_ways = __metal_driver_sifive_fu540_c000_l2_set_enabled_ways, -}; - -#endif - -typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_global-external-interrupts0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_global-external-interrupts0.c index 0d56bafef..3fd96b91d 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_global-external-interrupts0.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_global-external-interrupts0.c @@ -5,44 +5,51 @@ #ifdef METAL_SIFIVE_GLOBAL_EXTERNAL_INTERRUPTS0 -#include <metal/io.h> -#include <metal/shutdown.h> #include <metal/drivers/sifive_global-external-interrupts0.h> +#include <metal/io.h> #include <metal/machine.h> +#include <metal/shutdown.h> -void __metal_driver_sifive_global_external_interrupt_init(struct metal_interrupt *controller) -{ +void __metal_driver_sifive_global_external_interrupt_init( + struct metal_interrupt *controller) { struct __metal_driver_sifive_global_external_interrupts0 *global0; - global0 = (struct __metal_driver_sifive_global_external_interrupts0 *)(controller); - if ( !global0->init_done ) { + global0 = (struct __metal_driver_sifive_global_external_interrupts0 + *)(controller); + if (!global0->init_done) { struct metal_interrupt *intc = - __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); - - if (intc) { - intc->vtable->interrupt_init(intc); - /* Register its interrupts with with parent controller */ - for (int i = 0; - i < __metal_driver_sifive_global_external_interrupts0_num_interrupts(controller); - i++) { - intc->vtable->interrupt_register(intc, - __metal_driver_sifive_global_external_interrupts0_interrupt_lines(controller, i), - NULL, controller); - } + __metal_driver_sifive_global_external_interrupts0_interrupt_parent( + controller); + + if (intc) { + intc->vtable->interrupt_init(intc); + /* Register its interrupts with with parent controller */ + for ( + int i = 0; + i < + __metal_driver_sifive_global_external_interrupts0_num_interrupts( + controller); + i++) { + intc->vtable->interrupt_register( + intc, + __metal_driver_sifive_global_external_interrupts0_interrupt_lines( + controller, i), + NULL, controller); + } global0->init_done = 1; - } + } } } -int __metal_driver_sifive_global_external_interrupt_register(struct metal_interrupt *controller, - int id, metal_interrupt_handler_t isr, - void *priv) -{ +int __metal_driver_sifive_global_external_interrupt_register( + struct metal_interrupt *controller, int id, metal_interrupt_handler_t isr, + void *priv) { int rc = -1; if (id != 0) { struct metal_interrupt *intc = - __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + __metal_driver_sifive_global_external_interrupts0_interrupt_parent( + controller); /* Enable its interrupts with parent controller */ if (intc) { @@ -52,13 +59,14 @@ int __metal_driver_sifive_global_external_interrupt_register(struct metal_interr return rc; } -int __metal_driver_sifive_global_external_interrupt_enable(struct metal_interrupt *controller, int id) -{ +int __metal_driver_sifive_global_external_interrupt_enable( + struct metal_interrupt *controller, int id) { int rc = -1; if (id != 0) { struct metal_interrupt *intc = - __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + __metal_driver_sifive_global_external_interrupts0_interrupt_parent( + controller); /* Enable its interrupts with parent controller */ if (intc) { @@ -68,13 +76,14 @@ int __metal_driver_sifive_global_external_interrupt_enable(struct metal_interrup return rc; } -int __metal_driver_sifive_global_external_interrupt_disable(struct metal_interrupt *controller, int id) -{ +int __metal_driver_sifive_global_external_interrupt_disable( + struct metal_interrupt *controller, int id) { int rc = -1; if (id != 0) { struct metal_interrupt *intc = - __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + __metal_driver_sifive_global_external_interrupts0_interrupt_parent( + controller); /* Enable its interrupts with parent controller */ if (intc) { @@ -84,21 +93,22 @@ int __metal_driver_sifive_global_external_interrupt_disable(struct metal_interru return rc; } -int __metal_driver_sifive_global_external_interrupt_set_threshold(struct metal_interrupt *controller, - unsigned int threshold) -{ +int __metal_driver_sifive_global_external_interrupt_set_threshold( + struct metal_interrupt *controller, unsigned int threshold) { struct metal_interrupt *intc = - __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + __metal_driver_sifive_global_external_interrupts0_interrupt_parent( + controller); if (intc) { return intc->vtable->interrupt_set_threshold(intc, threshold); } return -1; } -unsigned int __metal_driver_sifive_global_external_interrupt_get_threshold(struct metal_interrupt *controller) -{ +unsigned int __metal_driver_sifive_global_external_interrupt_get_threshold( + struct metal_interrupt *controller) { struct metal_interrupt *intc = - __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + __metal_driver_sifive_global_external_interrupts0_interrupt_parent( + controller); if (intc) { return intc->vtable->interrupt_get_threshold(intc); @@ -106,21 +116,22 @@ unsigned int __metal_driver_sifive_global_external_interrupt_get_threshold(struc return 0; } -int __metal_driver_sifive_global_external_interrupt_set_priority(struct metal_interrupt *controller, - int id, unsigned int priority) -{ +int __metal_driver_sifive_global_external_interrupt_set_priority( + struct metal_interrupt *controller, int id, unsigned int priority) { struct metal_interrupt *intc = - __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + __metal_driver_sifive_global_external_interrupts0_interrupt_parent( + controller); if (intc) { return intc->vtable->interrupt_set_priority(intc, id, priority); } return -1; } -unsigned int __metal_driver_sifive_global_external_interrupt_get_priority(struct metal_interrupt *controller, int id) -{ +unsigned int __metal_driver_sifive_global_external_interrupt_get_priority( + struct metal_interrupt *controller, int id) { struct metal_interrupt *intc = - __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + __metal_driver_sifive_global_external_interrupts0_interrupt_parent( + controller); if (intc) { return intc->vtable->interrupt_get_priority(intc, id); @@ -128,21 +139,23 @@ unsigned int __metal_driver_sifive_global_external_interrupt_get_priority(struct return 0; } -int __metal_driver_sifive_global_external_command_request (struct metal_interrupt *controller, - int command, void *data) -{ +int __metal_driver_sifive_global_external_command_request( + struct metal_interrupt *controller, int command, void *data) { int idx; int rc = -1; switch (command) { case METAL_MAX_INTERRUPT_GET: - rc = __metal_driver_sifive_global_external_interrupts0_num_interrupts(controller); + rc = __metal_driver_sifive_global_external_interrupts0_num_interrupts( + controller); break; case METAL_INDEX_INTERRUPT_GET: rc = 0; if (data) { idx = *(int *)data; - rc = __metal_driver_sifive_global_external_interrupts0_interrupt_lines(controller, idx); + rc = + __metal_driver_sifive_global_external_interrupts0_interrupt_lines( + controller, idx); } break; default: @@ -152,16 +165,26 @@ int __metal_driver_sifive_global_external_command_request (struct metal_interrup return rc; } -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_global_external_interrupts0) = { - .global0_vtable.interrupt_init = __metal_driver_sifive_global_external_interrupt_init, - .global0_vtable.interrupt_register = __metal_driver_sifive_global_external_interrupt_register, - .global0_vtable.interrupt_enable = __metal_driver_sifive_global_external_interrupt_enable, - .global0_vtable.interrupt_disable = __metal_driver_sifive_global_external_interrupt_disable, - .global0_vtable.interrupt_get_threshold = __metal_driver_sifive_global_external_interrupt_get_threshold, - .global0_vtable.interrupt_set_threshold = __metal_driver_sifive_global_external_interrupt_set_threshold, - .global0_vtable.interrupt_get_priority = __metal_driver_sifive_global_external_interrupt_get_priority, - .global0_vtable.interrupt_set_priority = __metal_driver_sifive_global_external_interrupt_set_priority, - .global0_vtable.command_request = __metal_driver_sifive_global_external_command_request, +__METAL_DEFINE_VTABLE( + __metal_driver_vtable_sifive_global_external_interrupts0) = { + .global0_vtable.interrupt_init = + __metal_driver_sifive_global_external_interrupt_init, + .global0_vtable.interrupt_register = + __metal_driver_sifive_global_external_interrupt_register, + .global0_vtable.interrupt_enable = + __metal_driver_sifive_global_external_interrupt_enable, + .global0_vtable.interrupt_disable = + __metal_driver_sifive_global_external_interrupt_disable, + .global0_vtable.interrupt_get_threshold = + __metal_driver_sifive_global_external_interrupt_get_threshold, + .global0_vtable.interrupt_set_threshold = + __metal_driver_sifive_global_external_interrupt_set_threshold, + .global0_vtable.interrupt_get_priority = + __metal_driver_sifive_global_external_interrupt_get_priority, + .global0_vtable.interrupt_set_priority = + __metal_driver_sifive_global_external_interrupt_set_priority, + .global0_vtable.command_request = + __metal_driver_sifive_global_external_command_request, }; #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-buttons.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-buttons.c index 923fe2711..119bd8abe 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-buttons.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-buttons.c @@ -5,13 +5,12 @@ #ifdef METAL_SIFIVE_GPIO_BUTTONS -#include <string.h> #include <metal/drivers/riscv_cpu.h> #include <metal/drivers/sifive_gpio-buttons.h> #include <metal/machine.h> +#include <string.h> -int __metal_driver_button_exist (struct metal_button *button, char *label) -{ +int __metal_driver_button_exist(struct metal_button *button, char *label) { if (strcmp(__metal_driver_sifive_gpio_button_label(button), label) == 0) { return 1; } @@ -19,36 +18,33 @@ int __metal_driver_button_exist (struct metal_button *button, char *label) } struct metal_interrupt * -__metal_driver_button_interrupt_controller(struct metal_button *button) -{ +__metal_driver_button_interrupt_controller(struct metal_button *button) { return __metal_driver_sifive_gpio_button_interrupt_controller(button); } -int __metal_driver_button_get_interrupt_id(struct metal_button *button) -{ +int __metal_driver_button_get_interrupt_id(struct metal_button *button) { int irq, max_irq; struct metal_interrupt *irc; irq = __metal_driver_sifive_gpio_button_interrupt_line(button); - irc = __metal_driver_sifive_gpio_button_interrupt_controller(button); + irc = __metal_driver_sifive_gpio_button_interrupt_controller(button); if (irc != NULL) { - max_irq = _metal_interrupt_command_request(irc, - METAL_MAX_INTERRUPT_GET, + max_irq = _metal_interrupt_command_request(irc, METAL_MAX_INTERRUPT_GET, NULL); if (irq < max_irq) { - return _metal_interrupt_command_request(irc, - METAL_INDEX_INTERRUPT_GET, - (void *)&irq); + return _metal_interrupt_command_request( + irc, METAL_INDEX_INTERRUPT_GET, (void *)&irq); } } return METAL_INTERRUPT_ID_LCMX; } __METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_button) = { - .button_vtable.button_exist = __metal_driver_button_exist, - .button_vtable.interrupt_controller = __metal_driver_button_interrupt_controller, + .button_vtable.button_exist = __metal_driver_button_exist, + .button_vtable.interrupt_controller = + __metal_driver_button_interrupt_controller, .button_vtable.get_interrupt_id = __metal_driver_button_get_interrupt_id, }; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-leds.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-leds.c index a6b627458..ef32528c8 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-leds.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-leds.c @@ -5,79 +5,74 @@ #ifdef METAL_SIFIVE_GPIO_LEDS -#include <string.h> -#include <metal/gpio.h> #include <metal/drivers/sifive_gpio-leds.h> +#include <metal/gpio.h> #include <metal/machine.h> +#include <string.h> -int __metal_driver_led_exist (struct metal_led *led, char *label) -{ +int __metal_driver_led_exist(struct metal_led *led, char *label) { if (strcmp(__metal_driver_sifive_gpio_led_label(led), label) == 0) { return 1; } return 0; } -void __metal_driver_led_enable (struct metal_led *led) -{ +void __metal_driver_led_enable(struct metal_led *led) { int pin; struct metal_gpio *gpio; pin = __metal_driver_sifive_gpio_led_pin(led); - gpio = __metal_driver_sifive_gpio_led_gpio(led); + gpio = __metal_driver_sifive_gpio_led_gpio(led); if (gpio != NULL) { /* Configure LED as output */ - metal_gpio_disable_input((struct metal_gpio *) gpio, pin); - metal_gpio_enable_output((struct metal_gpio *) gpio, pin); + metal_gpio_disable_input((struct metal_gpio *)gpio, pin); + metal_gpio_enable_output((struct metal_gpio *)gpio, pin); } } -void __metal_driver_led_on (struct metal_led *led) -{ +void __metal_driver_led_on(struct metal_led *led) { int pin; struct metal_gpio *gpio; pin = __metal_driver_sifive_gpio_led_pin(led); - gpio = __metal_driver_sifive_gpio_led_gpio(led); + gpio = __metal_driver_sifive_gpio_led_gpio(led); if (gpio != NULL) { - metal_gpio_set_pin((struct metal_gpio *) gpio, pin, 1); + metal_gpio_set_pin((struct metal_gpio *)gpio, pin, 1); } } -void __metal_driver_led_off (struct metal_led *led) -{ +void __metal_driver_led_off(struct metal_led *led) { int pin; struct metal_gpio *gpio; pin = __metal_driver_sifive_gpio_led_pin(led); - gpio = __metal_driver_sifive_gpio_led_gpio(led); + gpio = __metal_driver_sifive_gpio_led_gpio(led); if (gpio != NULL) { - metal_gpio_set_pin((struct metal_gpio *) gpio, pin, 0); + metal_gpio_set_pin((struct metal_gpio *)gpio, pin, 0); } } -void __metal_driver_led_toggle (struct metal_led *led) -{ +void __metal_driver_led_toggle(struct metal_led *led) { int pin; struct metal_gpio *gpio; pin = __metal_driver_sifive_gpio_led_pin(led); - gpio = __metal_driver_sifive_gpio_led_gpio(led); + gpio = __metal_driver_sifive_gpio_led_gpio(led); if (gpio != NULL) { - metal_gpio_toggle_pin((struct metal_gpio *) gpio, pin); + metal_gpio_toggle_pin((struct metal_gpio *)gpio, pin); } } __METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_led) = { - .led_vtable.led_exist = __metal_driver_led_exist, - .led_vtable.led_enable = __metal_driver_led_enable, - .led_vtable.led_on = __metal_driver_led_on, - .led_vtable.led_off = __metal_driver_led_off, - .led_vtable.led_toggle = __metal_driver_led_toggle, + .led_vtable.led_exist = __metal_driver_led_exist, + .led_vtable.led_enable = __metal_driver_led_enable, + .led_vtable.led_on = __metal_driver_led_on, + .led_vtable.led_off = __metal_driver_led_off, + .led_vtable.led_toggle = __metal_driver_led_toggle, }; #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-switches.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-switches.c index fa0a819f1..dc0adb792 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-switches.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio-switches.c @@ -5,13 +5,12 @@ #ifdef METAL_SIFIVE_GPIO_SWITCHES -#include <string.h> #include <metal/drivers/riscv_cpu.h> #include <metal/drivers/sifive_gpio-switches.h> #include <metal/machine.h> +#include <string.h> -int __metal_driver_switch_exist (struct metal_switch *flip, char *label) -{ +int __metal_driver_switch_exist(struct metal_switch *flip, char *label) { if (strcmp(__metal_driver_sifive_gpio_switch_label(flip), label) == 0) { return 1; } @@ -19,35 +18,32 @@ int __metal_driver_switch_exist (struct metal_switch *flip, char *label) } struct metal_interrupt * -__metal_driver_switch_interrupt_controller(struct metal_switch *flip) -{ +__metal_driver_switch_interrupt_controller(struct metal_switch *flip) { return __metal_driver_sifive_gpio_switch_interrupt_controller(flip); } -int __metal_driver_switch_get_interrupt_id(struct metal_switch *flip) -{ +int __metal_driver_switch_get_interrupt_id(struct metal_switch *flip) { int irq, max_irq; struct metal_interrupt *irc; irq = __metal_driver_sifive_gpio_switch_interrupt_line(flip); - irc = __metal_driver_sifive_gpio_switch_interrupt_controller(flip); + irc = __metal_driver_sifive_gpio_switch_interrupt_controller(flip); if (irc != NULL) { - max_irq = _metal_interrupt_command_request(irc, - METAL_MAX_INTERRUPT_GET, + max_irq = _metal_interrupt_command_request(irc, METAL_MAX_INTERRUPT_GET, NULL); if (irq < max_irq) { - return _metal_interrupt_command_request(irc, - METAL_INDEX_INTERRUPT_GET, - (void *)&irq); + return _metal_interrupt_command_request( + irc, METAL_INDEX_INTERRUPT_GET, (void *)&irq); } } return METAL_INTERRUPT_ID_LCMX; } __METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_switch) = { - .switch_vtable.switch_exist = __metal_driver_switch_exist, - .switch_vtable.interrupt_controller = __metal_driver_switch_interrupt_controller, + .switch_vtable.switch_exist = __metal_driver_switch_exist, + .switch_vtable.interrupt_controller = + __metal_driver_switch_interrupt_controller, .switch_vtable.get_interrupt_id = __metal_driver_switch_get_interrupt_id, }; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio0.c index 9ebbea03c..1324eb6e1 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio0.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_gpio0.c @@ -9,209 +9,243 @@ #include <metal/io.h> #include <metal/machine.h> -int __metal_driver_sifive_gpio0_enable_input(struct metal_gpio *ggpio, long source) -{ +int __metal_driver_sifive_gpio0_enable_input(struct metal_gpio *ggpio, + long source) { long base = __metal_driver_sifive_gpio0_base(ggpio); - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_INPUT_EN)) |= source; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_INPUT_EN)) |= source; return 0; } -int __metal_driver_sifive_gpio0_disable_input(struct metal_gpio *ggpio, long source) -{ +int __metal_driver_sifive_gpio0_disable_input(struct metal_gpio *ggpio, + long source) { long base = __metal_driver_sifive_gpio0_base(ggpio); - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_INPUT_EN)) &= ~source; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_INPUT_EN)) &= ~source; return 0; } -long __metal_driver_sifive_gpio0_input(struct metal_gpio *ggpio) -{ +long __metal_driver_sifive_gpio0_input(struct metal_gpio *ggpio) { long base = __metal_driver_sifive_gpio0_base(ggpio); - return __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_VALUE)); + return __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_VALUE)); } -long __metal_driver_sifive_gpio0_output(struct metal_gpio *ggpio) -{ +long __metal_driver_sifive_gpio0_output(struct metal_gpio *ggpio) { long base = __metal_driver_sifive_gpio0_base(ggpio); - return __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)); + return __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)); } - -int __metal_driver_sifive_gpio0_disable_output(struct metal_gpio *ggpio, long source) -{ +int __metal_driver_sifive_gpio0_disable_output(struct metal_gpio *ggpio, + long source) { long base = __metal_driver_sifive_gpio0_base(ggpio); - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_OUTPUT_EN)) &= ~source; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_OUTPUT_EN)) &= ~source; return 0; } -int __metal_driver_sifive_gpio0_enable_output(struct metal_gpio *ggpio, long source) -{ +int __metal_driver_sifive_gpio0_enable_output(struct metal_gpio *ggpio, + long source) { long base = __metal_driver_sifive_gpio0_base(ggpio); - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_OUTPUT_EN)) |= source; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_OUTPUT_EN)) |= source; return 0; } -int __metal_driver_sifive_gpio0_output_set(struct metal_gpio *ggpio, long value) -{ +int __metal_driver_sifive_gpio0_output_set(struct metal_gpio *ggpio, + long value) { long base = __metal_driver_sifive_gpio0_base(ggpio); - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) |= value; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) |= + value; return 0; } -int __metal_driver_sifive_gpio0_output_clear(struct metal_gpio *ggpio, long value) -{ +int __metal_driver_sifive_gpio0_output_clear(struct metal_gpio *ggpio, + long value) { long base = __metal_driver_sifive_gpio0_base(ggpio); - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) &= ~value; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) &= + ~value; return 0; } -int __metal_driver_sifive_gpio0_output_toggle(struct metal_gpio *ggpio, long value) -{ +int __metal_driver_sifive_gpio0_output_toggle(struct metal_gpio *ggpio, + long value) { long base = __metal_driver_sifive_gpio0_base(ggpio); __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) = - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) ^ value; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_PORT)) ^ + value; return 0; } -int __metal_driver_sifive_gpio0_enable_io(struct metal_gpio *ggpio, long source, long dest) -{ +int __metal_driver_sifive_gpio0_enable_io(struct metal_gpio *ggpio, long source, + long dest) { long base = __metal_driver_sifive_gpio0_base(ggpio); - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_IOF_SEL)) &= ~source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_IOF_EN)) |= dest; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_IOF_SEL)) |= source; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_IOF_EN)) |= + dest; return 0; } -int __metal_driver_sifive_gpio0_disable_io(struct metal_gpio *ggpio, long source) -{ +int __metal_driver_sifive_gpio0_disable_io(struct metal_gpio *ggpio, + long source) { long base = __metal_driver_sifive_gpio0_base(ggpio); - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_IOF_EN)) &= ~source; + __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_IOF_EN)) &= + ~source; return 0; } -int __metal_driver_sifive_gpio0_config_int(struct metal_gpio *ggpio, long source, int intr_type) -{ +int __metal_driver_sifive_gpio0_config_int(struct metal_gpio *ggpio, + long source, int intr_type) { long base = __metal_driver_sifive_gpio0_base(ggpio); - switch (intr_type) - { - case METAL_GPIO_INT_DISABLE: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE)) &= ~source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE)) &= ~source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE)) &= ~source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE)) &= ~source; - break; - case METAL_GPIO_INT_RISING: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE)) |= source; - break; - case METAL_GPIO_INT_FALLING: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE)) |= source; - break; - case METAL_GPIO_INT_BOTH_EDGE: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE)) |= source; - break; - case METAL_GPIO_INT_HIGH: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE)) |= source; - break; - case METAL_GPIO_INT_LOW: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE)) |= source; - break; - case METAL_GPIO_INT_BOTH_LEVEL: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE)) |= source; - break; - case METAL_GPIO_INT_MAX: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE)) |= source; - break; + switch (intr_type) { + case METAL_GPIO_INT_DISABLE: + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE)) &= ~source; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE)) &= ~source; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE)) &= ~source; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE)) &= ~source; + break; + case METAL_GPIO_INT_RISING: + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE)) |= source; + break; + case METAL_GPIO_INT_FALLING: + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE)) |= source; + break; + case METAL_GPIO_INT_BOTH_EDGE: + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE)) |= source; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE)) |= source; + break; + case METAL_GPIO_INT_HIGH: + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE)) |= source; + break; + case METAL_GPIO_INT_LOW: + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE)) |= source; + break; + case METAL_GPIO_INT_BOTH_LEVEL: + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE)) |= source; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE)) |= source; + break; + case METAL_GPIO_INT_MAX: + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IE)) |= source; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IE)) |= source; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IE)) |= source; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IE)) |= source; + break; } return 0; } -int __metal_driver_sifive_gpio0_clear_int(struct metal_gpio *ggpio, long source, int intr_type) -{ +int __metal_driver_sifive_gpio0_clear_int(struct metal_gpio *ggpio, long source, + int intr_type) { long base = __metal_driver_sifive_gpio0_base(ggpio); - switch (intr_type) - { - case METAL_GPIO_INT_RISING: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IP)) |= source; - break; - case METAL_GPIO_INT_FALLING: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IP)) |= source; - break; - case METAL_GPIO_INT_BOTH_EDGE: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IP)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IP)) |= source; - break; - case METAL_GPIO_INT_HIGH: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IP)) |= source; - break; - case METAL_GPIO_INT_LOW: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IP)) |= source; - break; - case METAL_GPIO_INT_BOTH_LEVEL: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IP)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IP)) |= source; - break; - case METAL_GPIO_INT_MAX: - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IP)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IP)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IP)) |= source; - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IP)) |= source; - break; + switch (intr_type) { + case METAL_GPIO_INT_RISING: + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IP)) |= source; + break; + case METAL_GPIO_INT_FALLING: + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IP)) |= source; + break; + case METAL_GPIO_INT_BOTH_EDGE: + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IP)) |= source; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IP)) |= source; + break; + case METAL_GPIO_INT_HIGH: + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IP)) |= source; + break; + case METAL_GPIO_INT_LOW: + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IP)) |= source; + break; + case METAL_GPIO_INT_BOTH_LEVEL: + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IP)) |= source; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IP)) |= source; + break; + case METAL_GPIO_INT_MAX: + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_RISE_IP)) |= source; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_FALL_IP)) |= source; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_HIGH_IP)) |= source; + __METAL_ACCESS_ONCE( + (__metal_io_u32 *)(base + METAL_SIFIVE_GPIO0_LOW_IP)) |= source; + break; } return 0; } struct metal_interrupt * -__metal_driver_gpio_interrupt_controller(struct metal_gpio *gpio) -{ +__metal_driver_gpio_interrupt_controller(struct metal_gpio *gpio) { return __metal_driver_sifive_gpio0_interrupt_parent(gpio); } -int __metal_driver_gpio_get_interrupt_id(struct metal_gpio *gpio, int pin) -{ +int __metal_driver_gpio_get_interrupt_id(struct metal_gpio *gpio, int pin) { int irq; irq = __metal_driver_sifive_gpio0_interrupt_lines(gpio, pin); return irq; } __METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_gpio0) = { - .gpio.disable_input = __metal_driver_sifive_gpio0_disable_input, - .gpio.enable_input = __metal_driver_sifive_gpio0_enable_input, - .gpio.input = __metal_driver_sifive_gpio0_input, - .gpio.output = __metal_driver_sifive_gpio0_output, + .gpio.disable_input = __metal_driver_sifive_gpio0_disable_input, + .gpio.enable_input = __metal_driver_sifive_gpio0_enable_input, + .gpio.input = __metal_driver_sifive_gpio0_input, + .gpio.output = __metal_driver_sifive_gpio0_output, .gpio.disable_output = __metal_driver_sifive_gpio0_disable_output, - .gpio.enable_output = __metal_driver_sifive_gpio0_enable_output, - .gpio.output_set = __metal_driver_sifive_gpio0_output_set, - .gpio.output_clear = __metal_driver_sifive_gpio0_output_clear, - .gpio.output_toggle = __metal_driver_sifive_gpio0_output_toggle, - .gpio.enable_io = __metal_driver_sifive_gpio0_enable_io, - .gpio.disable_io = __metal_driver_sifive_gpio0_disable_io, - .gpio.config_int = __metal_driver_sifive_gpio0_config_int, - .gpio.clear_int = __metal_driver_sifive_gpio0_clear_int, + .gpio.enable_output = __metal_driver_sifive_gpio0_enable_output, + .gpio.output_set = __metal_driver_sifive_gpio0_output_set, + .gpio.output_clear = __metal_driver_sifive_gpio0_output_clear, + .gpio.output_toggle = __metal_driver_sifive_gpio0_output_toggle, + .gpio.enable_io = __metal_driver_sifive_gpio0_enable_io, + .gpio.disable_io = __metal_driver_sifive_gpio0_disable_io, + .gpio.config_int = __metal_driver_sifive_gpio0_config_int, + .gpio.clear_int = __metal_driver_sifive_gpio0_clear_int, .gpio.interrupt_controller = __metal_driver_gpio_interrupt_controller, .gpio.get_interrupt_id = __metal_driver_gpio_get_interrupt_id, }; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_i2c0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_i2c0.c new file mode 100644 index 000000000..ec79bbc37 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_i2c0.c @@ -0,0 +1,428 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include <metal/machine/platform.h> + +#ifdef METAL_SIFIVE_I2C0 +#include <metal/clock.h> +#include <metal/compiler.h> +#include <metal/drivers/sifive_gpio0.h> +#include <metal/drivers/sifive_i2c0.h> +#include <metal/io.h> +#include <metal/machine.h> +#include <metal/time.h> +#include <stdio.h> + +/* Register fields */ +#define METAL_I2C_CONTROL_EN (1UL << 7) +#define METAL_I2C_CONTROL_IE (1UL << 6) +#define METAL_I2C_WRITE (0UL << 0) +#define METAL_I2C_READ (1UL << 0) +#define METAL_I2C_CMD_START (1UL << 7) +#define METAL_I2C_CMD_STOP (1UL << 6) +#define METAL_I2C_CMD_READ (1UL << 5) +#define METAL_I2C_CMD_WRITE (1UL << 4) +#define METAL_I2C_CMD_ACK (1UL << 3) +#define METAL_I2C_CMD_IACK (1UL << 0) +#define METAL_I2C_STATUS_RXACK (1UL << 7) +#define METAL_I2C_STATUS_BUSY (1UL << 6) +#define METAL_I2C_STATUS_AL (1UL << 5) +#define METAL_I2C_STATUS_TIP (1UL << 1) +#define METAL_I2C_STATUS_IP (1UL << 0) + +/* Prescaler max value */ +#define METAL_I2C_PRESCALE_MAX 0xFFFF +/* Macros to access registers */ +#define METAL_I2C_REG(offset) ((base + offset)) +#define METAL_I2C_REGB(offset) \ + (__METAL_ACCESS_ONCE((__metal_io_u8 *)METAL_I2C_REG(offset))) +#define METAL_I2C_REGW(offset) \ + (__METAL_ACCESS_ONCE((__metal_io_u32 *)METAL_I2C_REG(offset))) + +/* Timeout macros for register status checks */ +#define METAL_I2C_RXDATA_TIMEOUT 1 +#define METAL_I2C_TIMEOUT_RESET(timeout) \ + timeout = metal_time() + METAL_I2C_RXDATA_TIMEOUT +#define METAL_I2C_TIMEOUT_CHECK(timeout) \ + if (metal_time() > timeout) { \ + METAL_I2C_LOG("I2C timeout error.\n"); \ + return METAL_I2C_RET_ERR; \ + } +#define METAL_I2C_REG_CHECK(exp, timeout) \ + while (exp) { \ + METAL_I2C_TIMEOUT_CHECK(timeout) \ + } + +/* Driver console logging */ +#if defined(METAL_I2C_DEBUG) +#define METAL_I2C_LOG(x) printf(x) +#else +#define METAL_I2C_LOG(x) +#endif + +/* Check endianess */ +#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ +#error *** Unsupported endianess *** +#endif + +#define METAL_SIFIVE_I2C_INSERT_STOP(stop_flag) ((stop_flag & 0x01UL) << 6) +#define METAL_SIFIVE_I2C_INSERT_RW_BIT(addr, rw) \ + ((addr & 0x7FUL) << 1 | (rw & 0x01UL)) +#define METAL_SIFIVE_I2C_GET_PRESCALER(baud) \ + ((clock_rate / (baud_rate * 5)) - 1) +#define METAL_I2C_INIT_OK 1 +#define METAL_I2C_RET_OK 0 +#define METAL_I2C_RET_ERR -1 + +static void pre_rate_change_callback(void *priv) { + unsigned long base = + __metal_driver_sifive_i2c0_control_base((struct metal_i2c *)priv); + /* Check for any pending transfers */ + while (METAL_I2C_REGB(METAL_SIFIVE_I2C0_STATUS) & METAL_I2C_STATUS_TIP) + ; +} + +static void post_rate_change_callback(void *priv) { + struct __metal_driver_sifive_i2c0 *i2c = priv; + /* Set baud rate after clock rate change */ + metal_i2c_set_baud_rate(&i2c->i2c, i2c->baud_rate); +} + +static void __metal_driver_sifive_i2c0_init(struct metal_i2c *gi2c, + unsigned int baud_rate, + metal_i2c_mode_t mode) { + struct __metal_driver_sifive_gpio0 *pinmux = + __metal_driver_sifive_i2c0_pinmux(gi2c); + struct __metal_driver_sifive_i2c0 *i2c = (void *)gi2c; + + if ((pinmux != NULL) && (gi2c != NULL)) { + /* configure I2C I/O pins */ + long pinmux_output_selector = + __metal_driver_sifive_i2c0_pinmux_output_selector(gi2c); + long pinmux_source_selector = + __metal_driver_sifive_i2c0_pinmux_source_selector(gi2c); + pinmux->gpio.vtable->enable_io((struct metal_gpio *)pinmux, + pinmux_output_selector, + pinmux_source_selector); + + /* 1: Master 0: Slave */ + if (mode == METAL_I2C_MASTER) { + /* Set requested baud rate */ + if (metal_i2c_set_baud_rate(gi2c, baud_rate) == METAL_I2C_RET_OK) { + i2c->init_done = METAL_I2C_INIT_OK; + } + } else { + /* Nothing to do. slave mode not supported */ + } + } +} + +static int __metal_driver_sifive_i2c0_get_baud_rate(struct metal_i2c *gi2c) { + struct __metal_driver_sifive_i2c0 *i2c = (void *)gi2c; + return i2c->baud_rate; +} + +static int __metal_driver_sifive_i2c0_set_baud_rate(struct metal_i2c *gi2c, + unsigned int baud_rate) { + struct metal_clock *clock = __metal_driver_sifive_i2c0_clock(gi2c); + struct __metal_driver_sifive_i2c0 *i2c = (void *)gi2c; + unsigned long base = __metal_driver_sifive_i2c0_control_base(gi2c); + int ret = METAL_I2C_RET_ERR; + + if ((clock != NULL) && (gi2c != NULL)) { + long clock_rate = clock->vtable->get_rate_hz(clock); + + i2c->pre_rate_change_callback.callback = &pre_rate_change_callback; + i2c->pre_rate_change_callback.priv = i2c; + metal_clock_register_pre_rate_change_callback( + clock, &(i2c->pre_rate_change_callback)); + + i2c->post_rate_change_callback.callback = &post_rate_change_callback; + i2c->post_rate_change_callback.priv = i2c; + metal_clock_register_post_rate_change_callback( + clock, &(i2c->post_rate_change_callback)); + + /* Calculate prescaler value */ + long prescaler = METAL_SIFIVE_I2C_GET_PRESCALER(baud_rate); + + if ((prescaler > METAL_I2C_PRESCALE_MAX) || (prescaler < 0)) { + /* Out of range value, return error */ + METAL_I2C_LOG("I2C Set baud failed.\n"); + } else { + /* Set pre-scaler value */ + METAL_I2C_REGB(METAL_SIFIVE_I2C0_CONTROL) &= ~METAL_I2C_CONTROL_EN; + METAL_I2C_REGB(METAL_SIFIVE_I2C0_PRESCALE_LOW) = prescaler & 0xFF; + METAL_I2C_REGB(METAL_SIFIVE_I2C0_PRESCALE_HIGH) = + (prescaler >> 8) & 0xFF; + METAL_I2C_REGB(METAL_SIFIVE_I2C0_CONTROL) |= METAL_I2C_CONTROL_EN; + + i2c->baud_rate = baud_rate; + ret = METAL_I2C_RET_OK; + } + } else { + METAL_I2C_LOG("I2C Set baud failed.\n"); + } + + return ret; +} + +static int __metal_driver_sifive_i2c0_write_addr(unsigned long base, + unsigned int addr, + unsigned char rw_flag) { + time_t timeout; + int ret = METAL_I2C_RET_OK; + /* Reset timeout */ + METAL_I2C_TIMEOUT_RESET(timeout); + + /* Check if any transfer is in progress */ + METAL_I2C_REG_CHECK( + (METAL_I2C_REGB(METAL_SIFIVE_I2C0_STATUS) & METAL_I2C_STATUS_TIP), + timeout); + + /* Set transmit register to given address with read/write flag */ + METAL_I2C_REGB(METAL_SIFIVE_I2C0_TRANSMIT) = + METAL_SIFIVE_I2C_INSERT_RW_BIT(addr, rw_flag); + + /* Set start flag to trigger the address transfer */ + METAL_I2C_REGB(METAL_SIFIVE_I2C0_COMMAND) = + METAL_I2C_CMD_WRITE | METAL_I2C_CMD_START; + /* Reset timeout */ + METAL_I2C_TIMEOUT_RESET(timeout); + + /* Check for transmit completion */ + METAL_I2C_REG_CHECK( + (METAL_I2C_REGB(METAL_SIFIVE_I2C0_STATUS) & METAL_I2C_STATUS_TIP), + timeout); + + /* Check for ACK from slave */ + if ((METAL_I2C_REGB(METAL_SIFIVE_I2C0_STATUS) & METAL_I2C_STATUS_RXACK)) { + /* No ACK, return error */ + METAL_I2C_LOG("I2C RX ACK failed.\n"); + ret = METAL_I2C_RET_ERR; + } + + return ret; +} + +static int __metal_driver_sifive_i2c0_write(struct metal_i2c *i2c, + unsigned int addr, unsigned int len, + unsigned char buf[], + metal_i2c_stop_bit_t stop_bit) { + __metal_io_u8 command; + time_t timeout; + int ret; + unsigned long base = __metal_driver_sifive_i2c0_control_base(i2c); + unsigned int i; + + if ((i2c != NULL) && + ((struct __metal_driver_sifive_i2c0 *)i2c)->init_done) { + + /* Send address over I2C bus, current driver supports only 7bit + * addressing */ + ret = + __metal_driver_sifive_i2c0_write_addr(base, addr, METAL_I2C_WRITE); + + if (ret != METAL_I2C_RET_OK) { + /* Write address failed */ + METAL_I2C_LOG("I2C Address Write failed.\n"); + } else { + /* Set command flags */ + command = METAL_I2C_CMD_WRITE; + + for (i = 0; i < len; i++) { + /* Copy into transmit register */ + METAL_I2C_REGB(METAL_SIFIVE_I2C0_TRANSMIT) = buf[i]; + + /* for last byte transfer, check if stop condition is requested + */ + if (i == (len - 1)) { + command |= METAL_SIFIVE_I2C_INSERT_STOP(stop_bit); + } + /* Write command register */ + METAL_I2C_REGB(METAL_SIFIVE_I2C0_COMMAND) = command; + /* Reset timeout */ + METAL_I2C_TIMEOUT_RESET(timeout); + + /* Check for transfer completion */ + METAL_I2C_REG_CHECK((METAL_I2C_REGB(METAL_SIFIVE_I2C0_STATUS) & + METAL_I2C_STATUS_TIP), + timeout); + + /* Check for ACK from slave */ + if ((METAL_I2C_REGB(METAL_SIFIVE_I2C0_STATUS) & + METAL_I2C_STATUS_RXACK)) { + /* No ACK, return error */ + METAL_I2C_LOG("I2C RX ACK failed.\n"); + ret = METAL_I2C_RET_ERR; + break; + } + } + } + + } else { + /* I2C device not initialized, return error */ + METAL_I2C_LOG("I2C device not initialized.\n"); + ret = METAL_I2C_RET_ERR; + } + + return ret; +} +static int __metal_driver_sifive_i2c0_read(struct metal_i2c *i2c, + unsigned int addr, unsigned int len, + unsigned char buf[], + metal_i2c_stop_bit_t stop_bit) { + int ret; + __metal_io_u8 command; + time_t timeout; + unsigned int i; + unsigned long base = __metal_driver_sifive_i2c0_control_base(i2c); + + if ((i2c != NULL) && + ((struct __metal_driver_sifive_i2c0 *)i2c)->init_done) { + + /* Send address over I2C bus, current driver supports only 7bit + * addressing */ + ret = __metal_driver_sifive_i2c0_write_addr(base, addr, METAL_I2C_READ); + + if (ret != METAL_I2C_RET_OK) { + /* Write address failed */ + METAL_I2C_LOG("I2C Read failed.\n"); + } else { + /* Set command flags */ + command = METAL_I2C_CMD_READ; + + for (i = 0; i < len; i++) { + /* check for last transfer */ + if (i == (len - 1)) { + /* Set NACK to end read, if requested generate STOP + * condition */ + command |= (METAL_I2C_CMD_ACK | + METAL_SIFIVE_I2C_INSERT_STOP(stop_bit)); + } + /* Write command register */ + METAL_I2C_REGB(METAL_SIFIVE_I2C0_COMMAND) = command; + /* Reset timeout */ + METAL_I2C_TIMEOUT_RESET(timeout); + + /* Wait for the read to complete */ + METAL_I2C_REG_CHECK((METAL_I2C_REGB(METAL_SIFIVE_I2C0_STATUS) & + METAL_I2C_STATUS_TIP), + timeout); + /* Store the received byte */ + buf[i] = METAL_I2C_REGB(METAL_SIFIVE_I2C0_TRANSMIT); + } + } + } else { + /* I2C device not initialized, return error */ + METAL_I2C_LOG("I2C device not initialized.\n"); + ret = METAL_I2C_RET_ERR; + } + + return ret; +} + +static int +__metal_driver_sifive_i2c0_transfer(struct metal_i2c *i2c, unsigned int addr, + unsigned char txbuf[], unsigned int txlen, + unsigned char rxbuf[], unsigned int rxlen) { + __metal_io_u8 command; + time_t timeout; + int ret; + unsigned int i; + unsigned long base = __metal_driver_sifive_i2c0_control_base(i2c); + + if ((i2c != NULL) && + ((struct __metal_driver_sifive_i2c0 *)i2c)->init_done) { + if (txlen) { + /* Set command flags */ + command = METAL_I2C_CMD_WRITE; + /* Send address over I2C bus, current driver supports only 7bit + * addressing */ + ret = __metal_driver_sifive_i2c0_write_addr(base, addr, + METAL_I2C_WRITE); + + if (ret != METAL_I2C_RET_OK) { + /* Write address failed */ + METAL_I2C_LOG("I2C Write failed.\n"); + return ret; + } + for (i = 0; i < txlen; i++) { + /* Copy into transmit register */ + METAL_I2C_REGB(METAL_SIFIVE_I2C0_TRANSMIT) = txbuf[i]; + + if (i == (txlen - 1) && (rxlen == 0)) { + /* Insert stop condition to end transfer */ + command |= METAL_I2C_CMD_STOP; + } + /* Write command register */ + METAL_I2C_REGB(METAL_SIFIVE_I2C0_COMMAND) = command; + /* Reset timeout */ + METAL_I2C_TIMEOUT_RESET(timeout); + + /* Check for transfer completion. */ + METAL_I2C_REG_CHECK((METAL_I2C_REGB(METAL_SIFIVE_I2C0_STATUS) & + METAL_I2C_STATUS_TIP), + timeout); + + /* Check for ACK from slave. */ + if ((METAL_I2C_REGB(METAL_SIFIVE_I2C0_STATUS) & + METAL_I2C_STATUS_RXACK)) { + /* No ACK, return error */ + METAL_I2C_LOG("I2C RX ACK failed.\n"); + ret = METAL_I2C_RET_ERR; + break; + } + } + } + if (rxlen) { + command = METAL_I2C_CMD_READ; /* Set command flags */ + /* Send address over I2C bus, current driver supports only 7bit + * addressing */ + ret = __metal_driver_sifive_i2c0_write_addr(base, addr, + METAL_I2C_READ); + + if (ret != METAL_I2C_RET_OK) { + /* Return error */ + METAL_I2C_LOG("I2C Read failed.\n"); + return ret; + } + for (i = 0; i < rxlen; i++) { + /* check for last transfer */ + if (i == (rxlen - 1)) { + /* Set NACK to end read, generate STOP condition */ + command |= (METAL_I2C_CMD_ACK | METAL_I2C_CMD_STOP); + } + /* Write command register */ + METAL_I2C_REGB(METAL_SIFIVE_I2C0_COMMAND) = command; + /* Reset timeout */ + METAL_I2C_TIMEOUT_RESET(timeout); + + /* Wait for the read to complete */ + METAL_I2C_REG_CHECK((METAL_I2C_REGB(METAL_SIFIVE_I2C0_STATUS) & + METAL_I2C_STATUS_TIP), + timeout); + /* Store the received byte */ + rxbuf[i] = METAL_I2C_REGB(METAL_SIFIVE_I2C0_TRANSMIT); + } + } + } else { + /* I2C device not initialized, return error */ + METAL_I2C_LOG("I2C device not initialized.\n"); + ret = METAL_I2C_RET_ERR; + } + + return ret; +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_i2c0) = { + .i2c.init = __metal_driver_sifive_i2c0_init, + .i2c.write = __metal_driver_sifive_i2c0_write, + .i2c.read = __metal_driver_sifive_i2c0_read, + .i2c.transfer = __metal_driver_sifive_i2c0_transfer, + .i2c.get_baud_rate = __metal_driver_sifive_i2c0_get_baud_rate, + .i2c.set_baud_rate = __metal_driver_sifive_i2c0_set_baud_rate, +}; + +#endif /* METAL_SIFIVE_I2C0 */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_l2pf0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_l2pf0.c new file mode 100644 index 000000000..63690fa38 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_l2pf0.c @@ -0,0 +1,164 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include <metal/machine/platform.h> + +#ifdef METAL_SIFIVE_L2PF0 + +#include <metal/drivers/sifive_l2pf0.h> +#include <metal/machine.h> + +/* Macros to access memory mapped registers */ +#define REGW(x) \ + *(volatile uint32_t *)(METAL_SIFIVE_L2PF0_0_BASE_ADDRESS + \ + hartid * 0x2000 + x) + +/* Macros for register bit masks */ +#define REG_MASK_BITWIDTH1 0x01 +#define REG_MASK_BITWIDTH4 0x0F +#define REG_MASK_BITWIDTH5 0x1F +#define REG_MASK_BITWIDTH6 0x3F +#define REG_MASK_BITWIDTH7 0x7F + +/* Macros to specify register bit shift */ +#define REG_BITSHIFT_1 1 +#define REG_BITSHIFT_2 2 +#define REG_BITSHIFT_4 4 +#define REG_BITSHIFT_8 8 +#define REG_BITSHIFT_9 9 +#define REG_BITSHIFT_13 13 +#define REG_BITSHIFT_14 14 +#define REG_BITSHIFT_20 20 +#define REG_BITSHIFT_21 21 +#define REG_BITSHIFT_28 28 + +/* Macros to capture trap, if L2PF does not exist for a hart id. */ +#define SIFIVE_L2PF0_TRAP_CAPTURE(exit, mtvec) \ + __asm__ __volatile__("la %0, 1f \n\t" \ + "csrr %1, mtvec \n\t" \ + "csrw mtvec, %0 \n\t" \ + : "+r"(exit), "+r"(mtvec)) + +#define SIFIVE_L2PF0_TRAP_RESTORE(mtvec) \ + __asm__ __volatile__(".align 2 \n\t" \ + "1: \n\t" \ + "csrw mtvec, %0 \n\t" \ + : "+r"(mtvec)) + +void sifive_l2pf0_enable(void) { + volatile uintptr_t exit = 0, mtvec = 0; + int hartid; + __asm__ volatile("csrr %0, mhartid" : "=r"(hartid)); + + SIFIVE_L2PF0_TRAP_CAPTURE(exit, mtvec); + + uint32_t val = REGW(METAL_SIFIVE_L2PF0_BASIC_CONTROL); + + /* Enable L2 prefetch unit for current hart */ + val |= REG_MASK_BITWIDTH1; + + REGW(METAL_SIFIVE_L2PF0_BASIC_CONTROL) = val; + + SIFIVE_L2PF0_TRAP_RESTORE(mtvec); +} + +void sifive_l2pf0_disable(void) { + volatile uintptr_t exit = 0, mtvec = 0; + int hartid; + __asm__ volatile("csrr %0, mhartid" : "=r"(hartid)); + + SIFIVE_L2PF0_TRAP_CAPTURE(exit, mtvec); + + uint32_t val = REGW(METAL_SIFIVE_L2PF0_BASIC_CONTROL); + + /* Disable L2 prefetch unit for current hart */ + val &= ~REG_MASK_BITWIDTH1; + + REGW(METAL_SIFIVE_L2PF0_BASIC_CONTROL) = val; + + SIFIVE_L2PF0_TRAP_RESTORE(mtvec); +} + +void sifive_l2pf0_get_config(sifive_l2pf0_config *config) { + volatile uintptr_t exit = 0, mtvec = 0; + int hartid; + __asm__ volatile("csrr %0, mhartid" : "=r"(hartid)); + uint32_t val; + + SIFIVE_L2PF0_TRAP_CAPTURE(exit, mtvec); + + if (config) /* Check for NULL */ + { + /* Get currently active L2 prefetch configuration values */ + val = REGW(METAL_SIFIVE_L2PF0_BASIC_CONTROL); + + config->HwPrefetchEnable = (val & REG_MASK_BITWIDTH1); + config->CrossPageOptmDisable = + ((val >> REG_BITSHIFT_1) & REG_MASK_BITWIDTH1); + config->PrefetchDistance = + ((val >> REG_BITSHIFT_2) & REG_MASK_BITWIDTH6); + config->MaxAllowedDistance = + ((val >> REG_BITSHIFT_8) & REG_MASK_BITWIDTH6); + config->LinToExpThreshold = + ((val >> REG_BITSHIFT_14) & REG_MASK_BITWIDTH6); + config->AgeOutEn = ((val >> REG_BITSHIFT_20) & REG_MASK_BITWIDTH1); + config->NumLdsToAgeOut = + ((val >> REG_BITSHIFT_21) & REG_MASK_BITWIDTH7); + config->CrossPageEn = ((val >> REG_BITSHIFT_28) & REG_MASK_BITWIDTH1); + + val = REGW(METAL_SIFIVE_L2PF0_USER_CONTROL); + + config->QFullnessThreshold = (val & REG_MASK_BITWIDTH4); + config->HitCacheThreshold = + ((val >> REG_BITSHIFT_4) & REG_MASK_BITWIDTH5); + config->hitMSHRThreshold = + ((val >> REG_BITSHIFT_9) & REG_MASK_BITWIDTH4); + config->Window = ((val >> REG_BITSHIFT_13) & REG_MASK_BITWIDTH6); + } + SIFIVE_L2PF0_TRAP_RESTORE(mtvec); +} + +void sifive_l2pf0_set_config(sifive_l2pf0_config *config) { + volatile uintptr_t exit = 0, mtvec = 0; + int hartid; + __asm__ volatile("csrr %0, mhartid" : "=r"(hartid)); + uint32_t val; + + SIFIVE_L2PF0_TRAP_CAPTURE(exit, mtvec); + + if (config) /* Check for NULL */ + { + /* Get values from configuration to write into register */ + val = (uint32_t)( + (config->HwPrefetchEnable & REG_MASK_BITWIDTH1) | + ((config->CrossPageOptmDisable & REG_MASK_BITWIDTH1) + << REG_BITSHIFT_1) | + ((config->PrefetchDistance & REG_MASK_BITWIDTH6) + << REG_BITSHIFT_2) | + ((config->MaxAllowedDistance & REG_MASK_BITWIDTH6) + << REG_BITSHIFT_8) | + ((config->LinToExpThreshold & REG_MASK_BITWIDTH6) + << REG_BITSHIFT_14) | + ((config->AgeOutEn & REG_MASK_BITWIDTH1) << REG_BITSHIFT_20) | + ((config->NumLdsToAgeOut & REG_MASK_BITWIDTH7) << REG_BITSHIFT_21) | + ((config->CrossPageEn & REG_MASK_BITWIDTH1) << REG_BITSHIFT_28)); + + /* Set user specified L2 prefetch configuration values */ + REGW(METAL_SIFIVE_L2PF0_BASIC_CONTROL) = val; + + val = (uint32_t)( + (config->QFullnessThreshold & REG_MASK_BITWIDTH4) | + ((config->HitCacheThreshold & REG_MASK_BITWIDTH5) + << REG_BITSHIFT_4) | + ((config->hitMSHRThreshold & REG_MASK_BITWIDTH4) + << REG_BITSHIFT_9) | + ((config->Window & REG_MASK_BITWIDTH6) << REG_BITSHIFT_13)); + + REGW(METAL_SIFIVE_L2PF0_USER_CONTROL) = val; + } + SIFIVE_L2PF0_TRAP_RESTORE(mtvec); +} + +#endif + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_local-external-interrupts0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_local-external-interrupts0.c index 1c34ca447..99b5e3a86 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_local-external-interrupts0.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_local-external-interrupts0.c @@ -5,42 +5,50 @@ #ifdef METAL_SIFIVE_LOCAL_EXTERNAL_INTERRUPTS0 -#include <metal/io.h> #include <metal/drivers/sifive_local-external-interrupts0.h> +#include <metal/io.h> #include <metal/machine.h> -void __metal_driver_sifive_local_external_interrupt_init(struct metal_interrupt *controller) -{ +void __metal_driver_sifive_local_external_interrupt_init( + struct metal_interrupt *controller) { struct __metal_driver_sifive_local_external_interrupts0 *local0; - local0 = (struct __metal_driver_sifive_local_external_interrupts0 *)(controller); - if ( !local0->init_done ) { + local0 = + (struct __metal_driver_sifive_local_external_interrupts0 *)(controller); + if (!local0->init_done) { struct metal_interrupt *intc = - __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller); - - if (intc) { - /* Register its interruptswith with parent controller, aka all external to default isr */ - for (int i = 0; - i < __metal_driver_sifive_local_external_interrupts0_num_interrupts(controller); - i++) { - intc->vtable->interrupt_register(intc, - __metal_driver_sifive_local_external_interrupts0_interrupt_lines(controller, i), - NULL, controller); - } - local0->init_done = 1; - } + __metal_driver_sifive_local_external_interrupts0_interrupt_parent( + controller); + + if (intc) { + /* Register its interruptswith with parent controller, aka all + * external to default isr */ + for ( + int i = 0; + i < + __metal_driver_sifive_local_external_interrupts0_num_interrupts( + controller); + i++) { + intc->vtable->interrupt_register( + intc, + __metal_driver_sifive_local_external_interrupts0_interrupt_lines( + controller, i), + NULL, controller); + } + local0->init_done = 1; + } } } -int __metal_driver_sifive_local_external_interrupt_register(struct metal_interrupt *controller, - int id, metal_interrupt_handler_t isr, - void *priv) -{ +int __metal_driver_sifive_local_external_interrupt_register( + struct metal_interrupt *controller, int id, metal_interrupt_handler_t isr, + void *priv) { int rc = -1; if (id != 0) { struct metal_interrupt *intc = - __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller); + __metal_driver_sifive_local_external_interrupts0_interrupt_parent( + controller); /* Enable its interrupts with parent controller */ if (intc) { @@ -50,13 +58,14 @@ int __metal_driver_sifive_local_external_interrupt_register(struct metal_interru return rc; } -int __metal_driver_sifive_local_external_interrupt_enable(struct metal_interrupt *controller, int id) -{ +int __metal_driver_sifive_local_external_interrupt_enable( + struct metal_interrupt *controller, int id) { int rc = -1; if (id != 0) { struct metal_interrupt *intc = - __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller); + __metal_driver_sifive_local_external_interrupts0_interrupt_parent( + controller); /* Enable its interrupts with parent controller */ if (intc) { @@ -66,13 +75,14 @@ int __metal_driver_sifive_local_external_interrupt_enable(struct metal_interrupt return rc; } -int __metal_driver_sifive_local_external_interrupt_disable(struct metal_interrupt *controller, int id) -{ +int __metal_driver_sifive_local_external_interrupt_disable( + struct metal_interrupt *controller, int id) { int rc = -1; if (id != 0) { struct metal_interrupt *intc = - __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller); + __metal_driver_sifive_local_external_interrupts0_interrupt_parent( + controller); /* Enable its interrupts with parent controller */ if (intc) { @@ -82,48 +92,47 @@ int __metal_driver_sifive_local_external_interrupt_disable(struct metal_interrup return rc; } -int __metal_driver_sifive_local_external_interrupt_set_threshold(struct metal_interrupt *controller, - unsigned int threshold) -{ +int __metal_driver_sifive_local_external_interrupt_set_threshold( + struct metal_interrupt *controller, unsigned int threshold) { /* Core controller does not support threshold configuration */ return -1; } -unsigned int __metal_driver_sifive_local_external_interrupt_get_threshold(struct metal_interrupt *controller) -{ +unsigned int __metal_driver_sifive_local_external_interrupt_get_threshold( + struct metal_interrupt *controller) { /* Core controller does not support threshold configuration */ return 0; } - -int __metal_driver_sifive_local_external_interrupt_set_priority(struct metal_interrupt *controller, - int id, unsigned int priority) -{ +int __metal_driver_sifive_local_external_interrupt_set_priority( + struct metal_interrupt *controller, int id, unsigned int priority) { /* Core controller does not support priority configuration */ return -1; } -unsigned int __metal_driver_sifive_local_external_interrupt_get_priority(struct metal_interrupt *controller, int id) -{ +unsigned int __metal_driver_sifive_local_external_interrupt_get_priority( + struct metal_interrupt *controller, int id) { /* Core controller does not support priority configuration */ return 0; } -int __metal_driver_sifive_local_external_command_request (struct metal_interrupt *controller, - int command, void *data) -{ +int __metal_driver_sifive_local_external_command_request( + struct metal_interrupt *controller, int command, void *data) { int idx; int rc = -1; switch (command) { case METAL_MAX_INTERRUPT_GET: - rc = __metal_driver_sifive_local_external_interrupts0_num_interrupts(controller); + rc = __metal_driver_sifive_local_external_interrupts0_num_interrupts( + controller); break; case METAL_INDEX_INTERRUPT_GET: rc = 0; if (data) { idx = *(int *)data; - rc = __metal_driver_sifive_local_external_interrupts0_interrupt_lines(controller, idx); + rc = + __metal_driver_sifive_local_external_interrupts0_interrupt_lines( + controller, idx); } break; default: @@ -133,19 +142,28 @@ int __metal_driver_sifive_local_external_command_request (struct metal_interrupt return rc; } -__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_local_external_interrupts0) = { - .local0_vtable.interrupt_init = __metal_driver_sifive_local_external_interrupt_init, - .local0_vtable.interrupt_register = __metal_driver_sifive_local_external_interrupt_register, - .local0_vtable.interrupt_enable = __metal_driver_sifive_local_external_interrupt_enable, - .local0_vtable.interrupt_disable = __metal_driver_sifive_local_external_interrupt_disable, - .local0_vtable.interrupt_get_threshold = __metal_driver_sifive_local_external_interrupt_get_threshold, - .local0_vtable.interrupt_set_threshold = __metal_driver_sifive_local_external_interrupt_set_threshold, - .local0_vtable.interrupt_get_priority = __metal_driver_sifive_local_external_interrupt_get_priority, - .local0_vtable.interrupt_set_priority = __metal_driver_sifive_local_external_interrupt_set_priority, - .local0_vtable.command_request = __metal_driver_sifive_local_external_command_request, +__METAL_DEFINE_VTABLE( + __metal_driver_vtable_sifive_local_external_interrupts0) = { + .local0_vtable.interrupt_init = + __metal_driver_sifive_local_external_interrupt_init, + .local0_vtable.interrupt_register = + __metal_driver_sifive_local_external_interrupt_register, + .local0_vtable.interrupt_enable = + __metal_driver_sifive_local_external_interrupt_enable, + .local0_vtable.interrupt_disable = + __metal_driver_sifive_local_external_interrupt_disable, + .local0_vtable.interrupt_get_threshold = + __metal_driver_sifive_local_external_interrupt_get_threshold, + .local0_vtable.interrupt_set_threshold = + __metal_driver_sifive_local_external_interrupt_set_threshold, + .local0_vtable.interrupt_get_priority = + __metal_driver_sifive_local_external_interrupt_get_priority, + .local0_vtable.interrupt_set_priority = + __metal_driver_sifive_local_external_interrupt_set_priority, + .local0_vtable.command_request = + __metal_driver_sifive_local_external_command_request, }; #endif typedef int no_empty_translation_units; - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_pwm0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_pwm0.c new file mode 100644 index 000000000..415d46825 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_pwm0.c @@ -0,0 +1,340 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include <metal/machine/platform.h> + +#ifdef METAL_SIFIVE_PWM0 +#include <metal/clock.h> +#include <metal/compiler.h> +#include <metal/drivers/sifive_gpio0.h> +#include <metal/drivers/sifive_pwm0.h> +#include <metal/io.h> +#include <metal/machine.h> +#include <metal/time.h> +#include <stdio.h> + +/* Register fields */ +#define METAL_PWMCFG_STICKY (1UL << 8) +#define METAL_PWMCFG_ZEROCMP (1UL << 9) +#define METAL_PWMCFG_DEGLITCH (1UL << 10) +#define METAL_PWMCFG_ENALWAYS (1UL << 12) +#define METAL_PWMCFG_ENONESHOT (1UL << 13) +#define METAL_PWMCFG_CMPCENTER(x) (1UL << (16 + x)) +#define METAL_PWMCFG_CMPIP(x) (1UL << (28 + x)) +#define METAL_SIFIVE_PWM0_PWMCMP(x) (METAL_SIFIVE_PWM0_PWMCMP0 + (x * 4)) + +/* Macros to access registers */ +#define METAL_PWM_REG(offset) ((base + offset)) +#define METAL_PWM_REGW(offset) \ + (__METAL_ACCESS_ONCE((__metal_io_u32 *)METAL_PWM_REG(offset))) + +/* Macro to get PWM compare count */ +#define METAL_PWM_GETCMPVAL(duty) (duty * pwm->count_val) / 100U +/* Max duty cycle value */ +#define METAL_PWM_MAXDUTY 100UL +/* Max pre-scalar value */ +#define METAL_PWM_MAXPRESCAL 15UL + +/* Check endianess */ +#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ +#error *** Unsupported endianess *** +#endif + +#if (METAL_MAX_PWM0_NCMP > METAL_MAX_PWM_CHANNELS) +#error *** METAL_MAX_PWM_CHANNELS exceeded *** +#endif + +/* Return values */ +#define METAL_PWM_RET_OK 0 +#define METAL_PWM_RET_ERR -1 + +static void pre_rate_change_callback(void *priv) { + struct metal_pwm *gpwm = priv; + /* Disable active PWM instance. */ + gpwm->vtable->stop(gpwm, 0); +} + +static void post_rate_change_callback(void *priv) { + struct __metal_driver_sifive_pwm0 *pwm = priv; + struct metal_pwm *gpwm = priv; + unsigned long base = __metal_driver_sifive_pwm0_control_base(gpwm); + unsigned int cmp_count = __metal_driver_sifive_pwm0_comparator_count(gpwm); + unsigned int idx = 0; + unsigned int duty; + + /* Check if PWM frequency was set */ + if (pwm->freq != 0) { + /* Set frequency after clock rate change */ + gpwm->vtable->set_freq(gpwm, 0, pwm->freq); + + /* Set duty cycle after clock rate change */ + while (++idx < cmp_count) { + duty = pwm->duty[idx]; + if (duty != 0) { + METAL_PWM_REGW(METAL_SIFIVE_PWM0_PWMCMP(idx)) = + METAL_PWM_GETCMPVAL(duty); + } + } + } +} + +static int __metal_driver_sifive_pwm0_enable(struct metal_pwm *gpwm) { + struct __metal_driver_sifive_gpio0 *pinmux = + __metal_driver_sifive_pwm0_pinmux(gpwm); + unsigned long base = __metal_driver_sifive_pwm0_control_base(gpwm); + struct __metal_driver_sifive_pwm0 *pwm = (void *)gpwm; + int ret = METAL_PWM_RET_ERR; + + if (base != 0) { + + if ((pinmux != NULL) && (gpwm != NULL)) { + /* Configure PWM I/O pins */ + long pinmux_output_selector = + __metal_driver_sifive_pwm0_pinmux_output_selector(gpwm); + long pinmux_source_selector = + __metal_driver_sifive_pwm0_pinmux_source_selector(gpwm); + + pinmux->gpio.vtable->enable_io((struct metal_gpio *)pinmux, + pinmux_output_selector, + pinmux_source_selector); + } + + /* Initialize default values */ + pwm->max_count = + (1UL << __metal_driver_sifive_pwm0_compare_width(gpwm)) - 1; + pwm->freq = 0; + pwm->count_val = 0; + METAL_PWM_REGW(METAL_SIFIVE_PWM0_PWMCFG) = 0; + ret = METAL_PWM_RET_OK; + } + return ret; +} + +static int __metal_driver_sifive_pwm0_disable(struct metal_pwm *gpwm) { + struct __metal_driver_sifive_gpio0 *pinmux = + __metal_driver_sifive_pwm0_pinmux(gpwm); + int ret = METAL_PWM_RET_ERR; + + if (gpwm != NULL) { + + if (pinmux != NULL) { + /* Disable PWM I/O pins */ + long pinmux_source_selector = + __metal_driver_sifive_pwm0_pinmux_source_selector(gpwm); + pinmux->gpio.vtable->disable_io((struct metal_gpio *)pinmux, + pinmux_source_selector); + } + + ret = METAL_PWM_RET_OK; + } + return ret; +} + +static int __metal_driver_sifive_pwm0_set_freq(struct metal_pwm *gpwm, + unsigned int idx, + unsigned int freq) { + struct metal_clock *clock = __metal_driver_sifive_pwm0_clock(gpwm); + unsigned long base = __metal_driver_sifive_pwm0_control_base(gpwm); + unsigned int cmp_count = __metal_driver_sifive_pwm0_comparator_count(gpwm); + struct __metal_driver_sifive_pwm0 *pwm = (void *)gpwm; + unsigned int clock_rate; + unsigned int count; + unsigned int prescale = 0; + int ret = METAL_PWM_RET_ERR; + + if ((clock != NULL) && (gpwm != NULL) && (idx < cmp_count)) { + clock_rate = clock->vtable->get_rate_hz(clock); + /* Register clock rate change call-backs */ + if (pwm->freq == 0) { + pwm->pre_rate_change_callback.callback = &pre_rate_change_callback; + pwm->pre_rate_change_callback.priv = pwm; + metal_clock_register_pre_rate_change_callback( + clock, &(pwm->pre_rate_change_callback)); + + pwm->post_rate_change_callback.callback = + &post_rate_change_callback; + pwm->post_rate_change_callback.priv = pwm; + metal_clock_register_post_rate_change_callback( + clock, &(pwm->post_rate_change_callback)); + } + + /* Calculate count value for given PWM frequency */ + do { + count = (clock_rate / (1UL << prescale)) / freq; + } while ((count > pwm->max_count) && + (prescale++ < METAL_PWM_MAXPRESCAL)); + + pwm->freq = (clock_rate / (1UL << prescale)) / count; + pwm->count_val = --count; + + /* Update values into registers */ + METAL_PWM_REGW(METAL_SIFIVE_PWM0_PWMCMP0) = count; + METAL_PWM_REGW(METAL_SIFIVE_PWM0_PWMCFG) |= (prescale & 0x0FUL); + ret = METAL_PWM_RET_OK; + +#if defined(METAL_PWM_DEBUG) + printf("PWM requested freq:%u set freq:%u \n", freq, pwm->freq); + printf("CPU Clk:%u Prescale:%u Count:%u \n", clock_rate, prescale, + count); +#endif + } + return ret; +} + +static int +__metal_driver_sifive_pwm0_set_duty(struct metal_pwm *gpwm, unsigned int idx, + unsigned int duty, + metal_pwm_phase_correct_t phase_corr) { + struct __metal_driver_sifive_pwm0 *pwm = (void *)gpwm; + unsigned long base = __metal_driver_sifive_pwm0_control_base(gpwm); + unsigned int cmp_count = __metal_driver_sifive_pwm0_comparator_count(gpwm); + int ret = METAL_PWM_RET_ERR; + + /* Check if duty value is within limits, duty cycle cannot be set for + * PWMCMP0 */ + if ((idx > 0) && (idx < cmp_count) && (duty <= METAL_PWM_MAXDUTY)) { + /* Calculate PWM compare count value for given duty cycle */ + METAL_PWM_REGW(METAL_SIFIVE_PWM0_PWMCMP(idx)) = + METAL_PWM_GETCMPVAL(duty); + pwm->duty[idx] = duty; + + /* Enable / Disable phase correct PWM mode */ + if (phase_corr == METAL_PWM_PHASE_CORRECT_ENABLE) { + METAL_PWM_REGW(METAL_SIFIVE_PWM0_PWMCFG) |= + METAL_PWMCFG_CMPCENTER(idx); + } else { + METAL_PWM_REGW(METAL_SIFIVE_PWM0_PWMCFG) &= + ~METAL_PWMCFG_CMPCENTER(idx); + } + ret = METAL_PWM_RET_OK; + } + return ret; +} + +static unsigned int __metal_driver_sifive_pwm0_get_duty(struct metal_pwm *gpwm, + unsigned int idx) { + struct __metal_driver_sifive_pwm0 *pwm = (void *)gpwm; + unsigned int cmp_count = __metal_driver_sifive_pwm0_comparator_count(gpwm); + unsigned int duty = 0; + + /* Check for valid parameters and get configured duty cycle value */ + if ((pwm != NULL) && (idx > 0) && (idx < cmp_count)) { + duty = pwm->duty[idx]; + } + return duty; +} + +static unsigned int __metal_driver_sifive_pwm0_get_freq(struct metal_pwm *gpwm, + unsigned int idx) { + struct __metal_driver_sifive_pwm0 *pwm = (void *)gpwm; + unsigned int freq = 0; + + (void)idx; /* Unused parameter, no support for per channel frequency */ + + /* Check for valid parameters and get configured PWM frequency value */ + if (pwm != NULL) { + freq = pwm->freq; + } + return freq; +} + +static int __metal_driver_sifive_pwm0_trigger(struct metal_pwm *gpwm, + unsigned int idx, + metal_pwm_run_mode_t mode) { + unsigned long base = __metal_driver_sifive_pwm0_control_base(gpwm); + int ret = METAL_PWM_RET_ERR; + + (void)idx; /* Unused parameter,for later use */ + + if (base != 0) { + /* Configure for requested PWM run mode */ + if (mode == METAL_PWM_CONTINUOUS) { + METAL_PWM_REGW(METAL_SIFIVE_PWM0_PWMCFG) |= METAL_PWMCFG_DEGLITCH | + METAL_PWMCFG_ZEROCMP | + METAL_PWMCFG_ENALWAYS; + } else { + METAL_PWM_REGW(METAL_SIFIVE_PWM0_PWMCFG) |= METAL_PWMCFG_DEGLITCH | + METAL_PWMCFG_ZEROCMP | + METAL_PWMCFG_ENONESHOT; + } + ret = METAL_PWM_RET_OK; + } + return ret; +} + +static int __metal_driver_sifive_pwm0_stop(struct metal_pwm *gpwm, + unsigned int idx) { + unsigned long base = __metal_driver_sifive_pwm0_control_base(gpwm); + int ret = METAL_PWM_RET_ERR; + + (void)idx; /* Unused parameter,for later use */ + + if (base != 0) { + /* Disable always running mode */ + METAL_PWM_REGW(METAL_SIFIVE_PWM0_PWMCFG) &= ~METAL_PWMCFG_ENALWAYS; + ret = METAL_PWM_RET_OK; + } + return ret; +} + +static int +__metal_driver_sifive_pwm0_cfg_interrupt(struct metal_pwm *gpwm, + metal_pwm_interrupt_t flag) { + unsigned long base = __metal_driver_sifive_pwm0_control_base(gpwm); + int ret = METAL_PWM_RET_ERR; + + if (base != 0) { + if (flag == METAL_PWM_INTERRUPT_ENABLE) { + /* Enable sticky bit, to make sure interrupts are not forgotten */ + METAL_PWM_REGW(METAL_SIFIVE_PWM0_PWMCFG) |= METAL_PWMCFG_STICKY; + } else { + METAL_PWM_REGW(METAL_SIFIVE_PWM0_PWMCFG) &= ~METAL_PWMCFG_STICKY; + } + ret = METAL_PWM_RET_OK; + } + return ret; +} + +static int __metal_driver_sifive_pwm0_clr_interrupt(struct metal_pwm *gpwm, + unsigned int idx) { + unsigned long base = __metal_driver_sifive_pwm0_control_base(gpwm); + unsigned int cmp_count = __metal_driver_sifive_pwm0_comparator_count(gpwm); + int ret = METAL_PWM_RET_ERR; + + if ((base != 0) && (idx < cmp_count)) { + /* Clear interrupt pending bit for given PWM comparator */ + METAL_PWM_REGW(METAL_SIFIVE_PWM0_PWMCFG) &= ~METAL_PWMCFG_CMPIP(idx); + ret = METAL_PWM_RET_OK; + } + return ret; +} + +static struct metal_interrupt * +__metal_driver_sifive_pwm0_interrupt_controller(struct metal_pwm *gpwm) { + return __metal_driver_sifive_pwm0_interrupt_parent(gpwm); +} + +static int __metal_driver_sifive_pwm0_interrupt_id(struct metal_pwm *gpwm, + unsigned int idx) { + return __metal_driver_sifive_pwm0_interrupt_lines(gpwm, idx); +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_pwm0) = { + .pwm.enable = __metal_driver_sifive_pwm0_enable, + .pwm.disable = __metal_driver_sifive_pwm0_disable, + .pwm.set_duty = __metal_driver_sifive_pwm0_set_duty, + .pwm.set_freq = __metal_driver_sifive_pwm0_set_freq, + .pwm.get_duty = __metal_driver_sifive_pwm0_get_duty, + .pwm.get_freq = __metal_driver_sifive_pwm0_get_freq, + .pwm.trigger = __metal_driver_sifive_pwm0_trigger, + .pwm.stop = __metal_driver_sifive_pwm0_stop, + .pwm.cfg_interrupt = __metal_driver_sifive_pwm0_cfg_interrupt, + .pwm.clr_interrupt = __metal_driver_sifive_pwm0_clr_interrupt, + .pwm.get_interrupt_controller = + __metal_driver_sifive_pwm0_interrupt_controller, + .pwm.get_interrupt_id = __metal_driver_sifive_pwm0_interrupt_id, +}; + +#endif /* METAL_SIFIVE_PWM0 */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_rtc0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_rtc0.c index 79b81e7bf..d9c06d349 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_rtc0.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_rtc0.c @@ -19,30 +19,40 @@ #define METAL_RTCCMP0_MAX UINT32_MAX #define RTC_REG(base, offset) (((unsigned long)base + offset)) -#define RTC_REGW(base, offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)RTC_REG(base, offset))) +#define RTC_REGW(base, offset) \ + (__METAL_ACCESS_ONCE((__metal_io_u32 *)RTC_REG(base, offset))) -uint64_t __metal_driver_sifive_rtc0_get_rate(const struct metal_rtc *const rtc) { - const struct metal_clock *const clock = __metal_driver_sifive_rtc0_clock(rtc); +uint64_t +__metal_driver_sifive_rtc0_get_rate(const struct metal_rtc *const rtc) { + const struct metal_clock *const clock = + __metal_driver_sifive_rtc0_clock(rtc); return metal_clock_get_rate_hz(clock); } -uint64_t __metal_driver_sifive_rtc0_set_rate(const struct metal_rtc *const rtc, const uint64_t rate) { - const struct metal_clock *const clock = __metal_driver_sifive_rtc0_clock(rtc); +uint64_t __metal_driver_sifive_rtc0_set_rate(const struct metal_rtc *const rtc, + const uint64_t rate) { + const struct metal_clock *const clock = + __metal_driver_sifive_rtc0_clock(rtc); return metal_clock_get_rate_hz(clock); } -uint64_t __metal_driver_sifive_rtc0_get_compare(const struct metal_rtc *const rtc) { +uint64_t +__metal_driver_sifive_rtc0_get_compare(const struct metal_rtc *const rtc) { const uint64_t base = __metal_driver_sifive_rtc0_control_base(rtc); - const uint32_t shift = RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCFG) & METAL_RTCCFG_RTCSCALE_MASK; + const uint32_t shift = + RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCFG) & METAL_RTCCFG_RTCSCALE_MASK; return ((uint64_t)RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCMP0) << shift); } -uint64_t __metal_driver_sifive_rtc0_set_compare(const struct metal_rtc *const rtc, const uint64_t compare) { +uint64_t +__metal_driver_sifive_rtc0_set_compare(const struct metal_rtc *const rtc, + const uint64_t compare) { const uint64_t base = __metal_driver_sifive_rtc0_control_base(rtc); - /* Determine the bit shift and shifted value to store in rtccmp0/rtccfg.scale */ + /* Determine the bit shift and shifted value to store in + * rtccmp0/rtccfg.scale */ uint32_t shift = 0; uint64_t comp_shifted = compare; while (comp_shifted > METAL_RTCCMP0_MAX) { @@ -57,12 +67,13 @@ uint64_t __metal_driver_sifive_rtc0_set_compare(const struct metal_rtc *const rt RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCFG) = cfg; /* Set the value of rtccmp0 */ - RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCMP0) = (uint32_t) comp_shifted; + RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCMP0) = (uint32_t)comp_shifted; return __metal_driver_sifive_rtc0_get_compare(rtc); } -uint64_t __metal_driver_sifive_rtc0_get_count(const struct metal_rtc *const rtc) { +uint64_t +__metal_driver_sifive_rtc0_get_count(const struct metal_rtc *const rtc) { const uint64_t base = __metal_driver_sifive_rtc0_control_base(rtc); uint64_t count = RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCOUNTHI); @@ -72,7 +83,8 @@ uint64_t __metal_driver_sifive_rtc0_get_count(const struct metal_rtc *const rtc) return count; } -uint64_t __metal_driver_sifive_rtc0_set_count(const struct metal_rtc *const rtc, const uint64_t count) { +uint64_t __metal_driver_sifive_rtc0_set_count(const struct metal_rtc *const rtc, + const uint64_t count) { const uint64_t base = __metal_driver_sifive_rtc0_control_base(rtc); RTC_REGW(base, METAL_SIFIVE_RTC0_RTCCOUNTHI) = (UINT_MAX & (count >> 32)); @@ -81,7 +93,8 @@ uint64_t __metal_driver_sifive_rtc0_set_count(const struct metal_rtc *const rtc, return __metal_driver_sifive_rtc0_get_count(rtc); } -int __metal_driver_sifive_rtc0_run(const struct metal_rtc *const rtc, const enum metal_rtc_run_option option) { +int __metal_driver_sifive_rtc0_run(const struct metal_rtc *const rtc, + const enum metal_rtc_run_option option) { const uint64_t base = __metal_driver_sifive_rtc0_control_base(rtc); switch (option) { @@ -97,11 +110,13 @@ int __metal_driver_sifive_rtc0_run(const struct metal_rtc *const rtc, const enum return 0; } -struct metal_interrupt *__metal_driver_sifive_rtc0_get_interrupt(const struct metal_rtc *const rtc) { +struct metal_interrupt * +__metal_driver_sifive_rtc0_get_interrupt(const struct metal_rtc *const rtc) { return __metal_driver_sifive_rtc0_interrupt_parent(rtc); } -int __metal_driver_sifive_rtc0_get_interrupt_id(const struct metal_rtc *const rtc) { +int __metal_driver_sifive_rtc0_get_interrupt_id( + const struct metal_rtc *const rtc) { return __metal_driver_sifive_rtc0_interrupt_line(rtc); } @@ -119,3 +134,4 @@ __METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_rtc0) = { #endif +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_simuart0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_simuart0.c new file mode 100644 index 000000000..7a3e1b655 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_simuart0.c @@ -0,0 +1,79 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include <metal/machine/platform.h> + +#ifdef METAL_SIFIVE_SIMUART0 + +#include <assert.h> +#include <metal/drivers/sifive_simuart0.h> +#include <metal/machine.h> + +/* TXDATA Fields */ +#define SIMUART_TXEN (1 << 0) + +#define SIMUART_REG(offset) (((unsigned long)control_base + offset)) +#define SIMUART_REGB(offset) \ + (__METAL_ACCESS_ONCE((__metal_io_u8 *)SIMUART_REG(offset))) +#define SIMUART_REGW(offset) \ + (__METAL_ACCESS_ONCE((__metal_io_u32 *)SIMUART_REG(offset))) + +struct metal_interrupt * +__metal_driver_sifive_simuart0_interrupt_controller(struct metal_uart *uart) { + return __metal_driver_sifive_simuart0_interrupt_parent(uart); +} + +int __metal_driver_sifive_simuart0_get_interrupt_id(struct metal_uart *uart) { + return (__metal_driver_sifive_simuart0_interrupt_line(uart) + + METAL_INTERRUPT_ID_GL0); +} + +int __metal_driver_sifive_simuart0_putc(struct metal_uart *uart, int c) { + long control_base = __metal_driver_sifive_simuart0_control_base(uart); + + SIMUART_REGW(METAL_SIFIVE_SIMUART0_TXDATA) = c; + return 0; +} + +int __metal_driver_sifive_simuart0_getc(struct metal_uart *uart, int *c) { + return 0; +} + +int __metal_driver_sifive_simuart0_get_baud_rate(struct metal_uart *guart) { + struct __metal_driver_sifive_simuart0 *uart = (void *)guart; + return uart->baud_rate; +} + +int __metal_driver_sifive_simuart0_set_baud_rate(struct metal_uart *guart, + int baud_rate) { + struct __metal_driver_sifive_simuart0 *uart = (void *)guart; + long control_base = __metal_driver_sifive_simuart0_control_base(guart); + struct metal_clock *clock = __metal_driver_sifive_simuart0_clock(guart); + + uart->baud_rate = baud_rate; + + if (clock != NULL) { + long clock_rate = clock->vtable->get_rate_hz(clock); + SIMUART_REGW(METAL_SIFIVE_SIMUART0_DIV) = clock_rate / baud_rate - 1; + SIMUART_REGW(METAL_SIFIVE_SIMUART0_TXCTRL) |= SIMUART_TXEN; + } + return 0; +} + +void __metal_driver_sifive_simuart0_init(struct metal_uart *guart, + int baud_rate) {} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_simuart0) = { + .uart.init = __metal_driver_sifive_simuart0_init, + .uart.putc = __metal_driver_sifive_simuart0_putc, + .uart.getc = __metal_driver_sifive_simuart0_getc, + .uart.get_baud_rate = __metal_driver_sifive_simuart0_get_baud_rate, + .uart.set_baud_rate = __metal_driver_sifive_simuart0_set_baud_rate, + .uart.controller_interrupt = + __metal_driver_sifive_simuart0_interrupt_controller, + .uart.get_interrupt_id = __metal_driver_sifive_simuart0_get_interrupt_id, +}; + +#endif /* METAL_SIFIVE_SIMUART0 */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_spi0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_spi0.c index 2a346354f..34f8e0a5d 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_spi0.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_spi0.c @@ -11,48 +11,51 @@ #include <time.h> /* Register fields */ -#define METAL_SPI_SCKDIV_MASK 0xFFF +#define METAL_SPI_SCKDIV_MASK 0xFFF -#define METAL_SPI_SCKMODE_PHA_SHIFT 0 -#define METAL_SPI_SCKMODE_POL_SHIFT 1 +#define METAL_SPI_SCKMODE_PHA_SHIFT 0 +#define METAL_SPI_SCKMODE_POL_SHIFT 1 -#define METAL_SPI_CSMODE_MASK 3 -#define METAL_SPI_CSMODE_AUTO 0 -#define METAL_SPI_CSMODE_HOLD 2 -#define METAL_SPI_CSMODE_OFF 3 +#define METAL_SPI_CSMODE_MASK 3 +#define METAL_SPI_CSMODE_AUTO 0 +#define METAL_SPI_CSMODE_HOLD 2 +#define METAL_SPI_CSMODE_OFF 3 -#define METAL_SPI_PROTO_MASK 3 -#define METAL_SPI_PROTO_SINGLE 0 -#define METAL_SPI_PROTO_DUAL 1 -#define METAL_SPI_PROTO_QUAD 2 +#define METAL_SPI_PROTO_MASK 3 +#define METAL_SPI_PROTO_SINGLE 0 +#define METAL_SPI_PROTO_DUAL 1 +#define METAL_SPI_PROTO_QUAD 2 -#define METAL_SPI_ENDIAN_LSB 4 +#define METAL_SPI_ENDIAN_LSB 4 -#define METAL_SPI_DISABLE_RX 8 +#define METAL_SPI_DISABLE_RX 8 -#define METAL_SPI_FRAME_LEN_SHIFT 16 -#define METAL_SPI_FRAME_LEN_MASK (0xF << METAL_SPI_FRAME_LEN_SHIFT) +#define METAL_SPI_FRAME_LEN_SHIFT 16 +#define METAL_SPI_FRAME_LEN_MASK (0xF << METAL_SPI_FRAME_LEN_SHIFT) -#define METAL_SPI_TXDATA_FULL (1 << 31) -#define METAL_SPI_RXDATA_EMPTY (1 << 31) -#define METAL_SPI_TXMARK_MASK 7 -#define METAL_SPI_TXWM 1 -#define METAL_SPI_TXRXDATA_MASK (0xFF) +#define METAL_SPI_TXDATA_FULL (1 << 31) +#define METAL_SPI_RXDATA_EMPTY (1 << 31) +#define METAL_SPI_TXMARK_MASK 7 +#define METAL_SPI_TXWM 1 +#define METAL_SPI_TXRXDATA_MASK (0xFF) -#define METAL_SPI_INTERVAL_SHIFT 16 +#define METAL_SPI_INTERVAL_SHIFT 16 -#define METAL_SPI_CONTROL_IO 0 -#define METAL_SPI_CONTROL_MAPPED 1 +#define METAL_SPI_CONTROL_IO 0 +#define METAL_SPI_CONTROL_MAPPED 1 -#define METAL_SPI_REG(offset) (((unsigned long)control_base + offset)) -#define METAL_SPI_REGB(offset) (__METAL_ACCESS_ONCE((__metal_io_u8 *)METAL_SPI_REG(offset))) -#define METAL_SPI_REGW(offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)METAL_SPI_REG(offset))) +#define METAL_SPI_REG(offset) (((unsigned long)control_base + offset)) +#define METAL_SPI_REGB(offset) \ + (__METAL_ACCESS_ONCE((__metal_io_u8 *)METAL_SPI_REG(offset))) +#define METAL_SPI_REGW(offset) \ + (__METAL_ACCESS_ONCE((__metal_io_u32 *)METAL_SPI_REG(offset))) -#define METAL_SPI_RXDATA_TIMEOUT 1 +#define METAL_SPI_RXDATA_TIMEOUT 1 -static int configure_spi(struct __metal_driver_sifive_spi0 *spi, struct metal_spi_config *config) -{ - long control_base = __metal_driver_sifive_spi0_control_base((struct metal_spi *)spi); +static int configure_spi(struct __metal_driver_sifive_spi0 *spi, + struct metal_spi_config *config) { + long control_base = + __metal_driver_sifive_spi0_control_base((struct metal_spi *)spi); /* Set protocol */ METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) &= ~(METAL_SPI_PROTO_MASK); switch (config->protocol) { @@ -77,21 +80,25 @@ static int configure_spi(struct __metal_driver_sifive_spi0 *spi, struct metal_sp } /* Set Polarity */ - if(config->polarity) { - METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKMODE) |= (1 << METAL_SPI_SCKMODE_PHA_SHIFT); + if (config->polarity) { + METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKMODE) |= + (1 << METAL_SPI_SCKMODE_POL_SHIFT); } else { - METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKMODE) &= ~(1 << METAL_SPI_SCKMODE_PHA_SHIFT); + METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKMODE) &= + ~(1 << METAL_SPI_SCKMODE_POL_SHIFT); } /* Set Phase */ - if(config->phase) { - METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKMODE) |= (1 << METAL_SPI_SCKMODE_POL_SHIFT); + if (config->phase) { + METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKMODE) |= + (1 << METAL_SPI_SCKMODE_PHA_SHIFT); } else { - METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKMODE) &= ~(1 << METAL_SPI_SCKMODE_POL_SHIFT); + METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKMODE) &= + ~(1 << METAL_SPI_SCKMODE_PHA_SHIFT); } /* Set Endianness */ - if(config->little_endian) { + if (config->little_endian) { METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= METAL_SPI_ENDIAN_LSB; } else { METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) &= ~(METAL_SPI_ENDIAN_LSB); @@ -101,24 +108,26 @@ static int configure_spi(struct __metal_driver_sifive_spi0 *spi, struct metal_sp METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) &= ~(METAL_SPI_DISABLE_RX); /* Set CS Active */ - if(config->cs_active_high) { + if (config->cs_active_high) { METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSDEF) = 0; } else { METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSDEF) = 1; } /* Set frame length */ - if((METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) & METAL_SPI_FRAME_LEN_MASK) != (8 << METAL_SPI_FRAME_LEN_SHIFT)) { + if ((METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) & METAL_SPI_FRAME_LEN_MASK) != + (8 << METAL_SPI_FRAME_LEN_SHIFT)) { METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) &= ~(METAL_SPI_FRAME_LEN_MASK); - METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= (8 << METAL_SPI_FRAME_LEN_SHIFT); + METAL_SPI_REGW(METAL_SIFIVE_SPI0_FMT) |= + (8 << METAL_SPI_FRAME_LEN_SHIFT); } /* Set CS line */ - METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSID) = 1 << (config->csid); + METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSID) = config->csid; /* Toggle off memory-mapped SPI flash mode, toggle on programmable IO mode - * It seems that with this line uncommented, the debugger cannot have access - * to the chip at all because it assumes the chip is in memory-mapped mode. + * It seems that with this line uncommented, the debugger cannot have access + * to the chip at all because it assumes the chip is in memory-mapped mode. * I have to compile the code with this line commented and launch gdb, * reset cores, reset $pc, set *((int *) 0x20004060) = 0, (set the flash * interface control register to programmable I/O mode) and then continue @@ -151,18 +160,16 @@ static void spi_mode_switch(struct __metal_driver_sifive_spi0 *spi, } int __metal_driver_sifive_spi0_transfer(struct metal_spi *gspi, - struct metal_spi_config *config, - size_t len, - char *tx_buf, - char *rx_buf) -{ + struct metal_spi_config *config, + size_t len, char *tx_buf, + char *rx_buf) { struct __metal_driver_sifive_spi0 *spi = (void *)gspi; long control_base = __metal_driver_sifive_spi0_control_base(gspi); int rc = 0; size_t i = 0; rc = configure_spi(spi, config); - if(rc != 0) { + if (rc != 0) { return rc; } @@ -171,7 +178,7 @@ int __metal_driver_sifive_spi0_transfer(struct metal_spi *gspi, METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) |= METAL_SPI_CSMODE_HOLD; unsigned long rxdata; - + /* Declare time_t variables to break out of infinite while loop */ time_t endwait; @@ -269,9 +276,11 @@ int __metal_driver_sifive_spi0_transfer(struct metal_spi *gspi, /* Master send bytes to the slave */ /* Wait for TXFIFO to not be full */ - while (METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXDATA) & METAL_SPI_TXDATA_FULL); - - /* Transfer byte by modifying the least significant byte in the TXDATA register */ + while (METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXDATA) & METAL_SPI_TXDATA_FULL) + ; + + /* Transfer byte by modifying the least significant byte in the TXDATA + * register */ if (tx_buf) { METAL_SPI_REGB(METAL_SIFIVE_SPI0_TXDATA) = tx_buf[i]; } else { @@ -281,15 +290,17 @@ int __metal_driver_sifive_spi0_transfer(struct metal_spi *gspi, /* Master receives bytes from the RX FIFO */ - /* Wait for RXFIFO to not be empty, but break the nested loops if timeout - * this timeout method needs refining, preferably taking into account - * the device specs */ + /* Wait for RXFIFO to not be empty, but break the nested loops if + * timeout this timeout method needs refining, preferably taking into + * account the device specs */ endwait = metal_time() + METAL_SPI_RXDATA_TIMEOUT; - while ((rxdata = METAL_SPI_REGW(METAL_SIFIVE_SPI0_RXDATA)) & METAL_SPI_RXDATA_EMPTY) { + while ((rxdata = METAL_SPI_REGW(METAL_SIFIVE_SPI0_RXDATA)) & + METAL_SPI_RXDATA_EMPTY) { if (metal_time() > endwait) { /* If timeout, deassert the CS */ - METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &= ~(METAL_SPI_CSMODE_MASK); + METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &= + ~(METAL_SPI_CSMODE_MASK); /* If timeout, return error code 1 immediately */ return 1; @@ -298,29 +309,30 @@ int __metal_driver_sifive_spi0_transfer(struct metal_spi *gspi, /* Only store the dequeued byte if the receive_buffer is not NULL */ if (rx_buf) { - rx_buf[i] = (char) (rxdata & METAL_SPI_TXRXDATA_MASK); + rx_buf[i] = (char)(rxdata & METAL_SPI_TXRXDATA_MASK); } } - /* On the last byte, set CSMODE to auto so that the chip select transitions back to high - * The reason that CS pin is not deasserted after transmitting out the byte buffer is timing. - * The code on the host side likely executes faster than the ability of FIFO to send out bytes. - * After the host iterates through the array, fifo is likely not cleared yet. If host deasserts - * the CS pin immediately, the following bytes in the output FIFO will not be sent consecutively. + /* On the last byte, set CSMODE to auto so that the chip select transitions + * back to high The reason that CS pin is not deasserted after transmitting + * out the byte buffer is timing. The code on the host side likely executes + * faster than the ability of FIFO to send out bytes. After the host + * iterates through the array, fifo is likely not cleared yet. If host + * deasserts the CS pin immediately, the following bytes in the output FIFO + * will not be sent consecutively. * There needs to be a better way to handle this. */ METAL_SPI_REGW(METAL_SIFIVE_SPI0_CSMODE) &= ~(METAL_SPI_CSMODE_MASK); return 0; } -int __metal_driver_sifive_spi0_get_baud_rate(struct metal_spi *gspi) -{ +int __metal_driver_sifive_spi0_get_baud_rate(struct metal_spi *gspi) { struct __metal_driver_sifive_spi0 *spi = (void *)gspi; return spi->baud_rate; } -int __metal_driver_sifive_spi0_set_baud_rate(struct metal_spi *gspi, int baud_rate) -{ +int __metal_driver_sifive_spi0_set_baud_rate(struct metal_spi *gspi, + int baud_rate) { long control_base = __metal_driver_sifive_spi0_control_base(gspi); struct metal_clock *clock = __metal_driver_sifive_spi0_clock(gspi); struct __metal_driver_sifive_spi0 *spi = (void *)gspi; @@ -333,7 +345,7 @@ int __metal_driver_sifive_spi0_set_baud_rate(struct metal_spi *gspi, int baud_ra /* Calculate divider */ long div = (clock_rate / (2 * baud_rate)) - 1; - if(div > METAL_SPI_SCKDIV_MASK) { + if (div > METAL_SPI_SCKDIV_MASK) { /* The requested baud rate is lower than we can support at * the current clock rate */ return -1; @@ -341,62 +353,67 @@ int __metal_driver_sifive_spi0_set_baud_rate(struct metal_spi *gspi, int baud_ra /* Set divider */ METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKDIV) &= ~METAL_SPI_SCKDIV_MASK; - METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKDIV) |= (div & METAL_SPI_SCKDIV_MASK); + METAL_SPI_REGW(METAL_SIFIVE_SPI0_SCKDIV) |= + (div & METAL_SPI_SCKDIV_MASK); } return 0; } -static void pre_rate_change_callback_func(void *priv) -{ - long control_base = __metal_driver_sifive_spi0_control_base((struct metal_spi *)priv); +static void pre_rate_change_callback_func(void *priv) { + long control_base = + __metal_driver_sifive_spi0_control_base((struct metal_spi *)priv); /* Detect when the TXDATA is empty by setting the transmit watermark count - * to one and waiting until an interrupt is pending (indicating an empty TXFIFO) */ + * to one and waiting until an interrupt is pending (indicating an empty + * TXFIFO) */ METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXMARK) &= ~(METAL_SPI_TXMARK_MASK); METAL_SPI_REGW(METAL_SIFIVE_SPI0_TXMARK) |= (METAL_SPI_TXMARK_MASK & 1); - while((METAL_SPI_REGW(METAL_SIFIVE_SPI0_IP) & METAL_SPI_TXWM) == 0) ; + while ((METAL_SPI_REGW(METAL_SIFIVE_SPI0_IP) & METAL_SPI_TXWM) == 0) + ; } -static void post_rate_change_callback_func(void *priv) -{ +static void post_rate_change_callback_func(void *priv) { struct __metal_driver_sifive_spi0 *spi = priv; metal_spi_set_baud_rate(&spi->spi, spi->baud_rate); } -void __metal_driver_sifive_spi0_init(struct metal_spi *gspi, int baud_rate) -{ +void __metal_driver_sifive_spi0_init(struct metal_spi *gspi, int baud_rate) { struct __metal_driver_sifive_spi0 *spi = (void *)(gspi); struct metal_clock *clock = __metal_driver_sifive_spi0_clock(gspi); - struct __metal_driver_sifive_gpio0 *pinmux = __metal_driver_sifive_spi0_pinmux(gspi); + struct __metal_driver_sifive_gpio0 *pinmux = + __metal_driver_sifive_spi0_pinmux(gspi); - if(clock != NULL) { + if (clock != NULL) { spi->pre_rate_change_callback.callback = &pre_rate_change_callback_func; spi->pre_rate_change_callback.priv = spi; - metal_clock_register_pre_rate_change_callback(clock, &(spi->pre_rate_change_callback)); + metal_clock_register_pre_rate_change_callback( + clock, &(spi->pre_rate_change_callback)); - spi->post_rate_change_callback.callback = &post_rate_change_callback_func; + spi->post_rate_change_callback.callback = + &post_rate_change_callback_func; spi->post_rate_change_callback.priv = spi; - metal_clock_register_post_rate_change_callback(clock, &(spi->post_rate_change_callback)); + metal_clock_register_post_rate_change_callback( + clock, &(spi->post_rate_change_callback)); } metal_spi_set_baud_rate(&(spi->spi), baud_rate); if (pinmux != NULL) { - long pinmux_output_selector = __metal_driver_sifive_spi0_pinmux_output_selector(gspi); - long pinmux_source_selector = __metal_driver_sifive_spi0_pinmux_source_selector(gspi); - pinmux->gpio.vtable->enable_io( - (struct metal_gpio *) pinmux, - pinmux_output_selector, - pinmux_source_selector - ); + long pinmux_output_selector = + __metal_driver_sifive_spi0_pinmux_output_selector(gspi); + long pinmux_source_selector = + __metal_driver_sifive_spi0_pinmux_source_selector(gspi); + pinmux->gpio.vtable->enable_io((struct metal_gpio *)pinmux, + pinmux_output_selector, + pinmux_source_selector); } } __METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_spi0) = { - .spi.init = __metal_driver_sifive_spi0_init, - .spi.transfer = __metal_driver_sifive_spi0_transfer, + .spi.init = __metal_driver_sifive_spi0_init, + .spi.transfer = __metal_driver_sifive_spi0_transfer, .spi.get_baud_rate = __metal_driver_sifive_spi0_get_baud_rate, .spi.set_baud_rate = __metal_driver_sifive_spi0_set_baud_rate, }; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_test0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_test0.c index 79deebbf5..c21d09685 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_test0.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_test0.c @@ -12,18 +12,20 @@ #include <metal/drivers/sifive_test0.h> #include <metal/io.h> -void __metal_driver_sifive_test0_exit(const struct __metal_shutdown *sd, int code) __attribute__((noreturn)); -void __metal_driver_sifive_test0_exit(const struct __metal_shutdown *sd, int code) -{ +void __metal_driver_sifive_test0_exit(const struct __metal_shutdown *sd, + int code) __attribute__((noreturn)); +void __metal_driver_sifive_test0_exit(const struct __metal_shutdown *sd, + int code) { long base = __metal_driver_sifive_test0_base(sd); uint32_t out = (code << 16) + (code == 0 ? 0x5555 : 0x3333); while (1) { - __METAL_ACCESS_ONCE((__metal_io_u32 *)(base + METAL_SIFIVE_TEST0_FINISHER_OFFSET)) = out; + __METAL_ACCESS_ONCE(( + __metal_io_u32 *)(base + METAL_SIFIVE_TEST0_FINISHER_OFFSET)) = out; } } __METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_test0) = { - .shutdown.exit = &__metal_driver_sifive_test0_exit, + .shutdown.exit = &__metal_driver_sifive_test0_exit, }; #endif /* METAL_SIFIVE_TEST0 */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_trace.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_trace.c index 8b63fbd28..6b82e0f3e 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_trace.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_trace.c @@ -34,8 +34,7 @@ static void write_itc_uint8(struct metal_uart *trace, uint8_t data) { TRACE_REG8(METAL_SIFIVE_TRACE_ITCSTIMULUS + 3) = data; } -int __metal_driver_sifive_trace_putc(struct metal_uart *trace, - unsigned char c) { +int __metal_driver_sifive_trace_putc(struct metal_uart *trace, int c) { static uint32_t buffer = 0; static int bytes_in_buffer = 0; @@ -48,7 +47,7 @@ int __metal_driver_sifive_trace_putc(struct metal_uart *trace, buffer = 0; bytes_in_buffer = 0; - } else if ((c == '\n') || (c == '\r')) { // partial write + } else if (((char)c == '\n') || ((char)c == '\r')) { // partial write switch (bytes_in_buffer) { case 3: // do a full word write write_itc_uint16(trace, (uint16_t)(buffer)); @@ -66,7 +65,7 @@ int __metal_driver_sifive_trace_putc(struct metal_uart *trace, bytes_in_buffer = 0; } - return (int)c; + return c; } void __metal_driver_sifive_trace_init(struct metal_uart *trace, int baud_rate) { @@ -93,3 +92,5 @@ __METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_trace) = { }; #endif /* METAL_SIFIVE_TRACE */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_uart0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_uart0.c index 2e8098aa7..8d2634413 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_uart0.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_uart0.c @@ -9,79 +9,132 @@ #include <metal/machine.h> /* TXDATA Fields */ -#define UART_TXEN (1 << 0) -#define UART_TXFULL (1 << 31) +#define UART_TXEN (1 << 0) +#define UART_TXFULL (1 << 31) /* RXDATA Fields */ -#define UART_RXEN (1 << 0) -#define UART_RXEMPTY (1 << 31) +#define UART_RXEN (1 << 0) +#define UART_RXEMPTY (1 << 31) /* TXCTRL Fields */ -#define UART_NSTOP (1 << 1) -#define UART_TXCNT(count) ((0x7 & count) << 16) +#define UART_NSTOP (1 << 1) +#define UART_TXCNT(count) ((0x7 & count) << 16) + +/* RXCTRL Fields */ +#define UART_RXCNT(count) ((0x7 & count) << 16) /* IP Fields */ -#define UART_TXWM (1 << 0) +#define UART_TXWM (1 << 0) +#define UART_RXWM (1 << 1) -#define UART_REG(offset) (((unsigned long)control_base + offset)) -#define UART_REGB(offset) (__METAL_ACCESS_ONCE((__metal_io_u8 *)UART_REG(offset))) -#define UART_REGW(offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)UART_REG(offset))) +#define UART_REG(offset) (((unsigned long)control_base + offset)) +#define UART_REGB(offset) \ + (__METAL_ACCESS_ONCE((__metal_io_u8 *)UART_REG(offset))) +#define UART_REGW(offset) \ + (__METAL_ACCESS_ONCE((__metal_io_u32 *)UART_REG(offset))) struct metal_interrupt * -__metal_driver_sifive_uart0_interrupt_controller(struct metal_uart *uart) -{ +__metal_driver_sifive_uart0_interrupt_controller(struct metal_uart *uart) { return __metal_driver_sifive_uart0_interrupt_parent(uart); } -int __metal_driver_sifive_uart0_get_interrupt_id(struct metal_uart *uart) -{ - return (__metal_driver_sifive_uart0_interrupt_line(uart) + METAL_INTERRUPT_ID_GL0); +int __metal_driver_sifive_uart0_get_interrupt_id(struct metal_uart *uart) { + return __metal_driver_sifive_uart0_interrupt_line(uart); } +int __metal_driver_sifive_uart0_tx_interrupt_enable(struct metal_uart *uart) { + long control_base = __metal_driver_sifive_uart0_control_base(uart); + + UART_REGW(METAL_SIFIVE_UART0_IE) |= UART_TXWM; + return 0; +} -int __metal_driver_sifive_uart0_txready(struct metal_uart *uart) -{ - long control_base = __metal_driver_sifive_uart0_control_base(uart); +int __metal_driver_sifive_uart0_tx_interrupt_disable(struct metal_uart *uart) { + long control_base = __metal_driver_sifive_uart0_control_base(uart); - return !((UART_REGW(METAL_SIFIVE_UART0_TXDATA) & UART_TXFULL)); + UART_REGW(METAL_SIFIVE_UART0_IE) &= ~UART_TXWM; + return 0; } +int __metal_driver_sifive_uart0_rx_interrupt_enable(struct metal_uart *uart) { + long control_base = __metal_driver_sifive_uart0_control_base(uart); + + UART_REGW(METAL_SIFIVE_UART0_IE) |= UART_RXWM; + return 0; +} -int __metal_driver_sifive_uart0_putc(struct metal_uart *uart, int c) -{ +int __metal_driver_sifive_uart0_rx_interrupt_disable(struct metal_uart *uart) { long control_base = __metal_driver_sifive_uart0_control_base(uart); - while (!__metal_driver_sifive_uart0_txready(uart)) { - /* wait */ + UART_REGW(METAL_SIFIVE_UART0_IE) &= ~UART_RXWM; + return 0; +} + +int __metal_driver_sifive_uart0_txready(struct metal_uart *uart) { + long control_base = __metal_driver_sifive_uart0_control_base(uart); + + return !!((UART_REGW(METAL_SIFIVE_UART0_TXDATA) & UART_TXFULL)); +} + +int __metal_driver_sifive_uart0_set_tx_watermark(struct metal_uart *uart, + size_t level) { + long control_base = __metal_driver_sifive_uart0_control_base(uart); + + UART_REGW(METAL_SIFIVE_UART0_TXCTRL) |= UART_TXCNT(level); + return 0; +} + +size_t __metal_driver_sifive_uart0_get_tx_watermark(struct metal_uart *uart) { + long control_base = __metal_driver_sifive_uart0_control_base(uart); + + return ((UART_REGW(METAL_SIFIVE_UART0_TXCTRL) >> 16) & 0x7); +} + +int __metal_driver_sifive_uart0_set_rx_watermark(struct metal_uart *uart, + size_t level) { + long control_base = __metal_driver_sifive_uart0_control_base(uart); + + UART_REGW(METAL_SIFIVE_UART0_RXCTRL) |= UART_RXCNT(level); + return 0; +} + +size_t __metal_driver_sifive_uart0_get_rx_watermark(struct metal_uart *uart) { + long control_base = __metal_driver_sifive_uart0_control_base(uart); + + return ((UART_REGW(METAL_SIFIVE_UART0_RXCTRL) >> 16) & 0x7); +} + +int __metal_driver_sifive_uart0_putc(struct metal_uart *uart, int c) { + long control_base = __metal_driver_sifive_uart0_control_base(uart); + + while (__metal_driver_sifive_uart0_txready(uart) != 0) { + /* wait */ } UART_REGW(METAL_SIFIVE_UART0_TXDATA) = c; return 0; } - -int __metal_driver_sifive_uart0_getc(struct metal_uart *uart, int *c) -{ +int __metal_driver_sifive_uart0_getc(struct metal_uart *uart, int *c) { uint32_t ch; long control_base = __metal_driver_sifive_uart0_control_base(uart); /* No seperate status register, we get status and the byte at same time */ - ch = UART_REGW(METAL_SIFIVE_UART0_RXDATA);; - if( ch & UART_RXEMPTY ){ - *c = -1; /* aka: EOF in most of the world */ + ch = UART_REGW(METAL_SIFIVE_UART0_RXDATA); + ; + if (ch & UART_RXEMPTY) { + *c = -1; /* aka: EOF in most of the world */ } else { - *c = ch & 0x0ff; + *c = ch & 0x0ff; } return 0; } - -int __metal_driver_sifive_uart0_get_baud_rate(struct metal_uart *guart) -{ +int __metal_driver_sifive_uart0_get_baud_rate(struct metal_uart *guart) { struct __metal_driver_sifive_uart0 *uart = (void *)guart; return uart->baud_rate; } -int __metal_driver_sifive_uart0_set_baud_rate(struct metal_uart *guart, int baud_rate) -{ +int __metal_driver_sifive_uart0_set_baud_rate(struct metal_uart *guart, + int baud_rate) { struct __metal_driver_sifive_uart0 *uart = (void *)guart; long control_base = __metal_driver_sifive_uart0_control_base(guart); struct metal_clock *clock = __metal_driver_sifive_uart0_clock(guart); @@ -97,11 +150,12 @@ int __metal_driver_sifive_uart0_set_baud_rate(struct metal_uart *guart, int baud return 0; } -static void pre_rate_change_callback_func(void *priv) -{ +static void pre_rate_change_callback_func(void *priv) { struct __metal_driver_sifive_uart0 *uart = priv; - long control_base = __metal_driver_sifive_uart0_control_base((struct metal_uart *)priv); - struct metal_clock *clock = __metal_driver_sifive_uart0_clock((struct metal_uart *)priv); + long control_base = + __metal_driver_sifive_uart0_control_base((struct metal_uart *)priv); + struct metal_clock *clock = + __metal_driver_sifive_uart0_clock((struct metal_uart *)priv); /* Detect when the TXDATA is empty by setting the transmit watermark count * to one and waiting until an interrupt is pending */ @@ -109,63 +163,80 @@ static void pre_rate_change_callback_func(void *priv) UART_REGW(METAL_SIFIVE_UART0_TXCTRL) &= ~(UART_TXCNT(0x7)); UART_REGW(METAL_SIFIVE_UART0_TXCTRL) |= UART_TXCNT(1); - while((UART_REGW(METAL_SIFIVE_UART0_IP) & UART_TXWM) == 0) ; + while ((UART_REGW(METAL_SIFIVE_UART0_IP) & UART_TXWM) == 0) + ; /* When the TXDATA clears, the UART is still shifting out the last byte. * Calculate the time we must drain to finish transmitting and then wait * that long. */ - long bits_per_symbol = (UART_REGW(METAL_SIFIVE_UART0_TXCTRL) & (1 << 1)) ? 9 : 10; + long bits_per_symbol = + (UART_REGW(METAL_SIFIVE_UART0_TXCTRL) & (1 << 1)) ? 9 : 10; long clk_freq = clock->vtable->get_rate_hz(clock); long cycles_to_wait = bits_per_symbol * clk_freq / uart->baud_rate; - for(volatile long x = 0; x < cycles_to_wait; x++) + for (volatile long x = 0; x < cycles_to_wait; x++) __asm__("nop"); } -static void post_rate_change_callback_func(void *priv) -{ +static void post_rate_change_callback_func(void *priv) { struct __metal_driver_sifive_uart0 *uart = priv; metal_uart_set_baud_rate(&uart->uart, uart->baud_rate); } -void __metal_driver_sifive_uart0_init(struct metal_uart *guart, int baud_rate) -{ +void __metal_driver_sifive_uart0_init(struct metal_uart *guart, int baud_rate) { struct __metal_driver_sifive_uart0 *uart = (void *)(guart); struct metal_clock *clock = __metal_driver_sifive_uart0_clock(guart); - struct __metal_driver_sifive_gpio0 *pinmux = __metal_driver_sifive_uart0_pinmux(guart); + struct __metal_driver_sifive_gpio0 *pinmux = + __metal_driver_sifive_uart0_pinmux(guart); - if(clock != NULL) { - uart->pre_rate_change_callback.callback = &pre_rate_change_callback_func; + if (clock != NULL) { + uart->pre_rate_change_callback.callback = + &pre_rate_change_callback_func; uart->pre_rate_change_callback.priv = guart; - metal_clock_register_pre_rate_change_callback(clock, &(uart->pre_rate_change_callback)); + metal_clock_register_pre_rate_change_callback( + clock, &(uart->pre_rate_change_callback)); - uart->post_rate_change_callback.callback = &post_rate_change_callback_func; + uart->post_rate_change_callback.callback = + &post_rate_change_callback_func; uart->post_rate_change_callback.priv = guart; - metal_clock_register_post_rate_change_callback(clock, &(uart->post_rate_change_callback)); + metal_clock_register_post_rate_change_callback( + clock, &(uart->post_rate_change_callback)); } metal_uart_set_baud_rate(&(uart->uart), baud_rate); if (pinmux != NULL) { - long pinmux_output_selector = __metal_driver_sifive_uart0_pinmux_output_selector(guart); - long pinmux_source_selector = __metal_driver_sifive_uart0_pinmux_source_selector(guart); - pinmux->gpio.vtable->enable_io( - (struct metal_gpio *) pinmux, - pinmux_output_selector, - pinmux_source_selector - ); + long pinmux_output_selector = + __metal_driver_sifive_uart0_pinmux_output_selector(guart); + long pinmux_source_selector = + __metal_driver_sifive_uart0_pinmux_source_selector(guart); + pinmux->gpio.vtable->enable_io((struct metal_gpio *)pinmux, + pinmux_output_selector, + pinmux_source_selector); } } __METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_uart0) = { - .uart.init = __metal_driver_sifive_uart0_init, - .uart.putc = __metal_driver_sifive_uart0_putc, - .uart.getc = __metal_driver_sifive_uart0_getc, + .uart.init = __metal_driver_sifive_uart0_init, + .uart.putc = __metal_driver_sifive_uart0_putc, + .uart.getc = __metal_driver_sifive_uart0_getc, + .uart.txready = __metal_driver_sifive_uart0_txready, .uart.get_baud_rate = __metal_driver_sifive_uart0_get_baud_rate, .uart.set_baud_rate = __metal_driver_sifive_uart0_set_baud_rate, - .uart.controller_interrupt = __metal_driver_sifive_uart0_interrupt_controller, - .uart.get_interrupt_id = __metal_driver_sifive_uart0_get_interrupt_id, + .uart.controller_interrupt = + __metal_driver_sifive_uart0_interrupt_controller, + .uart.get_interrupt_id = __metal_driver_sifive_uart0_get_interrupt_id, + .uart.tx_interrupt_enable = __metal_driver_sifive_uart0_tx_interrupt_enable, + .uart.tx_interrupt_disable = + __metal_driver_sifive_uart0_tx_interrupt_disable, + .uart.rx_interrupt_enable = __metal_driver_sifive_uart0_rx_interrupt_enable, + .uart.rx_interrupt_disable = + __metal_driver_sifive_uart0_rx_interrupt_disable, + .uart.set_tx_watermark = __metal_driver_sifive_uart0_set_tx_watermark, + .uart.get_tx_watermark = __metal_driver_sifive_uart0_get_tx_watermark, + .uart.set_rx_watermark = __metal_driver_sifive_uart0_set_rx_watermark, + .uart.get_rx_watermark = __metal_driver_sifive_uart0_get_rx_watermark, }; #endif /* METAL_SIFIVE_UART0 */ diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_wdog0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_wdog0.c index 1a6cf362e..4f37b7eb2 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_wdog0.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_wdog0.c @@ -21,54 +21,65 @@ /* WDOGCMP */ #define METAL_WDOGCMP_MASK 0xFFFF -#define WDOG_REG(base, offset) (((unsigned long)base + offset)) -#define WDOG_REGB(base, offset) (__METAL_ACCESS_ONCE((__metal_io_u8 *)WDOG_REG(base, offset))) -#define WDOG_REGW(base, offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)WDOG_REG(base, offset))) +#define WDOG_REG(base, offset) (((unsigned long)base + offset)) +#define WDOG_REGB(base, offset) \ + (__METAL_ACCESS_ONCE((__metal_io_u8 *)WDOG_REG(base, offset))) +#define WDOG_REGW(base, offset) \ + (__METAL_ACCESS_ONCE((__metal_io_u32 *)WDOG_REG(base, offset))) /* All writes to watchdog registers must be precedded by a write of * a magic number to WDOGKEY */ -#define WDOG_UNLOCK(base) (WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGKEY) = METAL_SIFIVE_WDOG0_MAGIC_KEY) +#define WDOG_UNLOCK(base) \ + (WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGKEY) = METAL_SIFIVE_WDOG0_MAGIC_KEY) /* Unlock the watchdog and then perform a register access */ -#define WDOG_UNLOCK_REGW(base, offset) \ - WDOG_UNLOCK(base);\ +#define WDOG_UNLOCK_REGW(base, offset) \ + WDOG_UNLOCK(base); \ WDOG_REGW(base, offset) -int __metal_driver_sifive_wdog0_feed(const struct metal_watchdog *const wdog) -{ - const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); +int __metal_driver_sifive_wdog0_feed(const struct metal_watchdog *const wdog) { + const uintptr_t base = + (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGFEED) = METAL_SIFIVE_WDOG0_MAGIC_FOOD; + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGFEED) = + METAL_SIFIVE_WDOG0_MAGIC_FOOD; return 0; } -long int __metal_driver_sifive_wdog0_get_rate(const struct metal_watchdog *const wdog) -{ - const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); - const struct metal_clock *const clock = __metal_driver_sifive_wdog0_clock(wdog); - +long int +__metal_driver_sifive_wdog0_get_rate(const struct metal_watchdog *const wdog) { + const uintptr_t base = + (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); + const struct metal_clock *const clock = + __metal_driver_sifive_wdog0_clock(wdog); + const long int clock_rate = metal_clock_get_rate_hz(clock); if (clock_rate == 0) return -1; - const unsigned int scale = (WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) & METAL_WDOGCFG_SCALE_MASK); + const unsigned int scale = (WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) & + METAL_WDOGCFG_SCALE_MASK); return clock_rate / (1 << scale); } -long int __metal_driver_sifive_wdog0_set_rate(const struct metal_watchdog *const wdog, const long int rate) -{ - const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); - const struct metal_clock *const clock = __metal_driver_sifive_wdog0_clock(wdog); - +long int +__metal_driver_sifive_wdog0_set_rate(const struct metal_watchdog *const wdog, + const long int rate) { + const uintptr_t base = + (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); + const struct metal_clock *const clock = + __metal_driver_sifive_wdog0_clock(wdog); + const long int clock_rate = metal_clock_get_rate_hz(clock); if (rate >= clock_rate) { /* We can't scale the rate above the driving clock. Clear the scale * field and return the driving clock rate */ - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_SCALE_MASK); + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= + ~(METAL_WDOGCFG_SCALE_MASK); return clock_rate; } @@ -88,30 +99,36 @@ long int __metal_driver_sifive_wdog0_set_rate(const struct metal_watchdog *const } } - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_SCALE_MASK); - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= (METAL_WDOGCFG_SCALE_MASK & min_scale); + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= + ~(METAL_WDOGCFG_SCALE_MASK); + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= + (METAL_WDOGCFG_SCALE_MASK & min_scale); return clock_rate / (1 << min_scale); } -long int __metal_driver_sifive_wdog0_get_timeout(const struct metal_watchdog *const wdog) -{ - const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); +long int __metal_driver_sifive_wdog0_get_timeout( + const struct metal_watchdog *const wdog) { + const uintptr_t base = + (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); return (WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGCMP) & METAL_WDOGCMP_MASK); } -long int __metal_driver_sifive_wdog0_set_timeout(const struct metal_watchdog *const wdog, const long int timeout) -{ - const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); +long int +__metal_driver_sifive_wdog0_set_timeout(const struct metal_watchdog *const wdog, + const long int timeout) { + const uintptr_t base = + (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); /* Cap the timeout at the max value */ - const long int set_timeout = timeout > METAL_WDOGCMP_MASK ? METAL_WDOGCMP_MASK : timeout; + const long int set_timeout = + timeout > METAL_WDOGCMP_MASK ? METAL_WDOGCMP_MASK : timeout; - /* If we edit the timeout value in-place by masking the compare value to 0 and - * then writing it, we cause a spurious interrupt because the compare value - * is temporarily 0. Instead, read the value into a local variable, modify it - * there, and then write the whole register back */ + /* If we edit the timeout value in-place by masking the compare value to 0 + * and then writing it, we cause a spurious interrupt because the compare + * value is temporarily 0. Instead, read the value into a local variable, + * modify it there, and then write the whole register back */ uint32_t wdogcmp = WDOG_REGW(base, METAL_SIFIVE_WDOG0_WDOGCMP); wdogcmp &= ~(METAL_WDOGCMP_MASK); @@ -122,13 +139,15 @@ long int __metal_driver_sifive_wdog0_set_timeout(const struct metal_watchdog *co return set_timeout; } -int __metal_driver_sifive_wdog0_set_result(const struct metal_watchdog *const wdog, - const enum metal_watchdog_result result) -{ - const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); +int __metal_driver_sifive_wdog0_set_result( + const struct metal_watchdog *const wdog, + const enum metal_watchdog_result result) { + const uintptr_t base = + (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); /* Turn off reset enable and counter reset */ - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_RSTEN | METAL_WDOGCFG_ZEROCMP); + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= + ~(METAL_WDOGCFG_RSTEN | METAL_WDOGCFG_ZEROCMP); switch (result) { default: @@ -136,22 +155,26 @@ int __metal_driver_sifive_wdog0_set_result(const struct metal_watchdog *const wd break; case METAL_WATCHDOG_INTERRUPT: /* Reset counter to zero after match */ - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= METAL_WDOGCFG_ZEROCMP; + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= + METAL_WDOGCFG_ZEROCMP; break; case METAL_WATCHDOG_FULL_RESET: - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= METAL_WDOGCFG_RSTEN; + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= + METAL_WDOGCFG_RSTEN; break; } return 0; } -int __metal_driver_sifive_wdog0_run(const struct metal_watchdog *const wdog, - const enum metal_watchdog_run_option option) -{ - const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); +int __metal_driver_sifive_wdog0_run( + const struct metal_watchdog *const wdog, + const enum metal_watchdog_run_option option) { + const uintptr_t base = + (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_ENALWAYS | METAL_WDOGCFG_COREAWAKE); + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= + ~(METAL_WDOGCFG_ENALWAYS | METAL_WDOGCFG_COREAWAKE); switch (option) { default: @@ -161,32 +184,35 @@ int __metal_driver_sifive_wdog0_run(const struct metal_watchdog *const wdog, /* Feed the watchdog before starting to reset counter */ __metal_driver_sifive_wdog0_feed(wdog); - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= METAL_WDOGCFG_ENALWAYS; + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= + METAL_WDOGCFG_ENALWAYS; break; case METAL_WATCHDOG_RUN_AWAKE: /* Feed the watchdog before starting to reset counter */ __metal_driver_sifive_wdog0_feed(wdog); - WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= METAL_WDOGCFG_COREAWAKE; + WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) |= + METAL_WDOGCFG_COREAWAKE; break; } return 0; } -struct metal_interrupt *__metal_driver_sifive_wdog0_get_interrupt(const struct metal_watchdog *const wdog) -{ +struct metal_interrupt *__metal_driver_sifive_wdog0_get_interrupt( + const struct metal_watchdog *const wdog) { return __metal_driver_sifive_wdog0_interrupt_parent(wdog); } -int __metal_driver_sifive_wdog0_get_interrupt_id(const struct metal_watchdog *const wdog) -{ +int __metal_driver_sifive_wdog0_get_interrupt_id( + const struct metal_watchdog *const wdog) { return __metal_driver_sifive_wdog0_interrupt_line(wdog); } -int __metal_driver_sifive_wdog0_clear_interrupt(const struct metal_watchdog *const wdog) -{ - const uintptr_t base = (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); +int __metal_driver_sifive_wdog0_clear_interrupt( + const struct metal_watchdog *const wdog) { + const uintptr_t base = + (uintptr_t)__metal_driver_sifive_wdog0_control_base(wdog); /* Clear the interrupt pending bit */ WDOG_UNLOCK_REGW(base, METAL_SIFIVE_WDOG0_WDOGCFG) &= ~(METAL_WDOGCFG_IP); @@ -210,4 +236,3 @@ __METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_wdog0) = { #endif /* METAL_SIFIVE_WDOG0 */ typedef int no_empty_translation_units; - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/ucb_htif0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/ucb_htif0.c new file mode 100644 index 000000000..417acbf09 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/ucb_htif0.c @@ -0,0 +1,128 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include <metal/machine/platform.h> + +#ifdef METAL_UCB_HTIF0 + +#include <metal/drivers/ucb_htif0.h> +#include <metal/io.h> +#include <stddef.h> +#include <stdint.h> + +#define FINISHER_OFFSET 0 + +volatile uint64_t fromhost __attribute__((aligned(4096))); +volatile uint64_t tohost __attribute__((aligned(4096))); + +#if __riscv_xlen == 64 +#define TOHOST_CMD(dev, cmd, payload) \ + (((uint64_t)(dev) << 56) | ((uint64_t)(cmd) << 48) | (uint64_t)(payload)) +#else +#define TOHOST_CMD(dev, cmd, payload) \ + ({ \ + if ((dev) || (cmd)) \ + __builtin_trap(); \ + (payload); \ + }) +#endif +#define FROMHOST_DEV(fromhost_value) ((uint64_t)(fromhost_value) >> 56) +#define FROMHOST_CMD(fromhost_value) ((uint64_t)(fromhost_value) << 8 >> 56) +#define FROMHOST_DATA(fromhost_value) ((uint64_t)(fromhost_value) << 16 >> 16) + +static void __check_fromhost() { + uint64_t fh = fromhost; + if (!fh) + return; + fromhost = 0; +} + +static void __set_tohost(uintptr_t dev, uintptr_t cmd, uintptr_t data) { + while (tohost) + __check_fromhost(); + tohost = TOHOST_CMD(dev, cmd, data); +} + +static void do_tohost_fromhost(uintptr_t dev, uintptr_t cmd, uintptr_t data) { + __set_tohost(dev, cmd, data); + + while (1) { + uint64_t fh = fromhost; + if (fh) { + if (FROMHOST_DEV(fh) == dev && FROMHOST_CMD(fh) == cmd) { + fromhost = 0; + break; + } + __check_fromhost(); + } + } +} + +void __metal_driver_ucb_htif0_init(struct metal_uart *uart, int baud_rate) {} + +void __metal_driver_ucb_htif0_exit(const struct __metal_shutdown *sd, + int code) { + volatile uint64_t magic_mem[8]; + magic_mem[0] = 93; // SYS_exit + magic_mem[1] = code; + magic_mem[2] = 0; + magic_mem[3] = 0; + + do_tohost_fromhost(0, 0, (uintptr_t)magic_mem); + + while (1) { + // loop forever + } +} + +int __metal_driver_ucb_htif0_putc(struct metal_uart *htif, int c) { + volatile uint64_t magic_mem[8]; + magic_mem[0] = 64; // SYS_write + magic_mem[1] = 1; + magic_mem[2] = (uintptr_t)&c; + magic_mem[3] = 1; + + do_tohost_fromhost(0, 0, (uintptr_t)magic_mem); + + return 0; +} + +int __metal_driver_ucb_htif0_getc(struct metal_uart *htif, int *c) { + return -1; +} + +int __metal_driver_ucb_htif0_get_baud_rate(struct metal_uart *guart) { + return 0; +} + +int __metal_driver_ucb_htif0_set_baud_rate(struct metal_uart *guart, + int baud_rate) { + return 0; +} + +struct metal_interrupt * +__metal_driver_ucb_htif0_interrupt_controller(struct metal_uart *uart) { + return NULL; +} + +int __metal_driver_ucb_htif0_get_interrupt_id(struct metal_uart *uart) { + return -1; +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_ucb_htif0_shutdown) = { + .shutdown.exit = &__metal_driver_ucb_htif0_exit, +}; + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_ucb_htif0_uart) = { + .uart.init = __metal_driver_ucb_htif0_init, + .uart.putc = __metal_driver_ucb_htif0_putc, + .uart.getc = __metal_driver_ucb_htif0_getc, + .uart.get_baud_rate = __metal_driver_ucb_htif0_get_baud_rate, + .uart.set_baud_rate = __metal_driver_ucb_htif0_set_baud_rate, + .uart.controller_interrupt = __metal_driver_ucb_htif0_interrupt_controller, + .uart.get_interrupt_id = __metal_driver_ucb_htif0_get_interrupt_id, +}; + +#endif /* METAL_UCB_HTIF0 */ + +typedef int no_empty_translation_units; diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/entry.S b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/entry.S index 97da3fd33..b4a254f1c 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/entry.S +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/entry.S @@ -24,31 +24,55 @@ _enter: la gp, __global_pointer$ .option pop - /* Set up a simple trap vector to catch anything that goes wrong early in - * the boot process. */ - la t0, early_trap_vector + /* trap over the chicken bit register clearing, aloe & fe310 dont have it */ + la t0, 1f csrw mtvec, t0 - /* enable chicken bit if core is bullet series*/ + /* chicken bit is enable if core are sifive series. */ la t0, __metal_chicken_bit beqz t0, 1f + /* If set, always clear the feature disable register for all cores series */ csrwi 0x7C1, 0 +.align 4 1: + /* Set up a simple trap vector to catch anything that goes wrong early in + * the boot process. */ + la t0, early_trap_vector + csrw mtvec, t0 /* There may be pre-initialization routines inside the MBI code that run in - * C, so here we set up a C environment. First we set up a stack pointer, + * C, so here we set up a C environment. First we set up a stack pointer, * which is left as a weak reference in order to allow initialization * routines that do not need a stack to be set up to transparently be * called. */ .weak __metal_stack_pointer la sp, __metal_stack_pointer + /* The METAL is designed for a bare-metal environment and therefore is expected + * to define its own stack pointer. We also align the stack pointer here + * because the only RISC-V ABI that's currently defined, mandates 16-byte + * stack alignment. */ + + bne sp, zero, 1f + la sp, _sp +1: + /* Increment by hartid number of stack sizes */ + csrr a0, mhartid + li t0, 0 + la t1, __stack_size +1: + andi sp, sp, -16 + beq t0, a0, 1f + add sp, sp, t1 + addi t0, t0, 1 + j 1b +1: + /* Check for an initialization routine and call it if one exists, otherwise * just skip over the call entirely. Note that __metal_initialize isn't * actually a full C function, as it doesn't end up with the .bss or .data * segments having been initialized. This is done to avoid putting a * burden on systems that can be initialized without having a C environment * set up. */ - .weak __metal_before_start la ra, __metal_before_start beqz ra, 1f jalr ra @@ -80,18 +104,6 @@ _enter: .cfi_endproc -/* For sanity's sake we set up an early trap vector that just does nothing. If - * you end up here then there's a bug in the early boot code somewhere. */ -.section .text.metal.init.trapvec -.align 2 -early_trap_vector: - .cfi_startproc - csrr t0, mcause - csrr t1, mepc - csrr t2, mtval - j early_trap_vector - .cfi_endproc - /* The GCC port might not emit a __register_frame_info symbol, which eventually * results in a weak undefined reference that eventually causes crash when it * is dereference early in boot. We really shouldn't need to put this here, diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/gpio.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/gpio.c index 504526eb3..838590635 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/gpio.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/gpio.c @@ -1,30 +1,40 @@ /* Copyright 2019 SiFive, Inc */ /* SPDX-License-Identifier: Apache-2.0 */ -#include <metal/machine.h> #include <metal/gpio.h> +#include <metal/machine.h> -extern __inline__ int metal_gpio_disable_input(struct metal_gpio *gpio, int pin); +extern __inline__ int metal_gpio_disable_input(struct metal_gpio *gpio, + int pin); extern __inline__ int metal_gpio_enable_input(struct metal_gpio *gpio, int pin); -extern __inline__ int metal_gpio_enable_output(struct metal_gpio *gpio, int pin); -extern __inline__ int metal_gpio_disable_output(struct metal_gpio *gpio, int pin); -extern __inline__ int metal_gpio_get_output_pin(struct metal_gpio *gpio, int pin); -extern __inline__ int metal_gpio_get_input_pin(struct metal_gpio *gpio, int pin); -extern __inline__ int metal_gpio_set_pin(struct metal_gpio *, int pin, int value); +extern __inline__ int metal_gpio_enable_output(struct metal_gpio *gpio, + int pin); +extern __inline__ int metal_gpio_disable_output(struct metal_gpio *gpio, + int pin); +extern __inline__ int metal_gpio_get_output_pin(struct metal_gpio *gpio, + int pin); +extern __inline__ int metal_gpio_get_input_pin(struct metal_gpio *gpio, + int pin); +extern __inline__ int metal_gpio_set_pin(struct metal_gpio *, int pin, + int value); extern __inline__ int metal_gpio_clear_pin(struct metal_gpio *, int pin); extern __inline__ int metal_gpio_toggle_pin(struct metal_gpio *, int pin); -extern __inline__ int metal_gpio_enable_pinmux(struct metal_gpio *, int pin, int io_function); +extern __inline__ int metal_gpio_enable_pinmux(struct metal_gpio *, int pin, + int io_function); extern __inline__ int metal_gpio_disable_pinmux(struct metal_gpio *, int pin); -extern __inline__ struct metal_interrupt* metal_gpio_interrupt_controller(struct metal_gpio *gpio); -extern __inline__ int metal_gpio_get_interrupt_id(struct metal_gpio *gpio, int pin); -extern __inline__ int metal_gpio_config_interrupt(struct metal_gpio *gpio, int pin, int intr_type); -extern __inline__ int metal_gpio_clear_interrupt(struct metal_gpio *gpio, int pin, int intr_type); +extern __inline__ struct metal_interrupt * +metal_gpio_interrupt_controller(struct metal_gpio *gpio); +extern __inline__ int metal_gpio_get_interrupt_id(struct metal_gpio *gpio, + int pin); +extern __inline__ int metal_gpio_config_interrupt(struct metal_gpio *gpio, + int pin, int intr_type); +extern __inline__ int metal_gpio_clear_interrupt(struct metal_gpio *gpio, + int pin, int intr_type); -struct metal_gpio *metal_gpio_get_device(unsigned int device_num) -{ - if(device_num > __MEE_DT_MAX_GPIOS) { - return NULL; +struct metal_gpio *metal_gpio_get_device(unsigned int device_num) { + if (device_num > __MEE_DT_MAX_GPIOS) { + return NULL; } - return (struct metal_gpio *) __metal_gpio_table[device_num]; + return (struct metal_gpio *)__metal_gpio_table[device_num]; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/hpm.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/hpm.c new file mode 100644 index 000000000..2e0bc051b --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/hpm.c @@ -0,0 +1,345 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include <metal/drivers/riscv_cpu.h> +#include <metal/hpm.h> +#include <stdint.h> + +/* Macro to generate code within a switch case */ +#define METAL_HPM_HANDLE_SWITCH(m) \ + m(3) m(4) m(5) m(6) m(7) m(8) m(9) m(10) m(11) m(12) m(13) m(14) m(15) \ + m(16) m(17) m(18) m(19) m(20) m(21) m(22) m(23) m(24) m(25) m(26) \ + m(27) m(28) m(29) m(30) m(31) + +/* Macro to set values into event selector register */ +#define METAL_HPM_SET_EVENT_REG(x) \ + case METAL_HPM_COUNTER_##x: \ + __asm__ __volatile__("csrr %0, mhpmevent" #x : "=r"(val)); \ + val &= ~bitmask; \ + val |= bitmask; \ + __asm__ __volatile__("csrw mhpmevent" #x ", %0" : : "r"(val)); \ + break; + +/* Macro to set values into event selector register */ +#define METAL_HPM_CLR_EVENT_REG(x) \ + case METAL_HPM_COUNTER_##x: \ + __asm__ __volatile__("csrr %0, mhpmevent" #x : "=r"(val)); \ + val &= ~bitmask; \ + __asm__ __volatile__("csrw mhpmevent" #x ", %0" : : "r"(val)); \ + break; + +/* Macro to get values from event selector register */ +#define METAL_HPM_GET_EVENT_REG(x) \ + case METAL_HPM_COUNTER_##x: \ + __asm__ __volatile__("csrr %0, mhpmevent" #x : "=r"(val)); \ + break; + +/* Macro to read HW performance monitor counter values */ +#if __riscv_xlen == 32 +#define METAL_HPM_GET_COUNT_REG(x) \ + case METAL_HPM_COUNTER_##x: \ + do { \ + __asm__ __volatile__("csrr %0, mhpmcounter" #x "h" : "=r"(vh)); \ + __asm__ __volatile__("csrr %0, mhpmcounter" #x : "=r"(vl)); \ + __asm__ __volatile__("csrr %0, mhpmcounter" #x "h" : "=r"(vh1)); \ + } while (vh != vh1); \ + break; +#else +#define METAL_HPM_GET_COUNT_REG(x) \ + case METAL_HPM_COUNTER_##x: \ + __asm__ __volatile__("csrr %0, mhpmcounter" #x : "=r"(vl)); \ + break; +#endif + +/* Macro to clear HW performance monitor counter values */ +#if __riscv_xlen == 32 +#define METAL_HPM_CLR_COUNT_REG(x) \ + case METAL_HPM_COUNTER_##x: \ + __asm__ __volatile__("csrw mhpmcounter" #x "h, zero"); \ + __asm__ __volatile__("csrw mhpmcounter" #x ", zero"); \ + __asm__ __volatile__("csrw mhpmcounter" #x "h, zero"); \ + break; +#else +#define METAL_HPM_CLR_COUNT_REG(x) \ + case METAL_HPM_COUNTER_##x: \ + __asm__ __volatile__("csrw mhpmcounter" #x ", zero"); \ + break; +#endif + +/* Max available counters */ +#define METAL_HPM_COUNT_MAX 32 + +/* Macro to check for instruction trap */ +#define MCAUSE_ILLEGAL_INST 0x02 + +/* Return codes */ +#define METAL_HPM_RET_OK 0 +#define METAL_HPM_RET_NOK 1 + +int metal_hpm_init(struct metal_cpu *gcpu) { + struct __metal_driver_cpu *cpu = (void *)gcpu; + + /* Check if counters are initialized or pointer is NULL */ + if ((gcpu) && (cpu->hpm_count == 0)) { + metal_hpm_counter n; + + /* Count number of available hardware performance counters */ + cpu->hpm_count = METAL_HPM_COUNT_MAX; + + /* mcycle, mtime and minstret counters are always available */ + for (n = METAL_HPM_COUNTER_3; n < METAL_HPM_COUNTER_31; n++) { + metal_hpm_set_event(gcpu, n, 0xFFFFFFFF); + + if (metal_hpm_get_event(gcpu, n) == 0) { + break; + } + } + cpu->hpm_count = n; + + /* TODO: mcountinhibit csr is not yet accessible. + * As per latest RiscV privileged spec v1.11, + * mcountinhibit controls which of the counters increment. + * Unused counters can be disabled to reduce power consumption. */ + /* Keep all counters disabled, enable them later on as needed. */ + /* __asm__ __volatile__("csrw mcountinhibit, zero"); */ + + /* Clear all counters */ + for (unsigned int i = 0; i < cpu->hpm_count; i++) { + metal_hpm_clr_event(gcpu, i, 0xFFFFFFFF); + metal_hpm_clear_counter(gcpu, i); + } + } else { + return METAL_HPM_RET_NOK; + } + + return METAL_HPM_RET_OK; +} + +int metal_hpm_disable(struct metal_cpu *gcpu) { + struct __metal_driver_cpu *cpu = (void *)gcpu; + uintptr_t temp = 0, val = 0; + + /* Check if pointer is NULL */ + if (gcpu) { + /* Disable counter access */ + __asm__ __volatile__("la %0, 1f \n\t" + "csrr %1, mtvec \n\t" + "csrw mtvec, %0 \n\t" + "csrw mcounteren, zero \n\t" + ".align 4 \n\t" + "1: \n\t" + "csrw mtvec, %1 \n\t" + : "+r"(val), "+r"(temp)); + + /* TODO: Disable all counters */ + /* __asm__ __volatile__("csrw mcountinhibit, zero"); */ + + cpu->hpm_count = 0; + } else { + return METAL_HPM_RET_NOK; + } + + return METAL_HPM_RET_OK; +} + +int metal_hpm_set_event(struct metal_cpu *gcpu, metal_hpm_counter counter, + unsigned int bitmask) { + struct __metal_driver_cpu *cpu = (void *)gcpu; + unsigned int val; + + /* Return error if counter is out of range or pointer is NULL */ + if ((gcpu) && (counter >= cpu->hpm_count)) + return METAL_HPM_RET_NOK; + + switch (counter) { + /* Set event register bit mask as requested */ + METAL_HPM_HANDLE_SWITCH(METAL_HPM_SET_EVENT_REG) + + default: + break; + } + + return METAL_HPM_RET_OK; +} + +unsigned int metal_hpm_get_event(struct metal_cpu *gcpu, + metal_hpm_counter counter) { + struct __metal_driver_cpu *cpu = (void *)gcpu; + unsigned int val = 0; + + /* Return error if counter is out of range or pointer is NULL */ + if ((gcpu) && (counter >= cpu->hpm_count)) + return METAL_HPM_RET_NOK; + + switch (counter) { + /* Read event registers */ + METAL_HPM_HANDLE_SWITCH(METAL_HPM_GET_EVENT_REG) + + default: + break; + } + + return val; +} + +int metal_hpm_clr_event(struct metal_cpu *gcpu, metal_hpm_counter counter, + unsigned int bitmask) { + struct __metal_driver_cpu *cpu = (void *)gcpu; + unsigned int val; + + /* Return error if counter is out of range or pointer is NULL */ + if ((gcpu) && (counter >= cpu->hpm_count)) + return METAL_HPM_RET_NOK; + + switch (counter) { + /* Clear event registers as requested */ + METAL_HPM_HANDLE_SWITCH(METAL_HPM_CLR_EVENT_REG) + + default: + break; + } + + return METAL_HPM_RET_OK; +} + +int metal_hpm_enable_access(struct metal_cpu *gcpu, metal_hpm_counter counter) { + struct __metal_driver_cpu *cpu = (void *)gcpu; + uintptr_t temp = 0, val = 0; + + /* Return error if counter is out of range or pointer is NULL */ + if ((gcpu) && (counter >= cpu->hpm_count)) + return METAL_HPM_RET_NOK; + + /* Set trap exit, to handle illegal instruction trap. */ + __asm__ __volatile__("la %0, 1f \n\t" + "csrr %1, mtvec \n\t" + "csrw mtvec, %0 \n\t" + "csrr %0, mcounteren \n\t" + "or %0, %0, %2 \n\t" + "csrw mcounteren, %0 \n\t" + ".align 4 \n\t" + "1: \n\t" + "csrw mtvec, %1 \n\t" + : "+r"(val), "+r"(temp) + : "r"(1 << counter)); + + return METAL_HPM_RET_OK; +} + +int metal_hpm_disable_access(struct metal_cpu *gcpu, + metal_hpm_counter counter) { + struct __metal_driver_cpu *cpu = (void *)gcpu; + uintptr_t temp = 0, val = 0; + + /* Return error if counter is out of range or pointer is NULL */ + if ((gcpu) && (counter >= cpu->hpm_count)) + return METAL_HPM_RET_NOK; + + /* Set trap exit, to handle illegal instruction trap. */ + __asm__ __volatile__("la %0, 1f \n\t" + "csrr %1, mtvec \n\t" + "csrw mtvec, %0 \n\t" + "csrr %0, mcounteren \n\t" + "and %0, %0, %2 \n\t" + "csrw mcounteren, %0 \n\t" + ".align 4 \n\t" + "1: \n\t" + "csrw mtvec, %1 \n\t" + : "+r"(val), "+r"(temp) + : "r"(~(1 << counter))); + + return METAL_HPM_RET_OK; +} + +unsigned long long metal_hpm_read_counter(struct metal_cpu *gcpu, + metal_hpm_counter counter) { + struct __metal_driver_cpu *cpu = (void *)gcpu; +#if __riscv_xlen == 32 + unsigned int vh = 0, vh1 = 0, vl = 0; +#else + unsigned long long vl = 0; +#endif + + /* Return error if counter is out of range or pointer is NULL */ + if ((gcpu) && (counter >= cpu->hpm_count)) + return METAL_HPM_RET_NOK; + + switch (counter) { + case METAL_HPM_CYCLE: +#if __riscv_xlen == 32 + do { + __asm__ __volatile__("csrr %0, mcycleh" : "=r"(vh)); + __asm__ __volatile__("csrr %0, mcycle" : "=r"(vl)); + __asm__ __volatile__("csrr %0, mcycleh" : "=r"(vh1)); + } while (vh != vh1); +#else + __asm__ __volatile__("csrr %0, mcycle" : "=r"(vl)); +#endif + break; + case METAL_HPM_TIME: + /* mtime is memory mapped within CLINT block, + * Use CLINT APIs to access this register. */ + return METAL_HPM_RET_NOK; + break; + + case METAL_HPM_INSTRET: +#if __riscv_xlen == 32 + do { + __asm__ __volatile__("csrr %0, minstreth" : "=r"(vh)); + __asm__ __volatile__("csrr %0, minstret" : "=r"(vl)); + __asm__ __volatile__("csrr %0, minstreth" : "=r"(vh1)); + } while (vh != vh1); +#else + __asm__ __volatile__("csrr %0, minstret" : "=r"(vl)); +#endif + break; + METAL_HPM_HANDLE_SWITCH(METAL_HPM_GET_COUNT_REG) + + default: + break; + } + +#if __riscv_xlen == 32 + return ((((unsigned long long)vh) << 32) | vl); +#else + return vl; +#endif +} + +int metal_hpm_clear_counter(struct metal_cpu *gcpu, metal_hpm_counter counter) { + struct __metal_driver_cpu *cpu = (void *)gcpu; + /* Return error if counter is out of range or pointer is NULL */ + if ((gcpu) && (counter >= cpu->hpm_count)) + return METAL_HPM_RET_NOK; + + switch (counter) { + case METAL_HPM_CYCLE: +#if __riscv_xlen == 32 + __asm__ __volatile__("csrw mcycleh, zero"); + __asm__ __volatile__("csrw mcycle, zero"); + __asm__ __volatile__("csrw mcycleh, zero"); +#else + __asm__ __volatile__("csrw mcycle, zero"); +#endif + break; + case METAL_HPM_TIME: + /* mtime is memory mapped within CLINT block */ + return METAL_HPM_RET_NOK; + break; + case METAL_HPM_INSTRET: +#if __riscv_xlen == 32 + __asm__ __volatile__("csrw minstreth, zero"); + __asm__ __volatile__("csrw minstret, zero"); + __asm__ __volatile__("csrw minstreth, zero"); +#else + __asm__ __volatile__("csrw minstret, zero"); +#endif + break; + METAL_HPM_HANDLE_SWITCH(METAL_HPM_CLR_COUNT_REG) + + default: + break; + } + + return METAL_HPM_RET_OK; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/i2c.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/i2c.c new file mode 100644 index 000000000..6c342aa31 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/i2c.c @@ -0,0 +1,28 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include <metal/i2c.h> +#include <metal/machine.h> + +extern inline void metal_i2c_init(struct metal_i2c *i2c, unsigned int baud_rate, + metal_i2c_mode_t mode); +extern inline int metal_i2c_write(struct metal_i2c *i2c, unsigned int addr, + unsigned int len, unsigned char buf[], + metal_i2c_stop_bit_t stop_bit); +extern inline int metal_i2c_read(struct metal_i2c *i2c, unsigned int addr, + unsigned int len, unsigned char buf[], + metal_i2c_stop_bit_t stop_bit); +extern inline int metal_i2c_transfer(struct metal_i2c *i2c, unsigned int addr, + unsigned char txbuf[], unsigned int txlen, + unsigned char rxbuf[], unsigned int rxlen); +extern inline int metal_i2c_get_baud_rate(struct metal_i2c *i2c); +extern inline int metal_i2c_set_baud_rate(struct metal_i2c *i2c, int baud_rate); + +struct metal_i2c *metal_i2c_get_device(unsigned int device_num) { +#if __METAL_DT_MAX_I2CS > 0 + if (device_num < __METAL_DT_MAX_I2CS) { + return (struct metal_i2c *)__metal_i2c_table[device_num]; + } +#endif + return NULL; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/init.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/init.c new file mode 100644 index 000000000..9d98737db --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/init.c @@ -0,0 +1,72 @@ +/* Copyright 2019 SiFive Inc. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include <metal/init.h> + +/* + * These function pointers are created by the linker script + * in the .init_array section. The arrays defined by these + * and end points are the set of functions defined by instances + * of METAL_CONSTRUCTOR() and METAL_DESTRUCTOR(). + */ +extern metal_constructor_t metal_constructors_start; +extern metal_constructor_t metal_constructors_end; +extern metal_destructor_t metal_destructors_start; +extern metal_destructor_t metal_destructors_end; + +void metal_init(void) { + /* Make sure the constructors only run once */ + static int init_done = 0; + if (init_done) { + return; + } + init_done = 1; + + if (&metal_constructors_end <= &metal_constructors_start) { + return; + } + + metal_constructor_t *funcptr = &metal_constructors_start; + while (funcptr != &metal_constructors_end) { + metal_constructor_t func = *funcptr; + + func(); + + funcptr += 1; + } +} + +void metal_fini(void) { + /* Make sure the destructors only run once */ + static int fini_done = 0; + if (fini_done) { + return; + } + fini_done = 1; + + if (&metal_destructors_end <= &metal_destructors_start) { + return; + } + + metal_destructor_t *funcptr = &metal_destructors_start; + while (funcptr != &metal_destructors_end) { + metal_destructor_t func = *funcptr; + + func(); + + funcptr += 1; + } +} + +/* + * metal_init_run() and metal_fini_run() are marked weak so that users + * can redefine them for their own purposes, including to no-ops + * in the case that users don't want the metal constructors or + * destructors to run. + */ + +void metal_init_run(void) __attribute__((weak)); +void metal_init_run(void) { metal_init(); } + +void metal_fini_run(void) __attribute__((weak)); +void metal_fini_run(void) { metal_fini(); } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/interrupt.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/interrupt.c index eeb88b26f..c4a7050c5 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/interrupt.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/interrupt.c @@ -1,13 +1,12 @@ /* Copyright 2018 SiFive, Inc */ /* SPDX-License-Identifier: Apache-2.0 */ -#include <string.h> #include <metal/interrupt.h> #include <metal/machine.h> +#include <string.h> -struct metal_interrupt* metal_interrupt_get_controller (metal_intr_cntrl_type cntrl, - int id) -{ +struct metal_interrupt * +metal_interrupt_get_controller(metal_intr_cntrl_type cntrl, int id) { switch (cntrl) { case METAL_CPU_CONTROLLER: break; @@ -32,51 +31,81 @@ struct metal_interrupt* metal_interrupt_get_controller (metal_intr_cntrl_type cn extern __inline__ void metal_interrupt_init(struct metal_interrupt *controller); -extern __inline__ int metal_interrupt_set_vector_mode(struct metal_interrupt *controller, - metal_vector_mode mode); -extern __inline__ metal_vector_mode metal_interrupt_get_vector_mode(struct metal_interrupt *controller); +extern __inline__ int +metal_interrupt_set_vector_mode(struct metal_interrupt *controller, + metal_vector_mode mode); +extern __inline__ metal_vector_mode +metal_interrupt_get_vector_mode(struct metal_interrupt *controller); + +extern __inline__ int +metal_interrupt_set_privilege(struct metal_interrupt *controller, + metal_intr_priv_mode mode); +extern __inline__ metal_intr_priv_mode +metal_interrupt_get_privilege(struct metal_interrupt *controller); -extern __inline__ int metal_interrupt_set_privilege(struct metal_interrupt *controller, - metal_intr_priv_mode mode); -extern __inline__ metal_intr_priv_mode metal_interrupt_get_privilege(struct metal_interrupt *controller); +extern __inline__ int +metal_interrupt_set_threshold(struct metal_interrupt *controller, + unsigned int level); +extern __inline__ unsigned int +metal_interrupt_get_threshold(struct metal_interrupt *controller); -extern __inline__ int metal_interrupt_set_threshold(struct metal_interrupt *controller, - unsigned int level); -extern __inline__ unsigned int metal_interrupt_get_threshold(struct metal_interrupt *controller); +extern __inline__ unsigned int +metal_interrupt_get_priority(struct metal_interrupt *controller, int id); -extern __inline__ unsigned int metal_interrupt_get_priority(struct metal_interrupt *controller, int id); +extern __inline__ int +metal_interrupt_set_priority(struct metal_interrupt *controller, int id, + unsigned int priority); -extern __inline__ int metal_interrupt_set_priority(struct metal_interrupt *controller, int id, unsigned int priority); +extern __inline__ int +metal_interrupt_set_preemptive_level(struct metal_interrupt *controller, int id, + unsigned int level); -extern __inline__ int metal_interrupt_clear(struct metal_interrupt *controller, int id); +extern __inline__ unsigned int +metal_interrupt_get_preemptive_level(struct metal_interrupt *controller, + int id); -extern __inline__ int metal_interrupt_set(struct metal_interrupt *controller, int id); +extern __inline__ int metal_interrupt_clear(struct metal_interrupt *controller, + int id); -extern __inline__ int metal_interrupt_register_handler(struct metal_interrupt *controller, - int id, - metal_interrupt_handler_t handler, - void *priv); +extern __inline__ int metal_interrupt_set(struct metal_interrupt *controller, + int id); -extern __inline__ int metal_interrupt_register_vector_handler(struct metal_interrupt *controller, - int id, - metal_interrupt_vector_handler_t handler, - void *priv_data); +extern __inline__ int +metal_interrupt_register_handler(struct metal_interrupt *controller, int id, + metal_interrupt_handler_t handler, void *priv); -extern __inline__ int metal_interrupt_enable(struct metal_interrupt *controller, int id); +extern __inline__ int metal_interrupt_register_vector_handler( + struct metal_interrupt *controller, int id, + metal_interrupt_vector_handler_t handler, void *priv_data); -extern __inline__ int metal_interrupt_disable(struct metal_interrupt *controller, int id); +extern __inline__ int metal_interrupt_enable(struct metal_interrupt *controller, + int id); -extern __inline__ unsigned int metal_interrupt_get_threshold(struct metal_interrupt *controller); +extern __inline__ int +metal_interrupt_disable(struct metal_interrupt *controller, int id); -extern __inline__ int metal_interrupt_set_threshold(struct metal_interrupt *controller, unsigned int threshold); +extern __inline__ int +metal_interrupt_vector_enable(struct metal_interrupt *controller, int id); -extern __inline__ unsigned int metal_interrupt_get_priority(struct metal_interrupt *controller, int id); +extern __inline__ int +metal_interrupt_vector_disable(struct metal_interrupt *controller, int id); -extern __inline__ int metal_interrupt_set_priority(struct metal_interrupt *controller, int id, unsigned int priority); +extern __inline__ int +_metal_interrupt_command_request(struct metal_interrupt *controller, int cmd, + void *data); -extern __inline__ int metal_interrupt_vector_enable(struct metal_interrupt *controller, int id); +extern __inline__ metal_affinity +metal_interrupt_affinity_enable(struct metal_interrupt *controller, + metal_affinity bitmask, int id); -extern __inline__ int metal_interrupt_vector_disable(struct metal_interrupt *controller, int id); +extern __inline__ metal_affinity +metal_interrupt_affinity_disable(struct metal_interrupt *controller, + metal_affinity bitmask, int id); -extern __inline__ int _metal_interrupt_command_request(struct metal_interrupt *controller, - int cmd, void *data); +extern __inline__ metal_affinity +metal_interrupt_affinity_set_threshold(struct metal_interrupt *controller, + metal_affinity bitmask, + unsigned int level); +extern __inline__ unsigned int +metal_interrupt_affinity_get_threshold(struct metal_interrupt *controller, + int contextid); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/led.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/led.c index 91b74dbde..f48de663a 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/led.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/led.c @@ -1,34 +1,31 @@ /* Copyright 2018 SiFive, Inc */ /* SPDX-License-Identifier: Apache-2.0 */ -#include <string.h> #include <metal/led.h> #include <metal/machine.h> +#include <string.h> -struct metal_led* metal_led_get_rgb (char *label, char *color) -{ +struct metal_led *metal_led_get_rgb(char *label, char *color) { int i; struct metal_led *led; char led_label[100]; - if ((__METAL_DT_MAX_LEDS == 0) || - (label == NULL) || (color == NULL)) { + if ((__METAL_DT_MAX_LEDS == 0) || (label == NULL) || (color == NULL)) { return NULL; } strcpy(led_label, label); strcat(led_label, color); for (i = 0; i < __METAL_DT_MAX_LEDS; i++) { - led = (struct metal_led*)__metal_led_table[i]; + led = (struct metal_led *)__metal_led_table[i]; if (led->vtable->led_exist(led, led_label)) { - return led; - } + return led; + } } return NULL; } -struct metal_led* metal_led_get (char *label) -{ +struct metal_led *metal_led_get(char *label) { return metal_led_get_rgb(label, ""); } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/memory.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/memory.c index 05ab7ead2..c963eb629 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/memory.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/memory.c @@ -5,22 +5,25 @@ #include <metal/memory.h> struct metal_memory *metal_get_memory_from_address(const uintptr_t address) { - for(int i = 0; i < __METAL_DT_MAX_MEMORIES; i++) { - struct metal_memory *mem = __metal_memory_table[i]; + for (int i = 0; i < __METAL_DT_MAX_MEMORIES; i++) { + struct metal_memory *mem = __metal_memory_table[i]; - uintptr_t lower_bound = metal_memory_get_base_address(mem); - uintptr_t upper_bound = lower_bound + metal_memory_get_size(mem); + uintptr_t lower_bound = metal_memory_get_base_address(mem); + uintptr_t upper_bound = lower_bound + metal_memory_get_size(mem); - if((address >= lower_bound) && (address < upper_bound)) { - return mem; - } - } + if ((address >= lower_bound) && (address < upper_bound)) { + return mem; + } + } - return NULL; + return NULL; } -extern __inline__ uintptr_t metal_memory_get_base_address(const struct metal_memory *memory); -extern __inline__ size_t metal_memory_get_size(const struct metal_memory *memory); -extern __inline__ int metal_memory_supports_atomics(const struct metal_memory *memory); -extern __inline__ int metal_memory_is_cachable(const struct metal_memory *memory); - +extern __inline__ uintptr_t +metal_memory_get_base_address(const struct metal_memory *memory); +extern __inline__ size_t +metal_memory_get_size(const struct metal_memory *memory); +extern __inline__ int +metal_memory_supports_atomics(const struct metal_memory *memory); +extern __inline__ int +metal_memory_is_cachable(const struct metal_memory *memory); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/pmp.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/pmp.c index 5c2f68ada..230a6c726 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/pmp.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/pmp.c @@ -1,15 +1,14 @@ /* Copyright 2018 SiFive, Inc */ /* SPDX-License-Identifier: Apache-2.0 */ +#include <metal/cpu.h> #include <metal/machine.h> #include <metal/pmp.h> -#include <metal/cpu.h> -#define CONFIG_TO_INT(_config) (*((char *) &(_config))) -#define INT_TO_CONFIG(_int) (*((struct metal_pmp_config *)(char *) &(_int))) +#define CONFIG_TO_INT(_config) (*((char *)&(_config))) +#define INT_TO_CONFIG(_int) (*((struct metal_pmp_config *)(char *)&(_int))) -struct metal_pmp *metal_pmp_get_device(void) -{ +struct metal_pmp *metal_pmp_get_device(void) { #ifdef __METAL_DT_PMP_HANDLE return __METAL_DT_PMP_HANDLE; #else @@ -28,13 +27,13 @@ struct metal_pmp *metal_pmp_get_device(void) * in a detected granularity of 2^(10 + 2) = 4096. */ static uintptr_t _get_detected_granularity(uintptr_t address) { - if(address == 0) { - return (uintptr_t) -1; + if (address == 0) { + return (uintptr_t)-1; } /* Get the index of the least significant set bit */ int index = 0; - while(((address >> index) & 0x1) == 0) { + while (((address >> index) & 0x1) == 0) { index += 1; } @@ -55,7 +54,7 @@ static uintptr_t _get_detected_granularity(uintptr_t address) { static uintptr_t _get_pmpaddr_granularity(uintptr_t address) { /* Get the index of the least significant unset bit */ int index = 0; - while(((address >> index) & 0x1) == 1) { + while (((address >> index) & 0x1) == 1) { index += 1; } @@ -64,8 +63,7 @@ static uintptr_t _get_pmpaddr_granularity(uintptr_t address) { } /* Get the number of pmp regions for the given hart */ -int metal_pmp_num_regions(int hartid) -{ +int metal_pmp_num_regions(int hartid) { struct metal_cpu *cpu = metal_cpu_get(hartid); return __metal_driver_cpu_num_pmp_regions(cpu); @@ -77,7 +75,7 @@ static unsigned int _pmp_regions() { } void metal_pmp_init(struct metal_pmp *pmp) { - if(!pmp) { + if (!pmp) { return; } @@ -89,196 +87,167 @@ void metal_pmp_init(struct metal_pmp *pmp) { .R = 0, }; - for(unsigned int i = 0; i < _pmp_regions(); i++) { + for (unsigned int i = 0; i < _pmp_regions(); i++) { metal_pmp_set_region(pmp, i, init_config, 0); } /* Detect the region granularity by writing all 1s to pmpaddr0 while * pmpcfg0 = 0. */ - if(metal_pmp_set_address(pmp, 0, -1) != 0) { + if (metal_pmp_set_address(pmp, 0, -1) != 0) { /* Failed to detect granularity */ return; } /* Calculate the granularity based on the value that pmpaddr0 takes on */ - pmp->_granularity[metal_cpu_get_current_hartid()] = _get_detected_granularity(metal_pmp_get_address(pmp, 0)); + pmp->_granularity[metal_cpu_get_current_hartid()] = + _get_detected_granularity(metal_pmp_get_address(pmp, 0)); /* Clear pmpaddr0 */ metal_pmp_set_address(pmp, 0, 0); } -int metal_pmp_set_region(struct metal_pmp *pmp, - unsigned int region, - struct metal_pmp_config config, - size_t address) -{ +int metal_pmp_set_region(struct metal_pmp *pmp, unsigned int region, + struct metal_pmp_config config, size_t address) { struct metal_pmp_config old_config; size_t old_address; size_t cfgmask; size_t pmpcfg; int rc = 0; - if(!pmp) { + if (!pmp) { /* Device handle cannot be NULL */ return 1; } - if(region > _pmp_regions()) { + if (region > _pmp_regions()) { /* Region outside of supported range */ return 2; } - if(config.A == METAL_PMP_NA4 && pmp->_granularity[metal_cpu_get_current_hartid()] > 4) { + if (config.A == METAL_PMP_NA4 && + pmp->_granularity[metal_cpu_get_current_hartid()] > 4) { /* The requested granularity is too small */ return 3; } - if(config.A == METAL_PMP_NAPOT && - pmp->_granularity[metal_cpu_get_current_hartid()] > _get_pmpaddr_granularity(address)) - { + if (config.A == METAL_PMP_NAPOT && + pmp->_granularity[metal_cpu_get_current_hartid()] > + _get_pmpaddr_granularity(address)) { /* The requested granularity is too small */ return 3; } rc = metal_pmp_get_region(pmp, region, &old_config, &old_address); - if(rc) { + if (rc) { /* Error reading region */ return rc; } - if(old_config.L == METAL_PMP_LOCKED) { + if (old_config.L == METAL_PMP_LOCKED) { /* Cannot modify locked region */ return 4; } /* Update the address first, because if the region is being locked we won't * be able to modify it after we set the config */ - if(old_address != address) { - switch(region) { + if (old_address != address) { + switch (region) { case 0: - __asm__("csrw pmpaddr0, %[addr]" - :: [addr] "r" (address) :); + __asm__("csrw pmpaddr0, %[addr]" ::[addr] "r"(address) :); break; case 1: - __asm__("csrw pmpaddr1, %[addr]" - :: [addr] "r" (address) :); + __asm__("csrw pmpaddr1, %[addr]" ::[addr] "r"(address) :); break; case 2: - __asm__("csrw pmpaddr2, %[addr]" - :: [addr] "r" (address) :); + __asm__("csrw pmpaddr2, %[addr]" ::[addr] "r"(address) :); break; case 3: - __asm__("csrw pmpaddr3, %[addr]" - :: [addr] "r" (address) :); + __asm__("csrw pmpaddr3, %[addr]" ::[addr] "r"(address) :); break; case 4: - __asm__("csrw pmpaddr4, %[addr]" - :: [addr] "r" (address) :); + __asm__("csrw pmpaddr4, %[addr]" ::[addr] "r"(address) :); break; case 5: - __asm__("csrw pmpaddr5, %[addr]" - :: [addr] "r" (address) :); + __asm__("csrw pmpaddr5, %[addr]" ::[addr] "r"(address) :); break; case 6: - __asm__("csrw pmpaddr6, %[addr]" - :: [addr] "r" (address) :); + __asm__("csrw pmpaddr6, %[addr]" ::[addr] "r"(address) :); break; case 7: - __asm__("csrw pmpaddr7, %[addr]" - :: [addr] "r" (address) :); + __asm__("csrw pmpaddr7, %[addr]" ::[addr] "r"(address) :); break; case 8: - __asm__("csrw pmpaddr8, %[addr]" - :: [addr] "r" (address) :); + __asm__("csrw pmpaddr8, %[addr]" ::[addr] "r"(address) :); break; case 9: - __asm__("csrw pmpaddr9, %[addr]" - :: [addr] "r" (address) :); + __asm__("csrw pmpaddr9, %[addr]" ::[addr] "r"(address) :); break; case 10: - __asm__("csrw pmpaddr10, %[addr]" - :: [addr] "r" (address) :); + __asm__("csrw pmpaddr10, %[addr]" ::[addr] "r"(address) :); break; case 11: - __asm__("csrw pmpaddr11, %[addr]" - :: [addr] "r" (address) :); + __asm__("csrw pmpaddr11, %[addr]" ::[addr] "r"(address) :); break; case 12: - __asm__("csrw pmpaddr12, %[addr]" - :: [addr] "r" (address) :); + __asm__("csrw pmpaddr12, %[addr]" ::[addr] "r"(address) :); break; case 13: - __asm__("csrw pmpaddr13, %[addr]" - :: [addr] "r" (address) :); + __asm__("csrw pmpaddr13, %[addr]" ::[addr] "r"(address) :); break; case 14: - __asm__("csrw pmpaddr14, %[addr]" - :: [addr] "r" (address) :); + __asm__("csrw pmpaddr14, %[addr]" ::[addr] "r"(address) :); break; case 15: - __asm__("csrw pmpaddr15, %[addr]" - :: [addr] "r" (address) :); + __asm__("csrw pmpaddr15, %[addr]" ::[addr] "r"(address) :); break; } } -#if __riscv_xlen==32 - if(CONFIG_TO_INT(old_config) != CONFIG_TO_INT(config)) { +#if __riscv_xlen == 32 + if (CONFIG_TO_INT(old_config) != CONFIG_TO_INT(config)) { /* Mask to clear old pmpcfg */ - cfgmask = (0xFF << (8 * (region % 4)) ); - pmpcfg = (CONFIG_TO_INT(config) << (8 * (region % 4)) ); - - switch(region / 4) { + cfgmask = (0xFF << (8 * (region % 4))); + pmpcfg = (CONFIG_TO_INT(config) << (8 * (region % 4))); + + switch (region / 4) { case 0: - __asm__("csrc pmpcfg0, %[mask]" - :: [mask] "r" (cfgmask) :); + __asm__("csrc pmpcfg0, %[mask]" ::[mask] "r"(cfgmask) :); - __asm__("csrs pmpcfg0, %[cfg]" - :: [cfg] "r" (pmpcfg) :); + __asm__("csrs pmpcfg0, %[cfg]" ::[cfg] "r"(pmpcfg) :); break; case 1: - __asm__("csrc pmpcfg1, %[mask]" - :: [mask] "r" (cfgmask) :); + __asm__("csrc pmpcfg1, %[mask]" ::[mask] "r"(cfgmask) :); - __asm__("csrs pmpcfg1, %[cfg]" - :: [cfg] "r" (pmpcfg) :); + __asm__("csrs pmpcfg1, %[cfg]" ::[cfg] "r"(pmpcfg) :); break; case 2: - __asm__("csrc pmpcfg2, %[mask]" - :: [mask] "r" (cfgmask) :); + __asm__("csrc pmpcfg2, %[mask]" ::[mask] "r"(cfgmask) :); - __asm__("csrs pmpcfg2, %[cfg]" - :: [cfg] "r" (pmpcfg) :); + __asm__("csrs pmpcfg2, %[cfg]" ::[cfg] "r"(pmpcfg) :); break; case 3: - __asm__("csrc pmpcfg3, %[mask]" - :: [mask] "r" (cfgmask) :); + __asm__("csrc pmpcfg3, %[mask]" ::[mask] "r"(cfgmask) :); - __asm__("csrs pmpcfg3, %[cfg]" - :: [cfg] "r" (pmpcfg) :); + __asm__("csrs pmpcfg3, %[cfg]" ::[cfg] "r"(pmpcfg) :); break; } } -#elif __riscv_xlen==64 - if(CONFIG_TO_INT(old_config) != CONFIG_TO_INT(config)) { +#elif __riscv_xlen == 64 + if (CONFIG_TO_INT(old_config) != CONFIG_TO_INT(config)) { /* Mask to clear old pmpcfg */ - cfgmask = (0xFF << (8 * (region % 8)) ); - pmpcfg = (CONFIG_TO_INT(config) << (8 * (region % 8)) ); - - switch(region / 8) { + cfgmask = (0xFF << (8 * (region % 8))); + pmpcfg = (CONFIG_TO_INT(config) << (8 * (region % 8))); + + switch (region / 8) { case 0: - __asm__("csrc pmpcfg0, %[mask]" - :: [mask] "r" (cfgmask) :); + __asm__("csrc pmpcfg0, %[mask]" ::[mask] "r"(cfgmask) :); - __asm__("csrs pmpcfg0, %[cfg]" - :: [cfg] "r" (pmpcfg) :); + __asm__("csrs pmpcfg0, %[cfg]" ::[cfg] "r"(pmpcfg) :); break; case 1: - __asm__("csrc pmpcfg2, %[mask]" - :: [mask] "r" (cfgmask) :); + __asm__("csrc pmpcfg2, %[mask]" ::[mask] "r"(cfgmask) :); - __asm__("csrs pmpcfg2, %[cfg]" - :: [cfg] "r" (pmpcfg) :); + __asm__("csrs pmpcfg2, %[cfg]" ::[cfg] "r"(pmpcfg) :); break; } } @@ -289,59 +258,50 @@ int metal_pmp_set_region(struct metal_pmp *pmp, return 0; } -int metal_pmp_get_region(struct metal_pmp *pmp, - unsigned int region, - struct metal_pmp_config *config, - size_t *address) -{ +int metal_pmp_get_region(struct metal_pmp *pmp, unsigned int region, + struct metal_pmp_config *config, size_t *address) { size_t pmpcfg = 0; char *pmpcfg_convert = (char *)&pmpcfg; - if(!pmp || !config || !address) { + if (!pmp || !config || !address) { /* NULL pointers are invalid arguments */ return 1; } - if(region > _pmp_regions()) { + if (region > _pmp_regions()) { /* Region outside of supported range */ return 2; } -#if __riscv_xlen==32 - switch(region / 4) { +#if __riscv_xlen == 32 + switch (region / 4) { case 0: - __asm__("csrr %[cfg], pmpcfg0" - : [cfg] "=r" (pmpcfg) ::); + __asm__("csrr %[cfg], pmpcfg0" : [cfg] "=r"(pmpcfg)::); break; case 1: - __asm__("csrr %[cfg], pmpcfg1" - : [cfg] "=r" (pmpcfg) ::); + __asm__("csrr %[cfg], pmpcfg1" : [cfg] "=r"(pmpcfg)::); break; case 2: - __asm__("csrr %[cfg], pmpcfg2" - : [cfg] "=r" (pmpcfg) ::); + __asm__("csrr %[cfg], pmpcfg2" : [cfg] "=r"(pmpcfg)::); break; case 3: - __asm__("csrr %[cfg], pmpcfg3" - : [cfg] "=r" (pmpcfg) ::); + __asm__("csrr %[cfg], pmpcfg3" : [cfg] "=r"(pmpcfg)::); break; } - pmpcfg = (0xFF & (pmpcfg >> (8 * (region % 4)) ) ); + pmpcfg = (0xFF & (pmpcfg >> (8 * (region % 4)))); -#elif __riscv_xlen==64 - switch(region / 8) { +#elif __riscv_xlen == 64 + switch (region / 8) { case 0: - __asm__("csrr %[cfg], pmpcfg0" - : [cfg] "=r" (pmpcfg) ::); + __asm__("csrr %[cfg], pmpcfg0" : [cfg] "=r"(pmpcfg)::); break; case 1: - __asm__("csrr %[cfg], pmpcfg2" - : [cfg] "=r" (pmpcfg) ::); + __asm__("csrr %[cfg], pmpcfg2" : [cfg] "=r"(pmpcfg)::); break; } - pmpcfg = (0xFF & (pmpcfg >> (8 * (region % 8)) ) ); + pmpcfg = (0xFF & (pmpcfg >> (8 * (region % 8)))); #else #error XLEN is not set to supported value for PMP driver @@ -349,88 +309,71 @@ int metal_pmp_get_region(struct metal_pmp *pmp, *config = INT_TO_CONFIG(*pmpcfg_convert); - switch(region) { + switch (region) { case 0: - __asm__("csrr %[addr], pmpaddr0" - : [addr] "=r" (*address) ::); + __asm__("csrr %[addr], pmpaddr0" : [addr] "=r"(*address)::); break; case 1: - __asm__("csrr %[addr], pmpaddr1" - : [addr] "=r" (*address) ::); + __asm__("csrr %[addr], pmpaddr1" : [addr] "=r"(*address)::); break; case 2: - __asm__("csrr %[addr], pmpaddr2" - : [addr] "=r" (*address) ::); + __asm__("csrr %[addr], pmpaddr2" : [addr] "=r"(*address)::); break; case 3: - __asm__("csrr %[addr], pmpaddr3" - : [addr] "=r" (*address) ::); + __asm__("csrr %[addr], pmpaddr3" : [addr] "=r"(*address)::); break; case 4: - __asm__("csrr %[addr], pmpaddr4" - : [addr] "=r" (*address) ::); + __asm__("csrr %[addr], pmpaddr4" : [addr] "=r"(*address)::); break; case 5: - __asm__("csrr %[addr], pmpaddr5" - : [addr] "=r" (*address) ::); + __asm__("csrr %[addr], pmpaddr5" : [addr] "=r"(*address)::); break; case 6: - __asm__("csrr %[addr], pmpaddr6" - : [addr] "=r" (*address) ::); + __asm__("csrr %[addr], pmpaddr6" : [addr] "=r"(*address)::); break; case 7: - __asm__("csrr %[addr], pmpaddr7" - : [addr] "=r" (*address) ::); + __asm__("csrr %[addr], pmpaddr7" : [addr] "=r"(*address)::); break; case 8: - __asm__("csrr %[addr], pmpaddr8" - : [addr] "=r" (*address) ::); + __asm__("csrr %[addr], pmpaddr8" : [addr] "=r"(*address)::); break; case 9: - __asm__("csrr %[addr], pmpaddr9" - : [addr] "=r" (*address) ::); + __asm__("csrr %[addr], pmpaddr9" : [addr] "=r"(*address)::); break; case 10: - __asm__("csrr %[addr], pmpaddr10" - : [addr] "=r" (*address) ::); + __asm__("csrr %[addr], pmpaddr10" : [addr] "=r"(*address)::); break; case 11: - __asm__("csrr %[addr], pmpaddr11" - : [addr] "=r" (*address) ::); + __asm__("csrr %[addr], pmpaddr11" : [addr] "=r"(*address)::); break; case 12: - __asm__("csrr %[addr], pmpaddr12" - : [addr] "=r" (*address) ::); + __asm__("csrr %[addr], pmpaddr12" : [addr] "=r"(*address)::); break; case 13: - __asm__("csrr %[addr], pmpaddr13" - : [addr] "=r" (*address) ::); + __asm__("csrr %[addr], pmpaddr13" : [addr] "=r"(*address)::); break; case 14: - __asm__("csrr %[addr], pmpaddr14" - : [addr] "=r" (*address) ::); + __asm__("csrr %[addr], pmpaddr14" : [addr] "=r"(*address)::); break; case 15: - __asm__("csrr %[addr], pmpaddr15" - : [addr] "=r" (*address) ::); + __asm__("csrr %[addr], pmpaddr15" : [addr] "=r"(*address)::); break; } return 0; } -int metal_pmp_lock(struct metal_pmp *pmp, unsigned int region) -{ +int metal_pmp_lock(struct metal_pmp *pmp, unsigned int region) { struct metal_pmp_config config; size_t address; int rc = 0; rc = metal_pmp_get_region(pmp, region, &config, &address); - if(rc) { + if (rc) { return rc; } - if(config.L == METAL_PMP_LOCKED) { + if (config.L == METAL_PMP_LOCKED) { return 0; } @@ -441,15 +384,14 @@ int metal_pmp_lock(struct metal_pmp *pmp, unsigned int region) return rc; } - -int metal_pmp_set_address(struct metal_pmp *pmp, unsigned int region, size_t address) -{ +int metal_pmp_set_address(struct metal_pmp *pmp, unsigned int region, + size_t address) { struct metal_pmp_config config; size_t old_address; int rc = 0; rc = metal_pmp_get_region(pmp, region, &config, &old_address); - if(rc) { + if (rc) { return rc; } @@ -458,8 +400,7 @@ int metal_pmp_set_address(struct metal_pmp *pmp, unsigned int region, size_t add return rc; } -size_t metal_pmp_get_address(struct metal_pmp *pmp, unsigned int region) -{ +size_t metal_pmp_get_address(struct metal_pmp *pmp, unsigned int region) { struct metal_pmp_config config; size_t address = 0; @@ -468,15 +409,14 @@ size_t metal_pmp_get_address(struct metal_pmp *pmp, unsigned int region) return address; } - -int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region, enum metal_pmp_address_mode mode) -{ +int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region, + enum metal_pmp_address_mode mode) { struct metal_pmp_config config; size_t address; int rc = 0; rc = metal_pmp_get_region(pmp, region, &config, &address); - if(rc) { + if (rc) { return rc; } @@ -487,8 +427,8 @@ int metal_pmp_set_address_mode(struct metal_pmp *pmp, unsigned int region, enum return rc; } -enum metal_pmp_address_mode metal_pmp_get_address_mode(struct metal_pmp *pmp, unsigned int region) -{ +enum metal_pmp_address_mode metal_pmp_get_address_mode(struct metal_pmp *pmp, + unsigned int region) { struct metal_pmp_config config; size_t address = 0; @@ -497,15 +437,14 @@ enum metal_pmp_address_mode metal_pmp_get_address_mode(struct metal_pmp *pmp, un return config.A; } - -int metal_pmp_set_executable(struct metal_pmp *pmp, unsigned int region, int X) -{ +int metal_pmp_set_executable(struct metal_pmp *pmp, unsigned int region, + int X) { struct metal_pmp_config config; size_t address; int rc = 0; rc = metal_pmp_get_region(pmp, region, &config, &address); - if(rc) { + if (rc) { return rc; } @@ -516,8 +455,7 @@ int metal_pmp_set_executable(struct metal_pmp *pmp, unsigned int region, int X) return rc; } -int metal_pmp_get_executable(struct metal_pmp *pmp, unsigned int region) -{ +int metal_pmp_get_executable(struct metal_pmp *pmp, unsigned int region) { struct metal_pmp_config config; size_t address = 0; @@ -526,15 +464,13 @@ int metal_pmp_get_executable(struct metal_pmp *pmp, unsigned int region) return config.X; } - -int metal_pmp_set_writeable(struct metal_pmp *pmp, unsigned int region, int W) -{ +int metal_pmp_set_writeable(struct metal_pmp *pmp, unsigned int region, int W) { struct metal_pmp_config config; size_t address; int rc = 0; rc = metal_pmp_get_region(pmp, region, &config, &address); - if(rc) { + if (rc) { return rc; } @@ -545,8 +481,7 @@ int metal_pmp_set_writeable(struct metal_pmp *pmp, unsigned int region, int W) return rc; } -int metal_pmp_get_writeable(struct metal_pmp *pmp, unsigned int region) -{ +int metal_pmp_get_writeable(struct metal_pmp *pmp, unsigned int region) { struct metal_pmp_config config; size_t address = 0; @@ -555,15 +490,13 @@ int metal_pmp_get_writeable(struct metal_pmp *pmp, unsigned int region) return config.W; } - -int metal_pmp_set_readable(struct metal_pmp *pmp, unsigned int region, int R) -{ +int metal_pmp_set_readable(struct metal_pmp *pmp, unsigned int region, int R) { struct metal_pmp_config config; size_t address; int rc = 0; rc = metal_pmp_get_region(pmp, region, &config, &address); - if(rc) { + if (rc) { return rc; } @@ -574,8 +507,7 @@ int metal_pmp_set_readable(struct metal_pmp *pmp, unsigned int region, int R) return rc; } -int metal_pmp_get_readable(struct metal_pmp *pmp, unsigned int region) -{ +int metal_pmp_get_readable(struct metal_pmp *pmp, unsigned int region) { struct metal_pmp_config config; size_t address = 0; @@ -583,4 +515,3 @@ int metal_pmp_get_readable(struct metal_pmp *pmp, unsigned int region) return config.R; } - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/privilege.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/privilege.c index 54bfcfc2c..0919d77d7 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/privilege.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/privilege.c @@ -5,53 +5,51 @@ #include <metal/privilege.h> -#define METAL_MSTATUS_MIE_OFFSET 3 -#define METAL_MSTATUS_MPIE_OFFSET 7 -#define METAL_MSTATUS_SIE_OFFSET 1 -#define METAL_MSTATUS_SPIE_OFFSET 5 -#define METAL_MSTATUS_UIE_OFFSET 0 -#define METAL_MSTATUS_UPIE_OFFSET 4 +#define METAL_MSTATUS_MIE_OFFSET 3 +#define METAL_MSTATUS_MPIE_OFFSET 7 +#define METAL_MSTATUS_SIE_OFFSET 1 +#define METAL_MSTATUS_SPIE_OFFSET 5 +#define METAL_MSTATUS_UIE_OFFSET 0 +#define METAL_MSTATUS_UPIE_OFFSET 4 -#define METAL_MSTATUS_MPP_OFFSET 11 -#define METAL_MSTATUS_MPP_MASK 3 +#define METAL_MSTATUS_MPP_OFFSET 11 +#define METAL_MSTATUS_MPP_MASK 3 void metal_privilege_drop_to_mode(enum metal_privilege_mode mode, - struct metal_register_file regfile, - metal_privilege_entry_point_t entry_point) -{ - uintptr_t mstatus; - __asm__ volatile("csrr %0, mstatus" : "=r" (mstatus)); - - /* Set xPIE bits based on current xIE bits */ - if(mstatus && (1 << METAL_MSTATUS_MIE_OFFSET)) { - mstatus |= (1 << METAL_MSTATUS_MPIE_OFFSET); - } else { - mstatus &= ~(1 << METAL_MSTATUS_MPIE_OFFSET); - } - if(mstatus && (1 << METAL_MSTATUS_SIE_OFFSET)) { - mstatus |= (1 << METAL_MSTATUS_SPIE_OFFSET); - } else { - mstatus &= ~(1 << METAL_MSTATUS_SPIE_OFFSET); - } - if(mstatus && (1 << METAL_MSTATUS_UIE_OFFSET)) { - mstatus |= (1 << METAL_MSTATUS_UPIE_OFFSET); - } else { - mstatus &= ~(1 << METAL_MSTATUS_UPIE_OFFSET); - } - - /* Set MPP to the requested privilege mode */ - mstatus &= ~(METAL_MSTATUS_MPP_MASK << METAL_MSTATUS_MPP_OFFSET); - mstatus |= (mode << METAL_MSTATUS_MPP_OFFSET); - - __asm__ volatile("csrw mstatus, %0" :: "r" (mstatus)); - - /* Set the entry point in MEPC */ - __asm__ volatile("csrw mepc, %0" :: "r" (entry_point)); - - /* Set the register file */ - __asm__ volatile("mv ra, %0" :: "r" (regfile.ra)); - __asm__ volatile("mv sp, %0" :: "r" (regfile.sp)); - - __asm__ volatile("mret"); + struct metal_register_file regfile, + metal_privilege_entry_point_t entry_point) { + uintptr_t mstatus; + __asm__ volatile("csrr %0, mstatus" : "=r"(mstatus)); + + /* Set xPIE bits based on current xIE bits */ + if (mstatus & (1 << METAL_MSTATUS_MIE_OFFSET)) { + mstatus |= (1 << METAL_MSTATUS_MPIE_OFFSET); + } else { + mstatus &= ~(1 << METAL_MSTATUS_MPIE_OFFSET); + } + if (mstatus & (1 << METAL_MSTATUS_SIE_OFFSET)) { + mstatus |= (1 << METAL_MSTATUS_SPIE_OFFSET); + } else { + mstatus &= ~(1 << METAL_MSTATUS_SPIE_OFFSET); + } + if (mstatus & (1 << METAL_MSTATUS_UIE_OFFSET)) { + mstatus |= (1 << METAL_MSTATUS_UPIE_OFFSET); + } else { + mstatus &= ~(1 << METAL_MSTATUS_UPIE_OFFSET); + } + + /* Set MPP to the requested privilege mode */ + mstatus &= ~(METAL_MSTATUS_MPP_MASK << METAL_MSTATUS_MPP_OFFSET); + mstatus |= (mode << METAL_MSTATUS_MPP_OFFSET); + + __asm__ volatile("csrw mstatus, %0" ::"r"(mstatus)); + + /* Set the entry point in MEPC */ + __asm__ volatile("csrw mepc, %0" ::"r"(entry_point)); + + /* Set the register file */ + __asm__ volatile("mv ra, %0" ::"r"(regfile.ra)); + __asm__ volatile("mv sp, %0" ::"r"(regfile.sp)); + + __asm__ volatile("mret"); } - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/pwm.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/pwm.c new file mode 100644 index 000000000..15e4e6ecf --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/pwm.c @@ -0,0 +1,36 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include <metal/machine.h> +#include <metal/pwm.h> + +extern inline int metal_pwm_enable(struct metal_pwm *pwm); +extern inline int metal_pwm_disable(struct metal_pwm *pwm); +extern inline int metal_pwm_set_freq(struct metal_pwm *pwm, unsigned int idx, + unsigned int freq); +extern inline int metal_pwm_set_duty(struct metal_pwm *pwm, unsigned int idx, + unsigned int duty, + metal_pwm_phase_correct_t phase_corr); +extern inline unsigned int metal_pwm_get_duty(struct metal_pwm *pwm, + unsigned int idx); +extern inline unsigned int metal_pwm_get_freq(struct metal_pwm *pwm, + unsigned int idx); +extern inline int metal_pwm_trigger(struct metal_pwm *pwm, unsigned int idx, + metal_pwm_run_mode_t mode); +extern inline int metal_pwm_stop(struct metal_pwm *pwm, unsigned int idx); +extern inline int metal_pwm_cfg_interrupt(struct metal_pwm *pwm, + metal_pwm_interrupt_t flag); +extern inline int metal_pwm_clr_interrupt(struct metal_pwm *pwm, + unsigned int idx); +extern struct metal_interrupt * +metal_pwm_interrupt_controller(struct metal_pwm *pwm); +extern int metal_pwm_get_interrupt_id(struct metal_pwm *pwm, unsigned int idx); + +struct metal_pwm *metal_pwm_get_device(unsigned int device_num) { +#if __METAL_DT_MAX_PWMS > 0 + if (device_num < __METAL_DT_MAX_PWMS) { + return (struct metal_pwm *)__metal_pwm_table[device_num]; + } +#endif + return NULL; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/rtc.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/rtc.c index 8b79892df..ff43ec32c 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/rtc.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/rtc.c @@ -7,21 +7,25 @@ #include <stddef.h> extern inline uint64_t metal_rtc_get_rate(const struct metal_rtc *const rtc); -extern inline uint64_t metal_rtc_set_rate(const struct metal_rtc *const rtc, const uint64_t rate); +extern inline uint64_t metal_rtc_set_rate(const struct metal_rtc *const rtc, + const uint64_t rate); extern inline uint64_t metal_rtc_get_compare(const struct metal_rtc *const rtc); -extern inline uint64_t metal_rtc_set_compare(const struct metal_rtc *const rtc, const uint64_t compare); +extern inline uint64_t metal_rtc_set_compare(const struct metal_rtc *const rtc, + const uint64_t compare); extern inline uint64_t metal_rtc_get_count(const struct metal_rtc *const rtc); -extern inline uint64_t metal_rtc_set_count(const struct metal_rtc *const rtc, const uint64_t count); -extern inline int metal_rtc_run(const struct metal_rtc *const rtc, const enum metal_rtc_run_option option); -extern inline struct metal_interrupt *metal_rtc_get_interrupt(const struct metal_rtc *const rtc); +extern inline uint64_t metal_rtc_set_count(const struct metal_rtc *const rtc, + const uint64_t count); +extern inline int metal_rtc_run(const struct metal_rtc *const rtc, + const enum metal_rtc_run_option option); +extern inline struct metal_interrupt * +metal_rtc_get_interrupt(const struct metal_rtc *const rtc); extern inline int metal_rtc_get_interrupt_id(const struct metal_rtc *const rtc); struct metal_rtc *metal_rtc_get_device(int index) { #ifdef __METAL_DT_MAX_RTCS if (index < __METAL_DT_MAX_RTCS) { - return (struct metal_rtc *) __metal_rtc_table[index]; + return (struct metal_rtc *)__metal_rtc_table[index]; } #endif return NULL; } - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/scrub.S b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/scrub.S new file mode 100644 index 000000000..08b4a73dc --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/scrub.S @@ -0,0 +1,132 @@ +/* Copyright 2020 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +/* + * Scrub memory with zeroes + */ + +/* Keep it in metal.init section with _enter */ +.section .text.metal.init.scrub +/* Disable linker relaxation */ +.option push +.option norelax + +/* Function to zero-scrub specified memory + * a0 : start address for zero-scrub + * a1 : size memory region size in bytes + */ +.global metal_mem_scrub +.type metal_mem_scrub, @function +metal_mem_scrub: + + /* Disable machine interrupts, + restore previous mstatus value at exit */ + li a3, 8 + csrrc t1, mstatus, a3 + +#if __riscv_xlen == 32 + addi t0, x0, 4 +1: + blt a1, t0, 2f + andi a2, a0, 3 + beqz a2, 3f +2: + sb x0, 0(a0) + addi a0, a0, 1 + addi a1, a1, -1 + bgtz a1, 1b + csrw mstatus, t1 + ret +3: + sw x0, 0(a0) + addi a0, a0, 4 + addi a1, a1, -4 + bgtz a1, 1b + csrw mstatus, t1 + ret +#else + addi t0, x0, 8 +1: + blt a1, t0, 2f + andi a2, a0, 7 + beqz a2, 3f +2: + sb x0, 0(a0) + addi a0, a0, 1 + addi a1, a1, -1 + bgtz a1, 1b + csrw mstatus, t1 + ret +3: + sd x0, 0(a0) + addi a0, a0, 8 + addi a1, a1, -8 + bgtz a1, 1b + csrw mstatus, t1 + ret +#endif + +.type __metal_memory_scrub, @function +__metal_memory_scrub: +/* Zero out specified memory regions */ +1: +#if __riscv_xlen == 32 + sw x0, 0(t1) + addi t1, t1, 4 + blt t1, t2, 1b +#else + sd x0, 0(t1) + addi t1, t1, 8 + blt t1, t2, 1b +#endif + ret + +/* + * Initialize memories to zero + * This must be called before setting up any stack(s) + */ +.weak __metal_eccscrub_bit +.weak __metal_before_start +.global __metal_before_start +.type __metal_before_start, @function +__metal_before_start: + /* Save caller ra */ + mv s0, ra + + la t0, __metal_eccscrub_bit + beqz t0, skip_scrub + + la t0, __metal_boot_hart + csrr a5, mhartid + + /* Disable machine interrupts to be safe */ + li a3, 8 + csrc mstatus, a3 + + /* Zero out per hart stack */ + mv t1, sp + la t2, __stack_size + add t2, t2, sp + beq t1, t2, 1f + jal __metal_memory_scrub +1: + bne a5, t0, skip_scrub + + /* Zero out data segment */ + la t1, metal_segment_data_target_start + la t2, metal_segment_data_target_end + beq t1, t2, 1f + jal __metal_memory_scrub +1: + /* Zero out itim memory */ + la t1, metal_segment_itim_target_start + la t2, metal_segment_itim_target_end + beq t1, t2, skip_scrub + jal __metal_memory_scrub + +skip_scrub: + /* Restore caller ra */ + mv ra, s0 + ret + +.option pop diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/shutdown.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/shutdown.c index c3b5255a7..eadb0fb89 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/shutdown.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/shutdown.c @@ -4,19 +4,19 @@ #include <metal/machine.h> #include <metal/shutdown.h> -extern __inline__ void __metal_shutdown_exit(const struct __metal_shutdown *sd, int code); +extern __inline__ void __metal_shutdown_exit(const struct __metal_shutdown *sd, + int code); #if defined(__METAL_DT_SHUTDOWN_HANDLE) -void metal_shutdown(int code) -{ +void metal_shutdown(int code) { __metal_shutdown_exit(__METAL_DT_SHUTDOWN_HANDLE, code); } #else -#pragma message("There is no defined shutdown mechanism, metal_shutdown() will spin.") -void metal_shutdown(int code) -{ +#pragma message( \ + "There is no defined shutdown mechanism, metal_shutdown() will spin.") +void metal_shutdown(int code) { while (1) { - __asm__ volatile ("nop"); + __asm__ volatile("nop"); } } #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/spi.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/spi.c index de8cda737..19fcb9f04 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/spi.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/spi.c @@ -5,15 +5,18 @@ #include <metal/spi.h> extern __inline__ void metal_spi_init(struct metal_spi *spi, int baud_rate); -extern __inline__ int metal_spi_transfer(struct metal_spi *spi, struct metal_spi_config *config, size_t len, char *tx_buf, char *rx_buf); +extern __inline__ int metal_spi_transfer(struct metal_spi *spi, + struct metal_spi_config *config, + size_t len, char *tx_buf, + char *rx_buf); extern __inline__ int metal_spi_get_baud_rate(struct metal_spi *spi); -extern __inline__ int metal_spi_set_baud_rate(struct metal_spi *spi, int baud_rate); +extern __inline__ int metal_spi_set_baud_rate(struct metal_spi *spi, + int baud_rate); -struct metal_spi *metal_spi_get_device(unsigned int device_num) -{ +struct metal_spi *metal_spi_get_device(unsigned int device_num) { #if __METAL_DT_MAX_SPIS > 0 if (device_num < __METAL_DT_MAX_SPIS) { - return (struct metal_spi *) __metal_spi_table[device_num]; + return (struct metal_spi *)__metal_spi_table[device_num]; } #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/switch.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/switch.c index 4f17229c7..fb72d1968 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/switch.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/switch.c @@ -1,11 +1,10 @@ /* Copyright 2018 SiFive, Inc */ /* SPDX-License-Identifier: Apache-2.0 */ -#include <metal/switch.h> #include <metal/machine.h> +#include <metal/switch.h> -struct metal_switch* metal_switch_get (char *label) -{ +struct metal_switch *metal_switch_get(char *label) { int i; struct metal_switch *flip; @@ -14,7 +13,7 @@ struct metal_switch* metal_switch_get (char *label) } for (i = 0; i < __METAL_DT_MAX_BUTTONS; i++) { - flip = (struct metal_switch*)__metal_switch_table[i]; + flip = (struct metal_switch *)__metal_switch_table[i]; if (flip->vtable->switch_exist(flip, label)) { return flip; } @@ -22,6 +21,6 @@ struct metal_switch* metal_switch_get (char *label) return NULL; } -extern __inline__ struct metal_interrupt* - metal_switch_interrupt_controller(struct metal_switch *flip); +extern __inline__ struct metal_interrupt * +metal_switch_interrupt_controller(struct metal_switch *flip); extern __inline__ int metal_switch_get_interrupt_id(struct metal_switch *flip); diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/synchronize_harts.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/synchronize_harts.c index a5338e942..b1548f9b5 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/synchronize_harts.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/synchronize_harts.c @@ -1,62 +1,66 @@ /* Copyright 2019 SiFive, Inc */ /* SPDX-License-Identifier: Apache-2.0 */ +#include <metal/cpu.h> +#include <metal/io.h> #include <metal/machine.h> #include <metal/machine/platform.h> -#include <metal/io.h> -#include <metal/cpu.h> -#define METAL_REG(base, offset) (((unsigned long)(base) + (offset))) -#define METAL_REGW(base, offset) (__METAL_ACCESS_ONCE((__metal_io_u32 *)METAL_REG((base), (offset)))) -#define METAL_MSIP(base, hart) (METAL_REGW((base),4*(hart))) +#define METAL_REG(base, offset) (((unsigned long)(base) + (offset))) +#define METAL_REGW(base, offset) \ + (__METAL_ACCESS_ONCE((__metal_io_u32 *)METAL_REG((base), (offset)))) +#define METAL_MSIP(base, hart) (METAL_REGW((base), 4 * (hart))) /* * _synchronize_harts() is called by crt0.S to cause harts > 0 to wait for * hart 0 to finish copying the datat section, zeroing the BSS, and running * the libc contstructors. */ -__attribute__((section(".init"))) -void __metal_synchronize_harts() { +__attribute__((section(".init"))) void __metal_synchronize_harts() { #if __METAL_DT_MAX_HARTS > 1 int hart; - __asm__ volatile("csrr %0, mhartid" : "=r" (hart) ::); + __asm__ volatile("csrr %0, mhartid" : "=r"(hart)::); uintptr_t msip_base = 0; /* Get the base address of the MSIP registers */ #ifdef __METAL_DT_RISCV_CLINT0_HANDLE - msip_base = __metal_driver_sifive_clint0_control_base(__METAL_DT_RISCV_CLINT0_HANDLE); + msip_base = __metal_driver_sifive_clint0_control_base( + __METAL_DT_RISCV_CLINT0_HANDLE); msip_base += METAL_RISCV_CLINT0_MSIP_BASE; #elif __METAL_DT_RISCV_CLIC0_HANDLE - msip_base = __metal_driver_sifive_clic0_control_base(__METAL_DT_RISCV_CLIC0_HANDLE); + msip_base = + __metal_driver_sifive_clic0_control_base(__METAL_DT_RISCV_CLIC0_HANDLE); msip_base += METAL_RISCV_CLIC0_MSIP_BASE; #else -#pragma message(No handle for CLINT or CLIC found, harts may be unsynchronized after init!) +#pragma message(No handle for CLINT or CLIC found, \ + harts may be unsynchronized after init !) #endif /* Disable machine interrupts as a precaution */ - __asm__ volatile("csrc mstatus, %0" :: "r" (METAL_MSTATUS_MIE)); + __asm__ volatile("csrc mstatus, %0" ::"r"(METAL_MSTATUS_MIE)); if (hart == 0) { /* Hart 0 waits for all harts to set their MSIP bit */ - for (int i = 1 ; i < __METAL_DT_MAX_HARTS; i++) { - while (METAL_MSIP(msip_base, i) == 0) ; + for (int i = 1; i < __METAL_DT_MAX_HARTS; i++) { + while (METAL_MSIP(msip_base, i) == 0) + ; } /* Hart 0 clears everyone's MSIP bit */ - for (int i = 1 ; i < __METAL_DT_MAX_HARTS; i++) { + for (int i = 1; i < __METAL_DT_MAX_HARTS; i++) { METAL_MSIP(msip_base, i) = 0; } } else { /* Other harts set their MSIP bit to indicate they're ready */ METAL_MSIP(msip_base, hart) = 1; - __asm__ volatile ("fence w,rw"); + __asm__ volatile("fence w,rw"); /* Wait for hart 0 to clear the MSIP bit */ - while (METAL_MSIP(msip_base, hart) == 1) ; + while (METAL_MSIP(msip_base, hart) == 1) + ; } #endif /* __METAL_DT_MAX_HARTS > 1 */ } - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/time.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/time.c index 529f8bd56..a40a3ced0 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/time.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/time.c @@ -4,14 +4,17 @@ #include <metal/time.h> #include <metal/timer.h> -int metal_gettimeofday(struct timeval *tp, void *tzp) -{ +#include <stddef.h> + +int metal_gettimeofday(struct timeval *tp, void *tzp) { int rv; unsigned long long mcc, timebase; - if ((rv = metal_timer_get_cyclecount(0, &mcc))) { + rv = metal_timer_get_cyclecount(0, &mcc); + if (rv != 0) { return -1; } - if ((rv = metal_timer_get_timebase_frequency(0, &timebase))) { + rv = metal_timer_get_timebase_frequency(0, &timebase); + if (rv != 0) { return -1; } tp->tv_sec = mcc / timebase; @@ -19,12 +22,11 @@ int metal_gettimeofday(struct timeval *tp, void *tzp) return 0; } -time_t metal_time (void) -{ +time_t metal_time(void) { struct timeval now; if (metal_gettimeofday(&now, NULL) < 0) - now.tv_sec = (time_t) -1; + now.tv_sec = (time_t)-1; - return now.tv_sec; + return now.tv_sec; } diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/timer.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/timer.c index f58413321..8e5859aa5 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/timer.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/timer.c @@ -1,80 +1,83 @@ /* Copyright 2018 SiFive, Inc */ /* SPDX-License-Identifier: Apache-2.0 */ -#include <sys/time.h> -#include <sys/times.h> #include <metal/cpu.h> -#include <metal/timer.h> #include <metal/machine.h> +#include <metal/timer.h> +#ifndef __SEGGER_LIBC__ +#include <sys/time.h> +#include <sys/times.h> +#endif #if defined(__METAL_DT_MAX_HARTS) /* This implementation serves as a small shim that interfaces with the first * timer on a system. */ -int metal_timer_get_cyclecount(int hartid, unsigned long long *mcc) -{ +int metal_timer_get_cyclecount(int hartid, unsigned long long *mcc) { struct metal_cpu *cpu = metal_cpu_get(hartid); - if ( cpu ) { + if (cpu) { *mcc = metal_cpu_get_timer(cpu); return 0; - } + } return -1; } -int metal_timer_get_timebase_frequency(int hartid, unsigned long long *timebase) -{ +int metal_timer_get_timebase_frequency(int hartid, + unsigned long long *timebase) { struct metal_cpu *cpu = metal_cpu_get(hartid); - if ( cpu ) { + if (cpu) { *timebase = metal_cpu_get_timebase(cpu); return 0; - } + } return -1; } -int metal_timer_get_machine_time(int hartid) -{ +int metal_timer_get_machine_time(int hartid) { struct metal_cpu *cpu = metal_cpu_get(hartid); - - if ( cpu ) { - return metal_cpu_get_mtime(cpu); + + if (cpu) { + return metal_cpu_get_mtime(cpu); } return 0; } -int metal_timer_set_machine_time(int hartid, unsigned long long time) -{ +int metal_timer_set_machine_time(int hartid, unsigned long long time) { struct metal_cpu *cpu = metal_cpu_get(hartid); - if ( cpu ) { - return metal_cpu_set_mtimecmp(cpu, time); + if (cpu) { + return metal_cpu_set_mtimecmp(cpu, time); } return -1; } #else -/* This implementation of gettimeofday doesn't actually do anything, it's just there to - * provide a shim and return 0 so we can ensure that everything can link to _gettimeofday. +/* This implementation of gettimeofday doesn't actually do anything, it's just + * there to provide a shim and return 0 so we can ensure that everything can + * link to _gettimeofday. */ -int nop_cyclecount(int id, unsigned long long *c) __attribute__((section(".text.metal.nop.cyclecount"))); +int nop_cyclecount(int id, unsigned long long *c) + __attribute__((section(".text.metal.nop.cyclecount"))); int nop_cyclecount(int id, unsigned long long *c) { return -1; } -int nop_timebase(unsigned long long *t) __attribute__((section(".text.metal.nop.timebase"))); +int nop_timebase(unsigned long long *t) + __attribute__((section(".text.metal.nop.timebase"))); int nop_timebase(unsigned long long *t) { return -1; } int nop_tick(int second) __attribute__((section(".text.metal.nop.tick"))); int nop_tick(int second) { return -1; } -int metal_timer_get_cyclecount(int hartid, unsigned long long *c) __attribute__((weak, alias("nop_cyclecount"))) -{ -#pragma message("There is no default timer device, metal_timer_get_cyclecount() will always return cyclecount -1.") +int metal_timer_get_cyclecount(int hartid, unsigned long long *c) + __attribute__((weak, alias("nop_cyclecount"))) { +#pragma message( \ + "There is no default timer device, metal_timer_get_cyclecount() will always return cyclecount -1.") } -int metal_timer_get_timebase_frequency(unsigned long long *t) __attribute__((weak, alias("nop_timebase"))) -{ -#pragma message("There is no default timer device, metal_timer_get_timebase_frequency() will always return timebase -1.") +int metal_timer_get_timebase_frequency(unsigned long long *t) + __attribute__((weak, alias("nop_timebase"))) { +#pragma message( \ + "There is no default timer device, metal_timer_get_timebase_frequency() will always return timebase -1.") } -int metal_timer_set_tick(int second) __attribute__((weak, alias("nop_tick"))) -{ -#pragma message("There is no default timer device, metal_timer_set_tick) will always return -1.") +int metal_timer_set_tick(int second) __attribute__((weak, alias("nop_tick"))) { +#pragma message( \ + "There is no default timer device, metal_timer_set_tick) will always return -1.") } #endif - diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/trap.S b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/trap.S index b55b6656a..7d12d640f 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/trap.S +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/trap.S @@ -51,3 +51,18 @@ _metal_trap: /* Jump to mtvec */ jr t0 + +/* + * For sanity's sake we set up an early trap vector that just does nothing. + * If you end up here then there's a bug in the early boot code somewhere. + */ +.section .text.metal.init.trapvec +.global early_trap_vector +.align 2 +early_trap_vector: + .cfi_startproc + csrr t0, mcause + csrr t1, mepc + csrr t2, mtval + j early_trap_vector + .cfi_endproc diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/tty.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/tty.c index 306192451..e5ffdb260 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/tty.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/tty.c @@ -1,33 +1,23 @@ /* Copyright 2018 SiFive, Inc */ /* SPDX-License-Identifier: Apache-2.0 */ -#include <metal/uart.h> -#include <metal/tty.h> +#include <metal/init.h> #include <metal/machine.h> +#include <metal/tty.h> +#include <metal/uart.h> #if defined(__METAL_DT_STDOUT_UART_HANDLE) /* This implementation serves as a small shim that interfaces with the first * UART on a system. */ -int metal_tty_putc(int c) -{ - if (c == '\n') { - metal_tty_putc_raw( '\r' ); - } - return metal_tty_putc_raw( c ); -} - -int metal_tty_putc_raw(int c) -{ +int metal_tty_putc(int c) { return metal_uart_putc(__METAL_DT_STDOUT_UART_HANDLE, c); } -int metal_tty_getc(int *c) -{ - do { - metal_uart_getc( __METAL_DT_STDOUT_UART_HANDLE, c ); +int metal_tty_getc(int *c) { + do { + metal_uart_getc(__METAL_DT_STDOUT_UART_HANDLE, c); /* -1 means no key pressed, getc waits */ - } while( -1 == *c ) - ; + } while (-1 == *c); return 0; } @@ -35,9 +25,7 @@ int metal_tty_getc(int *c) #define __METAL_DT_STDOUT_UART_BAUD 115200 #endif -static void metal_tty_init(void) __attribute__((constructor)); -static void metal_tty_init(void) -{ +METAL_CONSTRUCTOR(metal_tty_init) { metal_uart_init(__METAL_DT_STDOUT_UART_HANDLE, __METAL_DT_STDOUT_UART_BAUD); } #else @@ -45,7 +33,20 @@ static void metal_tty_init(void) * provide a shim that eats all the characters so we can ensure that everything * can link to metal_tty_putc. */ int nop_putc(int c) __attribute__((section(".text.metal.nop.putc"))); -int nop_putc(int c) { return -1; } +// Use a customizable NOP hint instruction so that a post-processor parser can +// look for this instruction, and use the value in a0 as the character to be +// printed. +int nop_putc(int c) { + // The ABI states that c will be passed in a0. However, under an LTO + // (link-time-optimizer), it may choose to optimize in ways that would + // break this assumption. We want to ensure that the passed argument is + // truly in a0, for easier post-processing, and so there is a single + // 32-bit opcode to match against. + // So explicitly ensure that the argument is placed into a0 first. + __asm__ volatile("mv a0, %0; slli x0,a0,0x11" ::"r"(c)); + return -1; +} int metal_tty_putc(int c) __attribute__((weak, alias("nop_putc"))); -#pragma message("There is no default output device, metal_tty_putc() will throw away all input.") +#pragma message( \ + "There is no default output device, metal_tty_putc() will throw away all input.") #endif diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/uart.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/uart.c index 8981eb8d3..753e5b430 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/uart.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/uart.c @@ -1,6 +1,7 @@ /* Copyright 2018 SiFive, Inc */ /* SPDX-License-Identifier: Apache-2.0 */ +#include <metal/machine.h> #include <metal/uart.h> extern __inline__ void metal_uart_init(struct metal_uart *uart, int baud_rate); @@ -8,4 +9,34 @@ extern __inline__ int metal_uart_putc(struct metal_uart *uart, int c); extern __inline__ int metal_uart_txready(struct metal_uart *uart); extern __inline__ int metal_uart_getc(struct metal_uart *uart, int *c); extern __inline__ int metal_uart_get_baud_rate(struct metal_uart *uart); -extern __inline__ int metal_uart_set_baud_rate(struct metal_uart *uart, int baud_rate); +extern __inline__ int metal_uart_set_baud_rate(struct metal_uart *uart, + int baud_rate); +extern __inline__ struct metal_interrupt * +metal_uart_interrupt_controller(struct metal_uart *uart); +extern __inline__ int metal_uart_get_interrupt_id(struct metal_uart *uart); +extern __inline__ int +metal_uart_transmit_interrupt_enable(struct metal_uart *uart); +extern __inline__ int +metal_uart_transmit_interrupt_disable(struct metal_uart *uart); +extern __inline__ int +metal_uart_receive_interrupt_enable(struct metal_uart *uart); +extern __inline__ int +metal_uart_receive_interrupt_disable(struct metal_uart *uart); +extern __inline__ int metal_uart_set_transmit_watermark(struct metal_uart *uart, + size_t level); +extern __inline__ size_t +metal_uart_get_transmit_watermark(struct metal_uart *uart); +extern __inline__ int metal_uart_set_receive_watermark(struct metal_uart *uart, + size_t level); +extern __inline__ size_t +metal_uart_get_receive_watermark(struct metal_uart *uart); + +struct metal_uart *metal_uart_get_device(unsigned int device_num) { +#if __METAL_DT_MAX_UARTS > 0 + if (device_num < __METAL_DT_MAX_UARTS) { + return (struct metal_uart *)__metal_uart_table[device_num]; + } +#endif + + return NULL; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/watchdog.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/watchdog.c new file mode 100644 index 000000000..5e9bc4965 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/watchdog.c @@ -0,0 +1,37 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include <metal/machine.h> +#include <metal/watchdog.h> + +extern inline int metal_watchdog_feed(const struct metal_watchdog *const wdog); +extern inline long int +metal_watchdog_get_rate(const struct metal_watchdog *const wdog); +extern inline long int +metal_watchdog_set_rate(const struct metal_watchdog *const wdog, + const long int rate); +extern inline long int +metal_watchdog_get_timeout(const struct metal_watchdog *const wdog); +extern inline long int +metal_watchdog_set_timeout(const struct metal_watchdog *const wdog, + const long int timeout); +extern inline int +metal_watchdog_set_result(const struct metal_watchdog *const wdog, + const enum metal_watchdog_result result); +extern inline int +metal_watchdog_run(const struct metal_watchdog *const wdog, + const enum metal_watchdog_run_option option); +extern inline struct metal_interrupt * +metal_watchdog_get_interrupt(const struct metal_watchdog *const wdog); +extern inline int +metal_watchdog_get_interrupt_id(const struct metal_watchdog *const wdog); +extern inline int +metal_watchdog_clear_interrupt(const struct metal_watchdog *const wdog); + +struct metal_watchdog *metal_watchdog_get_device(const int index) { + if (index > __METAL_DT_MAX_WDOGS) { + return NULL; + } + + return (struct metal_watchdog *)__metal_wdog_table[index]; +} diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/full_demo/RegTest.S b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/full_demo/RegTest.S index 1ae58c4e0..daa68f191 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/full_demo/RegTest.S +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/full_demo/RegTest.S @@ -1,266 +1,266 @@ -/*
- * FreeRTOS V202104.00
- * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
- .extern ulRegTest1LoopCounter
- .extern ulRegTest2LoopCounter
-
- .global vRegTest1Implementation
- .global vRegTest2Implementation
-
-/*-----------------------------------------------------------*/
-
-/*
- * The register check tasks are described in the comments at the top of
- * main_full.c.
- */
-
-.align( 4 )
-vRegTest1Implementation:
-
- /* Fill the core registers with known values. */
- li x5, 0x5
- li x6, 0x6
- li x7, 0x7
- li x8, 0x8
- li x9, 0x9
- li x10, 0xa
- li x11, 0xb
- li x12, 0xc
- li x13, 0xd
- li x14, 0xe
- li x15, 0xf
- li x16, 0x10
- li x17, 0x11
- li x18, 0x12
- li x19, 0x13
- li x20, 0x14
- li x21, 0x15
- li x22, 0x16
- li x23, 0x17
- li x24, 0x18
- li x25, 0x19
- li x26, 0x1a
- li x27, 0x1b
- li x28, 0x1c
- li x29, 0x1d
- li x30, 0x1e
-
-reg1_loop:
-
- /* Check each register still contains the expected known value.
- vRegTest1Implementation uses x31 as the temporary, vRegTest2Implementation
- uses x5 as the temporary. */
- li x31, 0x5
- bne x31, x5, reg1_error_loop
- li x31, 0x6
- bne x31, x6, reg1_error_loop
- li x31, 0x7
- bne x31, x7, reg1_error_loop
- li x31, 0x8
- bne x31, x8, reg1_error_loop
- li x31, 0x9
- bne x31, x9, reg1_error_loop
- li x31, 0xa
- bne x31, x10, reg1_error_loop
- li x31, 0xb
- bne x31, x11, reg1_error_loop
- li x31, 0xc
- bne x31, x12, reg1_error_loop
- li x31, 0xd
- bne x31, x13, reg1_error_loop
- li x31, 0xe
- bne x31, x14, reg1_error_loop
- li x31, 0xf
- bne x31, x15, reg1_error_loop
- li x31, 0x10
- bne x31, x16, reg1_error_loop
- li x31, 0x11
- bne x31, x17, reg1_error_loop
- li x31, 0x12
- bne x31, x18, reg1_error_loop
- li x31, 0x13
- bne x31, x19, reg1_error_loop
- li x31, 0x14
- bne x31, x20, reg1_error_loop
- li x31, 0x15
- bne x31, x21, reg1_error_loop
- li x31, 0x16
- bne x31, x22, reg1_error_loop
- li x31, 0x17
- bne x31, x23, reg1_error_loop
- li x31, 0x18
- bne x31, x24, reg1_error_loop
- li x31, 0x19
- bne x31, x25, reg1_error_loop
- li x31, 0x1a
- bne x31, x26, reg1_error_loop
- li x31, 0x1b
- bne x31, x27, reg1_error_loop
- li x31, 0x1c
- bne x31, x28, reg1_error_loop
- li x31, 0x1d
- bne x31, x29, reg1_error_loop
- li x31, 0x1e
- bne x31, x30, reg1_error_loop
-
- /* Everything passed, increment the loop counter. */
- lw x31, ulRegTest1LoopCounterConst
- lw x30, 0(x31)
- addi x30, x30, 1
- sw x30, 0(x31)
-
- /* Restore clobbered register reading for next loop. */
- li x30, 0x1e
-
- /* Yield to increase code coverage. */
- ecall
-
- /* Start again. */
- jal reg1_loop
-
-reg1_error_loop:
- /* Jump here if a register contains an uxpected value. This stops the loop
- counter being incremented so the check task knows an error was found. */
- ebreak
- jal reg1_error_loop
-
-.align( 4 )
-ulRegTest1LoopCounterConst: .word ulRegTest1LoopCounter
-
-/*-----------------------------------------------------------*/
-
-.align( 4 )
-vRegTest2Implementation:
-
- /* Fill the core registers with known values. */
- li x6, 0x61
- li x7, 0x71
- li x8, 0x81
- li x9, 0x91
- li x10, 0xa1
- li x11, 0xb1
- li x12, 0xc1
- li x13, 0xd1
- li x14, 0xe1
- li x15, 0xf1
- li x16, 0x20
- li x17, 0x21
- li x18, 0x22
- li x19, 0x23
- li x20, 0x24
- li x21, 0x25
- li x22, 0x26
- li x23, 0x27
- li x24, 0x28
- li x25, 0x29
- li x26, 0x2a
- li x27, 0x2b
- li x28, 0x2c
- li x29, 0x2d
- li x30, 0x2e
- li x31, 0x2f
-
-Reg2_loop:
-
- /* Check each register still contains the expected known value.
- vRegTest2Implementation uses x5 as the temporary, vRegTest1Implementation
- uses x31 as the temporary. */
- li x5, 0x61
- bne x5, x6, reg2_error_loop
- li x5, 0x71
- bne x5, x7, reg2_error_loop
- li x5, 0x81
- bne x5, x8, reg2_error_loop
- li x5, 0x91
- bne x5, x9, reg2_error_loop
- li x5, 0xa1
- bne x5, x10, reg2_error_loop
- li x5, 0xb1
- bne x5, x11, reg2_error_loop
- li x5, 0xc1
- bne x5, x12, reg2_error_loop
- li x5, 0xd1
- bne x5, x13, reg2_error_loop
- li x5, 0xe1
- bne x5, x14, reg2_error_loop
- li x5, 0xf1
- bne x5, x15, reg2_error_loop
- li x5, 0x20
- bne x5, x16, reg2_error_loop
- li x5, 0x21
- bne x5, x17, reg2_error_loop
- li x5, 0x22
- bne x5, x18, reg2_error_loop
- li x5, 0x23
- bne x5, x19, reg2_error_loop
- li x5, 0x24
- bne x5, x20, reg2_error_loop
- li x5, 0x25
- bne x5, x21, reg2_error_loop
- li x5, 0x26
- bne x5, x22, reg2_error_loop
- li x5, 0x27
- bne x5, x23, reg2_error_loop
- li x5, 0x28
- bne x5, x24, reg2_error_loop
- li x5, 0x29
- bne x5, x25, reg2_error_loop
- li x5, 0x2a
- bne x5, x26, reg2_error_loop
- li x5, 0x2b
- bne x5, x27, reg2_error_loop
- li x5, 0x2c
- bne x5, x28, reg2_error_loop
- li x5, 0x2d
- bne x5, x29, reg2_error_loop
- li x5, 0x2e
- bne x5, x30, reg2_error_loop
- li x5, 0x2f
- bne x5, x31, reg2_error_loop
-
- /* Everything passed, increment the loop counter. */
- lw x5, ulRegTest2LoopCounterConst
- lw x6, 0(x5)
- addi x6, x6, 1
- sw x6, 0(x5)
-
- /* Restore clobbered register reading for next loop. */
- li x6, 0x61
-
- /* Start again. */
- jal Reg2_loop
-
-reg2_error_loop:
- /* Jump here if a register contains an uxpected value. This stops the loop
- counter being incremented so the check task knows an error was found. */
- ebreak
- jal reg2_error_loop
-
-.align( 4 )
-ulRegTest2LoopCounterConst: .word ulRegTest2LoopCounter
-
-
+/* + * FreeRTOS V202104.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + .extern ulRegTest1LoopCounter + .extern ulRegTest2LoopCounter + + .global vRegTest1Implementation + .global vRegTest2Implementation + +/*-----------------------------------------------------------*/ + +/* + * The register check tasks are described in the comments at the top of + * main_full.c. + */ + +.align( 4 ) +vRegTest1Implementation: + + /* Fill the core registers with known values. */ + li x5, 0x5 + li x6, 0x6 + li x7, 0x7 + li x8, 0x8 + li x9, 0x9 + li x10, 0xa + li x11, 0xb + li x12, 0xc + li x13, 0xd + li x14, 0xe + li x15, 0xf + li x16, 0x10 + li x17, 0x11 + li x18, 0x12 + li x19, 0x13 + li x20, 0x14 + li x21, 0x15 + li x22, 0x16 + li x23, 0x17 + li x24, 0x18 + li x25, 0x19 + li x26, 0x1a + li x27, 0x1b + li x28, 0x1c + li x29, 0x1d + li x30, 0x1e + +reg1_loop: + + /* Check each register still contains the expected known value. + vRegTest1Implementation uses x31 as the temporary, vRegTest2Implementation + uses x5 as the temporary. */ + li x31, 0x5 + bne x31, x5, reg1_error_loop + li x31, 0x6 + bne x31, x6, reg1_error_loop + li x31, 0x7 + bne x31, x7, reg1_error_loop + li x31, 0x8 + bne x31, x8, reg1_error_loop + li x31, 0x9 + bne x31, x9, reg1_error_loop + li x31, 0xa + bne x31, x10, reg1_error_loop + li x31, 0xb + bne x31, x11, reg1_error_loop + li x31, 0xc + bne x31, x12, reg1_error_loop + li x31, 0xd + bne x31, x13, reg1_error_loop + li x31, 0xe + bne x31, x14, reg1_error_loop + li x31, 0xf + bne x31, x15, reg1_error_loop + li x31, 0x10 + bne x31, x16, reg1_error_loop + li x31, 0x11 + bne x31, x17, reg1_error_loop + li x31, 0x12 + bne x31, x18, reg1_error_loop + li x31, 0x13 + bne x31, x19, reg1_error_loop + li x31, 0x14 + bne x31, x20, reg1_error_loop + li x31, 0x15 + bne x31, x21, reg1_error_loop + li x31, 0x16 + bne x31, x22, reg1_error_loop + li x31, 0x17 + bne x31, x23, reg1_error_loop + li x31, 0x18 + bne x31, x24, reg1_error_loop + li x31, 0x19 + bne x31, x25, reg1_error_loop + li x31, 0x1a + bne x31, x26, reg1_error_loop + li x31, 0x1b + bne x31, x27, reg1_error_loop + li x31, 0x1c + bne x31, x28, reg1_error_loop + li x31, 0x1d + bne x31, x29, reg1_error_loop + li x31, 0x1e + bne x31, x30, reg1_error_loop + + /* Everything passed, increment the loop counter. */ + lw x31, ulRegTest1LoopCounterConst + lw x30, 0(x31) + addi x30, x30, 1 + sw x30, 0(x31) + + /* Restore clobbered register reading for next loop. */ + li x30, 0x1e + + /* Yield to increase code coverage. */ + ecall + + /* Start again. */ + jal reg1_loop + +reg1_error_loop: + /* Jump here if a register contains an uxpected value. This stops the loop + counter being incremented so the check task knows an error was found. */ + ebreak + jal reg1_error_loop + +.align( 4 ) +ulRegTest1LoopCounterConst: .word ulRegTest1LoopCounter + +/*-----------------------------------------------------------*/ + +.align( 4 ) +vRegTest2Implementation: + + /* Fill the core registers with known values. */ + li x6, 0x61 + li x7, 0x71 + li x8, 0x81 + li x9, 0x91 + li x10, 0xa1 + li x11, 0xb1 + li x12, 0xc1 + li x13, 0xd1 + li x14, 0xe1 + li x15, 0xf1 + li x16, 0x20 + li x17, 0x21 + li x18, 0x22 + li x19, 0x23 + li x20, 0x24 + li x21, 0x25 + li x22, 0x26 + li x23, 0x27 + li x24, 0x28 + li x25, 0x29 + li x26, 0x2a + li x27, 0x2b + li x28, 0x2c + li x29, 0x2d + li x30, 0x2e + li x31, 0x2f + +Reg2_loop: + + /* Check each register still contains the expected known value. + vRegTest2Implementation uses x5 as the temporary, vRegTest1Implementation + uses x31 as the temporary. */ + li x5, 0x61 + bne x5, x6, reg2_error_loop + li x5, 0x71 + bne x5, x7, reg2_error_loop + li x5, 0x81 + bne x5, x8, reg2_error_loop + li x5, 0x91 + bne x5, x9, reg2_error_loop + li x5, 0xa1 + bne x5, x10, reg2_error_loop + li x5, 0xb1 + bne x5, x11, reg2_error_loop + li x5, 0xc1 + bne x5, x12, reg2_error_loop + li x5, 0xd1 + bne x5, x13, reg2_error_loop + li x5, 0xe1 + bne x5, x14, reg2_error_loop + li x5, 0xf1 + bne x5, x15, reg2_error_loop + li x5, 0x20 + bne x5, x16, reg2_error_loop + li x5, 0x21 + bne x5, x17, reg2_error_loop + li x5, 0x22 + bne x5, x18, reg2_error_loop + li x5, 0x23 + bne x5, x19, reg2_error_loop + li x5, 0x24 + bne x5, x20, reg2_error_loop + li x5, 0x25 + bne x5, x21, reg2_error_loop + li x5, 0x26 + bne x5, x22, reg2_error_loop + li x5, 0x27 + bne x5, x23, reg2_error_loop + li x5, 0x28 + bne x5, x24, reg2_error_loop + li x5, 0x29 + bne x5, x25, reg2_error_loop + li x5, 0x2a + bne x5, x26, reg2_error_loop + li x5, 0x2b + bne x5, x27, reg2_error_loop + li x5, 0x2c + bne x5, x28, reg2_error_loop + li x5, 0x2d + bne x5, x29, reg2_error_loop + li x5, 0x2e + bne x5, x30, reg2_error_loop + li x5, 0x2f + bne x5, x31, reg2_error_loop + + /* Everything passed, increment the loop counter. */ + lw x5, ulRegTest2LoopCounterConst + lw x6, 0(x5) + addi x6, x6, 1 + sw x6, 0(x5) + + /* Restore clobbered register reading for next loop. */ + li x6, 0x61 + + /* Start again. */ + jal Reg2_loop + +reg2_error_loop: + /* Jump here if a register contains an uxpected value. This stops the loop + counter being incremented so the check task knows an error was found. */ + ebreak + jal reg2_error_loop + +.align( 4 ) +ulRegTest2LoopCounterConst: .word ulRegTest2LoopCounter + + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/full_demo/main_full.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/full_demo/main_full.c index d5b1d012b..f47e67962 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/full_demo/main_full.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/full_demo/main_full.c @@ -1,306 +1,313 @@ -/*
- * FreeRTOS V202104.00
- * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-/******************************************************************************
- * NOTE 1: This project provides two demo applications. A simple blinky style
- * project, and a more comprehensive test and demo application. The
- * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select
- * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY
- * in main.c. This file implements the comprehensive test and demo version.
- *
- * NOTE 2: This file only contains the source code that is specific to the
- * full demo. Generic functions, such FreeRTOS hook functions, and functions
- * required to configure the hardware, are defined in main.c.
- *
- ******************************************************************************
- *
- * main_full() creates all the demo application tasks and software timers, then
- * starts the scheduler. The web documentation provides more details of the
- * standard demo application tasks, which provide no particular functionality,
- * but do provide a good example of how to use the FreeRTOS API.
- *
- * In addition to the standard demo tasks, the following tasks and tests are
- * defined and/or created within this file:
- *
- * "Reg test" tasks - These fill both the core registers with known values, then
- * check that each register maintains its expected value for the lifetime of the
- * task. Each task uses a different set of values. The reg test tasks execute
- * with a very low priority, so get preempted very frequently. A register
- * containing an unexpected value is indicative of an error in the context
- * switching mechanism.
- *
- * "Check" task - The check executes every three seconds. It checks that all
- * the standard demo tasks, and the register check tasks, are not only still
- * executing, but are executing without reporting any errors. The check task
- * toggles the LED every three seconds if all the standard demo tasks are
- * executing as expected, or every 500ms if a potential error is discovered in
- * any task.
- */
-
-/* Standard includes. */
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-/* Kernel includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "timers.h"
-#include "semphr.h"
-
-/* Standard demo application includes. */
-#include "dynamic.h"
-#include "blocktim.h"
-#include "TimerDemo.h"
-#include "TaskNotify.h"
-
-/* Priorities for the demo application tasks. */
-#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
-
-/* The period of the check task, in ms, converted to ticks using the
-pdMS_TO_TICKS() macro. mainNO_ERROR_CHECK_TASK_PERIOD is used if no errors have
-been found, mainERROR_CHECK_TASK_PERIOD is used if an error has been found. */
-#define mainNO_ERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 3000UL )
-#define mainERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 500UL )
-
-/* Parameters that are passed into the register check tasks solely for the
-purpose of ensuring parameters are passed into tasks correctly. */
-#define mainREG_TEST_TASK_1_PARAMETER ( ( void * ) 0x12345678 )
-#define mainREG_TEST_TASK_2_PARAMETER ( ( void * ) 0x87654321 )
-
-/* The base period used by the timer test tasks. */
-#define mainTIMER_TEST_PERIOD ( 50 )
-
-/* The size of the stack allocated to the check task (as described in the
-comments at the top of this file. */
-#define mainCHECK_TASK_STACK_SIZE_WORDS 160
-
-/* Size of the stacks to allocated for the register check tasks. */
-#define mainREG_TEST_STACK_SIZE_WORDS 90
-
-/*-----------------------------------------------------------*/
-
-/*
- * Called by main() to run the full demo (as opposed to the blinky demo) when
- * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
- */
-void main_full( void );
-
-/*
- * The check task, as described at the top of this file.
- */
-static void prvCheckTask( void *pvParameters );
-
-/*
- * Register check tasks as described at the top of this file. The nature of
- * these files necessitates that they are written in an assembly file, but the
- * entry points are kept in the C file for the convenience of checking the task
- * parameter.
- */
-static void prvRegTestTaskEntry1( void *pvParameters );
-extern void vRegTest1Implementation( void );
-static void prvRegTestTaskEntry2( void *pvParameters );
-extern void vRegTest2Implementation( void );
-
-/*
- * Tick hook used by the full demo, which includes code that interacts with
- * some of the tests.
- */
-void vFullDemoTickHook( void );
-
-/*-----------------------------------------------------------*/
-
-/* The following two variables are used to communicate the status of the
-register check tasks to the check task. If the variables keep incrementing,
-then the register check tasks have not discovered any errors. If a variable
-stops incrementing, then an error has been found. */
-uint32_t ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL;
-volatile uint32_t *pulRegTest1LoopCounter = &ulRegTest1LoopCounter;
-volatile uint32_t *pulRegTest2LoopCounter = &ulRegTest2LoopCounter;
-/*-----------------------------------------------------------*/
-
-void main_full( void )
-{
- /* Start all the other standard demo/test tasks. They have no particular
- functionality, but do demonstrate how to use the FreeRTOS API and test the
- kernel port. */
- vCreateBlockTimeTasks();
- vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
- vStartDynamicPriorityTasks();
- vStartTaskNotifyTask();
-
- /* Create the register check tasks, as described at the top of this file.
- Use xTaskCreateStatic() to create a task using only statically allocated
- memory. */
- xTaskCreate( prvRegTestTaskEntry1, /* The function that implements the task. */
- "Reg1", /* The name of the task. */
- mainREG_TEST_STACK_SIZE_WORDS, /* Size of stack to allocate for the task - in words not bytes!. */
- mainREG_TEST_TASK_1_PARAMETER, /* Parameter passed into the task. */
- tskIDLE_PRIORITY, /* Priority of the task. */
- NULL ); /* Can be used to pass out a handle to the created task. */
- xTaskCreate( prvRegTestTaskEntry2, "Reg2", mainREG_TEST_STACK_SIZE_WORDS, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL );
-
- /* Create the task that performs the 'check' functionality, as described at
- the top of this file. */
- xTaskCreate( prvCheckTask, "Check", mainCHECK_TASK_STACK_SIZE_WORDS, NULL, mainCHECK_TASK_PRIORITY, NULL );
-
- /* Start the scheduler. */
- vTaskStartScheduler();
-
- /* If all is well, the scheduler will now be running, and the following
- line will never be reached. If the following line does execute, then
- there was insufficient FreeRTOS heap memory available for the Idle and/or
- timer tasks to be created. See the memory management section on the
- FreeRTOS web site for more details on the FreeRTOS heap
- http://www.freertos.org/a00111.html. */
- for( ;; );
-}
-/*-----------------------------------------------------------*/
-
-static void prvCheckTask( void *pvParameters )
-{
-TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD;
-TickType_t xLastExecutionTime;
-uint32_t ulLastRegTest1Value = 0, ulLastRegTest2Value = 0;
-char * const pcPassMessage = ".";
-char * pcStatusMessage = pcPassMessage;
-extern void vToggleLED( void );
-
- /* Just to stop compiler warnings. */
- ( void ) pvParameters;
-
- /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil()
- works correctly. */
- xLastExecutionTime = xTaskGetTickCount();
-
- /* Cycle for ever, delaying then checking all the other tasks are still
- operating without error. The onboard LED is toggled on each iteration.
- If an error is detected then the delay period is decreased from
- mainNO_ERROR_CHECK_TASK_PERIOD to mainERROR_CHECK_TASK_PERIOD. This has the
- effect of increasing the rate at which the onboard LED toggles, and in so
- doing gives visual feedback of the system status. */
- for( ;; )
- {
- /* Delay until it is time to execute again. */
- vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod );
-
- /* Check all the demo tasks (other than the flash tasks) to ensure
- that they are all still running, and that none have detected an error. */
- if( xAreDynamicPriorityTasksStillRunning() == pdFALSE )
- {
- pcStatusMessage = "ERROR: Dynamic priority demo/tests.\r\n";
- }
-
- if( xAreBlockTimeTestTasksStillRunning() == pdFALSE )
- {
- pcStatusMessage = "ERROR: Block time demo/tests.\r\n";
- }
-
- if( xAreTimerDemoTasksStillRunning( ( TickType_t ) xDelayPeriod ) == pdFALSE )
- {
- pcStatusMessage = "ERROR: Timer demo/tests.\r\n";
- }
-
- if( xAreTaskNotificationTasksStillRunning() == pdFALSE )
- {
- pcStatusMessage = "ERROR: Task notification demo/tests.\r\n";
- }
-
- /* Check that the register test 1 task is still running. */
- if( ulLastRegTest1Value == ulRegTest1LoopCounter )
- {
- pcStatusMessage = "ERROR: Register test 1.\r\n";
- }
- ulLastRegTest1Value = ulRegTest1LoopCounter;
-
- /* Check that the register test 2 task is still running. */
- if( ulLastRegTest2Value == ulRegTest2LoopCounter )
- {
- pcStatusMessage = "ERROR: Register test 2.\r\n";
- }
- ulLastRegTest2Value = ulRegTest2LoopCounter;
-
- /* Write the status message to the UART and toggle the LED to show the
- system status if the UART is not connected. */
- vToggleLED();
-
- /* If an error has been found then increase the LED toggle rate by
- increasing the cycle frequency. */
- if( pcStatusMessage != pcPassMessage )
- {
- xDelayPeriod = mainERROR_CHECK_TASK_PERIOD;
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvRegTestTaskEntry1( void *pvParameters )
-{
- /* Although the regtest task is written in assembler, its entry point is
- written in C for convenience of checking the task parameter is being passed
- in correctly. */
- if( pvParameters == mainREG_TEST_TASK_1_PARAMETER )
- {
- /* Start the part of the test that is written in assembler. */
- vRegTest1Implementation();
- }
-
- /* The following line will only execute if the task parameter is found to
- be incorrect. The check task will detect that the regtest loop counter is
- not being incremented and flag an error. */
- vTaskDelete( NULL );
-}
-/*-----------------------------------------------------------*/
-
-static void prvRegTestTaskEntry2( void *pvParameters )
-{
- /* Although the regtest task is written in assembler, its entry point is
- written in C for convenience of checking the task parameter is being passed
- in correctly. */
- if( pvParameters == mainREG_TEST_TASK_2_PARAMETER )
- {
- /* Start the part of the test that is written in assembler. */
- vRegTest2Implementation();
- }
-
- /* The following line will only execute if the task parameter is found to
- be incorrect. The check task will detect that the regtest loop counter is
- not being incremented and flag an error. */
- vTaskDelete( NULL );
-}
-/*-----------------------------------------------------------*/
-
-void vFullDemoTickHook( void )
-{
- /* Called from vApplicationTickHook() when the project is configured to
- build the full test/demo applications. */
-
- /* Use task notifications from an interrupt. */
- xNotifyTaskFromISR();
-}
-/*-----------------------------------------------------------*/
-
+/* + * FreeRTOS V202104.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/****************************************************************************** + * NOTE 1: This project provides two demo applications. A simple blinky style + * project, and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting in main.c is used to select + * between the two. See the notes on using mainCREATE_SIMPLE_BLINKY_DEMO_ONLY + * in main.c. This file implements the comprehensive test and demo version. + * + * NOTE 2: This file only contains the source code that is specific to the + * full demo. Generic functions, such FreeRTOS hook functions, and functions + * required to configure the hardware, are defined in main.c. + * + ****************************************************************************** + * + * main_full() creates all the demo application tasks and software timers, then + * starts the scheduler. The web documentation provides more details of the + * standard demo application tasks, which provide no particular functionality, + * but do provide a good example of how to use the FreeRTOS API. + * + * In addition to the standard demo tasks, the following tasks and tests are + * defined and/or created within this file: + * + * "Reg test" tasks - These fill both the core registers with known values, then + * check that each register maintains its expected value for the lifetime of the + * task. Each task uses a different set of values. The reg test tasks execute + * with a very low priority, so get preempted very frequently. A register + * containing an unexpected value is indicative of an error in the context + * switching mechanism. + * + * "Check" task - The check executes every three seconds. It checks that all + * the standard demo tasks, and the register check tasks, are not only still + * executing, but are executing without reporting any errors. The check task + * toggles the LED every three seconds if all the standard demo tasks are + * executing as expected, or every 500ms if a potential error is discovered in + * any task. + */ + +/* Standard includes. */ +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +/* Kernel includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "semphr.h" + +/* Standard demo application includes. */ +#include "dynamic.h" +#include "blocktim.h" +#include "TimerDemo.h" +#include "TaskNotify.h" + +/* Priorities for the demo application tasks. */ +#define mainCHECK_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) + +/* The period of the check task, in ms, converted to ticks using the +pdMS_TO_TICKS() macro. mainNO_ERROR_CHECK_TASK_PERIOD is used if no errors have +been found, mainERROR_CHECK_TASK_PERIOD is used if an error has been found. */ +#define mainNO_ERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 3000UL ) +#define mainERROR_CHECK_TASK_PERIOD pdMS_TO_TICKS( 500UL ) + +/* Parameters that are passed into the register check tasks solely for the +purpose of ensuring parameters are passed into tasks correctly. */ +#define mainREG_TEST_TASK_1_PARAMETER ( ( void * ) 0x12345678 ) +#define mainREG_TEST_TASK_2_PARAMETER ( ( void * ) 0x87654321 ) + +/* The base period used by the timer test tasks. */ +#define mainTIMER_TEST_PERIOD ( 50 ) + +/* The size of the stack allocated to the check task (as described in the +comments at the top of this file. */ +#define mainCHECK_TASK_STACK_SIZE_WORDS 160 + +/* Size of the stacks to allocated for the register check tasks. */ +#define mainREG_TEST_STACK_SIZE_WORDS 90 + +/* Success output messages. This is used by the CI - do not change. */ +#define mainDEMO_SUCCESS_MESSAGE "FreeRTOS Demo SUCCESS\r\n" +/*-----------------------------------------------------------*/ + +/* + * Called by main() to run the full demo (as opposed to the blinky demo) when + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. + */ +void main_full( void ); + +/* + * The check task, as described at the top of this file. + */ +static void prvCheckTask( void *pvParameters ); + +/* + * Register check tasks as described at the top of this file. The nature of + * these files necessitates that they are written in an assembly file, but the + * entry points are kept in the C file for the convenience of checking the task + * parameter. + */ +static void prvRegTestTaskEntry1( void *pvParameters ); +extern void vRegTest1Implementation( void ); +static void prvRegTestTaskEntry2( void *pvParameters ); +extern void vRegTest2Implementation( void ); + +/* + * Tick hook used by the full demo, which includes code that interacts with + * some of the tests. + */ +void vFullDemoTickHook( void ); + +/*-----------------------------------------------------------*/ + +/* The following two variables are used to communicate the status of the +register check tasks to the check task. If the variables keep incrementing, +then the register check tasks have not discovered any errors. If a variable +stops incrementing, then an error has been found. */ +uint32_t ulRegTest1LoopCounter = 0UL, ulRegTest2LoopCounter = 0UL; +volatile uint32_t *pulRegTest1LoopCounter = &ulRegTest1LoopCounter; +volatile uint32_t *pulRegTest2LoopCounter = &ulRegTest2LoopCounter; +/*-----------------------------------------------------------*/ + +void main_full( void ) +{ + /* Start all the other standard demo/test tasks. They have no particular + functionality, but do demonstrate how to use the FreeRTOS API and test the + kernel port. */ + vCreateBlockTimeTasks(); + vStartTimerDemoTask( mainTIMER_TEST_PERIOD ); + vStartDynamicPriorityTasks(); + vStartTaskNotifyTask(); + + /* Create the register check tasks, as described at the top of this file. + Use xTaskCreateStatic() to create a task using only statically allocated + memory. */ + xTaskCreate( prvRegTestTaskEntry1, /* The function that implements the task. */ + "Reg1", /* The name of the task. */ + mainREG_TEST_STACK_SIZE_WORDS, /* Size of stack to allocate for the task - in words not bytes!. */ + mainREG_TEST_TASK_1_PARAMETER, /* Parameter passed into the task. */ + tskIDLE_PRIORITY, /* Priority of the task. */ + NULL ); /* Can be used to pass out a handle to the created task. */ + xTaskCreate( prvRegTestTaskEntry2, "Reg2", mainREG_TEST_STACK_SIZE_WORDS, mainREG_TEST_TASK_2_PARAMETER, tskIDLE_PRIORITY, NULL ); + + /* Create the task that performs the 'check' functionality, as described at + the top of this file. */ + xTaskCreate( prvCheckTask, "Check", mainCHECK_TASK_STACK_SIZE_WORDS, NULL, mainCHECK_TASK_PRIORITY, NULL ); + + /* Start the scheduler. */ + vTaskStartScheduler(); + + /* If all is well, the scheduler will now be running, and the following + line will never be reached. If the following line does execute, then + there was insufficient FreeRTOS heap memory available for the Idle and/or + timer tasks to be created. See the memory management section on the + FreeRTOS web site for more details on the FreeRTOS heap + http://www.freertos.org/a00111.html. */ + for( ;; ); +} +/*-----------------------------------------------------------*/ + +static void prvCheckTask( void *pvParameters ) +{ +TickType_t xDelayPeriod = mainNO_ERROR_CHECK_TASK_PERIOD; +TickType_t xLastExecutionTime; +uint32_t ulLastRegTest1Value = 0, ulLastRegTest2Value = 0; +char * const pcPassMessage = mainDEMO_SUCCESS_MESSAGE; +char * pcStatusMessage = pcPassMessage; +extern void vToggleLED( void ); + + /* Just to stop compiler warnings. */ + ( void ) pvParameters; + + /* Demo start marker. */ + configPRINT_STRING( "FreeRTOS Demo Start\r\n" ); + + /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() + works correctly. */ + xLastExecutionTime = xTaskGetTickCount(); + + /* Cycle for ever, delaying then checking all the other tasks are still + operating without error. The onboard LED is toggled on each iteration. + If an error is detected then the delay period is decreased from + mainNO_ERROR_CHECK_TASK_PERIOD to mainERROR_CHECK_TASK_PERIOD. This has the + effect of increasing the rate at which the onboard LED toggles, and in so + doing gives visual feedback of the system status. */ + for( ;; ) + { + /* Delay until it is time to execute again. */ + vTaskDelayUntil( &xLastExecutionTime, xDelayPeriod ); + + /* Check all the demo tasks (other than the flash tasks) to ensure + that they are all still running, and that none have detected an error. */ + if( xAreDynamicPriorityTasksStillRunning() == pdFALSE ) + { + pcStatusMessage = "FreeRTOS Demo ERROR: Dynamic priority demo/tests.\r\n"; + } + + if( xAreBlockTimeTestTasksStillRunning() == pdFALSE ) + { + pcStatusMessage = "FreeRTOS Demo ERROR: Block time demo/tests.\r\n"; + } + + if( xAreTimerDemoTasksStillRunning( ( TickType_t ) xDelayPeriod ) == pdFALSE ) + { + pcStatusMessage = "FreeRTOS Demo ERROR: Timer demo/tests.\r\n"; + } + + if( xAreTaskNotificationTasksStillRunning() == pdFALSE ) + { + pcStatusMessage = "FreeRTOS Demo ERROR: Task notification demo/tests.\r\n"; + } + + /* Check that the register test 1 task is still running. */ + if( ulLastRegTest1Value == ulRegTest1LoopCounter ) + { + pcStatusMessage = "FreeRTOS Demo ERROR: Register test 1.\r\n"; + } + ulLastRegTest1Value = ulRegTest1LoopCounter; + + /* Check that the register test 2 task is still running. */ + if( ulLastRegTest2Value == ulRegTest2LoopCounter ) + { + pcStatusMessage = "FreeRTOS Demo ERROR: Register test 2.\r\n"; + } + ulLastRegTest2Value = ulRegTest2LoopCounter; + + /* Write the status message to the UART and toggle the LED to show the + system status if the UART is not connected. */ + vToggleLED(); + + /* If an error has been found then increase the LED toggle rate by + increasing the cycle frequency. */ + if( pcStatusMessage != pcPassMessage ) + { + xDelayPeriod = mainERROR_CHECK_TASK_PERIOD; + } + + configPRINT_STRING( pcStatusMessage ); + } +} +/*-----------------------------------------------------------*/ + +static void prvRegTestTaskEntry1( void *pvParameters ) +{ + /* Although the regtest task is written in assembler, its entry point is + written in C for convenience of checking the task parameter is being passed + in correctly. */ + if( pvParameters == mainREG_TEST_TASK_1_PARAMETER ) + { + /* Start the part of the test that is written in assembler. */ + vRegTest1Implementation(); + } + + /* The following line will only execute if the task parameter is found to + be incorrect. The check task will detect that the regtest loop counter is + not being incremented and flag an error. */ + vTaskDelete( NULL ); +} +/*-----------------------------------------------------------*/ + +static void prvRegTestTaskEntry2( void *pvParameters ) +{ + /* Although the regtest task is written in assembler, its entry point is + written in C for convenience of checking the task parameter is being passed + in correctly. */ + if( pvParameters == mainREG_TEST_TASK_2_PARAMETER ) + { + /* Start the part of the test that is written in assembler. */ + vRegTest2Implementation(); + } + + /* The following line will only execute if the task parameter is found to + be incorrect. The check task will detect that the regtest loop counter is + not being incremented and flag an error. */ + vTaskDelete( NULL ); +} +/*-----------------------------------------------------------*/ + +void vFullDemoTickHook( void ) +{ + /* Called from vApplicationTickHook() when the project is configured to + build the full test/demo applications. */ + + /* Use task notifications from an interrupt. */ + xNotifyTaskFromISR(); +} +/*-----------------------------------------------------------*/ + diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/main.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/main.c index 7142850fc..0ddf8a93a 100644 --- a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/main.c +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/main.c @@ -1,271 +1,271 @@ -/*
- * FreeRTOS V202104.00
- * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-/******************************************************************************
- * This project provides two demo applications. A simple blinky style project,
- * and a more comprehensive test and demo application. The
- * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting (defined in this file) is used to
- * select between the two. The simply blinky demo is implemented and described
- * in main_blinky.c. The more comprehensive test and demo application is
- * implemented and described in main_full.c.
- *
- * This file implements the code that is not demo specific, including the
- * hardware setup and standard FreeRTOS hook functions.
- *
- * When running on the HiFive Rev B hardware:
- * When executing correctly the blue LED will toggle every three seconds. If
- * the blue LED toggles every 500ms then one of the self-monitoring test tasks
- * discovered a potential issue. If the red led toggles rapidly then a hardware
- * exception occurred.
- *
- * ENSURE TO READ THE DOCUMENTATION PAGE FOR THIS PORT AND DEMO APPLICATION ON
- * THE http://www.FreeRTOS.org WEB SITE FOR FULL INFORMATION ON USING THIS DEMO
- * APPLICATION, AND ITS ASSOCIATE FreeRTOS ARCHITECTURE PORT!
- *
- */
-
-/* FreeRTOS kernel includes. */
-#include <FreeRTOS.h>
-#include <task.h>
-
-/* Freedom metal driver includes. */
-#include <metal/cpu.h>
-#include <metal/led.h>
-
-/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
-or 0 to run the more comprehensive test and demo application. */
-#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0
-
-/* Index to first HART (there is only one). */
-#define mainHART_0 0
-
-/* Registers used to initialise the PLIC. */
-#define mainPLIC_PENDING_0 ( * ( ( volatile uint32_t * ) 0x0C001000UL ) )
-#define mainPLIC_PENDING_1 ( * ( ( volatile uint32_t * ) 0x0C001004UL ) )
-#define mainPLIC_ENABLE_0 ( * ( ( volatile uint32_t * ) 0x0C002000UL ) )
-#define mainPLIC_ENABLE_1 ( * ( ( volatile uint32_t * ) 0x0C002004UL ) )
-
-/*-----------------------------------------------------------*/
-
-/*
- * main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1.
- * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0.
- */
-#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1
- extern void main_blinky( void );
-#else
- extern void main_full( void );
-#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */
-
-/*
- * Prototypes for the standard FreeRTOS callback/hook functions implemented
- * within this file. See https://www.freertos.org/a00016.html
- */
-void vApplicationMallocFailedHook( void );
-void vApplicationIdleHook( void );
-void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName );
-void vApplicationTickHook( void );
-
-/*
- * Setup the hardware to run this demo.
- */
-static void prvSetupHardware( void );
-
-/*
- * Used by the Freedom Metal drivers.
- */
-static struct metal_led *pxBlueLED = NULL;
-
-/*-----------------------------------------------------------*/
-
-int main( void )
-{
- prvSetupHardware();
-
- /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top
- of this file. */
- #if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 )
- {
- main_blinky();
- }
- #else
- {
- main_full();
- }
- #endif
-}
-/*-----------------------------------------------------------*/
-
-static void prvSetupHardware( void )
-{
-struct metal_cpu *pxCPU;
-struct metal_interrupt *pxInterruptController;
-
- /* Initialise the blue LED. */
- pxBlueLED = metal_led_get_rgb( "LD0", "blue" );
- configASSERT( pxBlueLED );
- metal_led_enable( pxBlueLED );
- metal_led_off( pxBlueLED );
-
- /* Initialise the interrupt controller. */
- pxCPU = metal_cpu_get( mainHART_0 );
- configASSERT( pxCPU );
- pxInterruptController = metal_cpu_interrupt_controller( pxCPU );
- configASSERT( pxInterruptController );
- metal_interrupt_init( pxInterruptController );
-
- /* Set all interrupt enable bits to 0. */
- mainPLIC_ENABLE_0 = 0UL;
- mainPLIC_ENABLE_1 = 0UL;
-}
-/*-----------------------------------------------------------*/
-
-void vApplicationMallocFailedHook( void )
-{
- /* vApplicationMallocFailedHook() will only be called if
- configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook
- function that will get called if a call to pvPortMalloc() fails.
- pvPortMalloc() is called internally by the kernel whenever a task, queue,
- timer or semaphore is created. It is also called by various parts of the
- demo application. If heap_1.c or heap_2.c are used, then the size of the
- heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
- FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
- to query the size of free heap space that remains (although it does not
- provide information on how the remaining heap might be fragmented). */
- taskDISABLE_INTERRUPTS();
- for( ;; );
-}
-/*-----------------------------------------------------------*/
-
-void vApplicationIdleHook( void )
-{
- /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set
- to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle
- task. It is essential that code added to this hook function never attempts
- to block in any way (for example, call xQueueReceive() with a block time
- specified, or call vTaskDelay()). If the application makes use of the
- vTaskDelete() API function (as this demo application does) then it is also
- important that vApplicationIdleHook() is permitted to return to its calling
- function, because it is the responsibility of the idle task to clean up
- memory allocated by the kernel to any task that has since been deleted. */
-}
-/*-----------------------------------------------------------*/
-
-void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
-{
- ( void ) pcTaskName;
- ( void ) pxTask;
-
- /* Run time stack overflow checking is performed if
- configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
- function is called if a stack overflow is detected. */
- taskDISABLE_INTERRUPTS();
- for( ;; );
-}
-/*-----------------------------------------------------------*/
-
-void vApplicationTickHook( void )
-{
- /* The tests in the full demo expect some interaction with interrupts. */
- #if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1 )
- {
- extern void vFullDemoTickHook( void );
- vFullDemoTickHook();
- }
- #endif
-}
-/*-----------------------------------------------------------*/
-
-void vAssertCalled( void )
-{
-static struct metal_led *pxRedLED = NULL;
-volatile uint32_t ul;
-const uint32_t ulNullLoopDelay = 0x1ffffUL;
-
- taskDISABLE_INTERRUPTS();
-
- /* Initialise the red LED. */
- pxRedLED = metal_led_get_rgb( "LD0", "red" );
- configASSERT( pxRedLED );
- metal_led_enable( pxRedLED );
- metal_led_off( pxRedLED );
-
- /* Flash the red LED to indicate that assert was hit - interrupts are off
- here to prevent any further tick interrupts or context switches, so the
- delay is implemented as a crude loop instead of a peripheral timer. */
- for( ;; )
- {
- for( ul = 0; ul < ulNullLoopDelay; ul++ )
- {
- __asm volatile( "nop" );
- }
- metal_led_toggle( pxRedLED );
- }
-}
-/*-----------------------------------------------------------*/
-
-void handle_trap( void )
-{
-volatile uint32_t ulMEPC = 0UL, ulMCAUSE = 0UL, ulPLICPending0Register = 0UL, ulPLICPending1Register = 0UL;
-
- /* Store a few register values that might be useful when determining why this
- function was called. */
- __asm volatile( "csrr %0, mepc" : "=r"( ulMEPC ) );
- __asm volatile( "csrr %0, mcause" : "=r"( ulMCAUSE ) );
- ulPLICPending0Register = mainPLIC_PENDING_0;
- ulPLICPending1Register = mainPLIC_PENDING_1;
-
- /* Prevent compiler warnings about unused variables. */
- ( void ) ulPLICPending0Register;
- ( void ) ulPLICPending1Register;
-
- /* Force an assert as this function has not been implemented as the demo
- does not use external interrupts. */
- configASSERT( metal_cpu_get( mainHART_0 ) == 0x00 );
-}
-/*-----------------------------------------------------------*/
-
-void vToggleLED( void )
-{
- metal_led_toggle( pxBlueLED );
-}
-/*-----------------------------------------------------------*/
-
-void *malloc( size_t xSize )
-{
- /* The linker script does not define a heap so artificially force an assert()
- if something unexpectedly uses the C library heap. See
- https://www.freertos.org/a00111.html for more information. */
- configASSERT( metal_cpu_get( mainHART_0 ) == 0x00 );
-
- /* Remove warnings about unused parameter. */
- ( void ) xSize;
- return NULL;
-}
-/*-----------------------------------------------------------*/
-
-
+/* + * FreeRTOS V202104.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/****************************************************************************** + * This project provides two demo applications. A simple blinky style project, + * and a more comprehensive test and demo application. The + * mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting (defined in this file) is used to + * select between the two. The simply blinky demo is implemented and described + * in main_blinky.c. The more comprehensive test and demo application is + * implemented and described in main_full.c. + * + * This file implements the code that is not demo specific, including the + * hardware setup and standard FreeRTOS hook functions. + * + * When running on the HiFive Rev B hardware: + * When executing correctly the blue LED will toggle every three seconds. If + * the blue LED toggles every 500ms then one of the self-monitoring test tasks + * discovered a potential issue. If the red led toggles rapidly then a hardware + * exception occurred. + * + * ENSURE TO READ THE DOCUMENTATION PAGE FOR THIS PORT AND DEMO APPLICATION ON + * THE http://www.FreeRTOS.org WEB SITE FOR FULL INFORMATION ON USING THIS DEMO + * APPLICATION, AND ITS ASSOCIATE FreeRTOS ARCHITECTURE PORT! + * + */ + +/* FreeRTOS kernel includes. */ +#include <FreeRTOS.h> +#include <task.h> + +/* Freedom metal driver includes. */ +#include <metal/cpu.h> +#include <metal/led.h> + +/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, +or 0 to run the more comprehensive test and demo application. */ +#define mainCREATE_SIMPLE_BLINKY_DEMO_ONLY 0 + +/* Index to first HART (there is only one). */ +#define mainHART_0 0 + +/* Registers used to initialise the PLIC. */ +#define mainPLIC_PENDING_0 ( * ( ( volatile uint32_t * ) 0x0C001000UL ) ) +#define mainPLIC_PENDING_1 ( * ( ( volatile uint32_t * ) 0x0C001004UL ) ) +#define mainPLIC_ENABLE_0 ( * ( ( volatile uint32_t * ) 0x0C002000UL ) ) +#define mainPLIC_ENABLE_1 ( * ( ( volatile uint32_t * ) 0x0C002004UL ) ) + +/*-----------------------------------------------------------*/ + +/* + * main_blinky() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 1. + * main_full() is used when mainCREATE_SIMPLE_BLINKY_DEMO_ONLY is set to 0. + */ +#if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 + extern void main_blinky( void ); +#else + extern void main_full( void ); +#endif /* #if mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 */ + +/* + * Prototypes for the standard FreeRTOS callback/hook functions implemented + * within this file. See https://www.freertos.org/a00016.html + */ +void vApplicationMallocFailedHook( void ); +void vApplicationIdleHook( void ); +void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ); +void vApplicationTickHook( void ); + +/* + * Setup the hardware to run this demo. + */ +static void prvSetupHardware( void ); + +/* + * Used by the Freedom Metal drivers. + */ +static struct metal_led *pxBlueLED = NULL; + +/*-----------------------------------------------------------*/ + +int main( void ) +{ + prvSetupHardware(); + + /* The mainCREATE_SIMPLE_BLINKY_DEMO_ONLY setting is described at the top + of this file. */ + #if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY == 1 ) + { + main_blinky(); + } + #else + { + main_full(); + } + #endif +} +/*-----------------------------------------------------------*/ + +static void prvSetupHardware( void ) +{ +struct metal_cpu *pxCPU; +struct metal_interrupt *pxInterruptController; + + /* Initialise the blue LED. */ + pxBlueLED = metal_led_get_rgb( "LD0", "blue" ); + configASSERT( pxBlueLED ); + metal_led_enable( pxBlueLED ); + metal_led_off( pxBlueLED ); + + /* Initialise the interrupt controller. */ + pxCPU = metal_cpu_get( mainHART_0 ); + configASSERT( pxCPU ); + pxInterruptController = metal_cpu_interrupt_controller( pxCPU ); + configASSERT( pxInterruptController ); + metal_interrupt_init( pxInterruptController ); + + /* Set all interrupt enable bits to 0. */ + mainPLIC_ENABLE_0 = 0UL; + mainPLIC_ENABLE_1 = 0UL; +} +/*-----------------------------------------------------------*/ + +void vApplicationMallocFailedHook( void ) +{ + /* vApplicationMallocFailedHook() will only be called if + configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h. It is a hook + function that will get called if a call to pvPortMalloc() fails. + pvPortMalloc() is called internally by the kernel whenever a task, queue, + timer or semaphore is created. It is also called by various parts of the + demo application. If heap_1.c or heap_2.c are used, then the size of the + heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in + FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used + to query the size of free heap space that remains (although it does not + provide information on how the remaining heap might be fragmented). */ + taskDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ + /* vApplicationIdleHook() will only be called if configUSE_IDLE_HOOK is set + to 1 in FreeRTOSConfig.h. It will be called on each iteration of the idle + task. It is essential that code added to this hook function never attempts + to block in any way (for example, call xQueueReceive() with a block time + specified, or call vTaskDelay()). If the application makes use of the + vTaskDelete() API function (as this demo application does) then it is also + important that vApplicationIdleHook() is permitted to return to its calling + function, because it is the responsibility of the idle task to clean up + memory allocated by the kernel to any task that has since been deleted. */ +} +/*-----------------------------------------------------------*/ + +void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName ) +{ + ( void ) pcTaskName; + ( void ) pxTask; + + /* Run time stack overflow checking is performed if + configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook + function is called if a stack overflow is detected. */ + taskDISABLE_INTERRUPTS(); + for( ;; ); +} +/*-----------------------------------------------------------*/ + +void vApplicationTickHook( void ) +{ + /* The tests in the full demo expect some interaction with interrupts. */ + #if( mainCREATE_SIMPLE_BLINKY_DEMO_ONLY != 1 ) + { + extern void vFullDemoTickHook( void ); + vFullDemoTickHook(); + } + #endif +} +/*-----------------------------------------------------------*/ + +void vAssertCalled( void ) +{ +static struct metal_led *pxRedLED = NULL; +volatile uint32_t ul; +const uint32_t ulNullLoopDelay = 0x1ffffUL; + + taskDISABLE_INTERRUPTS(); + + /* Initialise the red LED. */ + pxRedLED = metal_led_get_rgb( "LD0", "red" ); + configASSERT( pxRedLED ); + metal_led_enable( pxRedLED ); + metal_led_off( pxRedLED ); + + /* Flash the red LED to indicate that assert was hit - interrupts are off + here to prevent any further tick interrupts or context switches, so the + delay is implemented as a crude loop instead of a peripheral timer. */ + for( ;; ) + { + for( ul = 0; ul < ulNullLoopDelay; ul++ ) + { + __asm volatile( "nop" ); + } + metal_led_toggle( pxRedLED ); + } +} +/*-----------------------------------------------------------*/ + +void handle_trap( void ) +{ +volatile uint32_t ulMEPC = 0UL, ulMCAUSE = 0UL, ulPLICPending0Register = 0UL, ulPLICPending1Register = 0UL; + + /* Store a few register values that might be useful when determining why this + function was called. */ + __asm volatile( "csrr %0, mepc" : "=r"( ulMEPC ) ); + __asm volatile( "csrr %0, mcause" : "=r"( ulMCAUSE ) ); + ulPLICPending0Register = mainPLIC_PENDING_0; + ulPLICPending1Register = mainPLIC_PENDING_1; + + /* Prevent compiler warnings about unused variables. */ + ( void ) ulPLICPending0Register; + ( void ) ulPLICPending1Register; + + /* Force an assert as this function has not been implemented as the demo + does not use external interrupts. */ + configASSERT( metal_cpu_get( mainHART_0 ) == 0x00 ); +} +/*-----------------------------------------------------------*/ + +void vToggleLED( void ) +{ + metal_led_toggle( pxBlueLED ); +} +/*-----------------------------------------------------------*/ + +void *malloc( size_t xSize ) +{ + /* The linker script does not define a heap so artificially force an assert() + if something unexpectedly uses the C library heap. See + https://www.freertos.org/a00111.html for more information. */ + configASSERT( metal_cpu_get( mainHART_0 ) == 0x00 ); + + /* Remove warnings about unused parameter. */ + ( void ) xSize; + return NULL; +} +/*-----------------------------------------------------------*/ + + diff --git a/lexicon.txt b/lexicon.txt index 2db8f8a84..0d7d058b8 100644 --- a/lexicon.txt +++ b/lexicon.txt @@ -218,6 +218,7 @@ checktimer checkval checkvalue checon +ci ciconfiguration circleos ck |