updated to 6.0.1 and added additional processors/toolchains
This commit is contained in:
118
ports/cortex_a5x/ac6/example_build/sample_threadx/.cproject
Normal file
118
ports/cortex_a5x/ac6/example_build/sample_threadx/.cproject
Normal file
@@ -0,0 +1,118 @@
|
||||
<?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="com.arm.eclipse.build.config.v6.exe.debug.1756493040">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.exe.debug.1756493040" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="com.arm.eclipse.builder.armcc.error" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactExtension="axf" 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="clean" description="" id="com.arm.eclipse.build.config.v6.exe.debug.1756493040" name="Debug" parent="com.arm.eclipse.build.config.v6.exe.debug">
|
||||
<folderInfo id="com.arm.eclipse.build.config.v6.exe.debug.1756493040." name="/" resourcePath="">
|
||||
<toolChain id="com.arm.toolchain.v6.exe.debug.299888552" name="ARM Compiler 6 (DS-5 built-in)" superClass="com.arm.toolchain.v6.exe.debug">
|
||||
<targetPlatform id="com.arm.eclipse.build.config.v6.exe.debug.1756493040..302246591" name=""/>
|
||||
<builder buildPath="${workspace_loc:/sample_threadx}/Debug" id="com.arm.toolchain.v6.builder.869166565" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.arm.toolchain.v6.builder"/>
|
||||
<tool id="com.arm.tool.c.compiler.v6.1180490247" name="ARM C Compiler 6" superClass="com.arm.tool.c.compiler.v6">
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.min" id="com.arm.tool.c.compiler.v6.base.option.optlevel.526511916" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" valueType="enumerated"/>
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.tool.c.compiler.v6.base.options.debug.level.1965365158" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" valueType="enumerated"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.target.98510709" name="Target (--target)" superClass="com.arm.tool.c.compiler.v6.base.option.target" useByScannerDiscovery="true" value="aarch64-arm-none-eabi" valueType="string"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.cpu.1703325529" name="CPU (-mcpu)" superClass="com.arm.tool.c.compiler.v6.base.option.cpu" useByScannerDiscovery="true" value="cortex-a53+fp" valueType="string"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.defmac.1485103375" name="Define macro (-D)" superClass="com.arm.tool.c.compiler.v6.base.option.defmac" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="STANDALONE"/>
|
||||
</option>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.incpath.115625343" name="Include path (-I)" superClass="com.arm.tool.c.compiler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/tx/inc_generic}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/tx/inc_port}""/>
|
||||
</option>
|
||||
<inputType id="com.arm.tool.c.compiler.v6.base.input.1332371998" superClass="com.arm.tool.c.compiler.v6.base.input"/>
|
||||
<inputType id="com.arm.tool.cpp.compiler.v6.base.input.122592929" superClass="com.arm.tool.cpp.compiler.v6.base.input"/>
|
||||
</tool>
|
||||
<tool id="com.arm.tool.cpp.compiler.v6.757724458" name="ARM C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6">
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.min" id="com.arm.tool.c.compiler.v6.base.option.optlevel.328021275" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" valueType="enumerated"/>
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.tool.c.compiler.v6.base.options.debug.level.681507277" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="com.arm.tool.assembler.v6.1147311776" name="ARM Assembler 6" superClass="com.arm.tool.assembler.v6">
|
||||
<option defaultValue="com.arm.tool.assembler.v6.base.options.debug.level.std" id="com.arm.tool.assembler.v6.base.options.debug.level.895750985" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" valueType="enumerated"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.target.938598089" name="Target (--target)" superClass="com.arm.tool.assembler.v6.base.option.target" value="aarch64-arm-none-eabi" valueType="string"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.cpu.310599436" name="CPU (-mcpu)" superClass="com.arm.tool.assembler.v6.base.option.cpu" value="cortex-a53+fp" valueType="string"/>
|
||||
<inputType id="com.arm.tool.assembler.v6.base.input.603158778" superClass="com.arm.tool.assembler.v6.base.input"/>
|
||||
</tool>
|
||||
<tool id="com.arm.tool.c.linker.v6.996475472" name="ARM Linker 6" superClass="com.arm.tool.c.linker.v6">
|
||||
<option id="com.arm.tool.c.linker.option.entry.1400170036" name="Image entry point (--entry)" superClass="com.arm.tool.c.linker.option.entry" value="start64" valueType="string"/>
|
||||
<option id="com.arm.tool.c.linker.option.scatter.1388056657" name="Scatter file (--scatter)" superClass="com.arm.tool.c.linker.option.scatter" value="..\sample_threadx.txt" valueType="string"/>
|
||||
<option id="com.arm.tool.c.linker.option.imagemap.2104726082" name="Generate image map (--map)" superClass="com.arm.tool.c.linker.option.imagemap" value="true" valueType="boolean"/>
|
||||
<option id="com.arm.tool.c.linker.option.verbose.2075899330" name="Verbose output (--verbose)" superClass="com.arm.tool.c.linker.option.verbose" value="true" valueType="boolean"/>
|
||||
<option id="com.arm.tool.c.linker.option.totals.1648962874" name="List total code and data sizes of output image (--info=totals)" superClass="com.arm.tool.c.linker.option.totals" value="true" valueType="boolean"/>
|
||||
<option id="com.arm.tool.c.linker.option.redirectoutput.629734526" name="Redirect diagnostics output to file (--list)" superClass="com.arm.tool.c.linker.option.redirectoutput" value="sample_threadx.map" valueType="string"/>
|
||||
<option id="com.arm.tool.c.linker.option.libsearch.747365095" name="User library search path (--userlibpath)" superClass="com.arm.tool.c.linker.option.libsearch"/>
|
||||
<option id="com.arm.tool.c.linker.libs.2121493259" name="User library files" superClass="com.arm.tool.c.linker.libs" valueType="libs">
|
||||
<listOptionValue builtIn="false" value="..\..\tx\Debug\tx.a"/>
|
||||
</option>
|
||||
<option id="com.arm.tool.c.linker.option.flags.1576883448" name="Other flags" superClass="com.arm.tool.c.linker.option.flags" valueType="stringList"/>
|
||||
</tool>
|
||||
<tool id="com.arm.tool.librarian.v6.1090597542" name="ARM Librarian 6" superClass="com.arm.tool.librarian.v6"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="com.arm.eclipse.build.config.v6.exe.release.1970372372">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.exe.release.1970372372" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="com.arm.eclipse.builder.armcc.error" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactExtension="axf" 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.release" cleanCommand="clean" description="" id="com.arm.eclipse.build.config.v6.exe.release.1970372372" name="Release" parent="com.arm.eclipse.build.config.v6.exe.release">
|
||||
<folderInfo id="com.arm.eclipse.build.config.v6.exe.release.1970372372." name="/" resourcePath="">
|
||||
<toolChain id="com.arm.toolchain.v6.exe.release.1208724479" name="ARM Compiler 6 (DS-5 built-in)" superClass="com.arm.toolchain.v6.exe.release">
|
||||
<targetPlatform id="com.arm.eclipse.build.config.v6.exe.release.1970372372..306578502" name=""/>
|
||||
<builder buildPath="${workspace_loc:/sample_threadx}/Release" id="com.arm.toolchain.v6.builder.1599248707" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="com.arm.toolchain.v6.builder"/>
|
||||
<tool id="com.arm.tool.c.compiler.v6.117703562" name="ARM C Compiler 6" superClass="com.arm.tool.c.compiler.v6">
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.high" id="com.arm.tool.c.compiler.v6.base.option.optlevel.1549626078" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" valueType="enumerated"/>
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.none" id="com.arm.tool.c.compiler.v6.base.options.debug.level.109227440" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" valueType="enumerated"/>
|
||||
<inputType id="com.arm.tool.c.compiler.v6.base.input.1407956082" superClass="com.arm.tool.c.compiler.v6.base.input"/>
|
||||
<inputType id="com.arm.tool.cpp.compiler.v6.base.input.1636042802" superClass="com.arm.tool.cpp.compiler.v6.base.input"/>
|
||||
</tool>
|
||||
<tool id="com.arm.tool.cpp.compiler.v6.1755515797" name="ARM C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6">
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.high" id="com.arm.tool.c.compiler.v6.base.option.optlevel.1001199458" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" valueType="enumerated"/>
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.none" id="com.arm.tool.c.compiler.v6.base.options.debug.level.1882852746" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="com.arm.tool.assembler.v6.759015076" name="ARM Assembler 6" superClass="com.arm.tool.assembler.v6">
|
||||
<option defaultValue="com.arm.tool.assembler.v6.base.options.debug.level.none" id="com.arm.tool.assembler.v6.base.options.debug.level.1943766996" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" valueType="enumerated"/>
|
||||
<inputType id="com.arm.tool.assembler.v6.base.input.385905318" superClass="com.arm.tool.assembler.v6.base.input"/>
|
||||
</tool>
|
||||
<tool id="com.arm.tool.c.linker.v6.1686707697" name="ARM Linker 6" superClass="com.arm.tool.c.linker.v6"/>
|
||||
<tool id="com.arm.tool.librarian.v6.1878811431" name="ARM Librarian 6" superClass="com.arm.tool.librarian.v6"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="sample_threadx.com.arm.eclipse.build.project.v6.exe.1027551600" name="Executable" projectType="com.arm.eclipse.build.project.v6.exe"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
<configuration configurationName="Debug">
|
||||
<resource resourceType="PROJECT" workspacePath="/sample_threadx"/>
|
||||
</configuration>
|
||||
<configuration configurationName="Release">
|
||||
<resource resourceType="PROJECT" workspacePath="/sample_threadx"/>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
</cproject>
|
||||
26
ports/cortex_a5x/ac6/example_build/sample_threadx/.project
Normal file
26
ports/cortex_a5x/ac6/example_build/sample_threadx/.project
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>sample_threadx</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>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project>
|
||||
<configuration id="com.arm.eclipse.build.config.v6.exe.debug.1756493040" 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="com.arm.eclipse.builder.armcc.discovery.ArmCompiler6LanguageSettingsProvider" console="false" env-hash="-294697026837367808" id="com.arm.eclipse.builder.armcc.v6.langprovider" keep-relative-paths="false" name="ARM Compiler 6 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>
|
||||
<configuration id="com.arm.eclipse.build.config.v6.exe.release.1970372372" name="Release">
|
||||
<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="com.arm.eclipse.builder.armcc.discovery.ArmCompiler6LanguageSettingsProvider" console="false" env-hash="-264130677454984672" id="com.arm.eclipse.builder.armcc.v6.langprovider" keep-relative-paths="false" name="ARM Compiler 6 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>
|
||||
@@ -0,0 +1,431 @@
|
||||
// ------------------------------------------------------------
|
||||
// ARMv8-A AArch64 Generic Timer Access Functions
|
||||
//
|
||||
// Copyright ARM Ltd 2013. All rights reserved.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
|
||||
.section AArch64_GenericTimer,"ax"
|
||||
.align 3
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getCNTFRQ
|
||||
// uint32_t getCNTFRQ(void)
|
||||
// Returns the value of CNTFRQ_EL0
|
||||
.type getCNTFRQ, @function
|
||||
getCNTFRQ:
|
||||
MRS x0, CNTFRQ_EL0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global setCNTFRQ
|
||||
// void setCNTFRQ(uint32_t freq)
|
||||
// Sets the value of CNTFRQ_EL0 (only possible at EL3)
|
||||
// w0 - freq - The value to be written into CNTFRQ_EL0
|
||||
.type setCNTFRQ, @function
|
||||
setCNTFRQ:
|
||||
MSR CNTFRQ_EL0, x0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getPhysicalCount
|
||||
// uint64_t getPhysicalCount(void)
|
||||
// Returns the current value of physical count (CNTPCT_EL0)
|
||||
.type getPhysicalCount, @function
|
||||
getPhysicalCount:
|
||||
MRS x0, CNTPCT_EL0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getVirtualCount
|
||||
// uint64_t getVirtualCount(void)
|
||||
// Returns the current value of the virtual count register (CNTVCT_EL0)
|
||||
.type getVirtualCount, @function
|
||||
getVirtualCount:
|
||||
MRS x0, CNTVCT_EL0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getEL1Ctrl
|
||||
// uint32_t getEL1Ctrl(void)
|
||||
// Returns the value of EL1 Timer Control Register (CNTKCTL_EL1)
|
||||
.type getEL1Ctrl, @function
|
||||
getEL1Ctrl:
|
||||
MRS x0, CNTKCTL_EL1
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global setEL1Ctrl
|
||||
// void setEL1Ctrl(uint32_t value)
|
||||
// Sets the value of Counter Non-secure EL1 Control Register (CNTKCTL_EL1)
|
||||
// 0 - value - The value to be written into CNTKCTL_EL1
|
||||
.type setEL1Ctrl, @function
|
||||
setEL1Ctrl:
|
||||
MSR CNTKCTL_EL1, x0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getEL2Ctrl
|
||||
// uint32_t getEL2Ctrl(void)
|
||||
// Returns the value of the EL2 Timer Control Register (CNTHCTL_EL2)
|
||||
.type getEL2Ctrl, @function
|
||||
getEL2Ctrl:
|
||||
MRS x0, CNTHCTL_EL2
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global setEL2Ctrl
|
||||
// void setEL2Ctrl(uint32_t value)
|
||||
// Sets the value of the EL2 Timer Control Register (CNTHCTL_EL2)
|
||||
// x0 - value - The value to be written into CNTHCTL_EL2
|
||||
.type setEL2Ctrl, @function
|
||||
setEL2Ctrl:
|
||||
MSR CNTHCTL_EL2, x0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Non-Secure Physical Timer
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getNSEL1PhysicalCompValue
|
||||
// uint64_t getNSEL1PhysicalCompValue(void)
|
||||
// Returns the value of Non-Secure EL1 Physical Compare Value Register (CNTP_CVAL_EL0)
|
||||
.type getNSEL1PhysicalCompValue, @function
|
||||
getNSEL1PhysicalCompValue:
|
||||
MRS x0, CNTP_CVAL_EL0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global setNSEL1PhysicalCompValue
|
||||
// void setNSEL1PhysicalCompValue(uint64_t value)
|
||||
// Sets the value of the Non-Secure EL1 Physical Compare Value Register (CNTP_CVAL_EL0)
|
||||
// x0 - value - The value to be written into CNTP_CVAL_EL0
|
||||
.type setNSEL1PhysicalCompValue, @function
|
||||
setNSEL1PhysicalCompValue:
|
||||
MSR CNTP_CVAL_EL0, x0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getNSEL1PhysicalTimerValue
|
||||
// uint32_t getNSEL1PhysicalTimerValue(void)
|
||||
// Returns the value of Non-Secure EL1 Physical Timer Value Register (CNTP_TVAL_EL0)
|
||||
.type getNSEL1PhysicalTimerValue, @function
|
||||
getNSEL1PhysicalTimerValue:
|
||||
MRS x0, CNTP_TVAL_EL0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global setNSEL1PhysicalTimerValue
|
||||
// void setNSEL1PhysicalTimerValue(uint32_t value)
|
||||
// Sets the value of the Non-Secure EL1 Physical Timer Value Register (CNTP_TVAL_EL0)
|
||||
// w0 - value - The value to be written into CNTP_TVAL_EL0
|
||||
.type setNSEL1PhysicalTimerValue, @function
|
||||
setNSEL1PhysicalTimerValue:
|
||||
MSR CNTP_TVAL_EL0, x0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getNSEL1PhysicalTimerCtrl
|
||||
// uint32_t getNSEL1PhysicalTimerCtrl(void)
|
||||
// Returns the value of Non-Secure EL1 Physical Timer Control Register (CNTP_CTL_EL0)
|
||||
.type getNSEL1PhysicalTimerCtrl, @function
|
||||
getNSEL1PhysicalTimerCtrl:
|
||||
MRS x0, CNTP_CTL_EL0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global setNSEL1PhysicalTimerCtrl
|
||||
// void setNSEL1PhysicalTimerCtrl(uint32_t value)
|
||||
// Sets the value of the Non-Secure EL1 Physical Timer Control Register (CNTP_CTL_EL0)
|
||||
// w0 - value - The value to be written into CNTP_CTL_EL0
|
||||
.type setNSEL1PhysicalTimerCtrl, @function
|
||||
setNSEL1PhysicalTimerCtrl:
|
||||
MSR CNTP_CTL_EL0, x0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Secure Physical Timer
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getSEL1PhysicalCompValue
|
||||
// uint64_t getSEL1PhysicalCompValue(void)
|
||||
// Returns the value of Secure EL1 Physical Compare Value Register (CNTPS_CVAL_EL1)
|
||||
.type getSEL1PhysicalCompValue, @function
|
||||
getSEL1PhysicalCompValue:
|
||||
MRS x0, CNTPS_CVAL_EL1
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global setSEL1PhysicalCompValue
|
||||
// void setSEL1PhysicalCompValue(uint64_t value)
|
||||
// Sets the value of the Secure EL1 Physical Compare Value Register (CNTPS_CVAL_EL1)
|
||||
// x0 - value - The value to be written into CNTPS_CVAL_EL1
|
||||
.type setSEL1PhysicalCompValue, @function
|
||||
setSEL1PhysicalCompValue:
|
||||
MSR CNTPS_CVAL_EL1, x0
|
||||
RET
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getSEL1PhysicalTimerValue
|
||||
// uint32_t getSEL1PhysicalTimerValue(void)
|
||||
// Returns the value of Secure EL1 Physical Timer Value Register (CNTPS_TVAL_EL1)
|
||||
.type getSEL1PhysicalTimerValue, @function
|
||||
getSEL1PhysicalTimerValue:
|
||||
MRS x0, CNTPS_TVAL_EL1
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global setSEL1PhysicalTimerValue
|
||||
// void setSEL1PhysicalTimerValue(uint32_t value)
|
||||
// Sets the value of the Secure EL1 Physical Timer Value Register (CNTPS_TVAL_EL1)
|
||||
// w0 - value - The value to be written into CNTPS_TVAL_EL1
|
||||
.type setSEL1PhysicalTimerValue, @function
|
||||
setSEL1PhysicalTimerValue:
|
||||
MSR CNTPS_TVAL_EL1, x0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getSEL1PhysicalTimerCtrl
|
||||
// uint32_t getSEL1PhysicalTimerCtrl(void)
|
||||
// Returns the value of Secure EL1 Physical Timer Control Register (CNTPS_CTL_EL1)
|
||||
.type getSEL1PhysicalTimerCtrl, @function
|
||||
getSEL1PhysicalTimerCtrl:
|
||||
MRS x0, CNTPS_CTL_EL1
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global setSEL1PhysicalTimerCtrl
|
||||
// void setSEL1PhysicalTimerCtrl(uint32_t value)
|
||||
// Sets the value of the Secure EL1 Physical Timer Control Register (CNTPS_CTL_EL1)
|
||||
// w0 - value - The value to be written into CNTPS_CTL_EL1
|
||||
.type setSEL1PhysicalTimerCtrl, @function
|
||||
setSEL1PhysicalTimerCtrl:
|
||||
MSR CNTPS_CTL_EL1, x0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global configSecureEL1TimerAccess
|
||||
// void configSecureEL1TimerAccess(unsigned int config)//
|
||||
// Sets the values of the SCR_EL3.ST bit (bit 11) based on the value in x0
|
||||
// EL3 accessible only!
|
||||
.type configSecureEL1TimerAccess, @function
|
||||
configSecureEL1TimerAccess:
|
||||
MRS x1, SCR_EL3
|
||||
BFI x1, x0, #11, #1
|
||||
MSR SCR_EL3, x1
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Virtual Timer
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getEL1VirtualCompValue
|
||||
// uint64_t getEL1VirtualCompValue(void)
|
||||
// Returns the value of EL1 Virtual Compare Value Register (CNTV_CVAL_EL0)
|
||||
.type getEL1VirtualCompValue, @function
|
||||
getEL1VirtualCompValue:
|
||||
MRS x0, CNTV_CVAL_EL0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global setEL1VirtualCompValue
|
||||
// void setEL1VirtualCompValue(uint64_t value)
|
||||
// Sets the value of the EL1 Virtual Compare Value Register (CNTV_CVAL_EL0)
|
||||
// x0 - value - The value to be written into CNTV_CVAL_EL0
|
||||
.type setEL1VirtualCompValue, @function
|
||||
setEL1VirtualCompValue:
|
||||
MSR CNTV_CVAL_EL0, x0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getEL1VirtualTimerValue
|
||||
// uint32_t getEL1VirtualTimerValue(void)
|
||||
// Returns the value of EL1 Virtual Timer Value Register (CNTV_TVAL_EL0)
|
||||
.type getEL1VirtualTimerValue, @function
|
||||
getEL1VirtualTimerValue:
|
||||
MRS x0, CNTV_TVAL_EL0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global setEL1VirtualTimerValue
|
||||
// void setEL1VirtualTimerValue(uint32_t value)
|
||||
// Sets the value of the EL1 Virtual Timer Value Register (CNTV_TVAL_EL0)
|
||||
// w0 - value - The value to be written into CNTV_TVAL_EL0
|
||||
.type setEL1VirtualTimerValue, @function
|
||||
setEL1VirtualTimerValue:
|
||||
MSR CNTV_TVAL_EL0, x0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getEL1VirtualTimerCtrl
|
||||
// uint32_t getEL1VirtualTimerCtrl(void)
|
||||
// Returns the value of EL1 Virtual Timer Control Register (CNTV_CTL_EL0)
|
||||
.type getEL1VirtualTimerCtrl, @function
|
||||
getEL1VirtualTimerCtrl:
|
||||
MRS x0, CNTV_CTL_EL0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global setEL1VirtualTimerCtrl
|
||||
// void setEL1VirtualTimerCtrl(uint32_t value)
|
||||
// Sets the value of the EL1 Virtual Timer Control Register (CNTV_CTL_EL0)
|
||||
// w0 - value - The value to be written into CNTV_CTL_EL0
|
||||
.type setEL1VirtualTimerCtrl, @function
|
||||
setEL1VirtualTimerCtrl:
|
||||
MSR CNTV_CTL_EL0, x0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Virtual Timer functions to be called by EL2
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getVirtualCounterOffset
|
||||
// uint64_t getVirtualCounterOffset(void)
|
||||
// Returns the value of the Counter Virtual Offset Register (CNTVOFF_EL2)
|
||||
// EL2 and EL3 only
|
||||
.type getVirtualCounterOffset, @function
|
||||
getVirtualCounterOffset:
|
||||
MRS x0, CNTVOFF_EL2
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global setVirtualCounterOffset
|
||||
// void setVirtualCounterOffset(uint64_t offset)
|
||||
// Sets the value of the Counter Virtual Offset Register (CNTVOFF_EL2)
|
||||
// x0 - offset - The value to be written into CNTVOFF_EL2
|
||||
// EL2 and EL3 only
|
||||
.type setVirtualCounterOffset, @function
|
||||
setVirtualCounterOffset:
|
||||
MSR CNTVOFF_EL2, x0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// EL2 Physical Timer
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getEL2PhysicalCompValue
|
||||
// uint64_t getEL2PhysicalCompValue(void)
|
||||
// Returns the value of EL2 Physical Compare Value Register (CNTHP_CVAL_EL2)
|
||||
.type getEL2PhysicalCompValue, @function
|
||||
getEL2PhysicalCompValue:
|
||||
MRS x0, CNTHP_CVAL_EL2
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global setEL2PhysicalCompValue
|
||||
// void setEL2PhysicalCompValue(uint64_t value)
|
||||
// Sets the value of the EL2 Physical Compare Value Register (CNTHP_CVAL_EL2)
|
||||
// x0 - value - The value to be written into CNTHP_CVAL_EL2
|
||||
.type setEL2PhysicalCompValue, @function
|
||||
setEL2PhysicalCompValue:
|
||||
MSR CNTHP_CVAL_EL2, x0
|
||||
RET
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getEL2PhysicalTimerValue
|
||||
// uint32_t getEL2PhysicalTimerValue(void)
|
||||
// Returns the value of EL2 Physical Timer Value Register (CNTHP_TVAL_EL2)
|
||||
.type getEL2PhysicalTimerValue, @function
|
||||
getEL2PhysicalTimerValue:
|
||||
MRS x0, CNTHP_TVAL_EL2
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global setEL2PhysicalTimerValue
|
||||
// void setEL2PhysicalTimerValue(uint32_t value)
|
||||
// Sets the value of the EL2 Physical Timer Value Register (CNTHP_TVAL_EL2)
|
||||
// w0 - value - The value to be written into CNTHP_TVAL_EL2
|
||||
.type setEL2PhysicalTimerValue, @function
|
||||
setEL2PhysicalTimerValue:
|
||||
MSR CNTHP_TVAL_EL2, x0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global getEL2PhysicalTimerCtrl
|
||||
// uint32_t getEL2PhysicalTimerCtrl(void)
|
||||
// Returns the value of EL2 Physical Timer Control Register (CNTHP_CTL_EL2)
|
||||
.type getEL2PhysicalTimerCtrl, @function
|
||||
getEL2PhysicalTimerCtrl:
|
||||
MRS x0, CNTHP_CTL_EL2
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global setEL2PhysicalTimerCtrl
|
||||
// void setEL2PhysicalTimerCtrl(uint32_t value)
|
||||
// Sets the value of the EL2 Physical Timer Control Register (CNTHP_CTL_EL2)
|
||||
// w0 - value - The value to be written into CNTHP_CTL_EL2
|
||||
.type setEL2PhysicalTimerCtrl, @function
|
||||
setEL2PhysicalTimerCtrl:
|
||||
MSR CNTHP_CTL_EL2, x0
|
||||
RET
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// End of code
|
||||
// ------------------------------------------------------------
|
||||
@@ -0,0 +1,206 @@
|
||||
// ------------------------------------------------------------
|
||||
// ARMv8-A AArch64 System Timer
|
||||
// Header Filer
|
||||
//
|
||||
// Copyright ARM Ltd 2013. All rights reserved.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
#ifndef _ARMV8A_SYSTEM_TIMER_H
|
||||
#define _ARMV8A_SYSTEM_TIMER_H
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// CNTFRQ holds the frequency of the system counter
|
||||
// Readable in all ELs
|
||||
// Writable only by EL3
|
||||
|
||||
// Returns the value of CNTFRQ_EL0
|
||||
unsigned int getCNTFRQ(void);
|
||||
|
||||
// Sets the value of CNTFRQ_EL0 (EL3 only!)
|
||||
// freq - The value to be written into CNTFRQ_EL3
|
||||
void setCNTFRQ(unsigned int freq);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// CNTPCT_EL0 and CNTVCT_EL0 hold the physical and virtual counts
|
||||
// Always accessable in Hpy and Secure EL1
|
||||
// Access from EL2 and Non-Secure EL1 is configurable
|
||||
|
||||
// Returns the current value of physical count (CNTPCT_EL0)
|
||||
unsigned long long getPhysicalCount(void);
|
||||
|
||||
// Returns the current value of the virtual count register (CNTVCT_EL0)
|
||||
unsigned long long getVirtualCount(void);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// The CNTKCTL register controls whether CNTPCT can be accessed from EL0
|
||||
// Only acceable from EL1 and EL2
|
||||
|
||||
#define CNTKCTL_PCTEN (1 << 0) // Controls whether the physical counter, CNTPCT, and the frequency register CNTFRQ, are accessible from EL0
|
||||
#define CNTKCTL_VCTEN (1 << 1) // Controls whether the virtual counter, CNTVCT, and the frequency register CNTFRQ, are accessible from
|
||||
#define CNTKCTL_EVNTEN (1 << 2) // Enables the generation of an event stream from the virtual counter
|
||||
#define CNTKCTL_EVNTDIR (1 << 3) // Controls which transition of the CNTVCT trigger bit, defined by EVNTI, generates an event
|
||||
|
||||
// Returns the value of EL1 Timer Control Register (CNTKCTL_EL1)
|
||||
unsigned int getEL1Ctrl(void);
|
||||
|
||||
// Sets the value of EL1 Timer Control Register (CNTKCTL_EL1)
|
||||
// value - The value to be written into CNTKCTL_EL1
|
||||
void setEL1Ctrl(unsigned int value);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// The CNTHCTL_EL2 register controls whether CNTPCT_EL0 can be accessed from EL1
|
||||
// Only accessable from EL2 and EL3
|
||||
|
||||
#define CNTHCTL_CNTPCT (1 << 0)
|
||||
#define CNTHCTL_EVNTEN (1 << 2)
|
||||
#define CNTHCTL_EVNTDIR (1 << 3)
|
||||
|
||||
// Returns the value of the EL2 Timer Control Register (CNTHCTL_EL2)
|
||||
unsigned int getEL2Ctrl(void);
|
||||
|
||||
// Sets the value of EL2 Timer Control Register (CNTHCTL_EL2)
|
||||
// value - The value to be written into CNTHCTL_EL2
|
||||
void setEL2Ctrl(unsigned int value);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Non-Secure Physical Timer
|
||||
// ------------------------------------------------------------
|
||||
// Accessible from EL3, EL2 and EL1
|
||||
|
||||
// Returns the value of Non-Secure EL1 Physical Compare Value Register (CNTP_CVAL_EL0)
|
||||
unsigned long long getNSEL1PhysicalCompValue(void);
|
||||
|
||||
// Sets the value of the Non-Secure EL1 Physical Compare Value Register (CNTP_CVAL_EL0)
|
||||
// value - The value to be written into CNTP_CVAL_EL0
|
||||
void setNSEL1PhysicalCompValue(unsigned long long value);
|
||||
|
||||
// Returns the value of Non-Secure EL1 Physical Timer Value Register (CNTP_TVAL_EL0)
|
||||
unsigned int getNSEL1PhysicalTimerValue(void);
|
||||
|
||||
// Sets the value of the Non-Secure EL1 Physical Timer Value Register (CNTP_TVAL_EL0)
|
||||
// value - The value to be written into CNTP_TVAL_EL0
|
||||
void setNSEL1PhysicalTimerValue(unsigned int value);
|
||||
|
||||
#define CNTP_CTL_ENABLE (1 << 0)
|
||||
#define CNTP_CTL_MASK (1 << 1)
|
||||
#define CNTP_CTL_STATUS (1 << 2)
|
||||
|
||||
// Returns the value of Non-Secure EL1 Physical Timer Control Register (CNTP_CTL_EL0)
|
||||
unsigned int getNSEL1PhysicalTimerCtrl(void);
|
||||
|
||||
// Sets the value of the Non-Secure EL1 Physical Timer Control Register (CNTP_CTL_EL0)
|
||||
// value - The value to be written into CNTP_CTL_EL0
|
||||
void setNSEL1PhysicalTimerCtrl(unsigned int value);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Secure Physical Timer
|
||||
// ------------------------------------------------------------
|
||||
// Accessible from EL3, and configurably from secure EL1
|
||||
|
||||
// Returns the value of Secure EL1 Physical Compare Value Register (CNTPS_CVAL_EL1)
|
||||
unsigned long long getSEL1PhysicalCompValue(void);
|
||||
|
||||
// Sets the value of the Secure EL1 Physical Compare Value Register (CNTPS_CVAL_EL1)
|
||||
// value - The value to be written into CNTPS_CVAL_EL1
|
||||
void setSEL1PhysicalCompValue(unsigned long long value);
|
||||
|
||||
// Returns the value of Secure EL1 Physical Timer Value Register (CNTPS_TVAL_EL1)
|
||||
unsigned int getSEL1PhysicalTimerValue(void);
|
||||
|
||||
// Sets the value of the Secure EL1 Physical Timer Value Register (CNTPS_TVAL_EL1)
|
||||
// value - The value to be written into CNTPS_TVAL_EL1
|
||||
void setSEL1PhysicalTimerValue(unsigned int value);
|
||||
|
||||
#define CNTPS_CTL_ENABLE (1 << 0)
|
||||
#define CNTPS_CTL_MASK (1 << 1)
|
||||
#define CNTPS_CTL_STATUS (1 << 2)
|
||||
|
||||
// Returns the value of Secure EL1 Physical Timer Control Register (CNTPS_CTL_EL1)
|
||||
unsigned int getSEL1PhysicalTimerCtrl(void);
|
||||
|
||||
// Sets the value of the Secure EL1 Physical Timer Control Register (CNTPS_CTL_EL1)
|
||||
// value - The value to be written into CNTPS_CTL_EL1
|
||||
void setSEL1PhysicalTimerCtrl(unsigned int value);
|
||||
|
||||
// The SCR_EL3 register controls whether CNTPS_TVAL_EL1,
|
||||
// CNTPS_CTL_EL1, and CNTPS_CVAL_EL1 can be accessed by secure
|
||||
// EL1.
|
||||
// Only accessible from EL3
|
||||
|
||||
#define SCR_ENABLE_SECURE_EL1_ACCESS (1)
|
||||
#define SCR_DISABLE_SECURE_EL1_ACCESS (0)
|
||||
|
||||
// Sets the values of the SCR_EL3.ST bit (bit 11) based on the value passed in 'config'
|
||||
void configSecureEL1TimerAccess(unsigned int config);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Virtual Timer
|
||||
// ------------------------------------------------------------
|
||||
// Accessible from Non-Secure EL1 and EL2
|
||||
|
||||
// Returns the value of EL1 Virtual Compare Value Register (CNTV_CVAL)
|
||||
unsigned long long getEL1VirtualCompValue(void);
|
||||
|
||||
// Sets the value of the EL1 Virtual Compare Value Register (CNTV_CVAL)
|
||||
// value - The value to be written into CNTV_CVAL
|
||||
void setEL1VirtualCompValue(unsigned long long value);
|
||||
|
||||
// Returns the value of EL1 Virtual Timer Value Register (CNTV_TVAL)
|
||||
unsigned int getEL1VirtualTimerValue(void);
|
||||
|
||||
// Sets the value of the EL1 Virtual Timer Value Register (CNTV_TVAL)
|
||||
// value - The value to be written into CNTV_TVAL
|
||||
void setEL1VirtualTimerValue(unsigned int value);
|
||||
|
||||
#define CNTV_CTL_ENABLE (1 << 0)
|
||||
#define CNTV_CTL_MASK (1 << 1)
|
||||
#define CNTV_CTL_STATUS (1 << 2)
|
||||
|
||||
// Returns the value of EL1 Virtual Timer Control Register (CNTV_CTL)
|
||||
unsigned int getEL1VirtualTimerCtrl(void);
|
||||
|
||||
// Sets the value of the EL1 Virtual Timer Control Register (CNTV_CTL)
|
||||
// value - The value to be written into CNTV_CTL
|
||||
void setEL1VirtualTimerCtrl(unsigned int value);
|
||||
|
||||
//
|
||||
// Virtual timer functions to be called by EL2
|
||||
//
|
||||
|
||||
// CNTVCT_EL2 holds the offset the virtual count is from the physical count
|
||||
// Only accessable from EL2 and EL3
|
||||
|
||||
// Returns the value of the Counter Virtual Offset Register (CNTVOFF_EL2)
|
||||
unsigned long long getVirtualCounterOffset(void);
|
||||
|
||||
// Sets the value of the Counter Virtual Offset Register (CNTVOFF_EL2)
|
||||
// offset - The value to be written into CNTVOFF_EL2
|
||||
void setVirtualCounterOffset(unsigned long long offset);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Hypervisor (EL2) Timer
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// Returns the value of EL2 Physical Compare Value Register (CNTHP_CVAL_EL2)
|
||||
unsigned long long getEL2PhysicalCompValue(void);
|
||||
|
||||
// Sets the value of the EL2 Physical Compare Value Register (CNTHP_CVAL_EL2)
|
||||
// value - The value to be written into CNTHP_CVAL_EL2
|
||||
void setEL2PhysicalCompValue(unsigned long long value);
|
||||
|
||||
// Returns the value of EL2 Physical Timer Value Register (CNTHP_TVAL_EL2)
|
||||
unsigned int getEL2PhysicalTimerValue(void);
|
||||
|
||||
#define CNTHP_CTL_ENABLE (1 << 0)
|
||||
#define CNTHP_CTL_MASK (1 << 1)
|
||||
#define CNTHP_CTL_STATUS (1 << 2)
|
||||
|
||||
// Sets the value of the EL2 Physical Timer Value Register (CNTHP_TVAL_EL2)
|
||||
// value - The value to be written into CNTHP_TVAL_EL2
|
||||
void setEL2PhysicalTimerValue(unsigned int value);
|
||||
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// End of armv8_aarch64_SystemTimer.h
|
||||
// ------------------------------------------------------------
|
||||
138
ports/cortex_a5x/ac6/example_build/sample_threadx/el3_vectors.S
Normal file
138
ports/cortex_a5x/ac6/example_build/sample_threadx/el3_vectors.S
Normal file
@@ -0,0 +1,138 @@
|
||||
// ------------------------------------------------------------
|
||||
// Exceptions workbook exercise
|
||||
//
|
||||
// Copyright ARM LTD, 2012
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.section VECTORS,"ax"
|
||||
.align 12
|
||||
|
||||
|
||||
.global el3_vectors
|
||||
el3_vectors:
|
||||
|
||||
.global fiqHandler
|
||||
.global irqHandler
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Current EL with SP0
|
||||
// ------------------------------------------------------------
|
||||
.balign 128
|
||||
sync_current_el_sp0:
|
||||
B . // Synchronous
|
||||
|
||||
.balign 128
|
||||
irq_current_el_sp0:
|
||||
B irqFirstLevelHandler // IRQ
|
||||
|
||||
.balign 128
|
||||
fiq_current_el_sp0:
|
||||
B fiqFirstLevelHandler // FIQ
|
||||
|
||||
.balign 128
|
||||
serror_current_el_sp0:
|
||||
B . // SError
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Current EL with SPx
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.balign 128
|
||||
sync_current_el_spx:
|
||||
B . // Synchronous
|
||||
|
||||
.balign 128
|
||||
irq_current_el_spx:
|
||||
B irqFirstLevelHandler // IRQ
|
||||
|
||||
.balign 128
|
||||
fiq_current_el_spx:
|
||||
B fiqFirstLevelHandler // FIQ
|
||||
|
||||
.balign 128
|
||||
serror_current_el_spx:
|
||||
B . // SError
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Lower EL using AArch64
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.balign 128
|
||||
sync_lower_el_aarch64:
|
||||
B .
|
||||
|
||||
.balign 128
|
||||
irq_lower_el_aarch64:
|
||||
B irqFirstLevelHandler // IRQ
|
||||
|
||||
.balign 128
|
||||
fiq_lower_el_aarch64:
|
||||
B fiqFirstLevelHandler // FIQ
|
||||
|
||||
.balign 128
|
||||
serror_lower_el_aarch64:
|
||||
B . // SError
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Lower EL using AArch32
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.balign 128
|
||||
sync_lower_el_aarch32:
|
||||
B .
|
||||
|
||||
.balign 128
|
||||
irq_lower_el_aarch32:
|
||||
B irqFirstLevelHandler // IRQ
|
||||
|
||||
.balign 128
|
||||
fiq_lower_el_aarch32:
|
||||
B fiqFirstLevelHandler // FIQ
|
||||
|
||||
.balign 128
|
||||
serror_lower_el_aarch32:
|
||||
B . // SError
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
irqFirstLevelHandler:
|
||||
STP x29, x30, [sp, #-16]!
|
||||
BL _tx_thread_context_save
|
||||
|
||||
BL irqHandler
|
||||
|
||||
B _tx_thread_context_restore
|
||||
|
||||
fiqFirstLevelHandler:
|
||||
STP x29, x30, [sp, #-16]!
|
||||
STP x18, x19, [sp, #-16]!
|
||||
STP x16, x17, [sp, #-16]!
|
||||
STP x14, x15, [sp, #-16]!
|
||||
STP x12, x13, [sp, #-16]!
|
||||
STP x10, x11, [sp, #-16]!
|
||||
STP x8, x9, [sp, #-16]!
|
||||
STP x6, x7, [sp, #-16]!
|
||||
STP x4, x5, [sp, #-16]!
|
||||
STP x2, x3, [sp, #-16]!
|
||||
STP x0, x1, [sp, #-16]!
|
||||
|
||||
BL fiqHandler
|
||||
|
||||
LDP x0, x1, [sp], #16
|
||||
LDP x2, x3, [sp], #16
|
||||
LDP x4, x5, [sp], #16
|
||||
LDP x6, x7, [sp], #16
|
||||
LDP x8, x9, [sp], #16
|
||||
LDP x10, x11, [sp], #16
|
||||
LDP x12, x13, [sp], #16
|
||||
LDP x14, x15, [sp], #16
|
||||
LDP x16, x17, [sp], #16
|
||||
LDP x18, x19, [sp], #16
|
||||
LDP x29, x30, [sp], #16
|
||||
ERET
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// End of file
|
||||
// ------------------------------------------------------------
|
||||
|
||||
419
ports/cortex_a5x/ac6/example_build/sample_threadx/gic400_gic.c
Normal file
419
ports/cortex_a5x/ac6/example_build/sample_threadx/gic400_gic.c
Normal file
@@ -0,0 +1,419 @@
|
||||
// ----------------------------------------------------------
|
||||
// GIC400 - Generic Interrupt Controller
|
||||
//
|
||||
// GIC Exercise
|
||||
// ----------------------------------------------------------
|
||||
|
||||
#include "gic400_gic.h"
|
||||
|
||||
struct gic400_dist_if
|
||||
{
|
||||
volatile unsigned int GICD_CTLR; // +0x000 - RW - Distributor Control Register
|
||||
const volatile unsigned int GICD_TYPRE; // +0x004 - RO - Interrupt Controller Type Register
|
||||
const volatile unsigned int GICD_IIDR; // +0x008 - RO - Distributor Implementer Identification Register
|
||||
|
||||
const volatile unsigned int padding0[29];
|
||||
|
||||
volatile unsigned int GICD_IGROUPR[32]; // +0x080 - RW - Interrupt Groupt Registers (Security Registers in GICv1)
|
||||
|
||||
volatile unsigned int GICD_ISENABLER[32]; // +0x100 - RW - Interrupt Set-Enable Registers
|
||||
volatile unsigned int GICD_ICENABLER[32]; // +0x180 - RW - Interrupt Clear-Enable Registers
|
||||
volatile unsigned int GICD_ISPENDR[32]; // +0x200 - RW - Interrupt Set-Pending Registers
|
||||
volatile unsigned int GICD_ICPENDR[32]; // +0x280 - RW - Interrupt Clear-Pending Registers
|
||||
volatile unsigned int GICD_ISACTIVER[32]; // +0x300 - RW - Interrupt Set-Active Register
|
||||
volatile unsigned int GICD_ICACTIVER[32]; // +0x380 - RW - Interrupt Clear-Active Register
|
||||
|
||||
volatile unsigned char GICD_IPRIORITYR[1024]; // +0x400 - RW - Interrupt Priority Registers
|
||||
volatile unsigned int GICD_ITARGETSR[256]; // +0x800 - RW - Interrupt Processor Targets Registers
|
||||
volatile unsigned int GICD_ICFGR[64]; // +0xC00 - RW - Interrupt Configuration Registers
|
||||
|
||||
const volatile unsigned int padding2[128];
|
||||
|
||||
volatile unsigned int GICD_SGIR; // +0xF00 - WO - Software Generated Interrupt Register
|
||||
|
||||
};
|
||||
|
||||
struct gic400_physical_cpu_if
|
||||
{
|
||||
volatile unsigned int GICC_CTLR; // +0x000 - RW - CPU Interface Control Register
|
||||
volatile unsigned int GICC_PMR; // +0x004 - RW - Interrupt Priority Mask Register
|
||||
volatile unsigned int GICC_BPR; // +0x008 - RW - Binary Point Register
|
||||
const volatile unsigned int GICC_IAR; // +0x00C - RO - Interrupt Acknowledge Register
|
||||
volatile unsigned int GICC_EOIR; // +0x010 - WO - End of Interrupt Register
|
||||
const volatile unsigned int GICC_RPR; // +0x014 - RO - Running Priority Register
|
||||
const volatile unsigned int GICC_HPPIR; // +0x018 - RO - Highest Pending Interrupt Register
|
||||
volatile unsigned int GICC_ABPR; // +0x01C - RW - Aliased Binary Point Register
|
||||
const volatile unsigned int GICC_AIAR; // +0x020 - RO - Aliased Interrupt Acknowledge Register
|
||||
volatile unsigned int GICC_AEOIR; // +0x024 - WO - Aliased End of Interrupt Register
|
||||
const volatile unsigned int GICC_AHPPIR; // +0x028 - RO - Aliased Highest Pending Interrupt Register
|
||||
|
||||
const volatile unsigned int padding0[52];
|
||||
|
||||
const volatile unsigned int GICC_IIDR; // +0x0FC - RO - CPU Interface Identification Register
|
||||
};
|
||||
|
||||
struct gic400_dist_if* gic_dist;
|
||||
struct gic400_physical_cpu_if* gic_cpu;
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
void setGICAddr(void* dist, void* cpu)
|
||||
{
|
||||
gic_dist = (struct gic400_dist_if*)dist;
|
||||
gic_cpu = (struct gic400_physical_cpu_if*)cpu;
|
||||
return;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// Global enable of the Interrupt Distributor
|
||||
void enableGIC(void)
|
||||
{
|
||||
gic_dist->GICD_CTLR = 3;
|
||||
return;
|
||||
}
|
||||
|
||||
// Global disable of the Interrupt Distributor
|
||||
void disableGIC(void)
|
||||
{
|
||||
gic_dist->GICD_CTLR = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// Enables the interrupt source number ID
|
||||
void enableIntID(unsigned int ID)
|
||||
{
|
||||
unsigned int bank;
|
||||
|
||||
bank = ID/32; // There are 32 IDs per register, need to work out which register to access
|
||||
ID = ID & 0x1f; // ... and which bit within the register
|
||||
|
||||
ID = 1 << ID; // Move a '1' into the correct bit position
|
||||
|
||||
gic_dist->GICD_ISENABLER[bank] = ID;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Disables the interrupt source number ID
|
||||
void disableIntID(unsigned int ID)
|
||||
{
|
||||
unsigned int bank;
|
||||
|
||||
bank = ID/32; // There are 32 IDs per register, need to work out which register to access
|
||||
ID = ID & 0x1f; // ... and which bit within the register
|
||||
|
||||
ID = 1 << ID; // Move a '1' into the correct bit position
|
||||
|
||||
gic_dist->GICD_ICENABLER[bank] = ID;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// Sets the priority of the specified ID
|
||||
void setIntPriority(unsigned int ID, unsigned int priority)
|
||||
{
|
||||
if (ID > 1020) // Check ID in range
|
||||
return;
|
||||
|
||||
// The priority registers allows byte accesses
|
||||
// meaning using a char array we can directly
|
||||
// reference the correct entry
|
||||
gic_dist->GICD_IPRIORITYR[ID] = priority;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Returns the priority of the specified ID
|
||||
unsigned int getIntPriority(unsigned int ID)
|
||||
{
|
||||
if (ID > 1020) // Check ID in range
|
||||
return 0;
|
||||
|
||||
return gic_dist->GICD_IPRIORITYR[ID];
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// Sets the target CPUs of the specified ID
|
||||
// For 'target' use one of the above defines
|
||||
void setIntTarget(unsigned int ID, unsigned int target)
|
||||
{
|
||||
unsigned int bank, tmp;
|
||||
|
||||
target = target & 0xFF; // Target field is 8-bits, mask off unused bit
|
||||
bank = ID/4; // There are 4 IDs per register, need to work out which register to access
|
||||
ID = ID & 0x3; // ... and which field within the register
|
||||
ID = ID * 8; // Convert from which field to a bit offset (8-bits per field)
|
||||
|
||||
target = target << ID; // Move prioity value into correct bit position
|
||||
|
||||
tmp = gic_dist->GICD_ITARGETSR[bank]; // Read the current value in the register
|
||||
tmp = tmp & ~(0xFF << ID); // Blank out the field holding the value we're modifying
|
||||
tmp = tmp | target; // OR in the new target
|
||||
gic_dist->GICD_ITARGETSR[bank] = tmp;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Returns the target CPUs of the specified ID
|
||||
unsigned int getIntTarget(unsigned int ID)
|
||||
{
|
||||
unsigned int bank, tmp;
|
||||
|
||||
bank = ID/4; // There are 4 IDs per register, need to work out which register to access
|
||||
ID = ID & 0x3; // ... and which field within the register
|
||||
ID = ID * 8; // Convert from which field to a bit offset (8-bits per field)
|
||||
|
||||
tmp = gic_dist->GICD_ITARGETSR[bank];
|
||||
|
||||
tmp = tmp >> ID; // Shift desired field to bit position 0
|
||||
tmp = tmp & 0xFF; // Mask off the other bits
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// Configures the specified ID as being level or edge triggered
|
||||
void configureSPI(unsigned int ID, unsigned int conf)
|
||||
{
|
||||
unsigned int bank, tmp;
|
||||
|
||||
conf = conf & 0x3; // Mask out unused bits
|
||||
|
||||
bank = ID/16; // There are 16 IDs per register, need to work out which register to access
|
||||
ID = ID & 0xF; // ... and which field within the register
|
||||
ID = ID * 2; // Convert from which field to a bit offset (2-bits per field)
|
||||
|
||||
conf = conf << ID; // Move configuration value into correct bit position
|
||||
|
||||
tmp = gic_dist-> GICD_ICFGR[bank]; // Read current vlase
|
||||
tmp = tmp & ~(0x3 << ID); // Clear the bits for the specified field
|
||||
tmp = tmp | conf; // OR in new configuration
|
||||
gic_dist-> GICD_ICFGR[bank] = tmp; // Write updated value back
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// Sets the pending bit of the specified ID
|
||||
void setIntPending(unsigned int ID)
|
||||
{
|
||||
unsigned int bank;
|
||||
|
||||
bank = ID/32; // There are 32 IDs per register, need to work out which register to access
|
||||
ID = ID & 0x1f; // ... and which bit within the register
|
||||
|
||||
ID = 1 << ID; // Move a '1' into the correct bit position
|
||||
|
||||
gic_dist->GICD_ISPENDR[bank] = ID;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Clears the pending bit of the specified ID
|
||||
void clearIntPending(unsigned int ID)
|
||||
{
|
||||
unsigned int bank;
|
||||
|
||||
bank = ID/32; // There are 32 IDs per register, need to work out which register to access
|
||||
ID = ID & 0x1f; // ... and which bit within the register
|
||||
|
||||
ID = 1 << ID; // Move a '1' into the correct bit position
|
||||
|
||||
gic_dist->GICD_ICPENDR[bank] = ID;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Returns the value of the status bit of the specifed ID
|
||||
unsigned int getIntPending(unsigned int ID)
|
||||
{
|
||||
unsigned int bank, tmp;
|
||||
|
||||
bank = ID/32; // There are 32 IDs per register, need to work out which register to access
|
||||
ID = ID & 0x1f; // ... and which bit within the register
|
||||
|
||||
tmp = gic_dist->GICD_ICPENDR[bank]; // Read the register containing the ID we are interested in
|
||||
tmp = tmp >> ID; // Shift the status bit for specified ID to position 0
|
||||
tmp = tmp & 0x1; // Mask off the rest of the register
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// Send a software generate interrupt
|
||||
void sendSGI(unsigned int ID, unsigned int cpu_list, unsigned int filter_list, unsigned int SATT)
|
||||
{
|
||||
// Ensure unused bits are clear, and shift into correct bit position
|
||||
ID = ID & 0xF;
|
||||
SATT = (SATT & 0x1) << 15;
|
||||
cpu_list = (cpu_list & 0xFF) << 16;
|
||||
filter_list = (filter_list & 0x3) << 24;
|
||||
|
||||
// Combine fields
|
||||
ID = ID | SATT | cpu_list | filter_list;
|
||||
|
||||
gic_dist->GICD_SGIR = ID;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// Sets the specified ID as secure
|
||||
void makeIntGroup0(unsigned int ID)
|
||||
{
|
||||
unsigned int bank, tmp;
|
||||
|
||||
bank = ID/32; // There are 32 IDs per register, need to work out which register to access
|
||||
ID = ID & 0x1f; // ... and which bit within the register
|
||||
|
||||
ID = 1 << ID; // Move a '1' into the correct bit position
|
||||
ID = ~ID; // Invert to get mask
|
||||
|
||||
tmp = gic_dist->GICD_IGROUPR[bank]; // Read current value
|
||||
tmp = tmp & ID;
|
||||
gic_dist->GICD_IGROUPR[bank] = tmp;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the specified ID as non-secure
|
||||
void makeIntGroup1(unsigned int ID)
|
||||
{
|
||||
unsigned int bank, tmp;
|
||||
|
||||
bank = ID/32; // There are 32 IDs per register, need to work out which register to access
|
||||
ID = ID & 0x1f; // ... and which bit within the register
|
||||
|
||||
ID = 1 << ID; // Move a '1' into the correct bit position
|
||||
|
||||
tmp = gic_dist->GICD_IGROUPR[bank]; // Read current value
|
||||
tmp = tmp | ID; // Or with bit mask to set the bit
|
||||
gic_dist->GICD_IGROUPR[bank] = tmp; // Write-back
|
||||
}
|
||||
|
||||
// Returns the security of the specified ID
|
||||
unsigned int getIntGroup(unsigned int ID)
|
||||
{
|
||||
// TBD
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// CPU Interface functions
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// Enables the CPU interface
|
||||
// Must been done one each core seperately
|
||||
void enableCPUInterface(void)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
tmp = gic_cpu->GICC_CTLR;
|
||||
tmp = tmp | 0x1; // Set bit 0
|
||||
gic_cpu->GICC_CTLR = tmp;
|
||||
}
|
||||
|
||||
// Enables the group 1 (non-secure) CPU interface
|
||||
// This function can only be called from the Secure world
|
||||
// Must been done one each core seperately
|
||||
void enableNonSecureCPUInterface(void)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
tmp = gic_cpu->GICC_CTLR;
|
||||
tmp = tmp | 0x2; // Set bit 1
|
||||
gic_cpu->GICC_CTLR = tmp;
|
||||
}
|
||||
|
||||
// Disables the processor interface
|
||||
void disableCPUInterface(void)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
tmp = gic_cpu->GICC_CTLR;
|
||||
tmp = tmp & 0xFFFFFFFFE; // Clear bit 0
|
||||
gic_cpu->GICC_CTLR = tmp;
|
||||
}
|
||||
|
||||
// Enables the sending of secure interrupts as FIQs
|
||||
void enableSecureFIQs(void)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
tmp = gic_cpu->GICC_CTLR;
|
||||
tmp = tmp | 0x8; // Set bit 3
|
||||
gic_cpu->GICC_CTLR = tmp;
|
||||
}
|
||||
|
||||
// Disables the sending of secure interrupts as FIQs
|
||||
void disableSecureFIQs(void)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
tmp = gic_cpu->GICC_CTLR;
|
||||
tmp = tmp | 0xFFFFFFFF7; // Clear bit 3
|
||||
gic_cpu->GICC_CTLR = tmp;
|
||||
}
|
||||
|
||||
// Returns the value of the Interrupt Acknowledge Register
|
||||
unsigned int readIntAck(void)
|
||||
{
|
||||
return gic_cpu->GICC_IAR;
|
||||
}
|
||||
|
||||
// Writes ID to the End Of Interrupt register
|
||||
void writeEOI(unsigned int ID)
|
||||
{
|
||||
gic_cpu->GICC_EOIR = ID;
|
||||
return;
|
||||
}
|
||||
|
||||
// Returns the value of the Aliased Interrupt Acknowledge Register
|
||||
unsigned int readAliasedIntAck(void)
|
||||
{
|
||||
return gic_cpu->GICC_AIAR;
|
||||
}
|
||||
|
||||
// Writes ID to the Aliased End Of Interrupt register
|
||||
void writeAliasedEOI(unsigned int ID)
|
||||
{
|
||||
gic_cpu->GICC_AEOIR = ID;
|
||||
return;
|
||||
}
|
||||
|
||||
// Sets the Priority mask register for the core run on
|
||||
// The reset value masks ALL interrupts!
|
||||
void setPriorityMask(unsigned int priority)
|
||||
{
|
||||
gic_cpu->GICC_PMR = (priority & 0xFF);
|
||||
return;
|
||||
}
|
||||
|
||||
// Sets the Binary Point Register for the core run on
|
||||
void setBinaryPoint(unsigned int priority)
|
||||
{
|
||||
gic_cpu->GICC_BPR = (priority & 0xFF);
|
||||
return;
|
||||
}
|
||||
|
||||
// Sets the Aliased Binary Point Register for the core run on
|
||||
void setAliasedBinaryPoint(unsigned int priority)
|
||||
{
|
||||
gic_cpu->GICC_ABPR = (priority & 0xFF);
|
||||
return;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// End of gic400_gic.c
|
||||
// ------------------------------------------------------------
|
||||
192
ports/cortex_a5x/ac6/example_build/sample_threadx/gic400_gic.h
Normal file
192
ports/cortex_a5x/ac6/example_build/sample_threadx/gic400_gic.h
Normal file
@@ -0,0 +1,192 @@
|
||||
// ----------------------------------------------------------
|
||||
// GIC400 - Generic Interrupt Controller
|
||||
// Header
|
||||
//
|
||||
// Martin Weidmann Dec 2011
|
||||
// ----------------------------------------------------------
|
||||
|
||||
#ifndef __gic400_gic_h
|
||||
#define __gic400_gic_h
|
||||
|
||||
#define GIC_GIC400_PPI0 (0)
|
||||
#define GIC_GIC400_PPI1 (1)
|
||||
#define GIC_GIC400_PPI2 (2)
|
||||
#define GIC_GIC400_PPI3 (3)
|
||||
#define GIC_GIC400_PPI4 (4)
|
||||
#define GIC_GIC400_PPI5 (5)
|
||||
#define GIC_GIC400_PPI6 (6)
|
||||
#define GIC_GIC400_PPI7 (7)
|
||||
#define GIC_GIC400_PPI8 (8)
|
||||
#define GIC_GIC400_PPI9 (9)
|
||||
#define GIC_GIC400_PPI10 (10)
|
||||
#define GIC_GIC400_PPI11 (11)
|
||||
#define GIC_GIC400_PPI12 (12)
|
||||
#define GIC_GIC400_PPI13 (13)
|
||||
#define GIC_GIC400_PPI14 (14)
|
||||
#define GIC_GIC400_PPI15 (15)
|
||||
#define GIC_GIC400_PPI16 (16)
|
||||
#define GIC_GIC400_PPI17 (17)
|
||||
#define GIC_GIC400_PPI18 (18)
|
||||
#define GIC_GIC400_PPI19 (19)
|
||||
#define GIC_GIC400_PPI20 (20)
|
||||
#define GIC_GIC400_PPI21 (21)
|
||||
#define GIC_GIC400_PPI22 (22)
|
||||
#define GIC_GIC400_PPI23 (23)
|
||||
#define GIC_GIC400_PPI24 (24)
|
||||
#define GIC_GIC400_PPI25 (25)
|
||||
#define GIC_GIC400_PPI26 (26)
|
||||
#define GIC_GIC400_PPI27 (27)
|
||||
#define GIC_GIC400_PPI28 (28)
|
||||
#define GIC_GIC400_PPI29 (29)
|
||||
#define GIC_GIC400_PPI30 (30)
|
||||
#define GIC_GIC400_PPI31 (31)
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// Sets the address of the GIC's distributor and CPU interfaces
|
||||
void setGICAddr(void* dist, void* cpu);
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// Global enable of the Interrupt Distributor
|
||||
void enableGIC(void);
|
||||
|
||||
// Global disable of the Interrupt Distributor
|
||||
void disableGIC(void);
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// Enables the interrupt source number ID
|
||||
void enableIntID(unsigned int ID);
|
||||
|
||||
// Disables the interrupt source number ID
|
||||
void disableIntID(unsigned int ID);
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// Sets the priority of the specified ID
|
||||
void setIntPriority(unsigned int ID, unsigned int priority);
|
||||
|
||||
// Returns the priority of the specified ID
|
||||
unsigned int getIntPriority(unsigned int ID);
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
||||
#define GIC_GIC400_TARGET_CPU0 (0x01)
|
||||
#define GIC_GIC400_TARGET_CPU1 (0x02)
|
||||
#define GIC_GIC400_TARGET_CPU2 (0x04)
|
||||
#define GIC_GIC400_TARGET_CPU3 (0x08)
|
||||
#define GIC_GIC400_TARGET_CPU4 (0x10)
|
||||
#define GIC_GIC400_TARGET_CPU5 (0x20)
|
||||
#define GIC_GIC400_TARGET_CPU6 (0x40)
|
||||
#define GIC_GIC400_TARGET_CPU7 (0x80)
|
||||
|
||||
// Sets the target CPUs of the specified ID
|
||||
// For 'target' use one of the above defines
|
||||
void setIntTarget(unsigned int ID, unsigned int target);
|
||||
|
||||
// Returns the target CPUs of the specified ID
|
||||
unsigned int getIntTarget(unsigned int ID);
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
||||
#define GIC_GIC400_CONFIG_LEVEL (0)
|
||||
#define GIC_GIC400_CONFIG_EDGE (2)
|
||||
|
||||
// Configures the specified ID as being level or edge triggered
|
||||
|
||||
void configureSPI(unsigned int ID, unsigned int conf);
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// Sets the pending bit of the specified ID
|
||||
void setIntPending(unsigned int ID);
|
||||
|
||||
// Clears the pending bit of the specified ID
|
||||
void clearIntPending(unsigned int ID);
|
||||
|
||||
#define GIC_GIC400_PENDING_IS_SET (1)
|
||||
#define GIC_GIC400_PENDING_IS_CLEAR (0)
|
||||
|
||||
// Returns the value of the status bit of the specified ID
|
||||
unsigned int getIntPending(unsigned int ID);
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
||||
#define GIC_GIC400_SGI_SECURE (0)
|
||||
#define GIC_GIC400_SGI_NONSECURE (1)
|
||||
#define GIC_GIC400_SGI_FILTER_USE_LIST (0)
|
||||
#define GIC_GIC400_SGI_FILTER_NOT_THIS_CPU (1)
|
||||
#define GIC_GIC400_SGI_FILTER_THIS_CPU (2)
|
||||
#define GIC_GIC400_SGI_CPU0 (0x01)
|
||||
#define GIC_GIC400_SGI_CPU1 (0x02)
|
||||
#define GIC_GIC400_SGI_CPU2 (0x04)
|
||||
#define GIC_GIC400_SGI_CPU3 (0x08)
|
||||
#define GIC_GIC400_SGI_CPU4 (0x10)
|
||||
#define GIC_GIC400_SGI_CPU5 (0x20)
|
||||
#define GIC_GIC400_SGI_CPU6 (0x40)
|
||||
#define GIC_GIC400_SGI_CPU7 (0x80)
|
||||
|
||||
// Send a software generate interrupt
|
||||
void sendSGI(unsigned int ID, unsigned int cpu_list, unsigned int filter_list, unsigned int SATT);
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// Sets the specified ID as secure
|
||||
void makeIntGroup0(unsigned int ID);
|
||||
|
||||
// Set the specified ID as non-secure
|
||||
void makeIntGroup1(unsigned int ID);
|
||||
|
||||
// Returns the security of the specified ID
|
||||
unsigned int getIntGroup(unsigned int ID);
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// CPU Interface functions
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// Enables the processor interface
|
||||
// Must been done one each core seperately
|
||||
void enableCPUInterface(void);
|
||||
|
||||
// Enables the group 1 (non-secure) CPU interface
|
||||
// This function can only be called from the Secure world
|
||||
// Must been done one each core seperately
|
||||
void enableNonSecureCPUInterface(void);
|
||||
|
||||
// Disables the processor interface
|
||||
void disableCPUInterface(void);
|
||||
|
||||
// Enables the sending of secure interrupts as FIQs
|
||||
void enableSecureFIQs(void);
|
||||
|
||||
// Disables the sending of secure interrupts as FIQs
|
||||
void disableSecureFIQs(void);
|
||||
|
||||
// Returns the value of the Interrupt Acknowledge Register
|
||||
unsigned int readIntAck(void);
|
||||
|
||||
// Writes ID to the End Of Interrupt register
|
||||
void writeEOI(unsigned int ID);
|
||||
|
||||
// Returns the value of the Aliased Interrupt Acknowledge Register
|
||||
unsigned int readAliasedIntAck(void);
|
||||
|
||||
// Writes ID to the Aliased End Of Interrupt register
|
||||
void writeAliasedEOI(unsigned int ID);
|
||||
|
||||
// Sets the Priority mask register for the core run on
|
||||
// The reset value masks ALL interrupts!
|
||||
void setPriorityMask(unsigned int priority);
|
||||
|
||||
// Sets the Binary Point Register for the core run on
|
||||
void setBinaryPoint(unsigned int priority);
|
||||
|
||||
// Sets the Aliased Binary Point Register for the core run on
|
||||
void setAliasedBinaryPoint(unsigned int priority);
|
||||
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// End of gic400_gic.h
|
||||
// ----------------------------------------------------------
|
||||
104
ports/cortex_a5x/ac6/example_build/sample_threadx/hw_setup.c
Normal file
104
ports/cortex_a5x/ac6/example_build/sample_threadx/hw_setup.c
Normal file
@@ -0,0 +1,104 @@
|
||||
//
|
||||
// Copyright ARM LTD, 2013
|
||||
|
||||
#include <stdio.h>
|
||||
#include "gic400_gic.h"
|
||||
#include "armv8_aarch64_SystemTimer.h"
|
||||
#include "tx_api.h"
|
||||
|
||||
|
||||
void _tx_timer_interrupt(void);
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
void hw_setup(void)
|
||||
{
|
||||
long long current_time;
|
||||
|
||||
|
||||
setGICAddr((void*)0x2C001000, (void*)0x2C002000);
|
||||
|
||||
//
|
||||
// Configure interrupt controller (GICv2 assumed)
|
||||
//
|
||||
enableGIC();
|
||||
enableCPUInterface();
|
||||
enableNonSecureCPUInterface();
|
||||
setPriorityMask(0xFF);
|
||||
enableSecureFIQs();
|
||||
|
||||
// Secure Physical Timer (ID 29)
|
||||
enableIntID(29);
|
||||
setIntPriority(29, 0);
|
||||
makeIntGroup0(29);
|
||||
|
||||
// Non-Secure Physical Timer (ID 30)
|
||||
enableIntID(30);
|
||||
setIntPriority(30, 0);
|
||||
makeIntGroup1(30);
|
||||
|
||||
|
||||
//
|
||||
// Configure timer
|
||||
//
|
||||
configSecureEL1TimerAccess(SCR_ENABLE_SECURE_EL1_ACCESS);
|
||||
|
||||
current_time = getPhysicalCount();
|
||||
|
||||
// Configure the Secure Physical Timer
|
||||
setSEL1PhysicalCompValue(current_time + 10000);
|
||||
setSEL1PhysicalTimerCtrl(CNTPS_CTL_ENABLE);
|
||||
|
||||
// Configure the Non-Secure Physical Timer
|
||||
setNSEL1PhysicalCompValue(current_time + 20000);
|
||||
setNSEL1PhysicalTimerCtrl(CNTP_CTL_ENABLE);
|
||||
|
||||
|
||||
// NOTE:
|
||||
// This code assumes that the IRQ and FIQ exceptions
|
||||
// have been routed to the appropriate EL. In this
|
||||
// example that is done in the startup.s file
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
void fiqHandler(void)
|
||||
{
|
||||
unsigned int ID;
|
||||
|
||||
// printf("Hello from the FIQ handler\n");
|
||||
|
||||
ID = readIntAck();
|
||||
setSEL1PhysicalTimerCtrl(0); // Disable timer to clear interrupt
|
||||
writeEOI(ID);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
void irqHandler(void)
|
||||
{
|
||||
unsigned int ID;
|
||||
unsigned long long current_time;
|
||||
|
||||
// printf("Hello from the IRQ handler\n");
|
||||
|
||||
ID = readAliasedIntAck();
|
||||
setNSEL1PhysicalTimerCtrl(0); // Disable timer to clear interrupt
|
||||
writeAliasedEOI(ID);
|
||||
|
||||
current_time = getPhysicalCount();
|
||||
setNSEL1PhysicalCompValue(current_time + 20000);
|
||||
setNSEL1PhysicalTimerCtrl(CNTP_CTL_ENABLE);
|
||||
|
||||
//tx_thread_resume(&thread_1);
|
||||
_tx_timer_interrupt();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
@@ -0,0 +1,381 @@
|
||||
/* This is a small demo of the high-performance ThreadX kernel. It includes examples of eight
|
||||
threads of different priorities, using a message queue, semaphore, mutex, event flags group,
|
||||
byte pool, and block pool. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#define DEMO_STACK_SIZE 2048
|
||||
#define DEMO_BYTE_POOL_SIZE 64000
|
||||
#define DEMO_BLOCK_POOL_SIZE 100
|
||||
#define DEMO_QUEUE_SIZE 100
|
||||
|
||||
|
||||
/* Define the ThreadX object control blocks... */
|
||||
|
||||
TX_THREAD thread_0;
|
||||
TX_THREAD thread_1;
|
||||
TX_THREAD thread_2;
|
||||
TX_THREAD thread_3;
|
||||
TX_THREAD thread_4;
|
||||
TX_THREAD thread_5;
|
||||
TX_THREAD thread_6;
|
||||
TX_THREAD thread_7;
|
||||
TX_QUEUE queue_0;
|
||||
TX_SEMAPHORE semaphore_0;
|
||||
TX_MUTEX mutex_0;
|
||||
TX_EVENT_FLAGS_GROUP event_flags_0;
|
||||
TX_BYTE_POOL byte_pool_0;
|
||||
TX_BLOCK_POOL block_pool_0;
|
||||
|
||||
|
||||
/* Define the counters used in the demo application... */
|
||||
|
||||
ULONG thread_0_counter;
|
||||
ULONG thread_1_counter;
|
||||
ULONG thread_1_messages_sent;
|
||||
ULONG thread_2_counter;
|
||||
ULONG thread_2_messages_received;
|
||||
ULONG thread_3_counter;
|
||||
ULONG thread_4_counter;
|
||||
ULONG thread_5_counter;
|
||||
ULONG thread_6_counter;
|
||||
ULONG thread_7_counter;
|
||||
|
||||
|
||||
UCHAR memory_pool[DEMO_BYTE_POOL_SIZE];
|
||||
|
||||
/* Define thread prototypes. */
|
||||
|
||||
void thread_0_entry(ULONG thread_input);
|
||||
void thread_1_entry(ULONG thread_input);
|
||||
void thread_2_entry(ULONG thread_input);
|
||||
void thread_3_and_4_entry(ULONG thread_input);
|
||||
void thread_5_entry(ULONG thread_input);
|
||||
void thread_6_and_7_entry(ULONG thread_input);
|
||||
|
||||
|
||||
/* Define board-specific hardware setup. */
|
||||
|
||||
void hw_setup(void);
|
||||
|
||||
|
||||
/* Define main entry point. */
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
/* Setup hardware. */
|
||||
hw_setup();
|
||||
|
||||
/* Enter the ThreadX kernel. */
|
||||
tx_kernel_enter();
|
||||
}
|
||||
|
||||
|
||||
/* Define what the initial system looks like. */
|
||||
|
||||
void tx_application_define(void *first_unused_memory)
|
||||
{
|
||||
|
||||
UCHAR *pointer = TX_NULL;
|
||||
|
||||
|
||||
/* Create a byte memory pool from which to allocate the thread stacks. */
|
||||
tx_byte_pool_create(&byte_pool_0, "byte pool 0", memory_pool, DEMO_BYTE_POOL_SIZE);
|
||||
|
||||
/* Put system definition stuff in here, e.g. thread creates and other assorted
|
||||
create information. */
|
||||
|
||||
/* Allocate the stack for thread 0. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create the main thread. */
|
||||
tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
|
||||
/* Allocate the stack for thread 1. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create threads 1 and 2. These threads pass information through a ThreadX
|
||||
message queue. It is also interesting to note that these threads have a time
|
||||
slice. */
|
||||
tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
16, 16, 4, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 2. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
16, 16, 4, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 3. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore.
|
||||
An interesting thing here is that both threads share the same instruction area. */
|
||||
tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 4. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 5. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create thread 5. This thread simply pends on an event flag which will be set
|
||||
by thread_0. */
|
||||
tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 6. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create threads 6 and 7. These threads compete for a ThreadX mutex. */
|
||||
tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the stack for thread 7. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
|
||||
|
||||
tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7,
|
||||
pointer, DEMO_STACK_SIZE,
|
||||
8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
|
||||
|
||||
/* Allocate the message queue. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT);
|
||||
|
||||
/* Create the message queue shared by threads 1 and 2. */
|
||||
tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
|
||||
|
||||
/* Create the semaphore used by threads 3 and 4. */
|
||||
tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
|
||||
|
||||
/* Create the event flags group used by threads 1 and 5. */
|
||||
tx_event_flags_create(&event_flags_0, "event flags 0");
|
||||
|
||||
/* Create the mutex used by thread 6 and 7 without priority inheritance. */
|
||||
tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
|
||||
|
||||
/* Allocate the memory for a small block pool. */
|
||||
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT);
|
||||
|
||||
/* Create a block memory pool to allocate a message buffer from. */
|
||||
tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE);
|
||||
|
||||
/* Allocate a block and release the block memory. */
|
||||
tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT);
|
||||
|
||||
/* Release the block back to the pool. */
|
||||
tx_block_release(pointer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Define the test threads. */
|
||||
|
||||
void thread_0_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This thread simply sits in while-forever-sleep loop. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_0_counter++;
|
||||
|
||||
/* Sleep for 10 ticks. */
|
||||
tx_thread_sleep(10);
|
||||
|
||||
/* Set event flag 0 to wakeup thread 5. */
|
||||
status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_1_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This thread simply sends messages to a queue shared by thread 2. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_1_counter++;
|
||||
|
||||
/* Send message to queue 0. */
|
||||
status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check completion status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Increment the message sent. */
|
||||
thread_1_messages_sent++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_2_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
ULONG received_message;
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This thread retrieves messages placed on the queue by thread 1. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_2_counter++;
|
||||
|
||||
/* Retrieve a message from the queue. */
|
||||
status = tx_queue_receive(&queue_0, &received_message, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check completion status and make sure the message is what we
|
||||
expected. */
|
||||
if ((status != TX_SUCCESS) || (received_message != thread_2_messages_received))
|
||||
break;
|
||||
|
||||
/* Otherwise, all is okay. Increment the received message count. */
|
||||
thread_2_messages_received++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_3_and_4_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This function is executed from thread 3 and thread 4. As the loop
|
||||
below shows, these function compete for ownership of semaphore_0. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
if (thread_input == 3)
|
||||
thread_3_counter++;
|
||||
else
|
||||
thread_4_counter++;
|
||||
|
||||
/* Get the semaphore with suspension. */
|
||||
status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Sleep for 2 ticks to hold the semaphore. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Release the semaphore. */
|
||||
status = tx_semaphore_put(&semaphore_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_5_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
ULONG actual_flags;
|
||||
|
||||
|
||||
/* This thread simply waits for an event in a forever loop. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
thread_5_counter++;
|
||||
|
||||
/* Wait for event flag 0. */
|
||||
status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR,
|
||||
&actual_flags, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if ((status != TX_SUCCESS) || (actual_flags != 0x1))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void thread_6_and_7_entry(ULONG thread_input)
|
||||
{
|
||||
|
||||
UINT status;
|
||||
|
||||
|
||||
/* This function is executed from thread 6 and thread 7. As the loop
|
||||
below shows, these function compete for ownership of mutex_0. */
|
||||
while(1)
|
||||
{
|
||||
|
||||
/* Increment the thread counter. */
|
||||
if (thread_input == 6)
|
||||
thread_6_counter++;
|
||||
else
|
||||
thread_7_counter++;
|
||||
|
||||
/* Get the mutex with suspension. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Get the mutex again with suspension. This shows
|
||||
that an owning thread may retrieve the mutex it
|
||||
owns multiple times. */
|
||||
status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Sleep for 2 ticks to hold the mutex. */
|
||||
tx_thread_sleep(2);
|
||||
|
||||
/* Release the mutex. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Release the mutex again. This will actually
|
||||
release ownership since it was obtained twice. */
|
||||
status = tx_mutex_put(&mutex_0);
|
||||
|
||||
/* Check status. */
|
||||
if (status != TX_SUCCESS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
LOAD 0x80000000
|
||||
{
|
||||
BASE 0x80000000
|
||||
{
|
||||
* (+RO)
|
||||
}
|
||||
|
||||
RAM +0x0
|
||||
{
|
||||
* (+RW, +ZI)
|
||||
}
|
||||
|
||||
ARM_LIB_STACKHEAP 0x80090000 EMPTY -0x00040000
|
||||
{}
|
||||
}
|
||||
199
ports/cortex_a5x/ac6/example_build/sample_threadx/startup.S
Normal file
199
ports/cortex_a5x/ac6/example_build/sample_threadx/startup.S
Normal file
@@ -0,0 +1,199 @@
|
||||
//==================================================================
|
||||
// Copyright ARM Ltd 2012. All rights reserved.
|
||||
//
|
||||
// ARMv8 example - Startup Code
|
||||
//==================================================================
|
||||
|
||||
.section BOOT,"ax"
|
||||
.align 3
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.equ Mode_USR, 0x10
|
||||
|
||||
.equ AArch32_Mode_USR, 0x10
|
||||
.equ AArch32_Mode_FIQ, 0x11
|
||||
.equ AArch32_Mode_IRQ, 0x12
|
||||
.equ AArch32_Mode_SVC, 0x13
|
||||
.equ AArch32_Mode_ABT, 0x17
|
||||
.equ AArch32_Mode_UNDEF, 0x1B
|
||||
.equ AArch32_Mode_SYS, 0x1F
|
||||
.equ AArch32_Mode_HYP, 0x1A
|
||||
.equ AArch32_Mode_MON, 0x16
|
||||
|
||||
.equ AArch64_EL2_SP2, 0x09 // EL2h
|
||||
.equ AArch64_EL2_SP0, 0x08 // EL2t
|
||||
.equ AArch64_EL1_SP1, 0x05 // EL1h
|
||||
.equ AArch64_EL1_SP0, 0x04 // EL1t
|
||||
.equ AArch64_EL0_SP0, 0x00
|
||||
|
||||
.equ AArch32_State_Thumb, 0x20
|
||||
.equ AArch32_State_ARM, 0x00
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.equ TT_S1_TABLE, 0x00000000000000003 // NSTable=0, PXNTable=0, UXNTable=0, APTable=0
|
||||
|
||||
// TT block entries templates (L1 and L2, NOT L3)
|
||||
// Assuming table contents:
|
||||
// 0 = b01000100 = Normal, Inner/Outer Non-Cacheable
|
||||
// 1 = b11111111 = Normal, Inner/Outer WB/WA/RA
|
||||
// 2 = b00000000 = Device-nGnRnE
|
||||
.equ TT_S1_FAULT, 0x0
|
||||
.equ TT_S1_NORMAL_NO_CACHE, 0x00000000000000401 // Index = 0, AF=1
|
||||
.equ TT_S1_NORMAL_WBWA, 0x00000000000000405 // Index = 1, AF=1
|
||||
.equ TT_S1_DEVICE_nGnRnE, 0x00000000000000409 // Index = 2, AF=1
|
||||
|
||||
.equ TT_S1_UXN, (1 << 54)
|
||||
.equ TT_S1_PXN, (1 << 53)
|
||||
.equ TT_S1_nG, (1 << 11)
|
||||
.equ TT_S1_NS, (1 << 5)
|
||||
|
||||
.equ TT_S1_NON_SHARED, (0 << 8) // Non-shareable
|
||||
.equ TT_S1_INNER_SHARED, (3 << 8) // Inner-shareable
|
||||
.equ TT_S1_OUTER_SHARED, (2 << 8) // Outer-shareable
|
||||
|
||||
.equ TT_S1_PRIV_RW, (0x0)
|
||||
.equ TT_S1_PRIV_RO, (0x2 << 6)
|
||||
.equ TT_S1_USER_RW, (0x1 << 6)
|
||||
.equ TT_S1_USER_RO, (0x3 << 6)
|
||||
|
||||
// ------------------------------------------------------------
|
||||
|
||||
.global start64
|
||||
.type start64, @function
|
||||
start64:
|
||||
|
||||
// Clear registers
|
||||
// ---------------
|
||||
// This is primarily for RTL simulators, to avoid
|
||||
// possibility of X propergation
|
||||
MOV x0, #0
|
||||
MOV x1, #0
|
||||
MOV x2, #0
|
||||
MOV x3, #0
|
||||
MOV x4, #0
|
||||
MOV x5, #0
|
||||
MOV x6, #0
|
||||
MOV x7, #0
|
||||
MOV x8, #0
|
||||
MOV x9, #0
|
||||
MOV x10, #0
|
||||
MOV x11, #0
|
||||
MOV x12, #0
|
||||
MOV x13, #0
|
||||
MOV x14, #0
|
||||
MOV x15, #0
|
||||
MOV x16, #0
|
||||
MOV x17, #0
|
||||
MOV x18, #0
|
||||
MOV x19, #0
|
||||
MOV x20, #0
|
||||
MOV x21, #0
|
||||
MOV x22, #0
|
||||
MOV x23, #0
|
||||
MOV x24, #0
|
||||
MOV x25, #0
|
||||
MOV x26, #0
|
||||
MOV x27, #0
|
||||
MOV x28, #0
|
||||
MOV x29, #0
|
||||
MOV x30, #0
|
||||
|
||||
// Which core am I
|
||||
// ----------------
|
||||
MRS x0, MPIDR_EL1
|
||||
AND x0, x0, #0xFF // Mask off to leave Aff0
|
||||
CBZ x0, boot // If core 0, run the primary init code
|
||||
sleep:
|
||||
WFI
|
||||
B sleep
|
||||
boot:
|
||||
|
||||
|
||||
// Disable trapping of CPTR_EL3 accesses or use of Adv.SIMD/FPU
|
||||
// -------------------------------------------------------------
|
||||
MOV x0, #0 // Clear all trap bits
|
||||
MSR CPTR_EL3, x0
|
||||
|
||||
|
||||
// Install vector table
|
||||
// ---------------------
|
||||
LDR x0, vector_table_address
|
||||
MSR VBAR_EL3, x0
|
||||
|
||||
|
||||
// Configure SCR_EL3
|
||||
// ------------------
|
||||
MOV w1, #0 // Initial value of register is unknown
|
||||
ORR w1, w1, #(1 << 11) // Set ST bit (Secure EL1 can access CNTPS_TVAL_EL1, CNTPS_CTL_EL1 & CNTPS_CVAL_EL1)
|
||||
ORR w1, w1, #(1 << 10) // Set RW bit (EL1 is AArch64, as this is the Secure world)
|
||||
ORR w1, w1, #(1 << 3) // Set EA bit (SError routed to EL3)
|
||||
ORR w1, w1, #(1 << 2) // Set FIQ bit (FIQs routed to EL3)
|
||||
ORR w1, w1, #(1 << 1) // Set IRQ bit (IRQs routed to EL3)
|
||||
MSR SCR_EL3, x1
|
||||
|
||||
|
||||
//
|
||||
// Cortex-A series specified configuration
|
||||
//
|
||||
.ifdef CORTEXA
|
||||
// Configure ACTLR_EL1
|
||||
// --------------------
|
||||
// These bits are IMP DEF, so need to different for different
|
||||
// processors
|
||||
//MRS x1, ACTLR_EL1
|
||||
//ORR x1, x1, #1 // Enable EL1 access to ACTLR_EL1
|
||||
//ORR x1, x1, #(1 << 1) // Enable EL1 access to CPUECTLR_EL1
|
||||
//ORR x1, x1, #(1 << 4) // Enable EL1 access to L2CTLR_EL1
|
||||
//ORR x1, x1, #(1 << 5) // Enable EL1 access to L2ECTLR_EL1
|
||||
//ORR x1, x1, #(1 << 6) // Enable EL1 access to L2ACTLR_EL1
|
||||
//MSR ACTLR_EL1, x1
|
||||
|
||||
// Configure CPUECTLR_EL1
|
||||
// -----------------------
|
||||
// These bits are IMP DEF, so need to different for different
|
||||
// processors
|
||||
// SMPEN - bit 6 - Enables the processor to receive cache
|
||||
// and TLB maintenance operations
|
||||
//
|
||||
// NOTE: For Cortex-A57/53 CPUEN should be set beforebefore
|
||||
// enabling the caches and MMU, or performing any cache
|
||||
// and TLB maintenance operations.
|
||||
//MRS x0, S3_1_c15_c2_1 // Read EL1 CPU Extended Control Register
|
||||
//ORR x0, x0, #(1 << 6) // Set the SMPEN bit
|
||||
//MSR S3_1_c15_c2_1, x0 // Write EL1 CPU Extended Control Register
|
||||
//ISB
|
||||
.endif
|
||||
|
||||
|
||||
// Ensure changes to system register are visible before MMU enabled
|
||||
ISB
|
||||
|
||||
|
||||
// Enable Interrupts
|
||||
// ------------------
|
||||
MSR DAIFClr, 0x3
|
||||
|
||||
|
||||
// Branch to scatter loading and C library init code
|
||||
.global __main
|
||||
B __main
|
||||
|
||||
//==================================================================
|
||||
// Manually created literals pool
|
||||
//==================================================================
|
||||
.align 3
|
||||
|
||||
lit_stackheap_limit:
|
||||
.global Image$$ARM_LIB_STACKHEAP$$ZI$$Limit // Linker symbol from scatter file
|
||||
.quad (Image$$ARM_LIB_STACKHEAP$$ZI$$Limit)
|
||||
|
||||
vector_table_address:
|
||||
.global el3_vectors
|
||||
.quad el3_vectors
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// End of file
|
||||
// ------------------------------------------------------------
|
||||
|
||||
129
ports/cortex_a5x/ac6/example_build/tx/.cproject
Normal file
129
ports/cortex_a5x/ac6/example_build/tx/.cproject
Normal file
@@ -0,0 +1,129 @@
|
||||
<?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="com.arm.eclipse.build.config.v6.lib.debug.1636501669">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.lib.debug.1636501669" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
<externalSettings>
|
||||
<externalSetting>
|
||||
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/tx"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/tx/Debug"/>
|
||||
<entry flags="RESOLVED" kind="libraryFile" name="tx" srcPrefixMapping="" srcRootPath=""/>
|
||||
</externalSetting>
|
||||
</externalSettings>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="com.arm.eclipse.builder.armcc.error" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactExtension="a" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="clean" description="" id="com.arm.eclipse.build.config.v6.lib.debug.1636501669" name="Debug" parent="com.arm.eclipse.build.config.v6.lib.debug">
|
||||
<folderInfo id="com.arm.eclipse.build.config.v6.lib.debug.1636501669." name="/" resourcePath="">
|
||||
<toolChain id="com.arm.toolchain.v6.lib.debug.372997136" name="ARM Compiler 6 (DS-5 built-in)" superClass="com.arm.toolchain.v6.lib.debug">
|
||||
<targetPlatform id="com.arm.eclipse.build.config.v6.lib.debug.1636501669..1913630610" name=""/>
|
||||
<builder buildPath="${workspace_loc:/tx}/Debug" id="com.arm.toolchain.v6.builder.1983518587" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.arm.toolchain.v6.builder"/>
|
||||
<tool id="com.arm.tool.c.compiler.v6.424515954" name="ARM C Compiler 6" superClass="com.arm.tool.c.compiler.v6">
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.min" id="com.arm.tool.c.compiler.v6.base.option.optlevel.1943677123" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" valueType="enumerated"/>
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.tool.c.compiler.v6.base.options.debug.level.1549650007" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" valueType="enumerated"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.target.1356370649" name="Target (--target)" superClass="com.arm.tool.c.compiler.v6.base.option.target" useByScannerDiscovery="true" value="aarch64-arm-none-eabi" valueType="string"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.cpu.1958530753" name="CPU (-mcpu)" superClass="com.arm.tool.c.compiler.v6.base.option.cpu" useByScannerDiscovery="true" value="cortex-a53+fp" valueType="string"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.defmac.27547789" name="Define macro (-D)" superClass="com.arm.tool.c.compiler.v6.base.option.defmac" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="STANDALONE"/>
|
||||
<listOptionValue builtIn="false" value="ENABLE_ARM_FP"/>
|
||||
</option>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.options.preproc.enableToolSpecificSettings.564945141" name="Enable tool specific settings" superClass="com.arm.tool.c.compiler.v6.base.options.preproc.enableToolSpecificSettings" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="com.arm.tool.c.compiler.v6.base.option.incpath.1612505103" name="Include path (-I)" superClass="com.arm.tool.c.compiler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc_generic}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc_port}""/>
|
||||
</option>
|
||||
<inputType id="com.arm.tool.c.compiler.v6.base.input.1675127320" superClass="com.arm.tool.c.compiler.v6.base.input"/>
|
||||
<inputType id="com.arm.tool.cpp.compiler.v6.base.input.1720461009" superClass="com.arm.tool.cpp.compiler.v6.base.input"/>
|
||||
</tool>
|
||||
<tool id="com.arm.tool.cpp.compiler.v6.1361684972" name="ARM C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6">
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.min" id="com.arm.tool.c.compiler.v6.base.option.optlevel.612579770" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" valueType="enumerated"/>
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.std" id="com.arm.tool.c.compiler.v6.base.options.debug.level.1772335065" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="com.arm.tool.assembler.v6.1230485781" name="ARM Assembler 6" superClass="com.arm.tool.assembler.v6">
|
||||
<option defaultValue="com.arm.tool.assembler.v6.base.options.debug.level.std" id="com.arm.tool.assembler.v6.base.options.debug.level.2059874867" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" valueType="enumerated"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.target.1596122891" name="Target (--target)" superClass="com.arm.tool.assembler.v6.base.option.target" value="aarch64-arm-none-eabi" valueType="string"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.cpu.654928087" name="CPU (-mcpu)" superClass="com.arm.tool.assembler.v6.base.option.cpu" value="cortex-a53+fp" valueType="string"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.defmac.162845590" name="Define macro (-D)" superClass="com.arm.tool.assembler.v6.base.option.defmac"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.options.preproc.enableToolSpecificSettings.1821750188" name="Enable tool specific settings" superClass="com.arm.tool.assembler.v6.base.options.preproc.enableToolSpecificSettings" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option id="com.arm.tool.assembler.v6.base.option.incpath.920333443" name="Include path (-I)" superClass="com.arm.tool.assembler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath"/>
|
||||
<inputType id="com.arm.tool.assembler.v6.base.input.157969473" superClass="com.arm.tool.assembler.v6.base.input"/>
|
||||
</tool>
|
||||
<tool id="com.arm.tool.c.linker.v6.1251436674" name="ARM Linker 6" superClass="com.arm.tool.c.linker.v6"/>
|
||||
<tool id="com.arm.tool.librarian.v6.1167637188" name="ARM Librarian 6" superClass="com.arm.tool.librarian.v6"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry excluding="src_generic/tx_misra.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="com.arm.eclipse.build.config.v6.lib.release.1521587399">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.lib.release.1521587399" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
<externalSettings>
|
||||
<externalSetting>
|
||||
<entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/tx"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/tx/Release"/>
|
||||
<entry flags="RESOLVED" kind="libraryFile" name="tx" srcPrefixMapping="" srcRootPath=""/>
|
||||
</externalSetting>
|
||||
</externalSettings>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="com.arm.eclipse.builder.armcc.error" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactExtension="a" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.staticLib" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.staticLib,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="clean" description="" id="com.arm.eclipse.build.config.v6.lib.release.1521587399" name="Release" parent="com.arm.eclipse.build.config.v6.lib.release">
|
||||
<folderInfo id="com.arm.eclipse.build.config.v6.lib.release.1521587399." name="/" resourcePath="">
|
||||
<toolChain id="com.arm.toolchain.v6.lib.release.2074068559" name="ARM Compiler 6 (DS-5 built-in)" superClass="com.arm.toolchain.v6.lib.release">
|
||||
<targetPlatform id="com.arm.eclipse.build.config.v6.lib.release.1521587399..1369138044" name=""/>
|
||||
<builder buildPath="${workspace_loc:/tx}/Release" id="com.arm.toolchain.v6.builder.356216328" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="com.arm.toolchain.v6.builder"/>
|
||||
<tool id="com.arm.tool.c.compiler.v6.910156028" name="ARM C Compiler 6" superClass="com.arm.tool.c.compiler.v6">
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.high" id="com.arm.tool.c.compiler.v6.base.option.optlevel.49171447" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" useByScannerDiscovery="true" valueType="enumerated"/>
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.none" id="com.arm.tool.c.compiler.v6.base.options.debug.level.203884217" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" valueType="enumerated"/>
|
||||
<inputType id="com.arm.tool.c.compiler.v6.base.input.949469320" superClass="com.arm.tool.c.compiler.v6.base.input"/>
|
||||
<inputType id="com.arm.tool.cpp.compiler.v6.base.input.866107816" superClass="com.arm.tool.cpp.compiler.v6.base.input"/>
|
||||
</tool>
|
||||
<tool id="com.arm.tool.cpp.compiler.v6.2136467342" name="ARM C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6">
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.option.optlevel.high" id="com.arm.tool.c.compiler.v6.base.option.optlevel.62249493" name="Optimization level" superClass="com.arm.tool.c.compiler.v6.base.option.optlevel" valueType="enumerated"/>
|
||||
<option defaultValue="com.arm.tool.c.compiler.v6.base.options.debug.level.none" id="com.arm.tool.c.compiler.v6.base.options.debug.level.93807078" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" valueType="enumerated"/>
|
||||
</tool>
|
||||
<tool id="com.arm.tool.assembler.v6.1185271435" name="ARM Assembler 6" superClass="com.arm.tool.assembler.v6">
|
||||
<option defaultValue="com.arm.tool.assembler.v6.base.options.debug.level.none" id="com.arm.tool.assembler.v6.base.options.debug.level.2069699697" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" valueType="enumerated"/>
|
||||
<inputType id="com.arm.tool.assembler.v6.base.input.1112095021" superClass="com.arm.tool.assembler.v6.base.input"/>
|
||||
</tool>
|
||||
<tool id="com.arm.tool.c.linker.v6.1769504167" name="ARM Linker 6" superClass="com.arm.tool.c.linker.v6"/>
|
||||
<tool id="com.arm.tool.librarian.v6.801428272" name="ARM Librarian 6" superClass="com.arm.tool.librarian.v6"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry excluding="src_generic/tx_misra.c" 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="tx.com.arm.eclipse.build.project.v6.lib.1209080418" name="Static Library" projectType="com.arm.eclipse.build.project.v6.lib"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
<configuration configurationName="Debug">
|
||||
<resource resourceType="PROJECT" workspacePath="/tx"/>
|
||||
</configuration>
|
||||
<configuration configurationName="Release">
|
||||
<resource resourceType="PROJECT" workspacePath="/tx"/>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
</cproject>
|
||||
48
ports/cortex_a5x/ac6/example_build/tx/.project
Normal file
48
ports/cortex_a5x/ac6/example_build/tx/.project
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>tx</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>inc_generic</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-5-PROJECT_LOC%7D/common/inc</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>inc_port</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/inc</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>src_generic</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-5-PROJECT_LOC%7D/common/src</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>src_port</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/src</locationURI>
|
||||
</link>
|
||||
</linkedResources>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project>
|
||||
<configuration id="com.arm.eclipse.build.config.v6.lib.debug.1636501669" 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="com.arm.eclipse.builder.armcc.discovery.ArmCompiler6LanguageSettingsProvider" console="false" env-hash="-294697026837367808" id="com.arm.eclipse.builder.armcc.v6.langprovider" keep-relative-paths="false" name="ARM Compiler 6 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>
|
||||
<configuration id="com.arm.eclipse.build.config.v6.lib.release.1521587399" name="Release">
|
||||
<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="com.arm.eclipse.builder.armcc.discovery.ArmCompiler6LanguageSettingsProvider" console="false" env-hash="-264130677454984672" id="com.arm.eclipse.builder.armcc.v6.langprovider" keep-relative-paths="false" name="ARM Compiler 6 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>
|
||||
367
ports/cortex_a5x/ac6/inc/tx_port.h
Normal file
367
ports/cortex_a5x/ac6/inc/tx_port.h
Normal file
@@ -0,0 +1,367 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Port Specific */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* PORT SPECIFIC C INFORMATION RELEASE */
|
||||
/* */
|
||||
/* tx_port.h Cortex-A5x/ARM */
|
||||
/* 6.0.1 */
|
||||
/* */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This file contains data type definitions that make the ThreadX */
|
||||
/* real-time kernel function identically on a variety of different */
|
||||
/* processor architectures. For example, the size or number of bits */
|
||||
/* in an "int" data type vary between microprocessor architectures and */
|
||||
/* even C compilers for the same microprocessor. ThreadX does not */
|
||||
/* directly use native C data types. Instead, ThreadX creates its */
|
||||
/* own special types that can be mapped to actual data types by this */
|
||||
/* file to guarantee consistency in the interface and functionality. */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
#ifndef TX_PORT_H
|
||||
#define TX_PORT_H
|
||||
|
||||
|
||||
/* Determine if the optional ThreadX user define file should be used. */
|
||||
|
||||
#ifdef TX_INCLUDE_USER_DEFINE_FILE
|
||||
|
||||
|
||||
/* Yes, include the user defines in tx_user.h. The defines in this file may
|
||||
alternately be defined on the command line. */
|
||||
|
||||
#include "tx_user.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* Define compiler library include files. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* Define ThreadX basic types for this port. */
|
||||
|
||||
#define VOID void
|
||||
typedef char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
typedef int LONG;
|
||||
typedef unsigned int ULONG;
|
||||
typedef short SHORT;
|
||||
typedef unsigned short USHORT;
|
||||
|
||||
|
||||
/* Override the alignment type to use 64-bit alignment and storage for pointers. */
|
||||
|
||||
#define ALIGN_TYPE_DEFINED
|
||||
typedef unsigned long long ALIGN_TYPE;
|
||||
|
||||
|
||||
/* Override the free block marker for byte pools to be a 64-bit constant. */
|
||||
|
||||
#define TX_BYTE_BLOCK_FREE ((ALIGN_TYPE) 0xFFFFEEEEFFFFEEEE)
|
||||
|
||||
|
||||
/* Define the priority levels for ThreadX. Legal values range
|
||||
from 32 to 1024 and MUST be evenly divisible by 32. */
|
||||
|
||||
#ifndef TX_MAX_PRIORITIES
|
||||
#define TX_MAX_PRIORITIES 32
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
|
||||
thread creation is less than this value, the thread create call will return an error. */
|
||||
|
||||
#ifndef TX_MINIMUM_STACK
|
||||
#define TX_MINIMUM_STACK 200 /* Minimum stack size for this port */
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the system timer thread's default stack size and priority. These are only applicable
|
||||
if TX_TIMER_PROCESS_IN_ISR is not defined. */
|
||||
|
||||
#ifndef TX_TIMER_THREAD_STACK_SIZE
|
||||
#define TX_TIMER_THREAD_STACK_SIZE 4096 /* Default timer thread stack size */
|
||||
#endif
|
||||
|
||||
#ifndef TX_TIMER_THREAD_PRIORITY
|
||||
#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
|
||||
#endif
|
||||
|
||||
|
||||
/* Define various constants for the ThreadX ARM port. */
|
||||
|
||||
#define TX_INT_DISABLE 0xC0 /* Disable IRQ & FIQ interrupts */
|
||||
#define TX_INT_ENABLE 0x00 /* Enable IRQ & FIQ interrupts */
|
||||
|
||||
|
||||
/* Define the clock source for trace event entry time stamp. The following two item are port specific.
|
||||
For example, if the time source is at the address 0x0a800024 and is 16-bits in size, the clock
|
||||
source constants would be:
|
||||
|
||||
#define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
|
||||
#define TX_TRACE_TIME_MASK 0x0000FFFFUL
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TX_TRACE_TIME_SOURCE
|
||||
#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time
|
||||
#endif
|
||||
#ifndef TX_TRACE_TIME_MASK
|
||||
#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the port specific options for the _tx_build_options variable. This variable indicates
|
||||
how the ThreadX library was built. */
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_SUPPORT
|
||||
#define TX_FIQ_ENABLED 1
|
||||
#else
|
||||
#define TX_FIQ_ENABLED 0
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_IRQ_NESTING
|
||||
#define TX_IRQ_NESTING_ENABLED 2
|
||||
#else
|
||||
#define TX_IRQ_NESTING_ENABLED 0
|
||||
#endif
|
||||
|
||||
#ifdef TX_ENABLE_FIQ_NESTING
|
||||
#define TX_FIQ_NESTING_ENABLED 4
|
||||
#else
|
||||
#define TX_FIQ_NESTING_ENABLED 0
|
||||
#endif
|
||||
|
||||
#define TX_PORT_SPECIFIC_BUILD_OPTIONS TX_FIQ_ENABLED | TX_IRQ_NESTING_ENABLED | TX_FIQ_NESTING_ENABLED
|
||||
|
||||
|
||||
/* Define the in-line initialization constant so that modules with in-line
|
||||
initialization capabilities can prevent their initialization from being
|
||||
a function call. */
|
||||
|
||||
#define TX_INLINE_INITIALIZATION
|
||||
|
||||
|
||||
/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
|
||||
disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
|
||||
checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
|
||||
define is negated, thereby forcing the stack fill which is necessary for the stack checking
|
||||
logic. */
|
||||
|
||||
#ifdef TX_ENABLE_STACK_CHECKING
|
||||
#undef TX_DISABLE_STACK_FILLING
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the TX_THREAD control block extensions for this port. The main reason
|
||||
for the multiple macros is so that backward compatibility can be maintained with
|
||||
existing ThreadX kernel awareness modules. */
|
||||
|
||||
#define TX_THREAD_EXTENSION_0
|
||||
#define TX_THREAD_EXTENSION_1
|
||||
#define TX_THREAD_EXTENSION_2 ULONG tx_thread_fp_enable;
|
||||
#define TX_THREAD_EXTENSION_3
|
||||
|
||||
|
||||
/* Define the port extensions of the remaining ThreadX objects. */
|
||||
|
||||
#define TX_BLOCK_POOL_EXTENSION
|
||||
#define TX_BYTE_POOL_EXTENSION
|
||||
#define TX_EVENT_FLAGS_GROUP_EXTENSION
|
||||
#define TX_MUTEX_EXTENSION
|
||||
#define TX_QUEUE_EXTENSION
|
||||
#define TX_SEMAPHORE_EXTENSION
|
||||
#define TX_TIMER_EXTENSION
|
||||
|
||||
|
||||
/* Define the user extension field of the thread control block. Nothing
|
||||
additional is needed for this port so it is defined as white space. */
|
||||
|
||||
#ifndef TX_THREAD_USER_EXTENSION
|
||||
#define TX_THREAD_USER_EXTENSION
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
|
||||
tx_thread_shell_entry, and tx_thread_terminate. */
|
||||
|
||||
|
||||
#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
|
||||
#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
|
||||
|
||||
|
||||
/* Define the ThreadX object creation extensions for the remaining objects. */
|
||||
|
||||
#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
|
||||
#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
|
||||
#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
|
||||
#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
|
||||
#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
|
||||
#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
|
||||
#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
|
||||
|
||||
|
||||
/* Define the ThreadX object deletion extensions for the remaining objects. */
|
||||
|
||||
#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
|
||||
#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
|
||||
#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
|
||||
#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
|
||||
#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
|
||||
#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
|
||||
#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
|
||||
|
||||
|
||||
/* Determine if the ARM architecture has the CLZ instruction. This is available on
|
||||
architectures v5 and above. If available, redefine the macro for calculating the
|
||||
lowest bit set. */
|
||||
|
||||
#ifndef TX_DISABLE_INLINE
|
||||
|
||||
#define TX_LOWEST_SET_BIT_CALCULATE(m, b) b = (UINT) __builtin_ctz((unsigned int) m);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Define the internal timer extension to also hold the thread pointer such that _tx_thread_timeout
|
||||
can figure out what thread timeout to process. */
|
||||
|
||||
#define TX_TIMER_INTERNAL_EXTENSION VOID *tx_timer_internal_thread_timeout_ptr;
|
||||
|
||||
|
||||
/* Define the thread timeout setup logic in _tx_thread_create. */
|
||||
|
||||
#define TX_THREAD_CREATE_TIMEOUT_SETUP(t) (t) -> tx_thread_timer.tx_timer_internal_timeout_function = &(_tx_thread_timeout); \
|
||||
(t) -> tx_thread_timer.tx_timer_internal_timeout_param = 0; \
|
||||
(t) -> tx_thread_timer.tx_timer_internal_thread_timeout_ptr = (VOID *) (t);
|
||||
|
||||
|
||||
/* Define the thread timeout pointer setup in _tx_thread_timeout. */
|
||||
|
||||
#define TX_THREAD_TIMEOUT_POINTER_SETUP(t) (t) = (TX_THREAD *) _tx_timer_expired_timer_ptr -> tx_timer_internal_thread_timeout_ptr;
|
||||
|
||||
|
||||
/* Define ThreadX interrupt lockout and restore macros for protection on
|
||||
access of critical kernel information. The restore interrupt macro must
|
||||
restore the interrupt posture of the running thread prior to the value
|
||||
present prior to the disable macro. In most cases, the save area macro
|
||||
is used to define a local function save area for the disable and restore
|
||||
macros. */
|
||||
|
||||
#ifndef TX_DISABLE_INLINE
|
||||
|
||||
/* Define macros, with in-line assembly for performance. */
|
||||
|
||||
__attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void)
|
||||
{
|
||||
|
||||
unsigned long long daif_value;
|
||||
|
||||
__asm__ volatile (" MRS %0, DAIF ": "=r" (daif_value) );
|
||||
__asm__ volatile (" MSR DAIFSet, 0x3" : : : "memory" );
|
||||
return((unsigned int) daif_value);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int daif_value)
|
||||
{
|
||||
|
||||
unsigned long long temp;
|
||||
|
||||
temp = (unsigned long long) daif_value;
|
||||
__asm__ volatile (" MSR DAIF,%0": : "r" (temp): "memory" );
|
||||
}
|
||||
|
||||
|
||||
#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save;
|
||||
#define TX_DISABLE interrupt_save = __disable_interrupts();
|
||||
#define TX_RESTORE __restore_interrupts(interrupt_save);
|
||||
|
||||
#else
|
||||
|
||||
unsigned int _tx_thread_interrupt_disable(void);
|
||||
unsigned int _tx_thread_interrupt_restore(UINT old_posture);
|
||||
|
||||
|
||||
#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save;
|
||||
|
||||
#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
|
||||
#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
|
||||
#endif
|
||||
|
||||
|
||||
/* Define FP extension for the Cortex-A5x. Each is assumed to be called in the context of the executing
|
||||
thread. */
|
||||
|
||||
#ifndef TX_SOURCE_CODE
|
||||
#define tx_thread_fp_enable _tx_thread_fp_enable
|
||||
#define tx_thread_fp_disable _tx_thread_fp_disable
|
||||
#endif
|
||||
|
||||
VOID tx_thread_fp_enable(VOID);
|
||||
VOID tx_thread_fp_disable(VOID);
|
||||
|
||||
|
||||
/* Define the interrupt lockout macros for each ThreadX object. */
|
||||
|
||||
#define TX_BLOCK_POOL_DISABLE TX_DISABLE
|
||||
#define TX_BYTE_POOL_DISABLE TX_DISABLE
|
||||
#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE
|
||||
#define TX_MUTEX_DISABLE TX_DISABLE
|
||||
#define TX_QUEUE_DISABLE TX_DISABLE
|
||||
#define TX_SEMAPHORE_DISABLE TX_DISABLE
|
||||
|
||||
|
||||
/* Define the version ID of ThreadX. This may be utilized by the application. */
|
||||
|
||||
#ifdef TX_THREAD_INIT
|
||||
CHAR _tx_version_id[] =
|
||||
"Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-A5x/ARM Version 6.0 *";
|
||||
#else
|
||||
extern CHAR _tx_version_id[];
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
255
ports/cortex_a5x/ac6/readme_threadx.txt
Normal file
255
ports/cortex_a5x/ac6/readme_threadx.txt
Normal file
@@ -0,0 +1,255 @@
|
||||
Microsoft's Azure RTOS ThreadX for Cortex-A5x
|
||||
|
||||
Using the ARM Compiler 6 & DS
|
||||
|
||||
1. Open the Azure RTOS Workspace
|
||||
|
||||
In order to build the ThreadX library and the ThreadX demonstration first load
|
||||
the Azure RTOS Workspace, which is located inside your ThreadX installation
|
||||
directory.
|
||||
|
||||
Note: the workspace and projects were made using DS-5, so DS will prompt you
|
||||
to migrate the projects. This is expected, so please do so.
|
||||
|
||||
2. Building the ThreadX run-time Library
|
||||
|
||||
Building the ThreadX library is easy; simply select the Eclipse project file
|
||||
"tx" and then select the build button. You should now observe the compilation
|
||||
and assembly of the ThreadX library. This project build produces the ThreadX
|
||||
library file tx.a.
|
||||
|
||||
|
||||
3. Demonstration System
|
||||
|
||||
The ThreadX demonstration is designed to execute under the DS debugger on the
|
||||
VE-AEMv8x1 Bare Metal simulator.
|
||||
|
||||
Building the demonstration is easy; simply open the workspace file, select the
|
||||
sample_threadx project, and select the build button. Next, right-click on the
|
||||
project and select "Debug As -> Debug Configurations". The debugger is setup
|
||||
for VE_AEMv8x1 Bare Metal Debug, so selecting "Debug" will launch the simulator,
|
||||
load the sample_threadx.axf ELF file and run to main. You are now ready to
|
||||
execute the ThreadX demonstration.
|
||||
|
||||
|
||||
4. System Initialization
|
||||
|
||||
The entry point in ThreadX for the Cortex-A5x using ARM tools is at label
|
||||
start64. This is defined within the ARM compiler's startup code. In addition,
|
||||
this is where all static and global pre-set C variable initialization processing
|
||||
takes place.
|
||||
|
||||
The ThreadX tx_initialize_low_level.s file is responsible for determining the
|
||||
first available RAM address for use by the application, which is supplied as the
|
||||
sole input parameter to your application definition function, tx_application_define.
|
||||
|
||||
|
||||
5. Register Usage and Stack Frames
|
||||
|
||||
The 64-bit ARM compiler assumes that registers x0-x18 are scratch registers
|
||||
for each function. All other registers used by a C function must be preserved
|
||||
by the function. ThreadX takes advantage of this in situations where a context
|
||||
switch happens as a result of making a ThreadX service call (which is itself a
|
||||
C function). In such cases, the saved context of a thread is only the
|
||||
non-scratch registers.
|
||||
|
||||
The following defines the saved context stack frames for context switches
|
||||
that occur as a result of interrupt handling or from thread-level API calls.
|
||||
All suspended threads have one of these two types of stack frames. The top
|
||||
of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the
|
||||
associated thread control block TX_THREAD.
|
||||
|
||||
|
||||
FP not enabled and TX_THREAD.tx_thread_fp_enable == 0:
|
||||
|
||||
Offset Interrupted Stack Frame Non-Interrupt Stack Frame
|
||||
|
||||
0x000 SPSR DAIF
|
||||
0x008 ELR 0
|
||||
0x010 x28 x27
|
||||
0x018 reserved x28
|
||||
0x020 x26 x25
|
||||
0x028 x27 x26
|
||||
0x030 x24 x23
|
||||
0x038 x25 x24
|
||||
0x040 x22 x21
|
||||
0x048 x23 x22
|
||||
0x050 x20 x19
|
||||
0x058 x21 x20
|
||||
0x060 x18 x29
|
||||
0x068 x19 x30
|
||||
0x070 x16
|
||||
0x078 x17
|
||||
0x080 x14
|
||||
0x088 x15
|
||||
0x090 x12
|
||||
0x098 x13
|
||||
0x0A0 x10
|
||||
0x0A8 x11
|
||||
0x0B0 x8
|
||||
0x0B8 x9
|
||||
0x0C0 x6
|
||||
0x0C8 x7
|
||||
0x0D0 x4
|
||||
0x0D8 x5
|
||||
0x0E0 x2
|
||||
0x0E8 x3
|
||||
0x0F0 x0
|
||||
0x0F8 x1
|
||||
0x100 x29
|
||||
0x108 x30
|
||||
|
||||
|
||||
FP enabled and TX_THREAD.tx_thread_fp_enable == 1:
|
||||
|
||||
Offset Interrupted Stack Frame Non-Interrupt Stack Frame
|
||||
|
||||
0x000 SPSR DAIF
|
||||
0x008 ELR 0
|
||||
0x010 FPSR FPSR
|
||||
0x018 FPCR FPCR
|
||||
0x020 q30 q14
|
||||
0x030 q31 q15
|
||||
0x040 q28 q12
|
||||
0x050 q29 q13
|
||||
0x060 q26 q10
|
||||
0x070 q27 q11
|
||||
0x080 q24 q8
|
||||
0x090 q25 q9
|
||||
0x0A0 q22 x27
|
||||
0x0A8 x28
|
||||
0x0B0 q23 x25
|
||||
0x0B8 x26
|
||||
0x0C0 q20 x23
|
||||
0x0C8 x24
|
||||
0x0D0 q21 x21
|
||||
0x0D8 x22
|
||||
0x0E0 q18 x19
|
||||
0x0E8 x20
|
||||
0x0F0 q19 x29
|
||||
0x0F8 x30
|
||||
0x100 q16
|
||||
0x110 q17
|
||||
0x120 q14
|
||||
0x130 q15
|
||||
0x140 q12
|
||||
0x150 q13
|
||||
0x160 q10
|
||||
0x170 q11
|
||||
0x180 q8
|
||||
0x190 q9
|
||||
0x1A0 q6
|
||||
0x1B0 q7
|
||||
0x1C0 q4
|
||||
0x1D0 q5
|
||||
0x1E0 q2
|
||||
0x1F0 q3
|
||||
0x200 q0
|
||||
0x210 q1
|
||||
0x220 x28
|
||||
0x228 reserved
|
||||
0x230 x26
|
||||
0x238 x27
|
||||
0x240 x24
|
||||
0x248 x25
|
||||
0x250 x22
|
||||
0x258 x23
|
||||
0x260 x20
|
||||
0x268 x21
|
||||
0x270 x18
|
||||
0x278 x19
|
||||
0x280 x16
|
||||
0x288 x17
|
||||
0x290 x14
|
||||
0x298 x15
|
||||
0x2A0 x12
|
||||
0x2A8 x13
|
||||
0x2B0 x10
|
||||
0x2B8 x11
|
||||
0x2C0 x8
|
||||
0x2C8 x9
|
||||
0x2D0 x6
|
||||
0x2D8 x7
|
||||
0x2E0 x4
|
||||
0x2E8 x5
|
||||
0x2F0 x2
|
||||
0x2F8 x3
|
||||
0x300 x0
|
||||
0x308 x1
|
||||
0x310 x29
|
||||
0x318 x30
|
||||
|
||||
|
||||
|
||||
6. Improving Performance
|
||||
|
||||
The distribution version of ThreadX is built without any compiler optimizations.
|
||||
This makes it easy to debug because you can trace or set breakpoints inside of
|
||||
ThreadX itself. Of course, this costs some performance. To make it run faster,
|
||||
you can change the project settings to the desired compiler optimization level.
|
||||
|
||||
In addition, you can eliminate the ThreadX basic API error checking by
|
||||
compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING
|
||||
defined.
|
||||
|
||||
|
||||
7. Interrupt Handling
|
||||
|
||||
ThreadX provides complete and high-performance interrupt handling for Cortex-A5x
|
||||
targets. Interrupts handlers for the 64-bit mode of the Cortex-A5x have the following
|
||||
format:
|
||||
|
||||
.global irq_handler
|
||||
irq_handler:
|
||||
|
||||
STP x29, x30, [sp, #-16]!
|
||||
BL _tx_thread_context_save
|
||||
|
||||
/* Your ISR call goes here! */
|
||||
BL application_isr_handler
|
||||
|
||||
B _tx_thread_context_restore
|
||||
|
||||
By default, ThreadX assumes EL3 level of execution. Running and taking exceptions in EL1
|
||||
and EL2 can be done by simply building the ThreadX library with either EL1 or EL2 defined.
|
||||
|
||||
|
||||
8. ThreadX Timer Interrupt
|
||||
|
||||
ThreadX requires a periodic interrupt source to manage all time-slicing, thread sleeps,
|
||||
timeouts, and application timers. Without such a timer interrupt source, these services
|
||||
are not functional. However, all other ThreadX services are operational without a
|
||||
periodic timer source.
|
||||
|
||||
|
||||
9. ARM FP Support
|
||||
|
||||
By default, FP support is disabled for each thread. If saving the context of the FP registers
|
||||
is needed, the following API call must be made from the context of the application thread - before
|
||||
the FP usage:
|
||||
|
||||
void tx_thread_fp_enable(void);
|
||||
|
||||
After this API is called in the application, FP registers will be saved/restored for this thread if it
|
||||
is preempted via an interrupt. All other suspension of the this thread will not require the FP registers
|
||||
to be saved/restored.
|
||||
|
||||
To disable FP register context saving, simply call the following API:
|
||||
|
||||
void tx_thread_fp_disable(void);
|
||||
|
||||
|
||||
10. Revision History
|
||||
|
||||
For generic code revision information, please refer to the readme_threadx_generic.txt
|
||||
file, which is included in your distribution. The following details the revision
|
||||
information associated with this specific port of ThreadX:
|
||||
|
||||
06/30/2020 Initial ThreadX 6.0.1 version for Cortex-A5x using ARM tools.
|
||||
|
||||
|
||||
Copyright(c) 1996-2020 Microsoft Corporation
|
||||
|
||||
|
||||
https://azure.com/rtos
|
||||
|
||||
112
ports/cortex_a5x/ac6/src/tx_initialize_low_level.S
Normal file
112
ports/cortex_a5x/ac6/src/tx_initialize_low_level.S
Normal file
@@ -0,0 +1,112 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Initialize */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/*
|
||||
#include "tx_api.h"
|
||||
#include "tx_initialize.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_timer.h"
|
||||
*/
|
||||
|
||||
.text
|
||||
.align 3
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_initialize_low_level Cortex-A5x/ARM */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function is responsible for any low-level processor */
|
||||
/* initialization, including setting up interrupt vectors, setting */
|
||||
/* up a periodic timer interrupt source, saving the system stack */
|
||||
/* pointer for use in ISR processing later, and finding the first */
|
||||
/* available RAM memory address for tx_application_define. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _tx_initialize_kernel_enter ThreadX entry function */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_initialize_low_level(VOID)
|
||||
{ */
|
||||
.global _tx_initialize_low_level
|
||||
.type _tx_initialize_low_level, @function
|
||||
_tx_initialize_low_level:
|
||||
|
||||
MSR DAIFSet, 0x3 // Lockout interrupts
|
||||
|
||||
|
||||
/* Save the system stack pointer. */
|
||||
/* _tx_thread_system_stack_ptr = (VOID_PTR) (sp); */
|
||||
|
||||
LDR x0, =_tx_thread_system_stack_ptr // Pickup address of system stack ptr
|
||||
MOV x1, sp // Pickup SP
|
||||
BIC x1, x1, #0xF // Get 16-bit alignment
|
||||
STR x1, [x0] // Store system stack
|
||||
|
||||
/* Save the first available memory address. */
|
||||
/* _tx_initialize_unused_memory = (VOID_PTR) Image$$ZI$$Limit; */
|
||||
|
||||
LDR x0, =_tx_initialize_unused_memory // Pickup address of unused memory ptr
|
||||
LDR x1, =zi_limit // Pickup unused memory address
|
||||
LDR x1, [x1] //
|
||||
STR x1, [x0] // Store unused memory address
|
||||
|
||||
/* Done, return to caller. */
|
||||
|
||||
RET // Return to caller
|
||||
/* } */
|
||||
|
||||
|
||||
zi_limit:
|
||||
.quad (Image$$ARM_LIB_STACKHEAP$$ZI$$Limit)
|
||||
|
||||
302
ports/cortex_a5x/ac6/src/tx_thread_context_restore.S
Normal file
302
ports/cortex_a5x/ac6/src/tx_thread_context_restore.S
Normal file
@@ -0,0 +1,302 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/*
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_timer.h"
|
||||
*/
|
||||
|
||||
/* .set ENABLE_ARM_FP,1 */
|
||||
|
||||
.text
|
||||
.align 3
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_context_restore Cortex-A5x/ARM */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function restores the interrupt context if it is processing a */
|
||||
/* nested interrupt. If not, it returns to the interrupt thread if no */
|
||||
/* preemption is necessary. Otherwise, if preemption is necessary or */
|
||||
/* if no thread was running, the function returns to the scheduler. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_schedule Thread scheduling routine */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* ISRs Interrupt Service Routines */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_thread_context_restore(VOID)
|
||||
{ */
|
||||
.global _tx_thread_context_restore
|
||||
.type _tx_thread_context_restore, @function
|
||||
_tx_thread_context_restore:
|
||||
|
||||
/* Lockout interrupts. */
|
||||
|
||||
MSR DAIFSet, 0x3 // Lockout interrupts
|
||||
|
||||
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
|
||||
/* Call the ISR exit function to indicate an ISR is complete. */
|
||||
|
||||
BL _tx_execution_isr_exit // Call the ISR exit function
|
||||
.endif
|
||||
|
||||
/* Determine if interrupts are nested. */
|
||||
/* if (--_tx_thread_system_state)
|
||||
{ */
|
||||
|
||||
LDR x3, =_tx_thread_system_state // Pickup address of system state var
|
||||
LDR w2, [x3, #0] // Pickup system state
|
||||
SUB w2, w2, #1 // Decrement the counter
|
||||
STR w2, [x3, #0] // Store the counter
|
||||
CMP w2, #0 // Was this the first interrupt?
|
||||
BEQ __tx_thread_not_nested_restore // If so, not a nested restore
|
||||
|
||||
/* Interrupts are nested. */
|
||||
|
||||
/* Just recover the saved registers and return to the point of
|
||||
interrupt. */
|
||||
|
||||
LDP x4, x5, [sp], #16 // Pickup saved SPSR/DAIF and ELR_EL
|
||||
.ifdef EL1
|
||||
MSR SPSR_EL1, x4 // Setup SPSR for return
|
||||
MSR ELR_EL1, x5 // Setup point of interrupt
|
||||
.else
|
||||
.ifdef EL2
|
||||
MSR SPSR_EL2, x4 // Setup SPSR for return
|
||||
MSR ELR_EL2, x5 // Setup point of interrupt
|
||||
.else
|
||||
MSR SPSR_EL3, x4 // Setup SPSR for return
|
||||
MSR ELR_EL3, x5 // Setup point of interrupt
|
||||
.endif
|
||||
.endif
|
||||
LDP x18, x19, [sp], #16 // Recover x18, x19
|
||||
LDP x16, x17, [sp], #16 // Recover x16, x17
|
||||
LDP x14, x15, [sp], #16 // Recover x14, x15
|
||||
LDP x12, x13, [sp], #16 // Recover x12, x13
|
||||
LDP x10, x11, [sp], #16 // Recover x10, x11
|
||||
LDP x8, x9, [sp], #16 // Recover x8, x9
|
||||
LDP x6, x7, [sp], #16 // Recover x6, x7
|
||||
LDP x4, x5, [sp], #16 // Recover x4, x5
|
||||
LDP x2, x3, [sp], #16 // Recover x2, x3
|
||||
LDP x0, x1, [sp], #16 // Recover x0, x1
|
||||
LDP x29, x30, [sp], #16 // Recover x29, x30
|
||||
ERET // Return to point of interrupt
|
||||
|
||||
/* } */
|
||||
__tx_thread_not_nested_restore:
|
||||
|
||||
/* Determine if a thread was interrupted and no preemption is required. */
|
||||
/* else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
|
||||
|| (_tx_thread_preempt_disable))
|
||||
{ */
|
||||
|
||||
LDR x1, =_tx_thread_current_ptr // Pickup address of current thread ptr
|
||||
LDR x0, [x1, #0] // Pickup actual current thread pointer
|
||||
CMP x0, #0 // Is it NULL?
|
||||
BEQ __tx_thread_idle_system_restore // Yes, idle system was interrupted
|
||||
|
||||
LDR x3, =_tx_thread_preempt_disable // Pickup preempt disable address
|
||||
LDR w2, [x3, #0] // Pickup actual preempt disable flag
|
||||
CMP w2, #0 // Is it set?
|
||||
BNE __tx_thread_no_preempt_restore // Yes, don't preempt this thread
|
||||
LDR x3, =_tx_thread_execute_ptr // Pickup address of execute thread ptr
|
||||
LDR x2, [x3, #0] // Pickup actual execute thread pointer
|
||||
CMP x0, x2 // Is the same thread highest priority?
|
||||
BNE __tx_thread_preempt_restore // No, preemption needs to happen
|
||||
|
||||
|
||||
__tx_thread_no_preempt_restore:
|
||||
|
||||
/* Restore interrupted thread or ISR. */
|
||||
|
||||
/* Pickup the saved stack pointer. */
|
||||
/* sp = _tx_thread_current_ptr -> tx_thread_stack_ptr; */
|
||||
|
||||
LDR x4, [x0, #8] // Switch to thread stack pointer
|
||||
MOV sp, x4 //
|
||||
|
||||
/* Recover the saved context and return to the point of interrupt. */
|
||||
|
||||
LDP x4, x5, [sp], #16 // Pickup saved SPSR/DAIF and ELR_EL1
|
||||
.ifdef EL1
|
||||
MSR SPSR_EL1, x4 // Setup SPSR for return
|
||||
MSR ELR_EL1, x5 // Setup point of interrupt
|
||||
.else
|
||||
.ifdef EL2
|
||||
MSR SPSR_EL2, x4 // Setup SPSR for return
|
||||
MSR ELR_EL2, x5 // Setup point of interrupt
|
||||
.else
|
||||
MSR SPSR_EL3, x4 // Setup SPSR for return
|
||||
MSR ELR_EL3, x5 // Setup point of interrupt
|
||||
.endif
|
||||
.endif
|
||||
LDP x18, x19, [sp], #16 // Recover x18, x19
|
||||
LDP x16, x17, [sp], #16 // Recover x16, x17
|
||||
LDP x14, x15, [sp], #16 // Recover x14, x15
|
||||
LDP x12, x13, [sp], #16 // Recover x12, x13
|
||||
LDP x10, x11, [sp], #16 // Recover x10, x11
|
||||
LDP x8, x9, [sp], #16 // Recover x8, x9
|
||||
LDP x6, x7, [sp], #16 // Recover x6, x7
|
||||
LDP x4, x5, [sp], #16 // Recover x4, x5
|
||||
LDP x2, x3, [sp], #16 // Recover x2, x3
|
||||
LDP x0, x1, [sp], #16 // Recover x0, x1
|
||||
LDP x29, x30, [sp], #16 // Recover x29, x30
|
||||
ERET // Return to point of interrupt
|
||||
|
||||
/* }
|
||||
else
|
||||
{ */
|
||||
__tx_thread_preempt_restore:
|
||||
|
||||
LDR x4, [x0, #8] // Switch to thread stack pointer
|
||||
MOV sp, x4 //
|
||||
|
||||
LDP x4, x5, [sp], #16 // Pickup saved SPSR/DAIF and ELR_EL1
|
||||
STP x20, x21, [sp, #-16]! // Save x20, x21
|
||||
STP x22, x23, [sp, #-16]! // Save x22, x23
|
||||
STP x24, x25, [sp, #-16]! // Save x24, x25
|
||||
STP x26, x27, [sp, #-16]! // Save x26, x27
|
||||
STP x28, x29, [sp, #-16]! // Save x28, x29
|
||||
.ifdef ENABLE_ARM_FP
|
||||
LDR w3, [x0, #248] // Pickup FP enable flag
|
||||
CMP w3, #0 // Is FP enabled?
|
||||
BEQ _skip_fp_save // No, skip FP save
|
||||
STP q0, q1, [sp, #-32]! // Save q0, q1
|
||||
STP q2, q3, [sp, #-32]! // Save q2, q3
|
||||
STP q4, q5, [sp, #-32]! // Save q4, q5
|
||||
STP q6, q7, [sp, #-32]! // Save q6, q7
|
||||
STP q8, q9, [sp, #-32]! // Save q8, q9
|
||||
STP q10, q11, [sp, #-32]! // Save q10, q11
|
||||
STP q12, q13, [sp, #-32]! // Save q12, q13
|
||||
STP q14, q15, [sp, #-32]! // Save q14, q15
|
||||
STP q16, q17, [sp, #-32]! // Save q16, q17
|
||||
STP q18, q19, [sp, #-32]! // Save q18, q19
|
||||
STP q20, q21, [sp, #-32]! // Save q20, q21
|
||||
STP q22, q23, [sp, #-32]! // Save q22, q23
|
||||
STP q24, q25, [sp, #-32]! // Save q24, q25
|
||||
STP q26, q27, [sp, #-32]! // Save q26, q27
|
||||
STP q28, q29, [sp, #-32]! // Save q28, q29
|
||||
STP q30, q31, [sp, #-32]! // Save q30, q31
|
||||
MRS x2, FPSR // Pickup FPSR
|
||||
MRS x3, FPCR // Pickup FPCR
|
||||
STP x2, x3, [sp, #-16]! // Save FPSR, FPCR
|
||||
_skip_fp_save:
|
||||
.endif
|
||||
STP x4, x5, [sp, #-16]! // Save x4 (SPSR_EL3), x5 (ELR_E3)
|
||||
|
||||
MOV x3, sp // Move sp into x3
|
||||
STR x3, [x0, #8] // Save stack pointer in thread control
|
||||
// block
|
||||
LDR x3, =_tx_thread_system_stack_ptr // Pickup address of system stack
|
||||
LDR x4, [x3, #0] // Pickup system stack pointer
|
||||
MOV sp, x4 // Setup system stack pointer
|
||||
|
||||
|
||||
/* Save the remaining time-slice and disable it. */
|
||||
/* if (_tx_timer_time_slice)
|
||||
{ */
|
||||
|
||||
LDR x3, =_tx_timer_time_slice // Pickup time-slice variable address
|
||||
LDR w2, [x3, #0] // Pickup time-slice
|
||||
CMP w2, #0 // Is it active?
|
||||
BEQ __tx_thread_dont_save_ts // No, don't save it
|
||||
|
||||
/* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
|
||||
_tx_timer_time_slice = 0; */
|
||||
|
||||
STR w2, [x0, #36] // Save thread's time-slice
|
||||
MOV w2, #0 // Clear value
|
||||
STR w2, [x3, #0] // Disable global time-slice flag
|
||||
|
||||
/* } */
|
||||
__tx_thread_dont_save_ts:
|
||||
|
||||
|
||||
/* Clear the current task pointer. */
|
||||
/* _tx_thread_current_ptr = TX_NULL; */
|
||||
|
||||
MOV x0, #0 // NULL value
|
||||
STR x0, [x1, #0] // Clear current thread pointer
|
||||
|
||||
/* Return to the scheduler. */
|
||||
/* _tx_thread_schedule(); */
|
||||
|
||||
/* } */
|
||||
|
||||
__tx_thread_idle_system_restore:
|
||||
|
||||
/* Just return back to the scheduler! */
|
||||
|
||||
LDR x1, =_tx_thread_schedule // Build address for _tx_thread_schedule
|
||||
.ifdef EL1
|
||||
MSR ELR_EL1, x1 // Setup point of interrupt
|
||||
MOV x1, #0x5 // Setup EL1 return
|
||||
MSR spsr_el1, x1 // Move into SPSR
|
||||
.else
|
||||
.ifdef EL2
|
||||
MSR ELR_EL2, x1 // Setup point of interrupt
|
||||
MOV x1, #0x9 // Setup EL2 return
|
||||
MSR spsr_el2, x1 // Move into SPSR
|
||||
.else
|
||||
MSR ELR_EL3, x1 // Setup point of interrupt
|
||||
MOV x1, #0xD // Setup EL3 return
|
||||
MSR spsr_el3, x1 // Move into SPSR
|
||||
.endif
|
||||
.endif
|
||||
ERET // Return to scheduler
|
||||
/* } */
|
||||
|
||||
|
||||
228
ports/cortex_a5x/ac6/src/tx_thread_context_save.S
Normal file
228
ports/cortex_a5x/ac6/src/tx_thread_context_save.S
Normal file
@@ -0,0 +1,228 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/*
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
*/
|
||||
|
||||
.text
|
||||
.align 3
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_context_save Cortex-A5x/ARM */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function saves the context of an executing thread in the */
|
||||
/* beginning of interrupt processing. The function also ensures that */
|
||||
/* the system stack is used upon return to the calling ISR. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* ISRs */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_thread_context_save(VOID)
|
||||
{ */
|
||||
.global _tx_thread_context_save
|
||||
.type _tx_thread_context_save, @function
|
||||
_tx_thread_context_save:
|
||||
|
||||
/* Upon entry to this routine, it is assumed that IRQ/FIQ interrupts are locked
|
||||
out, x29 (frame pointer), x30 (link register) are saved, we are in EL1,
|
||||
and all other registers are intact. */
|
||||
|
||||
/* Check for a nested interrupt condition. */
|
||||
/* if (_tx_thread_system_state++)
|
||||
{ */
|
||||
|
||||
STP x0, x1, [sp, #-16]! // Save x0, x1
|
||||
STP x2, x3, [sp, #-16]! // Save x2, x3
|
||||
LDR x3, =_tx_thread_system_state // Pickup address of system state var
|
||||
LDR w2, [x3, #0] // Pickup system state
|
||||
CMP w2, #0 // Is this the first interrupt?
|
||||
BEQ __tx_thread_not_nested_save // Yes, not a nested context save
|
||||
|
||||
/* Nested interrupt condition. */
|
||||
|
||||
ADD w2, w2, #1 // Increment the nested interrupt counter
|
||||
STR w2, [x3, #0] // Store it back in the variable
|
||||
|
||||
/* Save the rest of the scratch registers on the stack and return to the
|
||||
calling ISR. */
|
||||
|
||||
STP x4, x5, [sp, #-16]! // Save x4, x5
|
||||
STP x6, x7, [sp, #-16]! // Save x6, x7
|
||||
STP x8, x9, [sp, #-16]! // Save x8, x9
|
||||
STP x10, x11, [sp, #-16]! // Save x10, x11
|
||||
STP x12, x13, [sp, #-16]! // Save x12, x13
|
||||
STP x14, x15, [sp, #-16]! // Save x14, x15
|
||||
STP x16, x17, [sp, #-16]! // Save x16, x17
|
||||
STP x18, x19, [sp, #-16]! // Save x18, x19
|
||||
.ifdef EL1
|
||||
MRS x0, SPSR_EL1 // Pickup SPSR
|
||||
MRS x1, ELR_EL1 // Pickup ELR (point of interrupt)
|
||||
.else
|
||||
.ifdef EL2
|
||||
MRS x0, SPSR_EL2 // Pickup SPSR
|
||||
MRS x1, ELR_EL2 // Pickup ELR (point of interrupt)
|
||||
.else
|
||||
MRS x0, SPSR_EL3 // Pickup SPSR
|
||||
MRS x1, ELR_EL3 // Pickup ELR (point of interrupt)
|
||||
.endif
|
||||
.endif
|
||||
STP x0, x1, [sp, #-16]! // Save SPSR, ELR
|
||||
|
||||
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
|
||||
/* Call the ISR enter function to indicate an ISR is executing. */
|
||||
|
||||
STP x29, x30, [sp, #-16]! // Save x29, x30
|
||||
BL _tx_execution_isr_enter // Call the ISR enter function
|
||||
LDP x29, x30, [sp], #16 // Recover x29, x30
|
||||
.endif
|
||||
|
||||
/* Return to the ISR. */
|
||||
|
||||
RET // Return to ISR
|
||||
|
||||
__tx_thread_not_nested_save:
|
||||
/* } */
|
||||
|
||||
/* Otherwise, not nested, check to see if a thread was running. */
|
||||
/* else if (_tx_thread_current_ptr)
|
||||
{ */
|
||||
|
||||
ADD w2, w2, #1 // Increment the interrupt counter
|
||||
STR w2, [x3, #0] // Store it back in the variable
|
||||
LDR x1, =_tx_thread_current_ptr // Pickup address of current thread ptr
|
||||
LDR x0, [x1, #0] // Pickup current thread pointer
|
||||
CMP x0, #0 // Is it NULL?
|
||||
BEQ __tx_thread_idle_system_save // If so, interrupt occurred in
|
||||
// scheduling loop - nothing needs saving!
|
||||
|
||||
/* Save minimal context of interrupted thread. */
|
||||
|
||||
STP x4, x5, [sp, #-16]! // Save x4, x5
|
||||
STP x6, x7, [sp, #-16]! // Save x6, x7
|
||||
STP x8, x9, [sp, #-16]! // Save x8, x9
|
||||
STP x10, x11, [sp, #-16]! // Save x10, x11
|
||||
STP x12, x13, [sp, #-16]! // Save x12, x13
|
||||
STP x14, x15, [sp, #-16]! // Save x14, x15
|
||||
STP x16, x17, [sp, #-16]! // Save x16, x17
|
||||
STP x18, x19, [sp, #-16]! // Save x18, x19
|
||||
.ifdef EL1
|
||||
MRS x4, SPSR_EL1 // Pickup SPSR
|
||||
MRS x5, ELR_EL1 // Pickup ELR (point of interrupt)
|
||||
.else
|
||||
.ifdef EL2
|
||||
MRS x4, SPSR_EL2 // Pickup SPSR
|
||||
MRS x5, ELR_EL2 // Pickup ELR (point of interrupt)
|
||||
.else
|
||||
MRS x4, SPSR_EL3 // Pickup SPSR
|
||||
MRS x5, ELR_EL3 // Pickup ELR (point of interrupt)
|
||||
.endif
|
||||
.endif
|
||||
STP x4, x5, [sp, #-16]! // Save SPSR, ELR
|
||||
|
||||
/* Save the current stack pointer in the thread's control block. */
|
||||
/* _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; */
|
||||
|
||||
MOV x4, sp //
|
||||
STR x4, [x0, #8] // Save thread stack pointer
|
||||
|
||||
/* Switch to the system stack. */
|
||||
/* sp = _tx_thread_system_stack_ptr; */
|
||||
|
||||
LDR x3, =_tx_thread_system_stack_ptr // Pickup address of system stack
|
||||
LDR x4, [x3, #0] // Pickup system stack pointer
|
||||
MOV sp, x4 // Setup system stack pointer
|
||||
|
||||
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
|
||||
/* Call the ISR enter function to indicate an ISR is executing. */
|
||||
|
||||
STP x29, x30, [sp, #-16]! // Save x29, x30
|
||||
BL _tx_execution_isr_enter // Call the ISR enter function
|
||||
LDP x29, x30, [sp], #16 // Recover x29, x30
|
||||
.endif
|
||||
|
||||
RET // Return to caller
|
||||
|
||||
/* }
|
||||
else
|
||||
{ */
|
||||
|
||||
__tx_thread_idle_system_save:
|
||||
|
||||
/* Interrupt occurred in the scheduling loop. */
|
||||
|
||||
/* Not much to do here, just adjust the stack pointer, and return to IRQ
|
||||
processing. */
|
||||
|
||||
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
|
||||
/* Call the ISR enter function to indicate an ISR is executing. */
|
||||
|
||||
STP x29, x30, [sp, #-16]! // Save x29, x30
|
||||
BL _tx_execution_isr_enter // Call the ISR enter function
|
||||
LDP x29, x30, [sp], #16 // Recover x29, x30
|
||||
.endif
|
||||
|
||||
ADD sp, sp, #48 // Recover saved registers
|
||||
RET // Continue IRQ processing
|
||||
|
||||
/* }
|
||||
} */
|
||||
|
||||
|
||||
95
ports/cortex_a5x/ac6/src/tx_thread_fp_disable.c
Normal file
95
ports/cortex_a5x/ac6/src/tx_thread_fp_disable.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_fp_disable Cortex-A5x/ARM */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function disables the FP for the currently executing thread. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _tx_thread_fp_disable(VOID)
|
||||
{
|
||||
|
||||
TX_THREAD *thread_ptr;
|
||||
ULONG system_state;
|
||||
|
||||
|
||||
/* Pickup the current thread pointer. */
|
||||
TX_THREAD_GET_CURRENT(thread_ptr);
|
||||
|
||||
/* Get the system state. */
|
||||
system_state = TX_THREAD_GET_SYSTEM_STATE();
|
||||
|
||||
/* Make sure it is not NULL. */
|
||||
if (thread_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Thread is running... make sure the call is from the thread context. */
|
||||
if (system_state == 0)
|
||||
{
|
||||
|
||||
/* Yes, now set the FP enable flag to false in the TX_THREAD structure. */
|
||||
thread_ptr -> tx_thread_fp_enable = TX_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
95
ports/cortex_a5x/ac6/src/tx_thread_fp_enable.c
Normal file
95
ports/cortex_a5x/ac6/src/tx_thread_fp_enable.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_fp_enable Cortex-A5x/ARM */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function enabled the FP for the currently executing thread. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
VOID _tx_thread_fp_enable(VOID)
|
||||
{
|
||||
|
||||
TX_THREAD *thread_ptr;
|
||||
ULONG system_state;
|
||||
|
||||
|
||||
/* Pickup the current thread pointer. */
|
||||
TX_THREAD_GET_CURRENT(thread_ptr);
|
||||
|
||||
/* Get the system state. */
|
||||
system_state = TX_THREAD_GET_SYSTEM_STATE();
|
||||
|
||||
/* Make sure it is not NULL. */
|
||||
if (thread_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Thread is running... make sure the call is from the thread context. */
|
||||
if (system_state == 0)
|
||||
{
|
||||
|
||||
/* Yes, now setup the FP enable flag in the TX_THREAD structure. */
|
||||
thread_ptr -> tx_thread_fp_enable = TX_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
89
ports/cortex_a5x/ac6/src/tx_thread_interrupt_control.S
Normal file
89
ports/cortex_a5x/ac6/src/tx_thread_interrupt_control.S
Normal file
@@ -0,0 +1,89 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/*#define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/*
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
*/
|
||||
|
||||
.text
|
||||
.align 3
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_interrupt_control Cortex-A5x/ARM */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function is responsible for changing the interrupt lockout */
|
||||
/* posture of the system. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* new_posture New interrupt lockout posture */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* old_posture Old interrupt lockout posture */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* UINT _tx_thread_interrupt_control(UINT new_posture)
|
||||
{ */
|
||||
.global _tx_thread_interrupt_control
|
||||
.type _tx_thread_interrupt_control, @function
|
||||
_tx_thread_interrupt_control:
|
||||
|
||||
/* Pickup current interrupt lockout posture. */
|
||||
|
||||
MRS x1, DAIF // Pickup current interrupt posture
|
||||
|
||||
/* Apply the new interrupt posture. */
|
||||
|
||||
MSR DAIF, x0 // Set new interrupt posture
|
||||
MOV x0, x1 // Setup return value
|
||||
RET // Return to caller
|
||||
/* } */
|
||||
|
||||
87
ports/cortex_a5x/ac6/src/tx_thread_interrupt_disable.S
Normal file
87
ports/cortex_a5x/ac6/src/tx_thread_interrupt_disable.S
Normal file
@@ -0,0 +1,87 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/*
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
*/
|
||||
|
||||
.text
|
||||
.align 3
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_interrupt_disable Cortex-A5x/ARM */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function is responsible for disabling interrupts */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* old_posture Old interrupt lockout posture */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* UINT _tx_thread_interrupt_disable(void)
|
||||
{ */
|
||||
.global _tx_thread_interrupt_disable
|
||||
.type _tx_thread_interrupt_disable, @function
|
||||
_tx_thread_interrupt_disable:
|
||||
|
||||
/* Pickup current interrupt lockout posture. */
|
||||
|
||||
MRS x0, DAIF // Pickup current interrupt lockout posture
|
||||
|
||||
/* Mask interrupts. */
|
||||
|
||||
MSR DAIFSet, 0x3 // Lockout interrupts
|
||||
RET // Return to caller
|
||||
/* } */
|
||||
|
||||
85
ports/cortex_a5x/ac6/src/tx_thread_interrupt_restore.S
Normal file
85
ports/cortex_a5x/ac6/src/tx_thread_interrupt_restore.S
Normal file
@@ -0,0 +1,85 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/*
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
*/
|
||||
|
||||
.text
|
||||
.align 3
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_interrupt_restore Cortex-A5x/ARM */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function is responsible for restoring interrupts to the state */
|
||||
/* returned by a previous _tx_thread_interrupt_disable call. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* old_posture Old interrupt lockout posture */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* UINT _tx_thread_interrupt_restore(UINT old_posture)
|
||||
{ */
|
||||
.global _tx_thread_interrupt_restore
|
||||
.type _tx_thread_interrupt_restore, @function
|
||||
_tx_thread_interrupt_restore:
|
||||
|
||||
/* Restore the old interrupt posture. */
|
||||
|
||||
MSR DAIF, x0 // Setup the old posture
|
||||
RET // Return to caller
|
||||
|
||||
/* } */
|
||||
|
||||
240
ports/cortex_a5x/ac6/src/tx_thread_schedule.S
Normal file
240
ports/cortex_a5x/ac6/src/tx_thread_schedule.S
Normal file
@@ -0,0 +1,240 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/*
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_timer.h"
|
||||
*/
|
||||
|
||||
/* .set ENABLE_ARM_FP,1 */
|
||||
|
||||
.text
|
||||
.align 3
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_schedule Cortex-A5x/ARM */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function waits for a thread control block pointer to appear in */
|
||||
/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
|
||||
/* in the variable, the corresponding thread is resumed. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _tx_initialize_kernel_enter ThreadX entry function */
|
||||
/* _tx_thread_system_return Return to system from thread */
|
||||
/* _tx_thread_context_restore Restore thread's context */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_thread_schedule(VOID)
|
||||
{ */
|
||||
.global _tx_thread_schedule
|
||||
.type _tx_thread_schedule, @function
|
||||
_tx_thread_schedule:
|
||||
|
||||
/* Enable interrupts. */
|
||||
|
||||
MSR DAIFClr, 0x3 // Enable interrupts
|
||||
|
||||
/* Wait for a thread to execute. */
|
||||
/* do
|
||||
{ */
|
||||
|
||||
LDR x1, =_tx_thread_execute_ptr // Address of thread execute ptr
|
||||
|
||||
.ifdef TX_ENABLE_WFI
|
||||
__tx_thread_schedule_loop:
|
||||
LDR x0, [x1, #0] // Pickup next thread to execute
|
||||
CMP x0, #0 // Is it NULL?
|
||||
BNE _tx_thread_schedule_thread //
|
||||
WFI //
|
||||
B __tx_thread_schedule_loop // Keep looking for a thread
|
||||
_tx_thread_schedule_thread:
|
||||
.else
|
||||
__tx_thread_schedule_loop:
|
||||
LDR x0, [x1, #0] // Pickup next thread to execute
|
||||
CMP x0, #0 // Is it NULL?
|
||||
BEQ __tx_thread_schedule_loop // If so, keep looking for a thread
|
||||
.endif
|
||||
|
||||
/* }
|
||||
while(_tx_thread_execute_ptr == TX_NULL); */
|
||||
|
||||
/* Yes! We have a thread to execute. Lockout interrupts and
|
||||
transfer control to it. */
|
||||
|
||||
MSR DAIFSet, 0x3 // Lockout interrupts
|
||||
|
||||
/* Setup the current thread pointer. */
|
||||
/* _tx_thread_current_ptr = _tx_thread_execute_ptr; */
|
||||
|
||||
LDR x1, =_tx_thread_current_ptr // Pickup address of current thread
|
||||
STR x0, [x1, #0] // Setup current thread pointer
|
||||
|
||||
/* Increment the run count for this thread. */
|
||||
/* _tx_thread_current_ptr -> tx_thread_run_count++; */
|
||||
|
||||
LDR w2, [x0, #4] // Pickup run counter
|
||||
LDR w3, [x0, #36] // Pickup time-slice for this thread
|
||||
ADD w2, w2, #1 // Increment thread run-counter
|
||||
STR w2, [x0, #4] // Store the new run counter
|
||||
|
||||
/* Setup time-slice, if present. */
|
||||
/* _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice; */
|
||||
|
||||
LDR x2, =_tx_timer_time_slice // Pickup address of time slice
|
||||
// variable
|
||||
LDR x4, [x0, #8] // Switch stack pointers
|
||||
MOV sp, x4 //
|
||||
STR w3, [x2, #0] // Setup time-slice
|
||||
|
||||
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
|
||||
/* Call the thread entry function to indicate the thread is executing. */
|
||||
|
||||
MOV x19, x0 // Save x0
|
||||
BL _tx_execution_thread_enter // Call the thread execution enter function
|
||||
MOV x0, x19 // Restore x0
|
||||
.endif
|
||||
|
||||
/* Switch to the thread's stack. */
|
||||
/* sp = _tx_thread_execute_ptr -> tx_thread_stack_ptr; */
|
||||
|
||||
/* Determine if an interrupt frame or a synchronous task suspension frame
|
||||
is present. */
|
||||
|
||||
LDP x4, x5, [sp], #16 // Pickup saved SPSR/DAIF and ELR_EL1
|
||||
CMP x5, #0 // Check for synchronous context switch (ELR_EL1 = NULL)
|
||||
BEQ _tx_solicited_return
|
||||
.ifdef EL1
|
||||
MSR SPSR_EL1, x4 // Setup SPSR for return
|
||||
MSR ELR_EL1, x5 // Setup point of interrupt
|
||||
.else
|
||||
.ifdef EL2
|
||||
MSR SPSR_EL2, x4 // Setup SPSR for return
|
||||
MSR ELR_EL2, x5 // Setup point of interrupt
|
||||
.else
|
||||
MSR SPSR_EL3, x4 // Setup SPSR for return
|
||||
MSR ELR_EL3, x5 // Setup point of interrupt
|
||||
.endif
|
||||
.endif
|
||||
.ifdef ENABLE_ARM_FP
|
||||
LDR w1, [x0, #248] // Pickup FP enable flag
|
||||
CMP w1, #0 // Is FP enabled?
|
||||
BEQ _skip_interrupt_fp_restore // No, skip FP restore
|
||||
LDP x0, x1, [sp], #16 // Pickup FPSR, FPCR
|
||||
MSR FPSR, x0 // Recover FPSR
|
||||
MSR FPCR, x1 // Recover FPCR
|
||||
LDP q30, q31, [sp], #32 // Recover q30, q31
|
||||
LDP q28, q29, [sp], #32 // Recover q28, q29
|
||||
LDP q26, q27, [sp], #32 // Recover q26, q27
|
||||
LDP q24, q25, [sp], #32 // Recover q24, q25
|
||||
LDP q22, q23, [sp], #32 // Recover q22, q23
|
||||
LDP q20, q21, [sp], #32 // Recover q20, q21
|
||||
LDP q18, q19, [sp], #32 // Recover q18, q19
|
||||
LDP q16, q17, [sp], #32 // Recover q16, q17
|
||||
LDP q14, q15, [sp], #32 // Recover q14, q15
|
||||
LDP q12, q13, [sp], #32 // Recover q12, q13
|
||||
LDP q10, q11, [sp], #32 // Recover q10, q11
|
||||
LDP q8, q9, [sp], #32 // Recover q8, q9
|
||||
LDP q6, q7, [sp], #32 // Recover q6, q7
|
||||
LDP q4, q5, [sp], #32 // Recover q4, q5
|
||||
LDP q2, q3, [sp], #32 // Recover q2, q3
|
||||
LDP q0, q1, [sp], #32 // Recover q0, q1
|
||||
_skip_interrupt_fp_restore:
|
||||
.endif
|
||||
LDP x28, x29, [sp], #16 // Recover x28
|
||||
LDP x26, x27, [sp], #16 // Recover x26, x27
|
||||
LDP x24, x25, [sp], #16 // Recover x24, x25
|
||||
LDP x22, x23, [sp], #16 // Recover x22, x23
|
||||
LDP x20, x21, [sp], #16 // Recover x20, x21
|
||||
LDP x18, x19, [sp], #16 // Recover x18, x19
|
||||
LDP x16, x17, [sp], #16 // Recover x16, x17
|
||||
LDP x14, x15, [sp], #16 // Recover x14, x15
|
||||
LDP x12, x13, [sp], #16 // Recover x12, x13
|
||||
LDP x10, x11, [sp], #16 // Recover x10, x11
|
||||
LDP x8, x9, [sp], #16 // Recover x8, x9
|
||||
LDP x6, x7, [sp], #16 // Recover x6, x7
|
||||
LDP x4, x5, [sp], #16 // Recover x4, x5
|
||||
LDP x2, x3, [sp], #16 // Recover x2, x3
|
||||
LDP x0, x1, [sp], #16 // Recover x0, x1
|
||||
LDP x29, x30, [sp], #16 // Recover x29, x30
|
||||
ERET // Return to point of interrupt
|
||||
|
||||
_tx_solicited_return:
|
||||
|
||||
.ifdef ENABLE_ARM_FP
|
||||
LDR w1, [x0, #248] // Pickup FP enable flag
|
||||
CMP w1, #0 // Is FP enabled?
|
||||
BEQ _skip_solicited_fp_restore // No, skip FP restore
|
||||
LDP x0, x1, [sp], #16 // Pickup FPSR, FPCR
|
||||
MSR FPSR, x0 // Recover FPSR
|
||||
MSR FPCR, x1 // Recover FPCR
|
||||
LDP q14, q15, [sp], #32 // Recover q14, q15
|
||||
LDP q12, q13, [sp], #32 // Recover q12, q13
|
||||
LDP q10, q11, [sp], #32 // Recover q10, q11
|
||||
LDP q8, q9, [sp], #32 // Recover q8, q9
|
||||
_skip_solicited_fp_restore:
|
||||
.endif
|
||||
LDP x27, x28, [sp], #16 // Recover x27, x28
|
||||
LDP x25, x26, [sp], #16 // Recover x25, x26
|
||||
LDP x23, x24, [sp], #16 // Recover x23, x24
|
||||
LDP x21, x22, [sp], #16 // Recover x21, x22
|
||||
LDP x19, x20, [sp], #16 // Recover x19, x20
|
||||
LDP x29, x30, [sp], #16 // Recover x29, x30
|
||||
MSR DAIF, x4 // Recover DAIF
|
||||
RET // Return to caller
|
||||
/* } */
|
||||
|
||||
|
||||
170
ports/cortex_a5x/ac6/src/tx_thread_stack_build.S
Normal file
170
ports/cortex_a5x/ac6/src/tx_thread_stack_build.S
Normal file
@@ -0,0 +1,170 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/*
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
*/
|
||||
|
||||
|
||||
.text
|
||||
.align 3
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_stack_build Cortex-A5x/ARM */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function builds a stack frame on the supplied thread's stack. */
|
||||
/* The stack frame results in a fake interrupt return to the supplied */
|
||||
/* function pointer. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* thread_ptr Pointer to thread control blk */
|
||||
/* function_ptr Pointer to return function */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* _tx_thread_create Create thread service */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
|
||||
{ */
|
||||
.global _tx_thread_stack_build
|
||||
.type _tx_thread_stack_build, @function
|
||||
_tx_thread_stack_build:
|
||||
|
||||
|
||||
/* Build a fake interrupt frame. The form of the fake interrupt stack
|
||||
on the Cortex-A5x should look like the following after it is built:
|
||||
|
||||
Stack Top: SSPR Initial SSPR
|
||||
ELR Point of interrupt
|
||||
x28 Initial value for x28
|
||||
not used Not used
|
||||
x26 Initial value for x26
|
||||
x27 Initial value for x27
|
||||
x24 Initial value for x24
|
||||
x25 Initial value for x25
|
||||
x22 Initial value for x22
|
||||
x23 Initial value for x23
|
||||
x20 Initial value for x20
|
||||
x21 Initial value for x21
|
||||
x18 Initial value for x18
|
||||
x19 Initial value for x19
|
||||
x16 Initial value for x16
|
||||
x17 Initial value for x17
|
||||
x14 Initial value for x14
|
||||
x15 Initial value for x15
|
||||
x12 Initial value for x12
|
||||
x13 Initial value for x13
|
||||
x10 Initial value for x10
|
||||
x11 Initial value for x11
|
||||
x8 Initial value for x8
|
||||
x9 Initial value for x9
|
||||
x6 Initial value for x6
|
||||
x7 Initial value for x7
|
||||
x4 Initial value for x4
|
||||
x5 Initial value for x5
|
||||
x2 Initial value for x2
|
||||
x3 Initial value for x3
|
||||
x0 Initial value for x0
|
||||
x1 Initial value for x1
|
||||
x29 Initial value for x29 (frame pointer)
|
||||
x30 Initial value for x30 (link register)
|
||||
0 For stack backtracing
|
||||
|
||||
Stack Bottom: (higher memory address) */
|
||||
|
||||
LDR x4, [x0, #24] // Pickup end of stack area
|
||||
BIC x4, x4, #0xF // Ensure 16-byte alignment
|
||||
|
||||
/* Actually build the stack frame. */
|
||||
|
||||
MOV x2, #0 // Build clear value
|
||||
MOV x3, #0 //
|
||||
|
||||
STP x2, x3, [x4, #-16]! // Set backtrace to 0
|
||||
STP x2, x3, [x4, #-16]! // Set initial x29, x30
|
||||
STP x2, x3, [x4, #-16]! // Set initial x0, x1
|
||||
STP x2, x3, [x4, #-16]! // Set initial x2, x3
|
||||
STP x2, x3, [x4, #-16]! // Set initial x4, x5
|
||||
STP x2, x3, [x4, #-16]! // Set initial x6, x7
|
||||
STP x2, x3, [x4, #-16]! // Set initial x8, x9
|
||||
STP x2, x3, [x4, #-16]! // Set initial x10, x11
|
||||
STP x2, x3, [x4, #-16]! // Set initial x12, x13
|
||||
STP x2, x3, [x4, #-16]! // Set initial x14, x15
|
||||
STP x2, x3, [x4, #-16]! // Set initial x16, x17
|
||||
STP x2, x3, [x4, #-16]! // Set initial x18, x19
|
||||
STP x2, x3, [x4, #-16]! // Set initial x20, x21
|
||||
STP x2, x3, [x4, #-16]! // Set initial x22, x23
|
||||
STP x2, x3, [x4, #-16]! // Set initial x24, x25
|
||||
STP x2, x3, [x4, #-16]! // Set initial x26, x27
|
||||
STP x2, x3, [x4, #-16]! // Set initial x28
|
||||
.ifdef EL1
|
||||
MOV x2, #0x5 // Build initial SPSR (EL1)
|
||||
.else
|
||||
.ifdef EL2
|
||||
MOV x2, #0x9 // Build initial SPSR (EL2)
|
||||
.else
|
||||
MOV x2, #0xD // Build initial SPSR (EL3)
|
||||
.endif
|
||||
.endif
|
||||
MOV x3, x1 // Build initial ELR
|
||||
STP x2, x3, [x4, #-16]! // Set initial SPSR & ELR
|
||||
|
||||
/* Setup stack pointer. */
|
||||
/* thread_ptr -> tx_thread_stack_ptr = x2; */
|
||||
|
||||
STR x4, [x0, #8] // Save stack pointer in thread's
|
||||
RET // Return to caller
|
||||
|
||||
/* } */
|
||||
|
||||
|
||||
165
ports/cortex_a5x/ac6/src/tx_thread_system_return.S
Normal file
165
ports/cortex_a5x/ac6/src/tx_thread_system_return.S
Normal file
@@ -0,0 +1,165 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Thread */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/*
|
||||
#include "tx_api.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_timer.h"
|
||||
*/
|
||||
|
||||
/* .set ENABLE_ARM_FP,1 */
|
||||
|
||||
.text
|
||||
.align 3
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_thread_system_return Cortex-A5x/ARM */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function is target processor specific. It is used to transfer */
|
||||
/* control from a thread back to the ThreadX system. Only a */
|
||||
/* minimal context is saved since the compiler assumes temp registers */
|
||||
/* are going to get slicked by a function call anyway. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_schedule Thread scheduling loop */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* ThreadX components */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_thread_system_return(VOID)
|
||||
{ */
|
||||
.global _tx_thread_system_return
|
||||
.type _tx_thread_system_return, @function
|
||||
_tx_thread_system_return:
|
||||
;
|
||||
; /* Save minimal context on the stack. */
|
||||
;
|
||||
MRS x0, DAIF // Pickup DAIF
|
||||
MSR DAIFSet, 0x3 // Lockout interrupts
|
||||
STP x29, x30, [sp, #-16]! // Save x29 (frame pointer), x30 (link register)
|
||||
STP x19, x20, [sp, #-16]! // Save x19, x20
|
||||
STP x21, x22, [sp, #-16]! // Save x21, x22
|
||||
STP x23, x24, [sp, #-16]! // Save x23, x24
|
||||
STP x25, x26, [sp, #-16]! // Save x25, x26
|
||||
STP x27, x28, [sp, #-16]! // Save x27, x28
|
||||
LDR x5, =_tx_thread_current_ptr // Pickup address of current ptr
|
||||
LDR x6, [x5, #0] // Pickup current thread pointer
|
||||
|
||||
.ifdef ENABLE_ARM_FP
|
||||
LDR w7, [x6, #248] // Pickup FP enable flag
|
||||
CMP w7, #0 // Is FP enabled?
|
||||
BEQ _skip_fp_save // No, skip FP save
|
||||
STP q8, q9, [sp, #-32]! // Save q8, q9
|
||||
STP q10, q11, [sp, #-32]! // Save q10, q11
|
||||
STP q12, q13, [sp, #-32]! // Save q12, q13
|
||||
STP q14, q15, [sp, #-32]! // Save q14, q15
|
||||
MRS x2, FPSR // Pickup FPSR
|
||||
MRS x3, FPCR // Pickup FPCR
|
||||
STP x2, x3, [sp, #-16]! // Save FPSR, FPCR
|
||||
_skip_fp_save:
|
||||
.endif
|
||||
|
||||
MOV x1, #0 // Clear x1
|
||||
STP x0, x1, [sp, #-16]! // Save DAIF and clear value for ELR_EK1
|
||||
|
||||
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
|
||||
|
||||
/* Call the thread exit function to indicate the thread is no longer executing. */
|
||||
|
||||
MOV x19, x5 // Save x5
|
||||
MOV x20, x6 // Save x6
|
||||
BL _tx_execution_thread_exit // Call the thread exit function
|
||||
MOV x5, x19 // Restore x5
|
||||
MOV x6, x20 // Restore x6
|
||||
.endif
|
||||
|
||||
LDR x2, =_tx_timer_time_slice // Pickup address of time slice
|
||||
LDR w1, [x2, #0] // Pickup current time slice
|
||||
|
||||
/* Save current stack and switch to system stack. */
|
||||
/* _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; */
|
||||
/* sp = _tx_thread_system_stack_ptr; */
|
||||
|
||||
MOV x4, sp //
|
||||
STR x4, [x6, #8] // Save thread stack pointer
|
||||
LDR x3, =_tx_thread_system_stack_ptr // Pickup address of system stack
|
||||
LDR x4, [x3, #0] // Pickup system stack pointer
|
||||
MOV sp, x4 // Setup system stack pointer
|
||||
|
||||
/* Determine if the time-slice is active. */
|
||||
/* if (_tx_timer_time_slice)
|
||||
{ */
|
||||
|
||||
MOV x4, #0 // Build clear value
|
||||
CMP w1, #0 // Is a time-slice active?
|
||||
BEQ __tx_thread_dont_save_ts // No, don't save the time-slice
|
||||
|
||||
/* Save the current remaining time-slice. */
|
||||
/* _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
|
||||
_tx_timer_time_slice = 0; */
|
||||
|
||||
STR w4, [x2, #0] // Clear time-slice
|
||||
STR w1, [x6, #36] // Store current time-slice
|
||||
|
||||
/* } */
|
||||
__tx_thread_dont_save_ts:
|
||||
|
||||
/* Clear the current thread pointer. */
|
||||
/* _tx_thread_current_ptr = TX_NULL; */
|
||||
|
||||
STR x4, [x5, #0] // Clear current thread pointer
|
||||
|
||||
B _tx_thread_schedule // Jump to scheduler!
|
||||
|
||||
/* } */
|
||||
|
||||
|
||||
240
ports/cortex_a5x/ac6/src/tx_timer_interrupt.S
Normal file
240
ports/cortex_a5x/ac6/src/tx_timer_interrupt.S
Normal file
@@ -0,0 +1,240 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Timer */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
/* #define TX_SOURCE_CODE */
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
/*
|
||||
#include "tx_api.h"
|
||||
#include "tx_timer.h"
|
||||
#include "tx_thread.h"
|
||||
*/
|
||||
|
||||
.text
|
||||
.align 3
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_timer_interrupt Cortex-A5x/ARM */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function processes the hardware timer interrupt. This */
|
||||
/* processing includes incrementing the system clock and checking for */
|
||||
/* time slice and/or timer expiration. If either is found, the */
|
||||
/* interrupt context save/restore functions are called along with the */
|
||||
/* expiration functions. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* None */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_timer_expiration_process Timer expiration processing */
|
||||
/* _tx_thread_time_slice Time slice interrupted thread */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* interrupt vector */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
/* VOID _tx_timer_interrupt(VOID)
|
||||
{ */
|
||||
.global _tx_timer_interrupt
|
||||
.type _tx_timer_interrupt, @function
|
||||
_tx_timer_interrupt:
|
||||
|
||||
/* Upon entry to this routine, it is assumed that context save has already
|
||||
been called, and therefore the compiler scratch registers are available
|
||||
for use. */
|
||||
|
||||
/* Increment the system clock. */
|
||||
/* _tx_timer_system_clock++; */
|
||||
|
||||
LDR x1, =_tx_timer_system_clock // Pickup address of system clock
|
||||
LDR w0, [x1, #0] // Pickup system clock
|
||||
ADD w0, w0, #1 // Increment system clock
|
||||
STR w0, [x1, #0] // Store new system clock
|
||||
|
||||
/* Test for time-slice expiration. */
|
||||
/* if (_tx_timer_time_slice)
|
||||
{ */
|
||||
|
||||
LDR x3, =_tx_timer_time_slice // Pickup address of time-slice
|
||||
LDR w2, [x3, #0] // Pickup time-slice
|
||||
CMP w2, #0 // Is it non-active?
|
||||
BEQ __tx_timer_no_time_slice // Yes, skip time-slice processing
|
||||
|
||||
/* Decrement the time_slice. */
|
||||
/* _tx_timer_time_slice--; */
|
||||
|
||||
SUB w2, w2, #1 // Decrement the time-slice
|
||||
STR w2, [x3, #0] // Store new time-slice value
|
||||
|
||||
/* Check for expiration. */
|
||||
/* if (__tx_timer_time_slice == 0) */
|
||||
|
||||
CMP w2, #0 // Has it expired?
|
||||
BNE __tx_timer_no_time_slice // No, skip expiration processing
|
||||
|
||||
/* Set the time-slice expired flag. */
|
||||
/* _tx_timer_expired_time_slice = TX_TRUE; */
|
||||
|
||||
LDR x3, =_tx_timer_expired_time_slice // Pickup address of expired flag
|
||||
MOV w0, #1 // Build expired value
|
||||
STR w0, [x3, #0] // Set time-slice expiration flag
|
||||
|
||||
/* } */
|
||||
|
||||
__tx_timer_no_time_slice:
|
||||
|
||||
/* Test for timer expiration. */
|
||||
/* if (*_tx_timer_current_ptr)
|
||||
{ */
|
||||
|
||||
LDR x1, =_tx_timer_current_ptr // Pickup current timer pointer addr
|
||||
LDR x0, [x1, #0] // Pickup current timer
|
||||
LDR x2, [x0, #0] // Pickup timer list entry
|
||||
CMP x2, #0 // Is there anything in the list?
|
||||
BEQ __tx_timer_no_timer // No, just increment the timer
|
||||
|
||||
/* Set expiration flag. */
|
||||
/* _tx_timer_expired = TX_TRUE; */
|
||||
|
||||
LDR x3, =_tx_timer_expired // Pickup expiration flag address
|
||||
MOV w2, #1 // Build expired value
|
||||
STR w2, [x3, #0] // Set expired flag
|
||||
B __tx_timer_done // Finished timer processing
|
||||
|
||||
/* }
|
||||
else
|
||||
{ */
|
||||
__tx_timer_no_timer:
|
||||
|
||||
/* No timer expired, increment the timer pointer. */
|
||||
/* _tx_timer_current_ptr++; */
|
||||
|
||||
ADD x0, x0, #8 // Move to next timer
|
||||
|
||||
/* Check for wrap-around. */
|
||||
/* if (_tx_timer_current_ptr == _tx_timer_list_end) */
|
||||
|
||||
LDR x3, =_tx_timer_list_end // Pickup addr of timer list end
|
||||
LDR x2, [x3, #0] // Pickup list end
|
||||
CMP x0, x2 // Are we at list end?
|
||||
BNE __tx_timer_skip_wrap // No, skip wrap-around logic
|
||||
|
||||
/* Wrap to beginning of list. */
|
||||
/* _tx_timer_current_ptr = _tx_timer_list_start; */
|
||||
|
||||
LDR x3, =_tx_timer_list_start // Pickup addr of timer list start
|
||||
LDR x0, [x3, #0] // Set current pointer to list start
|
||||
|
||||
__tx_timer_skip_wrap:
|
||||
|
||||
STR x0, [x1, #0] // Store new current timer pointer
|
||||
/* } */
|
||||
|
||||
__tx_timer_done:
|
||||
|
||||
|
||||
/* See if anything has expired. */
|
||||
/* if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
|
||||
{ */
|
||||
|
||||
LDR x3, =_tx_timer_expired_time_slice // Pickup addr of expired flag
|
||||
LDR w2, [x3, #0] // Pickup time-slice expired flag
|
||||
CMP w2, #0 // Did a time-slice expire?
|
||||
BNE __tx_something_expired // If non-zero, time-slice expired
|
||||
LDR x1, =_tx_timer_expired // Pickup addr of other expired flag
|
||||
LDR w0, [x1, #0] // Pickup timer expired flag
|
||||
CMP w0, #0 // Did a timer expire?
|
||||
BEQ __tx_timer_nothing_expired // No, nothing expired
|
||||
|
||||
__tx_something_expired:
|
||||
|
||||
|
||||
STP x29, x30, [sp, #-16]! // Save x29 (frame pointer), x30 (link register)
|
||||
|
||||
/* Did a timer expire? */
|
||||
/* if (_tx_timer_expired)
|
||||
{ */
|
||||
|
||||
LDR x1, =_tx_timer_expired // Pickup addr of expired flag
|
||||
LDR w0, [x1, #0] // Pickup timer expired flag
|
||||
CMP w0, #0 // Check for timer expiration
|
||||
BEQ __tx_timer_dont_activate // If not set, skip timer activation
|
||||
|
||||
/* Process timer expiration. */
|
||||
/* _tx_timer_expiration_process(); */
|
||||
|
||||
BL _tx_timer_expiration_process // Call the timer expiration handling routine
|
||||
|
||||
/* } */
|
||||
__tx_timer_dont_activate:
|
||||
|
||||
/* Did time slice expire? */
|
||||
/* if (_tx_timer_expired_time_slice)
|
||||
{ */
|
||||
|
||||
LDR x3, =_tx_timer_expired_time_slice // Pickup addr of time-slice expired
|
||||
LDR w2, [x3, #0] // Pickup the actual flag
|
||||
CMP w2, #0 // See if the flag is set
|
||||
BEQ __tx_timer_not_ts_expiration // No, skip time-slice processing
|
||||
|
||||
/* Time slice interrupted thread. */
|
||||
/* _tx_thread_time_slice(); */
|
||||
|
||||
BL _tx_thread_time_slice // Call time-slice processing
|
||||
|
||||
/* } */
|
||||
|
||||
__tx_timer_not_ts_expiration:
|
||||
|
||||
LDP x29, x30, [sp], #16 // Recover x29, x30
|
||||
/* } */
|
||||
|
||||
__tx_timer_nothing_expired:
|
||||
|
||||
RET // Return to caller
|
||||
|
||||
/* } */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user