updated to 6.0.1 and added additional processors/toolchains

This commit is contained in:
tameraw
2020-07-16 14:32:40 -07:00
parent f8e91d4762
commit 2c35570dc9
1285 changed files with 550383 additions and 50 deletions

View 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="&quot;${workspace_loc:/tx/inc_generic}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/tx/inc_port}&quot;"/>
</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>

View 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>

View File

@@ -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 &quot;${INPUTS}&quot;" 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 &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
</project>

View File

@@ -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
// ------------------------------------------------------------

View File

@@ -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
// ------------------------------------------------------------

View 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
// ------------------------------------------------------------

View 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
// ------------------------------------------------------------

View 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
// ----------------------------------------------------------

View 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;
}
// --------------------------------------------------------

View File

@@ -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;
}
}

View File

@@ -0,0 +1,15 @@
LOAD 0x80000000
{
BASE 0x80000000
{
* (+RO)
}
RAM +0x0
{
* (+RW, +ZI)
}
ARM_LIB_STACKHEAP 0x80090000 EMPTY -0x00040000
{}
}

View 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
// ------------------------------------------------------------

View 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="&quot;${workspace_loc:/${ProjName}/inc_generic}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc_port}&quot;"/>
</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>

View 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>

View File

@@ -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 &quot;${INPUTS}&quot;" 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 &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
</project>

View 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

View 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

View 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)

View 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
/* } */

View 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
/* }
} */

View 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;
}
}
}

View 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;
}
}
}

View 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
/* } */

View 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
/* } */

View 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
/* } */

View 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
/* } */

View 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
/* } */

View 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!
/* } */

View 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
/* } */