Compare commits

..
12 Commits
Author SHA1 Message Date
Jake.Stine d5f86e26f6 Tagged the 0.9.6 Official Release, in all of its glory.
git-svn-id: http://pcsx2.googlecode.com/svn/tags/0.9.6@684 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-03-05 04:14:30 +00:00
Jake.Stine d1314ca5fe RC: SIO's memcard ejection fix from trunk.
git-svn-id: http://pcsx2.googlecode.com/svn/branches/rc_0.9.6@623 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-02-27 04:45:09 +00:00
Jake.Stine 99945e0f27 RC: Merged unbroken SPR fix, and set the version number back. ;)
git-svn-id: http://pcsx2.googlecode.com/svn/branches/rc_0.9.6@613 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-02-26 12:41:40 +00:00
Jake.Stine b8011af5ea RC: Some important changes didn't get merged right, thanks to TSVN glitches. -_- (it's been a long night)
git-svn-id: http://pcsx2.googlecode.com/svn/branches/rc_0.9.6@610 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-02-26 09:55:24 +00:00
Jake.Stine 60b0c5c336 ... see above.
git-svn-id: http://pcsx2.googlecode.com/svn/branches/rc_0.9.6@608 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-02-26 04:05:06 +00:00
Jake.Stine b8a1d57600 Merged Ref's latest bugfix/opt into RC, after he and cotton finished debating it's validity. (for score keepers: Ref won this one! ;)
git-svn-id: http://pcsx2.googlecode.com/svn/branches/rc_0.9.6@607 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-02-26 03:08:32 +00:00
Jake.Stine 4f2e6e3122 Merged all recent bugfixes and stable changes into RC branch. (RC branch still uses the old buildsystem)
git-svn-id: http://pcsx2.googlecode.com/svn/branches/rc_0.9.6@606 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-02-26 02:53:33 +00:00
mattmenke 9152925524 LilyPad: Version number updated in rc copy. Refresh device list bug on device insertion/removal fixed. Attempt to resolve potential XInput/DirectInput infighting by deleting DirectInput interfaces to disabled/bindingless DirectInput devices.
git-svn-id: http://pcsx2.googlecode.com/svn/branches/rc_0.9.6@565 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-02-21 19:41:30 +00:00
ramapcsx2 de68593f4c Rc branch also needed the Tri-Ace gamefix fix :p
git-svn-id: http://pcsx2.googlecode.com/svn/branches/rc_0.9.6@554 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-02-20 18:17:05 +00:00
Jake.Stine e714c7a982 Merged some stable bugfixes from r543->548 into rc_0.9.6.
git-svn-id: http://pcsx2.googlecode.com/svn/branches/rc_0.9.6@549 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-02-20 09:27:12 +00:00
Jake.Stine 46944ebde2 Updated version information displayed in the window title for rc_0.9.6.
git-svn-id: http://pcsx2.googlecode.com/svn/branches/rc_0.9.6@545 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-02-20 03:32:10 +00:00
Jake.Stine 49b4cf3b77 New svn branch: Release Candidate for 0.9.6. (designated for bugfix/stability patches in preparation of a proper release to supersede the ageless 0.9.4 -- major code renovations will continue to be applied to /trunk)
git-svn-id: http://pcsx2.googlecode.com/svn/branches/rc_0.9.6@542 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-02-20 02:48:02 +00:00
4448 changed files with 611513 additions and 1677728 deletions
-90
View File
@@ -1,90 +0,0 @@
---
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: DontAlign
AlignOperands: true
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
BeforeCatch: true
BeforeElse: true
IndentBraces: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: false
BreakConstructorInitializers: BeforeComma
ColumnLimit: 0
CommentPragmas: '^ (IWYU pragma:|NOLINT)'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ForEachMacros: []
IncludeCategories:
- Regex: '^"(stdafx|PrecompiledHeader)'
Priority: -2
- Regex: '^".*Common'
Priority: -1
- Regex: '^<'
Priority: 1
- Regex: '^"'
Priority: 2
IndentCaseLabels: true
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 3
NamespaceIndentation: All
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
ReflowComments: false
SortIncludes: false
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 4
UseTab: ForContinuationAndIndentation
...
-5
View File
@@ -1,5 +0,0 @@
---
exclude_paths:
- '3rdparty/**'
- '*.md'
- '**/*.md'
-8
View File
@@ -1,8 +0,0 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Declare files that will always have CRLF line endings on checkout.
*.sln text eol=crlf
*.props text eol=crlf
*.vcxproj text eol=crlf
*.vcxproj.filters text eol=crlf
-54
View File
@@ -1,54 +0,0 @@
# So you want to contribute to PCSX2? Great
As a first step, please review these links as they'll help you understand how the development of PCSX2 works.
* [Just Starting Out](#just-starting-out)
* [Issue Reporting](#issue-reporting)
* [Pull Request Guidelines](#pull-request-guidelines)
* [General Documentation And Coding Strategies](#general-documentation-and-coding-strategies)
* [Tasks](#tasks)
## Just Starting Out
* If you're unfamilar with git, check out this [brief introduction to Git](https://github.com/PCSX2/pcsx2/wiki/07-Git-survival-guide)
* [How to build PCSX2 for Windows](https://github.com/PCSX2/pcsx2/wiki/12-Building-on-Windows)
* [How to build PCSX2 for Linux](https://github.com/PCSX2/pcsx2/wiki/10-Building-on-Linux)
## Issue Reporting
* [How to write a useful issue](https://github.com/PCSX2/pcsx2/wiki/How-to-create-useful-and-valid-issues)
## Pull Request Guidelines
The following is a list of *general* style recommendations that will make reviewing and merging easier:
* Commit Messages
* Please try to prefix your commit message, indicating what area of the project was modified.
* For example `gs: message...`.
* Looking at the project's commit history will help with keeping prefixes consistent overtime, *there is no strictly enforced list*.
* Try to keep messages brief and informative
* Remove unnecessary commits and squash commits together when appropriate.
* If you are not familiar with rebasing with git, check out the following resources:
* CLI - https://thoughtbot.com/blog/git-interactive-rebase-squash-amend-rewriting-history
* GUI (SourceTree) - https://www.atlassian.com/blog/sourcetree/interactive-rebase-sourcetree
* Code Styling and Formatting
* [Consult the style guide](https://github.com/tadanokojin/pcsx2/blob/coding-guide/pcsx2/Docs/Coding_Guidelines.md)
* Run `clang-format` using the configuration file in the root of the repository
* Visual Studio Setup - https://devblogs.microsoft.com/cppblog/clangformat-support-in-visual-studio-2017-15-7-preview-1/
* IMPORTANT - if you are running `clang-format` on unrelated changes (ie. formatting an entire file), please do so in a separate commit.
* If you cannot scope your `clang-format` to just your changes and do not want to format unrelated code. Try your best to stick with the existing formatting already established in the file in question.
## General Documentation And Coding Strategies
* [Commenting Etiquette](https://github.com/PCSX2/pcsx2/wiki/06-Commenting-Etiquette)
* [Coding style](https://github.com/PCSX2/pcsx2/wiki/Code-Formatting-Guidelines)
* [More comprehensive style-guide (Currently in Draft)](https://github.com/tadanokojin/pcsx2/blob/coding-guide/pcsx2/Docs/Coding_Guidelines.md)
## Tasks
* [Issues](https://github.com/PCSX2/pcsx2/issues)
-3
View File
@@ -1,3 +0,0 @@
# These are supported funding model platforms
github: [PCSX2]
@@ -1,92 +0,0 @@
# Docs - https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
name: Application Bug Report
description: Found a problem with the application itself (ie. bad file path handling, UX issue)? Help us improve it.
title: "[BUG]: "
labels: [Bug]
# assignees:
# - octocat
body:
- type: markdown
attributes:
value: |
## Important: Read First
Please do not make support requests on GitHub. Our issue tracker is for tracking bugs and feature requests only
If you need help configuring the emulator please make a request on our forums or contact us on discord.
If you are unsure, start with [discord](https://discord.com/invite/TCz3t9k) or the [forums](https://forums.pcsx2.net/index.php).
Please make an effort to make sure your issue isn't already reported.
Do not create issues involving software piracy of BIOS or ISO files, our rules specifically prohibit this and your issue will be closed.
### Please Avoid Issues Pertaining to the Following:
- We are **not** accepting bug reports for **PSX mode** at this time.
- If you are interested in helping contribute to PSX mode please do so on the forums. Otherwise our recommendation is that you use [Duckstation](https://github.com/stenzek/duckstation/releases/tag/latest).
- We do **not** accept issues relating to **upscaling** at this time.
- We are aware of the various problems with upscaling. The issue spans many games and having hundreds of issues for the same fundamental issues isn't particularly helpful. There are several workarounds for graphical problems that come as a result of upscaling.
- Please try your game at native resolution before creating an issue.
- If your bug is the result of upscaling please use the forums or discord for assistance with various upscaling workarounds. Additionally, the unofficial PCSX2 [Wiki](https://wiki.pcsx2.net/Main_Page) often lists various fixes for upscaling issues.
- We do **not** accept issues relating to Widescreen/no-interlace patches at this time.
- Any issues pertaining to Widescreen/no-interlace patches please forward them to the [patches repository](https://github.com/PCSX2/pcsx2_patches).
- type: textarea
id: desc
attributes:
label: Describe the Bug
description: "A clear and concise description of what the bug is"
validations:
required: true
- type: textarea
id: repro
attributes:
label: Reproduction Steps
description: "Steps to reproduce the behavior"
validations:
required: true
- type: textarea
id: expect
attributes:
label: Expected Behavior
description: "A clear and concise description of what you expected to happen"
validations:
required: false
- type: input
id: rev
attributes:
label: PCSX2 Revision
description: "Please ensure you are on the latest version before making an issue"
placeholder: "Example: v1.7.1337"
validations:
required: true
- type: dropdown
id: os
attributes:
label: Operating System
options:
- Windows 11
- Windows 10 (64bit)
- Linux (64bit) - Specify distro below
- macOS 13 (Ventura)
- macOS 12 (Monterey)
- macOS 11 (Big Sur)
- macOS 10.15 (Catalina)
- macOS 10.14 (Mojave)
validations:
required: true
- type: input
id: os-distro
attributes:
label: If Linux - Specify Distro
placeholder: "Example: Arch"
validations:
required: false
- type: textarea
id: logsDumps
attributes:
label: "Logs & Dumps"
description: |
Please feel free to attach any logs here.
If PCSX2 crashed, please post crash logs and the .dmp file (in a zip file) if appropriate.
validations:
required: false
-11
View File
@@ -1,11 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: Support Forums
url: https://forums.pcsx2.net/index.php
about: For community support and answers
- name: Discord
url: https://discord.com/invite/TCz3t9k
about: Get direct support and hang out with us
- name: Wiki
url: https://wiki.pcsx2.net/Main_Page
about: For user provided information and reports
-148
View File
@@ -1,148 +0,0 @@
# Docs - https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
name: Emulation Bug Report
description: Problem in a game (ie. graphical artifacts, crashes)? Help us improve it.
title: "[BUG]: "
labels: [Bug]
# assignees:
# - octocat
body:
- type: markdown
attributes:
value: |
## Important: Read First
Please do not make support requests on GitHub. Our issue tracker is for tracking bugs and feature requests only
If you need help configuring the emulator please make a request on our forums or contact us on discord.
If you are unsure, start with [discord](https://discord.com/invite/TCz3t9k) or the [forums](https://forums.pcsx2.net/index.php).
Please make an effort to make sure your issue isn't already reported.
Do not create issues involving software piracy of BIOS or ISO files, our rules specifically prohibit this and your issue will be closed.
### Please Avoid Issues Pertaining to the Following:
- We are **not** accepting bug reports for **PSX mode** at this time.
- If you are interested in helping contribute to PSX mode please do so on the forums. Otherwise our recommendation is that you use [Duckstation](https://github.com/stenzek/duckstation/releases/tag/latest).
- We do **not** accept issues relating to **upscaling** at this time.
- We are aware of the various problems with upscaling. The issue spans many games and having hundreds of issues for the same fundamental issues isn't particularly helpful. There are several workarounds for graphical problems that come as a result of upscaling.
- Please try your game at native resolution before creating an issue.
- If your bug is the result of upscaling please use the forums or discord for assistance with various upscaling workarounds. Additionally, the unofficial PCSX2 [Wiki](https://wiki.pcsx2.net/Main_Page) often lists various fixes for upscaling issues.
- We do **not** accept issues relating to Widescreen/no-interlace patches at this time.
- Any issues pertaining to Widescreen/no-interlace patches please forward them to the [patches repository](https://github.com/PCSX2/pcsx2_patches).
- type: textarea
id: desc
attributes:
label: Describe the Bug
description: "A clear and concise description of what the bug is"
validations:
required: true
- type: textarea
id: repro
attributes:
label: Reproduction Steps
description: "Steps to reproduce the behavior"
validations:
required: true
- type: textarea
id: expect
attributes:
label: Expected Behavior
description: "A clear and concise description of what you expected to happen"
validations:
required: false
- type: markdown
attributes:
value: |
## System Info
Please make sure your system meets our requirements for OS version, CPU and GPU
- [System Requirements](https://github.com/PCSX2/pcsx2#system-requirements).
Performance issues as a result of not meeting our hardware requirements are not valid.
Please read our known issues pages for AMD and Intel drivers.
- [Intel Drivers](https://github.com/PCSX2/pcsx2/wiki/OpenGL-and-Intel-GPUs-All-you-need-to-know).
- [AMD Drivers](https://github.com/PCSX2/pcsx2/wiki/OpenGL-and-AMD-GPUs---All-you-need-to-know).
We are **not** accepting issues related to the **libretro** core. The libretro core is being maintained separately at this time
- type: input
id: rev
attributes:
label: PCSX2 Revision
description: "We only accept bug reports for the latest dev version. Please try upgrading before making an issue."
placeholder: "Example: v1.7.1337"
validations:
required: true
- type: dropdown
id: os
attributes:
label: Operating System
options:
- Windows 11
- Windows 10 (64bit)
- Linux (64bit) - Specify distro below
- macOS 13 (Ventura)
- macOS 12 (Monterey)
- macOS 11 (Big Sur)
- macOS 10.15 (Catalina)
- macOS 10.14 (Mojave)
validations:
required: true
- type: input
id: os-distro
attributes:
label: If Linux - Specify Distro
placeholder: "Example: Arch"
validations:
required: false
- type: input
id: cpu
attributes:
label: CPU
placeholder: "Example: i5-7600"
validations:
required: true
- type: input
id: gpu
attributes:
label: GPU
placeholder: "Example: GTX 1070"
validations:
required: true
- type: textarea
id: gsSettings
attributes:
label: GS Settings
description: "Any **non-default** settings for GS. If you don't want to list them out, please provide screenshots of your configuration window (including hw hacks if enabled)."
validations:
required: false
- type: textarea
id: emuSettings
attributes:
label: Emulation Settings
description: |
Any non-default core settings. If you don't want to list them out, please provide screenshots of your configuration window.
Please note that the safe preset works for most games. MTVU can have some compatibility issues so please disable it before making a report.
If you need to modify the settings manually because a game requires you to do so to work, please state that explicitly.
validations:
required: false
- type: textarea
id: gsScreens
attributes:
label: GS Window Screenshots
description: "If your issue is graphical in nature and you think screenshots will help illustrate your issue, you may do that here."
validations:
required: false
- type: textarea
id: logsDumps
attributes:
label: "Logs & Dumps"
description: |
Please feel free to attach any logs, block dumps, GSdump, etc here.
If PCSX2 crashed, please post crash logs and the .dmp file (in a zip file) if appropriate.
If your problem is graphical in nature it is highly recommended that you provide a GSdump. [GSdump Guide](https://forums.pcsx2.net/Thread-How-to-create-a-proper-GS-dump)
validations:
required: false
@@ -1,50 +0,0 @@
# Docs - https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
name: Feature request
description: Suggest a new feature or improve an existing one
title: "[Feature Request]: "
labels: ["Enhancement / Feature Request"]
# assignees:
# - octocat
body:
- type: markdown
attributes:
value: |
## Important: Read First
Please make an effort to make sure your issue isn't already reported.
Do not create issues involving software piracy of BIOS or ISO files, our rules specifically prohibit this and your issue will be closed.
- type: textarea
id: desc
attributes:
label: Description
description: |
A concise description of the feature you want
Include step by step examples of how the feature should work under various circumstances
validations:
required: true
- type: textarea
id: reason
attributes:
label: Reason
description: |
Give a reason why you want this feature
- How will it make things easier for you?
- How does this feature help your enjoyment of the emulator?
- What does it provide that isn't being provided currently?
We are not accepting feature requests related to the libretro core as it's being maintained separately at this time
validations:
required: true
- type: textarea
id: examples
attributes:
label: Examples
description: |
Provide examples of the feature as implemented by other software
Include screenshots or video if you like to help demonstrate how you'd like this feature to work
validations:
required: true
-8
View File
@@ -1,8 +0,0 @@
### Description of Changes
<!-- Brief description or overview on what was changed in the PR -->
### Rationale behind Changes
<!-- Why were these changes made? What problem does it solve / area does it improve? -->
### Suggested Testing Steps
<!-- If applicable, including examples you've already tested with / recommendations for how to test further is very helpful! -->
-8
View File
@@ -1,8 +0,0 @@
# Set update schedule for GitHub Actions
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
# Check for updates to GitHub Actions every week
interval: "weekly"
-128
View File
@@ -1,128 +0,0 @@
# Documentation - https://github.com/actions/labeler
# General Labels
'Build | Project System':
- '.github/*'
- '.github/**/*'
- '*.sln'
- '**/*.sln'
- '*.vcxproj*'
- '**/*.vcxproj*'
- 'cmake/*'
- 'cmake/**/*'
- 'CMakeLists.txt'
- '**/CMakeLists.txt'
- 'build.sh'
'Dependencies':
- '3rdparty/*'
- '3rdparty/**/*'
- '**/3rdpartyDeps.props'
- '.gitmodules'
'Documentation':
- '*.md'
- '**/*.md'
- '*.pdf'
- '**/*.pdf'
'GUI/Qt':
- 'pcsx2-qt/*'
- 'pcsx2-qt/**/*'
- '3rdparty/Qt/*'
- '3rdparty/Qt/**/*'
'GameDB':
- '**/GameIndex.*'
'Installer | Package':
- 'build.sh'
'Translations':
- 'pcsx2-qt/Translations/*'
# Tools / Features
'Debugger':
- 'pcsx2/DebugTools/*'
- 'pcsx2/DebugTools/**/*'
- 'pcsx2-qt/Debugger/*'
- 'pcsx2-qt/Debugger/**/*'
'IPC':
- 'pcsx2/IPC*'
- 'pcsx2/**/IPC*'
'TAS Functionality':
- 'pcsx2/Recording/*'
- 'pcsx2/Recording/**/*'
'RetroAchievements':
- 'pcsx2/Frontend/Achievements.*'
- 'pcsx2/Achievements.*'
# Emulation Components
'Counters':
- 'pcsx2/Counters.*'
'Vector Units':
- 'pcsx2/VU*'
- 'pcsx2/**/VU*'
- 'pcsx2/*VU*'
- 'pcsx2/**/*VU*'
'VIF':
- 'pcsx2/Vif*'
- 'pcsx2/**/Vif*'
- 'pcsx2/VIF*'
- 'pcsx2/**/VIF*'
# GS Related Labels
'GS':
- 'pcsx2/GS/*'
- 'pcsx2/GS/**/*'
- 'bin/resources/shaders/*'
- 'bin/resources/shaders/**/*'
'GS: Direct3D 11':
- 'pcsx2/GS/Renderers/DX11/*'
- 'pcsx2/GS/Renderers/DX11/**/*'
- 'bin/resources/shaders/dx11/*'
- 'bin/resources/shaders/dx11/**/*'
'GS: Direct3D 12':
- 'pcsx2/GS/Renderers/DX12/*'
- 'pcsx2/GS/Renderers/DX12/**/*'
- 'bin/resources/shaders/dx11/*'
- 'bin/resources/shaders/dx11/**/*'
'GS: Hardware':
- 'pcsx2/GS/Renderers/HW/*'
- 'pcsx2/GS/Renderers/HW/**/*'
'GS: OpenGL':
- 'pcsx2/GS/Renderers/OpenGL/*'
- 'pcsx2/GS/Renderers/OpenGL/**/*'
- 'bin/resources/shaders/opengl/*'
- 'bin/resources/shaders/opengl/**/*'
'GS: Vulkan':
- 'pcsx2/GS/Renderers/Vulkan/*'
- 'pcsx2/GS/Renderers/Vulkan/**/*'
- 'bin/resources/shaders/vulkan/*'
- 'bin/resources/shaders/vulkan/**/*'
'GS: Metal':
- 'pcsx2/GS/Renderers/Metal/*'
- 'pcsx2/GS/Renderers/Metal/**/*'
'GS: Texture Cache':
- 'pcsx2/GS/Renderers/*TextureCache*.*'
- 'pcsx2/GS/Renderers/**/*TextureCache*.*'
'GS: Software':
- 'pcsx2/GS/Renderers/SW/*'
- 'pcsx2/GS/Renderers/SW/**/*'
# Other Core Components
'CDVD':
- 'pcsx2/CDVD/*'
- 'pcsx2/CDVD/**/*'
'DEV9':
- 'pcsx2/DEV9/*'
- 'pcsx2/DEV9/**/*'
'IPU':
- 'pcsx2/IPU/*'
- 'pcsx2/IPU/**/*'
'Memory Card':
- 'pcsx2/SIO/Memcard/*'
- 'pcsx2/SIO/Memcard/**/*'
'PAD':
- 'pcsx2/SIO/Pad/*'
- 'pcsx2/SIO/Pad/**/*'
'SPU2':
- 'pcsx2/SPU2/*'
- 'pcsx2/SPU2/**/*'
'USB':
- 'pcsx2/USB/*'
- 'pcsx2/USB/**/*'
-14
View File
@@ -1,14 +0,0 @@
# CI Documentation
## Releases
```mermaid
sequenceDiagram
PCSX2 Repo->>Actions: PR is merged or commit is pushed to master
Actions->>PCSX2 Repo: Increment latest tag and push, create a draft release
Actions->>Actions: Kicked off pipeline on the tag push, build relevant configs
Actions->>PCSX2 Repo: Rename and upload artifacts to draft release, publish the release
Actions->>Discord: Announce release via a WebHook
PCSX2 Repo->>Web API: POST webhook to API informing it that a new release has occurred
Web API->>Web API: Update cache with new release
```
@@ -1,42 +0,0 @@
name: 📦 Publish Flathub Release
on:
schedule:
- cron: "0 0 * * *" # Every day at 12am UTC.
workflow_dispatch: # As well as manually.
jobs:
check:
if: github.repository == 'PCSX2/pcsx2'
name: "Check if release is needed"
runs-on: ubuntu-latest
outputs:
PCSX2_RELEASE: ${{ steps.getinfo.outputs.PCSX2_RELEASE }}
FLATHUB_RELEASE: ${{ steps.getinfo.outputs.FLATHUB_RELEASE }}
steps:
- name: Get latest tag and Flathub release
id: getinfo
env:
GH_TOKEN: ${{ github.token }}
run: |
PCSX2_RELEASE=$(gh api -H 'Accept: application/vnd.github+json' -H 'X-GitHub-Api-Version: 2022-11-28' /repos/PCSX2/pcsx2/releases | jq -r '.[0].tag_name')
FLATHUB_RELEASE=$(curl -L -s https://flathub.org/api/v2/appstream/net.pcsx2.PCSX2 | jq -r '.releases | max_by(.version) | .version')
echo "Latest PCSX2 release is: '${PCSX2_RELEASE}'"
echo "Latest Flathub release is: '${FLATHUB_RELEASE}'"
echo "PCSX2_RELEASE=${PCSX2_RELEASE}" >> "$GITHUB_OUTPUT"
echo "FLATHUB_RELEASE=${FLATHUB_RELEASE}" >> "$GITHUB_OUTPUT"
build:
needs: check
if: needs.check.outputs.FLATHUB_RELEASE < needs.check.outputs.PCSX2_RELEASE
name: "Build and publish Flatpak"
uses: ./.github/workflows/linux_build_flatpak.yml
with:
jobName: "Qt"
compiler: clang
cmakeflags: ""
publish: true
branch: stable
fetchTags: true
secrets: inherit
@@ -1,28 +0,0 @@
name: 🌎 Update Base Translation
on:
schedule:
- cron: "0 0 * * *" # Every day at 12am UTC.
workflow_dispatch: # As well as manually.
jobs:
update:
if: github.repository == 'PCSX2/pcsx2'
name: "Update Base Translation"
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Update Base Translation
run: ./.github/workflows/scripts/common/update_base_translation.sh
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
with:
title: "Qt: Update Base Translation"
commit-message: "Qt: Update Base Translation"
committer: "PCSX2 Bot <PCSX2Bot@users.noreply.github.com>"
author: "PCSX2 Bot <PCSX2Bot@users.noreply.github.com>"
body: "Daily update of base translation sources."
branch: update-base-translation
delete-branch: true
@@ -1,29 +0,0 @@
name: 🏭 Update Controller Database
on:
schedule:
- cron: "0 16 * * 1" # every monday @ 12pm EST - https://crontab.guru/#0_16_*_*_1
jobs:
update-controller-db:
if: github.repository == 'PCSX2/pcsx2'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get Latest DB and Prepare DB File
run: |
cd .github/workflows/scripts/controller-db/
wget -O game_controller_db.txt https://raw.githubusercontent.com/gabomdq/SDL_GameControllerDB/master/gamecontrollerdb.txt
python ./update-db.py
mv ./game_controller_db.txt ${{github.workspace}}/bin/resources/game_controller_db.txt
- name: Create Pull Request
uses: peter-evans/create-pull-request@v5
with:
title: "PAD: Update to latest controller database"
commit-message: "PAD: Update to latest controller database."
committer: "PCSX2 Bot <PCSX2Bot@users.noreply.github.com>"
author: "PCSX2 Bot <PCSX2Bot@users.noreply.github.com>"
body: "Weekly automatic update of SDL Controller DB"
reviewers: lightningterror
-43
View File
@@ -1,43 +0,0 @@
name: 📝 Validate GameDB
on:
push:
branches-ignore:
- "l10n_master"
paths:
- '**/GameIndex.yaml'
pull_request:
branches:
- master
paths:
- '**/GameIndex.yaml'
jobs:
lint:
name: Lint and Validate GameDB
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Install Packages
run: |
npm install -g ajv-cli prettier
sudo apt-get -y install yamllint
- name: Validate YAML
run: |
yamllint -sd "{extends: relaxed, rules: {line-length: disable}}" ./bin/resources/GameIndex.yaml
- name: Validate Contents
run: |
ajv validate -s ./pcsx2/Docs/gamedb-schema.json --spec=draft2020 -d ./bin/resources/GameIndex.yaml
- name: Check Formatting
run: |
if ! prettier --check bin/resources/GameIndex.yaml; then
prettier --write bin/resources/GameIndex.yaml
echo "Prettier failed, diff:"
git diff bin/resources/GameIndex.yaml
exit 1
fi
-133
View File
@@ -1,133 +0,0 @@
name: Flatpak Build Steps
on:
workflow_call:
inputs:
jobName:
required: true
type: string
os:
required: false
type: string
default: ubuntu-22.04
platform:
required: false
type: string
default: x64
compiler:
required: true
type: string
cmakeflags:
required: true
type: string
branch:
required: false
type: string
default: "stable"
publish:
required: false
type: boolean
default: false
patchesUrl:
required: false
type: string
default: https://github.com/PCSX2/pcsx2_patches/releases/latest/download
fetchTags:
required: false
type: boolean
default: false
jobs:
build_linux:
name: ${{ inputs.jobName }}
runs-on: ${{ inputs.os }}
timeout-minutes: 60
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: recursive
# Hackity hack. When running the workflow on a schedule, we don't have the tag,
# it doesn't fetch tags, therefore we don't get a version. So grab them manually.
# actions/checkout elides tags, fetch them primarily for releases
- name: Fetch tags
if: ${{ inputs.fetchTags }}
run: git fetch --tags --no-recurse-submodules
- name: Prepare Artifact Metadata
id: artifact-metadata
shell: bash
env:
OS: linux
BUILD_SYSTEM: flatpak
ARCH: ${{ inputs.platform }}
EVENT_NAME: ${{ github.event_name }}
PR_TITLE: ${{ github.event.pull_request.title }}
PR_NUM: ${{ github.event.pull_request.number }}
PR_SHA: ${{ github.event.pull_request.head.sha }}
run: ./.github/workflows/scripts/common/name-artifacts.sh
- name: Install Packages
env:
COMPILER: ${{ inputs.compiler }}
run: .github/workflows/scripts/linux/install-packages-flatpak.sh
- name: Download patches
run: |
cd bin/resources
aria2c -Z "${{ inputs.patchesUrl }}/patches.zip"
- name: Generate AppStream XML
run: |
./.github/workflows/scripts/linux/generate-metainfo.sh .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.metainfo.xml
cat .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.metainfo.xml
flatpak run org.freedesktop.appstream-glib validate .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.metainfo.xml
- name: Validate manifest
run: |
flatpak run --command=flatpak-builder-lint org.flatpak.Builder manifest .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.json
- name: Build Flatpak
uses: flatpak/flatpak-github-actions/flatpak-builder@v6.3
with:
bundle: ${{ steps.artifact-metadata.outputs.artifact-name }}.flatpak
manifest-path: .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.json
arch: x86_64
build-bundle: true
verbose: true
mirror-screenshots-url: https://dl.flathub.org/repo/screenshots
branch: ${{ inputs.branch }}
cache: true
restore-cache: true
cache-key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} flatpak ${{ hashFiles('.github/workflows/scripts/linux/flatpak/**/*.json') }}
- name: Commit screenshots to OSTree
run: |
ostree commit --repo=repo --canonical-permissions --branch=screenshots/x86_64 flatpak_app/screenshots
#- name: Validate build directory
# run: |
# flatpak run --command=flatpak-builder-lint org.flatpak.Builder builddir flatpak_app
#
#- name: Validate repo
# run: |
# flatpak run --command=flatpak-builder-lint org.flatpak.Builder repo repo
- name: Push to Flathub beta
if: inputs.publish == true && inputs.branch == 'beta'
uses: flatpak/flatpak-github-actions/flat-manager@v6.3
with:
flat-manager-url: https://hub.flathub.org/
repository: beta
token: ${{ secrets.FLATHUB_BETA_TOKEN }}
- name: Push to Flathub stable
if: inputs.publish == true && inputs.branch == 'stable'
uses: flatpak/flatpak-github-actions/flat-manager@v6.3
with:
flat-manager-url: https://hub.flathub.org/
repository: stable
token: ${{ secrets.FLATHUB_TOKEN }}
-31
View File
@@ -1,31 +0,0 @@
name: 🐧 Linux Builds
on:
push:
branches-ignore:
- "l10n_master"
pull_request:
branches:
- master
jobs:
build_linux_qt:
name: "AppImage"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/linux_build_qt.yml
with:
jobName: "AppImage Build"
compiler: clang
cmakeflags: ""
buildAppImage: true
secrets: inherit
build_linux_flatpak:
name: "Flatpak"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/linux_build_flatpak.yml
with:
jobName: "Flatpak Build"
compiler: clang
cmakeflags: ""
publish: false
secrets: inherit
-148
View File
@@ -1,148 +0,0 @@
name: Linux Build Steps
on:
workflow_call:
inputs:
jobName:
required: true
type: string
os:
required: false
type: string
default: ubuntu-22.04
platform:
required: false
type: string
default: x64
compiler:
required: true
type: string
cmakeflags:
required: true
type: string
buildAppImage:
required: false
type: boolean
default: false
detail:
required: false
type: string
default: ""
patchesUrl:
required: false
type: string
default: https://github.com/PCSX2/pcsx2_patches/releases/latest/download
fetchTags:
required: false
type: boolean
default: false
jobs:
build_linux:
name: ${{ inputs.jobName }}
runs-on: ${{ inputs.os }}
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
timeout-minutes: 90
env:
CCACHE_BASEDIR: ${{ github.workspace }}
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_COMPRESS: true
CCACHE_COMPRESSLEVEL: 9
CCACHE_MAXSIZE: 100M
steps:
# Work around https://github.com/actions/runner-images/issues/8659
- name: Remove GCC 13 from runner image
shell: bash
run: |
sudo rm -f /etc/apt/sources.list.d/ubuntu-toolchain-r-ubuntu-test-jammy.list
sudo apt-get update
sudo apt-get install -y --allow-downgrades libc6=2.35-0ubuntu3.4 libc6-dev=2.35-0ubuntu3.4 libstdc++6=12.3.0-1ubuntu1~22.04 libgcc-s1=12.3.0-1ubuntu1~22.04
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: recursive
# actions/checkout elides tags, fetch them primarily for releases
- name: Fetch Tags
if: ${{ inputs.fetchTags }}
run: git fetch --tags --no-recurse-submodules
- name: Prepare Artifact Metadata
id: artifact-metadata
shell: bash
env:
OS: linux
ARCH: ${{ inputs.platform }}
EVENT_NAME: ${{ github.event_name }}
PR_TITLE: ${{ github.event.pull_request.title }}
PR_NUM: ${{ github.event.pull_request.number }}
PR_SHA: ${{ github.event.pull_request.head.sha }}
run: ./.github/workflows/scripts/common/name-artifacts.sh
# -- SETUP CCACHE - https://cristianadam.eu/20200113/speeding-up-c-plus-plus-github-actions-using-ccache/
- name: Prepare ccache timestamp
id: ccache_cache_timestamp
run: echo "timestamp=$(date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
- name: ccache cache files
uses: actions/cache@v3
with:
path: .ccache
key: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} ${{ inputs.detail }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
restore-keys: ${{ inputs.os }} ${{ inputs.platform }} ${{ inputs.compiler }} ${{ inputs.detail }} ccache
- name: Install Packages
env:
COMPILER: ${{ inputs.compiler }}
run: .github/workflows/scripts/linux/install-packages-qt.sh
- name: Cache Dependencies
id: cache-deps
uses: actions/cache@v3
with:
path: ~/deps
key: ${{ inputs.os }} ${{ inputs.platform }} deps ${{ hashFiles('.github/workflows/scripts/linux/build-dependencies-qt.sh') }}
- name: Build Dependencies
if: steps.cache-deps.outputs.cache-hit != 'true'
run: .github/workflows/scripts/linux/build-dependencies-qt.sh
- name: Download patches
run: |
cd bin/resources
aria2c -Z "${{ inputs.patchesUrl }}/patches.zip"
- name: Generate CMake
env:
COMPILER: ${{ inputs.compiler }}
ADDITIONAL_CMAKE_ARGS: ${{ inputs.cmakeflags }}
CLANG_PATH: /usr/bin/clang-17
CLANGXX_PATH: /usr/bin/clang++-17
run: |
DEPS_PREFIX="$HOME/deps" .github/workflows/scripts/linux/generate-cmake-qt.sh
- name: Build PCSX2
working-directory: build
run: ../.github/workflows/scripts/linux/compile.sh
- name: Run Tests
working-directory: ./build
run: ninja unittests
- name: Package AppImage
if: inputs.buildAppImage == true
env:
NAME: ${{ steps.artifact-metadata.outputs.artifact-name }}
run: |
.github/workflows/scripts/linux/appimage-qt.sh "$(realpath .)" "$(realpath ./build)" "$HOME/deps" "$NAME"
mkdir -p "$GITHUB_WORKSPACE"/ci-artifacts/
mv "${NAME}.AppImage" "$GITHUB_WORKSPACE"/ci-artifacts/
- name: Upload artifact
if: inputs.buildAppImage == true
uses: actions/upload-artifact@v3
with:
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
path: ci-artifacts
-154
View File
@@ -1,154 +0,0 @@
name: MacOS Build Steps
on:
workflow_call:
inputs:
jobName:
required: true
type: string
os:
required: false
type: string
default: macos-13
patchesUrl:
required: false
type: string
default: https://github.com/PCSX2/pcsx2_patches/releases/latest/download
fetchTags:
required: false
type: boolean
default: false
jobs:
build_macos:
name: ${{ inputs.jobName }}
runs-on: ${{ inputs.os }}
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
timeout-minutes: 90
env:
POWERSHELL_TELEMETRY_OPTOUT: 1
CCACHE_BASEDIR: ${{ github.workspace }}
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_COMPRESS: true
CCACHE_COMPRESSLEVEL: 9
CCACHE_MAXSIZE: 100M
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: recursive
# actions/checkout elides tags, fetch them primarily for releases
- name: Fetch Tags
if: ${{ inputs.fetchTags }}
run: git fetch --tags --no-recurse-submodules
- name: Use Xcode 14.3.1
run: sudo xcode-select -s /Applications/Xcode_14.3.1.app
- name: Prepare Artifact Metadata
id: artifact-metadata
shell: bash
env:
OS: macos
EVENT_NAME: ${{ github.event_name }}
PR_TITLE: ${{ github.event.pull_request.title }}
PR_NUM: ${{ github.event.pull_request.number }}
PR_SHA: ${{ github.event.pull_request.head.sha }}
run: ./.github/workflows/scripts/common/name-artifacts.sh
- name: Install Packages
env:
PLATFORM: "x64"
HOMEBREW_NO_INSTALL_CLEANUP: 1
HOMEBREW_NO_ANALYTICS: 1
run: |
# Unlike other packages, brew's MoltenVK build uses MoltenVK's minimum macOS version of 10.13 so we can use it
if ! brew install molten-vk ccache nasm; then
brew update
brew install molten-vk ccache nasm
fi
- name: Cache Dependencies
id: cache-deps
uses: actions/cache@v3
with:
path: ~/deps
key: ${{ inputs.os }} deps ${{ hashFiles('.github/workflows/scripts/macos/build-dependencies.sh') }}
- name: Build Dependencies
if: steps.cache-deps.outputs.cache-hit != 'true'
run: .github/workflows/scripts/macos/build-dependencies.sh
- name: Download patches
run: |
cd bin/resources
aria2c -Z "${{ inputs.patchesUrl }}/patches.zip"
# -- SETUP CCACHE - https://cristianadam.eu/20200113/speeding-up-c-plus-plus-github-actions-using-ccache/
- name: Prepare ccache timestamp
id: ccache_cache_timestamp
run: echo "timestamp=$(date -u "+%Y-%m-%d-%H;%M;%S")" >> $GITHUB_OUTPUT
- name: Cache ccache cache
uses: actions/cache@v3
with:
path: .ccache
key: ${{ inputs.os }} ccache ${{ steps.ccache_cache_timestamp.outputs.timestamp }}
restore-keys: ${{ inputs.os }} ccache
- name: Generate CMake Files
run: |
cmake -DCMAKE_PREFIX_PATH="$HOME/deps" \
-DCMAKE_BUILD_TYPE=Release \
-DUSE_OPENGL=OFF \
-DDISABLE_ADVANCE_SIMD=ON \
-DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON \
-DUSE_SYSTEM_LIBS=OFF \
-DUSE_SYSTEM_SDL2=ON \
-DUSE_LINKED_FFMPEG=ON \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON \
-B build .
- name: Build PCSX2
working-directory: build
run: |
ccache -p
ccache -s
ccache -z
make -j$(getconf _NPROCESSORS_ONLN) # macOS doesn't use make install
ccache -s
# Ensure there's no global constructors in multi-isa files
for dir in */CMakeFiles/GS-{avx,avx2}.dir; do
if find "$dir" -name "*.o" | xargs nm | grep _GLOBAL_; then
echo "::error::Multi-isa files must not have global constructors!"
exit 1
fi
done
- name: Run Tests
working-directory: build
run: make -j$(getconf _NPROCESSORS_ONLN) unittests
- name: Prepare Build Artifacts
run: |
cp /usr/local/lib/libMoltenVK.dylib build/pcsx2*/PCSX2.app/Contents/Frameworks/
TAG="$(git tag --points-at HEAD)"
if [ -z "$TAG" ]; then
APPNAME="${{ steps.artifact-metadata.outputs.artifact-name }}"
else
APPNAME="PCSX2-$TAG"
fi
mv build/pcsx2*/PCSX2.app "$APPNAME.app"
tar --options xz:compression-level=9 -cvJf "${{ steps.artifact-metadata.outputs.artifact-name }}.tar.xz" "$APPNAME.app"
mkdir ci-artifacts
cp "${{ steps.artifact-metadata.outputs.artifact-name }}.tar.xz" ci-artifacts/macOS.tar.xz
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
path: "*.tar.xz"
-18
View File
@@ -1,18 +0,0 @@
name: 🍎 MacOS Builds
on:
push:
branches-ignore:
- "l10n_master"
pull_request:
branches:
- master
jobs:
build_macos_qt:
name: "Defaults"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/macos_build.yml
with:
jobName: "MacOS Build"
secrets: inherit
-201
View File
@@ -1,201 +0,0 @@
# Whenever a commit is pushed to master (ideally via a pull-request!)
# this action will create the next release, which means:
# 1. tag master with the proper version
# 2. create a new draft release (pre-released if a nightly build)
# 3. add release notes
name: 🏭 Create Release
on:
push:
branches:
- master
# TODO - future work
# workflow_dispatch:
# inputs:
# isStable:
# description: 'Should it be a stable release?'
# required: true
# default: 'false'
# versionTag:
# description: 'The version to tag with'
# required: true
permissions:
contents: write
jobs:
cut-release:
if: github.repository == 'PCSX2/pcsx2'
name: "Create Tag and Release"
runs-on: ubuntu-latest
outputs:
new_tag: ${{ steps.tag_version.outputs.new_tag }}
steps:
- uses: actions/checkout@v4
# Docs - https://github.com/mathieudutour/github-tag-action
- name: Bump Version and Push Tag
id: tag_version
uses: mathieudutour/github-tag-action@v6.1
with:
github_token: ${{ github.token }}
tag_prefix: v
default_bump: patch
# TODO - we could do this and remove the node.js script, but auto-generated notes only work
# with PRs -- not commits (determine how much we care).
# - name: Create Draft Release
# run: |
# echo "Creating release with tag - ${{ steps.tag_version.outputs.new_tag }}"
# gh release create ${{ steps.tag_version.outputs.new_tag }} --draft --generate-notes -title ${{ steps.tag_version.outputs.new_tag }}
- name: Generate Release Notes
env:
OWNER: PCSX2
REPO: pcsx2
GITHUB_TOKEN: ${{ github.token }}
COMMIT_SHA: ${{ github.SHA }}
run: |
cd ./.github/workflows/scripts/releases/generate-release-notes
npm ci
node index.js
mv ./release-notes.md ${GITHUB_WORKSPACE}/release-notes.md
- name: Create a GitHub Release
uses: softprops/action-gh-release@v1
if: steps.tag_version.outputs.new_tag
with:
body_path: ./release-notes.md
draft: true
prerelease: true
tag_name: ${{ steps.tag_version.outputs.new_tag }}
# Build Everything
# Linux
build_linux_qt:
if: github.repository == 'PCSX2/pcsx2'
needs:
- cut-release
name: "Linux"
uses: ./.github/workflows/linux_build_qt.yml
with:
jobName: "AppImage Build"
compiler: clang
cmakeflags: ""
buildAppImage: true
fetchTags: true
secrets: inherit
build_linux_flatpak:
if: github.repository == 'PCSX2/pcsx2'
needs:
- cut-release
name: "Linux"
uses: ./.github/workflows/linux_build_flatpak.yml
with:
jobName: "Flatpak Build"
compiler: clang
cmakeflags: ""
branch: "stable"
publish: false
fetchTags: true
secrets: inherit
# Windows
build_windows_qt:
if: github.repository == 'PCSX2/pcsx2'
needs:
- cut-release
name: "Windows"
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: "Windows Build"
configuration: CMake
buildSystem: cmake
cmakeFlags: -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl
fetchTags: true
secrets: inherit
# MacOS
build_macos_qt:
if: github.repository == 'PCSX2/pcsx2'
needs:
- cut-release
name: "MacOS"
uses: ./.github/workflows/macos_build.yml
with:
jobName: "MacOS Build"
fetchTags: true
secrets: inherit
# Upload the Artifacts
upload_artifacts:
if: github.repository == 'PCSX2/pcsx2'
needs:
- cut-release
- build_linux_flatpak
- build_linux_qt
- build_windows_qt
- build_macos_qt
name: "Upload Artifacts"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Prepare Artifact Folder
run: mkdir ./ci-artifacts/
- uses: actions/download-artifact@v3
name: Download all Artifacts
with:
path: ./ci-artifacts/
- name: Display structure of downloaded files
run: ls ./ci-artifacts/
# Prepare artifacts, they are all zips from github!
- name: Prepare Artifacts
working-directory: ./ci-artifacts/
run: for d in *windows*/; do 7z a "${d}asset.7z" ./$d/*; done
# Artifact Naming:
# MacOS: PCSX2-<tag>-macOS-[additional hyphen seperated tags]
# Windows|Linux: PCSX2-<tag>-<windows|linux>-<32bit|64bit>--[additional hyphen seperated tags]
- name: Name and Upload the Release Assets
env:
GITHUB_TOKEN: ${{ github.token }}
SCAN_DIR: ${{ github.WORKSPACE }}/ci-artifacts
OUT_DIR: ${{ github.WORKSPACE }}/ci-artifacts/out
run: |
TAG_VAL=${{needs.cut-release.outputs.new_tag}}
echo "TAG_VAL=${TAG_VAL}"
gh release list --repo PCSX2/pcsx2
mkdir -p ${{ github.WORKSPACE }}/ci-artifacts/out
TAG_VAL=${TAG_VAL} python ./.github/workflows/scripts/releases/rename-release-assets.py
ls ${{ github.WORKSPACE }}/ci-artifacts/out
gh release upload "${TAG_VAL}" ${{ github.WORKSPACE }}/ci-artifacts/out/* --repo PCSX2/pcsx2 --clobber
- name: Publish Release
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
TAG_VAL=${{needs.cut-release.outputs.new_tag}}
echo "TAG_VAL=${TAG_VAL}"
gh release edit ${TAG_VAL} --draft=false --repo PCSX2/pcsx2
- uses: actions/setup-node@v4
with:
node-version: 16
- name: Announce Release
env:
OWNER: PCSX2
REPO: pcsx2
DISCORD_BUILD_WEBHOOK: ${{ secrets.DISCORD_BUILD_WEBHOOK }}
GITHUB_TOKEN: ${{ github.token }}
run: |
TAG_VAL=${{needs.cut-release.outputs.new_tag}}
cd ./.github/workflows/scripts/releases/announce-release
npm ci
TAG_VAL=${TAG_VAL} node index.js
@@ -1,57 +0,0 @@
#!/bin/bash
# Artifact Naming Scheme:
# PCSX2-<OS>-Qt-[ARCH]-[SIMD]-[pr\[PR_NUM\]]-[title|sha\[SHA|PR_TITLE\]
# -- limited to 200 chars
# Outputs:
# - artifact-name
# Inputs as env-vars
# OS
# BUILD_SYSTEM
# ARCH
# SIMD
# EVENT_NAME
# PR_TITLE
# PR_NUM
# PR_SHA
NAME=""
if [ "${OS}" == "macos" ]; then
# MacOS has combined binaries for x64 and ARM64.
NAME="PCSX2-${OS}-Qt"
elif [[ ("${OS}" == "windows" && "$BUILD_SYSTEM" != "cmake") ]]; then
NAME="PCSX2-${OS}-Qt-${ARCH}-${SIMD}"
else
NAME="PCSX2-${OS}-Qt-${ARCH}"
fi
# Add cmake if used to differentate it from msbuild builds
# Else the two artifacts will have the same name and the files will be merged
if [[ ! -z "${BUILD_SYSTEM}" ]]; then
if [[ "${BUILD_SYSTEM}" == "cmake" ]] || [[ "${BUILD_SYSTEM}" == "flatpak" ]]; then
NAME="${NAME}-${BUILD_SYSTEM}"
fi
fi
# Add PR / Commit Metadata
if [ "$EVENT_NAME" == "pull_request" ]; then
PR_SHA=$(git rev-parse --short "${PR_SHA}")
if [ ! -z "${PR_NUM}" ]; then
NAME="${NAME}-pr[${PR_NUM}]"
fi
NAME="${NAME}-sha[${PR_SHA}]"
if [ ! -z "${PR_TITLE}" ]; then
PR_TITLE=$(echo "${PR_TITLE}" | tr -cd '[a-zA-Z0-9[:space:]]_-')
NAME="${NAME}-title[${PR_TITLE}"
fi
else
SHA=$(git rev-parse --short "$GITHUB_SHA")
NAME="${NAME}-sha[${SHA}"
fi
# Trim the Name
NAME=$(printf "%.199s]" "$NAME")
echo "${NAME}"
echo "artifact-name=${NAME}" >> "$GITHUB_OUTPUT"
@@ -1,12 +0,0 @@
#!/bin/bash
SCRIPTDIR=$(dirname "${BASH_SOURCE[0]}")
source "$SCRIPTDIR/../linux/functions.sh"
set -e
# While we use custom Qt builds for our releases, the Qt6 package will be good enough
# for just updating translations. Saves building it for this action alone.
retry_command sudo apt-get -y install qt6-l10n-tools
PATH=/usr/lib/qt6/bin:$PATH "$SCRIPTDIR/../../../../pcsx2-qt/Translations/update_en_translation.sh"
@@ -1 +0,0 @@
*.txt
@@ -1,39 +0,0 @@
import os
relevant_categories = [
"# Windows",
"# Mac OS X",
"# Linux"
]
header_lines = []
new_db_contents = []
def is_relevant_category(line):
for category in relevant_categories:
if category in line:
return True
return False
with open("./game_controller_db.txt") as file:
lines = file.readlines()
finished_header = False
processing_section = False
for line in lines:
if finished_header is False:
header_lines.append(line)
if line == "\n":
finished_header = True
if processing_section and line == "\n":
processing_section = False
new_db_contents.append("\n")
if is_relevant_category(line) and processing_section is False:
processing_section = True
new_db_contents.append(line)
elif processing_section:
new_db_contents.append(line)
os.remove("./game_controller_db.txt")
with open("./game_controller_db.txt", "w") as f:
f.writelines(header_lines)
f.writelines(new_db_contents)
@@ -1,166 +0,0 @@
#!/usr/bin/env bash
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# For more information, please refer to <http://unlicense.org/>
SCRIPTDIR=$(dirname "${BASH_SOURCE[0]}")
source "$SCRIPTDIR/functions.sh"
if [ "$#" -ne 4 ]; then
echo "Syntax: $0 <path to pcsx2 directory> <path to build directory> <deps prefix> <output name>"
exit 1
fi
PCSX2DIR=$1
BUILDDIR=$2
DEPSDIR=$3
NAME=$4
BINARY=pcsx2-qt
APPDIRNAME=PCSX2.AppDir
STRIP=strip
declare -a MANUAL_QT_LIBS=(
"libQt6WaylandEglClientHwIntegration.so.6"
)
declare -a MANUAL_QT_PLUGINS=(
"wayland-decoration-client"
"wayland-graphics-integration-client"
"wayland-shell-integration"
)
set -e
LINUXDEPLOY=./linuxdeploy-x86_64.AppImage
LINUXDEPLOY_PLUGIN_QT=./linuxdeploy-plugin-qt-x86_64.AppImage
APPIMAGETOOL=./appimagetool-x86_64.AppImage
PATCHELF=patchelf
if [ ! -f "$LINUXDEPLOY" ]; then
retry_command wget -O "$LINUXDEPLOY" https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
chmod +x "$LINUXDEPLOY"
fi
if [ ! -f "$LINUXDEPLOY_PLUGIN_QT" ]; then
retry_command wget -O "$LINUXDEPLOY_PLUGIN_QT" https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage
chmod +x "$LINUXDEPLOY_PLUGIN_QT"
fi
if [ ! -f "$APPIMAGETOOL" ]; then
retry_command wget -O "$APPIMAGETOOL" https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
chmod +x "$APPIMAGETOOL"
fi
OUTDIR=$(realpath "./$APPDIRNAME")
rm -fr "$OUTDIR"
# Why the nastyness? linuxdeploy strips our main binary, and there's no option to turn it off.
# It also doesn't strip the Qt libs. We can't strip them after running linuxdeploy, because
# patchelf corrupts the libraries (but they still work), but patchelf+strip makes them crash
# on load. So, make a backup copy, strip the original (since that's where linuxdeploy finds
# the libs to copy), then swap them back after we're done.
# Isn't Linux packaging amazing?
rm -fr "$DEPSDIR.bak"
cp -a "$DEPSDIR" "$DEPSDIR.bak"
IFS="
"
for i in $(find "$DEPSDIR" -iname '*.so'); do
echo "Stripping deps library ${i}"
strip "$i"
done
echo "Copying desktop file..."
cp "$PCSX2DIR/.github/workflows/scripts/linux/pcsx2-qt.desktop" "net.pcsx2.PCSX2.desktop"
cp "$PCSX2DIR/bin/resources/icons/AppIconLarge.png" "PCSX2.png"
echo "Running linuxdeploy to create AppDir..."
EXTRA_QT_PLUGINS="core;gui;network;svg;waylandclient;widgets;xcbqpa" \
EXTRA_PLATFORM_PLUGINS="libqwayland-egl.so;libqwayland-generic.so" \
QMAKE="$DEPSDIR/bin/qmake" \
NO_STRIP="1" \
$LINUXDEPLOY --plugin qt --appdir="$OUTDIR" --executable="$BUILDDIR/bin/pcsx2-qt" \
--desktop-file="net.pcsx2.PCSX2.desktop" --icon-file="PCSX2.png"
echo "Copying resources into AppDir..."
cp -a "$BUILDDIR/bin/resources" "$OUTDIR/usr/bin"
# LinuxDeploy's Qt plugin doesn't include Wayland support. So manually copy in the additional Wayland libraries.
echo "Copying Qt Wayland libraries..."
for lib in "${MANUAL_QT_LIBS[@]}"; do
srcpath="$DEPSDIR/lib/$lib"
dstpath="$OUTDIR/usr/lib/$lib"
echo " $srcpath -> $dstpath"
cp "$srcpath" "$dstpath"
$PATCHELF --set-rpath '$ORIGIN' "$dstpath"
done
# .. and plugins.
echo "Copying Qt Wayland plugins..."
for GROUP in "${MANUAL_QT_PLUGINS[@]}"; do
srcpath="$DEPSDIR/plugins/$GROUP"
dstpath="$OUTDIR/usr/plugins/$GROUP"
echo " $srcpath -> $dstpath"
mkdir -p "$dstpath"
for srcsopath in $(find "$DEPSDIR/plugins/$GROUP" -iname '*.so'); do
# This is ../../ because it's usually plugins/group/name.so
soname=$(basename "$srcsopath")
dstsopath="$dstpath/$soname"
echo " $srcsopath -> $dstsopath"
cp "$srcsopath" "$dstsopath"
$PATCHELF --set-rpath '$ORIGIN/../../lib:$ORIGIN' "$dstsopath"
done
done
# Restore unstripped deps (for cache).
rm -fr "$DEPSDIR"
mv "$DEPSDIR.bak" "$DEPSDIR"
# Fix up translations.
rm -fr "$OUTDIR/usr/bin/translations" "$OUTDIR/usr/translations"
cp -a "$BUILDDIR/bin/translations" "$OUTDIR/usr/bin"
# Generate AppStream meta-info.
echo "Generating AppStream metainfo..."
mkdir -p "$OUTDIR/usr/share/metainfo"
"$SCRIPTDIR/generate-metainfo.sh" "$OUTDIR/usr/share/metainfo/net.pcsx2.PCSX2.appdata.xml"
# Copy in AppRun hooks.
# Unfortunately linuxdeploy is a bit lame and doesn't let us provide our own AppRun hooks, instead
# they have to come from plugins.. and screw writing one of those just to disable Wayland.
echo "Copying AppRun hooks..."
mkdir -p "$OUTDIR/apprun-hooks"
for hookpath in "$SCRIPTDIR/apprun-hooks"/*; do
hookname=$(basename "$hookpath")
cp -v "$hookpath" "$OUTDIR/apprun-hooks/$hookname"
sed -i -e 's/exec /source "$this_dir"\/apprun-hooks\/"'"$hookname"'"\nexec /' "$OUTDIR/AppRun"
done
echo "Generating AppImage..."
rm -f "$NAME.AppImage"
$APPIMAGETOOL -v "$OUTDIR" "$NAME.AppImage"
@@ -1,9 +0,0 @@
if [[ -z "$I_WANT_A_BROKEN_WAYLAND_UI" ]]; then
echo "Forcing X11 instead of Wayland, due to various protocol limitations"
echo "and Qt issues. If you want to use Wayland, launch PCSX2 with"
echo "I_WANT_A_BROKEN_WAYLAND_UI=YES set."
export QT_QPA_PLATFORM=xcb
else
echo "Wayland is not being disabled. Do not complain when things break."
fi
@@ -1,159 +0,0 @@
#!/usr/bin/env bash
set -e
INSTALLDIR="$HOME/deps"
NPROCS="$(getconf _NPROCESSORS_ONLN)"
SDL=SDL2-2.28.5
QT=6.6.1
LIBBACKTRACE=ad106d5fdd5d960bd33fae1c48a351af567fd075
mkdir -p deps-build
cd deps-build
cat > SHASUMS <<EOF
332cb37d0be20cb9541739c61f79bae5a477427d79ae85e352089afdaf6666e4 $SDL.tar.gz
fd6f417fe9e3a071cf1424a5152d926a34c4a3c5070745470be6cf12a404ed79 $LIBBACKTRACE.zip
450c5b4677b2fe40ed07954d7f0f40690068e80a94c9df86c2c905ccd59d02f7 qtbase-everywhere-src-$QT.tar.xz
ac4ed08950072e375be662cfa64fdb447dd6e935cf29c56a4128d1500492188f qtimageformats-everywhere-src-$QT.tar.xz
248deb56d26a463cf3162f530358ccf90cfb654bbf518bb35ddf81b205e09228 qtsvg-everywhere-src-$QT.tar.xz
4939105a7345ab4e19e7caee8654a836e65bd41910359623e0f233f3aff0914a qttools-everywhere-src-$QT.tar.xz
668702e822ad7150b27e7caa2158595fd9b3b77ffbc8262e6509872a3920ee88 qttranslations-everywhere-src-$QT.tar.xz
66cc2d632dc07fc6cc4e35247f48b7c1753276ccbf86e86d7b24d799725568b1 qtwayland-everywhere-src-$QT.tar.xz
EOF
curl -L \
-O "https://libsdl.org/release/$SDL.tar.gz" \
-O "https://github.com/ianlancetaylor/libbacktrace/archive/$LIBBACKTRACE.zip" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtwayland-everywhere-src-$QT.tar.xz"
shasum -a 256 --check SHASUMS
echo "Building SDL..."
tar xf "$SDL.tar.gz"
cd "$SDL"
./configure --prefix "$INSTALLDIR" --enable-dbus --without-x --disable-video-opengl --disable-video-opengles --disable-video-vulkan --disable-wayland-shared --disable-ime --disable-oss --disable-alsa --disable-jack --disable-esd --disable-pipewire --disable-pulseaudio --disable-arts --disable-nas --disable-sndio --disable-fusionsound --disable-diskaudio
make "-j$NPROCS"
make install
cd ..
echo "Building libbacktrace..."
unzip "$LIBBACKTRACE.zip"
cd "libbacktrace-$LIBBACKTRACE"
./configure --prefix="$HOME/deps"
make
make install
cd ..
# Couple notes:
# -fontconfig is needed otherwise Qt Widgets render only boxes.
# -qt-doubleconversion avoids a dependency on libdouble-conversion.
# ICU avoids pulling in a bunch of large libraries, and hopefully we can get away without it.
# OpenGL is needed to render window decorations in Wayland, apparently.
echo "Building Qt Base..."
tar xf "qtbase-everywhere-src-$QT.tar.xz"
cd "qtbase-everywhere-src-$QT"
mkdir build
cd build
../configure -prefix "$INSTALLDIR" -release -dbus-linked -gui -widgets -fontconfig -qt-doubleconversion -ssl -openssl-runtime -opengl desktop -qpa xcb,wayland -xkbcommon -- -DFEATURE_dbus=ON -DFEATURE_icu=OFF -DFEATURE_printsupport=OFF -DFEATURE_sql=OFF
cmake --build . --parallel
cmake --install .
cd ../../
echo "Building Qt SVG..."
tar xf "qtsvg-everywhere-src-$QT.tar.xz"
cd "qtsvg-everywhere-src-$QT"
mkdir build
cd build
cmake -G Ninja -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --parallel
cmake --install .
cd ../../
echo "Building Qt Image Formats..."
tar xf "qtimageformats-everywhere-src-$QT.tar.xz"
cd "qtimageformats-everywhere-src-$QT"
mkdir build
cd build
cmake -G Ninja -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --parallel
cmake --install .
cd ../../
echo "Building Qt Wayland..."
tar xf "qtwayland-everywhere-src-$QT.tar.xz"
cd "qtwayland-everywhere-src-$QT"
mkdir build
cd build
cmake -G Ninja -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --parallel
cmake --install .
cd ../../
echo "Installing Qt Tools..."
tar xf "qttools-everywhere-src-$QT.tar.xz"
cd "qttools-everywhere-src-$QT"
# From Mac build-dependencies.sh:
# Linguist relies on a library in the Designer target, which takes 5-7 minutes to build on the CI
# Avoid it by not building Linguist, since we only need the tools that come with it
patch -u src/linguist/CMakeLists.txt <<EOF
--- src/linguist/CMakeLists.txt
+++ src/linguist/CMakeLists.txt
@@ -14,7 +14,7 @@
add_subdirectory(lrelease-pro)
add_subdirectory(lupdate)
add_subdirectory(lupdate-pro)
-if(QT_FEATURE_process AND QT_FEATURE_pushbutton AND QT_FEATURE_toolbutton AND TARGET Qt::Widgets AND NOT no-png)
+if(QT_FEATURE_process AND QT_FEATURE_pushbutton AND QT_FEATURE_toolbutton AND TARGET Qt::Widgets AND TARGET Qt::PrintSupport AND NOT no-png)
add_subdirectory(linguist)
endif()
EOF
# Also force disable clang scanning, it gets very confused.
patch -u configure.cmake <<EOF
--- configure.cmake
+++ configure.cmake
@@ -14,12 +14,12 @@
# Presumably because 6.0 ClangConfig.cmake files are not good enough?
# In any case explicitly request a minimum version of 8.x for now, otherwise
# building with CMake will fail at compilation time.
-qt_find_package(WrapLibClang 8 PROVIDED_TARGETS WrapLibClang::WrapLibClang)
+#qt_find_package(WrapLibClang 8 PROVIDED_TARGETS WrapLibClang::WrapLibClang)
# special case end
-if(TARGET WrapLibClang::WrapLibClang)
- set(TEST_libclang "ON" CACHE BOOL "Required libclang version found." FORCE)
-endif()
+#if(TARGET WrapLibClang::WrapLibClang)
+# set(TEST_libclang "ON" CACHE BOOL "Required libclang version found." FORCE)
+#endif()
EOF
mkdir build
cd build
cmake -G Ninja -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=OFF -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF ..
cmake --build . --parallel
cmake --install .
cd ../../
echo "Installing Qt Translations..."
tar xf "qttranslations-everywhere-src-$QT.tar.xz"
cd "qttranslations-everywhere-src-$QT"
mkdir build
cd build
cmake -G Ninja -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --parallel
cmake --install .
cd ../../
echo "Cleaning up..."
cd ..
rm -r deps-build
@@ -1,15 +0,0 @@
#!/bin/bash
set -e
if [ -n "${GITHUB_ACTIONS}" ]; then
echo "Warning: Running this script outside of GitHub Actions isn't recommended."
fi
# Prepare the Cache
ccache -p
ccache -z
# Build
ninja
# Save the Cache
ccache -s
@@ -1,24 +0,0 @@
{
"name": "libpcap",
"buildsystem": "cmake-ninja",
"build-options": {
"strip": true
},
"sources": [
{
"type": "git",
"url": "https://github.com/the-tcpdump-group/libpcap.git",
"tag": "libpcap-1.10.4",
"commit": "104271ba4a14de6743e43bcf87536786d8fddea4"
}
],
"cleanup": [
"/bin",
"/include",
"/lib/*.a",
"/lib/*.la",
"/lib/pkgconfig",
"/share/man"
]
}
@@ -1,24 +0,0 @@
{
"name": "libaio",
"no-autogen": true,
"make-install-args": [
"prefix=/app"
],
"build-options": {
"strip": true
},
"sources": [
{
"type": "git",
"url": "https://pagure.io/libaio.git",
"tag": "libaio-0.3.113",
"commit": "1b18bfafc6a2f7b9fa2c6be77a95afed8b7be448"
}
],
"cleanup": [
"/include",
"/lib/*.a",
"/lib/*.la"
]
}
@@ -1,45 +0,0 @@
{
"name": "sdl2",
"buildsystem": "autotools",
"no-autogen": true,
"config-opts": [
"--disable-dbus",
"--without-x",
"--disable-video-opengl",
"--disable-video-opengles",
"--disable-video-vulkan",
"--disable-wayland-shared",
"--disable-ime",
"--disable-oss",
"--disable-alsa",
"--disable-jack",
"--disable-esd",
"--disable-pipewire",
"--disable-pulseaudio",
"--disable-arts",
"--disable-nas",
"--disable-sndio",
"--disable-fusionsound",
"--disable-diskaudio"
],
"build-options": {
"strip": true
},
"sources": [
{
"type": "archive",
"url": "https://libsdl.org/release/SDL2-2.28.5.tar.gz",
"sha256": "332cb37d0be20cb9541739c61f79bae5a477427d79ae85e352089afdaf6666e4"
}
],
"cleanup": [
"/bin",
"/include",
"/lib/*.a",
"/lib/*.la",
"/lib/cmake",
"/lib/pkgconfig",
"/share/aclocal"
]
}
@@ -1,22 +0,0 @@
{
"name": "libbacktrace",
"buildsystem": "autotools",
"no-autogen": true,
"build-options": {
"strip": false,
"no-debuginfo": true
},
"sources": [
{
"type": "git",
"url": "https://github.com/ianlancetaylor/libbacktrace.git",
"commit": "ad106d5fdd5d960bd33fae1c48a351af567fd075"
}
],
"cleanup": [
"/include",
"/lib/*.a",
"/lib/*.la"
]
}
@@ -1,68 +0,0 @@
{
"app-id": "net.pcsx2.PCSX2",
"runtime": "org.kde.Platform",
"runtime-version": "6.6",
"sdk": "org.kde.Sdk",
"sdk-extensions": [
"org.freedesktop.Sdk.Extension.llvm17"
],
"add-extensions": {
"org.freedesktop.Platform.ffmpeg-full": {
"directory": "lib/ffmpeg",
"version": "22.08",
"add-ld-path": ".",
"autodownload": true
}
},
"command": "pcsx2-qt",
"finish-args": [
"--device=all",
"--share=network",
"--share=ipc",
"--socket=x11",
"--socket=pulseaudio",
"--talk-name=org.freedesktop.ScreenSaver",
"--env=QT_QPA_PLATFORM=xcb"
],
"modules": [
"modules/10-libpcap.json",
"modules/11-libaio.json",
"modules/20-sdl2.json",
"modules/21-libbacktrace.json",
{
"name": "pcsx2",
"buildsystem": "simple",
"build-options": {
"strip": false,
"no-debuginfo": true,
"env": {
"DEPS_PREFIX": "/app",
"COMPILER": "clang",
"CLANG_PATH": "/usr/lib/sdk/llvm17/bin/clang",
"CLANGXX_PATH": "/usr/lib/sdk/llvm17/bin/clang++",
"ADDITIONAL_CMAKE_ARGS": "-DUSE_LINKED_FFMPEG=ON"
}
},
"sources": [
{
"type": "dir",
"path": "../../../../.."
}
],
"build-commands": [
".github/workflows/scripts/linux/generate-cmake-qt.sh",
"cd build && ../.github/workflows/scripts/linux/compile.sh && cd ..",
"cp -a build/bin ${FLATPAK_DEST}",
"cd build && ninja unittests && cd .."
],
"post-install": [
"install -Dm644 bin/resources/icons/AppIconLarge.png ${FLATPAK_DEST}/share/icons/hicolor/512x512/apps/net.pcsx2.PCSX2.png",
"install -Dm644 .github/workflows/scripts/linux/pcsx2-qt.desktop ${FLATPAK_DEST}/share/applications/net.pcsx2.PCSX2.desktop",
"desktop-file-edit --set-key=Icon --set-value=net.pcsx2.PCSX2 ${FLATPAK_DEST}/share/applications/net.pcsx2.PCSX2.desktop",
"install -Dm644 .github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.metainfo.xml ${FLATPAK_DEST}/share/metainfo/net.pcsx2.PCSX2.metainfo.xml",
"mkdir -p ${FLATPAK_DEST}/lib/ffmpeg"
]
}
]
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

@@ -1,16 +0,0 @@
#!/bin/bash
function retry_command {
# Package servers tend to be unreliable at times..
# Retry a bunch of times.
local RETRIES=10
for i in $(seq 1 "$RETRIES"); do
"$@" && break
if [ "$i" == "$RETRIES" ]; then
echo "Command \"$@\" failed after ${RETRIES} retries."
exit 1
fi
done
}
@@ -1,50 +0,0 @@
#!/usr/bin/env bash
set -e
if [[ -z "${DEPS_PREFIX}" ]]; then
echo "DEPS_PREFIX is not set."
exit 1
fi
echo "Using build dependencies from: ${DEPS_PREFIX}"
if [ "${COMPILER}" = "clang" ]; then
if [[ -z "${CLANG_PATH}" ]] || [[ -z "${CLANGXX_PATH}" ]]; then
echo "CLANG_PATH or CLANGXX_PATH is not set."
exit 1
fi
echo "Using clang toolchain"
cat > "clang-toolchain.cmake" << EOF
set(CMAKE_C_COMPILER "${CLANG_PATH}")
set(CMAKE_CXX_COMPILER "${CLANGXX_PATH}")
set(CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=lld")
set(CMAKE_MODULE_LINKER_FLAGS_INIT "-fuse-ld=lld")
set(CMAKE_SHARED_LINKER_FLAGS_INIT "-fuse-ld=lld")
EOF
ADDITIONAL_CMAKE_ARGS="$ADDITIONAL_CMAKE_ARGS -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DCMAKE_TOOLCHAIN_FILE=clang-toolchain.cmake"
fi
echo "Additional CMake Args - ${ADDITIONAL_CMAKE_ARGS}"
# Generate CMake into ./build
# DISABLE_ADVANCE_SIMD is needed otherwise we end up doing -march=native.
# shellcheck disable=SC2086
cmake \
-B build \
-G Ninja \
$ADDITIONAL_CMAKE_ARGS \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_BUILD_TYPE=Release \
-DQT_BUILD=ON \
-DCUBEB_API=ON \
-DX11_API=ON \
-DWAYLAND_API=ON \
-DENABLE_SETCAP=OFF \
-DCMAKE_PREFIX_PATH="${DEPS_PREFIX}" \
-DUSE_SYSTEM_SDL2=ON \
-DUSE_SYSTEM_ZSTD=OFF \
-DDISABLE_ADVANCE_SIMD=TRUE
@@ -1,32 +0,0 @@
#!/usr/bin/env bash
SCRIPTDIR=$(dirname "${BASH_SOURCE[0]}")
if [[ $# -lt 1 ]]; then
echo "Output file must be provided as a parameter"
exit 1
fi
OUTFILE=$1
GIT_DATE=$(git log -1 --pretty=%cd --date=short)
GIT_VERSION=$(git tag --points-at HEAD)
GIT_HASH=$(git rev-parse HEAD)
if [[ "${GIT_VERSION}" == "" ]]; then
# In the odd event that we run this script before the release gets tagged.
GIT_VERSION=$(git describe --tags)
if [[ "${GIT_VERSION}" == "" ]]; then
GIT_VERSION=$(git rev-parse HEAD)
fi
fi
echo "GIT_DATE: ${GIT_DATE}"
echo "GIT_VERSION: ${GIT_VERSION}"
echo "GIT_HASH: ${GIT_HASH}"
cp "${SCRIPTDIR}"/pcsx2-qt.metainfo.xml.in "${OUTFILE}"
sed -i -e "s/@GIT_VERSION@/${GIT_VERSION}/" "${OUTFILE}"
sed -i -e "s/@GIT_DATE@/${GIT_DATE}/" "${OUTFILE}"
sed -i -e "s/@GIT_HASH@/${GIT_HASH}/" "${OUTFILE}"
@@ -1,58 +0,0 @@
#!/bin/bash
SCRIPTDIR=$(dirname "${BASH_SOURCE[0]}")
source "$SCRIPTDIR/functions.sh"
set -e
ARCH=x86_64
KDE_BRANCH=6.6
BRANCH=23.08
FLAT_MANAGER_CLIENT_DIR="$HOME/.local/bin"
# Build packages. Mostly needed for flat-manager-client.
declare -a BUILD_PACKAGES=(
"flatpak"
"flatpak-builder"
"appstream-util"
"python3-aiohttp"
"python3-tenacity"
"python3-gi"
"gobject-introspection"
"libappstream-glib8"
"libappstream-glib-dev"
"libappstream-dev"
"gir1.2-ostree-1.0"
)
# Flatpak runtimes and SDKs.
declare -a FLATPAK_PACKAGES=(
"org.kde.Platform/${ARCH}/${KDE_BRANCH}"
"org.kde.Sdk/${ARCH}/${KDE_BRANCH}"
"org.freedesktop.Platform.ffmpeg-full/${ARCH}/${BRANCH}"
"org.freedesktop.Sdk.Extension.llvm17/${ARCH}/${BRANCH}"
"org.freedesktop.appstream-glib/${ARCH}/stable"
)
retry_command sudo apt-get -qq update
# Install packages needed for building
echo "Will install the following packages for building - ${BUILD_PACKAGES[*]}"
retry_command sudo apt-get -y install "${BUILD_PACKAGES[@]}"
sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
# Install packages needed for building
echo "Will install the following packages for building - ${FLATPAK_PACKAGES[*]}"
retry_command sudo flatpak -y install "${FLATPAK_PACKAGES[@]}"
echo "Installing Flatpak Builder"
retry_command sudo flatpak -y install flathub org.flatpak.builder
echo "Downloading flat-manager-client"
mkdir -p "$FLAT_MANAGER_CLIENT_DIR"
pushd "$FLAT_MANAGER_CLIENT_DIR"
aria2c -Z "https://raw.githubusercontent.com/flatpak/flat-manager/9401efbdc0d6bd489507d8401c567ba219d735d5/flat-manager-client"
chmod +x flat-manager-client
echo "$FLAT_MANAGER_CLIENT_DIR" >> $GITHUB_PATH
popd
@@ -1,84 +0,0 @@
#!/bin/bash
SCRIPTDIR=$(dirname "${BASH_SOURCE[0]}")
source "$SCRIPTDIR/functions.sh"
set -e
# Packages - Build and Qt
declare -a BUILD_PACKAGES=(
"build-essential"
"g++"
"git"
"cmake"
"ccache"
"ninja-build"
"patchelf"
"libfuse2"
"libglib2.0-dev"
"libfontconfig1-dev"
"libharfbuzz-dev"
"libjpeg-dev"
"libpng-dev"
"libfreetype-dev"
"libinput-dev"
"libxcb-*-dev"
"libxkbcommon-dev"
"libxkbcommon-x11-dev"
"libxrender-dev"
"libwayland-dev"
"libgl1-mesa-dev"
"libegl-dev"
"libegl1-mesa-dev"
"libgl1-mesa-dev"
"libssl-dev"
)
# Packages - PCSX2
declare -a PCSX2_PACKAGES=(
"extra-cmake-modules"
"libaio-dev"
"libasound2-dev"
"libbz2-dev"
"libcurl4-openssl-dev"
"libdbus-1-dev"
"libegl1-mesa-dev"
"libgl1-mesa-dev"
"libgtk-3-dev"
"libharfbuzz-dev"
"libjpeg-dev"
"liblzma-dev"
"libpcap0.8-dev"
"libpng-dev"
"libpulse-dev"
"librsvg2-dev"
"libsamplerate0-dev"
"libudev-dev"
"libx11-xcb-dev"
"libavcodec-dev"
"libavformat-dev"
"libavutil-dev"
"libswresample-dev"
"libswscale-dev"
"pkg-config"
"zlib1g-dev"
)
if [ "${COMPILER}" = "clang" ]; then
BUILD_PACKAGES+=("llvm-17" "lld-17" "clang-17")
# Ubuntu 22.04 doesn't ship with LLVM 16, so we need to pull it from the llvm.org repos.
retry_command wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo apt-add-repository -n 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-17 main'
fi
retry_command sudo apt-get -qq update && break
# Install packages needed for building
echo "Will install the following packages for building - ${BUILD_PACKAGES[*]}"
retry_command sudo apt-get -y install "${BUILD_PACKAGES[@]}"
# Install packages needed by pcsx2
PCSX2_PACKAGES=("${PCSX2_PACKAGES[@]}")
echo "Will install the following packages for pcsx2 - ${PCSX2_PACKAGES[*]}"
retry_command sudo apt-get -y install "${PCSX2_PACKAGES[@]}"
@@ -1,12 +0,0 @@
[Desktop Entry]
Version=1.0
Terminal=false
Type=Application
Name=PCSX2
StartupWMClass=PCSX2
GenericName=PlayStation 2 Emulator
Comment=Sony PlayStation 2 emulator
Exec=pcsx2-qt
Icon=PCSX2
Keywords=game;emulator;
Categories=Game;Emulator;
@@ -1,37 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<id>net.pcsx2.PCSX2</id>
<launchable type="desktop-id">net.pcsx2.PCSX2.desktop</launchable>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0</project_license>
<name>PCSX2</name>
<developer_name>PCSX2</developer_name>
<summary>PlayStation 2 Emulator</summary>
<description>
<p>PCSX2 is a free and open-source PlayStation 2 (PS2) emulator. Its purpose is to emulate the PS2's hardware, using a combination of MIPS CPU Interpreters, Recompilers and a Virtual Machine which manages hardware states and PS2 system memory. This allows you to play PS2 games on your PC, with many additional features and benefits.</p>
<p>PlayStation 2 and PS2 are registered trademarks of Sony Interactive Entertainment. This application is not affiliated in any way with Sony Interactive Entertainment.</p>
</description>
<url type="homepage">https://pcsx2.net/</url>
<url type="bugtracker">https://github.com/PCSX2/pcsx2/issues</url>
<url type="donation">https://github.com/sponsors/PCSX2</url>
<url type="faq">https://pcsx2.net/docs/</url>
<url type="help">https://discord.com/invite/TCz3t9k</url>
<url type="translate">https://crowdin.com/project/pcsx2-emulator</url>
<url type="vcs-browser">https://github.com/PCSX2/pcsx2</url>
<screenshots>
<screenshot type="default">
<image>https://raw.githubusercontent.com/PCSX2/pcsx2/master/.github/workflows/scripts/linux/flatpak/screenshots/screenshot1.png</image>
</screenshot>
<screenshot>
<image>https://raw.githubusercontent.com/PCSX2/pcsx2/master/.github/workflows/scripts/linux/flatpak/screenshots/screenshot2.png</image>
</screenshot>
</screenshots>
<content_rating type="oars-1.1"/>
<update_contact>stenzek_AT_gmail.com</update_contact>
<releases>
<release version="@GIT_VERSION@" date="@GIT_DATE@" />
</releases>
<custom>
<value key="flathub::manifest">https://raw.githubusercontent.com/PCSX2/pcsx2/@GIT_HASH@/.github/workflows/scripts/linux/flatpak/net.pcsx2.PCSX2.json</value>
</custom>
</component>
@@ -1,145 +0,0 @@
#!/bin/bash
set -e
export MACOSX_DEPLOYMENT_TARGET=11.0
INSTALLDIR="$HOME/deps"
NPROCS="$(getconf _NPROCESSORS_ONLN)"
SDL=SDL2-2.28.5
PNG=1.6.37
JPG=9e
FFMPEG=6.0
QT=6.6.0
mkdir deps-build
cd deps-build
export PKG_CONFIG_PATH="$INSTALLDIR/lib/pkgconfig:$PKG_CONFIG_PATH"
export LDFLAGS="-L$INSTALLDIR/lib -dead_strip $LDFLAGS"
export CFLAGS="-I$INSTALLDIR/include -Os $CFLAGS"
export CXXFLAGS="-I$INSTALLDIR/include -Os $CXXFLAGS"
cat > SHASUMS <<EOF
332cb37d0be20cb9541739c61f79bae5a477427d79ae85e352089afdaf6666e4 $SDL.tar.gz
505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca libpng-$PNG.tar.xz
57be87c22d9b49c112b6d24bc67d42508660e6b718b3db89c44e47e289137082 ffmpeg-$FFMPEG.tar.xz
039d53312acb5897a9054bd38c9ccbdab72500b71fdccdb3f4f0844b0dd39e0e qtbase-everywhere-src-$QT.tar.xz
e1542cb50176e237809895c6549598c08587c63703d100be54ac2d806834e384 qtimageformats-everywhere-src-$QT.tar.xz
33da25fef51102f564624a7ea3e57cb4a0a31b7b44783d1af5749ac36d3c72de qtsvg-everywhere-src-$QT.tar.xz
4e9feebc142bbb6e453e1dc3277e09ec45c8ef081b5ee2a029e6684b5905ba99 qttools-everywhere-src-$QT.tar.xz
a0d89a236f64b810eb0fe4ae1e90db22b0e86263521b35f89e69f1392815078c qttranslations-everywhere-src-$QT.tar.xz
EOF
curl -L \
-O "https://libsdl.org/release/$SDL.tar.gz" \
-O "https://downloads.sourceforge.net/project/libpng/libpng16/$PNG/libpng-$PNG.tar.xz" \
-O "https://ffmpeg.org/releases/ffmpeg-$FFMPEG.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtbase-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtimageformats-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qtsvg-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttools-everywhere-src-$QT.tar.xz" \
-O "https://download.qt.io/official_releases/qt/${QT%.*}/$QT/submodules/qttranslations-everywhere-src-$QT.tar.xz" \
shasum -a 256 --check SHASUMS
echo "Installing SDL..."
tar xf "$SDL.tar.gz"
cd "$SDL"
# MFI causes multiple joystick connection events, I'm guessing because both the HIDAPI and MFI interfaces
# race each other, and sometimes both end up getting through. So, just force MFI off.
patch -u CMakeLists.txt <<EOF
--- CMakeLists.txt 2023-08-03 01:33:11
+++ CMakeLists.txt 2023-08-26 12:58:53
@@ -2105,7 +2105,7 @@
#import <Foundation/Foundation.h>
#import <CoreHaptics/CoreHaptics.h>
int main() { return 0; }" HAVE_FRAMEWORK_COREHAPTICS)
- if(HAVE_FRAMEWORK_GAMECONTROLLER AND HAVE_FRAMEWORK_COREHAPTICS)
+ if(HAVE_FRAMEWORK_GAMECONTROLLER AND HAVE_FRAMEWORK_COREHAPTICS AND FALSE)
# Only enable MFI if we also have CoreHaptics to ensure rumble works
set(SDL_JOYSTICK_MFI 1)
set(SDL_FRAMEWORK_GAMECONTROLLER 1)
EOF
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DSDL_X11=OFF
make -C build "-j$NPROCS"
make -C build install
cd ..
echo "Installing libpng..."
tar xf "libpng-$PNG.tar.xz"
cd "libpng-$PNG"
./configure --prefix "$INSTALLDIR" --disable-dependency-tracking
make "-j$NPROCS"
make install
cd ..
echo "Installing FFmpeg..."
tar xf "ffmpeg-$FFMPEG.tar.xz"
cd "ffmpeg-$FFMPEG"
./configure --prefix="$INSTALLDIR" --disable-all --disable-autodetect --disable-static --enable-shared \
--enable-avcodec --enable-avformat --enable-avutil --enable-swresample --enable-swscale \
--enable-audiotoolbox --enable-videotoolbox \
--enable-encoder=ffv1,qtrle,pcm_s16be,pcm_s16le,*_at,*_videotoolbox \
--enable-muxer=avi,matroska,mov,mp3,mp4,wav \
--enable-protocol=file
make "-j$NPROCS"
make install
cd ..
echo "Installing Qt Base..."
tar xf "qtbase-everywhere-src-$QT.tar.xz"
cd "qtbase-everywhere-src-$QT"
cmake -B build -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release -DFEATURE_optimize_size=ON -DFEATURE_dbus=OFF -DFEATURE_framework=OFF -DFEATURE_icu=OFF -DFEATURE_opengl=OFF -DFEATURE_printsupport=OFF -DFEATURE_sql=OFF -DFEATURE_gssapi=OFF
make -C build "-j$NPROCS"
make -C build install
cd ..
echo "Installing Qt SVG..."
tar xf "qtsvg-everywhere-src-$QT.tar.xz"
cd "qtsvg-everywhere-src-$QT"
cmake -B build -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=MinSizeRel
make -C build "-j$NPROCS"
make -C build install
cd ..
echo "Installing Qt Image Formats..."
tar xf "qtimageformats-everywhere-src-$QT.tar.xz"
cd "qtimageformats-everywhere-src-$QT"
cmake -B build -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=MinSizeRel
make -C build "-j$NPROCS"
make -C build install
cd ..
echo "Installing Qt Tools..."
tar xf "qttools-everywhere-src-$QT.tar.xz"
cd "qttools-everywhere-src-$QT"
# Linguist relies on a library in the Designer target, which takes 5-7 minutes to build on the CI
# Avoid it by not building Linguist, since we only need the tools that come with it
patch -u src/linguist/CMakeLists.txt <<EOF
--- src/linguist/CMakeLists.txt
+++ src/linguist/CMakeLists.txt
@@ -14,7 +14,7 @@
add_subdirectory(lrelease-pro)
add_subdirectory(lupdate)
add_subdirectory(lupdate-pro)
-if(QT_FEATURE_process AND QT_FEATURE_pushbutton AND QT_FEATURE_toolbutton AND TARGET Qt::Widgets AND NOT no-png)
+if(QT_FEATURE_process AND QT_FEATURE_pushbutton AND QT_FEATURE_toolbutton AND TARGET Qt::Widgets AND TARGET Qt::PrintSupport AND NOT no-png)
add_subdirectory(linguist)
endif()
EOF
cmake -B build -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=OFF -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF
make -C build "-j$NPROCS"
make -C build install
cd ..
echo "Installing Qt Translations..."
tar xf "qttranslations-everywhere-src-$QT.tar.xz"
cd "qttranslations-everywhere-src-$QT"
cmake -B build -DCMAKE_PREFIX_PATH="$INSTALLDIR" -DCMAKE_INSTALL_PREFIX="$INSTALLDIR" -DCMAKE_BUILD_TYPE=Release
make -C build "-j$NPROCS"
make -C build install
cd ..
echo "Cleaning up..."
cd ..
rm -r deps-build
@@ -1,2 +0,0 @@
node_modules/
*.md
@@ -1,82 +0,0 @@
import { MessageEmbed, WebhookClient } from "discord.js";
import { Octokit } from "@octokit/rest";
import { throttling } from "@octokit/plugin-throttling";
import { retry } from "@octokit/plugin-retry";
let owner = process.env.OWNER;
let repo = process.env.REPO;
Octokit.plugin(throttling);
Octokit.plugin(retry);
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN,
userAgent: `${owner}/${repo}`,
log: {
debug: () => { },
info: () => { },
warn: console.warn,
error: console.error
},
throttle: {
onRateLimit: (retryAfter, options) => {
octokit.log.warn(
`Request quota exhausted for request ${options.method} ${options.url}`
);
// Retry twice after hitting a rate limit error, then give up
if (options.request.retryCount <= 2) {
console.log(`Retrying after ${retryAfter} seconds!`);
return true;
}
},
onAbuseLimit: (retryAfter, options) => {
// does not retry, only logs a warning
octokit.log.warn(
`Abuse detected for request ${options.method} ${options.url}`
);
},
}
});
if (process.env.TAG_VAL === undefined || process.env.TAG_VAL === "") {
console.log(`Not announcing - TAG_VAL not defined`);
process.exit(1);
}
const { data: releaseInfo } = await octokit.rest.repos.getReleaseByTag({
owner: owner,
repo: repo,
tag: process.env.TAG_VAL,
});
if (releaseInfo === undefined) {
console.log(`Not announcing - could not locate release with tag ${process.env.TAG_VAL}`);
process.exit(1);
}
if (!releaseInfo.prerelease) {
console.log("Not announcing - release was not a pre-release (aka a Nightly)");
process.exit(0);
}
// Publish Webhook
const embed = new MessageEmbed()
.setColor('#FF8000')
.setTitle('New PCSX2 Nightly Build Available!')
.setDescription("To download the latest or previous builds, [visit the official downloads page](https://pcsx2.net/downloads/).")
.addFields(
{ name: 'Version', value: releaseInfo.tag_name, inline: true },
{ name: 'Installation Steps', value: '[See Here](https://github.com/PCSX2/pcsx2/wiki/Nightly-Build-Usage-Guide)', inline: true },
{ name: 'Included Changes', value: releaseInfo.body, inline: false }
);
console.log(embed);
// Get all webhooks, simple comma-sep string
const webhookUrls = process.env.DISCORD_BUILD_WEBHOOK.split(",");
for (const url of webhookUrls) {
const webhookClient = new WebhookClient({ url: url });
await webhookClient.send({
embeds: [embed],
});
}
@@ -1,851 +0,0 @@
{
"name": "announce-release",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "announce-release",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@octokit/plugin-retry": "^3.0.9",
"@octokit/plugin-throttling": "^3.5.2",
"@octokit/rest": "^18.12.0",
"discord.js": "^13.2.0"
}
},
"node_modules/@discordjs/builders": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.6.0.tgz",
"integrity": "sha512-mH3Gx61LKk2CD05laCI9K5wp+a3NyASHDUGx83DGJFkqJlRlSV5WMJNY6RS37A5SjqDtGMF4wVR9jzFaqShe6Q==",
"dependencies": {
"@sindresorhus/is": "^4.0.1",
"discord-api-types": "^0.22.0",
"ow": "^0.27.0",
"ts-mixer": "^6.0.0",
"tslib": "^2.3.1"
},
"engines": {
"node": ">=14.0.0",
"npm": ">=7.0.0"
}
},
"node_modules/@discordjs/builders/node_modules/discord-api-types": {
"version": "0.22.0",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.22.0.tgz",
"integrity": "sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg==",
"engines": {
"node": ">=12"
}
},
"node_modules/@discordjs/collection": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.2.1.tgz",
"integrity": "sha512-vhxqzzM8gkomw0TYRF3tgx7SwElzUlXT/Aa41O7mOcyN6wIJfj5JmDWaO5XGKsGSsNx7F3i5oIlrucCCWV1Nog==",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/@discordjs/form-data": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@discordjs/form-data/-/form-data-3.0.1.tgz",
"integrity": "sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/@octokit/auth-token": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
"dependencies": {
"@octokit/types": "^6.0.3"
}
},
"node_modules/@octokit/core": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
"dependencies": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
"@octokit/request": "^5.6.0",
"@octokit/request-error": "^2.0.5",
"@octokit/types": "^6.0.3",
"before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/endpoint": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
"dependencies": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/graphql": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
"dependencies": {
"@octokit/request": "^5.6.0",
"@octokit/types": "^6.0.3",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/openapi-types": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.1.0.tgz",
"integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw=="
},
"node_modules/@octokit/plugin-paginate-rest": {
"version": "2.16.9",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.9.tgz",
"integrity": "sha512-gfSCMgz5scFKsR0dW4jaYsDJVt/UwCHp4dF7sHlmSekZvwzvLiOAGZ4MQkEsL5DW9hIk2W+UQkYZMTA1b6Wsqw==",
"dependencies": {
"@octokit/types": "^6.33.0"
}
},
"node_modules/@octokit/plugin-request-log": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
"peerDependencies": {
"@octokit/core": ">=3"
}
},
"node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "5.12.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz",
"integrity": "sha512-0nY3htfl6x9UkPcqv8pm9vOC/bTA7f4IMDWln13neHRdNWQvOQgZ9fRxK7BAc74rye4yVINEFi9Yb9rnGUvosA==",
"dependencies": {
"@octokit/types": "^6.33.0",
"deprecation": "^2.3.1"
}
},
"node_modules/@octokit/plugin-retry": {
"version": "3.0.9",
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz",
"integrity": "sha512-r+fArdP5+TG6l1Rv/C9hVoty6tldw6cE2pRHNGmFPdyfrc696R6JjrQ3d7HdVqGwuzfyrcaLAKD7K8TX8aehUQ==",
"dependencies": {
"@octokit/types": "^6.0.3",
"bottleneck": "^2.15.3"
}
},
"node_modules/@octokit/plugin-throttling": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.7.0.tgz",
"integrity": "sha512-qrKT1Yl/KuwGSC6/oHpLBot3ooC9rq0/ryDYBCpkRtoj+R8T47xTMDT6Tk2CxWopFota/8Pi/2SqArqwC0JPow==",
"dependencies": {
"@octokit/types": "^6.0.1",
"bottleneck": "^2.15.3"
},
"peerDependencies": {
"@octokit/core": "^3.5.0"
}
},
"node_modules/@octokit/request": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
"integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
"dependencies": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.1.0",
"@octokit/types": "^6.16.1",
"is-plain-object": "^5.0.0",
"node-fetch": "^2.6.1",
"universal-user-agent": "^6.0.0"
}
},
"node_modules/@octokit/request-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
"dependencies": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
"once": "^1.4.0"
}
},
"node_modules/@octokit/rest": {
"version": "18.12.0",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
"dependencies": {
"@octokit/core": "^3.5.1",
"@octokit/plugin-paginate-rest": "^2.16.8",
"@octokit/plugin-request-log": "^1.0.4",
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
}
},
"node_modules/@octokit/types": {
"version": "6.33.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.33.0.tgz",
"integrity": "sha512-0zffZ048M0UhthyPXQHLz4038Ak46nMWZXkzlXvXB/M/L1jYPBceq4iZj4qjKVrvveaJrrgKdJ9+3yUuITfcCw==",
"dependencies": {
"@octokit/openapi-types": "^11.1.0"
}
},
"node_modules/@sapphire/async-queue": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.6.tgz",
"integrity": "sha512-M5CbgMgesemMUCQo5G/InGHvp+GZx6uuJNV1iwvSWD8EFNVrfxaTcqhcAXM3MPYkjlxvNnoDNk0R1lfzvca6LA==",
"engines": {
"node": ">=v14.18.0",
"npm": ">=7.24.2"
}
},
"node_modules/@sindresorhus/is": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.2.0.tgz",
"integrity": "sha512-VkE3KLBmJwcCaVARtQpfuKcKv8gcBmUubrfHGF84dXuuW6jgsRYxPtzcIhPyK9WAPpRt2/xY6zkD9MnRaJzSyw==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sindresorhus/is?sponsor=1"
}
},
"node_modules/@types/node": {
"version": "16.10.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.3.tgz",
"integrity": "sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ=="
},
"node_modules/@types/ws": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.2.0.tgz",
"integrity": "sha512-cyeefcUCgJlEk+hk2h3N+MqKKsPViQgF5boi9TTHSK+PoR9KWBb/C5ccPcDyAqgsbAYHTwulch725DV84+pSpg==",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"node_modules/before-after-hook": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
},
"node_modules/bottleneck": {
"version": "2.19.5",
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
"integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
},
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"engines": {
"node": ">=6"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/deprecation": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
},
"node_modules/discord-api-types": {
"version": "0.23.1",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.23.1.tgz",
"integrity": "sha512-igWmn+45mzXRWNEPU25I/pr8MwxHb767wAr51oy3VRLRcTlp5ADBbrBR0lq3SA1Rfw3MtM4TQu1xo3kxscfVdQ==",
"engines": {
"node": ">=12"
}
},
"node_modules/discord.js": {
"version": "13.2.0",
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.2.0.tgz",
"integrity": "sha512-nyxUvL8wuQG38zx13wUMkpcA8koFszyiXdkSLwwM9opKW2LC2H5gD0cTZxImeJ6GtEnKPWT8xBiE8lLBmbNIhw==",
"dependencies": {
"@discordjs/builders": "^0.6.0",
"@discordjs/collection": "^0.2.1",
"@discordjs/form-data": "^3.0.1",
"@sapphire/async-queue": "^1.1.5",
"@types/ws": "^8.2.0",
"discord-api-types": "^0.23.1",
"node-fetch": "^2.6.1",
"ws": "^8.2.3"
},
"engines": {
"node": ">=16.6.0",
"npm": ">=7.0.0"
}
},
"node_modules/dot-prop": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
"integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==",
"dependencies": {
"is-obj": "^2.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-obj": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
"integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
"engines": {
"node": ">=8"
}
},
"node_modules/is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
},
"node_modules/mime-db": {
"version": "1.50.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz",
"integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.33",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz",
"integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==",
"dependencies": {
"mime-db": "1.50.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/ow": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/ow/-/ow-0.27.0.tgz",
"integrity": "sha512-SGnrGUbhn4VaUGdU0EJLMwZWSupPmF46hnTRII7aCLCrqixTAC5eKo8kI4/XXf1eaaI8YEVT+3FeGNJI9himAQ==",
"dependencies": {
"@sindresorhus/is": "^4.0.1",
"callsites": "^3.1.0",
"dot-prop": "^6.0.1",
"lodash.isequal": "^4.5.0",
"type-fest": "^1.2.1",
"vali-date": "^1.0.0"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
},
"node_modules/ts-mixer": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.0.tgz",
"integrity": "sha512-nXIb1fvdY5CBSrDIblLn73NW0qRDk5yJ0Sk1qPBF560OdJfQp9jhl+0tzcY09OZ9U+6GpeoI9RjwoIKFIoB9MQ=="
},
"node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/type-fest": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
"integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/universal-user-agent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
},
"node_modules/vali-date": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz",
"integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"node_modules/ws": {
"version": "8.2.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
"integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
}
},
"dependencies": {
"@discordjs/builders": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-0.6.0.tgz",
"integrity": "sha512-mH3Gx61LKk2CD05laCI9K5wp+a3NyASHDUGx83DGJFkqJlRlSV5WMJNY6RS37A5SjqDtGMF4wVR9jzFaqShe6Q==",
"requires": {
"@sindresorhus/is": "^4.0.1",
"discord-api-types": "^0.22.0",
"ow": "^0.27.0",
"ts-mixer": "^6.0.0",
"tslib": "^2.3.1"
},
"dependencies": {
"discord-api-types": {
"version": "0.22.0",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.22.0.tgz",
"integrity": "sha512-l8yD/2zRbZItUQpy7ZxBJwaLX/Bs2TGaCthRppk8Sw24LOIWg12t9JEreezPoYD0SQcC2htNNo27kYEpYW/Srg=="
}
}
},
"@discordjs/collection": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.2.1.tgz",
"integrity": "sha512-vhxqzzM8gkomw0TYRF3tgx7SwElzUlXT/Aa41O7mOcyN6wIJfj5JmDWaO5XGKsGSsNx7F3i5oIlrucCCWV1Nog=="
},
"@discordjs/form-data": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@discordjs/form-data/-/form-data-3.0.1.tgz",
"integrity": "sha512-ZfFsbgEXW71Rw/6EtBdrP5VxBJy4dthyC0tpQKGKmYFImlmmrykO14Za+BiIVduwjte0jXEBlhSKf0MWbFp9Eg==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
}
},
"@octokit/auth-token": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
"requires": {
"@octokit/types": "^6.0.3"
}
},
"@octokit/core": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
"requires": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
"@octokit/request": "^5.6.0",
"@octokit/request-error": "^2.0.5",
"@octokit/types": "^6.0.3",
"before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/endpoint": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
"requires": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/graphql": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
"requires": {
"@octokit/request": "^5.6.0",
"@octokit/types": "^6.0.3",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/openapi-types": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.1.0.tgz",
"integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw=="
},
"@octokit/plugin-paginate-rest": {
"version": "2.16.9",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.9.tgz",
"integrity": "sha512-gfSCMgz5scFKsR0dW4jaYsDJVt/UwCHp4dF7sHlmSekZvwzvLiOAGZ4MQkEsL5DW9hIk2W+UQkYZMTA1b6Wsqw==",
"requires": {
"@octokit/types": "^6.33.0"
}
},
"@octokit/plugin-request-log": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
"requires": {}
},
"@octokit/plugin-rest-endpoint-methods": {
"version": "5.12.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz",
"integrity": "sha512-0nY3htfl6x9UkPcqv8pm9vOC/bTA7f4IMDWln13neHRdNWQvOQgZ9fRxK7BAc74rye4yVINEFi9Yb9rnGUvosA==",
"requires": {
"@octokit/types": "^6.33.0",
"deprecation": "^2.3.1"
}
},
"@octokit/plugin-retry": {
"version": "3.0.9",
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz",
"integrity": "sha512-r+fArdP5+TG6l1Rv/C9hVoty6tldw6cE2pRHNGmFPdyfrc696R6JjrQ3d7HdVqGwuzfyrcaLAKD7K8TX8aehUQ==",
"requires": {
"@octokit/types": "^6.0.3",
"bottleneck": "^2.15.3"
}
},
"@octokit/plugin-throttling": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.7.0.tgz",
"integrity": "sha512-qrKT1Yl/KuwGSC6/oHpLBot3ooC9rq0/ryDYBCpkRtoj+R8T47xTMDT6Tk2CxWopFota/8Pi/2SqArqwC0JPow==",
"requires": {
"@octokit/types": "^6.0.1",
"bottleneck": "^2.15.3"
}
},
"@octokit/request": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
"integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
"requires": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.1.0",
"@octokit/types": "^6.16.1",
"is-plain-object": "^5.0.0",
"node-fetch": "^2.6.1",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/request-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
"requires": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
"once": "^1.4.0"
}
},
"@octokit/rest": {
"version": "18.12.0",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
"requires": {
"@octokit/core": "^3.5.1",
"@octokit/plugin-paginate-rest": "^2.16.8",
"@octokit/plugin-request-log": "^1.0.4",
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
}
},
"@octokit/types": {
"version": "6.33.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.33.0.tgz",
"integrity": "sha512-0zffZ048M0UhthyPXQHLz4038Ak46nMWZXkzlXvXB/M/L1jYPBceq4iZj4qjKVrvveaJrrgKdJ9+3yUuITfcCw==",
"requires": {
"@octokit/openapi-types": "^11.1.0"
}
},
"@sapphire/async-queue": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.1.6.tgz",
"integrity": "sha512-M5CbgMgesemMUCQo5G/InGHvp+GZx6uuJNV1iwvSWD8EFNVrfxaTcqhcAXM3MPYkjlxvNnoDNk0R1lfzvca6LA=="
},
"@sindresorhus/is": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.2.0.tgz",
"integrity": "sha512-VkE3KLBmJwcCaVARtQpfuKcKv8gcBmUubrfHGF84dXuuW6jgsRYxPtzcIhPyK9WAPpRt2/xY6zkD9MnRaJzSyw=="
},
"@types/node": {
"version": "16.10.3",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.3.tgz",
"integrity": "sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ=="
},
"@types/ws": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.2.0.tgz",
"integrity": "sha512-cyeefcUCgJlEk+hk2h3N+MqKKsPViQgF5boi9TTHSK+PoR9KWBb/C5ccPcDyAqgsbAYHTwulch725DV84+pSpg==",
"requires": {
"@types/node": "*"
}
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"before-after-hook": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
},
"bottleneck": {
"version": "2.19.5",
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
"integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
},
"callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"deprecation": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
},
"discord-api-types": {
"version": "0.23.1",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.23.1.tgz",
"integrity": "sha512-igWmn+45mzXRWNEPU25I/pr8MwxHb767wAr51oy3VRLRcTlp5ADBbrBR0lq3SA1Rfw3MtM4TQu1xo3kxscfVdQ=="
},
"discord.js": {
"version": "13.2.0",
"resolved": "https://registry.npmjs.org/discord.js/-/discord.js-13.2.0.tgz",
"integrity": "sha512-nyxUvL8wuQG38zx13wUMkpcA8koFszyiXdkSLwwM9opKW2LC2H5gD0cTZxImeJ6GtEnKPWT8xBiE8lLBmbNIhw==",
"requires": {
"@discordjs/builders": "^0.6.0",
"@discordjs/collection": "^0.2.1",
"@discordjs/form-data": "^3.0.1",
"@sapphire/async-queue": "^1.1.5",
"@types/ws": "^8.2.0",
"discord-api-types": "^0.23.1",
"node-fetch": "^2.6.1",
"ws": "^8.2.3"
}
},
"dot-prop": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
"integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==",
"requires": {
"is-obj": "^2.0.0"
}
},
"is-obj": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
"integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="
},
"is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
},
"lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA="
},
"mime-db": {
"version": "1.50.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz",
"integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A=="
},
"mime-types": {
"version": "2.1.33",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz",
"integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==",
"requires": {
"mime-db": "1.50.0"
}
},
"node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"requires": {
"whatwg-url": "^5.0.0"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
"wrappy": "1"
}
},
"ow": {
"version": "0.27.0",
"resolved": "https://registry.npmjs.org/ow/-/ow-0.27.0.tgz",
"integrity": "sha512-SGnrGUbhn4VaUGdU0EJLMwZWSupPmF46hnTRII7aCLCrqixTAC5eKo8kI4/XXf1eaaI8YEVT+3FeGNJI9himAQ==",
"requires": {
"@sindresorhus/is": "^4.0.1",
"callsites": "^3.1.0",
"dot-prop": "^6.0.1",
"lodash.isequal": "^4.5.0",
"type-fest": "^1.2.1",
"vali-date": "^1.0.0"
}
},
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
},
"ts-mixer": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.0.tgz",
"integrity": "sha512-nXIb1fvdY5CBSrDIblLn73NW0qRDk5yJ0Sk1qPBF560OdJfQp9jhl+0tzcY09OZ9U+6GpeoI9RjwoIKFIoB9MQ=="
},
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"type-fest": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
"integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA=="
},
"universal-user-agent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
},
"vali-date": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz",
"integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY="
},
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
},
"whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
"requires": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"ws": {
"version": "8.2.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
"integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
"requires": {}
}
}
}
@@ -1,18 +0,0 @@
{
"name": "announce-release",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@octokit/plugin-retry": "^3.0.9",
"@octokit/plugin-throttling": "^3.5.2",
"@octokit/rest": "^18.12.0",
"discord.js": "^13.2.0"
}
}
@@ -1,2 +0,0 @@
node_modules/
*.md
@@ -1,68 +0,0 @@
import { Octokit } from "@octokit/rest";
import { throttling } from "@octokit/plugin-throttling";
import { retry } from "@octokit/plugin-retry";
let owner = process.env.OWNER;
let repo = process.env.REPO;
Octokit.plugin(throttling);
Octokit.plugin(retry);
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN,
userAgent: `${owner}/${repo}`,
log: {
debug: () => { },
info: () => { },
warn: console.warn,
error: console.error
},
throttle: {
onRateLimit: (retryAfter, options) => {
octokit.log.warn(
`Request quota exhausted for request ${options.method} ${options.url}`
);
// Retry twice after hitting a rate limit error, then give up
if (options.request.retryCount <= 2) {
console.log(`Retrying after ${retryAfter} seconds!`);
return true;
}
},
onAbuseLimit: (retryAfter, options) => {
// does not retry, only logs a warning
octokit.log.warn(
`Abuse detected for request ${options.method} ${options.url}`
);
},
}
});
var args = process.argv.slice(2);
let commitSha = process.env.COMMIT_SHA;
console.log(`Searching for Commit - ${commitSha}`);
const { data: commit } = await octokit.rest.repos.getCommit({
owner: owner,
repo: repo,
ref: commitSha,
});
const { data: associatedPulls } = await octokit.rest.repos.listPullRequestsAssociatedWithCommit({
owner: owner,
repo: repo,
commit_sha: commit.sha,
});
let releaseNotes = ``;
if (associatedPulls.length === 0) {
releaseNotes += `- ${commit.commit.message}\n`;
} else {
for (var j = 0; j < associatedPulls.length; j++) {
releaseNotes += `- [${associatedPulls[j].title}](${associatedPulls[j].html_url})\n`;
}
}
import * as fs from 'fs';
fs.writeFileSync('./release-notes.md', releaseNotes);
@@ -1,202 +0,0 @@
{
"name": "generate-release-notes",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@octokit/auth-token": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
"requires": {
"@octokit/types": "^6.0.3"
}
},
"@octokit/core": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
"integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
"requires": {
"@octokit/auth-token": "^2.4.4",
"@octokit/graphql": "^4.5.8",
"@octokit/request": "^5.6.0",
"@octokit/request-error": "^2.0.5",
"@octokit/types": "^6.0.3",
"before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/endpoint": {
"version": "6.0.12",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
"requires": {
"@octokit/types": "^6.0.3",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/graphql": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
"requires": {
"@octokit/request": "^5.6.0",
"@octokit/types": "^6.0.3",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/openapi-types": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.1.0.tgz",
"integrity": "sha512-dWZfYvCCdjZzDYA3lIAMF72Q0jld8xidqCq5Ryw09eBJXZdcM6he0vWBTvw/b5UnGYqexxOyHWgfrsTlUJL3Gw=="
},
"@octokit/plugin-paginate-rest": {
"version": "2.16.9",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.9.tgz",
"integrity": "sha512-gfSCMgz5scFKsR0dW4jaYsDJVt/UwCHp4dF7sHlmSekZvwzvLiOAGZ4MQkEsL5DW9hIk2W+UQkYZMTA1b6Wsqw==",
"requires": {
"@octokit/types": "^6.33.0"
}
},
"@octokit/plugin-request-log": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
"integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA=="
},
"@octokit/plugin-rest-endpoint-methods": {
"version": "5.12.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.12.1.tgz",
"integrity": "sha512-0nY3htfl6x9UkPcqv8pm9vOC/bTA7f4IMDWln13neHRdNWQvOQgZ9fRxK7BAc74rye4yVINEFi9Yb9rnGUvosA==",
"requires": {
"@octokit/types": "^6.33.0",
"deprecation": "^2.3.1"
}
},
"@octokit/plugin-retry": {
"version": "3.0.9",
"resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-3.0.9.tgz",
"integrity": "sha512-r+fArdP5+TG6l1Rv/C9hVoty6tldw6cE2pRHNGmFPdyfrc696R6JjrQ3d7HdVqGwuzfyrcaLAKD7K8TX8aehUQ==",
"requires": {
"@octokit/types": "^6.0.3",
"bottleneck": "^2.15.3"
}
},
"@octokit/plugin-throttling": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-3.5.2.tgz",
"integrity": "sha512-Eu7kfJxU8vmHqWGNszWpg+GVp2tnAfax3XQV5CkYPEE69C+KvInJXW9WajgSeW+cxYe0UVdouzCtcreGNuJo7A==",
"requires": {
"@octokit/types": "^6.0.1",
"bottleneck": "^2.15.3"
}
},
"@octokit/request": {
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
"integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
"requires": {
"@octokit/endpoint": "^6.0.1",
"@octokit/request-error": "^2.1.0",
"@octokit/types": "^6.16.1",
"is-plain-object": "^5.0.0",
"node-fetch": "^2.6.1",
"universal-user-agent": "^6.0.0"
}
},
"@octokit/request-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
"requires": {
"@octokit/types": "^6.0.3",
"deprecation": "^2.0.0",
"once": "^1.4.0"
}
},
"@octokit/rest": {
"version": "18.12.0",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
"integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
"requires": {
"@octokit/core": "^3.5.1",
"@octokit/plugin-paginate-rest": "^2.16.8",
"@octokit/plugin-request-log": "^1.0.4",
"@octokit/plugin-rest-endpoint-methods": "^5.12.0"
}
},
"@octokit/types": {
"version": "6.33.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.33.0.tgz",
"integrity": "sha512-0zffZ048M0UhthyPXQHLz4038Ak46nMWZXkzlXvXB/M/L1jYPBceq4iZj4qjKVrvveaJrrgKdJ9+3yUuITfcCw==",
"requires": {
"@octokit/openapi-types": "^11.1.0"
}
},
"before-after-hook": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
"integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ=="
},
"bottleneck": {
"version": "2.19.5",
"resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
"integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="
},
"deprecation": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
},
"is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
},
"node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"requires": {
"whatwg-url": "^5.0.0"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
"wrappy": "1"
}
},
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
},
"universal-user-agent": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
"integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w=="
},
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
},
"whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
"requires": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
}
}
}
@@ -1,17 +0,0 @@
{
"name": "generate-release-notes",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"@octokit/plugin-retry": "^3.0.9",
"@octokit/plugin-throttling": "^3.5.2",
"@octokit/rest": "^18.12.0"
}
}
@@ -1,49 +0,0 @@
import os
import shutil
tag = os.environ['TAG_VAL']
scan_dir = os.environ['SCAN_DIR']
output_dir = os.environ['OUT_DIR']
accepted_exts = ["AppImage", "flatpak", "tar.xz", "7z"]
for dir_name in os.listdir(scan_dir):
asset_name = "pcsx2-{}".format(tag)
if "macos" in dir_name.lower():
asset_name += "-macos"
elif "linux" in dir_name.lower():
if "flatpak" in dir_name.lower():
asset_name += "-linux-flatpak-x64"
else:
asset_name += "-linux-appimage-x64"
elif "windows" in dir_name.lower():
asset_name += "-windows-x64"
else:
continue;
if "avx2" in dir_name.lower():
asset_name += "-AVX2"
elif "sse4" in dir_name.lower():
asset_name += "-SSE4"
asset_name += "-Qt"
if "symbols" in dir_name.lower():
asset_name += "-symbols"
print(asset_name)
dir_handled = False
for file in os.listdir(os.path.join(scan_dir, dir_name)):
for ext in accepted_exts:
if file.endswith(ext):
dir_handled = True
print("Moving {} to out dir".format(file))
shutil.move(os.path.join(scan_dir, dir_name, file), os.path.join(output_dir, asset_name + "." + ext))
break
if dir_handled:
break
if not dir_handled:
print("Could not find asset in directory when one was expected")
exit(1)
@@ -1,162 +0,0 @@
@echo off
setlocal enabledelayedexpansion
echo Setting environment...
if exist "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" (
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
) else if exist "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat" (
call "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat"
) else (
echo Visual Studio 2022 not found.
goto error
)
set SEVENZIP="C:\Program Files\7-Zip\7z.exe"
if defined DEBUG (
echo DEBUG=%DEBUG%
) else (
set DEBUG=1
)
pushd %~dp0
set "SCRIPTDIR=%CD%"
cd ..\..\..\..
mkdir deps-build
cd deps-build || goto error
set "BUILDDIR=%CD%"
cd ..
mkdir deps
cd deps || goto error
set "INSTALLDIR=%CD%"
popd
echo SCRIPTDIR=%SCRIPTDIR%
echo BUILDDIR=%BUILDDIR%
echo INSTALLDIR=%INSTALLDIR%
cd "%BUILDDIR%"
set QT=6.6.1
set QTMINOR=6.6
set SDL=SDL2-2.28.5
call :downloadfile "%SDL%.zip" "https://libsdl.org/release/%SDL%.zip" 97bd14ee0ec67494d2b93f1a4f7da2bf891103c57090d96fdcc2b019d885c76a || goto error
call :downloadfile "qtbase-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtbase-everywhere-src-%QT%.zip" 818f92518d1a89ee98ae818891a7d2f0e41aa45b933d55215da2df6d5459428e || goto error
call :downloadfile "qtimageformats-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtimageformats-everywhere-src-%QT%.zip" 03f01042f86b4dbf7329a179f20835817c660a183178c11570cc0535b3c3ba58 || goto error
call :downloadfile "qtsvg-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qtsvg-everywhere-src-%QT%.zip" d44d5ead8d4682f54c91687b5e32f2735f086419e3889e05609feae1a7f02da9 || goto error
call :downloadfile "qttools-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttools-everywhere-src-%QT%.zip" a17eba4e1c00dbd62c13d708c2bc918c2954b2b25a94d3c05e891d62e8f187c8 || goto error
call :downloadfile "qttranslations-everywhere-src-%QT%.zip" "https://download.qt.io/official_releases/qt/%QTMINOR%/%QT%/submodules/qttranslations-everywhere-src-%QT%.zip" e5ccf0eefd6b1ef9604fdf57f6d16ad8484d07fb141ca3a2d9c3f1771296ae25 || goto error
if %DEBUG%==1 (
echo Building debug and release libraries...
) else (
echo Building release libraries...
)
echo Building SDL...
rmdir /S /Q "%SDL%"
%SEVENZIP% x "%SDL%.zip" || goto error
cd "%SDL%" || goto error
if %DEBUG%==1 (
cmake -B build-debug -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DSDL_SHARED=ON -DSDL_STATIC=OFF -G Ninja || goto error
cmake --build build-debug --parallel || goto error
ninja -C build-debug install || goto error
)
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DBUILD_SHARED_LIBS=ON -DSDL_SHARED=ON -DSDL_STATIC=OFF -G Ninja || goto error
cmake --build build --parallel || goto error
ninja -C build install || goto error
cd .. || goto error
if %DEBUG%==1 (
set QTBUILDSPEC=-DCMAKE_CONFIGURATION_TYPES="Release;Debug" -G "Ninja Multi-Config"
) else (
set QTBUILDSPEC=-DCMAKE_BUILD_TYPE=Release -G Ninja
)
echo Building Qt base...
rmdir /S /Q "qtbase-everywhere-src-%QT%"
%SEVENZIP% x "qtbase-everywhere-src-%QT%.zip" || goto error
cd "qtbase-everywhere-src-%QT%" || goto error
cmake -B build -DFEATURE_sql=OFF -DCMAKE_INSTALL_PREFIX="%INSTALLDIR%" -DINPUT_gui=yes -DINPUT_widgets=yes -DINPUT_ssl=yes -DINPUT_openssl=no -DINPUT_schannel=yes %QTBUILDSPEC% || goto error
cmake --build build --parallel || goto error
ninja -C build install || goto error
cd .. || goto error
echo Building Qt SVG...
rmdir /S /Q "qtsvg-everywhere-src-%QT%"
%SEVENZIP% x "qtsvg-everywhere-src-%QT%.zip" || goto error
cd "qtsvg-everywhere-src-%QT%" || goto error
mkdir build || goto error
cd build || goto error
call "%INSTALLDIR%\bin\qt-configure-module.bat" .. || goto error
cmake --build . --parallel || goto error
ninja install || goto error
cd ..\.. || goto error
echo Building Qt Image Formats...
rmdir /S /Q "qtimageformats-everywhere-src-%QT%"
%SEVENZIP% x "qtimageformats-everywhere-src-%QT%.zip" || goto error
cd "qtimageformats-everywhere-src-%QT%" || goto error
mkdir build || goto error
cd build || goto error
call "%INSTALLDIR%\bin\qt-configure-module.bat" .. || goto error
cmake --build . --parallel || goto error
ninja install || goto error
cd ..\.. || goto error
echo Building Qt Tools...
rmdir /S /Q "qtimageformats-everywhere-src-%QT%"
%SEVENZIP% x "qttools-everywhere-src-%QT%.zip" || goto error
cd "qttools-everywhere-src-%QT%" || goto error
mkdir build || goto error
cd build || goto error
call "%INSTALLDIR%\bin\qt-configure-module.bat" .. -- -DFEATURE_assistant=OFF -DFEATURE_clang=OFF -DFEATURE_designer=OFF -DFEATURE_kmap2qmap=OFF -DFEATURE_pixeltool=OFF -DFEATURE_pkg_config=OFF -DFEATURE_qev=OFF -DFEATURE_qtattributionsscanner=OFF -DFEATURE_qtdiag=OFF -DFEATURE_qtplugininfo=OFF || goto error
cmake --build . --parallel || goto error
ninja install || goto error
cd ..\.. || goto error
echo Building Qt Translations...
rmdir /S /Q "qttranslations-everywhere-src-%QT%"
%SEVENZIP% x "qttranslations-everywhere-src-%QT%.zip" || goto error
cd "qttranslations-everywhere-src-%QT%" || goto error
mkdir build || goto error
cd build || goto error
call "%INSTALLDIR%\bin\qt-configure-module.bat" .. || goto error
cmake --build . --parallel || goto error
ninja install || goto error
cd ..\.. || goto error
echo Cleaning up...
cd ..
rd /S /Q deps-build
echo Exiting with success.
exit 0
:error
echo Failed with error #%errorlevel%.
pause
exit %errorlevel%
:downloadfile
if not exist "%~1" (
echo Downloading %~1 from %~2...
curl -L -o "%~1" "%~2" || goto error
)
rem based on https://gist.github.com/gsscoder/e22daefaff9b5d8ac16afb070f1a7971
set idx=0
for /f %%F in ('certutil -hashfile "%~1" SHA256') do (
set "out!idx!=%%F"
set /a idx += 1
)
set filechecksum=%out1%
if /i %~3==%filechecksum% (
echo Validated %~1.
exit /B 0
) else (
echo Expected %~3 got %filechecksum%.
exit /B 1
)
@@ -1,19 +0,0 @@
$filterFiles = Get-ChildItem $PWD -name -recurse *.vcxproj.filters
$failed = $FALSE
foreach ($file in $filterFiles) {
# Skip 3rdparty files
if ($file -NotMatch "^3rdparty") {
$expression = "python -c `"import sys, xml.dom.minidom as d; d.parse(sys.argv[1])`" $($file)"
$expression += ';$LastExitCode'
$exitCode = Invoke-Expression $expression
if($exitCode -ne 0){
Write-Host -foregroundColor red "$($file) - Invalid VS filters file. Likely missing tags"
$failed = $TRUE
}
}
}
if ($failed) {
exit 1
}
-27
View File
@@ -1,27 +0,0 @@
# Runs steps to triage an incoming Pull Request, for example - applying labels.
name: 🤔 Pull Request Triage
on: pull_request_target
jobs:
triage:
if: github.repository == 'PCSX2/pcsx2'
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@main
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- uses: xTVaser/first-interaction@v1.2.4
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
debug-mode: false
pr-message: |-
## Thank you for submitting a contribution to PCSX2
As this is your first pull request, [please be aware of the contributing guidelines](https://github.com/PCSX2/pcsx2/blob/master/.github/CONTRIBUTING.md).
Additionally, as per recent changes in GitHub Actions, your pull request will need to be approved by a maintainer before GitHub Actions can run against it. [You can find more information about this change here.](https://github.blog/2021-04-22-github-actions-update-helping-maintainers-combat-bad-actors/)
Please be patient until this happens. In the meantime if you'd like to confirm the builds are passing, you have the option of opening a PR on your own fork, just make sure your fork's master branch is up to date!
pr-labels: "First Time Contribution"
@@ -1,84 +0,0 @@
name: 🖥️ Windows Builds
on:
push:
branches-ignore:
- "l10n_master"
pull_request:
branches:
- master
jobs:
# MSBUILD
lint_vs_proj_files:
name: Lint VS Project Files
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
runs-on: windows-2019
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Verify VS Project Files
run: .github\workflows\scripts\windows\validate-vs-filters.ps1
build_qt_sse4:
needs: lint_vs_proj_files
name: "SSE4"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: "MSVC SSE4"
configuration: Release
simd: "SSE4"
secrets: inherit
build_qt_avx2:
needs: lint_vs_proj_files
name: "AVX2"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: "MSVC AVX2"
configuration: Release AVX2
secrets: inherit
build_qt_cmake:
name: "CMake"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: "CMake MSVC"
configuration: CMake
buildSystem: cmake
secrets: inherit
build_qt_clang_sse4:
needs: lint_vs_proj_files
name: "SSE4"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: "Clang SSE4"
configuration: Release Clang
simd: "SSE4"
secrets: inherit
build_qt_clang_avx2:
needs: lint_vs_proj_files
name: "AVX2"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: "Clang AVX2"
configuration: Release Clang AVX2
secrets: inherit
build_qt_cmake_clang:
name: "CMake"
if: github.repository != 'PCSX2/pcsx2' || github.event_name == 'pull_request'
uses: ./.github/workflows/windows_build_qt.yml
with:
jobName: "CMake Clang"
configuration: CMake
buildSystem: cmake
cmakeFlags: -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DPCSX2_EXE_NAME=pcsx2-qt-clang
secrets: inherit
-142
View File
@@ -1,142 +0,0 @@
name: Windows Build Steps - Qt
on:
workflow_call:
inputs:
jobName:
required: true
type: string
os:
required: false
type: string
default: windows-2022
platform:
required: false
type: string
default: x64
configuration:
required: true
type: string
simd:
required: false
type: string
default: AVX2
buildSystem:
required: false
type: string
default: msbuild
cmakeFlags:
required: false
type: string
default: ""
patchesUrl:
required: false
type: string
default: https://github.com/PCSX2/pcsx2_patches/releases/latest/download
fetchTags:
required: false
type: boolean
default: false
jobs:
build_windows_qt:
name: ${{ inputs.jobName }}
runs-on: ${{ inputs.os }}
# Set some sort of timeout in the event of run-away builds. We are limited on concurrent jobs so, get rid of them.
timeout-minutes: 90
env:
POWERSHELL_TELEMETRY_OPTOUT: 1
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
submodules: recursive
# actions/checkout elides tags, fetch them primarily for releases
- name: Fetch Tags
if: ${{ inputs.fetchTags }}
run: git fetch --tags --no-recurse-submodules
- name: Prepare Artifact Metadata
id: artifact-metadata
shell: bash
env:
OS: windows
BUILD_SYSTEM: ${{ inputs.buildSystem }}
ARCH: ${{ inputs.platform }}
SIMD: ${{ inputs.simd }}
EVENT_NAME: ${{ github.event_name }}
PR_TITLE: ${{ github.event.pull_request.title }}
PR_NUM: ${{ github.event.pull_request.number }}
PR_SHA: ${{ github.event.pull_request.head.sha }}
run: ./.github/workflows/scripts/common/name-artifacts.sh
- name: Setup msbuild
if: inputs.configuration != 'CMake'
uses: microsoft/setup-msbuild@v1
- name: Download patches
shell: cmd
run: |
cd bin/resources
aria2c -Z "${{ inputs.patchesUrl }}/patches.zip"
- name: Cache Dependencies
id: cache-deps
uses: actions/cache@v3
with:
path: deps
key: ${{ inputs.os }} ${{ inputs.platform }} deps ${{ hashFiles('.github/workflows/scripts/windows/build-dependencies.bat') }}
- name: Build Dependencies
if: steps.cache-deps.outputs.cache-hit != 'true'
env:
DEBUG: 0
run: .github/workflows/scripts/windows/build-dependencies.bat
- name: Generate CMake
if: inputs.configuration == 'CMake'
id: cmake
shell: cmd
run: |
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
cmake . -B build ${{ inputs.cmakeFlags }} "-DCMAKE_PREFIX_PATH=%cd%\deps" -DQT_BUILD=ON -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=ON -DDISABLE_ADVANCE_SIMD=ON -G Ninja
- name: Build PCSX2
shell: cmd
run: |
if "${{ inputs.configuration }}"=="CMake" (
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
cmake --build build --config Release || exit /b
cmake --install build --config Release || exit /b
) else (
msbuild "PCSX2_qt.sln" /m /v:m /p:Configuration="${{ inputs.configuration }}" /p:Platform="${{ inputs.platform }}"
)
- name: Run Tests
if: inputs.configuration == 'CMake'
shell: cmd
run: |
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
cmake --build build --config Release --target unittests
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: ${{ steps.artifact-metadata.outputs.artifact-name }}
path: |
./bin
!./bin/**/*.bsc
!./bin/**/*.exp
!./bin/**/*.ilk
!./bin/**/*.iobj
!./bin/**/*.ipdb
!./bin/**/*.pdb
!./bin/**/*.lib
- name: Upload artifact - with symbols
uses: actions/upload-artifact@v3
with:
name: ${{ steps.artifact-metadata.outputs.artifact-name }}-symbols
path: ./bin/**/*.pdb
-93
View File
@@ -1,93 +0,0 @@
.*.swp
.*.swn
.*.swo
*.suo
*.ncb
*.sdf
*.opensdf
*.user
*.log
*.dsp
*.dsw
*.bsc
*.aps
*.exe
*.wav
*.trace
*.dump
*.asm
*.VC.db
*.VC.VC.opendb
_ReSharper.*
pcsx2.snapshot_*
svnrev.h
/build*
/obj-*
*.obj
.DS_Store
Thumbs.db
Debug.txt
install_log.txt
bad_shader_*
crash-*.txt
Debug
Release
Devel
oprofile_data/
# Recording Specific Ignores (pcsx2-rr)
*.p2s
*.p2m2
*.p2m2_backup
*.p2m2_SaveState.p2s
# Visual Studio upgrades
/Backup*
/UpgradeLog*.htm
/.vscode*
/bin/**/*.dll
/bin/**/*.dmp
/bin/**/*.exp
/bin/**/*.ilk
/bin/**/*.lib
/bin/**/*.pdb
/bin/pcsx2*
/bin/qt.conf
/bin/bios
/bin/cache
/bin/cheats
/bin/covers
/bin/dumps
/bin/gamesettings
/bin/help
/bin/inis
/bin/logs
/bin/memcards
/bin/plugins
/bin/snaps
/bin/sstates
/bin/textures
/bin/translations
/bin/inputprofiles
/deps
/ipch
!/3rdparty/libjpeg/change.log
/tools/bin
.vs
/out/build/x64-Debug (default)
CMakeSettings.json
/ci-artifacts/
/out/
-32
View File
@@ -1,32 +0,0 @@
[submodule "3rdparty/xz/xz"]
path = 3rdparty/xz/xz
url = https://github.com/PCSX2/xz.git
[submodule "3rdparty/gtest"]
path = 3rdparty/gtest
url = https://github.com/google/googletest.git
[submodule "3rdparty/fmt/fmt"]
path = 3rdparty/fmt/fmt
url = https://github.com/fmtlib/fmt.git
[submodule "3rdparty/wil"]
path = 3rdparty/wil
url = https://github.com/microsoft/wil.git
branch = master
[submodule "3rdparty/rapidyaml/rapidyaml"]
path = 3rdparty/rapidyaml/rapidyaml
url = https://github.com/biojppm/rapidyaml.git
branch = master
[submodule "3rdparty/glslang/glslang"]
path = 3rdparty/glslang/glslang
url = https://github.com/KhronosGroup/glslang.git
[submodule "3rdparty/vulkan-headers"]
path = 3rdparty/vulkan-headers
url = https://github.com/KhronosGroup/Vulkan-Headers.git
[submodule "3rdparty/zstd/zstd"]
path = 3rdparty/zstd/zstd
url = https://github.com/facebook/zstd.git
[submodule "3rdparty/rcheevos/rcheevos"]
path = 3rdparty/rcheevos/rcheevos
url = https://github.com/RetroAchievements/rcheevos.git
[submodule "3rdparty/libwebp/libwebp"]
path = 3rdparty/libwebp/libwebp
url = https://github.com/webmproject/libwebp
-8
View File
@@ -1,8 +0,0 @@
overrides:
- files: "**/GameIndex.yaml"
options:
tabWidth: 2
useTabs: false
quoteProps: consistent
endOfLine: auto
proseWrap: preserve
-21
View File
@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
<OutDir>$(SolutionDir)build\3rdparty\lib-$(PlatformName)-$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)build\3rdparty\obj-$(ProjectName)-$(PlatformName)-$(Configuration)\</IntDir>
<ExtensionsToDeleteOnClean>*.bsc;*.idb;*.sbr;*.res;*.pch;*.pdb;*.obj;*.tlb;*.tli;*.tlh;*.tmp;*.rsp;*.pgc;*.pgd;*.meta;$(TargetPath);$(ExtensionsToDeleteOnClean)</ExtensionsToDeleteOnClean>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<AdditionalIncludeDirectories>$(ProjectDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__WIN32__;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_HAS_EXCEPTIONS=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<FunctionLevelLinking>true</FunctionLevelLinking>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<ExceptionHandling>false</ExceptionHandling>
<WarningLevel>TurnOffAllWarnings</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
</ClCompile>
</ItemDefinitionGroup>
</Project>
-18
View File
@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="UserMacros">
<ProjectRootDir>$(ProjectDir)</ProjectRootDir>
<SvnRootDir>$(ProjectRootDir)\..\..</SvnRootDir>
</PropertyGroup>
<PropertyGroup>
<_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
</PropertyGroup>
<ItemGroup>
<BuildMacro Include="ProjectRootDir">
<Value>$(ProjectRootDir)</Value>
</BuildMacro>
<BuildMacro Include="SvnRootDir">
<Value>$(SvnRootDir)</Value>
</BuildMacro>
</ItemGroup>
</Project>
-282
View File
@@ -1,282 +0,0 @@
#ifndef __khrplatform_h_
#define __khrplatform_h_
/*
** Copyright (c) 2008-2018 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Khronos platform-specific types and definitions.
*
* The master copy of khrplatform.h is maintained in the Khronos EGL
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
* The last semantic modification to khrplatform.h was at commit ID:
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
* group so that they can be included in future versions of this file.
* Please submit changes by filing pull requests or issues on
* the EGL Registry repository linked above.
*
*
* See the Implementer's Guidelines for information about where this file
* should be located on your system and for more details of its use:
* http://www.khronos.org/registry/implementers_guide.pdf
*
* This file should be included as
* #include <KHR/khrplatform.h>
* by Khronos client API header files that use its types and defines.
*
* The types in khrplatform.h should only be used to define API-specific types.
*
* Types defined in khrplatform.h:
* khronos_int8_t signed 8 bit
* khronos_uint8_t unsigned 8 bit
* khronos_int16_t signed 16 bit
* khronos_uint16_t unsigned 16 bit
* khronos_int32_t signed 32 bit
* khronos_uint32_t unsigned 32 bit
* khronos_int64_t signed 64 bit
* khronos_uint64_t unsigned 64 bit
* khronos_intptr_t signed same number of bits as a pointer
* khronos_uintptr_t unsigned same number of bits as a pointer
* khronos_ssize_t signed size
* khronos_usize_t unsigned size
* khronos_float_t signed 32 bit floating point
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
* nanoseconds
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
* khronos_boolean_enum_t enumerated boolean type. This should
* only be used as a base type when a client API's boolean type is
* an enum. Client APIs which use an integer or other type for
* booleans cannot use this as the base type for their boolean.
*
* Tokens defined in khrplatform.h:
*
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
*
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
*
* Calling convention macros defined in this file:
* KHRONOS_APICALL
* KHRONOS_APIENTRY
* KHRONOS_APIATTRIBUTES
*
* These may be used in function prototypes as:
*
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
* int arg1,
* int arg2) KHRONOS_APIATTRIBUTES;
*/
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APICALL
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
#if defined(_WIN32) && !defined(__SCITECH_SNAP__)
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
#elif defined(__ANDROID__)
# define KHRONOS_APICALL __attribute__((visibility("default")))
#else
# define KHRONOS_APICALL
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIENTRY
*-------------------------------------------------------------------------
* This follows the return type of the function and precedes the function
* name in the function prototype.
*/
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
/* Win32 but not WinCE */
# define KHRONOS_APIENTRY __stdcall
#else
# define KHRONOS_APIENTRY
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIATTRIBUTES
*-------------------------------------------------------------------------
* This follows the closing parenthesis of the function prototype arguments.
*/
#if defined (__ARMCC_2__)
#define KHRONOS_APIATTRIBUTES __softfp
#else
#define KHRONOS_APIATTRIBUTES
#endif
/*-------------------------------------------------------------------------
* basic type definitions
*-----------------------------------------------------------------------*/
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
/*
* Using <stdint.h>
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__VMS ) || defined(__sgi)
/*
* Using <inttypes.h>
*/
#include <inttypes.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
/*
* Win32
*/
typedef __int32 khronos_int32_t;
typedef unsigned __int32 khronos_uint32_t;
typedef __int64 khronos_int64_t;
typedef unsigned __int64 khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__sun__) || defined(__digital__)
/*
* Sun or Digital
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#if defined(__arch64__) || defined(_LP64)
typedef long int khronos_int64_t;
typedef unsigned long int khronos_uint64_t;
#else
typedef long long int khronos_int64_t;
typedef unsigned long long int khronos_uint64_t;
#endif /* __arch64__ */
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif 0
/*
* Hypothetical platform with no float or int64 support
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#define KHRONOS_SUPPORT_INT64 0
#define KHRONOS_SUPPORT_FLOAT 0
#else
/*
* Generic fallback
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#endif
/*
* Types that are (so far) the same on all platforms
*/
typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
#ifdef _WIN64
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#endif
#if KHRONOS_SUPPORT_FLOAT
/*
* Float type
*/
typedef float khronos_float_t;
#endif
#if KHRONOS_SUPPORT_INT64
/* Time types
*
* These types can be used to represent a time interval in nanoseconds or
* an absolute Unadjusted System Time. Unadjusted System Time is the number
* of nanoseconds since some arbitrary system event (e.g. since the last
* time the system booted). The Unadjusted System Time is an unsigned
* 64 bit value that wraps back to 0 every 584 years. Time intervals
* may be either signed or unsigned.
*/
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
typedef khronos_int64_t khronos_stime_nanoseconds_t;
#endif
/*
* Dummy value used to pad enum types to 32 bits.
*/
#ifndef KHRONOS_MAX_ENUM
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
#endif
/*
* Enumerated boolean type
*
* Values other than zero should be considered to be true. Therefore
* comparisons should not be made against KHRONOS_TRUE.
*/
typedef enum {
KHRONOS_FALSE = 0,
KHRONOS_TRUE = 1,
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
} khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */
-21
View File
@@ -1,21 +0,0 @@
# Ninja files
build.ninja
# Build objects and artifacts
deps/
build/
bin/
lib/
libs/
obj/
*.pyc
*.pyo
# System files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
-915
View File
@@ -1,915 +0,0 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.5 FATAL_ERROR)
# ---[ Setup project
PROJECT(
cpuinfo
LANGUAGES C
)
# ---[ Options.
SET(CPUINFO_LIBRARY_TYPE "default" CACHE STRING "Type of cpuinfo library (shared, static, or default) to build")
SET_PROPERTY(CACHE CPUINFO_LIBRARY_TYPE PROPERTY STRINGS default static shared)
SET(CPUINFO_RUNTIME_TYPE "default" CACHE STRING "Type of runtime library (shared, static, or default) to use")
SET_PROPERTY(CACHE CPUINFO_RUNTIME_TYPE PROPERTY STRINGS default static shared)
SET(CPUINFO_LOG_LEVEL "default" CACHE STRING "Minimum logging level (info with lower severity will be ignored)")
SET_PROPERTY(CACHE CPUINFO_LOG_LEVEL PROPERTY STRINGS default debug info warning error fatal none)
IF(ANDROID)
OPTION(CPUINFO_LOG_TO_STDIO "Log errors, warnings, and information to stdout/stderr" OFF)
ELSE()
OPTION(CPUINFO_LOG_TO_STDIO "Log errors, warnings, and information to stdout/stderr" ON)
ENDIF()
OPTION(CPUINFO_BUILD_TOOLS "Build command-line tools" OFF)
OPTION(CPUINFO_BUILD_UNIT_TESTS "Build cpuinfo unit tests" OFF)
OPTION(CPUINFO_BUILD_MOCK_TESTS "Build cpuinfo mock tests" OFF)
OPTION(CPUINFO_BUILD_BENCHMARKS "Build cpuinfo micro-benchmarks" OFF)
OPTION(CPUINFO_BUILD_PKG_CONFIG "Build pkg-config manifest" OFF)
OPTION(USE_SYSTEM_LIBS "Use system libraries instead of downloading and building them" OFF)
OPTION(USE_SYSTEM_GOOGLEBENCHMARK "Use system Google Benchmark library instead of downloading and building it" ${USE_SYSTEM_LIBS})
OPTION(USE_SYSTEM_GOOGLETEST "Use system Google Test library instead of downloading and building it" ${USE_SYSTEM_LIBS})
# ---[ CMake options
INCLUDE(GNUInstallDirs)
IF(CPUINFO_BUILD_UNIT_TESTS OR CPUINFO_BUILD_MOCK_TESTS)
ENABLE_TESTING()
ENDIF()
MACRO(CPUINFO_TARGET_ENABLE_C99 target)
SET_TARGET_PROPERTIES(${target} PROPERTIES
C_STANDARD 99
C_EXTENSIONS NO)
ENDMACRO()
MACRO(CPUINFO_TARGET_ENABLE_CXX11 target)
SET_TARGET_PROPERTIES(${target} PROPERTIES
CXX_STANDARD 14
CXX_EXTENSIONS NO)
ENDMACRO()
MACRO(CPUINFO_TARGET_RUNTIME_LIBRARY target)
IF(MSVC AND NOT CPUINFO_RUNTIME_TYPE STREQUAL "default")
IF(CPUINFO_RUNTIME_TYPE STREQUAL "shared")
TARGET_COMPILE_OPTIONS(${target} PRIVATE
"/MD$<$<CONFIG:Debug>:d>")
ELSEIF(CPUINFO_RUNTIME_TYPE STREQUAL "static")
TARGET_COMPILE_OPTIONS(${target} PRIVATE
"/MT$<$<CONFIG:Debug>:d>")
ENDIF()
ENDIF()
ENDMACRO()
# -- [ Determine whether building for Apple's desktop or mobile OSes
IF(CMAKE_SYSTEM_NAME MATCHES "^(Darwin|iOS|tvOS|watchOS)$")
SET(IS_APPLE_OS TRUE)
ELSE()
SET(IS_APPLE_OS FALSE)
ENDIF()
# -- [ Determine target processor
SET(CPUINFO_TARGET_PROCESSOR "${CMAKE_SYSTEM_PROCESSOR}")
IF(IS_APPLE_OS AND CMAKE_OSX_ARCHITECTURES MATCHES "^(x86_64|arm64.*)$")
SET(CPUINFO_TARGET_PROCESSOR "${CMAKE_OSX_ARCHITECTURES}")
ELSEIF(CMAKE_GENERATOR MATCHES "^Visual Studio " AND CMAKE_VS_PLATFORM_NAME)
IF(CMAKE_VS_PLATFORM_NAME STREQUAL "Win32")
SET(CPUINFO_TARGET_PROCESSOR "x86")
ELSEIF(CMAKE_VS_PLATFORM_NAME STREQUAL "x64")
SET(CPUINFO_TARGET_PROCESSOR "x86_64")
ELSEIF(CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64")
SET(CPUINFO_TARGET_PROCESSOR "arm64")
ELSEIF(CMAKE_VS_PLATFORM_NAME MATCHES "^(ARM64EC|arm64ec|ARM64E|arm64e)")
SET(CPUINFO_TARGET_PROCESSOR "arm64")
ELSE()
MESSAGE(FATAL_ERROR "Unsupported Visual Studio architecture \"${CMAKE_VS_PLATFORM_NAME}\"")
ENDIF()
ENDIF()
# ---[ Build flags
SET(CPUINFO_SUPPORTED_PLATFORM TRUE)
IF(NOT CMAKE_SYSTEM_PROCESSOR)
IF(NOT IOS)
MESSAGE(WARNING
"Target processor architecture is not specified. "
"cpuinfo will compile, but cpuinfo_initialize() will always fail.")
SET(CPUINFO_SUPPORTED_PLATFORM FALSE)
ENDIF()
ELSEIF(NOT CPUINFO_TARGET_PROCESSOR MATCHES "^(i[3-6]86|AMD64|x86(_64)?|armv[5-8].*|aarch64|arm64.*|ARM64.*|riscv(32|64))$")
MESSAGE(WARNING
"Target processor architecture \"${CPUINFO_TARGET_PROCESSOR}\" is not supported in cpuinfo. "
"cpuinfo will compile, but cpuinfo_initialize() will always fail.")
SET(CPUINFO_SUPPORTED_PLATFORM FALSE)
ENDIF()
IF(NOT CMAKE_SYSTEM_NAME)
MESSAGE(WARNING
"Target operating system is not specified. "
"cpuinfo will compile, but cpuinfo_initialize() will always fail.")
SET(CPUINFO_SUPPORTED_PLATFORM FALSE)
ELSEIF(NOT CMAKE_SYSTEM_NAME MATCHES "^(Windows|WindowsStore|CYGWIN|MSYS|Darwin|Linux|Android)$")
IF(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14" AND NOT IS_APPLE_OS)
MESSAGE(WARNING
"Target operating system \"${CMAKE_SYSTEM_NAME}\" is not supported in cpuinfo. "
"cpuinfo will compile, but cpuinfo_initialize() will always fail.")
SET(CPUINFO_SUPPORTED_PLATFORM FALSE)
ENDIF()
ENDIF()
IF(CPUINFO_SUPPORTED_PLATFORM)
IF(CPUINFO_BUILD_MOCK_TESTS OR CPUINFO_BUILD_UNIT_TESTS OR CPUINFO_BUILD_BENCHMARKS)
ENABLE_LANGUAGE(CXX)
ENDIF()
ENDIF()
# ---[ Download deps
SET(CONFU_DEPENDENCIES_SOURCE_DIR ${CMAKE_SOURCE_DIR}/deps
CACHE PATH "Confu-style dependencies source directory")
SET(CONFU_DEPENDENCIES_BINARY_DIR ${CMAKE_BINARY_DIR}/deps
CACHE PATH "Confu-style dependencies binary directory")
IF(CPUINFO_SUPPORTED_PLATFORM AND (CPUINFO_BUILD_MOCK_TESTS OR CPUINFO_BUILD_UNIT_TESTS))
IF(USE_SYSTEM_GOOGLETEST)
FIND_PACKAGE(GTest REQUIRED)
ELSEIF(NOT DEFINED GOOGLETEST_SOURCE_DIR)
MESSAGE(STATUS "Downloading Google Test to ${CONFU_DEPENDENCIES_SOURCE_DIR}/googletest (define GOOGLETEST_SOURCE_DIR to avoid it)")
CONFIGURE_FILE(cmake/DownloadGoogleTest.cmake "${CONFU_DEPENDENCIES_BINARY_DIR}/googletest-download/CMakeLists.txt")
EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
WORKING_DIRECTORY "${CONFU_DEPENDENCIES_BINARY_DIR}/googletest-download")
EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" --build .
WORKING_DIRECTORY "${CONFU_DEPENDENCIES_BINARY_DIR}/googletest-download")
SET(GOOGLETEST_SOURCE_DIR "${CONFU_DEPENDENCIES_SOURCE_DIR}/googletest" CACHE STRING "Google Test source directory")
ENDIF()
ENDIF()
IF(CPUINFO_SUPPORTED_PLATFORM AND CPUINFO_BUILD_BENCHMARKS)
IF(USE_SYSTEM_GOOGLEBENCHMARK)
FIND_PACKAGE(benchmark REQUIRED)
ELSEIF(NOT DEFINED GOOGLEBENCHMARK_SOURCE_DIR)
MESSAGE(STATUS "Downloading Google Benchmark to ${CONFU_DEPENDENCIES_SOURCE_DIR}/googlebenchmark (define GOOGLEBENCHMARK_SOURCE_DIR to avoid it)")
CONFIGURE_FILE(cmake/DownloadGoogleBenchmark.cmake "${CONFU_DEPENDENCIES_BINARY_DIR}/googlebenchmark-download/CMakeLists.txt")
EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
WORKING_DIRECTORY "${CONFU_DEPENDENCIES_BINARY_DIR}/googlebenchmark-download")
EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" --build .
WORKING_DIRECTORY "${CONFU_DEPENDENCIES_BINARY_DIR}/googlebenchmark-download")
SET(GOOGLEBENCHMARK_SOURCE_DIR "${CONFU_DEPENDENCIES_SOURCE_DIR}/googlebenchmark" CACHE STRING "Google Benchmark source directory")
ENDIF()
ENDIF()
# ---[ cpuinfo library
SET(CPUINFO_SRCS src/api.c src/cache.c src/init.c src/log.c)
IF(CPUINFO_SUPPORTED_PLATFORM)
IF(NOT CMAKE_SYSTEM_NAME STREQUAL "Emscripten" AND (CPUINFO_TARGET_PROCESSOR MATCHES "^(i[3-6]86|AMD64|x86(_64)?)$" OR IOS_ARCH MATCHES "^(i386|x86_64)$"))
LIST(APPEND CPUINFO_SRCS
src/x86/init.c
src/x86/info.c
src/x86/vendor.c
src/x86/uarch.c
src/x86/name.c
src/x86/topology.c
src/x86/isa.c
src/x86/cache/init.c
src/x86/cache/descriptor.c
src/x86/cache/deterministic.c)
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
LIST(APPEND CPUINFO_SRCS
src/x86/linux/init.c
src/x86/linux/cpuinfo.c)
ELSEIF(IS_APPLE_OS)
LIST(APPEND CPUINFO_SRCS src/x86/mach/init.c)
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "^(Windows|WindowsStore|CYGWIN|MSYS)$")
LIST(APPEND CPUINFO_SRCS src/x86/windows/init.c)
ENDIF()
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "^Windows" AND CPUINFO_TARGET_PROCESSOR MATCHES "^(ARM64|arm64)$")
LIST(APPEND CPUINFO_SRCS
src/arm/windows/init-by-logical-sys-info.c
src/arm/windows/init.c)
ELSEIF(CPUINFO_TARGET_PROCESSOR MATCHES "^(armv[5-8].*|aarch64|arm64.*)$" OR IOS_ARCH MATCHES "^(armv7.*|arm64.*)$")
LIST(APPEND CPUINFO_SRCS
src/arm/uarch.c
src/arm/cache.c)
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
LIST(APPEND CPUINFO_SRCS
src/arm/linux/init.c
src/arm/linux/cpuinfo.c
src/arm/linux/clusters.c
src/arm/linux/chipset.c
src/arm/linux/midr.c
src/arm/linux/hwcap.c)
IF(CMAKE_SYSTEM_PROCESSOR MATCHES "^armv[5-8]")
LIST(APPEND CPUINFO_SRCS src/arm/linux/aarch32-isa.c)
IF(CMAKE_SYSTEM_NAME STREQUAL "Android" AND ANDROID_ABI STREQUAL "armeabi")
SET_SOURCE_FILES_PROPERTIES(src/arm/linux/aarch32-isa.c PROPERTIES COMPILE_FLAGS -marm)
ENDIF()
ELSEIF(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)$")
LIST(APPEND CPUINFO_SRCS src/arm/linux/aarch64-isa.c)
ENDIF()
ELSEIF(IS_APPLE_OS AND CPUINFO_TARGET_PROCESSOR MATCHES "arm64.*")
LIST(APPEND CPUINFO_SRCS src/arm/mach/init.c)
ENDIF()
IF(CMAKE_SYSTEM_NAME STREQUAL "Android")
LIST(APPEND CPUINFO_SRCS
src/arm/android/properties.c)
ENDIF()
ELSEIF(CPUINFO_TARGET_PROCESSOR MATCHES "^(riscv(32|64))$")
LIST(APPEND CPUINFO_SRCS
src/riscv/uarch.c)
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
LIST(APPEND CPUINFO_SRCS
src/riscv/linux/init.c
src/riscv/linux/riscv-hw.c
src/riscv/linux/riscv-isa.c)
ENDIF()
ENDIF()
IF(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
LIST(APPEND CPUINFO_SRCS
src/emscripten/init.c)
ENDIF()
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
LIST(APPEND CPUINFO_SRCS
src/linux/smallfile.c
src/linux/multiline.c
src/linux/cpulist.c
src/linux/processors.c)
ELSEIF(IS_APPLE_OS)
LIST(APPEND CPUINFO_SRCS src/mach/topology.c)
ENDIF()
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
SET(CMAKE_THREAD_PREFER_PTHREAD TRUE)
SET(THREADS_PREFER_PTHREAD_FLAG TRUE)
FIND_PACKAGE(Threads REQUIRED)
ENDIF()
ENDIF()
IF(CPUINFO_LIBRARY_TYPE STREQUAL "default")
ADD_LIBRARY(cpuinfo ${CPUINFO_SRCS})
ELSEIF(CPUINFO_LIBRARY_TYPE STREQUAL "shared")
ADD_LIBRARY(cpuinfo SHARED ${CPUINFO_SRCS})
ELSEIF(CPUINFO_LIBRARY_TYPE STREQUAL "static")
ADD_LIBRARY(cpuinfo STATIC ${CPUINFO_SRCS})
ELSE()
MESSAGE(FATAL_ERROR "Unsupported library type ${CPUINFO_LIBRARY_TYPE}")
ENDIF()
ADD_LIBRARY(cpuinfo_internals STATIC ${CPUINFO_SRCS})
CPUINFO_TARGET_ENABLE_C99(cpuinfo)
CPUINFO_TARGET_ENABLE_C99(cpuinfo_internals)
CPUINFO_TARGET_RUNTIME_LIBRARY(cpuinfo)
IF(CMAKE_SYSTEM_NAME MATCHES "^(Windows|WindowsStore|CYGWIN|MSYS)$")
# Target Windows 7+ API
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE _WIN32_WINNT=0x0601 _CRT_SECURE_NO_WARNINGS)
TARGET_COMPILE_DEFINITIONS(cpuinfo_internals PRIVATE _WIN32_WINNT=0x0601 _CRT_SECURE_NO_WARNINGS)
# Explicitly link Kernel32 for UWP build
if(CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
TARGET_LINK_LIBRARIES(cpuinfo PUBLIC Kernel32)
endif()
ENDIF()
IF(ANDROID AND NOT CPUINFO_LOG_TO_STDIO)
TARGET_LINK_LIBRARIES(cpuinfo PRIVATE "log")
ENDIF()
SET_TARGET_PROPERTIES(cpuinfo PROPERTIES PUBLIC_HEADER include/cpuinfo.h)
TARGET_INCLUDE_DIRECTORIES(cpuinfo BEFORE PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
TARGET_INCLUDE_DIRECTORIES(cpuinfo BEFORE PRIVATE src)
TARGET_INCLUDE_DIRECTORIES(cpuinfo_internals BEFORE PUBLIC include src)
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE "CPUINFO_LOG_TO_STDIO=$<BOOL:${CPUINFO_LOG_TO_STDIO}>")
IF(CPUINFO_LOG_LEVEL STREQUAL "default")
# default logging level: error (subject to change)
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE "CPUINFO_LOG_LEVEL=2")
ELSEIF(CPUINFO_LOG_LEVEL STREQUAL "debug")
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE "CPUINFO_LOG_LEVEL=5")
ELSEIF(CPUINFO_LOG_LEVEL STREQUAL "info")
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE "CPUINFO_LOG_LEVEL=4")
ELSEIF(CPUINFO_LOG_LEVEL STREQUAL "warning")
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE "CPUINFO_LOG_LEVEL=3")
ELSEIF(CPUINFO_LOG_LEVEL STREQUAL "error")
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE "CPUINFO_LOG_LEVEL=2")
ELSEIF(CPUINFO_LOG_LEVEL STREQUAL "fatal")
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE "CPUINFO_LOG_LEVEL=1")
ELSEIF(CPUINFO_LOG_LEVEL STREQUAL "none")
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE "CPUINFO_LOG_LEVEL=0")
ELSE()
MESSAGE(FATAL_ERROR "Unsupported logging level ${CPUINFO_LOG_LEVEL}")
ENDIF()
TARGET_COMPILE_DEFINITIONS(cpuinfo_internals PRIVATE "CPUINFO_LOG_LEVEL=0")
TARGET_COMPILE_DEFINITIONS(cpuinfo_internals PRIVATE "CPUINFO_LOG_TO_STDIO=1")
IF(CPUINFO_SUPPORTED_PLATFORM)
TARGET_COMPILE_DEFINITIONS(cpuinfo INTERFACE CPUINFO_SUPPORTED_PLATFORM=1)
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
TARGET_LINK_LIBRARIES(cpuinfo PUBLIC ${CMAKE_THREAD_LIBS_INIT})
TARGET_LINK_LIBRARIES(cpuinfo_internals PUBLIC ${CMAKE_THREAD_LIBS_INIT})
TARGET_COMPILE_DEFINITIONS(cpuinfo PRIVATE _GNU_SOURCE=1)
TARGET_COMPILE_DEFINITIONS(cpuinfo_internals PRIVATE _GNU_SOURCE=1)
ENDIF()
ELSE()
TARGET_COMPILE_DEFINITIONS(cpuinfo INTERFACE CPUINFO_SUPPORTED_PLATFORM=0)
ENDIF()
ADD_LIBRARY(${PROJECT_NAME}::cpuinfo ALIAS cpuinfo)
# support find_package(cpuinfo CONFIG)
INCLUDE(CMakePackageConfigHelpers)
GET_FILENAME_COMPONENT(CONFIG_FILE_PATH ${CMAKE_CURRENT_BINARY_DIR}/cpuinfo-config.cmake ABSOLUTE)
CONFIGURE_PACKAGE_CONFIG_FILE(
cmake/cpuinfo-config.cmake.in ${CONFIG_FILE_PATH}
INSTALL_DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME})
INSTALL(FILES ${CONFIG_FILE_PATH}
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}) # cpuinfo_DIR ${prefix}/share/cpuinfo
INSTALL(TARGETS cpuinfo
EXPORT cpuinfo-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
INSTALL(EXPORT cpuinfo-targets
NAMESPACE ${PROJECT_NAME}:: # IMPORTED cpuinfo::cpuinfo
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME})
# ---[ cpuinfo micro-benchmarks
IF(CPUINFO_SUPPORTED_PLATFORM AND CPUINFO_BUILD_BENCHMARKS)
# ---[ Build google benchmark
IF(NOT TARGET benchmark AND NOT USE_SYSTEM_GOOGLEBENCHMARK)
SET(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "")
ADD_SUBDIRECTORY(
"${GOOGLEBENCHMARK_SOURCE_DIR}"
"${CONFU_DEPENDENCIES_BINARY_DIR}/googlebenchmark")
ENDIF()
IF(CMAKE_SYSTEM_NAME MATCHES "^(Linux|Android)$")
ADD_EXECUTABLE(get-current-bench bench/get-current.cc)
TARGET_LINK_LIBRARIES(get-current-bench cpuinfo benchmark)
ENDIF()
ADD_EXECUTABLE(init-bench bench/init.cc)
TARGET_LINK_LIBRARIES(init-bench cpuinfo benchmark)
ENDIF()
IF(CPUINFO_SUPPORTED_PLATFORM)
IF(CPUINFO_BUILD_MOCK_TESTS OR CPUINFO_BUILD_UNIT_TESTS)
# ---[ Build google test
IF(NOT TARGET gtest AND NOT USE_SYSTEM_GOOGLETEST)
IF(MSVC AND NOT CPUINFO_RUNTIME_TYPE STREQUAL "static")
SET(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
ENDIF()
ADD_SUBDIRECTORY(
"${GOOGLETEST_SOURCE_DIR}"
"${CONFU_DEPENDENCIES_BINARY_DIR}/googletest")
ENDIF()
ENDIF()
ENDIF()
# ---[ cpuinfo mock library and mock tests
IF(CPUINFO_SUPPORTED_PLATFORM AND CPUINFO_BUILD_MOCK_TESTS)
SET(CPUINFO_MOCK_SRCS "${CPUINFO_SRCS}")
IF(CPUINFO_TARGET_PROCESSOR MATCHES "^(i[3-6]86|AMD64|x86(_64)?)$")
LIST(APPEND CPUINFO_MOCK_SRCS src/x86/mockcpuid.c)
ENDIF()
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
LIST(APPEND CPUINFO_MOCK_SRCS src/linux/mockfile.c)
ENDIF()
ADD_LIBRARY(cpuinfo_mock STATIC ${CPUINFO_MOCK_SRCS})
CPUINFO_TARGET_ENABLE_C99(cpuinfo_mock)
CPUINFO_TARGET_RUNTIME_LIBRARY(cpuinfo_mock)
SET_TARGET_PROPERTIES(cpuinfo_mock PROPERTIES PUBLIC_HEADER include/cpuinfo.h)
TARGET_INCLUDE_DIRECTORIES(cpuinfo_mock BEFORE PUBLIC include)
TARGET_INCLUDE_DIRECTORIES(cpuinfo_mock BEFORE PRIVATE src)
TARGET_COMPILE_DEFINITIONS(cpuinfo_mock PUBLIC "CPUINFO_MOCK=1")
TARGET_COMPILE_DEFINITIONS(cpuinfo_mock PRIVATE "CPUINFO_LOG_LEVEL=5")
TARGET_COMPILE_DEFINITIONS(cpuinfo_mock PRIVATE "CPUINFO_LOG_TO_STDIO=1")
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
TARGET_LINK_LIBRARIES(cpuinfo_mock PUBLIC ${CMAKE_THREAD_LIBS_INIT})
TARGET_COMPILE_DEFINITIONS(cpuinfo_mock PRIVATE _GNU_SOURCE=1)
ENDIF()
IF(CMAKE_SYSTEM_NAME STREQUAL "Android" AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv5te|armv7-a)$")
ADD_EXECUTABLE(atm7029b-tablet-test test/mock/atm7029b-tablet.cc)
TARGET_INCLUDE_DIRECTORIES(atm7029b-tablet-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(atm7029b-tablet-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME atm7029b-tablet-test COMMAND atm7029b-tablet-test)
ADD_EXECUTABLE(blu-r1-hd-test test/mock/blu-r1-hd.cc)
TARGET_INCLUDE_DIRECTORIES(blu-r1-hd-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(blu-r1-hd-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME blu-r1-hd-test COMMAND blu-r1-hd-test)
ADD_EXECUTABLE(galaxy-a3-2016-eu-test test/mock/galaxy-a3-2016-eu.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-a3-2016-eu-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-a3-2016-eu-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-a3-2016-eu-test COMMAND galaxy-a3-2016-eu-test)
ADD_EXECUTABLE(galaxy-a8-2016-duos-test test/mock/galaxy-a8-2016-duos.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-a8-2016-duos-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-a8-2016-duos-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-a8-2016-duos-test COMMAND galaxy-a8-2016-duos-test)
ADD_EXECUTABLE(galaxy-grand-prime-value-edition-test test/mock/galaxy-grand-prime-value-edition.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-grand-prime-value-edition-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-grand-prime-value-edition-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-grand-prime-value-edition-test COMMAND galaxy-grand-prime-value-edition-test)
ADD_EXECUTABLE(galaxy-j1-2016-test test/mock/galaxy-j1-2016.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-j1-2016-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-j1-2016-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-j1-2016-test COMMAND galaxy-j1-2016-test)
ADD_EXECUTABLE(galaxy-j5-test test/mock/galaxy-j5.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-j5-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-j5-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-j5-test COMMAND galaxy-j5-test)
ADD_EXECUTABLE(galaxy-j7-prime-test test/mock/galaxy-j7-prime.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-j7-prime-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-j7-prime-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-j7-prime-test COMMAND galaxy-j7-prime-test)
ADD_EXECUTABLE(galaxy-j7-tmobile-test test/mock/galaxy-j7-tmobile.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-j7-tmobile-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-j7-tmobile-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-j7-tmobile-test COMMAND galaxy-j7-tmobile-test)
ADD_EXECUTABLE(galaxy-j7-uae-test test/mock/galaxy-j7-uae.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-j7-uae-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-j7-uae-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-j7-uae-test COMMAND galaxy-j7-uae-test)
ADD_EXECUTABLE(galaxy-s3-us-test test/mock/galaxy-s3-us.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-s3-us-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-s3-us-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-s3-us-test COMMAND galaxy-s3-us-test)
ADD_EXECUTABLE(galaxy-s4-us-test test/mock/galaxy-s4-us.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-s4-us-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-s4-us-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-s4-us-test COMMAND galaxy-s4-us-test)
ADD_EXECUTABLE(galaxy-s5-global-test test/mock/galaxy-s5-global.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-s5-global-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-s5-global-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-s5-global-test COMMAND galaxy-s5-global-test)
ADD_EXECUTABLE(galaxy-s5-us-test test/mock/galaxy-s5-us.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-s5-us-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-s5-us-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-s5-us-test COMMAND galaxy-s5-us-test)
ADD_EXECUTABLE(galaxy-tab-3-7.0-test test/mock/galaxy-tab-3-7.0.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-tab-3-7.0-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-tab-3-7.0-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-tab-3-7.0-test COMMAND galaxy-tab-3-7.0-test)
ADD_EXECUTABLE(galaxy-tab-3-lite-test test/mock/galaxy-tab-3-lite.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-tab-3-lite-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-tab-3-lite-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-tab-3-lite-test COMMAND galaxy-tab-3-lite-test)
ADD_EXECUTABLE(galaxy-win-duos-test test/mock/galaxy-win-duos.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-win-duos-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-win-duos-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-win-duos-test COMMAND galaxy-win-duos-test)
ADD_EXECUTABLE(huawei-ascend-p7-test test/mock/huawei-ascend-p7.cc)
TARGET_INCLUDE_DIRECTORIES(huawei-ascend-p7-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(huawei-ascend-p7-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME huawei-ascend-p7-test COMMAND huawei-ascend-p7-test)
ADD_EXECUTABLE(huawei-honor-6-test test/mock/huawei-honor-6.cc)
TARGET_INCLUDE_DIRECTORIES(huawei-honor-6-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(huawei-honor-6-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME huawei-honor-6-test COMMAND huawei-honor-6-test)
ADD_EXECUTABLE(lenovo-a6600-plus-test test/mock/lenovo-a6600-plus.cc)
TARGET_INCLUDE_DIRECTORIES(lenovo-a6600-plus-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(lenovo-a6600-plus-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME lenovo-a6600-plus-test COMMAND lenovo-a6600-plus-test)
ADD_EXECUTABLE(lenovo-vibe-x2-test test/mock/lenovo-vibe-x2.cc)
TARGET_INCLUDE_DIRECTORIES(lenovo-vibe-x2-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(lenovo-vibe-x2-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME lenovo-vibe-x2-test COMMAND lenovo-vibe-x2-test)
ADD_EXECUTABLE(lg-k10-eu-test test/mock/lg-k10-eu.cc)
TARGET_INCLUDE_DIRECTORIES(lg-k10-eu-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(lg-k10-eu-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME lg-k10-eu-test COMMAND lg-k10-eu-test)
ADD_EXECUTABLE(lg-optimus-g-pro-test test/mock/lg-optimus-g-pro.cc)
TARGET_INCLUDE_DIRECTORIES(lg-optimus-g-pro-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(lg-optimus-g-pro-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME lg-optimus-g-pro-test COMMAND lg-optimus-g-pro-test)
ADD_EXECUTABLE(moto-e-gen1-test test/mock/moto-e-gen1.cc)
TARGET_INCLUDE_DIRECTORIES(moto-e-gen1-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(moto-e-gen1-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME moto-e-gen1-test COMMAND moto-e-gen1-test)
ADD_EXECUTABLE(moto-g-gen1-test test/mock/moto-g-gen1.cc)
TARGET_INCLUDE_DIRECTORIES(moto-g-gen1-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(moto-g-gen1-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME moto-g-gen1-test COMMAND moto-g-gen1-test)
ADD_EXECUTABLE(moto-g-gen2-test test/mock/moto-g-gen2.cc)
TARGET_INCLUDE_DIRECTORIES(moto-g-gen2-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(moto-g-gen2-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME moto-g-gen2-test COMMAND moto-g-gen2-test)
ADD_EXECUTABLE(moto-g-gen3-test test/mock/moto-g-gen3.cc)
TARGET_INCLUDE_DIRECTORIES(moto-g-gen3-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(moto-g-gen3-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME moto-g-gen3-test COMMAND moto-g-gen3-test)
ADD_EXECUTABLE(moto-g-gen4-test test/mock/moto-g-gen4.cc)
TARGET_INCLUDE_DIRECTORIES(moto-g-gen4-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(moto-g-gen4-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME moto-g-gen4-test COMMAND moto-g-gen4-test)
ADD_EXECUTABLE(moto-g-gen5-test test/mock/moto-g-gen5.cc)
TARGET_INCLUDE_DIRECTORIES(moto-g-gen5-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(moto-g-gen5-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME moto-g-gen5-test COMMAND moto-g-gen5-test)
ADD_EXECUTABLE(nexus-s-test test/mock/nexus-s.cc)
TARGET_INCLUDE_DIRECTORIES(nexus-s-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(nexus-s-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME nexus-s-test COMMAND nexus-s-test)
ADD_EXECUTABLE(nexus4-test test/mock/nexus4.cc)
TARGET_INCLUDE_DIRECTORIES(nexus4-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(nexus4-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME nexus4-test COMMAND nexus4-test)
ADD_EXECUTABLE(nexus6-test test/mock/nexus6.cc)
TARGET_INCLUDE_DIRECTORIES(nexus6-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(nexus6-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME nexus6-test COMMAND nexus6-test)
ADD_EXECUTABLE(nexus10-test test/mock/nexus10.cc)
TARGET_INCLUDE_DIRECTORIES(nexus10-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(nexus10-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME nexus10-test COMMAND nexus10-test)
ADD_EXECUTABLE(padcod-10.1-test test/mock/padcod-10.1.cc)
TARGET_INCLUDE_DIRECTORIES(padcod-10.1-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(padcod-10.1-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME padcod-10.1-test COMMAND padcod-10.1-test)
ADD_EXECUTABLE(xiaomi-redmi-2a-test test/mock/xiaomi-redmi-2a.cc)
TARGET_INCLUDE_DIRECTORIES(xiaomi-redmi-2a-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(xiaomi-redmi-2a-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME xiaomi-redmi-2a-test COMMAND xiaomi-redmi-2a-test)
ADD_EXECUTABLE(xperia-sl-test test/mock/xperia-sl.cc)
TARGET_INCLUDE_DIRECTORIES(xperia-sl-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(xperia-sl-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME xperia-sl-test COMMAND xperia-sl-test)
ENDIF()
IF(CMAKE_SYSTEM_NAME STREQUAL "Android" AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv5te|armv7-a|aarch64)$")
ADD_EXECUTABLE(alcatel-revvl-test test/mock/alcatel-revvl.cc)
TARGET_INCLUDE_DIRECTORIES(alcatel-revvl-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(alcatel-revvl-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME alcatel-revvl-test COMMAND alcatel-revvl-test)
ADD_EXECUTABLE(galaxy-a8-2018-test test/mock/galaxy-a8-2018.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-a8-2018-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-a8-2018-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-a8-2018-test COMMAND galaxy-a8-2018-test)
ADD_EXECUTABLE(galaxy-c9-pro-test test/mock/galaxy-c9-pro.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-c9-pro-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-c9-pro-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-c9-pro-test COMMAND galaxy-c9-pro-test)
ADD_EXECUTABLE(galaxy-s6-test test/mock/galaxy-s6.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-s6-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-s6-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-s6-test COMMAND galaxy-s6-test)
ADD_EXECUTABLE(galaxy-s7-us-test test/mock/galaxy-s7-us.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-s7-us-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-s7-us-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-s7-us-test COMMAND galaxy-s7-us-test)
ADD_EXECUTABLE(galaxy-s7-global-test test/mock/galaxy-s7-global.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-s7-global-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-s7-global-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-s7-global-test COMMAND galaxy-s7-global-test)
ADD_EXECUTABLE(galaxy-s8-us-test test/mock/galaxy-s8-us.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-s8-us-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-s8-us-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-s8-us-test COMMAND galaxy-s8-us-test)
ADD_EXECUTABLE(galaxy-s8-global-test test/mock/galaxy-s8-global.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-s8-global-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-s8-global-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-s8-global-test COMMAND galaxy-s8-global-test)
ADD_EXECUTABLE(galaxy-s9-us-test test/mock/galaxy-s9-us.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-s9-us-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-s9-us-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-s9-us-test COMMAND galaxy-s9-us-test)
ADD_EXECUTABLE(galaxy-s9-global-test test/mock/galaxy-s9-global.cc)
TARGET_INCLUDE_DIRECTORIES(galaxy-s9-global-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(galaxy-s9-global-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME galaxy-s9-global-test COMMAND galaxy-s9-global-test)
ADD_EXECUTABLE(huawei-mate-8-test test/mock/huawei-mate-8.cc)
TARGET_INCLUDE_DIRECTORIES(huawei-mate-8-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(huawei-mate-8-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME huawei-mate-8-test COMMAND huawei-mate-8-test)
ADD_EXECUTABLE(huawei-mate-9-test test/mock/huawei-mate-9.cc)
TARGET_INCLUDE_DIRECTORIES(huawei-mate-9-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(huawei-mate-9-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME huawei-mate-9-test COMMAND huawei-mate-9-test)
ADD_EXECUTABLE(huawei-mate-10-test test/mock/huawei-mate-10.cc)
TARGET_INCLUDE_DIRECTORIES(huawei-mate-10-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(huawei-mate-10-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME huawei-mate-10-test COMMAND huawei-mate-10-test)
ADD_EXECUTABLE(huawei-mate-20-test test/mock/huawei-mate-20.cc)
TARGET_INCLUDE_DIRECTORIES(huawei-mate-20-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(huawei-mate-20-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME huawei-mate-20-test COMMAND huawei-mate-20-test)
ADD_EXECUTABLE(huawei-p8-lite-test test/mock/huawei-p8-lite.cc)
TARGET_INCLUDE_DIRECTORIES(huawei-p8-lite-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(huawei-p8-lite-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME huawei-p8-lite-test COMMAND huawei-p8-lite-test)
ADD_EXECUTABLE(huawei-p9-lite-test test/mock/huawei-p9-lite.cc)
TARGET_INCLUDE_DIRECTORIES(huawei-p9-lite-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(huawei-p9-lite-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME huawei-p9-lite-test COMMAND huawei-p9-lite-test)
ADD_EXECUTABLE(huawei-p20-pro-test test/mock/huawei-p20-pro.cc)
TARGET_INCLUDE_DIRECTORIES(huawei-p20-pro-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(huawei-p20-pro-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME huawei-p20-pro-test COMMAND huawei-p20-pro-test)
ADD_EXECUTABLE(iconia-one-10-test test/mock/iconia-one-10.cc)
TARGET_INCLUDE_DIRECTORIES(iconia-one-10-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(iconia-one-10-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME iconia-one-10-test COMMAND iconia-one-10-test)
ADD_EXECUTABLE(meizu-pro-6-test test/mock/meizu-pro-6.cc)
TARGET_INCLUDE_DIRECTORIES(meizu-pro-6-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(meizu-pro-6-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME meizu-pro-6-test COMMAND meizu-pro-6-test)
ADD_EXECUTABLE(meizu-pro-6s-test test/mock/meizu-pro-6s.cc)
TARGET_INCLUDE_DIRECTORIES(meizu-pro-6s-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(meizu-pro-6s-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME meizu-pro-6s-test COMMAND meizu-pro-6s-test)
ADD_EXECUTABLE(meizu-pro-7-plus-test test/mock/meizu-pro-7-plus.cc)
TARGET_INCLUDE_DIRECTORIES(meizu-pro-7-plus-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(meizu-pro-7-plus-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME meizu-pro-7-plus-test COMMAND meizu-pro-7-plus-test)
ADD_EXECUTABLE(nexus5x-test test/mock/nexus5x.cc)
TARGET_INCLUDE_DIRECTORIES(nexus5x-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(nexus5x-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME nexus5x-test COMMAND nexus5x-test)
ADD_EXECUTABLE(nexus6p-test test/mock/nexus6p.cc)
TARGET_INCLUDE_DIRECTORIES(nexus6p-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(nexus6p-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME nexus6p-test COMMAND nexus6p-test)
ADD_EXECUTABLE(nexus9-test test/mock/nexus9.cc)
TARGET_INCLUDE_DIRECTORIES(nexus9-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(nexus9-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME nexus9-test COMMAND nexus9-test)
ADD_EXECUTABLE(oneplus-3t-test test/mock/oneplus-3t.cc)
TARGET_INCLUDE_DIRECTORIES(oneplus-3t-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(oneplus-3t-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME oneplus-3t-test COMMAND oneplus-3t-test)
ADD_EXECUTABLE(oneplus-5-test test/mock/oneplus-5.cc)
TARGET_INCLUDE_DIRECTORIES(oneplus-5-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(oneplus-5-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME oneplus-5-test COMMAND oneplus-5-test)
ADD_EXECUTABLE(oneplus-5t-test test/mock/oneplus-5t.cc)
TARGET_INCLUDE_DIRECTORIES(oneplus-5t-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(oneplus-5t-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME oneplus-5t-test COMMAND oneplus-5t-test)
ADD_EXECUTABLE(oppo-a37-test test/mock/oppo-a37.cc)
TARGET_INCLUDE_DIRECTORIES(oppo-a37-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(oppo-a37-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME oppo-a37-test COMMAND oppo-a37-test)
ADD_EXECUTABLE(oppo-r9-test test/mock/oppo-r9.cc)
TARGET_INCLUDE_DIRECTORIES(oppo-r9-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(oppo-r9-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME oppo-r9-test COMMAND oppo-r9-test)
ADD_EXECUTABLE(oppo-r15-test test/mock/oppo-r15.cc)
TARGET_INCLUDE_DIRECTORIES(oppo-r15-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(oppo-r15-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME oppo-r15-test COMMAND oppo-r15-test)
ADD_EXECUTABLE(pixel-test test/mock/pixel.cc)
TARGET_INCLUDE_DIRECTORIES(pixel-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(pixel-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME pixel-test COMMAND pixel-test)
ADD_EXECUTABLE(pixel-c-test test/mock/pixel-c.cc)
TARGET_INCLUDE_DIRECTORIES(pixel-c-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(pixel-c-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME pixel-c-test COMMAND pixel-c-test)
ADD_EXECUTABLE(pixel-xl-test test/mock/pixel-xl.cc)
TARGET_INCLUDE_DIRECTORIES(pixel-xl-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(pixel-xl-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME pixel-xl-test COMMAND pixel-xl-test)
ADD_EXECUTABLE(pixel-2-xl-test test/mock/pixel-2-xl.cc)
TARGET_INCLUDE_DIRECTORIES(pixel-2-xl-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(pixel-2-xl-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME pixel-2-xl-test COMMAND pixel-2-xl-test)
ADD_EXECUTABLE(xiaomi-mi-5c-test test/mock/xiaomi-mi-5c.cc)
TARGET_INCLUDE_DIRECTORIES(xiaomi-mi-5c-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(xiaomi-mi-5c-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME xiaomi-mi-5c-test COMMAND xiaomi-mi-5c-test)
ADD_EXECUTABLE(xiaomi-redmi-note-3-test test/mock/xiaomi-redmi-note-3.cc)
TARGET_INCLUDE_DIRECTORIES(xiaomi-redmi-note-3-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(xiaomi-redmi-note-3-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME xiaomi-redmi-note-3-test COMMAND xiaomi-redmi-note-3-test)
ADD_EXECUTABLE(xiaomi-redmi-note-4-test test/mock/xiaomi-redmi-note-4.cc)
TARGET_INCLUDE_DIRECTORIES(xiaomi-redmi-note-4-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(xiaomi-redmi-note-4-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME xiaomi-redmi-note-4-test COMMAND xiaomi-redmi-note-4-test)
ADD_EXECUTABLE(xperia-c4-dual-test test/mock/xperia-c4-dual.cc)
TARGET_INCLUDE_DIRECTORIES(xperia-c4-dual-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(xperia-c4-dual-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME xperia-c4-dual-test COMMAND xperia-c4-dual-test)
ENDIF()
IF(CMAKE_SYSTEM_NAME STREQUAL "Android" AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(i686|x86_64)$")
ADD_EXECUTABLE(alldocube-iwork8-test test/mock/alldocube-iwork8.cc)
TARGET_INCLUDE_DIRECTORIES(alldocube-iwork8-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(alldocube-iwork8-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME alldocube-iwork8-test COMMAND alldocube-iwork8-test)
ADD_EXECUTABLE(leagoo-t5c-test test/mock/leagoo-t5c.cc)
TARGET_INCLUDE_DIRECTORIES(leagoo-t5c-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(leagoo-t5c-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME leagoo-t5c-test COMMAND leagoo-t5c-test)
ADD_EXECUTABLE(memo-pad-7-test test/mock/memo-pad-7.cc)
TARGET_INCLUDE_DIRECTORIES(memo-pad-7-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(memo-pad-7-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME memo-pad-7-test COMMAND memo-pad-7-test)
ADD_EXECUTABLE(zenfone-c-test test/mock/zenfone-c.cc)
TARGET_INCLUDE_DIRECTORIES(zenfone-c-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(zenfone-c-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME zenfone-c-test COMMAND zenfone-c-test)
ADD_EXECUTABLE(zenfone-2-test test/mock/zenfone-2.cc)
TARGET_INCLUDE_DIRECTORIES(zenfone-2-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(zenfone-2-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME zenfone-2-test COMMAND zenfone-2-test)
ADD_EXECUTABLE(zenfone-2e-test test/mock/zenfone-2e.cc)
TARGET_INCLUDE_DIRECTORIES(zenfone-2e-test BEFORE PRIVATE test/mock)
TARGET_LINK_LIBRARIES(zenfone-2e-test PRIVATE cpuinfo_mock gtest)
ADD_TEST(NAME zenfone-2e-test COMMAND zenfone-2e-test)
ENDIF()
ENDIF()
# ---[ cpuinfo unit tests
IF(CPUINFO_SUPPORTED_PLATFORM AND CPUINFO_BUILD_UNIT_TESTS)
ADD_EXECUTABLE(init-test test/init.cc)
CPUINFO_TARGET_ENABLE_CXX11(init-test)
CPUINFO_TARGET_RUNTIME_LIBRARY(init-test)
TARGET_LINK_LIBRARIES(init-test PRIVATE cpuinfo gtest gtest_main)
ADD_TEST(NAME init-test COMMAND init-test)
IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
ADD_EXECUTABLE(get-current-test test/get-current.cc)
CPUINFO_TARGET_ENABLE_CXX11(get-current-test)
CPUINFO_TARGET_RUNTIME_LIBRARY(get-current-test)
TARGET_LINK_LIBRARIES(get-current-test PRIVATE cpuinfo gtest gtest_main)
ADD_TEST(NAME get-current-test COMMAND get-current-test)
ENDIF()
IF(CPUINFO_TARGET_PROCESSOR MATCHES "^(i[3-6]86|AMD64|x86(_64)?)$")
ADD_EXECUTABLE(brand-string-test test/name/brand-string.cc)
CPUINFO_TARGET_ENABLE_CXX11(brand-string-test)
CPUINFO_TARGET_RUNTIME_LIBRARY(brand-string-test)
TARGET_LINK_LIBRARIES(brand-string-test PRIVATE cpuinfo_internals gtest gtest_main)
ADD_TEST(NAME brand-string-test COMMAND brand-string-test)
ENDIF()
IF(CMAKE_SYSTEM_NAME STREQUAL "Android" AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv[5-8].*|aarch64)$")
ADD_LIBRARY(android_properties_interface STATIC test/name/android-properties-interface.c)
CPUINFO_TARGET_ENABLE_C99(android_properties_interface)
CPUINFO_TARGET_RUNTIME_LIBRARY(android_properties_interface)
TARGET_LINK_LIBRARIES(android_properties_interface PRIVATE cpuinfo_internals)
ADD_EXECUTABLE(chipset-test
test/name/proc-cpuinfo-hardware.cc
test/name/ro-product-board.cc
test/name/ro-board-platform.cc
test/name/ro-mediatek-platform.cc
test/name/ro-arch.cc
test/name/ro-chipname.cc
test/name/android-properties.cc)
CPUINFO_TARGET_ENABLE_CXX11(chipset-test)
CPUINFO_TARGET_RUNTIME_LIBRARY(chipset-test)
TARGET_LINK_LIBRARIES(chipset-test PRIVATE android_properties_interface gtest gtest_main)
ADD_TEST(NAME chipset-test COMMAND chipset-test)
ADD_EXECUTABLE(cache-test test/arm-cache.cc)
CPUINFO_TARGET_ENABLE_CXX11(cache-test)
CPUINFO_TARGET_RUNTIME_LIBRARY(cache-test)
TARGET_COMPILE_DEFINITIONS(cache-test PRIVATE __STDC_LIMIT_MACROS=1 __STDC_CONSTANT_MACROS=1)
TARGET_LINK_LIBRARIES(cache-test PRIVATE cpuinfo_internals gtest gtest_main)
ADD_TEST(NAME cache-test COMMAND cache-test)
ENDIF()
ENDIF()
# ---[ Helper and debug tools
IF(CPUINFO_SUPPORTED_PLATFORM AND CPUINFO_BUILD_TOOLS)
ADD_EXECUTABLE(isa-info tools/isa-info.c)
CPUINFO_TARGET_ENABLE_C99(isa-info)
CPUINFO_TARGET_RUNTIME_LIBRARY(isa-info)
TARGET_LINK_LIBRARIES(isa-info PRIVATE cpuinfo)
INSTALL(TARGETS isa-info RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
ADD_EXECUTABLE(cpu-info tools/cpu-info.c)
CPUINFO_TARGET_ENABLE_C99(cpu-info)
CPUINFO_TARGET_RUNTIME_LIBRARY(cpu-info)
TARGET_LINK_LIBRARIES(cpu-info PRIVATE cpuinfo)
INSTALL(TARGETS cpu-info RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
ADD_EXECUTABLE(cache-info tools/cache-info.c)
CPUINFO_TARGET_ENABLE_C99(cache-info)
CPUINFO_TARGET_RUNTIME_LIBRARY(cache-info)
TARGET_LINK_LIBRARIES(cache-info PRIVATE cpuinfo)
INSTALL(TARGETS cache-info RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
IF(CMAKE_SYSTEM_NAME MATCHES "^(Android|Linux)$" AND CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv[5-8].*|aarch64)$")
ADD_EXECUTABLE(auxv-dump tools/auxv-dump.c)
CPUINFO_TARGET_ENABLE_C99(auxv-dump)
CPUINFO_TARGET_RUNTIME_LIBRARY(auxv-dump)
TARGET_LINK_LIBRARIES(auxv-dump PRIVATE ${CMAKE_DL_LIBS} cpuinfo)
ADD_EXECUTABLE(cpuinfo-dump tools/cpuinfo-dump.c)
CPUINFO_TARGET_ENABLE_C99(cpuinfo-dump)
CPUINFO_TARGET_RUNTIME_LIBRARY(cpuinfo-dump)
ENDIF()
IF(CPUINFO_TARGET_PROCESSOR MATCHES "^(i[3-6]86|AMD64|x86(_64)?)$")
ADD_EXECUTABLE(cpuid-dump tools/cpuid-dump.c)
CPUINFO_TARGET_ENABLE_C99(cpuid-dump)
CPUINFO_TARGET_RUNTIME_LIBRARY(cpuid-dump)
TARGET_INCLUDE_DIRECTORIES(cpuid-dump BEFORE PRIVATE src)
TARGET_INCLUDE_DIRECTORIES(cpuid-dump BEFORE PRIVATE include)
INSTALL(TARGETS cpuid-dump RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
ENDIF()
ENDIF()
# ---[ pkg-config manifest. This is mostly from JsonCpp...
IF(CPUINFO_BUILD_PKG_CONFIG)
FUNCTION(JOIN_PATHS joined_path first_path_segment)
SET(temp_path "${first_path_segment}")
FOREACH(current_segment IN LISTS ARGN)
IF(NOT ("${current_segment}" STREQUAL ""))
IF(IS_ABSOLUTE "${current_segment}")
SET(temp_path "${current_segment}")
ELSE()
SET(temp_path "${temp_path}/${current_segment}")
ENDIF()
ENDIF()
ENDFOREACH()
SET(${joined_path} "${temp_path}" PARENT_SCOPE)
ENDFUNCTION()
JOIN_PATHS(libdir_for_pc_file "\${exec_prefix}" "${CMAKE_INSTALL_LIBDIR}")
JOIN_PATHS(includedir_for_pc_file "\${prefix}" "${CMAKE_INSTALL_INCLUDEDIR}")
CONFIGURE_FILE(
"libcpuinfo.pc.in"
"libcpuinfo.pc"
@ONLY)
INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/libcpuinfo.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
ENDIF()
-27
View File
@@ -1,27 +0,0 @@
Copyright (c) 2019 Google LLC
Copyright (c) 2017-2018 Facebook Inc.
Copyright (C) 2012-2017 Georgia Institute of Technology
Copyright (C) 2010-2012 Marat Dukhan
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-318
View File
@@ -1,318 +0,0 @@
# CPU INFOrmation library
[![BSD (2 clause) License](https://img.shields.io/badge/License-BSD%202--Clause%20%22Simplified%22%20License-blue.svg)](https://github.com/pytorch/cpuinfo/blob/master/LICENSE)
[![Linux/Mac build status](https://img.shields.io/travis/pytorch/cpuinfo.svg)](https://travis-ci.org/pytorch/cpuinfo)
[![Windows build status](https://ci.appveyor.com/api/projects/status/g5khy9nr0xm458t7/branch/master?svg=true)](https://ci.appveyor.com/project/MaratDukhan/cpuinfo/branch/master)
cpuinfo is a library to detect essential for performance optimization information about host CPU.
## Features
- **Cross-platform** availability:
- Linux, Windows, macOS, Android, and iOS operating systems
- x86, x86-64, ARM, and ARM64 architectures
- Modern **C/C++ interface**
- Thread-safe
- No memory allocation after initialization
- No exceptions thrown
- Detection of **supported instruction sets**, up to AVX512 (x86) and ARMv8.3 extensions
- Detection of SoC and core information:
- **Processor (SoC) name**
- Vendor and **microarchitecture** for each CPU core
- ID (**MIDR** on ARM, **CPUID** leaf 1 EAX value on x86) for each CPU core
- Detection of **cache information**:
- Cache type (instruction/data/unified), size and line size
- Cache associativity
- Cores and logical processors (hyper-threads) sharing the cache
- Detection of **topology information** (relative between logical processors, cores, and processor packages)
- Well-tested **production-quality** code:
- 60+ mock tests based on data from real devices
- Includes work-arounds for common bugs in hardware and OS kernels
- Supports systems with heterogenous cores, such as **big.LITTLE** and Max.Med.Min
- Permissive **open-source** license (Simplified BSD)
## Examples
Log processor name:
```c
cpuinfo_initialize();
printf("Running on %s CPU\n", cpuinfo_get_package(0)->name);
```
Detect if target is a 32-bit or 64-bit ARM system:
```c
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
/* 32-bit ARM-specific code here */
#endif
```
Check if the host CPU supports ARM NEON
```c
cpuinfo_initialize();
if (cpuinfo_has_arm_neon()) {
neon_implementation(arguments);
}
```
Check if the host CPU supports x86 AVX
```c
cpuinfo_initialize();
if (cpuinfo_has_x86_avx()) {
avx_implementation(arguments);
}
```
Check if the thread runs on a Cortex-A53 core
```c
cpuinfo_initialize();
switch (cpuinfo_get_current_core()->uarch) {
case cpuinfo_uarch_cortex_a53:
cortex_a53_implementation(arguments);
break;
default:
generic_implementation(arguments);
break;
}
```
Get the size of level 1 data cache on the fastest core in the processor (e.g. big core in big.LITTLE ARM systems):
```c
cpuinfo_initialize();
const size_t l1_size = cpuinfo_get_processor(0)->cache.l1d->size;
```
Pin thread to cores sharing L2 cache with the current core (Linux or Android)
```c
cpuinfo_initialize();
cpu_set_t cpu_set;
CPU_ZERO(&cpu_set);
const struct cpuinfo_cache* current_l2 = cpuinfo_get_current_processor()->cache.l2;
for (uint32_t i = 0; i < current_l2->processor_count; i++) {
CPU_SET(cpuinfo_get_processor(current_l2->processor_start + i)->linux_id, &cpu_set);
}
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpu_set);
```
## Use via pkg-config
If you would like to provide your project's build environment with the necessary compiler and linker flags in a portable manner, the library by default when built enables `CPUINFO_BUILD_PKG_CONFIG` and will generate a [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/) manifest (_libcpuinfo.pc_). Here are several examples of how to use it:
### Command Line
If you used your distro's package manager to install the library, you can verify that it is available to your build environment like so:
```console
$ pkg-config --cflags --libs libcpuinfo
-I/usr/include/x86_64-linux-gnu/ -L/lib/x86_64-linux-gnu/ -lcpuinfo
```
If you have installed the library from source into a non-standard prefix, pkg-config may need help finding it:
```console
$ PKG_CONFIG_PATH="/home/me/projects/cpuinfo/prefix/lib/pkgconfig/:$PKG_CONFIG_PATH" pkg-config --cflags --libs libcpuinfo
-I/home/me/projects/cpuinfo/prefix/include -L/home/me/projects/cpuinfo/prefix/lib -lcpuinfo
```
### GNU Autotools
To [use](https://autotools.io/pkgconfig/pkg_check_modules.html) with the GNU Autotools include the following snippet in your project's `configure.ac`:
```makefile
# CPU INFOrmation library...
PKG_CHECK_MODULES(
[libcpuinfo], [libcpuinfo], [],
[AC_MSG_ERROR([libcpuinfo missing...])])
YOURPROJECT_CXXFLAGS="$YOURPROJECT_CXXFLAGS $libcpuinfo_CFLAGS"
YOURPROJECT_LIBS="$YOURPROJECT_LIBS $libcpuinfo_LIBS"
```
### Meson
To use with Meson you just need to add `dependency('libcpuinfo')` as a dependency for your executable.
```meson
project(
'MyCpuInfoProject',
'cpp',
meson_version: '>=0.55.0'
)
executable(
'MyCpuInfoExecutable',
sources: 'main.cpp',
dependencies: dependency('libcpuinfo')
)
```
### Bazel
This project can be built using [Bazel](https://bazel.build/install).
You can also use this library as a dependency to your Bazel project. Add to the `WORKSPACE` file:
```python
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
git_repository(
name = "org_pytorch_cpuinfo",
branch = "master",
remote = "https://github.com/Vertexwahn/cpuinfo.git",
)
```
And to your `BUILD` file:
```python
cc_binary(
name = "cpuinfo_test",
srcs = [
# ...
],
deps = [
"@org_pytorch_cpuinfo//:cpuinfo",
],
)
```
### CMake
To use with CMake use the [FindPkgConfig](https://cmake.org/cmake/help/latest/module/FindPkgConfig.html) module. Here is an example:
```cmake
cmake_minimum_required(VERSION 3.6)
project("MyCpuInfoProject")
find_package(PkgConfig)
pkg_check_modules(CpuInfo REQUIRED IMPORTED_TARGET libcpuinfo)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} PkgConfig::CpuInfo)
```
### Makefile
To use within a vanilla makefile, you can call pkg-config directly to supply compiler and linker flags using shell substitution.
```makefile
CFLAGS=-g3 -Wall -Wextra -Werror ...
LDFLAGS=-lfoo ...
...
CFLAGS+= $(pkg-config --cflags libcpuinfo)
LDFLAGS+= $(pkg-config --libs libcpuinfo)
```
## Exposed information
- [x] Processor (SoC) name
- [x] Microarchitecture
- [x] Usable instruction sets
- [ ] CPU frequency
- [x] Cache
- [x] Size
- [x] Associativity
- [x] Line size
- [x] Number of partitions
- [x] Flags (unified, inclusive, complex hash function)
- [x] Topology (logical processors that share this cache level)
- [ ] TLB
- [ ] Number of entries
- [ ] Associativity
- [ ] Covered page types (instruction, data)
- [ ] Covered page sizes
- [x] Topology information
- [x] Logical processors
- [x] Cores
- [x] Packages (sockets)
## Supported environments:
- [x] Android
- [x] x86 ABI
- [x] x86_64 ABI
- [x] armeabi ABI
- [x] armeabiv7-a ABI
- [x] arm64-v8a ABI
- [ ] ~~mips ABI~~
- [ ] ~~mips64 ABI~~
- [x] Linux
- [x] x86
- [x] x86-64
- [x] 32-bit ARM (ARMv5T and later)
- [x] ARM64
- [ ] PowerPC64
- [x] iOS
- [x] x86 (iPhone simulator)
- [x] x86-64 (iPhone simulator)
- [x] ARMv7
- [x] ARM64
- [x] macOS
- [x] x86
- [x] x86-64
- [x] ARM64 (Apple silicon)
- [x] Windows
- [x] x86
- [x] x86-64
- [x] arm64
## Methods
- Processor (SoC) name detection
- [x] Using CPUID leaves 0x800000020x80000004 on x86/x86-64
- [x] Using `/proc/cpuinfo` on ARM
- [x] Using `ro.chipname`, `ro.board.platform`, `ro.product.board`, `ro.mediatek.platform`, `ro.arch` properties (Android)
- [ ] Using kernel log (`dmesg`) on ARM Linux
- [x] Using Windows registry on ARM64 Windows
- Vendor and microarchitecture detection
- [x] Intel-designed x86/x86-64 cores (up to Sunny Cove, Goldmont Plus, and Knights Mill)
- [x] AMD-designed x86/x86-64 cores (up to Puma/Jaguar and Zen 2)
- [ ] VIA-designed x86/x86-64 cores
- [ ] Other x86 cores (DM&P, RDC, Transmeta, Cyrix, Rise)
- [x] ARM-designed ARM cores (up to Cortex-A55, Cortex-A77, and Neoverse E1/V1/N2/V2)
- [x] Qualcomm-designed ARM cores (Scorpion, Krait, and Kryo)
- [x] Nvidia-designed ARM cores (Denver and Carmel)
- [x] Samsung-designed ARM cores (Exynos)
- [x] Intel-designed ARM cores (XScale up to 3rd-gen)
- [x] Apple-designed ARM cores (up to Lightning and Thunder)
- [x] Cavium-designed ARM cores (ThunderX)
- [x] AppliedMicro-designed ARM cores (X-Gene)
- Instruction set detection
- [x] Using CPUID (x86/x86-64)
- [x] Using `/proc/cpuinfo` on 32-bit ARM EABI (Linux)
- [x] Using microarchitecture heuristics on (32-bit ARM)
- [x] Using `FPSID` and `WCID` registers (32-bit ARM)
- [x] Using `getauxval` (Linux/ARM)
- [x] Using `/proc/self/auxv` (Android/ARM)
- [ ] Using instruction probing on ARM (Linux)
- [ ] Using CPUID registers on ARM64 (Linux)
- [x] Using IsProcessorFeaturePresent on ARM64 Windows
- Cache detection
- [x] Using CPUID leaf 0x00000002 (x86/x86-64)
- [x] Using CPUID leaf 0x00000004 (non-AMD x86/x86-64)
- [ ] Using CPUID leaves 0x80000005-0x80000006 (AMD x86/x86-64)
- [x] Using CPUID leaf 0x8000001D (AMD x86/x86-64)
- [x] Using `/proc/cpuinfo` (Linux/pre-ARMv7)
- [x] Using microarchitecture heuristics (ARM)
- [x] Using chipset name (ARM)
- [x] Using `sysctlbyname` (Mach)
- [x] Using sysfs `typology` directories (ARM/Linux)
- [ ] Using sysfs `cache` directories (Linux)
- [x] Using `GetLogicalProcessorInformationEx` on ARM64 Windows
- TLB detection
- [x] Using CPUID leaf 0x00000002 (x86/x86-64)
- [ ] Using CPUID leaves 0x80000005-0x80000006 and 0x80000019 (AMD x86/x86-64)
- [x] Using microarchitecture heuristics (ARM)
- Topology detection
- [x] Using CPUID leaf 0x00000001 on x86/x86-64 (legacy APIC ID)
- [x] Using CPUID leaf 0x0000000B on x86/x86-64 (Intel APIC ID)
- [ ] Using CPUID leaf 0x8000001E on x86/x86-64 (AMD APIC ID)
- [x] Using `/proc/cpuinfo` (Linux)
- [x] Using `host_info` (Mach)
- [x] Using `GetLogicalProcessorInformationEx` (Windows)
- [x] Using sysfs (Linux)
- [x] Using chipset name (ARM/Linux)
-15
View File
@@ -1,15 +0,0 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR)
PROJECT(googlebenchmark-download NONE)
INCLUDE(ExternalProject)
ExternalProject_Add(googlebenchmark
URL https://github.com/google/benchmark/archive/v1.6.1.zip
URL_HASH SHA256=367e963b8620080aff8c831e24751852cffd1f74ea40f25d9cc1b667a9dd5e45
SOURCE_DIR "${CONFU_DEPENDENCIES_SOURCE_DIR}/googlebenchmark"
BINARY_DIR "${CONFU_DEPENDENCIES_BINARY_DIR}/googlebenchmark"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
-15
View File
@@ -1,15 +0,0 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12 FATAL_ERROR)
PROJECT(googletest-download NONE)
INCLUDE(ExternalProject)
ExternalProject_Add(googletest
URL https://github.com/google/googletest/archive/release-1.11.0.zip
URL_HASH SHA256=353571c2440176ded91c2de6d6cd88ddd41401d14692ec1f99e35d013feda55a
SOURCE_DIR "${CONFU_DEPENDENCIES_SOURCE_DIR}/googletest"
BINARY_DIR "${CONFU_DEPENDENCIES_BINARY_DIR}/googletest"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
-12
View File
@@ -1,12 +0,0 @@
@PACKAGE_INIT@
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
file(GLOB CONFIG_FILES "${_DIR}/cpuinfo-config-*.cmake")
foreach(f ${CONFIG_FILES})
include(${f})
endforeach()
# ${_DIR}/cpuinfo-targets-*.cmake will be included here
include("${_DIR}/cpuinfo-targets.cmake")
check_required_components(@PROJECT_NAME@)
-70
View File
@@ -1,70 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(SolutionDir)common\vsprops\BaseProjectConfig.props" />
<Import Project="$(SolutionDir)common\vsprops\WinSDK.props" />
<PropertyGroup Label="Globals">
<ProjectGuid>{7E183337-A7E9-460C-9D3D-568BC9F9BCC1}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset Condition="!$(Configuration.Contains(Clang))">$(DefaultPlatformToolset)</PlatformToolset>
<PlatformToolset Condition="$(Configuration.Contains(Clang))">ClangCL</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization Condition="$(Configuration.Contains(Release))">true</WholeProgramOptimization>
<UseDebugLibraries Condition="$(Configuration.Contains(Debug))">true</UseDebugLibraries>
<UseDebugLibraries Condition="!$(Configuration.Contains(Debug))">false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="PropertySheets">
<Import Project="..\DefaultProjectRootDir.props" />
<Import Project="..\3rdparty.props" />
<Import Condition="$(Configuration.Contains(Debug))" Project="..\..\common\vsprops\CodeGen_Debug.props" />
<Import Condition="$(Configuration.Contains(Devel))" Project="..\..\common\vsprops\CodeGen_Devel.props" />
<Import Condition="$(Configuration.Contains(Release))" Project="..\..\common\vsprops\CodeGen_Release.props" />
<Import Condition="!$(Configuration.Contains(Release))" Project="..\..\common\vsprops\IncrementalLinking.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<ClCompile Include="deps\clog\src\clog.c" />
<ClCompile Include="src\api.c" />
<ClCompile Include="src\cache.c" />
<ClCompile Include="src\init.c" />
<ClCompile Include="src\x86\cache\descriptor.c" />
<ClCompile Include="src\x86\cache\deterministic.c" />
<ClCompile Include="src\x86\cache\init.c" />
<ClCompile Include="src\x86\info.c" />
<ClCompile Include="src\x86\init.c" />
<ClCompile Include="src\x86\isa.c" />
<ClCompile Include="src\x86\name.c" />
<ClCompile Include="src\x86\topology.c" />
<ClCompile Include="src\x86\uarch.c" />
<ClCompile Include="src\x86\vendor.c" />
<ClCompile Include="src\x86\windows\init.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="deps\clog\include\clog.h" />
<ClInclude Include="include\cpuinfo.h" />
<ClInclude Include="src\cpuinfo\common.h" />
<ClInclude Include="src\cpuinfo\internal-api.h" />
<ClInclude Include="src\cpuinfo\log.h" />
<ClInclude Include="src\cpuinfo\utils.h" />
<ClInclude Include="src\x86\api.h" />
<ClInclude Include="src\x86\cpuid.h" />
<ClInclude Include="src\x86\windows\api.h" />
</ItemGroup>
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>CPUINFO_LOG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>TurnOffAllWarnings</WarningLevel>
<AdditionalIncludeDirectories>$(ProjectDir)include;$(ProjectDir)src;$(ProjectDir)deps\clog\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ObjectFileName>$(IntDir)%(RelativeDir)</ObjectFileName>
</ClCompile>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>
-88
View File
@@ -1,88 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="x86">
<UniqueIdentifier>{8fc9f543-ff04-48fb-ae1a-7c575a8aed13}</UniqueIdentifier>
</Filter>
<Filter Include="x86\windows">
<UniqueIdentifier>{0b540baa-aafb-4e51-8cbf-b7e7c00d9a4d}</UniqueIdentifier>
</Filter>
<Filter Include="x86\descriptor">
<UniqueIdentifier>{53ef3c40-8e03-46d1-aeb3-6446c40469da}</UniqueIdentifier>
</Filter>
<Filter Include="cpuinfo">
<UniqueIdentifier>{26002d26-399a-41bb-93cb-42fb9be21c1f}</UniqueIdentifier>
</Filter>
<Filter Include="clog">
<UniqueIdentifier>{7f0aba4c-ca06-4a7b-aed1-4f1e6976e839}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\x86\isa.c">
<Filter>x86</Filter>
</ClCompile>
<ClCompile Include="src\x86\name.c">
<Filter>x86</Filter>
</ClCompile>
<ClCompile Include="src\x86\topology.c">
<Filter>x86</Filter>
</ClCompile>
<ClCompile Include="src\x86\uarch.c">
<Filter>x86</Filter>
</ClCompile>
<ClCompile Include="src\x86\vendor.c">
<Filter>x86</Filter>
</ClCompile>
<ClCompile Include="src\x86\info.c">
<Filter>x86</Filter>
</ClCompile>
<ClCompile Include="src\x86\init.c">
<Filter>x86</Filter>
</ClCompile>
<ClCompile Include="src\x86\windows\init.c">
<Filter>x86\windows</Filter>
</ClCompile>
<ClCompile Include="src\x86\cache\deterministic.c">
<Filter>x86\descriptor</Filter>
</ClCompile>
<ClCompile Include="src\x86\cache\init.c">
<Filter>x86\descriptor</Filter>
</ClCompile>
<ClCompile Include="src\x86\cache\descriptor.c">
<Filter>x86\descriptor</Filter>
</ClCompile>
<ClCompile Include="src\api.c" />
<ClCompile Include="src\cache.c" />
<ClCompile Include="src\init.c" />
<ClCompile Include="deps\clog\src\clog.c">
<Filter>clog</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\x86\api.h">
<Filter>x86</Filter>
</ClInclude>
<ClInclude Include="src\x86\cpuid.h">
<Filter>x86</Filter>
</ClInclude>
<ClInclude Include="src\x86\windows\api.h">
<Filter>x86\windows</Filter>
</ClInclude>
<ClInclude Include="src\cpuinfo\internal-api.h">
<Filter>cpuinfo</Filter>
</ClInclude>
<ClInclude Include="src\cpuinfo\log.h">
<Filter>cpuinfo</Filter>
</ClInclude>
<ClInclude Include="src\cpuinfo\utils.h">
<Filter>cpuinfo</Filter>
</ClInclude>
<ClInclude Include="src\cpuinfo\common.h">
<Filter>cpuinfo</Filter>
</ClInclude>
<ClInclude Include="include\cpuinfo.h" />
<ClInclude Include="deps\clog\include\clog.h">
<Filter>clog</Filter>
</ClInclude>
</ItemGroup>
</Project>
-19
View File
@@ -1,19 +0,0 @@
# Ninja files
build.ninja
# Build objects and artifacts
deps/
build/
bin/
lib/
*.pyc
*.pyo
# System files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
-101
View File
@@ -1,101 +0,0 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.1 FATAL_ERROR)
INCLUDE(GNUInstallDirs)
# ---[ Project and semantic versioning.
PROJECT(clog C CXX)
# ---[ Options.
SET(CLOG_RUNTIME_TYPE "default" CACHE STRING "Type of runtime library (shared, static, or default) to use")
SET_PROPERTY(CACHE CLOG_RUNTIME_TYPE PROPERTY STRINGS default static shared)
IF(ANDROID)
OPTION(CLOG_LOG_TO_STDIO "Log errors, warnings, and information to stdout/stderr" OFF)
ELSE()
OPTION(CLOG_LOG_TO_STDIO "Log errors, warnings, and information to stdout/stderr" ON)
ENDIF()
OPTION(CLOG_BUILD_TESTS "Build clog tests" ON)
OPTION(USE_SYSTEM_LIBS "Use system libraries instead of downloading and building them" OFF)
OPTION(USE_SYSTEM_GOOGLETEST "Use system Google Test library instead of downloading and building it" ${USE_SYSTEM_LIBS})
# ---[ CMake options
IF(CLOG_BUILD_TESTS)
ENABLE_TESTING()
ENDIF()
MACRO(CLOG_TARGET_RUNTIME_LIBRARY target)
IF(MSVC AND NOT CLOG_RUNTIME_TYPE STREQUAL "default")
IF(CLOG_RUNTIME_TYPE STREQUAL "shared")
TARGET_COMPILE_OPTIONS(${target} PRIVATE
"/MD$<$<CONFIG:Debug>:d>")
ELSEIF(CLOG_RUNTIME_TYPE STREQUAL "static")
TARGET_COMPILE_OPTIONS(${target} PRIVATE
"/MT$<$<CONFIG:Debug>:d>")
ENDIF()
ENDIF()
ENDMACRO()
# ---[ Download deps
SET(CONFU_DEPENDENCIES_SOURCE_DIR ${CMAKE_SOURCE_DIR}/deps
CACHE PATH "Confu-style dependencies source directory")
SET(CONFU_DEPENDENCIES_BINARY_DIR ${CMAKE_BINARY_DIR}/deps
CACHE PATH "Confu-style dependencies binary directory")
IF(CLOG_BUILD_TESTS)
IF(USE_SYSTEM_GOOGLETEST)
FIND_PACKAGE(GTest REQUIRED)
ELSEIF(NOT DEFINED GOOGLETEST_SOURCE_DIR)
MESSAGE(STATUS "Downloading Google Test to ${CONFU_DEPENDENCIES_SOURCE_DIR}/googletest (define GOOGLETEST_SOURCE_DIR to avoid it)")
CONFIGURE_FILE(cmake/DownloadGoogleTest.cmake "${CONFU_DEPENDENCIES_BINARY_DIR}/googletest-download/CMakeLists.txt")
EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
WORKING_DIRECTORY "${CONFU_DEPENDENCIES_BINARY_DIR}/googletest-download")
EXECUTE_PROCESS(COMMAND "${CMAKE_COMMAND}" --build .
WORKING_DIRECTORY "${CONFU_DEPENDENCIES_BINARY_DIR}/googletest-download")
SET(GOOGLETEST_SOURCE_DIR "${CONFU_DEPENDENCIES_SOURCE_DIR}/googletest" CACHE STRING "Google Test source directory")
ENDIF()
ENDIF()
# ---[ clog library
ADD_LIBRARY(clog STATIC src/clog.c)
SET_TARGET_PROPERTIES(clog PROPERTIES
C_STANDARD 99
C_EXTENSIONS NO)
CLOG_TARGET_RUNTIME_LIBRARY(clog)
SET_TARGET_PROPERTIES(clog PROPERTIES PUBLIC_HEADER include/clog.h)
TARGET_INCLUDE_DIRECTORIES(clog PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
IF(CLOG_LOG_TO_STDIO)
TARGET_COMPILE_DEFINITIONS(clog PRIVATE CLOG_LOG_TO_STDIO=1)
ELSE()
TARGET_COMPILE_DEFINITIONS(clog PRIVATE CLOG_LOG_TO_STDIO=0)
ENDIF()
IF(ANDROID AND NOT CLOG_LOG_TO_STDIO)
TARGET_LINK_LIBRARIES(clog PRIVATE log)
ENDIF()
ADD_LIBRARY(cpuinfo::clog ALIAS clog)
INSTALL(TARGETS clog
EXPORT cpuinfo-targets
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
# ---[ clog tests
IF(CLOG_BUILD_TESTS)
# ---[ Build google test
IF(NOT TARGET gtest AND NOT USE_SYSTEM_GOOGLETEST)
IF(MSVC AND NOT CLOG_RUNTIME_TYPE STREQUAL "static")
SET(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
ENDIF()
ADD_SUBDIRECTORY(
"${GOOGLETEST_SOURCE_DIR}"
"${CONFU_DEPENDENCIES_BINARY_DIR}/googletest")
ENDIF()
ADD_EXECUTABLE(clog-test test/clog.cc)
SET_TARGET_PROPERTIES(clog-test PROPERTIES
CXX_STANDARD 11
CXX_EXTENSIONS NO)
CLOG_TARGET_RUNTIME_LIBRARY(clog-test)
TARGET_LINK_LIBRARIES(clog-test PRIVATE clog gtest gtest_main)
ADD_TEST(clog-test clog-test)
ENDIF()
-26
View File
@@ -1,26 +0,0 @@
Copyright (C) 2018 Marat Dukhan
Copyright (c) 2017-2018 Facebook Inc.
Copyright (c) 2017 Georgia Institute of Technology
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-57
View File
@@ -1,57 +0,0 @@
# clog: C-style (a-la printf) logging library
[![BSD (2 clause) License](https://img.shields.io/badge/License-BSD%202--Clause%20%22Simplified%22%20License-blue.svg)](https://github.com/pytorch/cpuinfo/blob/master/deps/clog/LICENSE)
C-style library for logging errors, warnings, information notes, and debug information.
## Features
- printf-style interface for formatting variadic parameters.
- Separate functions for logging errors, warnings, information notes, and debug information.
- Independent logging settings for different modules.
- Logging to logcat on Android and stderr/stdout on other platforms.
- Compatible with C99 and C++.
- Covered with unit tests.
## Example
```c
#include <clog.h>
#ifndef MYMODULE_LOG_LEVEL
#define MYMODULE_LOG_LEVEL CLOG_DEBUG
#endif
CLOG_DEFINE_LOG_DEBUG(mymodule_, "My Module", MYMODULE_LOG_LEVEL);
CLOG_DEFINE_LOG_INFO(mymodule_, "My Module", MYMODULE_LOG_LEVEL);
CLOG_DEFINE_LOG_WARNING(mymodule_, "My Module", MYMODULE_LOG_LEVEL);
CLOG_DEFINE_LOG_ERROR(mymodule_, "My Module", MYMODULE_LOG_LEVEL);
...
void some_function(...) {
int status = ...
if (status != 0) {
mymodule_log_error(
"something really bad happened: "
"operation failed with status %d", status);
}
uint32_t expected_zero = ...
if (expected_zero != 0) {
mymodule_log_warning(
"something suspicious happened (var = %"PRIu32"), "
"fall back to generic implementation", expected_zero);
}
void* usually_non_null = ...
if (usually_non_null == NULL) {
mymodule_log_info(
"something unusual, but common, happened: "
"enabling work-around");
}
float a = ...
mymodule_log_debug("computed a = %.7f", a);
}
```
-100
View File
@@ -1,100 +0,0 @@
#pragma once
#include <stdarg.h>
#include <stdlib.h>
#include <inttypes.h>
#define CLOG_NONE 0
#define CLOG_FATAL 1
#define CLOG_ERROR 2
#define CLOG_WARNING 3
#define CLOG_INFO 4
#define CLOG_DEBUG 5
#ifndef CLOG_VISIBILITY
#if defined(__ELF__)
#define CLOG_VISIBILITY __attribute__((__visibility__("internal")))
#elif defined(__MACH__)
#define CLOG_VISIBILITY __attribute__((__visibility__("hidden")))
#else
#define CLOG_VISIBILITY
#endif
#endif
#ifndef CLOG_ARGUMENTS_FORMAT
#if defined(__GNUC__)
#define CLOG_ARGUMENTS_FORMAT __attribute__((__format__(__printf__, 1, 2)))
#else
#define CLOG_ARGUMENTS_FORMAT
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
CLOG_VISIBILITY void clog_vlog_debug(const char* module, const char* format, va_list args);
CLOG_VISIBILITY void clog_vlog_info(const char* module, const char* format, va_list args);
CLOG_VISIBILITY void clog_vlog_warning(const char* module, const char* format, va_list args);
CLOG_VISIBILITY void clog_vlog_error(const char* module, const char* format, va_list args);
CLOG_VISIBILITY void clog_vlog_fatal(const char* module, const char* format, va_list args);
#define CLOG_DEFINE_LOG_DEBUG(log_debug_function_name, module, level) \
CLOG_ARGUMENTS_FORMAT \
inline static void log_debug_function_name(const char* format, ...) { \
if (level >= CLOG_DEBUG) { \
va_list args; \
va_start(args, format); \
clog_vlog_debug(module, format, args); \
va_end(args); \
} \
}
#define CLOG_DEFINE_LOG_INFO(log_info_function_name, module, level) \
CLOG_ARGUMENTS_FORMAT \
inline static void log_info_function_name(const char* format, ...) { \
if (level >= CLOG_INFO) { \
va_list args; \
va_start(args, format); \
clog_vlog_info(module, format, args); \
va_end(args); \
} \
}
#define CLOG_DEFINE_LOG_WARNING(log_warning_function_name, module, level) \
CLOG_ARGUMENTS_FORMAT \
inline static void log_warning_function_name(const char* format, ...) { \
if (level >= CLOG_WARNING) { \
va_list args; \
va_start(args, format); \
clog_vlog_warning(module, format, args); \
va_end(args); \
} \
}
#define CLOG_DEFINE_LOG_ERROR(log_error_function_name, module, level) \
CLOG_ARGUMENTS_FORMAT \
inline static void log_error_function_name(const char* format, ...) { \
if (level >= CLOG_ERROR) { \
va_list args; \
va_start(args, format); \
clog_vlog_error(module, format, args); \
va_end(args); \
} \
}
#define CLOG_DEFINE_LOG_FATAL(log_fatal_function_name, module, level) \
CLOG_ARGUMENTS_FORMAT \
inline static void log_fatal_function_name(const char* format, ...) { \
if (level >= CLOG_FATAL) { \
va_list args; \
va_start(args, format); \
clog_vlog_fatal(module, format, args); \
va_end(args); \
} \
abort(); \
}
#ifdef __cplusplus
} /* extern "C" */
#endif
-436
View File
@@ -1,436 +0,0 @@
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#ifdef __ANDROID__
#include <android/log.h>
#endif
#ifdef __hexagon__
#include <qurt_printf.h>
#endif
#ifndef CLOG_LOG_TO_STDIO
#ifdef __ANDROID__
#define CLOG_LOG_TO_STDIO 0
#else
#define CLOG_LOG_TO_STDIO 1
#endif
#endif
#include <clog.h>
/* Messages up to this size are formatted entirely on-stack, and don't allocate heap memory */
#define CLOG_STACK_BUFFER_SIZE 1024
#define CLOG_FATAL_PREFIX "Fatal error: "
#define CLOG_FATAL_PREFIX_LENGTH 13
#define CLOG_FATAL_PREFIX_FORMAT "Fatal error in %s: "
#define CLOG_ERROR_PREFIX "Error: "
#define CLOG_ERROR_PREFIX_LENGTH 7
#define CLOG_ERROR_PREFIX_FORMAT "Error in %s: "
#define CLOG_WARNING_PREFIX "Warning: "
#define CLOG_WARNING_PREFIX_LENGTH 9
#define CLOG_WARNING_PREFIX_FORMAT "Warning in %s: "
#define CLOG_INFO_PREFIX "Note: "
#define CLOG_INFO_PREFIX_LENGTH 6
#define CLOG_INFO_PREFIX_FORMAT "Note (%s): "
#define CLOG_DEBUG_PREFIX "Debug: "
#define CLOG_DEBUG_PREFIX_LENGTH 7
#define CLOG_DEBUG_PREFIX_FORMAT "Debug (%s): "
#define CLOG_SUFFIX_LENGTH 1
void clog_vlog_fatal(const char* module, const char* format, va_list args) {
#if defined(__ANDROID__) && !CLOG_LOG_TO_STDIO
__android_log_vprint(ANDROID_LOG_FATAL, module, format, args);
#else
char stack_buffer[CLOG_STACK_BUFFER_SIZE];
char* heap_buffer = NULL;
char* out_buffer = &stack_buffer[0];
/* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */
va_list args_copy;
va_copy(args_copy, args);
int prefix_chars = CLOG_FATAL_PREFIX_LENGTH;
if (module == NULL) {
memcpy(stack_buffer, CLOG_FATAL_PREFIX, CLOG_FATAL_PREFIX_LENGTH);
} else {
prefix_chars = snprintf(stack_buffer, CLOG_STACK_BUFFER_SIZE, CLOG_FATAL_PREFIX_FORMAT, module);
if (prefix_chars < 0) {
/* Format error in prefix (possible if prefix is modified): skip prefix and continue as if nothing happened. */
prefix_chars = 0;
}
}
int format_chars;
if (prefix_chars + CLOG_SUFFIX_LENGTH >= CLOG_STACK_BUFFER_SIZE) {
/*
* Prefix + suffix alone would overflow the on-stack buffer, thus need to use on-heap buffer.
* Do not even try to format the string into on-stack buffer.
*/
format_chars = vsnprintf(NULL, 0, format, args);
} else {
format_chars =
vsnprintf(
&stack_buffer[prefix_chars],
CLOG_STACK_BUFFER_SIZE - prefix_chars - CLOG_SUFFIX_LENGTH,
format,
args);
}
if (format_chars < 0) {
/* Format error in the message: silently ignore this particular message. */
goto cleanup;
}
if (prefix_chars + format_chars + CLOG_SUFFIX_LENGTH > CLOG_STACK_BUFFER_SIZE) {
/* Allocate a buffer on heap, and vsnprintf to this buffer */
heap_buffer = malloc(prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
if (heap_buffer == NULL) {
goto cleanup;
}
if (prefix_chars > CLOG_STACK_BUFFER_SIZE) {
/* Prefix didn't fit into on-stack buffer, re-format it again to on-heap buffer */
snprintf(heap_buffer, prefix_chars + 1 /* for '\0'-terminator */, CLOG_FATAL_PREFIX_FORMAT, module);
} else {
/* Copy pre-formatted prefix from on-stack buffer to on-heap buffer */
memcpy(heap_buffer, stack_buffer, prefix_chars);
}
vsnprintf(heap_buffer + prefix_chars, format_chars + CLOG_SUFFIX_LENGTH, format, args_copy);
out_buffer = heap_buffer;
}
out_buffer[prefix_chars + format_chars] = '\n';
#if defined(_WIN32)
DWORD bytes_written;
WriteFile(
GetStdHandle(STD_ERROR_HANDLE),
out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH,
&bytes_written, NULL);
#elif defined(__hexagon__)
qurt_printf("%s", out_buffer);
#else
write(STDERR_FILENO, out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
#endif
cleanup:
free(heap_buffer);
va_end(args_copy);
#endif
}
void clog_vlog_error(const char* module, const char* format, va_list args) {
#if defined(__ANDROID__) && !CLOG_LOG_TO_STDIO
__android_log_vprint(ANDROID_LOG_ERROR, module, format, args);
#else
char stack_buffer[CLOG_STACK_BUFFER_SIZE];
char* heap_buffer = NULL;
char* out_buffer = &stack_buffer[0];
/* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */
va_list args_copy;
va_copy(args_copy, args);
int prefix_chars = CLOG_ERROR_PREFIX_LENGTH;
if (module == NULL) {
memcpy(stack_buffer, CLOG_ERROR_PREFIX, CLOG_ERROR_PREFIX_LENGTH);
} else {
prefix_chars = snprintf(stack_buffer, CLOG_STACK_BUFFER_SIZE, CLOG_ERROR_PREFIX_FORMAT, module);
if (prefix_chars < 0) {
/* Format error in prefix (possible if prefix is modified): skip prefix and continue as if nothing happened. */
prefix_chars = 0;
}
}
int format_chars;
if (prefix_chars + CLOG_SUFFIX_LENGTH >= CLOG_STACK_BUFFER_SIZE) {
/*
* Prefix + suffix alone would overflow the on-stack buffer, thus need to use on-heap buffer.
* Do not even try to format the string into on-stack buffer.
*/
format_chars = vsnprintf(NULL, 0, format, args);
} else {
format_chars =
vsnprintf(
&stack_buffer[prefix_chars],
CLOG_STACK_BUFFER_SIZE - prefix_chars - CLOG_SUFFIX_LENGTH,
format,
args);
}
if (format_chars < 0) {
/* Format error in the message: silently ignore this particular message. */
goto cleanup;
}
if (prefix_chars + format_chars + CLOG_SUFFIX_LENGTH > CLOG_STACK_BUFFER_SIZE) {
/* Allocate a buffer on heap, and vsnprintf to this buffer */
heap_buffer = malloc(prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
if (heap_buffer == NULL) {
goto cleanup;
}
if (prefix_chars > CLOG_STACK_BUFFER_SIZE) {
/* Prefix didn't fit into on-stack buffer, re-format it again to on-heap buffer */
snprintf(heap_buffer, prefix_chars + 1 /* for '\0'-terminator */, CLOG_ERROR_PREFIX_FORMAT, module);
} else {
/* Copy pre-formatted prefix from on-stack buffer to on-heap buffer */
memcpy(heap_buffer, stack_buffer, prefix_chars);
}
vsnprintf(heap_buffer + prefix_chars, format_chars + CLOG_SUFFIX_LENGTH, format, args_copy);
out_buffer = heap_buffer;
}
out_buffer[prefix_chars + format_chars] = '\n';
#if defined(_WIN32)
DWORD bytes_written;
WriteFile(
GetStdHandle(STD_ERROR_HANDLE),
out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH,
&bytes_written, NULL);
#elif defined(__hexagon__)
qurt_printf("%s", out_buffer);
#else
write(STDERR_FILENO, out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
#endif
cleanup:
free(heap_buffer);
va_end(args_copy);
#endif
}
void clog_vlog_warning(const char* module, const char* format, va_list args) {
#if defined(__ANDROID__) && !CLOG_LOG_TO_STDIO
__android_log_vprint(ANDROID_LOG_WARN, module, format, args);
#else
char stack_buffer[CLOG_STACK_BUFFER_SIZE];
char* heap_buffer = NULL;
char* out_buffer = &stack_buffer[0];
/* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */
va_list args_copy;
va_copy(args_copy, args);
int prefix_chars = CLOG_WARNING_PREFIX_LENGTH;
if (module == NULL) {
memcpy(stack_buffer, CLOG_WARNING_PREFIX, CLOG_WARNING_PREFIX_LENGTH);
} else {
prefix_chars = snprintf(stack_buffer, CLOG_STACK_BUFFER_SIZE, CLOG_WARNING_PREFIX_FORMAT, module);
if (prefix_chars < 0) {
/* Format error in prefix (possible if prefix is modified): skip prefix and continue as if nothing happened. */
prefix_chars = 0;
}
}
int format_chars;
if (prefix_chars + CLOG_SUFFIX_LENGTH >= CLOG_STACK_BUFFER_SIZE) {
/*
* Prefix + suffix alone would overflow the on-stack buffer, thus need to use on-heap buffer.
* Do not even try to format the string into on-stack buffer.
*/
format_chars = vsnprintf(NULL, 0, format, args);
} else {
format_chars =
vsnprintf(
&stack_buffer[prefix_chars],
CLOG_STACK_BUFFER_SIZE - prefix_chars - CLOG_SUFFIX_LENGTH,
format,
args);
}
if (format_chars < 0) {
/* Format error in the message: silently ignore this particular message. */
goto cleanup;
}
if (prefix_chars + format_chars + CLOG_SUFFIX_LENGTH > CLOG_STACK_BUFFER_SIZE) {
/* Allocate a buffer on heap, and vsnprintf to this buffer */
heap_buffer = malloc(prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
if (heap_buffer == NULL) {
goto cleanup;
}
if (prefix_chars > CLOG_STACK_BUFFER_SIZE) {
/* Prefix didn't fit into on-stack buffer, re-format it again to on-heap buffer */
snprintf(heap_buffer, prefix_chars + 1 /* for '\0'-terminator */, CLOG_WARNING_PREFIX_FORMAT, module);
} else {
/* Copy pre-formatted prefix from on-stack buffer to on-heap buffer */
memcpy(heap_buffer, stack_buffer, prefix_chars);
}
vsnprintf(heap_buffer + prefix_chars, format_chars + CLOG_SUFFIX_LENGTH, format, args_copy);
out_buffer = heap_buffer;
}
out_buffer[prefix_chars + format_chars] = '\n';
#if defined(_WIN32)
DWORD bytes_written;
WriteFile(
GetStdHandle(STD_ERROR_HANDLE),
out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH,
&bytes_written, NULL);
#elif defined(__hexagon__)
qurt_printf("%s", out_buffer);
#else
write(STDERR_FILENO, out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
#endif
cleanup:
free(heap_buffer);
va_end(args_copy);
#endif
}
void clog_vlog_info(const char* module, const char* format, va_list args) {
#if defined(__ANDROID__) && !CLOG_LOG_TO_STDIO
__android_log_vprint(ANDROID_LOG_INFO, module, format, args);
#else
char stack_buffer[CLOG_STACK_BUFFER_SIZE];
char* heap_buffer = NULL;
char* out_buffer = &stack_buffer[0];
/* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */
va_list args_copy;
va_copy(args_copy, args);
int prefix_chars = CLOG_INFO_PREFIX_LENGTH;
if (module == NULL) {
memcpy(stack_buffer, CLOG_INFO_PREFIX, CLOG_INFO_PREFIX_LENGTH);
} else {
prefix_chars = snprintf(stack_buffer, CLOG_STACK_BUFFER_SIZE, CLOG_INFO_PREFIX_FORMAT, module);
if (prefix_chars < 0) {
/* Format error in prefix (possible if prefix is modified): skip prefix and continue as if nothing happened. */
prefix_chars = 0;
}
}
int format_chars;
if (prefix_chars + CLOG_SUFFIX_LENGTH >= CLOG_STACK_BUFFER_SIZE) {
/*
* Prefix + suffix alone would overflow the on-stack buffer, thus need to use on-heap buffer.
* Do not even try to format the string into on-stack buffer.
*/
format_chars = vsnprintf(NULL, 0, format, args);
} else {
format_chars =
vsnprintf(
&stack_buffer[prefix_chars],
CLOG_STACK_BUFFER_SIZE - prefix_chars - CLOG_SUFFIX_LENGTH,
format,
args);
}
if (format_chars < 0) {
/* Format error in the message: silently ignore this particular message. */
goto cleanup;
}
if (prefix_chars + format_chars + CLOG_SUFFIX_LENGTH > CLOG_STACK_BUFFER_SIZE) {
/* Allocate a buffer on heap, and vsnprintf to this buffer */
heap_buffer = malloc(prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
if (heap_buffer == NULL) {
goto cleanup;
}
if (prefix_chars > CLOG_STACK_BUFFER_SIZE) {
/* Prefix didn't fit into on-stack buffer, re-format it again to on-heap buffer */
snprintf(heap_buffer, prefix_chars + 1 /* for '\0'-terminator */, CLOG_INFO_PREFIX_FORMAT, module);
} else {
/* Copy pre-formatted prefix from on-stack buffer to on-heap buffer */
memcpy(heap_buffer, stack_buffer, prefix_chars);
}
vsnprintf(heap_buffer + prefix_chars, format_chars + CLOG_SUFFIX_LENGTH, format, args_copy);
out_buffer = heap_buffer;
}
out_buffer[prefix_chars + format_chars] = '\n';
#if defined(_WIN32)
DWORD bytes_written;
WriteFile(
GetStdHandle(STD_OUTPUT_HANDLE),
out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH,
&bytes_written, NULL);
#elif defined(__hexagon__)
qurt_printf("%s", out_buffer);
#else
write(STDOUT_FILENO, out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
#endif
cleanup:
free(heap_buffer);
va_end(args_copy);
#endif
}
void clog_vlog_debug(const char* module, const char* format, va_list args) {
#if defined(__ANDROID__) && !CLOG_LOG_TO_STDIO
__android_log_vprint(ANDROID_LOG_DEBUG, module, format, args);
#else
char stack_buffer[CLOG_STACK_BUFFER_SIZE];
char* heap_buffer = NULL;
char* out_buffer = &stack_buffer[0];
/* The first call to vsnprintf will clobber args, thus need a copy in case a second vsnprintf call is needed */
va_list args_copy;
va_copy(args_copy, args);
int prefix_chars = CLOG_DEBUG_PREFIX_LENGTH;
if (module == NULL) {
memcpy(stack_buffer, CLOG_DEBUG_PREFIX, CLOG_DEBUG_PREFIX_LENGTH);
} else {
prefix_chars = snprintf(stack_buffer, CLOG_STACK_BUFFER_SIZE, CLOG_DEBUG_PREFIX_FORMAT, module);
if (prefix_chars < 0) {
/* Format error in prefix (possible if prefix is modified): skip prefix and continue as if nothing happened. */
prefix_chars = 0;
}
}
int format_chars;
if (prefix_chars + CLOG_SUFFIX_LENGTH >= CLOG_STACK_BUFFER_SIZE) {
/*
* Prefix + suffix alone would overflow the on-stack buffer, thus need to use on-heap buffer.
* Do not even try to format the string into on-stack buffer.
*/
format_chars = vsnprintf(NULL, 0, format, args);
} else {
format_chars =
vsnprintf(
&stack_buffer[prefix_chars],
CLOG_STACK_BUFFER_SIZE - prefix_chars - CLOG_SUFFIX_LENGTH,
format,
args);
}
if (format_chars < 0) {
/* Format error in the message: silently ignore this particular message. */
goto cleanup;
}
if (prefix_chars + format_chars + CLOG_SUFFIX_LENGTH > CLOG_STACK_BUFFER_SIZE) {
/* Allocate a buffer on heap, and vsnprintf to this buffer */
heap_buffer = malloc(prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
if (heap_buffer == NULL) {
goto cleanup;
}
if (prefix_chars > CLOG_STACK_BUFFER_SIZE) {
/* Prefix didn't fit into on-stack buffer, re-format it again to on-heap buffer */
snprintf(heap_buffer, prefix_chars + 1 /* for '\0'-terminator */, CLOG_DEBUG_PREFIX_FORMAT, module);
} else {
/* Copy pre-formatted prefix from on-stack buffer to on-heap buffer */
memcpy(heap_buffer, stack_buffer, prefix_chars);
}
vsnprintf(heap_buffer + prefix_chars, format_chars + CLOG_SUFFIX_LENGTH, format, args_copy);
out_buffer = heap_buffer;
}
out_buffer[prefix_chars + format_chars] = '\n';
#if defined(_WIN32)
DWORD bytes_written;
WriteFile(
GetStdHandle(STD_OUTPUT_HANDLE),
out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH,
&bytes_written, NULL);
#elif defined(__hexagon__)
qurt_printf("%s", out_buffer);
#else
write(STDOUT_FILENO, out_buffer, prefix_chars + format_chars + CLOG_SUFFIX_LENGTH);
#endif
cleanup:
free(heap_buffer);
va_end(args_copy);
#endif
}
-78
View File
@@ -1,78 +0,0 @@
#pragma once
#ifndef CPUINFO_MOCK_H
#define CPUINFO_MOCK_H
#include <stddef.h>
#include <stdint.h>
#include <cpuinfo.h>
#if defined(__linux__)
#include <sys/types.h>
#endif
#if !defined(CPUINFO_MOCK) || !(CPUINFO_MOCK)
#error This header is intended only for test use
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if CPUINFO_ARCH_ARM
void CPUINFO_ABI cpuinfo_set_fpsid(uint32_t fpsid);
void CPUINFO_ABI cpuinfo_set_wcid(uint32_t wcid);
#endif /* CPUINFO_ARCH_ARM */
#if CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64
struct cpuinfo_mock_cpuid {
uint32_t input_eax;
uint32_t input_ecx;
uint32_t eax;
uint32_t ebx;
uint32_t ecx;
uint32_t edx;
};
void CPUINFO_ABI cpuinfo_mock_set_cpuid(struct cpuinfo_mock_cpuid* dump, size_t entries);
void CPUINFO_ABI cpuinfo_mock_get_cpuid(uint32_t eax, uint32_t regs[4]);
void CPUINFO_ABI cpuinfo_mock_get_cpuidex(uint32_t eax, uint32_t ecx, uint32_t regs[4]);
#endif /* CPUINFO_ARCH_X86 || CPUINFO_ARCH_X86_64 */
struct cpuinfo_mock_file {
const char* path;
size_t size;
const char* content;
size_t offset;
};
struct cpuinfo_mock_property {
const char* key;
const char* value;
};
#if defined(__linux__)
void CPUINFO_ABI cpuinfo_mock_filesystem(struct cpuinfo_mock_file* files);
int CPUINFO_ABI cpuinfo_mock_open(const char* path, int oflag);
int CPUINFO_ABI cpuinfo_mock_close(int fd);
ssize_t CPUINFO_ABI cpuinfo_mock_read(int fd, void* buffer, size_t capacity);
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64
void CPUINFO_ABI cpuinfo_set_hwcap(uint32_t hwcap);
#endif
#if CPUINFO_ARCH_ARM
void CPUINFO_ABI cpuinfo_set_hwcap2(uint32_t hwcap2);
#endif
#endif
#if defined(__ANDROID__)
void CPUINFO_ABI cpuinfo_mock_android_properties(struct cpuinfo_mock_property* properties);
void CPUINFO_ABI cpuinfo_mock_gl_renderer(const char* renderer);
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* CPUINFO_MOCK_H */
-2077
View File
File diff suppressed because it is too large Load Diff
-417
View File
@@ -1,417 +0,0 @@
#include <stdbool.h>
#include <stddef.h>
#include <cpuinfo.h>
#include <cpuinfo/internal-api.h>
#include <cpuinfo/log.h>
#ifdef __linux__
#include <linux/api.h>
#include <unistd.h>
#include <sys/syscall.h>
#if !defined(__NR_getcpu)
#include <asm-generic/unistd.h>
#endif
#endif
bool cpuinfo_is_initialized = false;
struct cpuinfo_processor* cpuinfo_processors = NULL;
struct cpuinfo_core* cpuinfo_cores = NULL;
struct cpuinfo_cluster* cpuinfo_clusters = NULL;
struct cpuinfo_package* cpuinfo_packages = NULL;
struct cpuinfo_cache* cpuinfo_cache[cpuinfo_cache_level_max] = { NULL };
uint32_t cpuinfo_processors_count = 0;
uint32_t cpuinfo_cores_count = 0;
uint32_t cpuinfo_clusters_count = 0;
uint32_t cpuinfo_packages_count = 0;
uint32_t cpuinfo_cache_count[cpuinfo_cache_level_max] = { 0 };
uint32_t cpuinfo_max_cache_size = 0;
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 \
|| CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
struct cpuinfo_uarch_info* cpuinfo_uarchs = NULL;
uint32_t cpuinfo_uarchs_count = 0;
#else
struct cpuinfo_uarch_info cpuinfo_global_uarch = { cpuinfo_uarch_unknown };
#endif
#ifdef __linux__
uint32_t cpuinfo_linux_cpu_max = 0;
const struct cpuinfo_processor** cpuinfo_linux_cpu_to_processor_map = NULL;
const struct cpuinfo_core** cpuinfo_linux_cpu_to_core_map = NULL;
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 \
|| CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
const uint32_t* cpuinfo_linux_cpu_to_uarch_index_map = NULL;
#endif
#endif
const struct cpuinfo_processor* cpuinfo_get_processors(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "processors");
}
return cpuinfo_processors;
}
const struct cpuinfo_core* cpuinfo_get_cores(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "core");
}
return cpuinfo_cores;
}
const struct cpuinfo_cluster* cpuinfo_get_clusters(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "clusters");
}
return cpuinfo_clusters;
}
const struct cpuinfo_package* cpuinfo_get_packages(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "packages");
}
return cpuinfo_packages;
}
const struct cpuinfo_uarch_info* cpuinfo_get_uarchs() {
if (!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "uarchs");
}
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 \
|| CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
return cpuinfo_uarchs;
#else
return &cpuinfo_global_uarch;
#endif
}
const struct cpuinfo_processor* cpuinfo_get_processor(uint32_t index) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "processor");
}
if CPUINFO_UNLIKELY(index >= cpuinfo_processors_count) {
return NULL;
}
return &cpuinfo_processors[index];
}
const struct cpuinfo_core* cpuinfo_get_core(uint32_t index) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "core");
}
if CPUINFO_UNLIKELY(index >= cpuinfo_cores_count) {
return NULL;
}
return &cpuinfo_cores[index];
}
const struct cpuinfo_cluster* cpuinfo_get_cluster(uint32_t index) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "cluster");
}
if CPUINFO_UNLIKELY(index >= cpuinfo_clusters_count) {
return NULL;
}
return &cpuinfo_clusters[index];
}
const struct cpuinfo_package* cpuinfo_get_package(uint32_t index) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "package");
}
if CPUINFO_UNLIKELY(index >= cpuinfo_packages_count) {
return NULL;
}
return &cpuinfo_packages[index];
}
const struct cpuinfo_uarch_info* cpuinfo_get_uarch(uint32_t index) {
if (!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "uarch");
}
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 \
|| CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
if CPUINFO_UNLIKELY(index >= cpuinfo_uarchs_count) {
return NULL;
}
return &cpuinfo_uarchs[index];
#else
if CPUINFO_UNLIKELY(index != 0) {
return NULL;
}
return &cpuinfo_global_uarch;
#endif
}
uint32_t cpuinfo_get_processors_count(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "processors_count");
}
return cpuinfo_processors_count;
}
uint32_t cpuinfo_get_cores_count(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "cores_count");
}
return cpuinfo_cores_count;
}
uint32_t cpuinfo_get_clusters_count(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "clusters_count");
}
return cpuinfo_clusters_count;
}
uint32_t cpuinfo_get_packages_count(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "packages_count");
}
return cpuinfo_packages_count;
}
uint32_t cpuinfo_get_uarchs_count(void) {
if (!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "uarchs_count");
}
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 \
|| CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
return cpuinfo_uarchs_count;
#else
return 1;
#endif
}
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1i_caches(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1i_caches");
}
return cpuinfo_cache[cpuinfo_cache_level_1i];
}
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1d_caches(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1d_caches");
}
return cpuinfo_cache[cpuinfo_cache_level_1d];
}
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l2_caches(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l2_caches");
}
return cpuinfo_cache[cpuinfo_cache_level_2];
}
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l3_caches(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l3_caches");
}
return cpuinfo_cache[cpuinfo_cache_level_3];
}
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l4_caches(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l4_caches");
}
return cpuinfo_cache[cpuinfo_cache_level_4];
}
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1i_cache(uint32_t index) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1i_cache");
}
if CPUINFO_UNLIKELY(index >= cpuinfo_cache_count[cpuinfo_cache_level_1i]) {
return NULL;
}
return &cpuinfo_cache[cpuinfo_cache_level_1i][index];
}
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l1d_cache(uint32_t index) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1d_cache");
}
if CPUINFO_UNLIKELY(index >= cpuinfo_cache_count[cpuinfo_cache_level_1d]) {
return NULL;
}
return &cpuinfo_cache[cpuinfo_cache_level_1d][index];
}
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l2_cache(uint32_t index) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l2_cache");
}
if CPUINFO_UNLIKELY(index >= cpuinfo_cache_count[cpuinfo_cache_level_2]) {
return NULL;
}
return &cpuinfo_cache[cpuinfo_cache_level_2][index];
}
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l3_cache(uint32_t index) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l3_cache");
}
if CPUINFO_UNLIKELY(index >= cpuinfo_cache_count[cpuinfo_cache_level_3]) {
return NULL;
}
return &cpuinfo_cache[cpuinfo_cache_level_3][index];
}
const struct cpuinfo_cache* CPUINFO_ABI cpuinfo_get_l4_cache(uint32_t index) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l4_cache");
}
if CPUINFO_UNLIKELY(index >= cpuinfo_cache_count[cpuinfo_cache_level_4]) {
return NULL;
}
return &cpuinfo_cache[cpuinfo_cache_level_4][index];
}
uint32_t CPUINFO_ABI cpuinfo_get_l1i_caches_count(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1i_caches_count");
}
return cpuinfo_cache_count[cpuinfo_cache_level_1i];
}
uint32_t CPUINFO_ABI cpuinfo_get_l1d_caches_count(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l1d_caches_count");
}
return cpuinfo_cache_count[cpuinfo_cache_level_1d];
}
uint32_t CPUINFO_ABI cpuinfo_get_l2_caches_count(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l2_caches_count");
}
return cpuinfo_cache_count[cpuinfo_cache_level_2];
}
uint32_t CPUINFO_ABI cpuinfo_get_l3_caches_count(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l3_caches_count");
}
return cpuinfo_cache_count[cpuinfo_cache_level_3];
}
uint32_t CPUINFO_ABI cpuinfo_get_l4_caches_count(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "l4_caches_count");
}
return cpuinfo_cache_count[cpuinfo_cache_level_4];
}
uint32_t CPUINFO_ABI cpuinfo_get_max_cache_size(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "max_cache_size");
}
return cpuinfo_max_cache_size;
}
const struct cpuinfo_processor* CPUINFO_ABI cpuinfo_get_current_processor(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "current_processor");
}
#ifdef __linux__
/* Initializing this variable silences a MemorySanitizer error. */
unsigned cpu = 0;
if CPUINFO_UNLIKELY(syscall(__NR_getcpu, &cpu, NULL, NULL) != 0) {
return 0;
}
if CPUINFO_UNLIKELY((uint32_t) cpu >= cpuinfo_linux_cpu_max) {
return 0;
}
return cpuinfo_linux_cpu_to_processor_map[cpu];
#else
return NULL;
#endif
}
const struct cpuinfo_core* CPUINFO_ABI cpuinfo_get_current_core(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "current_core");
}
#ifdef __linux__
/* Initializing this variable silences a MemorySanitizer error. */
unsigned cpu = 0;
if CPUINFO_UNLIKELY(syscall(__NR_getcpu, &cpu, NULL, NULL) != 0) {
return 0;
}
if CPUINFO_UNLIKELY((uint32_t) cpu >= cpuinfo_linux_cpu_max) {
return 0;
}
return cpuinfo_linux_cpu_to_core_map[cpu];
#else
return NULL;
#endif
}
uint32_t CPUINFO_ABI cpuinfo_get_current_uarch_index(void) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "current_uarch_index");
}
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 \
|| CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
#ifdef __linux__
if (cpuinfo_linux_cpu_to_uarch_index_map == NULL) {
/* Special case: avoid syscall on systems with only a single type of cores */
return 0;
}
/* General case */
/* Initializing this variable silences a MemorySanitizer error. */
unsigned cpu = 0;
if CPUINFO_UNLIKELY(syscall(__NR_getcpu, &cpu, NULL, NULL) != 0) {
return 0;
}
if CPUINFO_UNLIKELY((uint32_t) cpu >= cpuinfo_linux_cpu_max) {
return 0;
}
return cpuinfo_linux_cpu_to_uarch_index_map[cpu];
#else
/* Fallback: pretend to be on the big core. */
return 0;
#endif
#else
/* Only ARM/ARM64/RISCV processors may include cores of different types in the same package. */
return 0;
#endif
}
uint32_t CPUINFO_ABI cpuinfo_get_current_uarch_index_with_default(uint32_t default_uarch_index) {
if CPUINFO_UNLIKELY(!cpuinfo_is_initialized) {
cpuinfo_log_fatal("cpuinfo_get_%s called before cpuinfo is initialized", "current_uarch_index_with_default");
}
#if CPUINFO_ARCH_ARM || CPUINFO_ARCH_ARM64 \
|| CPUINFO_ARCH_RISCV32 || CPUINFO_ARCH_RISCV64
#ifdef __linux__
if (cpuinfo_linux_cpu_to_uarch_index_map == NULL) {
/* Special case: avoid syscall on systems with only a single type of cores */
return 0;
}
/* General case */
/* Initializing this variable silences a MemorySanitizer error. */
unsigned cpu = 0;
if CPUINFO_UNLIKELY(syscall(__NR_getcpu, &cpu, NULL, NULL) != 0) {
return default_uarch_index;
}
if CPUINFO_UNLIKELY((uint32_t) cpu >= cpuinfo_linux_cpu_max) {
return default_uarch_index;
}
return cpuinfo_linux_cpu_to_uarch_index_map[cpu];
#else
/* Fallback: no API to query current core, use default uarch index. */
return default_uarch_index;
#endif
#else
/* Only ARM/ARM64/RISCV processors may include cores of different types in the same package. */
return 0;
#endif
}
-20
View File
@@ -1,20 +0,0 @@
#pragma once
#include <cpuinfo.h>
#include <cpuinfo/common.h>
#include <arm/api.h>
#include <arm/linux/api.h>
enum cpuinfo_android_chipset_property {
cpuinfo_android_chipset_property_proc_cpuinfo_hardware = 0,
cpuinfo_android_chipset_property_ro_product_board,
cpuinfo_android_chipset_property_ro_board_platform,
cpuinfo_android_chipset_property_ro_mediatek_platform,
cpuinfo_android_chipset_property_ro_arch,
cpuinfo_android_chipset_property_ro_chipname,
cpuinfo_android_chipset_property_ro_hardware_chipname,
cpuinfo_android_chipset_property_max,
};
CPUINFO_INTERNAL void cpuinfo_arm_android_parse_properties(
struct cpuinfo_android_properties properties[restrict static 1]);
-67
View File
@@ -1,67 +0,0 @@
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <sys/system_properties.h>
#include <linux/api.h>
#include <arm/android/api.h>
#include <arm/linux/api.h>
#include <cpuinfo/log.h>
#if CPUINFO_MOCK
#include <cpuinfo-mock.h>
static struct cpuinfo_mock_property* cpuinfo_mock_properties = NULL;
void CPUINFO_ABI cpuinfo_mock_android_properties(struct cpuinfo_mock_property* properties) {
cpuinfo_log_info("Android properties mocking enabled");
cpuinfo_mock_properties = properties;
}
static int cpuinfo_android_property_get(const char* key, char* value) {
if (cpuinfo_mock_properties != NULL) {
for (const struct cpuinfo_mock_property* prop = cpuinfo_mock_properties; prop->key != NULL; prop++) {
if (strncmp(key, prop->key, CPUINFO_BUILD_PROP_NAME_MAX) == 0) {
strncpy(value, prop->value, CPUINFO_BUILD_PROP_VALUE_MAX);
return (int) strnlen(prop->value, CPUINFO_BUILD_PROP_VALUE_MAX);
}
}
}
*value = '\0';
return 0;
}
#else
static inline int cpuinfo_android_property_get(const char* key, char* value) {
return __system_property_get(key, value);
}
#endif
void cpuinfo_arm_android_parse_properties(struct cpuinfo_android_properties properties[restrict static 1]) {
const int ro_product_board_length =
cpuinfo_android_property_get("ro.product.board", properties->ro_product_board);
cpuinfo_log_debug("read ro.product.board = \"%.*s\"", ro_product_board_length, properties->ro_product_board);
const int ro_board_platform_length =
cpuinfo_android_property_get("ro.board.platform", properties->ro_board_platform);
cpuinfo_log_debug("read ro.board.platform = \"%.*s\"", ro_board_platform_length, properties->ro_board_platform);
const int ro_mediatek_platform_length =
cpuinfo_android_property_get("ro.mediatek.platform", properties->ro_mediatek_platform);
cpuinfo_log_debug("read ro.mediatek.platform = \"%.*s\"",
ro_mediatek_platform_length, properties->ro_mediatek_platform);
const int ro_arch_length =
cpuinfo_android_property_get("ro.arch", properties->ro_arch);
cpuinfo_log_debug("read ro.arch = \"%.*s\"", ro_arch_length, properties->ro_arch);
const int ro_chipname_length =
cpuinfo_android_property_get("ro.chipname", properties->ro_chipname);
cpuinfo_log_debug("read ro.chipname = \"%.*s\"", ro_chipname_length, properties->ro_chipname);
const int ro_hardware_chipname_length =
cpuinfo_android_property_get("ro.hardware.chipname", properties->ro_hardware_chipname);
cpuinfo_log_debug("read ro.hardware.chipname = \"%.*s\"", ro_hardware_chipname_length, properties->ro_hardware_chipname);
}
-124
View File
@@ -1,124 +0,0 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <cpuinfo.h>
#include <cpuinfo/common.h>
enum cpuinfo_arm_chipset_vendor {
cpuinfo_arm_chipset_vendor_unknown = 0,
cpuinfo_arm_chipset_vendor_qualcomm,
cpuinfo_arm_chipset_vendor_mediatek,
cpuinfo_arm_chipset_vendor_samsung,
cpuinfo_arm_chipset_vendor_hisilicon,
cpuinfo_arm_chipset_vendor_actions,
cpuinfo_arm_chipset_vendor_allwinner,
cpuinfo_arm_chipset_vendor_amlogic,
cpuinfo_arm_chipset_vendor_broadcom,
cpuinfo_arm_chipset_vendor_lg,
cpuinfo_arm_chipset_vendor_leadcore,
cpuinfo_arm_chipset_vendor_marvell,
cpuinfo_arm_chipset_vendor_mstar,
cpuinfo_arm_chipset_vendor_novathor,
cpuinfo_arm_chipset_vendor_nvidia,
cpuinfo_arm_chipset_vendor_pinecone,
cpuinfo_arm_chipset_vendor_renesas,
cpuinfo_arm_chipset_vendor_rockchip,
cpuinfo_arm_chipset_vendor_spreadtrum,
cpuinfo_arm_chipset_vendor_telechips,
cpuinfo_arm_chipset_vendor_texas_instruments,
cpuinfo_arm_chipset_vendor_unisoc,
cpuinfo_arm_chipset_vendor_wondermedia,
cpuinfo_arm_chipset_vendor_max,
};
enum cpuinfo_arm_chipset_series {
cpuinfo_arm_chipset_series_unknown = 0,
cpuinfo_arm_chipset_series_qualcomm_qsd,
cpuinfo_arm_chipset_series_qualcomm_msm,
cpuinfo_arm_chipset_series_qualcomm_apq,
cpuinfo_arm_chipset_series_qualcomm_snapdragon,
cpuinfo_arm_chipset_series_mediatek_mt,
cpuinfo_arm_chipset_series_samsung_exynos,
cpuinfo_arm_chipset_series_hisilicon_k3v,
cpuinfo_arm_chipset_series_hisilicon_hi,
cpuinfo_arm_chipset_series_hisilicon_kirin,
cpuinfo_arm_chipset_series_actions_atm,
cpuinfo_arm_chipset_series_allwinner_a,
cpuinfo_arm_chipset_series_amlogic_aml,
cpuinfo_arm_chipset_series_amlogic_s,
cpuinfo_arm_chipset_series_broadcom_bcm,
cpuinfo_arm_chipset_series_lg_nuclun,
cpuinfo_arm_chipset_series_leadcore_lc,
cpuinfo_arm_chipset_series_marvell_pxa,
cpuinfo_arm_chipset_series_mstar_6a,
cpuinfo_arm_chipset_series_novathor_u,
cpuinfo_arm_chipset_series_nvidia_tegra_t,
cpuinfo_arm_chipset_series_nvidia_tegra_ap,
cpuinfo_arm_chipset_series_nvidia_tegra_sl,
cpuinfo_arm_chipset_series_pinecone_surge_s,
cpuinfo_arm_chipset_series_renesas_mp,
cpuinfo_arm_chipset_series_rockchip_rk,
cpuinfo_arm_chipset_series_spreadtrum_sc,
cpuinfo_arm_chipset_series_telechips_tcc,
cpuinfo_arm_chipset_series_texas_instruments_omap,
cpuinfo_arm_chipset_series_unisoc_t,
cpuinfo_arm_chipset_series_wondermedia_wm,
cpuinfo_arm_chipset_series_max,
};
#define CPUINFO_ARM_CHIPSET_SUFFIX_MAX 8
struct cpuinfo_arm_chipset {
enum cpuinfo_arm_chipset_vendor vendor;
enum cpuinfo_arm_chipset_series series;
uint32_t model;
char suffix[CPUINFO_ARM_CHIPSET_SUFFIX_MAX];
};
#define CPUINFO_ARM_CHIPSET_NAME_MAX CPUINFO_PACKAGE_NAME_MAX
#ifndef __cplusplus
CPUINFO_INTERNAL void cpuinfo_arm_chipset_to_string(
const struct cpuinfo_arm_chipset chipset[restrict static 1],
char name[restrict static CPUINFO_ARM_CHIPSET_NAME_MAX]);
CPUINFO_INTERNAL void cpuinfo_arm_fixup_chipset(
struct cpuinfo_arm_chipset chipset[restrict static 1], uint32_t cores, uint32_t max_cpu_freq_max);
CPUINFO_INTERNAL void cpuinfo_arm_decode_vendor_uarch(
uint32_t midr,
#if CPUINFO_ARCH_ARM
bool has_vfpv4,
#endif
enum cpuinfo_vendor vendor[restrict static 1],
enum cpuinfo_uarch uarch[restrict static 1]);
CPUINFO_INTERNAL void cpuinfo_arm_decode_cache(
enum cpuinfo_uarch uarch,
uint32_t cluster_cores,
uint32_t midr,
const struct cpuinfo_arm_chipset chipset[restrict static 1],
uint32_t cluster_id,
uint32_t arch_version,
struct cpuinfo_cache l1i[restrict static 1],
struct cpuinfo_cache l1d[restrict static 1],
struct cpuinfo_cache l2[restrict static 1],
struct cpuinfo_cache l3[restrict static 1]);
CPUINFO_INTERNAL uint32_t cpuinfo_arm_compute_max_cache_size(
const struct cpuinfo_processor processor[restrict static 1]);
#else /* defined(__cplusplus) */
CPUINFO_INTERNAL void cpuinfo_arm_decode_cache(
enum cpuinfo_uarch uarch,
uint32_t cluster_cores,
uint32_t midr,
const struct cpuinfo_arm_chipset chipset[1],
uint32_t cluster_id,
uint32_t arch_version,
struct cpuinfo_cache l1i[1],
struct cpuinfo_cache l1d[1],
struct cpuinfo_cache l2[1],
struct cpuinfo_cache l3[1]);
#endif
-1731
View File
File diff suppressed because it is too large Load Diff
-330
View File
@@ -1,330 +0,0 @@
#include <stdint.h>
#if CPUINFO_MOCK
#include <cpuinfo-mock.h>
#endif
#include <arm/linux/api.h>
#include <arm/linux/cp.h>
#include <arm/midr.h>
#include <cpuinfo/log.h>
#if CPUINFO_MOCK
uint32_t cpuinfo_arm_fpsid = 0;
uint32_t cpuinfo_arm_mvfr0 = 0;
uint32_t cpuinfo_arm_wcid = 0;
void cpuinfo_set_fpsid(uint32_t fpsid) {
cpuinfo_arm_fpsid = fpsid;
}
void cpuinfo_set_wcid(uint32_t wcid) {
cpuinfo_arm_wcid = wcid;
}
#endif
void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
uint32_t features,
uint32_t features2,
uint32_t midr,
uint32_t architecture_version,
uint32_t architecture_flags,
const struct cpuinfo_arm_chipset chipset[restrict static 1],
struct cpuinfo_arm_isa isa[restrict static 1])
{
if (architecture_version < 8) {
const uint32_t armv8_features2_mask = CPUINFO_ARM_LINUX_FEATURE2_AES | CPUINFO_ARM_LINUX_FEATURE2_PMULL |
CPUINFO_ARM_LINUX_FEATURE2_SHA1 | CPUINFO_ARM_LINUX_FEATURE2_SHA2 | CPUINFO_ARM_LINUX_FEATURE2_CRC32;
if (features2 & armv8_features2_mask) {
architecture_version = 8;
}
}
if (architecture_version >= 8) {
/*
* ARMv7 code running on ARMv8: IDIV, VFP, NEON are always supported,
* but may be not reported in /proc/cpuinfo features.
*/
isa->armv5e = true;
isa->armv6 = true;
isa->armv6k = true;
isa->armv7 = true;
isa->armv7mp = true;
isa->armv8 = true;
isa->thumb = true;
isa->thumb2 = true;
isa->idiv = true;
isa->vfpv3 = true;
isa->d32 = true;
isa->fp16 = true;
isa->fma = true;
isa->neon = true;
/*
* NEON FP16 compute extension and VQRDMLAH/VQRDMLSH instructions are not indicated in /proc/cpuinfo.
* Use a MIDR-based heuristic to whitelist processors known to support it:
* - Processors with Cortex-A55 cores
* - Processors with Cortex-A75 cores
* - Processors with Cortex-A76 cores
* - Processors with Cortex-A77 cores
* - Processors with Cortex-A78 cores
* - Processors with Cortex-A510 cores
* - Processors with Cortex-A710 cores
* - Processors with Cortex-A715 cores
* - Processors with Cortex-X1 cores
* - Processors with Cortex-X2 cores
* - Processors with Cortex-X3 cores
* - Processors with Exynos M4 cores
* - Processors with Exynos M5 cores
* - Neoverse N1 cores
* - Neoverse N2 cores
* - Neoverse V1 cores
* - Neoverse V2 cores
*/
if (chipset->series == cpuinfo_arm_chipset_series_samsung_exynos && chipset->model == 9810) {
/* Only little cores of Exynos 9810 support FP16 & RDM */
cpuinfo_log_warning("FP16 arithmetics and RDM disabled: only little cores in Exynos 9810 support these extensions");
} else {
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
case UINT32_C(0x4100D050): /* Cortex-A55 */
case UINT32_C(0x4100D0A0): /* Cortex-A75 */
case UINT32_C(0x4100D0B0): /* Cortex-A76 */
case UINT32_C(0x4100D0C0): /* Neoverse N1 */
case UINT32_C(0x4100D0D0): /* Cortex-A77 */
case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
case UINT32_C(0x4100D400): /* Neoverse V1 */
case UINT32_C(0x4100D410): /* Cortex-A78 */
case UINT32_C(0x4100D440): /* Cortex-X1 */
case UINT32_C(0x4100D460): /* Cortex-A510 */
case UINT32_C(0x4100D470): /* Cortex-A710 */
case UINT32_C(0x4100D480): /* Cortex-X2 */
case UINT32_C(0x4100D490): /* Neoverse N2 */
case UINT32_C(0x4100D4D0): /* Cortex-A715 */
case UINT32_C(0x4100D4E0): /* Cortex-X3 */
case UINT32_C(0x4100D4F0): /* Neoverse V2 */
case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
case UINT32_C(0x51008020): /* Kryo 385 Gold (Cortex-A75) */
case UINT32_C(0x51008030): /* Kryo 385 Silver (Cortex-A55) */
case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */
case UINT32_C(0x51008050): /* Kryo 485 Silver (Cortex-A55) */
case UINT32_C(0x53000030): /* Exynos M4 */
case UINT32_C(0x53000040): /* Exynos M5 */
isa->fp16arith = true;
isa->rdm = true;
break;
}
}
/*
* NEON VDOT instructions are not indicated in /proc/cpuinfo.
* Use a MIDR-based heuristic to whitelist processors known to support it:
* - Processors with Cortex-A76 cores
* - Processors with Cortex-A77 cores
* - Processors with Cortex-A78 cores
* - Processors with Cortex-A510 cores
* - Processors with Cortex-A710 cores
* - Processors with Cortex-A715 cores
* - Processors with Cortex-X1 cores
* - Processors with Cortex-X2 cores
* - Processors with Cortex-X3 cores
* - Processors with Exynos M4 cores
* - Processors with Exynos M5 cores
* - Neoverse N1 cores
* - Neoverse N2 cores
* - Neoverse V1 cores
* - Neoverse V2 cores
*/
if (chipset->series == cpuinfo_arm_chipset_series_spreadtrum_sc && chipset->model == 9863) {
cpuinfo_log_warning("VDOT instructions disabled: cause occasional SIGILL on Spreadtrum SC9863A");
} else if (chipset->series == cpuinfo_arm_chipset_series_unisoc_t && chipset->model == 310) {
cpuinfo_log_warning("VDOT instructions disabled: cause occasional SIGILL on Unisoc T310");
} else {
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
case UINT32_C(0x4100D0B0): /* Cortex-A76 */
case UINT32_C(0x4100D0C0): /* Neoverse N1 */
case UINT32_C(0x4100D0D0): /* Cortex-A77 */
case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
case UINT32_C(0x4100D400): /* Neoverse V1 */
case UINT32_C(0x4100D410): /* Cortex-A78 */
case UINT32_C(0x4100D440): /* Cortex-X1 */
case UINT32_C(0x4100D460): /* Cortex-A510 */
case UINT32_C(0x4100D470): /* Cortex-A710 */
case UINT32_C(0x4100D480): /* Cortex-X2 */
case UINT32_C(0x4100D490): /* Neoverse N2 */
case UINT32_C(0x4100D4D0): /* Cortex-A715 */
case UINT32_C(0x4100D4E0): /* Cortex-X3 */
case UINT32_C(0x4100D4F0): /* Neoverse V2 */
case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */
case UINT32_C(0x51008050): /* Kryo 485 Silver (Cortex-A55) */
case UINT32_C(0x53000030): /* Exynos M4 */
case UINT32_C(0x53000040): /* Exynos M5 */
isa->dot = true;
break;
case UINT32_C(0x4100D050): /* Cortex A55: revision 1 or later only */
isa->dot = !!(midr_get_variant(midr) >= 1);
break;
case UINT32_C(0x4100D0A0): /* Cortex A75: revision 2 or later only */
isa->dot = !!(midr_get_variant(midr) >= 2);
break;
}
}
} else {
/* ARMv7 or lower: use feature flags to detect optional features */
/*
* ARM11 (ARM 1136/1156/1176/11 MPCore) processors can report v7 architecture
* even though they support only ARMv6 instruction set.
*/
if (architecture_version == 7 && midr_is_arm11(midr)) {
cpuinfo_log_warning("kernel-reported architecture ARMv7 ignored due to mismatch with processor microarchitecture (ARM11)");
architecture_version = 6;
}
if (architecture_version < 7) {
const uint32_t armv7_features_mask = CPUINFO_ARM_LINUX_FEATURE_VFPV3 | CPUINFO_ARM_LINUX_FEATURE_VFPV3D16 | CPUINFO_ARM_LINUX_FEATURE_VFPD32 |
CPUINFO_ARM_LINUX_FEATURE_VFPV4 | CPUINFO_ARM_LINUX_FEATURE_NEON | CPUINFO_ARM_LINUX_FEATURE_IDIVT | CPUINFO_ARM_LINUX_FEATURE_IDIVA;
if (features & armv7_features_mask) {
architecture_version = 7;
}
}
if ((architecture_version >= 6) || (features & CPUINFO_ARM_LINUX_FEATURE_EDSP) || (architecture_flags & CPUINFO_ARM_LINUX_ARCH_E)) {
isa->armv5e = true;
}
if (architecture_version >= 6) {
isa->armv6 = true;
}
if (architecture_version >= 7) {
isa->armv6k = true;
isa->armv7 = true;
/*
* ARMv7 MP extension (PLDW instruction) is not indicated in /proc/cpuinfo.
* Use heuristic list of supporting processors:
* - Processors supporting UDIV/SDIV instructions ("idiva" + "idivt" features in /proc/cpuinfo)
* - Cortex-A5
* - Cortex-A9
* - Dual-Core Scorpion
* - Krait (supports UDIV/SDIV, but kernels may not report it in /proc/cpuinfo)
*
* TODO: check single-core Qualcomm Scorpion.
*/
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
case UINT32_C(0x4100C050): /* Cortex-A5 */
case UINT32_C(0x4100C090): /* Cortex-A9 */
case UINT32_C(0x510002D0): /* Scorpion (dual-core) */
case UINT32_C(0x510004D0): /* Krait (dual-core) */
case UINT32_C(0x510006F0): /* Krait (quad-core) */
isa->armv7mp = true;
break;
default:
/* In practice IDIV instruction implies ARMv7+MP ISA */
isa->armv7mp = (features & CPUINFO_ARM_LINUX_FEATURE_IDIV) == CPUINFO_ARM_LINUX_FEATURE_IDIV;
break;
}
}
if (features & CPUINFO_ARM_LINUX_FEATURE_IWMMXT) {
#if !defined(__ARM_ARCH_8A__) && !(defined(__ARM_ARCH) && (__ARM_ARCH >= 8))
const uint32_t wcid = read_wcid();
cpuinfo_log_debug("WCID = 0x%08"PRIx32, wcid);
const uint32_t coprocessor_type = (wcid >> 8) & UINT32_C(0xFF);
if (coprocessor_type >= 0x10) {
isa->wmmx = true;
if (coprocessor_type >= 0x20) {
isa->wmmx2 = true;
}
} else {
cpuinfo_log_warning("WMMX ISA disabled: OS reported iwmmxt feature, "
"but WCID coprocessor type 0x%"PRIx32" indicates no WMMX support",
coprocessor_type);
}
#else
cpuinfo_log_warning("WMMX ISA disabled: OS reported iwmmxt feature, "
"but there is no iWMMXt coprocessor");
#endif
}
if ((features & CPUINFO_ARM_LINUX_FEATURE_THUMB) || (architecture_flags & CPUINFO_ARM_LINUX_ARCH_T)) {
isa->thumb = true;
/*
* There is no separate feature flag for Thumb 2.
* All ARMv7 processors and ARM 1156 support Thumb 2.
*/
if (architecture_version >= 7 || midr_is_arm1156(midr)) {
isa->thumb2 = true;
}
}
if (features & CPUINFO_ARM_LINUX_FEATURE_THUMBEE) {
isa->thumbee = true;
}
if ((features & CPUINFO_ARM_LINUX_FEATURE_JAVA) || (architecture_flags & CPUINFO_ARM_LINUX_ARCH_J)) {
isa->jazelle = true;
}
/* Qualcomm Krait may have buggy kernel configuration that doesn't report IDIV */
if ((features & CPUINFO_ARM_LINUX_FEATURE_IDIV) == CPUINFO_ARM_LINUX_FEATURE_IDIV || midr_is_krait(midr)) {
isa->idiv = true;
}
const uint32_t vfp_mask = \
CPUINFO_ARM_LINUX_FEATURE_VFP | CPUINFO_ARM_LINUX_FEATURE_VFPV3 | CPUINFO_ARM_LINUX_FEATURE_VFPV3D16 | \
CPUINFO_ARM_LINUX_FEATURE_VFPD32 | CPUINFO_ARM_LINUX_FEATURE_VFPV4 | CPUINFO_ARM_LINUX_FEATURE_NEON;
if (features & vfp_mask) {
const uint32_t vfpv3_mask = CPUINFO_ARM_LINUX_FEATURE_VFPV3 | CPUINFO_ARM_LINUX_FEATURE_VFPV3D16 | \
CPUINFO_ARM_LINUX_FEATURE_VFPD32 | CPUINFO_ARM_LINUX_FEATURE_VFPV4 | CPUINFO_ARM_LINUX_FEATURE_NEON;
if ((architecture_version >= 7) || (features & vfpv3_mask)) {
isa->vfpv3 = true;
const uint32_t d32_mask = CPUINFO_ARM_LINUX_FEATURE_VFPD32 | CPUINFO_ARM_LINUX_FEATURE_NEON;
if (features & d32_mask) {
isa->d32 = true;
}
} else {
#if defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_8A__) || defined(__ARM_ARCH) && (__ARM_ARCH >= 7)
isa->vfpv3 = true;
#else
const uint32_t fpsid = read_fpsid();
cpuinfo_log_debug("FPSID = 0x%08"PRIx32, fpsid);
const uint32_t subarchitecture = (fpsid >> 16) & UINT32_C(0x7F);
if (subarchitecture >= 0x01) {
isa->vfpv2 = true;
}
#endif
}
}
if (features & CPUINFO_ARM_LINUX_FEATURE_NEON) {
isa->neon = true;
}
/*
* There is no separate feature flag for FP16 support.
* VFPv4 implies VFPv3-FP16 support (and in practice, NEON-HP as well).
* Additionally, ARM Cortex-A9 and Qualcomm Scorpion support FP16.
*/
if ((features & CPUINFO_ARM_LINUX_FEATURE_VFPV4) || midr_is_cortex_a9(midr) || midr_is_scorpion(midr)) {
isa->fp16 = true;
}
if (features & CPUINFO_ARM_LINUX_FEATURE_VFPV4) {
isa->fma = true;
}
}
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_AES) {
isa->aes = true;
}
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_PMULL) {
isa->pmull = true;
}
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SHA1) {
isa->sha1 = true;
}
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SHA2) {
isa->sha2 = true;
}
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_CRC32) {
isa->crc32 = true;
}
}
-149
View File
@@ -1,149 +0,0 @@
#include <stdint.h>
#include <arm/linux/api.h>
#include <cpuinfo/log.h>
void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
uint32_t features,
uint32_t features2,
uint32_t midr,
const struct cpuinfo_arm_chipset chipset[restrict static 1],
struct cpuinfo_arm_isa isa[restrict static 1])
{
if (features & CPUINFO_ARM_LINUX_FEATURE_AES) {
isa->aes = true;
}
if (features & CPUINFO_ARM_LINUX_FEATURE_PMULL) {
isa->pmull = true;
}
if (features & CPUINFO_ARM_LINUX_FEATURE_SHA1) {
isa->sha1 = true;
}
if (features & CPUINFO_ARM_LINUX_FEATURE_SHA2) {
isa->sha2 = true;
}
if (features & CPUINFO_ARM_LINUX_FEATURE_CRC32) {
isa->crc32 = true;
}
if (features & CPUINFO_ARM_LINUX_FEATURE_ATOMICS) {
isa->atomics = true;
}
/*
* Some phones ship with an old kernel configuration that doesn't report NEON FP16 compute extension and SQRDMLAH/SQRDMLSH/UQRDMLAH/UQRDMLSH instructions.
* Use a MIDR-based heuristic to whitelist processors known to support it:
* - Processors with Cortex-A55 cores
* - Processors with Cortex-A65 cores
* - Processors with Cortex-A75 cores
* - Processors with Cortex-A76 cores
* - Processors with Cortex-A77 cores
* - Processors with Exynos M4 cores
* - Processors with Exynos M5 cores
* - Neoverse N1 cores
* - Neoverse V1 cores
* - Neoverse N2 cores
* - Neoverse V2 cores
*/
if (chipset->series == cpuinfo_arm_chipset_series_samsung_exynos && chipset->model == 9810) {
/* Exynos 9810 reports that it supports FP16 compute, but in fact only little cores do */
cpuinfo_log_warning("FP16 arithmetics and RDM disabled: only little cores in Exynos 9810 support these extensions");
} else {
const uint32_t fp16arith_mask = CPUINFO_ARM_LINUX_FEATURE_FPHP | CPUINFO_ARM_LINUX_FEATURE_ASIMDHP;
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
case UINT32_C(0x4100D050): /* Cortex-A55 */
case UINT32_C(0x4100D060): /* Cortex-A65 */
case UINT32_C(0x4100D0A0): /* Cortex-A75 */
case UINT32_C(0x4100D0B0): /* Cortex-A76 */
case UINT32_C(0x4100D0C0): /* Neoverse N1 */
case UINT32_C(0x4100D0D0): /* Cortex-A77 */
case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
case UINT32_C(0x4100D400): /* Neoverse V1 */
case UINT32_C(0x4100D490): /* Neoverse N2 */
case UINT32_C(0x4100D4F0): /* Neoverse V2 */
case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
case UINT32_C(0x51008020): /* Kryo 385 Gold (Cortex-A75) */
case UINT32_C(0x51008030): /* Kryo 385 Silver (Cortex-A55) */
case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */
case UINT32_C(0x51008050): /* Kryo 485 Silver (Cortex-A55) */
case UINT32_C(0x53000030): /* Exynos M4 */
case UINT32_C(0x53000040): /* Exynos M5 */
isa->fp16arith = true;
isa->rdm = true;
break;
default:
if ((features & fp16arith_mask) == fp16arith_mask) {
isa->fp16arith = true;
} else if (features & CPUINFO_ARM_LINUX_FEATURE_FPHP) {
cpuinfo_log_warning("FP16 arithmetics disabled: detected support only for scalar operations");
} else if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDHP) {
cpuinfo_log_warning("FP16 arithmetics disabled: detected support only for SIMD operations");
}
if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDRDM) {
isa->rdm = true;
}
break;
}
}
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_I8MM) {
isa->i8mm = true;
}
/*
* Many phones ship with an old kernel configuration that doesn't report UDOT/SDOT instructions.
* Use a MIDR-based heuristic to whitelist processors known to support it.
*/
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
case UINT32_C(0x4100D060): /* Cortex-A65 */
case UINT32_C(0x4100D0B0): /* Cortex-A76 */
case UINT32_C(0x4100D0C0): /* Neoverse N1 */
case UINT32_C(0x4100D0D0): /* Cortex-A77 */
case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
case UINT32_C(0x4100D400): /* Neoverse V1 */
case UINT32_C(0x4100D490): /* Neoverse N2 */
case UINT32_C(0x4100D4A0): /* Neoverse E1 */
case UINT32_C(0x4100D4F0): /* Neoverse V2 */
case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
case UINT32_C(0x51008040): /* Kryo 485 Gold (Cortex-A76) */
case UINT32_C(0x51008050): /* Kryo 485 Silver (Cortex-A55) */
case UINT32_C(0x53000030): /* Exynos-M4 */
case UINT32_C(0x53000040): /* Exynos-M5 */
isa->dot = true;
break;
case UINT32_C(0x4100D050): /* Cortex A55: revision 1 or later only */
isa->dot = !!(midr_get_variant(midr) >= 1);
break;
case UINT32_C(0x4100D0A0): /* Cortex A75: revision 2 or later only */
isa->dot = !!(midr_get_variant(midr) >= 2);
break;
default:
if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDDP) {
isa->dot = true;
}
break;
}
if (features & CPUINFO_ARM_LINUX_FEATURE_JSCVT) {
isa->jscvt = true;
}
if (features & CPUINFO_ARM_LINUX_FEATURE_JSCVT) {
isa->jscvt = true;
}
if (features & CPUINFO_ARM_LINUX_FEATURE_FCMA) {
isa->fcma = true;
}
if (features & CPUINFO_ARM_LINUX_FEATURE_SVE) {
isa->sve = true;
}
if (features2 & CPUINFO_ARM_LINUX_FEATURE2_SVE2) {
isa->sve2 = true;
}
// SVEBF16 is set iff SVE and BF16 are both supported, but the SVEBF16 feature flag
// was added in Linux kernel before the BF16 feature flag, so we check for either.
if (features2 & (CPUINFO_ARM_LINUX_FEATURE2_BF16 | CPUINFO_ARM_LINUX_FEATURE2_SVEBF16)) {
isa->bf16 = true;
}
if (features & CPUINFO_ARM_LINUX_FEATURE_ASIMDFHM) {
isa->fhm = true;
}
}
-384
View File
@@ -1,384 +0,0 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <cpuinfo.h>
#include <cpuinfo/common.h>
#include <arm/midr.h>
#include <arm/api.h>
#include <linux/api.h>
/* No hard limit in the kernel, maximum length observed on non-rogue kernels is 64 */
#define CPUINFO_HARDWARE_VALUE_MAX 64
/* No hard limit in the kernel, maximum length on Raspberry Pi is 8. Add 1 symbol to detect overly large revision strings */
#define CPUINFO_REVISION_VALUE_MAX 9
#ifdef __ANDROID__
/* As per include/sys/system_properties.h in Android NDK */
#define CPUINFO_BUILD_PROP_NAME_MAX 32
#define CPUINFO_BUILD_PROP_VALUE_MAX 92
struct cpuinfo_android_properties {
char proc_cpuinfo_hardware[CPUINFO_HARDWARE_VALUE_MAX];
char ro_product_board[CPUINFO_BUILD_PROP_VALUE_MAX];
char ro_board_platform[CPUINFO_BUILD_PROP_VALUE_MAX];
char ro_mediatek_platform[CPUINFO_BUILD_PROP_VALUE_MAX];
char ro_arch[CPUINFO_BUILD_PROP_VALUE_MAX];
char ro_chipname[CPUINFO_BUILD_PROP_VALUE_MAX];
char ro_hardware_chipname[CPUINFO_BUILD_PROP_VALUE_MAX];
};
#endif
#define CPUINFO_ARM_LINUX_ARCH_T UINT32_C(0x00000001)
#define CPUINFO_ARM_LINUX_ARCH_E UINT32_C(0x00000002)
#define CPUINFO_ARM_LINUX_ARCH_J UINT32_C(0x00000004)
#define CPUINFO_ARM_LINUX_ARCH_TE UINT32_C(0x00000003)
#define CPUINFO_ARM_LINUX_ARCH_TEJ UINT32_C(0x00000007)
struct cpuinfo_arm_linux_proc_cpuinfo_cache {
uint32_t i_size;
uint32_t i_assoc;
uint32_t i_line_length;
uint32_t i_sets;
uint32_t d_size;
uint32_t d_assoc;
uint32_t d_line_length;
uint32_t d_sets;
};
#if CPUINFO_ARCH_ARM
/* arch/arm/include/uapi/asm/hwcap.h */
#define CPUINFO_ARM_LINUX_FEATURE_SWP UINT32_C(0x00000001)
#define CPUINFO_ARM_LINUX_FEATURE_HALF UINT32_C(0x00000002)
#define CPUINFO_ARM_LINUX_FEATURE_THUMB UINT32_C(0x00000004)
#define CPUINFO_ARM_LINUX_FEATURE_26BIT UINT32_C(0x00000008)
#define CPUINFO_ARM_LINUX_FEATURE_FASTMULT UINT32_C(0x00000010)
#define CPUINFO_ARM_LINUX_FEATURE_FPA UINT32_C(0x00000020)
#define CPUINFO_ARM_LINUX_FEATURE_VFP UINT32_C(0x00000040)
#define CPUINFO_ARM_LINUX_FEATURE_EDSP UINT32_C(0x00000080)
#define CPUINFO_ARM_LINUX_FEATURE_JAVA UINT32_C(0x00000100)
#define CPUINFO_ARM_LINUX_FEATURE_IWMMXT UINT32_C(0x00000200)
#define CPUINFO_ARM_LINUX_FEATURE_CRUNCH UINT32_C(0x00000400)
#define CPUINFO_ARM_LINUX_FEATURE_THUMBEE UINT32_C(0x00000800)
#define CPUINFO_ARM_LINUX_FEATURE_NEON UINT32_C(0x00001000)
#define CPUINFO_ARM_LINUX_FEATURE_VFPV3 UINT32_C(0x00002000)
#define CPUINFO_ARM_LINUX_FEATURE_VFPV3D16 UINT32_C(0x00004000) /* Also set for VFPv4 with 16 double-precision registers */
#define CPUINFO_ARM_LINUX_FEATURE_TLS UINT32_C(0x00008000)
#define CPUINFO_ARM_LINUX_FEATURE_VFPV4 UINT32_C(0x00010000)
#define CPUINFO_ARM_LINUX_FEATURE_IDIVA UINT32_C(0x00020000)
#define CPUINFO_ARM_LINUX_FEATURE_IDIVT UINT32_C(0x00040000)
#define CPUINFO_ARM_LINUX_FEATURE_IDIV UINT32_C(0x00060000)
#define CPUINFO_ARM_LINUX_FEATURE_VFPD32 UINT32_C(0x00080000)
#define CPUINFO_ARM_LINUX_FEATURE_LPAE UINT32_C(0x00100000)
#define CPUINFO_ARM_LINUX_FEATURE_EVTSTRM UINT32_C(0x00200000)
#define CPUINFO_ARM_LINUX_FEATURE2_AES UINT32_C(0x00000001)
#define CPUINFO_ARM_LINUX_FEATURE2_PMULL UINT32_C(0x00000002)
#define CPUINFO_ARM_LINUX_FEATURE2_SHA1 UINT32_C(0x00000004)
#define CPUINFO_ARM_LINUX_FEATURE2_SHA2 UINT32_C(0x00000008)
#define CPUINFO_ARM_LINUX_FEATURE2_CRC32 UINT32_C(0x00000010)
#elif CPUINFO_ARCH_ARM64
/* arch/arm64/include/uapi/asm/hwcap.h */
#define CPUINFO_ARM_LINUX_FEATURE_FP UINT32_C(0x00000001)
#define CPUINFO_ARM_LINUX_FEATURE_ASIMD UINT32_C(0x00000002)
#define CPUINFO_ARM_LINUX_FEATURE_EVTSTRM UINT32_C(0x00000004)
#define CPUINFO_ARM_LINUX_FEATURE_AES UINT32_C(0x00000008)
#define CPUINFO_ARM_LINUX_FEATURE_PMULL UINT32_C(0x00000010)
#define CPUINFO_ARM_LINUX_FEATURE_SHA1 UINT32_C(0x00000020)
#define CPUINFO_ARM_LINUX_FEATURE_SHA2 UINT32_C(0x00000040)
#define CPUINFO_ARM_LINUX_FEATURE_CRC32 UINT32_C(0x00000080)
#define CPUINFO_ARM_LINUX_FEATURE_ATOMICS UINT32_C(0x00000100)
#define CPUINFO_ARM_LINUX_FEATURE_FPHP UINT32_C(0x00000200)
#define CPUINFO_ARM_LINUX_FEATURE_ASIMDHP UINT32_C(0x00000400)
#define CPUINFO_ARM_LINUX_FEATURE_CPUID UINT32_C(0x00000800)
#define CPUINFO_ARM_LINUX_FEATURE_ASIMDRDM UINT32_C(0x00001000)
#define CPUINFO_ARM_LINUX_FEATURE_JSCVT UINT32_C(0x00002000)
#define CPUINFO_ARM_LINUX_FEATURE_FCMA UINT32_C(0x00004000)
#define CPUINFO_ARM_LINUX_FEATURE_LRCPC UINT32_C(0x00008000)
#define CPUINFO_ARM_LINUX_FEATURE_DCPOP UINT32_C(0x00010000)
#define CPUINFO_ARM_LINUX_FEATURE_SHA3 UINT32_C(0x00020000)
#define CPUINFO_ARM_LINUX_FEATURE_SM3 UINT32_C(0x00040000)
#define CPUINFO_ARM_LINUX_FEATURE_SM4 UINT32_C(0x00080000)
#define CPUINFO_ARM_LINUX_FEATURE_ASIMDDP UINT32_C(0x00100000)
#define CPUINFO_ARM_LINUX_FEATURE_SHA512 UINT32_C(0x00200000)
#define CPUINFO_ARM_LINUX_FEATURE_SVE UINT32_C(0x00400000)
#define CPUINFO_ARM_LINUX_FEATURE_ASIMDFHM UINT32_C(0x00800000)
#define CPUINFO_ARM_LINUX_FEATURE_DIT UINT32_C(0x01000000)
#define CPUINFO_ARM_LINUX_FEATURE_USCAT UINT32_C(0x02000000)
#define CPUINFO_ARM_LINUX_FEATURE_ILRCPC UINT32_C(0x04000000)
#define CPUINFO_ARM_LINUX_FEATURE_FLAGM UINT32_C(0x08000000)
#define CPUINFO_ARM_LINUX_FEATURE_SSBS UINT32_C(0x10000000)
#define CPUINFO_ARM_LINUX_FEATURE_SB UINT32_C(0x20000000)
#define CPUINFO_ARM_LINUX_FEATURE_PACA UINT32_C(0x40000000)
#define CPUINFO_ARM_LINUX_FEATURE_PACG UINT32_C(0x80000000)
#define CPUINFO_ARM_LINUX_FEATURE2_DCPODP UINT32_C(0x00000001)
#define CPUINFO_ARM_LINUX_FEATURE2_SVE2 UINT32_C(0x00000002)
#define CPUINFO_ARM_LINUX_FEATURE2_SVEAES UINT32_C(0x00000004)
#define CPUINFO_ARM_LINUX_FEATURE2_SVEPMULL UINT32_C(0x00000008)
#define CPUINFO_ARM_LINUX_FEATURE2_SVEBITPERM UINT32_C(0x00000010)
#define CPUINFO_ARM_LINUX_FEATURE2_SVESHA3 UINT32_C(0x00000020)
#define CPUINFO_ARM_LINUX_FEATURE2_SVESM4 UINT32_C(0x00000040)
#define CPUINFO_ARM_LINUX_FEATURE2_FLAGM2 UINT32_C(0x00000080)
#define CPUINFO_ARM_LINUX_FEATURE2_FRINT UINT32_C(0x00000100)
#define CPUINFO_ARM_LINUX_FEATURE2_SVEI8MM UINT32_C(0x00000200)
#define CPUINFO_ARM_LINUX_FEATURE2_SVEF32MM UINT32_C(0x00000400)
#define CPUINFO_ARM_LINUX_FEATURE2_SVEF64MM UINT32_C(0x00000800)
#define CPUINFO_ARM_LINUX_FEATURE2_SVEBF16 UINT32_C(0x00001000)
#define CPUINFO_ARM_LINUX_FEATURE2_I8MM UINT32_C(0x00002000)
#define CPUINFO_ARM_LINUX_FEATURE2_BF16 UINT32_C(0x00004000)
#define CPUINFO_ARM_LINUX_FEATURE2_DGH UINT32_C(0x00008000)
#define CPUINFO_ARM_LINUX_FEATURE2_RNG UINT32_C(0x00010000)
#define CPUINFO_ARM_LINUX_FEATURE2_BTI UINT32_C(0x00020000)
#endif
#define CPUINFO_ARM_LINUX_VALID_ARCHITECTURE UINT32_C(0x00010000)
#define CPUINFO_ARM_LINUX_VALID_IMPLEMENTER UINT32_C(0x00020000)
#define CPUINFO_ARM_LINUX_VALID_VARIANT UINT32_C(0x00040000)
#define CPUINFO_ARM_LINUX_VALID_PART UINT32_C(0x00080000)
#define CPUINFO_ARM_LINUX_VALID_REVISION UINT32_C(0x00100000)
#define CPUINFO_ARM_LINUX_VALID_PROCESSOR UINT32_C(0x00200000)
#define CPUINFO_ARM_LINUX_VALID_FEATURES UINT32_C(0x00400000)
#if CPUINFO_ARCH_ARM
#define CPUINFO_ARM_LINUX_VALID_ICACHE_SIZE UINT32_C(0x01000000)
#define CPUINFO_ARM_LINUX_VALID_ICACHE_SETS UINT32_C(0x02000000)
#define CPUINFO_ARM_LINUX_VALID_ICACHE_WAYS UINT32_C(0x04000000)
#define CPUINFO_ARM_LINUX_VALID_ICACHE_LINE UINT32_C(0x08000000)
#define CPUINFO_ARM_LINUX_VALID_DCACHE_SIZE UINT32_C(0x10000000)
#define CPUINFO_ARM_LINUX_VALID_DCACHE_SETS UINT32_C(0x20000000)
#define CPUINFO_ARM_LINUX_VALID_DCACHE_WAYS UINT32_C(0x40000000)
#define CPUINFO_ARM_LINUX_VALID_DCACHE_LINE UINT32_C(0x80000000)
#endif
#define CPUINFO_ARM_LINUX_VALID_INFO UINT32_C(0x007F0000)
#define CPUINFO_ARM_LINUX_VALID_MIDR UINT32_C(0x003F0000)
#if CPUINFO_ARCH_ARM
#define CPUINFO_ARM_LINUX_VALID_ICACHE UINT32_C(0x0F000000)
#define CPUINFO_ARM_LINUX_VALID_DCACHE UINT32_C(0xF0000000)
#define CPUINFO_ARM_LINUX_VALID_CACHE_LINE UINT32_C(0x88000000)
#endif
struct cpuinfo_arm_linux_processor {
uint32_t architecture_version;
#if CPUINFO_ARCH_ARM
uint32_t architecture_flags;
struct cpuinfo_arm_linux_proc_cpuinfo_cache proc_cpuinfo_cache;
#endif
uint32_t features;
uint32_t features2;
/**
* Main ID Register value.
*/
uint32_t midr;
enum cpuinfo_vendor vendor;
enum cpuinfo_uarch uarch;
uint32_t uarch_index;
/**
* ID of the physical package which includes this logical processor.
* The value is parsed from /sys/devices/system/cpu/cpu<N>/topology/physical_package_id
*/
uint32_t package_id;
/**
* Minimum processor ID on the package which includes this logical processor.
* This value can serve as an ID for the cluster of logical processors: it is the
* same for all logical processors on the same package.
*/
uint32_t package_leader_id;
/**
* Number of logical processors in the package.
*/
uint32_t package_processor_count;
/**
* Maximum frequency, in kHZ.
* The value is parsed from /sys/devices/system/cpu/cpu<N>/cpufreq/cpuinfo_max_freq
* If failed to read or parse the file, the value is 0.
*/
uint32_t max_frequency;
/**
* Minimum frequency, in kHZ.
* The value is parsed from /sys/devices/system/cpu/cpu<N>/cpufreq/cpuinfo_min_freq
* If failed to read or parse the file, the value is 0.
*/
uint32_t min_frequency;
/** Linux processor ID */
uint32_t system_processor_id;
uint32_t flags;
};
struct cpuinfo_arm_linux_cluster {
uint32_t processor_id_min;
uint32_t processor_id_max;
};
/* Returns true if the two processors do belong to the same cluster */
static inline bool cpuinfo_arm_linux_processor_equals(
struct cpuinfo_arm_linux_processor processor_i[restrict static 1],
struct cpuinfo_arm_linux_processor processor_j[restrict static 1])
{
const uint32_t joint_flags = processor_i->flags & processor_j->flags;
bool same_max_frequency = false;
if (joint_flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
if (processor_i->max_frequency != processor_j->max_frequency) {
return false;
} else {
same_max_frequency = true;
}
}
bool same_min_frequency = false;
if (joint_flags & CPUINFO_LINUX_FLAG_MIN_FREQUENCY) {
if (processor_i->min_frequency != processor_j->min_frequency) {
return false;
} else {
same_min_frequency = true;
}
}
if ((joint_flags & CPUINFO_ARM_LINUX_VALID_MIDR) == CPUINFO_ARM_LINUX_VALID_MIDR) {
if (processor_i->midr == processor_j->midr) {
if (midr_is_cortex_a53(processor_i->midr)) {
return same_min_frequency & same_max_frequency;
} else {
return true;
}
}
}
return same_max_frequency && same_min_frequency;
}
/* Returns true if the two processors certainly don't belong to the same cluster */
static inline bool cpuinfo_arm_linux_processor_not_equals(
struct cpuinfo_arm_linux_processor processor_i[restrict static 1],
struct cpuinfo_arm_linux_processor processor_j[restrict static 1])
{
const uint32_t joint_flags = processor_i->flags & processor_j->flags;
if (joint_flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
if (processor_i->max_frequency != processor_j->max_frequency) {
return true;
}
}
if (joint_flags & CPUINFO_LINUX_FLAG_MIN_FREQUENCY) {
if (processor_i->min_frequency != processor_j->min_frequency) {
return true;
}
}
if ((joint_flags & CPUINFO_ARM_LINUX_VALID_MIDR) == CPUINFO_ARM_LINUX_VALID_MIDR) {
if (processor_i->midr != processor_j->midr) {
return true;
}
}
return false;
}
CPUINFO_INTERNAL bool cpuinfo_arm_linux_parse_proc_cpuinfo(
char hardware[restrict static CPUINFO_HARDWARE_VALUE_MAX],
char revision[restrict static CPUINFO_REVISION_VALUE_MAX],
uint32_t max_processors_count,
struct cpuinfo_arm_linux_processor processors[restrict static max_processors_count]);
#if CPUINFO_ARCH_ARM
CPUINFO_INTERNAL bool cpuinfo_arm_linux_hwcap_from_getauxval(
uint32_t hwcap[restrict static 1],
uint32_t hwcap2[restrict static 1]);
CPUINFO_INTERNAL bool cpuinfo_arm_linux_hwcap_from_procfs(
uint32_t hwcap[restrict static 1],
uint32_t hwcap2[restrict static 1]);
CPUINFO_INTERNAL void cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
uint32_t features,
uint32_t features2,
uint32_t midr,
uint32_t architecture_version,
uint32_t architecture_flags,
const struct cpuinfo_arm_chipset chipset[restrict static 1],
struct cpuinfo_arm_isa isa[restrict static 1]);
#elif CPUINFO_ARCH_ARM64
CPUINFO_INTERNAL void cpuinfo_arm_linux_hwcap_from_getauxval(
uint32_t hwcap[restrict static 1],
uint32_t hwcap2[restrict static 1]);
CPUINFO_INTERNAL void cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
uint32_t features,
uint32_t features2,
uint32_t midr,
const struct cpuinfo_arm_chipset chipset[restrict static 1],
struct cpuinfo_arm_isa isa[restrict static 1]);
#endif
#if defined(__ANDROID__)
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
cpuinfo_arm_android_decode_chipset(
const struct cpuinfo_android_properties properties[restrict static 1],
uint32_t cores,
uint32_t max_cpu_freq_max);
#else
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
cpuinfo_arm_linux_decode_chipset(
const char hardware[restrict static CPUINFO_HARDWARE_VALUE_MAX],
const char revision[restrict static CPUINFO_REVISION_VALUE_MAX],
uint32_t cores,
uint32_t max_cpu_freq_max);
#endif
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
cpuinfo_arm_linux_decode_chipset_from_proc_cpuinfo_hardware(
const char proc_cpuinfo_hardware[restrict static CPUINFO_HARDWARE_VALUE_MAX],
uint32_t cores, uint32_t max_cpu_freq_max, bool is_tegra);
#ifdef __ANDROID__
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
cpuinfo_arm_android_decode_chipset_from_ro_product_board(
const char ro_product_board[restrict static CPUINFO_BUILD_PROP_VALUE_MAX],
uint32_t cores, uint32_t max_cpu_freq_max);
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
cpuinfo_arm_android_decode_chipset_from_ro_board_platform(
const char ro_board_platform[restrict static CPUINFO_BUILD_PROP_VALUE_MAX],
uint32_t cores, uint32_t max_cpu_freq_max);
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
cpuinfo_arm_android_decode_chipset_from_ro_mediatek_platform(
const char ro_mediatek_platform[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]);
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
cpuinfo_arm_android_decode_chipset_from_ro_arch(
const char ro_arch[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]);
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
cpuinfo_arm_android_decode_chipset_from_ro_chipname(
const char ro_chipname[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]);
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
cpuinfo_arm_android_decode_chipset_from_ro_hardware_chipname(
const char ro_hardware_chipname[restrict static CPUINFO_BUILD_PROP_VALUE_MAX]);
#else
CPUINFO_INTERNAL struct cpuinfo_arm_chipset
cpuinfo_arm_linux_decode_chipset_from_proc_cpuinfo_revision(
const char proc_cpuinfo_revision[restrict static CPUINFO_REVISION_VALUE_MAX]);
#endif
CPUINFO_INTERNAL bool cpuinfo_arm_linux_detect_core_clusters_by_heuristic(
uint32_t usable_processors,
uint32_t max_processors,
struct cpuinfo_arm_linux_processor processors[restrict static max_processors]);
CPUINFO_INTERNAL void cpuinfo_arm_linux_detect_core_clusters_by_sequential_scan(
uint32_t max_processors,
struct cpuinfo_arm_linux_processor processors[restrict static max_processors]);
CPUINFO_INTERNAL void cpuinfo_arm_linux_count_cluster_processors(
uint32_t max_processors,
struct cpuinfo_arm_linux_processor processors[restrict static max_processors]);
CPUINFO_INTERNAL uint32_t cpuinfo_arm_linux_detect_cluster_midr(
const struct cpuinfo_arm_chipset chipset[restrict static 1],
uint32_t max_processors,
uint32_t usable_processors,
struct cpuinfo_arm_linux_processor processors[restrict static max_processors]);
extern CPUINFO_INTERNAL const uint32_t* cpuinfo_linux_cpu_to_uarch_index_map;
extern CPUINFO_INTERNAL uint32_t cpuinfo_linux_cpu_to_uarch_index_map_entries;
File diff suppressed because it is too large Load Diff
-493
View File
@@ -1,493 +0,0 @@
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <cpuinfo.h>
#include <arm/linux/api.h>
#if defined(__ANDROID__)
#include <arm/android/api.h>
#endif
#include <arm/api.h>
#include <arm/midr.h>
#include <linux/api.h>
#include <cpuinfo/internal-api.h>
#include <cpuinfo/log.h>
static inline bool bitmask_all(uint32_t bitfield, uint32_t mask) {
return (bitfield & mask) == mask;
}
/*
* Assigns logical processors to clusters of cores using heuristic based on the typical configuration of clusters for
* 5, 6, 8, and 10 cores:
* - 5 cores (ARM32 Android only): 2 clusters of 4+1 cores
* - 6 cores: 2 clusters of 4+2 cores
* - 8 cores: 2 clusters of 4+4 cores
* - 10 cores: 3 clusters of 4+4+2 cores
*
* The function must be called after parsing OS-provided information on core clusters.
* Its purpose is to detect clusters of cores when OS-provided information is lacking or incomplete, i.e.
* - Linux kernel is not configured to report information in sysfs topology leaf.
* - Linux kernel reports topology information only for online cores, and only cores on one cluster are online, e.g.:
* - Exynos 8890 has 8 cores in 4+4 clusters, but only the first cluster of 4 cores is reported, and cluster
* configuration of logical processors 4-7 is not reported (all remaining processors 4-7 form cluster 1)
* - MT6797 has 10 cores in 4+4+2, but only the first cluster of 4 cores is reported, and cluster configuration
* of logical processors 4-9 is not reported (processors 4-7 form cluster 1, and processors 8-9 form cluster 2).
*
* Heuristic assignment of processors to the above pre-defined clusters fails if such assignment would contradict
* information provided by the operating system:
* - Any of the OS-reported processor clusters is different than the corresponding heuristic cluster.
* - Processors in a heuristic cluster have no OS-provided cluster siblings information, but have known and different
* minimum/maximum frequency.
* - Processors in a heuristic cluster have no OS-provided cluster siblings information, but have known and different
* MIDR components.
*
* If the heuristic assignment of processors to clusters of cores fails, all processors' clusters are unchanged.
*
* @param usable_processors - number of processors in the @p processors array with CPUINFO_LINUX_FLAG_VALID flags.
* @param max_processors - number of elements in the @p processors array.
* @param[in,out] processors - processor descriptors with pre-parsed POSSIBLE and PRESENT flags, minimum/maximum
* frequency, MIDR information, and core cluster (package siblings list) information.
*
* @retval true if the heuristic successfully assigned all processors into clusters of cores.
* @retval false if known details about processors contradict the heuristic configuration of core clusters.
*/
bool cpuinfo_arm_linux_detect_core_clusters_by_heuristic(
uint32_t usable_processors,
uint32_t max_processors,
struct cpuinfo_arm_linux_processor processors[restrict static max_processors])
{
uint32_t cluster_processors[3];
switch (usable_processors) {
case 10:
cluster_processors[0] = 4;
cluster_processors[1] = 4;
cluster_processors[2] = 2;
break;
case 8:
cluster_processors[0] = 4;
cluster_processors[1] = 4;
break;
case 6:
cluster_processors[0] = 4;
cluster_processors[1] = 2;
break;
#if defined(__ANDROID__) && CPUINFO_ARCH_ARM
case 5:
/*
* The only processor with 5 cores is Leadcore L1860C (ARMv7, mobile),
* but this configuration is not too unreasonable for a virtualized ARM server.
*/
cluster_processors[0] = 4;
cluster_processors[1] = 1;
break;
#endif
default:
return false;
}
/*
* Assignment of processors to core clusters is done in two passes:
* 1. Verify that the clusters proposed by heuristic are compatible with known details about processors.
* 2. If verification passed, update core clusters for the processors.
*/
uint32_t cluster = 0;
uint32_t expected_cluster_processors = 0;
uint32_t cluster_start, cluster_flags, cluster_midr, cluster_max_frequency, cluster_min_frequency;
bool expected_cluster_exists;
for (uint32_t i = 0; i < max_processors; i++) {
if (bitmask_all(processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
if (expected_cluster_processors == 0) {
/* Expect this processor to start a new cluster */
expected_cluster_exists = !!(processors[i].flags & CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER);
if (expected_cluster_exists) {
if (processors[i].package_leader_id != i) {
cpuinfo_log_debug(
"heuristic detection of core clusters failed: "
"processor %"PRIu32" is expected to start a new cluster #%"PRIu32" with %"PRIu32" cores, "
"but system siblings lists reported it as a sibling of processor %"PRIu32,
i, cluster, cluster_processors[cluster], processors[i].package_leader_id);
return false;
}
} else {
cluster_flags = 0;
}
cluster_start = i;
expected_cluster_processors = cluster_processors[cluster++];
} else {
/* Expect this processor to belong to the same cluster as processor */
if (expected_cluster_exists) {
/*
* The cluster suggested by the heuristic was already parsed from system siblings lists.
* For all processors we expect in the cluster, check that:
* - They have pre-assigned cluster from siblings lists (CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER flag).
* - They were assigned to the same cluster based on siblings lists
* (package_leader_id points to the first processor in the cluster).
*/
if ((processors[i].flags & CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER) == 0) {
cpuinfo_log_debug(
"heuristic detection of core clusters failed: "
"processor %"PRIu32" is expected to belong to the cluster of processor %"PRIu32", "
"but system siblings lists did not report it as a sibling of processor %"PRIu32,
i, cluster_start, cluster_start);
return false;
}
if (processors[i].package_leader_id != cluster_start) {
cpuinfo_log_debug(
"heuristic detection of core clusters failed: "
"processor %"PRIu32" is expected to belong to the cluster of processor %"PRIu32", "
"but system siblings lists reported it to belong to the cluster of processor %"PRIu32,
i, cluster_start, cluster_start);
return false;
}
} else {
/*
* The cluster suggest by the heuristic was not parsed from system siblings lists.
* For all processors we expect in the cluster, check that:
* - They have no pre-assigned cluster from siblings lists.
* - If their min/max CPU frequency is known, it is the same.
* - If any part of their MIDR (Implementer, Variant, Part, Revision) is known, it is the same.
*/
if (processors[i].flags & CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER) {
cpuinfo_log_debug(
"heuristic detection of core clusters failed: "
"processor %"PRIu32" is expected to be unassigned to any cluster, "
"but system siblings lists reported it to belong to the cluster of processor %"PRIu32,
i, processors[i].package_leader_id);
return false;
}
if (processors[i].flags & CPUINFO_LINUX_FLAG_MIN_FREQUENCY) {
if (cluster_flags & CPUINFO_LINUX_FLAG_MIN_FREQUENCY) {
if (cluster_min_frequency != processors[i].min_frequency) {
cpuinfo_log_debug(
"heuristic detection of core clusters failed: "
"minimum frequency of processor %"PRIu32" (%"PRIu32" KHz) is different than of its expected cluster (%"PRIu32" KHz)",
i, processors[i].min_frequency, cluster_min_frequency);
return false;
}
} else {
cluster_min_frequency = processors[i].min_frequency;
cluster_flags |= CPUINFO_LINUX_FLAG_MIN_FREQUENCY;
}
}
if (processors[i].flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
if (cluster_flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
if (cluster_max_frequency != processors[i].max_frequency) {
cpuinfo_log_debug(
"heuristic detection of core clusters failed: "
"maximum frequency of processor %"PRIu32" (%"PRIu32" KHz) is different than of its expected cluster (%"PRIu32" KHz)",
i, processors[i].max_frequency, cluster_max_frequency);
return false;
}
} else {
cluster_max_frequency = processors[i].max_frequency;
cluster_flags |= CPUINFO_LINUX_FLAG_MAX_FREQUENCY;
}
}
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_IMPLEMENTER) {
if (cluster_flags & CPUINFO_ARM_LINUX_VALID_IMPLEMENTER) {
if ((cluster_midr & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) != (processors[i].midr & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK)) {
cpuinfo_log_debug(
"heuristic detection of core clusters failed: "
"CPU Implementer of processor %"PRIu32" (0x%02"PRIx32") is different than of its expected cluster (0x%02"PRIx32")",
i, midr_get_implementer(processors[i].midr), midr_get_implementer(cluster_midr));
return false;
}
} else {
cluster_midr = midr_copy_implementer(cluster_midr, processors[i].midr);
cluster_flags |= CPUINFO_ARM_LINUX_VALID_IMPLEMENTER;
}
}
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_VARIANT) {
if (cluster_flags & CPUINFO_ARM_LINUX_VALID_VARIANT) {
if ((cluster_midr & CPUINFO_ARM_MIDR_VARIANT_MASK) != (processors[i].midr & CPUINFO_ARM_MIDR_VARIANT_MASK)) {
cpuinfo_log_debug(
"heuristic detection of core clusters failed: "
"CPU Variant of processor %"PRIu32" (0x%"PRIx32") is different than of its expected cluster (0x%"PRIx32")",
i, midr_get_variant(processors[i].midr), midr_get_variant(cluster_midr));
return false;
}
} else {
cluster_midr = midr_copy_variant(cluster_midr, processors[i].midr);
cluster_flags |= CPUINFO_ARM_LINUX_VALID_VARIANT;
}
}
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_PART) {
if (cluster_flags & CPUINFO_ARM_LINUX_VALID_PART) {
if ((cluster_midr & CPUINFO_ARM_MIDR_PART_MASK) != (processors[i].midr & CPUINFO_ARM_MIDR_PART_MASK)) {
cpuinfo_log_debug(
"heuristic detection of core clusters failed: "
"CPU Part of processor %"PRIu32" (0x%03"PRIx32") is different than of its expected cluster (0x%03"PRIx32")",
i, midr_get_part(processors[i].midr), midr_get_part(cluster_midr));
return false;
}
} else {
cluster_midr = midr_copy_part(cluster_midr, processors[i].midr);
cluster_flags |= CPUINFO_ARM_LINUX_VALID_PART;
}
}
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_REVISION) {
if (cluster_flags & CPUINFO_ARM_LINUX_VALID_REVISION) {
if ((cluster_midr & CPUINFO_ARM_MIDR_REVISION_MASK) != (processors[i].midr & CPUINFO_ARM_MIDR_REVISION_MASK)) {
cpuinfo_log_debug(
"heuristic detection of core clusters failed: "
"CPU Revision of processor %"PRIu32" (0x%"PRIx32") is different than of its expected cluster (0x%"PRIx32")",
i, midr_get_revision(cluster_midr), midr_get_revision(processors[i].midr));
return false;
}
} else {
cluster_midr = midr_copy_revision(cluster_midr, processors[i].midr);
cluster_flags |= CPUINFO_ARM_LINUX_VALID_REVISION;
}
}
}
}
expected_cluster_processors--;
}
}
/* Verification passed, assign all processors to new clusters */
cluster = 0;
expected_cluster_processors = 0;
for (uint32_t i = 0; i < max_processors; i++) {
if (bitmask_all(processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
if (expected_cluster_processors == 0) {
/* Expect this processor to start a new cluster */
cluster_start = i;
expected_cluster_processors = cluster_processors[cluster++];
} else {
/* Expect this processor to belong to the same cluster as processor */
if (!(processors[i].flags & CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER)) {
cpuinfo_log_debug("assigned processor %"PRIu32" to cluster of processor %"PRIu32" based on heuristic",
i, cluster_start);
}
processors[i].package_leader_id = cluster_start;
processors[i].flags |= CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER;
}
expected_cluster_processors--;
}
}
return true;
}
/*
* Assigns logical processors to clusters of cores in sequential manner:
* - Clusters detected from OS-provided information are unchanged:
* - Processors assigned to these clusters stay assigned to the same clusters
* - No new processors are added to these clusters
* - Processors without pre-assigned cluster are clustered in one sequential scan:
* - If known details (min/max frequency, MIDR components) of a processor are compatible with a preceding
* processor, without pre-assigned cluster, the processor is assigned to the cluster of the preceding processor.
* - If known details (min/max frequency, MIDR components) of a processor are not compatible with a preceding
* processor, the processor is assigned to a newly created cluster.
*
* The function must be called after parsing OS-provided information on core clusters, and usually is called only
* if heuristic assignment of processors to clusters (cpuinfo_arm_linux_cluster_processors_by_heuristic) failed.
*
* Its purpose is to detect clusters of cores when OS-provided information is lacking or incomplete, i.e.
* - Linux kernel is not configured to report information in sysfs topology leaf.
* - Linux kernel reports topology information only for online cores, and all cores on some of the clusters are offline.
*
* Sequential assignment of processors to clusters always succeeds, and upon exit, all usable processors in the
* @p processors array have cluster information.
*
* @param max_processors - number of elements in the @p processors array.
* @param[in,out] processors - processor descriptors with pre-parsed POSSIBLE and PRESENT flags, minimum/maximum
* frequency, MIDR information, and core cluster (package siblings list) information.
*
* @retval true if the heuristic successfully assigned all processors into clusters of cores.
* @retval false if known details about processors contradict the heuristic configuration of core clusters.
*/
void cpuinfo_arm_linux_detect_core_clusters_by_sequential_scan(
uint32_t max_processors,
struct cpuinfo_arm_linux_processor processors[restrict static max_processors])
{
uint32_t cluster_flags = 0;
uint32_t cluster_processors = 0;
uint32_t cluster_start, cluster_midr, cluster_max_frequency, cluster_min_frequency;
for (uint32_t i = 0; i < max_processors; i++) {
if ((processors[i].flags & (CPUINFO_LINUX_FLAG_VALID | CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER)) == CPUINFO_LINUX_FLAG_VALID) {
if (cluster_processors == 0) {
goto new_cluster;
}
if (processors[i].flags & CPUINFO_LINUX_FLAG_MIN_FREQUENCY) {
if (cluster_flags & CPUINFO_LINUX_FLAG_MIN_FREQUENCY) {
if (cluster_min_frequency != processors[i].min_frequency) {
cpuinfo_log_info(
"minimum frequency of processor %"PRIu32" (%"PRIu32" KHz) is different than of preceding cluster (%"PRIu32" KHz); "
"processor %"PRIu32" starts to a new cluster",
i, processors[i].min_frequency, cluster_min_frequency, i);
goto new_cluster;
}
} else {
cluster_min_frequency = processors[i].min_frequency;
cluster_flags |= CPUINFO_LINUX_FLAG_MIN_FREQUENCY;
}
}
if (processors[i].flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
if (cluster_flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
if (cluster_max_frequency != processors[i].max_frequency) {
cpuinfo_log_debug(
"maximum frequency of processor %"PRIu32" (%"PRIu32" KHz) is different than of preceding cluster (%"PRIu32" KHz); "
"processor %"PRIu32" starts a new cluster",
i, processors[i].max_frequency, cluster_max_frequency, i);
goto new_cluster;
}
} else {
cluster_max_frequency = processors[i].max_frequency;
cluster_flags |= CPUINFO_LINUX_FLAG_MAX_FREQUENCY;
}
}
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_IMPLEMENTER) {
if (cluster_flags & CPUINFO_ARM_LINUX_VALID_IMPLEMENTER) {
if ((cluster_midr & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) != (processors[i].midr & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK)) {
cpuinfo_log_debug(
"CPU Implementer of processor %"PRIu32" (0x%02"PRIx32") is different than of preceding cluster (0x%02"PRIx32"); "
"processor %"PRIu32" starts to a new cluster",
i, midr_get_implementer(processors[i].midr), midr_get_implementer(cluster_midr), i);
goto new_cluster;
}
} else {
cluster_midr = midr_copy_implementer(cluster_midr, processors[i].midr);
cluster_flags |= CPUINFO_ARM_LINUX_VALID_IMPLEMENTER;
}
}
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_VARIANT) {
if (cluster_flags & CPUINFO_ARM_LINUX_VALID_VARIANT) {
if ((cluster_midr & CPUINFO_ARM_MIDR_VARIANT_MASK) != (processors[i].midr & CPUINFO_ARM_MIDR_VARIANT_MASK)) {
cpuinfo_log_debug(
"CPU Variant of processor %"PRIu32" (0x%"PRIx32") is different than of its expected cluster (0x%"PRIx32")"
"processor %"PRIu32" starts to a new cluster",
i, midr_get_variant(processors[i].midr), midr_get_variant(cluster_midr), i);
goto new_cluster;
}
} else {
cluster_midr = midr_copy_variant(cluster_midr, processors[i].midr);
cluster_flags |= CPUINFO_ARM_LINUX_VALID_VARIANT;
}
}
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_PART) {
if (cluster_flags & CPUINFO_ARM_LINUX_VALID_PART) {
if ((cluster_midr & CPUINFO_ARM_MIDR_PART_MASK) != (processors[i].midr & CPUINFO_ARM_MIDR_PART_MASK)) {
cpuinfo_log_debug(
"CPU Part of processor %"PRIu32" (0x%03"PRIx32") is different than of its expected cluster (0x%03"PRIx32")"
"processor %"PRIu32" starts to a new cluster",
i, midr_get_part(processors[i].midr), midr_get_part(cluster_midr), i);
goto new_cluster;
}
} else {
cluster_midr = midr_copy_part(cluster_midr, processors[i].midr);
cluster_flags |= CPUINFO_ARM_LINUX_VALID_PART;
}
}
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_REVISION) {
if (cluster_flags & CPUINFO_ARM_LINUX_VALID_REVISION) {
if ((cluster_midr & CPUINFO_ARM_MIDR_REVISION_MASK) != (processors[i].midr & CPUINFO_ARM_MIDR_REVISION_MASK)) {
cpuinfo_log_debug(
"CPU Revision of processor %"PRIu32" (0x%"PRIx32") is different than of its expected cluster (0x%"PRIx32")"
"processor %"PRIu32" starts to a new cluster",
i, midr_get_revision(cluster_midr), midr_get_revision(processors[i].midr), i);
goto new_cluster;
}
} else {
cluster_midr = midr_copy_revision(cluster_midr, processors[i].midr);
cluster_flags |= CPUINFO_ARM_LINUX_VALID_REVISION;
}
}
/* All checks passed, attach processor to the preceding cluster */
cluster_processors++;
processors[i].package_leader_id = cluster_start;
processors[i].flags |= CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER;
cpuinfo_log_debug("assigned processor %"PRIu32" to preceding cluster of processor %"PRIu32, i, cluster_start);
continue;
new_cluster:
/* Create a new cluster starting with processor i */
cluster_start = i;
processors[i].package_leader_id = i;
processors[i].flags |= CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER;
cluster_processors = 1;
/* Copy known information from processor to cluster, and set the flags accordingly */
cluster_flags = 0;
if (processors[i].flags & CPUINFO_LINUX_FLAG_MIN_FREQUENCY) {
cluster_min_frequency = processors[i].min_frequency;
cluster_flags |= CPUINFO_LINUX_FLAG_MIN_FREQUENCY;
}
if (processors[i].flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
cluster_max_frequency = processors[i].max_frequency;
cluster_flags |= CPUINFO_LINUX_FLAG_MAX_FREQUENCY;
}
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_IMPLEMENTER) {
cluster_midr = midr_copy_implementer(cluster_midr, processors[i].midr);
cluster_flags |= CPUINFO_ARM_LINUX_VALID_IMPLEMENTER;
}
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_VARIANT) {
cluster_midr = midr_copy_variant(cluster_midr, processors[i].midr);
cluster_flags |= CPUINFO_ARM_LINUX_VALID_VARIANT;
}
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_PART) {
cluster_midr = midr_copy_part(cluster_midr, processors[i].midr);
cluster_flags |= CPUINFO_ARM_LINUX_VALID_PART;
}
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_REVISION) {
cluster_midr = midr_copy_revision(cluster_midr, processors[i].midr);
cluster_flags |= CPUINFO_ARM_LINUX_VALID_REVISION;
}
}
}
}
/*
* Counts the number of logical processors in each core cluster.
* This function should be called after all processors are assigned to core clusters.
*
* @param max_processors - number of elements in the @p processors array.
* @param[in,out] processors - processor descriptors with pre-parsed POSSIBLE and PRESENT flags,
* and decoded core cluster (package_leader_id) information.
* The function expects the value of processors[i].package_processor_count to be zero.
* Upon return, processors[i].package_processor_count will contain the number of logical
* processors in the respective core cluster.
*/
void cpuinfo_arm_linux_count_cluster_processors(
uint32_t max_processors,
struct cpuinfo_arm_linux_processor processors[restrict static max_processors])
{
/* First pass: accumulate the number of processors at the group leader's package_processor_count */
for (uint32_t i = 0; i < max_processors; i++) {
if (bitmask_all(processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
const uint32_t package_leader_id = processors[i].package_leader_id;
processors[package_leader_id].package_processor_count += 1;
}
}
/* Second pass: copy the package_processor_count from the group leader processor */
for (uint32_t i = 0; i < max_processors; i++) {
if (bitmask_all(processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
const uint32_t package_leader_id = processors[i].package_leader_id;
processors[i].package_processor_count = processors[package_leader_id].package_processor_count;
}
}
}
-50
View File
@@ -1,50 +0,0 @@
#include <stdint.h>
#if CPUINFO_MOCK
extern uint32_t cpuinfo_arm_fpsid;
extern uint32_t cpuinfo_arm_mvfr0;
extern uint32_t cpuinfo_arm_wcid;
static inline uint32_t read_fpsid(void) {
return cpuinfo_arm_fpsid;
}
static inline uint32_t read_mvfr0(void) {
return cpuinfo_arm_mvfr0;
}
static inline uint32_t read_wcid(void) {
return cpuinfo_arm_wcid;
}
#else
#if !defined(__ARM_ARCH_7A__) && !defined(__ARM_ARCH_8A__) && !(defined(__ARM_ARCH) && (__ARM_ARCH >= 7))
/*
* CoProcessor 10 is inaccessible from user mode since ARMv7,
* and clang refuses to compile inline assembly when targeting ARMv7+
*/
static inline uint32_t read_fpsid(void) {
uint32_t fpsid;
__asm__ __volatile__("MRC p10, 0x7, %[fpsid], cr0, cr0, 0" : [fpsid] "=r" (fpsid));
return fpsid;
}
static inline uint32_t read_mvfr0(void) {
uint32_t mvfr0;
__asm__ __volatile__("MRC p10, 0x7, %[mvfr0], cr7, cr0, 0" : [mvfr0] "=r" (mvfr0));
return mvfr0;
}
#endif
#if !defined(__ARM_ARCH_8A__) && !(defined(__ARM_ARCH) && (__ARM_ARCH >= 8))
/*
* In ARMv8, AArch32 state supports only conceptual coprocessors CP10, CP11, CP14, and CP15.
* AArch64 does not support the concept of coprocessors.
* and clang refuses to compile inline assembly when targeting ARMv8+
*/
static inline uint32_t read_wcid(void) {
uint32_t wcid;
__asm__ __volatile__("MRC p1, 0, %[wcid], c0, c0" : [wcid] "=r" (wcid));
return wcid;
}
#endif
#endif
-917
View File
@@ -1,917 +0,0 @@
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <linux/api.h>
#include <arm/linux/api.h>
#include <arm/midr.h>
#include <cpuinfo/log.h>
/*
* Size, in chars, of the on-stack buffer used for parsing lines of /proc/cpuinfo.
* This is also the limit on the length of a single line.
*/
#define BUFFER_SIZE 1024
static uint32_t parse_processor_number(
const char* processor_start,
const char* processor_end)
{
const size_t processor_length = (size_t) (processor_end - processor_start);
if (processor_length == 0) {
cpuinfo_log_warning("Processor number in /proc/cpuinfo is ignored: string is empty");
return 0;
}
uint32_t processor_number = 0;
for (const char* digit_ptr = processor_start; digit_ptr != processor_end; digit_ptr++) {
const uint32_t digit = (uint32_t) (*digit_ptr - '0');
if (digit > 10) {
cpuinfo_log_warning("non-decimal suffix %.*s in /proc/cpuinfo processor number is ignored",
(int) (processor_end - digit_ptr), digit_ptr);
break;
}
processor_number = processor_number * 10 + digit;
}
return processor_number;
}
/*
* Full list of ARM features reported in /proc/cpuinfo:
*
* * swp - support for SWP instruction (deprecated in ARMv7, can be removed in future)
* * half - support for half-word loads and stores. These instruction are part of ARMv4,
* so no need to check it on supported CPUs.
* * thumb - support for 16-bit Thumb instruction set. Note that BX instruction is detected
* by ARMv4T architecture, not by this flag.
* * 26bit - old CPUs merged 26-bit PC and program status register (flags) into 32-bit PC
* and had special instructions for working with packed PC. Now it is all deprecated.
* * fastmult - most old ARM CPUs could only compute 2 bits of multiplication result per clock
* cycle, but CPUs with M suffix (e.g. ARM7TDMI) could compute 4 bits per cycle.
* Of course, now it makes no sense.
* * fpa - floating point accelerator available. On original ARM ABI all floating-point operations
* generated FPA instructions. If FPA was not available, these instructions generated
* "illegal operation" interrupts, and the OS processed them by emulating the FPA instructions.
* Debian used this ABI before it switched to EABI. Now FPA is deprecated.
* * vfp - vector floating point instructions. Available on most modern CPUs (as part of VFPv3).
* Required by Android ARMv7A ABI and by Ubuntu on ARM.
* Note: there is no flag for VFPv2.
* * edsp - V5E instructions: saturating add/sub and 16-bit x 16-bit -> 32/64-bit multiplications.
* Required on Android, supported by all CPUs in production.
* * java - Jazelle extension. Supported on most CPUs.
* * iwmmxt - Intel/Marvell Wireless MMX instructions. 64-bit integer SIMD.
* Supported on XScale (Since PXA270) and Sheeva (PJ1, PJ4) architectures.
* Note that there is no flag for WMMX2 instructions.
* * crunch - Maverick Crunch instructions. Junk.
* * thumbee - ThumbEE instructions. Almost no documentation is available.
* * neon - NEON instructions (aka Advanced SIMD). MVFR1 register gives more
* fine-grained information on particular supported features, but
* the Linux kernel exports only a single flag for all of them.
* According to ARMv7A docs it also implies the availability of VFPv3
* (with 32 double-precision registers d0-d31).
* * vfpv3 - VFPv3 instructions. Available on most modern CPUs. Augment VFPv2 by
* conversion to/from integers and load constant instructions.
* Required by Android ARMv7A ABI and by Ubuntu on ARM.
* * vfpv3d16 - VFPv3 instructions with only 16 double-precision registers (d0-d15).
* * tls - software thread ID registers.
* Used by kernel (and likely libc) for efficient implementation of TLS.
* * vfpv4 - fused multiply-add instructions.
* * idiva - DIV instructions available in ARM mode.
* * idivt - DIV instructions available in Thumb mode.
* * vfpd32 - VFP (of any version) with 32 double-precision registers d0-d31.
* * lpae - Large Physical Address Extension (physical address up to 40 bits).
* * evtstrm - generation of Event Stream by timer.
* * aes - AES instructions.
* * pmull - Polinomial Multiplication instructions.
* * sha1 - SHA1 instructions.
* * sha2 - SHA2 instructions.
* * crc32 - CRC32 instructions.
*
* /proc/cpuinfo on ARM is populated in file arch/arm/kernel/setup.c in Linux kernel
* Note that some devices may use patched Linux kernels with different feature names.
* However, the names above were checked on a large number of /proc/cpuinfo listings.
*/
static void parse_features(
const char* features_start,
const char* features_end,
struct cpuinfo_arm_linux_processor processor[restrict static 1])
{
const char* feature_start = features_start;
const char* feature_end;
/* Mark the features as valid */
processor->flags |= CPUINFO_ARM_LINUX_VALID_FEATURES | CPUINFO_ARM_LINUX_VALID_PROCESSOR;
do {
feature_end = feature_start + 1;
for (; feature_end != features_end; feature_end++) {
if (*feature_end == ' ') {
break;
}
}
const size_t feature_length = (size_t) (feature_end - feature_start);
switch (feature_length) {
case 2:
if (memcmp(feature_start, "fp", feature_length) == 0) {
#if CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_FP;
#endif
#if CPUINFO_ARCH_ARM
} else if (memcmp(feature_start, "wp", feature_length) == 0) {
/*
* Some AArch64 kernels, including the one on Nexus 5X,
* erroneously report "swp" as "wp" to AArch32 programs
*/
processor->features |= CPUINFO_ARM_LINUX_FEATURE_SWP;
#endif
} else {
goto unexpected;
}
break;
case 3:
if (memcmp(feature_start, "aes", feature_length) == 0) {
#if CPUINFO_ARCH_ARM
processor->features2 |= CPUINFO_ARM_LINUX_FEATURE2_AES;
#elif CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_AES;
#endif
#if CPUINFO_ARCH_ARM
} else if (memcmp(feature_start, "swp", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_SWP;
} else if (memcmp(feature_start, "fpa", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_FPA;
} else if (memcmp(feature_start, "vfp", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_VFP;
} else if (memcmp(feature_start, "tls", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_TLS;
#endif /* CPUINFO_ARCH_ARM */
} else {
goto unexpected;
}
break;
case 4:
if (memcmp(feature_start, "sha1", feature_length) == 0) {
#if CPUINFO_ARCH_ARM
processor->features2 |= CPUINFO_ARM_LINUX_FEATURE2_SHA1;
#elif CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_SHA1;
#endif
} else if (memcmp(feature_start, "sha2", feature_length) == 0) {
#if CPUINFO_ARCH_ARM
processor->features2 |= CPUINFO_ARM_LINUX_FEATURE2_SHA2;
#elif CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_SHA2;
#endif
} else if (memcmp(feature_start, "fphp", feature_length) == 0) {
#if CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_FPHP;
#endif
} else if (memcmp(feature_start, "fcma", feature_length) == 0) {
#if CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_FCMA;
#endif
} else if (memcmp(feature_start, "i8mm", feature_length) == 0) {
#if CPUINFO_ARCH_ARM64
processor->features2 |= CPUINFO_ARM_LINUX_FEATURE2_I8MM;
#endif
#if CPUINFO_ARCH_ARM
} else if (memcmp(feature_start, "half", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_HALF;
} else if (memcmp(feature_start, "edsp", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_EDSP;
} else if (memcmp(feature_start, "java", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_JAVA;
} else if (memcmp(feature_start, "neon", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_NEON;
} else if (memcmp(feature_start, "lpae", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_LPAE;
} else if (memcmp(feature_start, "tlsi", feature_length) == 0) {
/*
* Some AArch64 kernels, including the one on Nexus 5X,
* erroneously report "tls" as "tlsi" to AArch32 programs
*/
processor->features |= CPUINFO_ARM_LINUX_FEATURE_TLS;
#endif /* CPUINFO_ARCH_ARM */
} else {
goto unexpected;
}
break;
case 5:
if (memcmp(feature_start, "pmull", feature_length) == 0) {
#if CPUINFO_ARCH_ARM
processor->features2 |= CPUINFO_ARM_LINUX_FEATURE2_PMULL;
#elif CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_PMULL;
#endif
} else if (memcmp(feature_start, "crc32", feature_length) == 0) {
#if CPUINFO_ARCH_ARM
processor->features2 |= CPUINFO_ARM_LINUX_FEATURE2_CRC32;
#elif CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_CRC32;
#endif
} else if (memcmp(feature_start, "asimd", feature_length) == 0) {
#if CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_ASIMD;
#endif
} else if (memcmp(feature_start, "cpuid", feature_length) == 0) {
#if CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_CPUID;
#endif
} else if (memcmp(feature_start, "jscvt", feature_length) == 0) {
#if CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_JSCVT;
#endif
} else if (memcmp(feature_start, "lrcpc", feature_length) == 0) {
#if CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_LRCPC;
#endif
#if CPUINFO_ARCH_ARM
} else if (memcmp(feature_start, "thumb", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_THUMB;
} else if (memcmp(feature_start, "26bit", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_26BIT;
} else if (memcmp(feature_start, "vfpv3", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_VFPV3;
} else if (memcmp(feature_start, "vfpv4", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_VFPV4;
} else if (memcmp(feature_start, "idiva", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_IDIVA;
} else if (memcmp(feature_start, "idivt", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_IDIVT;
#endif /* CPUINFO_ARCH_ARM */
} else {
goto unexpected;
}
break;
#if CPUINFO_ARCH_ARM
case 6:
if (memcmp(feature_start, "iwmmxt", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_IWMMXT;
} else if (memcmp(feature_start, "crunch", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_CRUNCH;
} else if (memcmp(feature_start, "vfpd32", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_VFPD32;
} else {
goto unexpected;
}
break;
#endif /* CPUINFO_ARCH_ARM */
case 7:
if (memcmp(feature_start, "evtstrm", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_EVTSTRM;
} else if (memcmp(feature_start, "atomics", feature_length) == 0) {
#if CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_ATOMICS;
#endif
} else if (memcmp(feature_start, "asimdhp", feature_length) == 0) {
#if CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_ASIMDHP;
#endif
#if CPUINFO_ARCH_ARM
} else if (memcmp(feature_start, "thumbee", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_THUMBEE;
#endif /* CPUINFO_ARCH_ARM */
} else {
goto unexpected;
}
break;
case 8:
if (memcmp(feature_start, "asimdrdm", feature_length) == 0) {
#if CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_ASIMDRDM;
#endif
} else if (memcmp(feature_start, "asimdfhm", feature_length) == 0) {
#if CPUINFO_ARCH_ARM64
processor->features |= CPUINFO_ARM_LINUX_FEATURE_ASIMDFHM;
#endif
#if CPUINFO_ARCH_ARM
} else if (memcmp(feature_start, "fastmult", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_FASTMULT;
} else if (memcmp(feature_start, "vfpv3d16", feature_length) == 0) {
processor->features |= CPUINFO_ARM_LINUX_FEATURE_VFPV3D16;
#endif /* CPUINFO_ARCH_ARM */
} else {
goto unexpected;
}
break;
default:
unexpected:
cpuinfo_log_warning("unexpected /proc/cpuinfo feature \"%.*s\" is ignored",
(int) feature_length, feature_start);
break;
}
feature_start = feature_end;
for (; feature_start != features_end; feature_start++) {
if (*feature_start != ' ') {
break;
}
}
} while (feature_start != feature_end);
}
static void parse_cpu_architecture(
const char* cpu_architecture_start,
const char* cpu_architecture_end,
struct cpuinfo_arm_linux_processor processor[restrict static 1])
{
const size_t cpu_architecture_length = (size_t) (cpu_architecture_end - cpu_architecture_start);
/* Early AArch64 kernels report "CPU architecture: AArch64" instead of a numeric value 8 */
if (cpu_architecture_length == 7) {
if (memcmp(cpu_architecture_start, "AArch64", cpu_architecture_length) == 0) {
processor->midr = midr_set_architecture(processor->midr, UINT32_C(0xF));
processor->architecture_version = 8;
processor->flags |= CPUINFO_ARM_LINUX_VALID_ARCHITECTURE | CPUINFO_ARM_LINUX_VALID_PROCESSOR;
return;
}
}
uint32_t architecture = 0;
const char* cpu_architecture_ptr = cpu_architecture_start;
for (; cpu_architecture_ptr != cpu_architecture_end; cpu_architecture_ptr++) {
const uint32_t digit = (*cpu_architecture_ptr) - '0';
/* Verify that CPU architecture is a decimal number */
if (digit >= 10) {
break;
}
architecture = architecture * 10 + digit;
}
if (cpu_architecture_ptr == cpu_architecture_start) {
cpuinfo_log_warning("CPU architecture %.*s in /proc/cpuinfo is ignored due to non-digit at the beginning of the string",
(int) cpu_architecture_length, cpu_architecture_start);
} else {
if (architecture != 0) {
processor->architecture_version = architecture;
processor->flags |= CPUINFO_ARM_LINUX_VALID_ARCHITECTURE | CPUINFO_ARM_LINUX_VALID_PROCESSOR;
for (; cpu_architecture_ptr != cpu_architecture_end; cpu_architecture_ptr++) {
const char feature = *cpu_architecture_ptr;
switch (feature) {
#if CPUINFO_ARCH_ARM
case 'T':
processor->architecture_flags |= CPUINFO_ARM_LINUX_ARCH_T;
break;
case 'E':
processor->architecture_flags |= CPUINFO_ARM_LINUX_ARCH_E;
break;
case 'J':
processor->architecture_flags |= CPUINFO_ARM_LINUX_ARCH_J;
break;
#endif /* CPUINFO_ARCH_ARM */
case ' ':
case '\t':
/* Ignore whitespace at the end */
break;
default:
cpuinfo_log_warning("skipped unknown architectural feature '%c' for ARMv%"PRIu32,
feature, architecture);
break;
}
}
} else {
cpuinfo_log_warning("CPU architecture %.*s in /proc/cpuinfo is ignored due to invalid value (0)",
(int) cpu_architecture_length, cpu_architecture_start);
}
}
uint32_t midr_architecture = UINT32_C(0xF);
#if CPUINFO_ARCH_ARM
switch (processor->architecture_version) {
case 6:
midr_architecture = UINT32_C(0x7); /* ARMv6 */
break;
case 5:
if ((processor->architecture_flags & CPUINFO_ARM_LINUX_ARCH_TEJ) == CPUINFO_ARM_LINUX_ARCH_TEJ) {
midr_architecture = UINT32_C(0x6); /* ARMv5TEJ */
} else if ((processor->architecture_flags & CPUINFO_ARM_LINUX_ARCH_TE) == CPUINFO_ARM_LINUX_ARCH_TE) {
midr_architecture = UINT32_C(0x5); /* ARMv5TE */
} else {
midr_architecture = UINT32_C(0x4); /* ARMv5T */
}
break;
}
#endif
processor->midr = midr_set_architecture(processor->midr, midr_architecture);
}
static void parse_cpu_part(
const char* cpu_part_start,
const char* cpu_part_end,
struct cpuinfo_arm_linux_processor processor[restrict static 1])
{
const size_t cpu_part_length = (size_t) (cpu_part_end - cpu_part_start);
/*
* CPU part should contain hex prefix (0x) and one to three hex digits.
* I have never seen less than three digits as a value of this field,
* but I don't think it is impossible to see such values in future.
* Value can not contain more than three hex digits since
* Main ID Register (MIDR) assigns only a 12-bit value for CPU part.
*/
if (cpu_part_length < 3 || cpu_part_length > 5) {
cpuinfo_log_warning("CPU part %.*s in /proc/cpuinfo is ignored due to unexpected length (%zu)",
(int) cpu_part_length, cpu_part_start, cpu_part_length);
return;
}
/* Verify the presence of hex prefix */
if (cpu_part_start[0] != '0' || cpu_part_start[1] != 'x') {
cpuinfo_log_warning("CPU part %.*s in /proc/cpuinfo is ignored due to lack of 0x prefix",
(int) cpu_part_length, cpu_part_start);
return;
}
/* Verify that characters after hex prefix are hexadecimal digits and decode them */
uint32_t cpu_part = 0;
for (const char* digit_ptr = cpu_part_start + 2; digit_ptr != cpu_part_end; digit_ptr++) {
const char digit_char = *digit_ptr;
uint32_t digit;
if (digit_char >= '0' && digit_char <= '9') {
digit = digit_char - '0';
} else if ((uint32_t) (digit_char - 'A') < 6) {
digit = 10 + (digit_char - 'A');
} else if ((uint32_t) (digit_char - 'a') < 6) {
digit = 10 + (digit_char - 'a');
} else {
cpuinfo_log_warning("CPU part %.*s in /proc/cpuinfo is ignored due to unexpected non-hex character %c at offset %zu",
(int) cpu_part_length, cpu_part_start, digit_char, (size_t) (digit_ptr - cpu_part_start));
return;
}
cpu_part = cpu_part * 16 + digit;
}
processor->midr = midr_set_part(processor->midr, cpu_part);
processor->flags |= CPUINFO_ARM_LINUX_VALID_PART | CPUINFO_ARM_LINUX_VALID_PROCESSOR;
}
static void parse_cpu_implementer(
const char* cpu_implementer_start,
const char* cpu_implementer_end,
struct cpuinfo_arm_linux_processor processor[restrict static 1])
{
const size_t cpu_implementer_length = cpu_implementer_end - cpu_implementer_start;
/*
* Value should contain hex prefix (0x) and one or two hex digits.
* I have never seen single hex digit as a value of this field,
* but I don't think it is impossible in future.
* Value can not contain more than two hex digits since
* Main ID Register (MIDR) assigns only an 8-bit value for CPU implementer.
*/
switch (cpu_implementer_length) {
case 3:
case 4:
break;
default:
cpuinfo_log_warning("CPU implementer %.*s in /proc/cpuinfo is ignored due to unexpected length (%zu)",
(int) cpu_implementer_length, cpu_implementer_start, cpu_implementer_length);
return;
}
/* Verify the presence of hex prefix */
if (cpu_implementer_start[0] != '0' || cpu_implementer_start[1] != 'x') {
cpuinfo_log_warning("CPU implementer %.*s in /proc/cpuinfo is ignored due to lack of 0x prefix",
(int) cpu_implementer_length, cpu_implementer_start);
return;
}
/* Verify that characters after hex prefix are hexadecimal digits and decode them */
uint32_t cpu_implementer = 0;
for (const char* digit_ptr = cpu_implementer_start + 2; digit_ptr != cpu_implementer_end; digit_ptr++) {
const char digit_char = *digit_ptr;
uint32_t digit;
if (digit_char >= '0' && digit_char <= '9') {
digit = digit_char - '0';
} else if ((uint32_t) (digit_char - 'A') < 6) {
digit = 10 + (digit_char - 'A');
} else if ((uint32_t) (digit_char - 'a') < 6) {
digit = 10 + (digit_char - 'a');
} else {
cpuinfo_log_warning("CPU implementer %.*s in /proc/cpuinfo is ignored due to unexpected non-hex character '%c' at offset %zu",
(int) cpu_implementer_length, cpu_implementer_start, digit_char, (size_t) (digit_ptr - cpu_implementer_start));
return;
}
cpu_implementer = cpu_implementer * 16 + digit;
}
processor->midr = midr_set_implementer(processor->midr, cpu_implementer);
processor->flags |= CPUINFO_ARM_LINUX_VALID_IMPLEMENTER | CPUINFO_ARM_LINUX_VALID_PROCESSOR;
}
static void parse_cpu_variant(
const char* cpu_variant_start,
const char* cpu_variant_end,
struct cpuinfo_arm_linux_processor processor[restrict static 1])
{
const size_t cpu_variant_length = cpu_variant_end - cpu_variant_start;
/*
* Value should contain hex prefix (0x) and one hex digit.
* Value can not contain more than one hex digits since
* Main ID Register (MIDR) assigns only a 4-bit value for CPU variant.
*/
if (cpu_variant_length != 3) {
cpuinfo_log_warning("CPU variant %.*s in /proc/cpuinfo is ignored due to unexpected length (%zu)",
(int) cpu_variant_length, cpu_variant_start, cpu_variant_length);
return;
}
/* Skip if there is no hex prefix (0x) */
if (cpu_variant_start[0] != '0' || cpu_variant_start[1] != 'x') {
cpuinfo_log_warning("CPU variant %.*s in /proc/cpuinfo is ignored due to lack of 0x prefix",
(int) cpu_variant_length, cpu_variant_start);
return;
}
/* Check if the value after hex prefix is indeed a hex digit and decode it. */
const char digit_char = cpu_variant_start[2];
uint32_t cpu_variant;
if ((uint32_t) (digit_char - '0') < 10) {
cpu_variant = (uint32_t) (digit_char - '0');
} else if ((uint32_t) (digit_char - 'A') < 6) {
cpu_variant = 10 + (uint32_t) (digit_char - 'A');
} else if ((uint32_t) (digit_char - 'a') < 6) {
cpu_variant = 10 + (uint32_t) (digit_char - 'a');
} else {
cpuinfo_log_warning("CPU variant %.*s in /proc/cpuinfo is ignored due to unexpected non-hex character '%c'",
(int) cpu_variant_length, cpu_variant_start, digit_char);
return;
}
processor->midr = midr_set_variant(processor->midr, cpu_variant);
processor->flags |= CPUINFO_ARM_LINUX_VALID_VARIANT | CPUINFO_ARM_LINUX_VALID_PROCESSOR;
}
static void parse_cpu_revision(
const char* cpu_revision_start,
const char* cpu_revision_end,
struct cpuinfo_arm_linux_processor processor[restrict static 1])
{
uint32_t cpu_revision = 0;
for (const char* digit_ptr = cpu_revision_start; digit_ptr != cpu_revision_end; digit_ptr++) {
const uint32_t digit = (uint32_t) (*digit_ptr - '0');
/* Verify that the character in CPU revision is a decimal digit */
if (digit >= 10) {
cpuinfo_log_warning("CPU revision %.*s in /proc/cpuinfo is ignored due to unexpected non-digit character '%c' at offset %zu",
(int) (cpu_revision_end - cpu_revision_start), cpu_revision_start,
*digit_ptr, (size_t) (digit_ptr - cpu_revision_start));
return;
}
cpu_revision = cpu_revision * 10 + digit;
}
processor->midr = midr_set_revision(processor->midr, cpu_revision);
processor->flags |= CPUINFO_ARM_LINUX_VALID_REVISION | CPUINFO_ARM_LINUX_VALID_PROCESSOR;
}
#if CPUINFO_ARCH_ARM
/*
* Decode one of the cache-related numbers reported by Linux kernel
* for pre-ARMv7 architecture.
* An example cache-related information in /proc/cpuinfo:
*
* I size : 32768
* I assoc : 4
* I line length : 32
* I sets : 256
* D size : 16384
* D assoc : 4
* D line length : 32
* D sets : 128
*
*/
static void parse_cache_number(
const char* number_start,
const char* number_end,
const char* number_name,
uint32_t number_ptr[restrict static 1],
uint32_t flags[restrict static 1],
uint32_t number_mask)
{
uint32_t number = 0;
for (const char* digit_ptr = number_start; digit_ptr != number_end; digit_ptr++) {
const uint32_t digit = *digit_ptr - '0';
if (digit >= 10) {
cpuinfo_log_warning("%s %.*s in /proc/cpuinfo is ignored due to unexpected non-digit character '%c' at offset %zu",
number_name, (int) (number_end - number_start), number_start,
*digit_ptr, (size_t) (digit_ptr - number_start));
return;
}
number = number * 10 + digit;
}
if (number == 0) {
cpuinfo_log_warning("%s %.*s in /proc/cpuinfo is ignored due to invalid value of zero reported by the kernel",
number_name, (int) (number_end - number_start), number_start);
}
/* If the number specifies a cache line size, verify that is a reasonable power of 2 */
if (number_mask & CPUINFO_ARM_LINUX_VALID_CACHE_LINE) {
switch (number) {
case 16:
case 32:
case 64:
case 128:
break;
default:
cpuinfo_log_warning("invalid %s %.*s is ignored: a value of 16, 32, 64, or 128 expected",
number_name, (int) (number_end - number_start), number_start);
}
}
*number_ptr = number;
*flags |= number_mask | CPUINFO_ARM_LINUX_VALID_PROCESSOR;
}
#endif /* CPUINFO_ARCH_ARM */
struct proc_cpuinfo_parser_state {
char* hardware;
char* revision;
uint32_t processor_index;
uint32_t max_processors_count;
struct cpuinfo_arm_linux_processor* processors;
struct cpuinfo_arm_linux_processor dummy_processor;
};
/*
* Decode a single line of /proc/cpuinfo information.
* Lines have format <words-with-spaces>[ ]*:[ ]<space-separated words>
* An example of /proc/cpuinfo (from Pandaboard-ES):
*
* Processor : ARMv7 Processor rev 10 (v7l)
* processor : 0
* BogoMIPS : 1392.74
*
* processor : 1
* BogoMIPS : 1363.33
*
* Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3
* CPU implementer : 0x41
* CPU architecture: 7
* CPU variant : 0x2
* CPU part : 0xc09
* CPU revision : 10
*
* Hardware : OMAP4 Panda board
* Revision : 0020
* Serial : 0000000000000000
*/
static bool parse_line(
const char* line_start,
const char* line_end,
struct proc_cpuinfo_parser_state state[restrict static 1],
uint64_t line_number)
{
/* Empty line. Skip. */
if (line_start == line_end) {
return true;
}
/* Search for ':' on the line. */
const char* separator = line_start;
for (; separator != line_end; separator++) {
if (*separator == ':') {
break;
}
}
/* Skip line if no ':' separator was found. */
if (separator == line_end) {
cpuinfo_log_info("Line %.*s in /proc/cpuinfo is ignored: key/value separator ':' not found",
(int) (line_end - line_start), line_start);
return true;
}
/* Skip trailing spaces in key part. */
const char* key_end = separator;
for (; key_end != line_start; key_end--) {
if (key_end[-1] != ' ' && key_end[-1] != '\t') {
break;
}
}
/* Skip line if key contains nothing but spaces. */
if (key_end == line_start) {
cpuinfo_log_info("Line %.*s in /proc/cpuinfo is ignored: key contains only spaces",
(int) (line_end - line_start), line_start);
return true;
}
/* Skip leading spaces in value part. */
const char* value_start = separator + 1;
for (; value_start != line_end; value_start++) {
if (*value_start != ' ') {
break;
}
}
/* Value part contains nothing but spaces. Skip line. */
if (value_start == line_end) {
cpuinfo_log_info("Line %.*s in /proc/cpuinfo is ignored: value contains only spaces",
(int) (line_end - line_start), line_start);
return true;
}
/* Skip trailing spaces in value part (if any) */
const char* value_end = line_end;
for (; value_end != value_start; value_end--) {
if (value_end[-1] != ' ') {
break;
}
}
const uint32_t processor_index = state->processor_index;
const uint32_t max_processors_count = state->max_processors_count;
struct cpuinfo_arm_linux_processor* processors = state->processors;
struct cpuinfo_arm_linux_processor* processor = &state->dummy_processor;
if (processor_index < max_processors_count) {
processor = &processors[processor_index];
}
const size_t key_length = key_end - line_start;
switch (key_length) {
case 6:
if (memcmp(line_start, "Serial", key_length) == 0) {
/* Usually contains just zeros, useless */
#if CPUINFO_ARCH_ARM
} else if (memcmp(line_start, "I size", key_length) == 0) {
parse_cache_number(value_start, value_end,
"instruction cache size", &processor->proc_cpuinfo_cache.i_size,
&processor->flags, CPUINFO_ARM_LINUX_VALID_ICACHE_SIZE);
} else if (memcmp(line_start, "I sets", key_length) == 0) {
parse_cache_number(value_start, value_end,
"instruction cache sets", &processor->proc_cpuinfo_cache.i_sets,
&processor->flags, CPUINFO_ARM_LINUX_VALID_ICACHE_SETS);
} else if (memcmp(line_start, "D size", key_length) == 0) {
parse_cache_number(value_start, value_end,
"data cache size", &processor->proc_cpuinfo_cache.d_size,
&processor->flags, CPUINFO_ARM_LINUX_VALID_DCACHE_SIZE);
} else if (memcmp(line_start, "D sets", key_length) == 0) {
parse_cache_number(value_start, value_end,
"data cache sets", &processor->proc_cpuinfo_cache.d_sets,
&processor->flags, CPUINFO_ARM_LINUX_VALID_DCACHE_SETS);
#endif /* CPUINFO_ARCH_ARM */
} else {
goto unknown;
}
break;
#if CPUINFO_ARCH_ARM
case 7:
if (memcmp(line_start, "I assoc", key_length) == 0) {
parse_cache_number(value_start, value_end,
"instruction cache associativity", &processor->proc_cpuinfo_cache.i_assoc,
&processor->flags, CPUINFO_ARM_LINUX_VALID_ICACHE_WAYS);
} else if (memcmp(line_start, "D assoc", key_length) == 0) {
parse_cache_number(value_start, value_end,
"data cache associativity", &processor->proc_cpuinfo_cache.d_assoc,
&processor->flags, CPUINFO_ARM_LINUX_VALID_DCACHE_WAYS);
} else {
goto unknown;
}
break;
#endif /* CPUINFO_ARCH_ARM */
case 8:
if (memcmp(line_start, "CPU part", key_length) == 0) {
parse_cpu_part(value_start, value_end, processor);
} else if (memcmp(line_start, "Features", key_length) == 0) {
parse_features(value_start, value_end, processor);
} else if (memcmp(line_start, "BogoMIPS", key_length) == 0) {
/* BogoMIPS is useless, don't parse */
} else if (memcmp(line_start, "Hardware", key_length) == 0) {
size_t value_length = value_end - value_start;
if (value_length > CPUINFO_HARDWARE_VALUE_MAX) {
cpuinfo_log_info(
"length of Hardware value \"%.*s\" in /proc/cpuinfo exceeds limit (%d): truncating to the limit",
(int) value_length, value_start, CPUINFO_HARDWARE_VALUE_MAX);
value_length = CPUINFO_HARDWARE_VALUE_MAX;
} else {
state->hardware[value_length] = '\0';
}
memcpy(state->hardware, value_start, value_length);
cpuinfo_log_debug("parsed /proc/cpuinfo Hardware = \"%.*s\"", (int) value_length, value_start);
} else if (memcmp(line_start, "Revision", key_length) == 0) {
size_t value_length = value_end - value_start;
if (value_length > CPUINFO_REVISION_VALUE_MAX) {
cpuinfo_log_info(
"length of Revision value \"%.*s\" in /proc/cpuinfo exceeds limit (%d): truncating to the limit",
(int) value_length, value_start, CPUINFO_REVISION_VALUE_MAX);
value_length = CPUINFO_REVISION_VALUE_MAX;
} else {
state->revision[value_length] = '\0';
}
memcpy(state->revision, value_start, value_length);
cpuinfo_log_debug("parsed /proc/cpuinfo Revision = \"%.*s\"", (int) value_length, value_start);
} else {
goto unknown;
}
break;
case 9:
if (memcmp(line_start, "processor", key_length) == 0) {
const uint32_t new_processor_index = parse_processor_number(value_start, value_end);
if (new_processor_index < processor_index) {
/* Strange: decreasing processor number */
cpuinfo_log_warning(
"unexpectedly low processor number %"PRIu32" following processor %"PRIu32" in /proc/cpuinfo",
new_processor_index, processor_index);
} else if (new_processor_index > processor_index + 1) {
/* Strange, but common: skipped processor $(processor_index + 1) */
cpuinfo_log_info(
"unexpectedly high processor number %"PRIu32" following processor %"PRIu32" in /proc/cpuinfo",
new_processor_index, processor_index);
}
if (new_processor_index < max_processors_count) {
/* Record that the processor was mentioned in /proc/cpuinfo */
processors[new_processor_index].flags |= CPUINFO_ARM_LINUX_VALID_PROCESSOR;
} else {
/* Log and ignore processor */
cpuinfo_log_warning("processor %"PRIu32" in /proc/cpuinfo is ignored: index exceeds system limit %"PRIu32,
new_processor_index, max_processors_count - 1);
}
state->processor_index = new_processor_index;
return true;
} else if (memcmp(line_start, "Processor", key_length) == 0) {
/* TODO: parse to fix misreported architecture, similar to Android's cpufeatures */
} else {
goto unknown;
}
break;
case 11:
if (memcmp(line_start, "CPU variant", key_length) == 0) {
parse_cpu_variant(value_start, value_end, processor);
} else {
goto unknown;
}
break;
case 12:
if (memcmp(line_start, "CPU revision", key_length) == 0) {
parse_cpu_revision(value_start, value_end, processor);
} else {
goto unknown;
}
break;
#if CPUINFO_ARCH_ARM
case 13:
if (memcmp(line_start, "I line length", key_length) == 0) {
parse_cache_number(value_start, value_end,
"instruction cache line size", &processor->proc_cpuinfo_cache.i_line_length,
&processor->flags, CPUINFO_ARM_LINUX_VALID_ICACHE_LINE);
} else if (memcmp(line_start, "D line length", key_length) == 0) {
parse_cache_number(value_start, value_end,
"data cache line size", &processor->proc_cpuinfo_cache.d_line_length,
&processor->flags, CPUINFO_ARM_LINUX_VALID_DCACHE_LINE);
} else {
goto unknown;
}
break;
#endif /* CPUINFO_ARCH_ARM */
case 15:
if (memcmp(line_start, "CPU implementer", key_length) == 0) {
parse_cpu_implementer(value_start, value_end, processor);
} else if (memcmp(line_start, "CPU implementor", key_length) == 0) {
parse_cpu_implementer(value_start, value_end, processor);
} else {
goto unknown;
}
break;
case 16:
if (memcmp(line_start, "CPU architecture", key_length) == 0) {
parse_cpu_architecture(value_start, value_end, processor);
} else {
goto unknown;
}
break;
default:
unknown:
cpuinfo_log_debug("unknown /proc/cpuinfo key: %.*s", (int) key_length, line_start);
}
return true;
}
bool cpuinfo_arm_linux_parse_proc_cpuinfo(
char hardware[restrict static CPUINFO_HARDWARE_VALUE_MAX],
char revision[restrict static CPUINFO_REVISION_VALUE_MAX],
uint32_t max_processors_count,
struct cpuinfo_arm_linux_processor processors[restrict static max_processors_count])
{
hardware[0] = '\0';
struct proc_cpuinfo_parser_state state = {
.hardware = hardware,
.revision = revision,
.processor_index = 0,
.max_processors_count = max_processors_count,
.processors = processors,
};
return cpuinfo_linux_parse_multiline_file("/proc/cpuinfo", BUFFER_SIZE,
(cpuinfo_line_callback) parse_line, &state);
}
-163
View File
@@ -1,163 +0,0 @@
#include <limits.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <dlfcn.h>
#include <elf.h>
#if CPUINFO_MOCK
#include <cpuinfo-mock.h>
#endif
#include <cpuinfo.h>
#include <arm/linux/api.h>
#include <cpuinfo/log.h>
#if CPUINFO_ARCH_ARM64 || CPUINFO_ARCH_ARM && \
defined(__GLIBC__) && defined(__GLIBC_MINOR__) && (__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 16)
#include <sys/auxv.h>
#else
#define AT_HWCAP 16
#define AT_HWCAP2 26
#endif
#if CPUINFO_MOCK
static uint32_t mock_hwcap = 0;
void cpuinfo_set_hwcap(uint32_t hwcap) {
mock_hwcap = hwcap;
}
static uint32_t mock_hwcap2 = 0;
void cpuinfo_set_hwcap2(uint32_t hwcap2) {
mock_hwcap2 = hwcap2;
}
#endif
#if CPUINFO_ARCH_ARM
typedef unsigned long (*getauxval_function_t)(unsigned long);
bool cpuinfo_arm_linux_hwcap_from_getauxval(
uint32_t hwcap[restrict static 1],
uint32_t hwcap2[restrict static 1])
{
#if CPUINFO_MOCK
*hwcap = mock_hwcap;
*hwcap2 = mock_hwcap2;
return true;
#elif defined(__ANDROID__)
/* Android: dynamically check if getauxval is supported */
void* libc = NULL;
getauxval_function_t getauxval = NULL;
dlerror();
libc = dlopen("libc.so", RTLD_LAZY);
if (libc == NULL) {
cpuinfo_log_warning("failed to load libc.so: %s", dlerror());
goto cleanup;
}
getauxval = (getauxval_function_t) dlsym(libc, "getauxval");
if (getauxval == NULL) {
cpuinfo_log_info("failed to locate getauxval in libc.so: %s", dlerror());
goto cleanup;
}
*hwcap = getauxval(AT_HWCAP);
*hwcap2 = getauxval(AT_HWCAP2);
cleanup:
if (libc != NULL) {
dlclose(libc);
libc = NULL;
}
return getauxval != NULL;
#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) && (__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 16)
/* GNU/Linux: getauxval is supported since glibc-2.16 */
*hwcap = getauxval(AT_HWCAP);
*hwcap2 = getauxval(AT_HWCAP2);
return true;
#else
return false;
#endif
}
#ifdef __ANDROID__
bool cpuinfo_arm_linux_hwcap_from_procfs(
uint32_t hwcap[restrict static 1],
uint32_t hwcap2[restrict static 1])
{
#if CPUINFO_MOCK
*hwcap = mock_hwcap;
*hwcap2 = mock_hwcap2;
return true;
#else
uint32_t hwcaps[2] = { 0, 0 };
bool result = false;
int file = -1;
file = open("/proc/self/auxv", O_RDONLY);
if (file == -1) {
cpuinfo_log_warning("failed to open /proc/self/auxv: %s", strerror(errno));
goto cleanup;
}
ssize_t bytes_read;
do {
Elf32_auxv_t elf_auxv;
bytes_read = read(file, &elf_auxv, sizeof(Elf32_auxv_t));
if (bytes_read < 0) {
cpuinfo_log_warning("failed to read /proc/self/auxv: %s", strerror(errno));
goto cleanup;
} else if (bytes_read > 0) {
if (bytes_read == sizeof(elf_auxv)) {
switch (elf_auxv.a_type) {
case AT_HWCAP:
hwcaps[0] = (uint32_t) elf_auxv.a_un.a_val;
break;
case AT_HWCAP2:
hwcaps[1] = (uint32_t) elf_auxv.a_un.a_val;
break;
}
} else {
cpuinfo_log_warning(
"failed to read %zu bytes from /proc/self/auxv: %zu bytes available",
sizeof(elf_auxv), (size_t) bytes_read);
goto cleanup;
}
}
} while (bytes_read == sizeof(Elf32_auxv_t));
/* Success, commit results */
*hwcap = hwcaps[0];
*hwcap2 = hwcaps[1];
result = true;
cleanup:
if (file != -1) {
close(file);
file = -1;
}
return result;
#endif
}
#endif /* __ANDROID__ */
#elif CPUINFO_ARCH_ARM64
void cpuinfo_arm_linux_hwcap_from_getauxval(
uint32_t hwcap[restrict static 1],
uint32_t hwcap2[restrict static 1])
{
#if CPUINFO_MOCK
*hwcap = mock_hwcap;
*hwcap2 = mock_hwcap2;
#else
*hwcap = (uint32_t) getauxval(AT_HWCAP);
*hwcap2 = (uint32_t) getauxval(AT_HWCAP2);
return ;
#endif
}
#endif
-769
View File
@@ -1,769 +0,0 @@
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <cpuinfo.h>
#include <arm/linux/api.h>
#if defined(__ANDROID__)
#include <arm/android/api.h>
#endif
#include <arm/api.h>
#include <arm/midr.h>
#include <linux/api.h>
#include <cpuinfo/internal-api.h>
#include <cpuinfo/log.h>
struct cpuinfo_arm_isa cpuinfo_isa = { 0 };
static struct cpuinfo_package package = { { 0 } };
static inline bool bitmask_all(uint32_t bitfield, uint32_t mask) {
return (bitfield & mask) == mask;
}
static inline uint32_t min(uint32_t a, uint32_t b) {
return a < b ? a : b;
}
static inline int cmp(uint32_t a, uint32_t b) {
return (a > b) - (a < b);
}
static bool cluster_siblings_parser(
uint32_t processor, uint32_t siblings_start, uint32_t siblings_end,
struct cpuinfo_arm_linux_processor* processors)
{
processors[processor].flags |= CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER;
uint32_t package_leader_id = processors[processor].package_leader_id;
for (uint32_t sibling = siblings_start; sibling < siblings_end; sibling++) {
if (!bitmask_all(processors[sibling].flags, CPUINFO_LINUX_FLAG_VALID)) {
cpuinfo_log_info("invalid processor %"PRIu32" reported as a sibling for processor %"PRIu32,
sibling, processor);
continue;
}
const uint32_t sibling_package_leader_id = processors[sibling].package_leader_id;
if (sibling_package_leader_id < package_leader_id) {
package_leader_id = sibling_package_leader_id;
}
processors[sibling].package_leader_id = package_leader_id;
processors[sibling].flags |= CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER;
}
processors[processor].package_leader_id = package_leader_id;
return true;
}
static int cmp_arm_linux_processor(const void* ptr_a, const void* ptr_b) {
const struct cpuinfo_arm_linux_processor* processor_a = (const struct cpuinfo_arm_linux_processor*) ptr_a;
const struct cpuinfo_arm_linux_processor* processor_b = (const struct cpuinfo_arm_linux_processor*) ptr_b;
/* Move usable processors towards the start of the array */
const bool usable_a = bitmask_all(processor_a->flags, CPUINFO_LINUX_FLAG_VALID);
const bool usable_b = bitmask_all(processor_b->flags, CPUINFO_LINUX_FLAG_VALID);
if (usable_a != usable_b) {
return (int) usable_b - (int) usable_a;
}
/* Compare based on core type (e.g. Cortex-A57 < Cortex-A53) */
const uint32_t midr_a = processor_a->midr;
const uint32_t midr_b = processor_b->midr;
if (midr_a != midr_b) {
const uint32_t score_a = midr_score_core(midr_a);
const uint32_t score_b = midr_score_core(midr_b);
if (score_a != score_b) {
return score_a > score_b ? -1 : 1;
}
}
/* Compare based on core frequency (e.g. 2.0 GHz < 1.2 GHz) */
const uint32_t frequency_a = processor_a->max_frequency;
const uint32_t frequency_b = processor_b->max_frequency;
if (frequency_a != frequency_b) {
return frequency_a > frequency_b ? -1 : 1;
}
/* Compare based on cluster leader id (i.e. cluster 1 < cluster 0) */
const uint32_t cluster_a = processor_a->package_leader_id;
const uint32_t cluster_b = processor_b->package_leader_id;
if (cluster_a != cluster_b) {
return cluster_a > cluster_b ? -1 : 1;
}
/* Compare based on system processor id (i.e. processor 0 < processor 1) */
const uint32_t id_a = processor_a->system_processor_id;
const uint32_t id_b = processor_b->system_processor_id;
return cmp(id_a, id_b);
}
void cpuinfo_arm_linux_init(void) {
struct cpuinfo_arm_linux_processor* arm_linux_processors = NULL;
struct cpuinfo_processor* processors = NULL;
struct cpuinfo_core* cores = NULL;
struct cpuinfo_cluster* clusters = NULL;
struct cpuinfo_uarch_info* uarchs = NULL;
struct cpuinfo_cache* l1i = NULL;
struct cpuinfo_cache* l1d = NULL;
struct cpuinfo_cache* l2 = NULL;
struct cpuinfo_cache* l3 = NULL;
const struct cpuinfo_processor** linux_cpu_to_processor_map = NULL;
const struct cpuinfo_core** linux_cpu_to_core_map = NULL;
uint32_t* linux_cpu_to_uarch_index_map = NULL;
const uint32_t max_processors_count = cpuinfo_linux_get_max_processors_count();
cpuinfo_log_debug("system maximum processors count: %"PRIu32, max_processors_count);
const uint32_t max_possible_processors_count = 1 +
cpuinfo_linux_get_max_possible_processor(max_processors_count);
cpuinfo_log_debug("maximum possible processors count: %"PRIu32, max_possible_processors_count);
const uint32_t max_present_processors_count = 1 +
cpuinfo_linux_get_max_present_processor(max_processors_count);
cpuinfo_log_debug("maximum present processors count: %"PRIu32, max_present_processors_count);
uint32_t valid_processor_mask = 0;
uint32_t arm_linux_processors_count = max_processors_count;
if (max_present_processors_count != 0) {
arm_linux_processors_count = min(arm_linux_processors_count, max_present_processors_count);
valid_processor_mask = CPUINFO_LINUX_FLAG_PRESENT;
}
if (max_possible_processors_count != 0) {
arm_linux_processors_count = min(arm_linux_processors_count, max_possible_processors_count);
valid_processor_mask |= CPUINFO_LINUX_FLAG_POSSIBLE;
}
if ((max_present_processors_count | max_possible_processors_count) == 0) {
cpuinfo_log_error("failed to parse both lists of possible and present processors");
return;
}
arm_linux_processors = calloc(arm_linux_processors_count, sizeof(struct cpuinfo_arm_linux_processor));
if (arm_linux_processors == NULL) {
cpuinfo_log_error(
"failed to allocate %zu bytes for descriptions of %"PRIu32" ARM logical processors",
arm_linux_processors_count * sizeof(struct cpuinfo_arm_linux_processor),
arm_linux_processors_count);
return;
}
if (max_possible_processors_count) {
cpuinfo_linux_detect_possible_processors(
arm_linux_processors_count, &arm_linux_processors->flags,
sizeof(struct cpuinfo_arm_linux_processor),
CPUINFO_LINUX_FLAG_POSSIBLE);
}
if (max_present_processors_count) {
cpuinfo_linux_detect_present_processors(
arm_linux_processors_count, &arm_linux_processors->flags,
sizeof(struct cpuinfo_arm_linux_processor),
CPUINFO_LINUX_FLAG_PRESENT);
}
#if defined(__ANDROID__)
struct cpuinfo_android_properties android_properties;
cpuinfo_arm_android_parse_properties(&android_properties);
#else
char proc_cpuinfo_hardware[CPUINFO_HARDWARE_VALUE_MAX];
#endif
char proc_cpuinfo_revision[CPUINFO_REVISION_VALUE_MAX];
if (!cpuinfo_arm_linux_parse_proc_cpuinfo(
#if defined(__ANDROID__)
android_properties.proc_cpuinfo_hardware,
#else
proc_cpuinfo_hardware,
#endif
proc_cpuinfo_revision,
arm_linux_processors_count,
arm_linux_processors)) {
cpuinfo_log_error("failed to parse processor information from /proc/cpuinfo");
return;
}
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
if (bitmask_all(arm_linux_processors[i].flags, valid_processor_mask)) {
arm_linux_processors[i].flags |= CPUINFO_LINUX_FLAG_VALID;
cpuinfo_log_debug("parsed processor %"PRIu32" MIDR 0x%08"PRIx32,
i, arm_linux_processors[i].midr);
}
}
uint32_t valid_processors = 0, last_midr = 0;
#if CPUINFO_ARCH_ARM
uint32_t last_architecture_version = 0, last_architecture_flags = 0;
#endif
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
arm_linux_processors[i].system_processor_id = i;
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
if (arm_linux_processors[i].flags & CPUINFO_ARM_LINUX_VALID_PROCESSOR) {
/*
* Processor is in possible and present lists, and also reported in /proc/cpuinfo.
* This processor is availble for compute.
*/
valid_processors += 1;
} else {
/*
* Processor is in possible and present lists, but not reported in /proc/cpuinfo.
* This is fairly common: high-index processors can be not reported if they are offline.
*/
cpuinfo_log_info("processor %"PRIu32" is not listed in /proc/cpuinfo", i);
}
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_ARM_LINUX_VALID_MIDR)) {
last_midr = arm_linux_processors[i].midr;
}
#if CPUINFO_ARCH_ARM
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_ARM_LINUX_VALID_ARCHITECTURE)) {
last_architecture_version = arm_linux_processors[i].architecture_version;
last_architecture_flags = arm_linux_processors[i].architecture_flags;
}
#endif
} else {
/* Processor reported in /proc/cpuinfo, but not in possible and/or present lists: log and ignore */
if (!(arm_linux_processors[i].flags & CPUINFO_ARM_LINUX_VALID_PROCESSOR)) {
cpuinfo_log_warning("invalid processor %"PRIu32" reported in /proc/cpuinfo", i);
}
}
}
#if defined(__ANDROID__)
const struct cpuinfo_arm_chipset chipset =
cpuinfo_arm_android_decode_chipset(&android_properties, valid_processors, 0);
#else
const struct cpuinfo_arm_chipset chipset =
cpuinfo_arm_linux_decode_chipset(proc_cpuinfo_hardware, proc_cpuinfo_revision, valid_processors, 0);
#endif
#if CPUINFO_ARCH_ARM
uint32_t isa_features = 0, isa_features2 = 0;
#ifdef __ANDROID__
/*
* On Android before API 20, libc.so does not provide getauxval function.
* Thus, we try to dynamically find it, or use two fallback mechanisms:
* 1. dlopen libc.so, and try to find getauxval
* 2. Parse /proc/self/auxv procfs file
* 3. Use features reported in /proc/cpuinfo
*/
if (!cpuinfo_arm_linux_hwcap_from_getauxval(&isa_features, &isa_features2)) {
/* getauxval can't be used, fall back to parsing /proc/self/auxv */
if (!cpuinfo_arm_linux_hwcap_from_procfs(&isa_features, &isa_features2)) {
/*
* Reading /proc/self/auxv failed, probably due to file permissions.
* Use information from /proc/cpuinfo to detect ISA.
*
* If different processors report different ISA features, take the intersection.
*/
uint32_t processors_with_features = 0;
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID | CPUINFO_ARM_LINUX_VALID_FEATURES)) {
if (processors_with_features == 0) {
isa_features = arm_linux_processors[i].features;
isa_features2 = arm_linux_processors[i].features2;
} else {
isa_features &= arm_linux_processors[i].features;
isa_features2 &= arm_linux_processors[i].features2;
}
processors_with_features += 1;
}
}
}
}
#else
/* On GNU/Linux getauxval is always available */
cpuinfo_arm_linux_hwcap_from_getauxval(&isa_features, &isa_features2);
#endif
cpuinfo_arm_linux_decode_isa_from_proc_cpuinfo(
isa_features, isa_features2,
last_midr, last_architecture_version, last_architecture_flags,
&chipset, &cpuinfo_isa);
#elif CPUINFO_ARCH_ARM64
uint32_t isa_features = 0, isa_features2 = 0;
/* getauxval is always available on ARM64 Android */
cpuinfo_arm_linux_hwcap_from_getauxval(&isa_features, &isa_features2);
cpuinfo_arm64_linux_decode_isa_from_proc_cpuinfo(
isa_features, isa_features2, last_midr, &chipset, &cpuinfo_isa);
#endif
/* Detect min/max frequency and package ID */
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
const uint32_t max_frequency = cpuinfo_linux_get_processor_max_frequency(i);
if (max_frequency != 0) {
arm_linux_processors[i].max_frequency = max_frequency;
arm_linux_processors[i].flags |= CPUINFO_LINUX_FLAG_MAX_FREQUENCY;
}
const uint32_t min_frequency = cpuinfo_linux_get_processor_min_frequency(i);
if (min_frequency != 0) {
arm_linux_processors[i].min_frequency = min_frequency;
arm_linux_processors[i].flags |= CPUINFO_LINUX_FLAG_MIN_FREQUENCY;
}
if (cpuinfo_linux_get_processor_package_id(i, &arm_linux_processors[i].package_id)) {
arm_linux_processors[i].flags |= CPUINFO_LINUX_FLAG_PACKAGE_ID;
}
}
}
/* Initialize topology group IDs */
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
arm_linux_processors[i].package_leader_id = i;
}
/* Propagate topology group IDs among siblings */
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
if (!bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
continue;
}
if (arm_linux_processors[i].flags & CPUINFO_LINUX_FLAG_PACKAGE_ID) {
cpuinfo_linux_detect_core_siblings(
arm_linux_processors_count, i,
(cpuinfo_siblings_callback) cluster_siblings_parser,
arm_linux_processors);
}
}
/* Propagate all cluster IDs */
uint32_t clustered_processors = 0;
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID | CPUINFO_LINUX_FLAG_PACKAGE_CLUSTER)) {
clustered_processors += 1;
const uint32_t package_leader_id = arm_linux_processors[i].package_leader_id;
if (package_leader_id < i) {
arm_linux_processors[i].package_leader_id = arm_linux_processors[package_leader_id].package_leader_id;
}
cpuinfo_log_debug("processor %"PRIu32" clustered with processor %"PRIu32" as inferred from system siblings lists",
i, arm_linux_processors[i].package_leader_id);
}
}
if (clustered_processors != valid_processors) {
/*
* Topology information about some or all logical processors may be unavailable, for the following reasons:
* - Linux kernel is too old, or configured without support for topology information in sysfs.
* - Core is offline, and Linux kernel is configured to not report topology for offline cores.
*
* In this case, we assign processors to clusters using two methods:
* - Try heuristic cluster configurations (e.g. 6-core SoC usually has 4+2 big.LITTLE configuration).
* - If heuristic failed, assign processors to core clusters in a sequential scan.
*/
if (!cpuinfo_arm_linux_detect_core_clusters_by_heuristic(valid_processors, arm_linux_processors_count, arm_linux_processors)) {
cpuinfo_arm_linux_detect_core_clusters_by_sequential_scan(arm_linux_processors_count, arm_linux_processors);
}
}
cpuinfo_arm_linux_count_cluster_processors(arm_linux_processors_count, arm_linux_processors);
const uint32_t cluster_count = cpuinfo_arm_linux_detect_cluster_midr(
&chipset,
arm_linux_processors_count, valid_processors, arm_linux_processors);
/* Initialize core vendor, uarch, MIDR, and frequency for every logical processor */
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
const uint32_t cluster_leader = arm_linux_processors[i].package_leader_id;
if (cluster_leader == i) {
/* Cluster leader: decode core vendor and uarch */
cpuinfo_arm_decode_vendor_uarch(
arm_linux_processors[cluster_leader].midr,
#if CPUINFO_ARCH_ARM
!!(arm_linux_processors[cluster_leader].features & CPUINFO_ARM_LINUX_FEATURE_VFPV4),
#endif
&arm_linux_processors[cluster_leader].vendor,
&arm_linux_processors[cluster_leader].uarch);
} else {
/* Cluster non-leader: copy vendor, uarch, MIDR, and frequency from cluster leader */
arm_linux_processors[i].flags |= arm_linux_processors[cluster_leader].flags &
(CPUINFO_ARM_LINUX_VALID_MIDR | CPUINFO_LINUX_FLAG_MAX_FREQUENCY);
arm_linux_processors[i].midr = arm_linux_processors[cluster_leader].midr;
arm_linux_processors[i].vendor = arm_linux_processors[cluster_leader].vendor;
arm_linux_processors[i].uarch = arm_linux_processors[cluster_leader].uarch;
arm_linux_processors[i].max_frequency = arm_linux_processors[cluster_leader].max_frequency;
}
}
}
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
cpuinfo_log_debug("post-analysis processor %"PRIu32": MIDR %08"PRIx32" frequency %"PRIu32,
i, arm_linux_processors[i].midr, arm_linux_processors[i].max_frequency);
}
}
qsort(arm_linux_processors, arm_linux_processors_count,
sizeof(struct cpuinfo_arm_linux_processor), cmp_arm_linux_processor);
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
cpuinfo_log_debug("post-sort processor %"PRIu32": system id %"PRIu32" MIDR %08"PRIx32" frequency %"PRIu32,
i, arm_linux_processors[i].system_processor_id, arm_linux_processors[i].midr, arm_linux_processors[i].max_frequency);
}
}
uint32_t uarchs_count = 0;
enum cpuinfo_uarch last_uarch;
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
if (uarchs_count == 0 || arm_linux_processors[i].uarch != last_uarch) {
last_uarch = arm_linux_processors[i].uarch;
uarchs_count += 1;
}
arm_linux_processors[i].uarch_index = uarchs_count - 1;
}
}
/*
* Assumptions:
* - No SMP (i.e. each core supports only one hardware thread).
* - Level 1 instruction and data caches are private to the core clusters.
* - Level 2 and level 3 cache is shared between cores in the same cluster.
*/
cpuinfo_arm_chipset_to_string(&chipset, package.name);
package.processor_count = valid_processors;
package.core_count = valid_processors;
package.cluster_count = cluster_count;
processors = calloc(valid_processors, sizeof(struct cpuinfo_processor));
if (processors == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" logical processors",
valid_processors * sizeof(struct cpuinfo_processor), valid_processors);
goto cleanup;
}
cores = calloc(valid_processors, sizeof(struct cpuinfo_core));
if (cores == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" cores",
valid_processors * sizeof(struct cpuinfo_core), valid_processors);
goto cleanup;
}
clusters = calloc(cluster_count, sizeof(struct cpuinfo_cluster));
if (clusters == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" core clusters",
cluster_count * sizeof(struct cpuinfo_cluster), cluster_count);
goto cleanup;
}
uarchs = calloc(uarchs_count, sizeof(struct cpuinfo_uarch_info));
if (uarchs == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" microarchitectures",
uarchs_count * sizeof(struct cpuinfo_uarch_info), uarchs_count);
goto cleanup;
}
linux_cpu_to_processor_map = calloc(arm_linux_processors_count, sizeof(struct cpuinfo_processor*));
if (linux_cpu_to_processor_map == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for %"PRIu32" logical processor mapping entries",
arm_linux_processors_count * sizeof(struct cpuinfo_processor*), arm_linux_processors_count);
goto cleanup;
}
linux_cpu_to_core_map = calloc(arm_linux_processors_count, sizeof(struct cpuinfo_core*));
if (linux_cpu_to_core_map == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for %"PRIu32" core mapping entries",
arm_linux_processors_count * sizeof(struct cpuinfo_core*), arm_linux_processors_count);
goto cleanup;
}
if (uarchs_count > 1) {
linux_cpu_to_uarch_index_map = calloc(arm_linux_processors_count, sizeof(uint32_t));
if (linux_cpu_to_uarch_index_map == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for %"PRIu32" uarch index mapping entries",
arm_linux_processors_count * sizeof(uint32_t), arm_linux_processors_count);
goto cleanup;
}
}
l1i = calloc(valid_processors, sizeof(struct cpuinfo_cache));
if (l1i == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L1I caches",
valid_processors * sizeof(struct cpuinfo_cache), valid_processors);
goto cleanup;
}
l1d = calloc(valid_processors, sizeof(struct cpuinfo_cache));
if (l1d == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L1D caches",
valid_processors * sizeof(struct cpuinfo_cache), valid_processors);
goto cleanup;
}
uint32_t uarchs_index = 0;
for (uint32_t i = 0; i < arm_linux_processors_count; i++) {
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
if (uarchs_index == 0 || arm_linux_processors[i].uarch != last_uarch) {
last_uarch = arm_linux_processors[i].uarch;
uarchs[uarchs_index] = (struct cpuinfo_uarch_info) {
.uarch = arm_linux_processors[i].uarch,
.midr = arm_linux_processors[i].midr,
};
uarchs_index += 1;
}
uarchs[uarchs_index - 1].processor_count += 1;
uarchs[uarchs_index - 1].core_count += 1;
}
}
uint32_t l2_count = 0, l3_count = 0, big_l3_size = 0, cluster_id = UINT32_MAX;
/* Indication whether L3 (if it exists) is shared between all cores */
bool shared_l3 = true;
/* Populate cache information structures in l1i, l1d */
for (uint32_t i = 0; i < valid_processors; i++) {
if (arm_linux_processors[i].package_leader_id == arm_linux_processors[i].system_processor_id) {
cluster_id += 1;
clusters[cluster_id] = (struct cpuinfo_cluster) {
.processor_start = i,
.processor_count = arm_linux_processors[i].package_processor_count,
.core_start = i,
.core_count = arm_linux_processors[i].package_processor_count,
.cluster_id = cluster_id,
.package = &package,
.vendor = arm_linux_processors[i].vendor,
.uarch = arm_linux_processors[i].uarch,
.midr = arm_linux_processors[i].midr,
};
}
processors[i].smt_id = 0;
processors[i].core = cores + i;
processors[i].cluster = clusters + cluster_id;
processors[i].package = &package;
processors[i].linux_id = (int) arm_linux_processors[i].system_processor_id;
processors[i].cache.l1i = l1i + i;
processors[i].cache.l1d = l1d + i;
linux_cpu_to_processor_map[arm_linux_processors[i].system_processor_id] = &processors[i];
cores[i].processor_start = i;
cores[i].processor_count = 1;
cores[i].core_id = i;
cores[i].cluster = clusters + cluster_id;
cores[i].package = &package;
cores[i].vendor = arm_linux_processors[i].vendor;
cores[i].uarch = arm_linux_processors[i].uarch;
cores[i].midr = arm_linux_processors[i].midr;
linux_cpu_to_core_map[arm_linux_processors[i].system_processor_id] = &cores[i];
if (linux_cpu_to_uarch_index_map != NULL) {
linux_cpu_to_uarch_index_map[arm_linux_processors[i].system_processor_id] =
arm_linux_processors[i].uarch_index;
}
struct cpuinfo_cache temp_l2 = { 0 }, temp_l3 = { 0 };
cpuinfo_arm_decode_cache(
arm_linux_processors[i].uarch,
arm_linux_processors[i].package_processor_count,
arm_linux_processors[i].midr,
&chipset,
cluster_id,
arm_linux_processors[i].architecture_version,
&l1i[i], &l1d[i], &temp_l2, &temp_l3);
l1i[i].processor_start = l1d[i].processor_start = i;
l1i[i].processor_count = l1d[i].processor_count = 1;
#if CPUINFO_ARCH_ARM
/* L1I reported in /proc/cpuinfo overrides defaults */
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_ARM_LINUX_VALID_ICACHE)) {
l1i[i] = (struct cpuinfo_cache) {
.size = arm_linux_processors[i].proc_cpuinfo_cache.i_size,
.associativity = arm_linux_processors[i].proc_cpuinfo_cache.i_assoc,
.sets = arm_linux_processors[i].proc_cpuinfo_cache.i_sets,
.partitions = 1,
.line_size = arm_linux_processors[i].proc_cpuinfo_cache.i_line_length
};
}
/* L1D reported in /proc/cpuinfo overrides defaults */
if (bitmask_all(arm_linux_processors[i].flags, CPUINFO_ARM_LINUX_VALID_DCACHE)) {
l1d[i] = (struct cpuinfo_cache) {
.size = arm_linux_processors[i].proc_cpuinfo_cache.d_size,
.associativity = arm_linux_processors[i].proc_cpuinfo_cache.d_assoc,
.sets = arm_linux_processors[i].proc_cpuinfo_cache.d_sets,
.partitions = 1,
.line_size = arm_linux_processors[i].proc_cpuinfo_cache.d_line_length
};
}
#endif
if (temp_l3.size != 0) {
/*
* Assumptions:
* - L2 is private to each core
* - L3 is shared by cores in the same cluster
* - If cores in different clusters report the same L3, it is shared between all cores.
*/
l2_count += 1;
if (arm_linux_processors[i].package_leader_id == arm_linux_processors[i].system_processor_id) {
if (cluster_id == 0) {
big_l3_size = temp_l3.size;
l3_count = 1;
} else if (temp_l3.size != big_l3_size) {
/* If some cores have different L3 size, L3 is not shared between all cores */
shared_l3 = false;
l3_count += 1;
}
}
} else {
/* If some cores don't have L3 cache, L3 is not shared between all cores */
shared_l3 = false;
if (temp_l2.size != 0) {
/* Assume L2 is shared by cores in the same cluster */
if (arm_linux_processors[i].package_leader_id == arm_linux_processors[i].system_processor_id) {
l2_count += 1;
}
}
}
}
if (l2_count != 0) {
l2 = calloc(l2_count, sizeof(struct cpuinfo_cache));
if (l2 == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L2 caches",
l2_count * sizeof(struct cpuinfo_cache), l2_count);
goto cleanup;
}
if (l3_count != 0) {
l3 = calloc(l3_count, sizeof(struct cpuinfo_cache));
if (l3 == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L3 caches",
l3_count * sizeof(struct cpuinfo_cache), l3_count);
goto cleanup;
}
}
}
cluster_id = UINT32_MAX;
uint32_t l2_index = UINT32_MAX, l3_index = UINT32_MAX;
for (uint32_t i = 0; i < valid_processors; i++) {
if (arm_linux_processors[i].package_leader_id == arm_linux_processors[i].system_processor_id) {
cluster_id++;
}
struct cpuinfo_cache dummy_l1i, dummy_l1d, temp_l2 = { 0 }, temp_l3 = { 0 };
cpuinfo_arm_decode_cache(
arm_linux_processors[i].uarch,
arm_linux_processors[i].package_processor_count,
arm_linux_processors[i].midr,
&chipset,
cluster_id,
arm_linux_processors[i].architecture_version,
&dummy_l1i, &dummy_l1d, &temp_l2, &temp_l3);
if (temp_l3.size != 0) {
/*
* Assumptions:
* - L2 is private to each core
* - L3 is shared by cores in the same cluster
* - If cores in different clusters report the same L3, it is shared between all cores.
*/
l2_index += 1;
l2[l2_index] = (struct cpuinfo_cache) {
.size = temp_l2.size,
.associativity = temp_l2.associativity,
.sets = temp_l2.sets,
.partitions = 1,
.line_size = temp_l2.line_size,
.flags = temp_l2.flags,
.processor_start = i,
.processor_count = 1,
};
processors[i].cache.l2 = l2 + l2_index;
if (arm_linux_processors[i].package_leader_id == arm_linux_processors[i].system_processor_id) {
l3_index += 1;
if (l3_index < l3_count) {
l3[l3_index] = (struct cpuinfo_cache) {
.size = temp_l3.size,
.associativity = temp_l3.associativity,
.sets = temp_l3.sets,
.partitions = 1,
.line_size = temp_l3.line_size,
.flags = temp_l3.flags,
.processor_start = i,
.processor_count =
shared_l3 ? valid_processors : arm_linux_processors[i].package_processor_count,
};
}
}
if (shared_l3) {
processors[i].cache.l3 = l3;
} else if (l3_index < l3_count) {
processors[i].cache.l3 = l3 + l3_index;
}
} else if (temp_l2.size != 0) {
/* Assume L2 is shared by cores in the same cluster */
if (arm_linux_processors[i].package_leader_id == arm_linux_processors[i].system_processor_id) {
l2_index += 1;
l2[l2_index] = (struct cpuinfo_cache) {
.size = temp_l2.size,
.associativity = temp_l2.associativity,
.sets = temp_l2.sets,
.partitions = 1,
.line_size = temp_l2.line_size,
.flags = temp_l2.flags,
.processor_start = i,
.processor_count = arm_linux_processors[i].package_processor_count,
};
}
processors[i].cache.l2 = l2 + l2_index;
}
}
/* Commit */
cpuinfo_processors = processors;
cpuinfo_cores = cores;
cpuinfo_clusters = clusters;
cpuinfo_packages = &package;
cpuinfo_uarchs = uarchs;
cpuinfo_cache[cpuinfo_cache_level_1i] = l1i;
cpuinfo_cache[cpuinfo_cache_level_1d] = l1d;
cpuinfo_cache[cpuinfo_cache_level_2] = l2;
cpuinfo_cache[cpuinfo_cache_level_3] = l3;
cpuinfo_processors_count = valid_processors;
cpuinfo_cores_count = valid_processors;
cpuinfo_clusters_count = cluster_count;
cpuinfo_packages_count = 1;
cpuinfo_uarchs_count = uarchs_count;
cpuinfo_cache_count[cpuinfo_cache_level_1i] = valid_processors;
cpuinfo_cache_count[cpuinfo_cache_level_1d] = valid_processors;
cpuinfo_cache_count[cpuinfo_cache_level_2] = l2_count;
cpuinfo_cache_count[cpuinfo_cache_level_3] = l3_count;
cpuinfo_max_cache_size = cpuinfo_arm_compute_max_cache_size(&processors[0]);
cpuinfo_linux_cpu_max = arm_linux_processors_count;
cpuinfo_linux_cpu_to_processor_map = linux_cpu_to_processor_map;
cpuinfo_linux_cpu_to_core_map = linux_cpu_to_core_map;
cpuinfo_linux_cpu_to_uarch_index_map = linux_cpu_to_uarch_index_map;
__sync_synchronize();
cpuinfo_is_initialized = true;
processors = NULL;
cores = NULL;
clusters = NULL;
uarchs = NULL;
l1i = l1d = l2 = l3 = NULL;
linux_cpu_to_processor_map = NULL;
linux_cpu_to_core_map = NULL;
linux_cpu_to_uarch_index_map = NULL;
cleanup:
free(arm_linux_processors);
free(processors);
free(cores);
free(clusters);
free(uarchs);
free(l1i);
free(l1d);
free(l2);
free(l3);
free(linux_cpu_to_processor_map);
free(linux_cpu_to_core_map);
free(linux_cpu_to_uarch_index_map);
}
-863
View File
@@ -1,863 +0,0 @@
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <cpuinfo.h>
#include <arm/linux/api.h>
#if defined(__ANDROID__)
#include <arm/android/api.h>
#endif
#include <arm/api.h>
#include <arm/midr.h>
#include <linux/api.h>
#include <cpuinfo/internal-api.h>
#include <cpuinfo/log.h>
#include <cpuinfo/common.h>
#define CLUSTERS_MAX 3
static inline bool bitmask_all(uint32_t bitfield, uint32_t mask) {
return (bitfield & mask) == mask;
}
/* Description of core clusters configuration in a chipset (identified by series and model number) */
struct cluster_config {
/* Number of cores (logical processors) */
uint8_t cores;
/* ARM chipset series (see cpuinfo_arm_chipset_series enum) */
uint8_t series;
/* Chipset model number (see cpuinfo_arm_chipset struct) */
uint16_t model;
/* Number of heterogenous clusters in the CPU package */
uint8_t clusters;
/*
* Number of cores in each cluster:
# - Symmetric configurations: [0] = # cores
* - big.LITTLE configurations: [0] = # LITTLE cores, [1] = # big cores
* - Max.Med.Min configurations: [0] = # Min cores, [1] = # Med cores, [2] = # Max cores
*/
uint8_t cluster_cores[CLUSTERS_MAX];
/*
* MIDR of cores in each cluster:
* - Symmetric configurations: [0] = core MIDR
* - big.LITTLE configurations: [0] = LITTLE core MIDR, [1] = big core MIDR
* - Max.Med.Min configurations: [0] = Min core MIDR, [1] = Med core MIDR, [2] = Max core MIDR
*/
uint32_t cluster_midr[CLUSTERS_MAX];
};
/*
* The list of chipsets where MIDR may not be unambigiously decoded at least on some devices.
* The typical reasons for impossibility to decoded MIDRs are buggy kernels, which either do not report all MIDR
* information (e.g. on ATM7029 kernel doesn't report CPU Part), or chipsets have more than one type of cores
* (i.e. 4x Cortex-A53 + 4x Cortex-A53 is out) and buggy kernels report MIDR information only about some cores
* in /proc/cpuinfo (either only online cores, or only the core that reads /proc/cpuinfo). On these kernels/chipsets,
* it is not possible to detect all core types by just parsing /proc/cpuinfo, so we use chipset name and this table to
* find their MIDR (and thus microarchitecture, cache, etc).
*
* Note: not all chipsets with heterogeneous multiprocessing need an entry in this table. The following HMP
* chipsets always list information about all cores in /proc/cpuinfo:
*
* - Snapdragon 660
* - Snapdragon 820 (MSM8996)
* - Snapdragon 821 (MSM8996PRO)
* - Snapdragon 835 (MSM8998)
* - Exynos 8895
* - Kirin 960
*
* As these are all new processors, there is hope that this table won't uncontrollably grow over time.
*/
static const struct cluster_config cluster_configs[] = {
#if CPUINFO_ARCH_ARM
{
/*
* MSM8916 (Snapdragon 410): 4x Cortex-A53
* Some AArch32 phones use non-standard /proc/cpuinfo format.
*/
.cores = 4,
.series = cpuinfo_arm_chipset_series_qualcomm_msm,
.model = UINT16_C(8916),
.clusters = 1,
.cluster_cores = {
[0] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FD030),
},
},
{
/*
* MSM8939 (Snapdragon 615): 4x Cortex-A53 + 4x Cortex-A53
* Some AArch32 phones use non-standard /proc/cpuinfo format.
*/
.cores = 8,
.series = cpuinfo_arm_chipset_series_qualcomm_msm,
.model = UINT16_C(8939),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FD034),
[1] = UINT32_C(0x410FD034),
},
},
#endif
{
/* MSM8956 (Snapdragon 650): 2x Cortex-A72 + 4x Cortex-A53 */
.cores = 6,
.series = cpuinfo_arm_chipset_series_qualcomm_msm,
.model = UINT16_C(8956),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 2,
},
.cluster_midr = {
[0] = UINT32_C(0x410FD034),
[1] = UINT32_C(0x410FD080),
},
},
{
/* MSM8976/MSM8976PRO (Snapdragon 652/653): 4x Cortex-A72 + 4x Cortex-A53 */
.cores = 8,
.series = cpuinfo_arm_chipset_series_qualcomm_msm,
.model = UINT16_C(8976),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FD034),
[1] = UINT32_C(0x410FD080),
},
},
{
/* MSM8992 (Snapdragon 808): 2x Cortex-A57 + 4x Cortex-A53 */
.cores = 6,
.series = cpuinfo_arm_chipset_series_qualcomm_msm,
.model = UINT16_C(8992),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 2,
},
.cluster_midr = {
[0] = UINT32_C(0x410FD033),
[1] = UINT32_C(0x411FD072),
},
},
{
/* MSM8994/MSM8994V (Snapdragon 810): 4x Cortex-A57 + 4x Cortex-A53 */
.cores = 8,
.series = cpuinfo_arm_chipset_series_qualcomm_msm,
.model = UINT16_C(8994),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FD032),
[1] = UINT32_C(0x411FD071),
},
},
#if CPUINFO_ARCH_ARM
{
/* Exynos 5422: 4x Cortex-A15 + 4x Cortex-A7 */
.cores = 8,
.series = cpuinfo_arm_chipset_series_samsung_exynos,
.model = UINT16_C(5422),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FC073),
[1] = UINT32_C(0x412FC0F3),
},
},
{
/* Exynos 5430: 4x Cortex-A15 + 4x Cortex-A7 */
.cores = 8,
.series = cpuinfo_arm_chipset_series_samsung_exynos,
.model = UINT16_C(5430),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FC074),
[1] = UINT32_C(0x413FC0F3),
},
},
#endif /* CPUINFO_ARCH_ARM */
{
/* Exynos 5433: 4x Cortex-A57 + 4x Cortex-A53 */
.cores = 8,
.series = cpuinfo_arm_chipset_series_samsung_exynos,
.model = UINT16_C(5433),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FD031),
[1] = UINT32_C(0x411FD070),
},
},
{
/* Exynos 7420: 4x Cortex-A57 + 4x Cortex-A53 */
.cores = 8,
.series = cpuinfo_arm_chipset_series_samsung_exynos,
.model = UINT16_C(7420),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FD032),
[1] = UINT32_C(0x411FD070),
},
},
{
/* Exynos 8890: 4x Exynos M1 + 4x Cortex-A53 */
.cores = 8,
.series = cpuinfo_arm_chipset_series_samsung_exynos,
.model = UINT16_C(8890),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FD034),
[1] = UINT32_C(0x531F0011),
},
},
#if CPUINFO_ARCH_ARM
{
/* Kirin 920: 4x Cortex-A15 + 4x Cortex-A7 */
.cores = 8,
.series = cpuinfo_arm_chipset_series_hisilicon_kirin,
.model = UINT16_C(920),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FC075),
[1] = UINT32_C(0x413FC0F3),
},
},
{
/* Kirin 925: 4x Cortex-A15 + 4x Cortex-A7 */
.cores = 8,
.series = cpuinfo_arm_chipset_series_hisilicon_kirin,
.model = UINT16_C(925),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FC075),
[1] = UINT32_C(0x413FC0F3),
},
},
{
/* Kirin 928: 4x Cortex-A15 + 4x Cortex-A7 */
.cores = 8,
.series = cpuinfo_arm_chipset_series_hisilicon_kirin,
.model = UINT16_C(928),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FC075),
[1] = UINT32_C(0x413FC0F3),
},
},
#endif /* CPUINFO_ARCH_ARM */
{
/* Kirin 950: 4x Cortex-A72 + 4x Cortex-A53 */
.cores = 8,
.series = cpuinfo_arm_chipset_series_hisilicon_kirin,
.model = UINT16_C(950),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FD034),
[1] = UINT32_C(0x410FD080),
},
},
{
/* Kirin 955: 4x Cortex-A72 + 4x Cortex-A53 */
.cores = 8,
.series = cpuinfo_arm_chipset_series_hisilicon_kirin,
.model = UINT16_C(955),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FD034),
[1] = UINT32_C(0x410FD080),
},
},
#if CPUINFO_ARCH_ARM
{
/* MediaTek MT8135: 2x Cortex-A7 + 2x Cortex-A15 */
.cores = 4,
.series = cpuinfo_arm_chipset_series_mediatek_mt,
.model = UINT16_C(8135),
.clusters = 2,
.cluster_cores = {
[0] = 2,
[1] = 2,
},
.cluster_midr = {
[0] = UINT32_C(0x410FC073),
[1] = UINT32_C(0x413FC0F2),
},
},
#endif
{
/* MediaTek MT8173: 2x Cortex-A72 + 2x Cortex-A53 */
.cores = 4,
.series = cpuinfo_arm_chipset_series_mediatek_mt,
.model = UINT16_C(8173),
.clusters = 2,
.cluster_cores = {
[0] = 2,
[1] = 2,
},
.cluster_midr = {
[0] = UINT32_C(0x410FD032),
[1] = UINT32_C(0x410FD080),
},
},
{
/* MediaTek MT8176: 2x Cortex-A72 + 4x Cortex-A53 */
.cores = 6,
.series = cpuinfo_arm_chipset_series_mediatek_mt,
.model = UINT16_C(8176),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 2,
},
.cluster_midr = {
[0] = UINT32_C(0x410FD032),
[1] = UINT32_C(0x410FD080),
},
},
#if CPUINFO_ARCH_ARM64
{
/*
* MediaTek MT8735: 4x Cortex-A53
* Some AArch64 phones use non-standard /proc/cpuinfo format.
*/
.cores = 4,
.series = cpuinfo_arm_chipset_series_mediatek_mt,
.model = UINT16_C(8735),
.clusters = 1,
.cluster_cores = {
[0] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FD034),
},
},
#endif
#if CPUINFO_ARCH_ARM
{
/*
* MediaTek MT6592: 4x Cortex-A7 + 4x Cortex-A7
* Some phones use non-standard /proc/cpuinfo format.
*/
.cores = 4,
.series = cpuinfo_arm_chipset_series_mediatek_mt,
.model = UINT16_C(6592),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FC074),
[1] = UINT32_C(0x410FC074),
},
},
{
/* MediaTek MT6595: 4x Cortex-A17 + 4x Cortex-A7 */
.cores = 8,
.series = cpuinfo_arm_chipset_series_mediatek_mt,
.model = UINT16_C(6595),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FC075),
[1] = UINT32_C(0x410FC0E0),
},
},
#endif
{
/* MediaTek MT6797: 2x Cortex-A72 + 4x Cortex-A53 + 4x Cortex-A53 */
.cores = 10,
.series = cpuinfo_arm_chipset_series_mediatek_mt,
.model = UINT16_C(6797),
.clusters = 3,
.cluster_cores = {
[0] = 4,
[1] = 4,
[2] = 2,
},
.cluster_midr = {
[0] = UINT32_C(0x410FD034),
[1] = UINT32_C(0x410FD034),
[2] = UINT32_C(0x410FD081),
},
},
{
/* MediaTek MT6799: 2x Cortex-A73 + 4x Cortex-A53 + 4x Cortex-A35 */
.cores = 10,
.series = cpuinfo_arm_chipset_series_mediatek_mt,
.model = UINT16_C(6799),
.clusters = 3,
.cluster_cores = {
[0] = 4,
[1] = 4,
[2] = 2,
},
.cluster_midr = {
[0] = UINT32_C(0x410FD041),
[1] = UINT32_C(0x410FD034),
[2] = UINT32_C(0x410FD092),
},
},
{
/* Rockchip RK3399: 2x Cortex-A72 + 4x Cortex-A53 */
.cores = 6,
.series = cpuinfo_arm_chipset_series_rockchip_rk,
.model = UINT16_C(3399),
.clusters = 2,
.cluster_cores = {
[0] = 4,
[1] = 2,
},
.cluster_midr = {
[0] = UINT32_C(0x410FD034),
[1] = UINT32_C(0x410FD082),
},
},
#if CPUINFO_ARCH_ARM
{
/* Actions ATM8029: 4x Cortex-A5
* Most devices use non-standard /proc/cpuinfo format.
*/
.cores = 4,
.series = cpuinfo_arm_chipset_series_actions_atm,
.model = UINT16_C(7029),
.clusters = 1,
.cluster_cores = {
[0] = 4,
},
.cluster_midr = {
[0] = UINT32_C(0x410FC051),
},
},
#endif
};
/*
* Searches chipset name in mapping of chipset name to cores' MIDR values. If match is successful, initializes MIDR
* for all clusters' leaders with tabulated values.
*
* @param[in] chipset - chipset (SoC) name information.
* @param clusters_count - number of CPU core clusters detected in the SoC.
* @param cluster_leaders - indices of core clusters' leaders in the @p processors array.
* @param processors_count - number of usable logical processors in the system.
* @param[in,out] processors - array of logical processor descriptions with pre-parsed MIDR, maximum frequency,
* and decoded core cluster (package_leader_id) information.
* Upon successful return, processors[i].midr for all clusters' leaders contains the
* tabulated MIDR values.
* @param verify_midr - indicated whether the function should check that the MIDR values to be assigned to leaders of
* core clusters are consistent with known parts of their parsed values.
* Set if to false if the only MIDR value parsed from /proc/cpuinfo is for the last processor
* reported in /proc/cpuinfo and thus can't be unambiguously attributed to that processor.
*
* @retval true if the chipset was found in the mapping and core clusters' leaders initialized with MIDR values.
* @retval false if the chipset was not found in the mapping, or any consistency check failed.
*/
static bool cpuinfo_arm_linux_detect_cluster_midr_by_chipset(
const struct cpuinfo_arm_chipset chipset[restrict static 1],
uint32_t clusters_count,
const uint32_t cluster_leaders[restrict static CLUSTERS_MAX],
uint32_t processors_count,
struct cpuinfo_arm_linux_processor processors[restrict static processors_count],
bool verify_midr)
{
if (clusters_count <= CLUSTERS_MAX) {
for (uint32_t c = 0; c < CPUINFO_COUNT_OF(cluster_configs); c++) {
if (cluster_configs[c].model == chipset->model && cluster_configs[c].series == chipset->series) {
/* Verify that the total number of cores and clusters of cores matches expectation */
if (cluster_configs[c].cores != processors_count || cluster_configs[c].clusters != clusters_count) {
return false;
}
/* Verify that core cluster configuration matches expectation */
for (uint32_t cluster = 0; cluster < clusters_count; cluster++) {
const uint32_t cluster_leader = cluster_leaders[cluster];
if (cluster_configs[c].cluster_cores[cluster] != processors[cluster_leader].package_processor_count) {
return false;
}
}
if (verify_midr) {
/* Verify known parts of MIDR */
for (uint32_t cluster = 0; cluster < clusters_count; cluster++) {
const uint32_t cluster_leader = cluster_leaders[cluster];
/* Create a mask of known midr bits */
uint32_t midr_mask = 0;
if (processors[cluster_leader].flags & CPUINFO_ARM_LINUX_VALID_IMPLEMENTER) {
midr_mask |= CPUINFO_ARM_MIDR_IMPLEMENTER_MASK;
}
if (processors[cluster_leader].flags & CPUINFO_ARM_LINUX_VALID_VARIANT) {
midr_mask |= CPUINFO_ARM_MIDR_VARIANT_MASK;
}
if (processors[cluster_leader].flags & CPUINFO_ARM_LINUX_VALID_PART) {
midr_mask |= CPUINFO_ARM_MIDR_PART_MASK;
}
if (processors[cluster_leader].flags & CPUINFO_ARM_LINUX_VALID_REVISION) {
midr_mask |= CPUINFO_ARM_MIDR_REVISION_MASK;
}
/* Verify the bits under the mask */
if ((processors[cluster_leader].midr ^ cluster_configs[c].cluster_midr[cluster]) & midr_mask) {
cpuinfo_log_debug("parsed MIDR of cluster %08"PRIu32" does not match tabulated value %08"PRIu32,
processors[cluster_leader].midr, cluster_configs[c].cluster_midr[cluster]);
return false;
}
}
}
/* Assign MIDRs according to tabulated configurations */
for (uint32_t cluster = 0; cluster < clusters_count; cluster++) {
const uint32_t cluster_leader = cluster_leaders[cluster];
processors[cluster_leader].midr = cluster_configs[c].cluster_midr[cluster];
processors[cluster_leader].flags |= CPUINFO_ARM_LINUX_VALID_MIDR;
cpuinfo_log_debug("cluster %"PRIu32" MIDR = 0x%08"PRIx32, cluster, cluster_configs[c].cluster_midr[cluster]);
}
return true;
}
}
}
return false;
}
/*
* Initializes MIDR for leaders of core clusters using a heuristic for big.LITTLE systems:
* - If the only known MIDR is for the big core cluster, guess the matching MIDR for the LITTLE cluster.
* - Estimate which of the clusters is big using maximum frequency, if known, otherwise using system processor ID.
* - Initialize the MIDR for big and LITTLE core clusters using the guesstimates values.
*
* @param clusters_count - number of CPU core clusters detected in the SoC.
* @param cluster_with_midr_count - number of CPU core clusters in the SoC with known MIDR values.
* @param last_processor_with_midr - index of the last logical processor with known MIDR in the @p processors array.
* @param cluster_leaders - indices of core clusters' leaders in the @p processors array.
* @param[in,out] processors - array of logical processor descriptions with pre-parsed MIDR, maximum frequency,
* and decoded core cluster (package_leader_id) information.
* Upon successful return, processors[i].midr for all core clusters' leaders contains
* the heuristically detected MIDR value.
* @param verify_midr - indicated whether the function should check that the MIDR values to be assigned to leaders of
* core clusters are consistent with known parts of their parsed values.
* Set if to false if the only MIDR value parsed from /proc/cpuinfo is for the last processor
* reported in /proc/cpuinfo and thus can't be unambiguously attributed to that processor.
*
* @retval true if this is a big.LITTLE system with only one known MIDR and the CPU core clusters' leaders were
* initialized with MIDR values.
* @retval false if this is not a big.LITTLE system.
*/
static bool cpuinfo_arm_linux_detect_cluster_midr_by_big_little_heuristic(
uint32_t clusters_count,
uint32_t cluster_with_midr_count,
uint32_t last_processor_with_midr,
const uint32_t cluster_leaders[restrict static CLUSTERS_MAX],
struct cpuinfo_arm_linux_processor processors[restrict static last_processor_with_midr],
bool verify_midr)
{
if (clusters_count != 2 || cluster_with_midr_count != 1) {
/* Not a big.LITTLE system, or MIDR is known for both/neither clusters */
return false;
}
const uint32_t midr_flags =
(processors[processors[last_processor_with_midr].package_leader_id].flags & CPUINFO_ARM_LINUX_VALID_MIDR);
const uint32_t big_midr = processors[processors[last_processor_with_midr].package_leader_id].midr;
const uint32_t little_midr = midr_little_core_for_big(big_midr);
/* Default assumption: the first reported cluster is LITTLE cluster (this holds on most Linux kernels) */
uint32_t little_cluster_leader = cluster_leaders[0];
const uint32_t other_cluster_leader = cluster_leaders[1];
/* If maximum frequency is known for both clusters, assume LITTLE cluster is the one with lower frequency */
if (processors[little_cluster_leader].flags & processors[other_cluster_leader].flags & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
if (processors[little_cluster_leader].max_frequency > processors[other_cluster_leader].max_frequency) {
little_cluster_leader = other_cluster_leader;
}
}
if (verify_midr) {
/* Verify known parts of MIDR */
for (uint32_t cluster = 0; cluster < clusters_count; cluster++) {
const uint32_t cluster_leader = cluster_leaders[cluster];
/* Create a mask of known midr bits */
uint32_t midr_mask = 0;
if (processors[cluster_leader].flags & CPUINFO_ARM_LINUX_VALID_IMPLEMENTER) {
midr_mask |= CPUINFO_ARM_MIDR_IMPLEMENTER_MASK;
}
if (processors[cluster_leader].flags & CPUINFO_ARM_LINUX_VALID_VARIANT) {
midr_mask |= CPUINFO_ARM_MIDR_VARIANT_MASK;
}
if (processors[cluster_leader].flags & CPUINFO_ARM_LINUX_VALID_PART) {
midr_mask |= CPUINFO_ARM_MIDR_PART_MASK;
}
if (processors[cluster_leader].flags & CPUINFO_ARM_LINUX_VALID_REVISION) {
midr_mask |= CPUINFO_ARM_MIDR_REVISION_MASK;
}
/* Verify the bits under the mask */
const uint32_t midr = (cluster_leader == little_cluster_leader) ? little_midr : big_midr;
if ((processors[cluster_leader].midr ^ midr) & midr_mask) {
cpuinfo_log_debug(
"parsed MIDR %08"PRIu32" of cluster leader %"PRIu32" is inconsistent with expected value %08"PRIu32,
processors[cluster_leader].midr, cluster_leader, midr);
return false;
}
}
}
for (uint32_t c = 0; c < clusters_count; c++) {
/* Skip cluster with already assigned MIDR */
const uint32_t cluster_leader = cluster_leaders[c];
if (bitmask_all(processors[cluster_leader].flags, CPUINFO_ARM_LINUX_VALID_MIDR)) {
continue;
}
const uint32_t midr = (cluster_leader == little_cluster_leader) ? little_midr : big_midr;
cpuinfo_log_info("assume processor %"PRIu32" to have MIDR %08"PRIx32, cluster_leader, midr);
/* To be consistent, we copy the MIDR entirely, rather than by parts */
processors[cluster_leader].midr = midr;
processors[cluster_leader].flags |= midr_flags;
}
return true;
}
/*
* Initializes MIDR for leaders of core clusters in a single sequential scan:
* - Clusters preceding the first reported MIDR value are assumed to have default MIDR value.
* - Clusters following any reported MIDR value to have that MIDR value.
*
* @param default_midr - MIDR value that will be assigned to cluster leaders preceding any reported MIDR value.
* @param processors_count - number of logical processor descriptions in the @p processors array.
* @param[in,out] processors - array of logical processor descriptions with pre-parsed MIDR, maximum frequency,
* and decoded core cluster (package_leader_id) information.
* Upon successful return, processors[i].midr for all core clusters' leaders contains
* the assigned MIDR value.
*/
static void cpuinfo_arm_linux_detect_cluster_midr_by_sequential_scan(
uint32_t default_midr,
uint32_t processors_count,
struct cpuinfo_arm_linux_processor processors[restrict static processors_count])
{
uint32_t midr = default_midr;
for (uint32_t i = 0; i < processors_count; i++) {
if (bitmask_all(processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
if (processors[i].package_leader_id == i) {
if (bitmask_all(processors[i].flags, CPUINFO_ARM_LINUX_VALID_MIDR)) {
midr = processors[i].midr;
} else {
cpuinfo_log_info("assume processor %"PRIu32" to have MIDR %08"PRIx32, i, midr);
/* To be consistent, we copy the MIDR entirely, rather than by parts */
processors[i].midr = midr;
processors[i].flags |= CPUINFO_ARM_LINUX_VALID_MIDR;
}
}
}
}
}
/*
* Detects MIDR of each CPU core clusters' leader.
*
* @param[in] chipset - chipset (SoC) name information.
* @param max_processors - number of processor descriptions in the @p processors array.
* @param usable_processors - number of processor descriptions in the @p processors array with both POSSIBLE and
* PRESENT flags.
* @param[in,out] processors - array of logical processor descriptions with pre-parsed MIDR, maximum frequency,
* and decoded core cluster (package_leader_id) information.
* Upon return, processors[i].midr for all clusters' leaders contains the MIDR value.
*
* @returns The number of core clusters
*/
uint32_t cpuinfo_arm_linux_detect_cluster_midr(
const struct cpuinfo_arm_chipset chipset[restrict static 1],
uint32_t max_processors,
uint32_t usable_processors,
struct cpuinfo_arm_linux_processor processors[restrict static max_processors])
{
uint32_t clusters_count = 0;
uint32_t cluster_leaders[CLUSTERS_MAX];
uint32_t last_processor_in_cpuinfo = max_processors;
uint32_t last_processor_with_midr = max_processors;
uint32_t processors_with_midr_count = 0;
for (uint32_t i = 0; i < max_processors; i++) {
if (bitmask_all(processors[i].flags, CPUINFO_LINUX_FLAG_VALID)) {
if (processors[i].flags & CPUINFO_ARM_LINUX_VALID_PROCESSOR) {
last_processor_in_cpuinfo = i;
}
if (bitmask_all(processors[i].flags, CPUINFO_ARM_LINUX_VALID_IMPLEMENTER | CPUINFO_ARM_LINUX_VALID_PART)) {
last_processor_with_midr = i;
processors_with_midr_count += 1;
}
const uint32_t group_leader = processors[i].package_leader_id;
if (group_leader == i) {
if (clusters_count < CLUSTERS_MAX) {
cluster_leaders[clusters_count] = i;
}
clusters_count += 1;
} else {
/* Copy known bits of information to cluster leader */
if ((processors[i].flags & ~processors[group_leader].flags) & CPUINFO_LINUX_FLAG_MAX_FREQUENCY) {
processors[group_leader].max_frequency = processors[i].max_frequency;
processors[group_leader].flags |= CPUINFO_LINUX_FLAG_MAX_FREQUENCY;
}
if (!bitmask_all(processors[group_leader].flags, CPUINFO_ARM_LINUX_VALID_MIDR) &&
bitmask_all(processors[i].flags, CPUINFO_ARM_LINUX_VALID_MIDR))
{
processors[group_leader].midr = processors[i].midr;
processors[group_leader].flags |= CPUINFO_ARM_LINUX_VALID_MIDR;
}
}
}
}
cpuinfo_log_debug("detected %"PRIu32" core clusters", clusters_count);
/*
* Two relations between reported /proc/cpuinfo information, and cores is possible:
* - /proc/cpuinfo reports information for all or some of the cores below the corresponding
* "processor : <number>" lines. Information on offline cores may be missing.
* - /proc/cpuinfo reports information only once, after all "processor : <number>" lines.
* The reported information may relate to processor #0 or to the processor which
* executed the system calls to read /proc/cpuinfo. It is also indistinguishable
* from /proc/cpuinfo reporting information only for the last core (e.g. if all other
* cores are offline).
*
* We detect the second case by checking if /proc/cpuinfo contains valid MIDR only for one,
* last reported, processor. Note, that the last reported core may be not the last
* present & possible processor, as /proc/cpuinfo may non-report high-index offline cores.
*/
if (processors_with_midr_count == 1 && last_processor_in_cpuinfo == last_processor_with_midr && clusters_count > 1) {
/*
* There are multiple core clusters, but /proc/cpuinfo reported MIDR only for one
* processor, and we don't even know which logical processor this information refers to.
*
* We make three attempts to detect MIDR for all clusters:
* 1. Search tabulated MIDR values for chipsets which have heterogeneous clusters and ship with Linux
* kernels which do not always report all cores in /proc/cpuinfo. If found, use the tabulated values.
* 2. For systems with 2 clusters and MIDR known for one cluster, assume big.LITTLE configuration,
* and estimate MIDR for the other cluster under assumption that MIDR for the big cluster is known.
* 3. Initialize MIDRs for all core clusters to the only parsed MIDR value.
*/
cpuinfo_log_debug("the only reported MIDR can not be attributed to a particular processor");
if (cpuinfo_arm_linux_detect_cluster_midr_by_chipset(
chipset, clusters_count, cluster_leaders, usable_processors, processors, false))
{
return clusters_count;
}
/* Try big.LITTLE heuristic */
if (cpuinfo_arm_linux_detect_cluster_midr_by_big_little_heuristic(
clusters_count, 1, last_processor_with_midr,
cluster_leaders, processors, false))
{
return clusters_count;
}
/* Fall back to sequential initialization of MIDR values for core clusters */
cpuinfo_arm_linux_detect_cluster_midr_by_sequential_scan(
processors[processors[last_processor_with_midr].package_leader_id].midr,
max_processors, processors);
} else if (processors_with_midr_count < usable_processors) {
/*
* /proc/cpuinfo reported MIDR only for some processors, and probably some core clusters do not have MIDR
* for any of the cores. Check if this is the case.
*/
uint32_t clusters_with_midr_count = 0;
for (uint32_t i = 0; i < max_processors; i++) {
if (bitmask_all(processors[i].flags, CPUINFO_LINUX_FLAG_VALID | CPUINFO_ARM_LINUX_VALID_MIDR)) {
if (processors[i].package_leader_id == i) {
clusters_with_midr_count += 1;
}
}
}
if (clusters_with_midr_count < clusters_count) {
/*
* /proc/cpuinfo reported MIDR only for some clusters, need to reconstruct others.
* We make three attempts to detect MIDR for clusters without it:
* 1. Search tabulated MIDR values for chipsets which have heterogeneous clusters and ship with Linux
* kernels which do not always report all cores in /proc/cpuinfo. If found, use the tabulated values.
* 2. For systems with 2 clusters and MIDR known for one cluster, assume big.LITTLE configuration,
* and estimate MIDR for the other cluster under assumption that MIDR for the big cluster is known.
* 3. Initialize MIDRs for core clusters in a single sequential scan:
* - Clusters preceding the first reported MIDR value are assumed to have the last reported MIDR value.
* - Clusters following any reported MIDR value to have that MIDR value.
*/
if (cpuinfo_arm_linux_detect_cluster_midr_by_chipset(
chipset, clusters_count, cluster_leaders, usable_processors, processors, true))
{
return clusters_count;
}
if (last_processor_with_midr != max_processors) {
/* Try big.LITTLE heuristic */
if (cpuinfo_arm_linux_detect_cluster_midr_by_big_little_heuristic(
clusters_count, processors_with_midr_count, last_processor_with_midr,
cluster_leaders, processors, true))
{
return clusters_count;
}
/* Fall back to sequential initialization of MIDR values for core clusters */
cpuinfo_arm_linux_detect_cluster_midr_by_sequential_scan(
processors[processors[last_processor_with_midr].package_leader_id].midr,
max_processors, processors);
}
}
}
return clusters_count;
}
-636
View File
@@ -1,636 +0,0 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <alloca.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <mach/machine.h>
#include <cpuinfo.h>
#include <mach/api.h>
#include <cpuinfo/internal-api.h>
#include <cpuinfo/log.h>
/* Polyfill recent CPUFAMILY_ARM_* values for older SDKs */
#ifndef CPUFAMILY_ARM_VORTEX_TEMPEST
#define CPUFAMILY_ARM_VORTEX_TEMPEST 0x07D34B9F
#endif
#ifndef CPUFAMILY_ARM_LIGHTNING_THUNDER
#define CPUFAMILY_ARM_LIGHTNING_THUNDER 0x462504D2
#endif
#ifndef CPUFAMILY_ARM_FIRESTORM_ICESTORM
#define CPUFAMILY_ARM_FIRESTORM_ICESTORM 0x1B588BB3
#endif
#ifndef CPUFAMILY_ARM_AVALANCHE_BLIZZARD
#define CPUFAMILY_ARM_AVALANCHE_BLIZZARD 0xDA33D83D
#endif
struct cpuinfo_arm_isa cpuinfo_isa = {
.aes = true,
.sha1 = true,
.sha2 = true,
.pmull = true,
.crc32 = true,
};
static uint32_t get_sys_info(int type_specifier, const char* name) {
size_t size = 0;
uint32_t result = 0;
int mib[2] = { CTL_HW, type_specifier };
if (sysctl(mib, 2, NULL, &size, NULL, 0) != 0) {
cpuinfo_log_info("sysctl(\"%s\") failed: %s", name, strerror(errno));
} else if (size == sizeof(uint32_t)) {
sysctl(mib, 2, &result, &size, NULL, 0);
cpuinfo_log_debug("%s: %"PRIu32 ", size = %lu", name, result, size);
} else {
cpuinfo_log_info("sysctl does not support non-integer lookup for (\"%s\")", name);
}
return result;
}
static uint32_t get_sys_info_by_name(const char* type_specifier) {
size_t size = 0;
uint32_t result = 0;
if (sysctlbyname(type_specifier, NULL, &size, NULL, 0) != 0) {
cpuinfo_log_info("sysctlbyname(\"%s\") failed: %s", type_specifier, strerror(errno));
} else if (size == sizeof(uint32_t)) {
sysctlbyname(type_specifier, &result, &size, NULL, 0);
cpuinfo_log_debug("%s: %"PRIu32 ", size = %lu", type_specifier, result, size);
} else {
cpuinfo_log_info("sysctl does not support non-integer lookup for (\"%s\")", type_specifier);
}
return result;
}
static enum cpuinfo_uarch decode_uarch(uint32_t cpu_family, uint32_t core_index, uint32_t core_count) {
switch (cpu_family) {
case CPUFAMILY_ARM_CYCLONE:
return cpuinfo_uarch_cyclone;
case CPUFAMILY_ARM_TYPHOON:
return cpuinfo_uarch_typhoon;
case CPUFAMILY_ARM_TWISTER:
return cpuinfo_uarch_twister;
case CPUFAMILY_ARM_HURRICANE:
return cpuinfo_uarch_hurricane;
case CPUFAMILY_ARM_MONSOON_MISTRAL:
/* 2x Monsoon + 4x Mistral cores */
return core_index < 2 ? cpuinfo_uarch_monsoon : cpuinfo_uarch_mistral;
case CPUFAMILY_ARM_VORTEX_TEMPEST:
/* Hexa-core: 2x Vortex + 4x Tempest; Octa-core: 4x Cortex + 4x Tempest */
return core_index + 4 < core_count ? cpuinfo_uarch_vortex : cpuinfo_uarch_tempest;
case CPUFAMILY_ARM_LIGHTNING_THUNDER:
/* Hexa-core: 2x Lightning + 4x Thunder; Octa-core (presumed): 4x Lightning + 4x Thunder */
return core_index + 4 < core_count ? cpuinfo_uarch_lightning : cpuinfo_uarch_thunder;
case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
/* Hexa-core: 2x Firestorm + 4x Icestorm; Octa-core: 4x Firestorm + 4x Icestorm */
return core_index + 4 < core_count ? cpuinfo_uarch_firestorm : cpuinfo_uarch_icestorm;
case CPUFAMILY_ARM_AVALANCHE_BLIZZARD:
/* Hexa-core: 2x Avalanche + 4x Blizzard */
return core_index + 4 < core_count ? cpuinfo_uarch_avalanche : cpuinfo_uarch_blizzard;
default:
/* Use hw.cpusubtype for detection */
break;
}
return cpuinfo_uarch_unknown;
}
static void decode_package_name(char* package_name) {
size_t size;
if (sysctlbyname("hw.machine", NULL, &size, NULL, 0) != 0) {
cpuinfo_log_warning("sysctlbyname(\"hw.machine\") failed: %s", strerror(errno));
return;
}
char *machine_name = alloca(size);
if (sysctlbyname("hw.machine", machine_name, &size, NULL, 0) != 0) {
cpuinfo_log_warning("sysctlbyname(\"hw.machine\") failed: %s", strerror(errno));
return;
}
cpuinfo_log_debug("hw.machine: %s", machine_name);
char name[10];
uint32_t major = 0, minor = 0;
if (sscanf(machine_name, "%9[^,0123456789]%"SCNu32",%"SCNu32, name, &major, &minor) != 3) {
cpuinfo_log_warning("parsing \"hw.machine\" failed: %s", strerror(errno));
return;
}
uint32_t chip_model = 0;
char suffix = '\0';
if (strcmp(name, "iPhone") == 0) {
/*
* iPhone 4 and up are supported:
* - iPhone 4 [A4]: iPhone3,1, iPhone3,2, iPhone3,3
* - iPhone 4S [A5]: iPhone4,1
* - iPhone 5 [A6]: iPhone5,1, iPhone5,2
* - iPhone 5c [A6]: iPhone5,3, iPhone5,4
* - iPhone 5s [A7]: iPhone6,1, iPhone6,2
* - iPhone 6 [A8]: iPhone7,2
* - iPhone 6 Plus [A8]: iPhone7,1
* - iPhone 6s [A9]: iPhone8,1
* - iPhone 6s Plus [A9]: iPhone8,2
* - iPhone SE [A9]: iPhone8,4
* - iPhone 7 [A10]: iPhone9,1, iPhone9,3
* - iPhone 7 Plus [A10]: iPhone9,2, iPhone9,4
* - iPhone 8 [A11]: iPhone10,1, iPhone10,4
* - iPhone 8 Plus [A11]: iPhone10,2, iPhone10,5
* - iPhone X [A11]: iPhone10,3, iPhone10,6
* - iPhone XS [A12]: iPhone11,2,
* - iPhone XS Max [A12]: iPhone11,4, iPhone11,6
* - iPhone XR [A12]: iPhone11,8
*/
chip_model = major + 1;
} else if (strcmp(name, "iPad") == 0) {
switch (major) {
/* iPad 2 and up are supported */
case 2:
/*
* iPad 2 [A5]: iPad2,1, iPad2,2, iPad2,3, iPad2,4
* iPad mini [A5]: iPad2,5, iPad2,6, iPad2,7
*/
chip_model = major + 3;
break;
case 3:
/*
* iPad 3rd Gen [A5X]: iPad3,1, iPad3,2, iPad3,3
* iPad 4th Gen [A6X]: iPad3,4, iPad3,5, iPad3,6
*/
chip_model = (minor <= 3) ? 5 : 6;
suffix = 'X';
break;
case 4:
/*
* iPad Air [A7]: iPad4,1, iPad4,2, iPad4,3
* iPad mini Retina [A7]: iPad4,4, iPad4,5, iPad4,6
* iPad mini 3 [A7]: iPad4,7, iPad4,8, iPad4,9
*/
chip_model = major + 3;
break;
case 5:
/*
* iPad mini 4 [A8]: iPad5,1, iPad5,2
* iPad Air 2 [A8X]: iPad5,3, iPad5,4
*/
chip_model = major + 3;
suffix = (minor <= 2) ? '\0' : 'X';
break;
case 6:
/*
* iPad Pro 9.7" [A9X]: iPad6,3, iPad6,4
* iPad Pro [A9X]: iPad6,7, iPad6,8
* iPad 5th Gen [A9]: iPad6,11, iPad6,12
*/
chip_model = major + 3;
suffix = minor <= 8 ? 'X' : '\0';
break;
case 7:
/*
* iPad Pro 12.9" [A10X]: iPad7,1, iPad7,2
* iPad Pro 10.5" [A10X]: iPad7,3, iPad7,4
* iPad 6th Gen [A10]: iPad7,5, iPad7,6
*/
chip_model = major + 3;
suffix = minor <= 4 ? 'X' : '\0';
break;
default:
cpuinfo_log_info("unknown iPad: %s", machine_name);
break;
}
} else if (strcmp(name, "iPod") == 0) {
switch (major) {
case 5:
chip_model = 5;
break;
/* iPod touch (5th Gen) [A5]: iPod5,1 */
case 7:
/* iPod touch (6th Gen, 2015) [A8]: iPod7,1 */
chip_model = 8;
break;
default:
cpuinfo_log_info("unknown iPod: %s", machine_name);
break;
}
} else {
cpuinfo_log_info("unknown device: %s", machine_name);
}
if (chip_model != 0) {
snprintf(package_name, CPUINFO_PACKAGE_NAME_MAX, "Apple A%"PRIu32"%c", chip_model, suffix);
}
}
void cpuinfo_arm_mach_init(void) {
struct cpuinfo_processor* processors = NULL;
struct cpuinfo_core* cores = NULL;
struct cpuinfo_cluster* clusters = NULL;
struct cpuinfo_package* packages = NULL;
struct cpuinfo_uarch_info* uarchs = NULL;
struct cpuinfo_cache* l1i = NULL;
struct cpuinfo_cache* l1d = NULL;
struct cpuinfo_cache* l2 = NULL;
struct cpuinfo_cache* l3 = NULL;
struct cpuinfo_mach_topology mach_topology = cpuinfo_mach_detect_topology();
processors = calloc(mach_topology.threads, sizeof(struct cpuinfo_processor));
if (processors == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" logical processors",
mach_topology.threads * sizeof(struct cpuinfo_processor), mach_topology.threads);
goto cleanup;
}
cores = calloc(mach_topology.cores, sizeof(struct cpuinfo_core));
if (cores == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" cores",
mach_topology.cores * sizeof(struct cpuinfo_core), mach_topology.cores);
goto cleanup;
}
packages = calloc(mach_topology.packages, sizeof(struct cpuinfo_package));
if (packages == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" packages",
mach_topology.packages * sizeof(struct cpuinfo_package), mach_topology.packages);
goto cleanup;
}
const uint32_t threads_per_core = mach_topology.threads / mach_topology.cores;
const uint32_t threads_per_package = mach_topology.threads / mach_topology.packages;
const uint32_t cores_per_package = mach_topology.cores / mach_topology.packages;
for (uint32_t i = 0; i < mach_topology.packages; i++) {
packages[i] = (struct cpuinfo_package) {
.processor_start = i * threads_per_package,
.processor_count = threads_per_package,
.core_start = i * cores_per_package,
.core_count = cores_per_package,
};
decode_package_name(packages[i].name);
}
const uint32_t cpu_family = get_sys_info_by_name("hw.cpufamily");
/*
* iOS 15 and macOS 12 added sysctls for ARM features, use them where possible.
* Otherwise, fallback to hardcoded set of CPUs with known support.
*/
const uint32_t has_feat_lse = get_sys_info_by_name("hw.optional.arm.FEAT_LSE");
if (has_feat_lse != 0) {
cpuinfo_isa.atomics = true;
} else {
// Mandatory in ARMv8.1-A, list only cores released before iOS 15 / macOS 12
switch (cpu_family) {
case CPUFAMILY_ARM_MONSOON_MISTRAL:
case CPUFAMILY_ARM_VORTEX_TEMPEST:
case CPUFAMILY_ARM_LIGHTNING_THUNDER:
case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
cpuinfo_isa.atomics = true;
}
}
const uint32_t has_feat_rdm = get_sys_info_by_name("hw.optional.arm.FEAT_RDM");
if (has_feat_rdm != 0) {
cpuinfo_isa.rdm = true;
} else {
// Optional in ARMv8.2-A (implemented in Apple cores),
// list only cores released before iOS 15 / macOS 12
switch (cpu_family) {
case CPUFAMILY_ARM_MONSOON_MISTRAL:
case CPUFAMILY_ARM_VORTEX_TEMPEST:
case CPUFAMILY_ARM_LIGHTNING_THUNDER:
case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
cpuinfo_isa.rdm = true;
}
}
const uint32_t has_feat_fp16 = get_sys_info_by_name("hw.optional.arm.FEAT_FP16");
if (has_feat_fp16 != 0) {
cpuinfo_isa.fp16arith = true;
} else {
// Optional in ARMv8.2-A (implemented in Apple cores),
// list only cores released before iOS 15 / macOS 12
switch (cpu_family) {
case CPUFAMILY_ARM_MONSOON_MISTRAL:
case CPUFAMILY_ARM_VORTEX_TEMPEST:
case CPUFAMILY_ARM_LIGHTNING_THUNDER:
case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
cpuinfo_isa.fp16arith = true;
}
}
const uint32_t has_feat_fhm = get_sys_info_by_name("hw.optional.arm.FEAT_FHM");
if (has_feat_fhm != 0) {
cpuinfo_isa.fhm = true;
} else {
// Prior to iOS 15, use 'hw.optional.armv8_2_fhm'
const uint32_t has_feat_fhm_legacy = get_sys_info_by_name("hw.optional.armv8_2_fhm");
if (has_feat_fhm_legacy != 0) {
cpuinfo_isa.fhm = true;
} else {
// Mandatory in ARMv8.4-A when FP16 arithmetics is implemented,
// list only cores released before iOS 15 / macOS 12
switch (cpu_family) {
case CPUFAMILY_ARM_LIGHTNING_THUNDER:
case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
cpuinfo_isa.fhm = true;
}
}
}
const uint32_t has_feat_bf16 = get_sys_info_by_name("hw.optional.arm.FEAT_BF16");
if (has_feat_bf16 != 0) {
cpuinfo_isa.bf16 = true;
}
const uint32_t has_feat_fcma = get_sys_info_by_name("hw.optional.arm.FEAT_FCMA");
if (has_feat_fcma != 0) {
cpuinfo_isa.fcma = true;
} else {
// Mandatory in ARMv8.3-A, list only cores released before iOS 15 / macOS 12
switch (cpu_family) {
case CPUFAMILY_ARM_LIGHTNING_THUNDER:
case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
cpuinfo_isa.fcma = true;
}
}
const uint32_t has_feat_jscvt = get_sys_info_by_name("hw.optional.arm.FEAT_JSCVT");
if (has_feat_jscvt != 0) {
cpuinfo_isa.jscvt = true;
} else {
// Mandatory in ARMv8.3-A, list only cores released before iOS 15 / macOS 12
switch (cpu_family) {
case CPUFAMILY_ARM_LIGHTNING_THUNDER:
case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
cpuinfo_isa.jscvt = true;
}
}
const uint32_t has_feat_dotprod = get_sys_info_by_name("hw.optional.arm.FEAT_DotProd");
if (has_feat_dotprod != 0) {
cpuinfo_isa.dot = true;
} else {
// Mandatory in ARMv8.4-A, list only cores released before iOS 15 / macOS 12
switch (cpu_family) {
case CPUFAMILY_ARM_LIGHTNING_THUNDER:
case CPUFAMILY_ARM_FIRESTORM_ICESTORM:
cpuinfo_isa.dot = true;
}
}
const uint32_t has_feat_i8mm = get_sys_info_by_name("hw.optional.arm.FEAT_I8MM");
if (has_feat_i8mm != 0) {
cpuinfo_isa.i8mm = true;
}
uint32_t num_clusters = 1;
for (uint32_t i = 0; i < mach_topology.cores; i++) {
cores[i] = (struct cpuinfo_core) {
.processor_start = i * threads_per_core,
.processor_count = threads_per_core,
.core_id = i % cores_per_package,
.package = packages + i / cores_per_package,
.vendor = cpuinfo_vendor_apple,
.uarch = decode_uarch(cpu_family, i, mach_topology.cores),
};
if (i != 0 && cores[i].uarch != cores[i - 1].uarch) {
num_clusters++;
}
}
for (uint32_t i = 0; i < mach_topology.threads; i++) {
const uint32_t smt_id = i % threads_per_core;
const uint32_t core_id = i / threads_per_core;
const uint32_t package_id = i / threads_per_package;
processors[i].smt_id = smt_id;
processors[i].core = &cores[core_id];
processors[i].package = &packages[package_id];
}
clusters = calloc(num_clusters, sizeof(struct cpuinfo_cluster));
if (clusters == NULL) {
cpuinfo_log_error(
"failed to allocate %zu bytes for descriptions of %"PRIu32" clusters",
num_clusters * sizeof(struct cpuinfo_cluster), num_clusters);
goto cleanup;
}
uarchs = calloc(num_clusters, sizeof(struct cpuinfo_uarch_info));
if (uarchs == NULL) {
cpuinfo_log_error(
"failed to allocate %zu bytes for descriptions of %"PRIu32" uarchs",
num_clusters * sizeof(enum cpuinfo_uarch), num_clusters);
goto cleanup;
}
uint32_t cluster_idx = UINT32_MAX;
for (uint32_t i = 0; i < mach_topology.cores; i++) {
if (i == 0 || cores[i].uarch != cores[i - 1].uarch) {
cluster_idx++;
uarchs[cluster_idx] = (struct cpuinfo_uarch_info) {
.uarch = cores[i].uarch,
.processor_count = 1,
.core_count = 1,
};
clusters[cluster_idx] = (struct cpuinfo_cluster) {
.processor_start = i * threads_per_core,
.processor_count = 1,
.core_start = i,
.core_count = 1,
.cluster_id = cluster_idx,
.package = cores[i].package,
.vendor = cores[i].vendor,
.uarch = cores[i].uarch,
};
} else {
uarchs[cluster_idx].processor_count++;
uarchs[cluster_idx].core_count++;
clusters[cluster_idx].processor_count++;
clusters[cluster_idx].core_count++;
}
cores[i].cluster = &clusters[cluster_idx];
}
for (uint32_t i = 0; i < mach_topology.threads; i++) {
const uint32_t core_id = i / threads_per_core;
processors[i].cluster = cores[core_id].cluster;
}
for (uint32_t i = 0; i < mach_topology.packages; i++) {
packages[i].cluster_start = 0;
packages[i].cluster_count = num_clusters;
}
const uint32_t cacheline_size = get_sys_info(HW_CACHELINE, "HW_CACHELINE");
const uint32_t l1d_cache_size = get_sys_info(HW_L1DCACHESIZE, "HW_L1DCACHESIZE");
const uint32_t l1i_cache_size = get_sys_info(HW_L1ICACHESIZE, "HW_L1ICACHESIZE");
const uint32_t l2_cache_size = get_sys_info(HW_L2CACHESIZE, "HW_L2CACHESIZE");
const uint32_t l3_cache_size = get_sys_info(HW_L3CACHESIZE, "HW_L3CACHESIZE");
const uint32_t l1_cache_associativity = 4;
const uint32_t l2_cache_associativity = 8;
const uint32_t l3_cache_associativity = 16;
const uint32_t cache_partitions = 1;
const uint32_t cache_flags = 0;
uint32_t threads_per_l1 = 0, l1_count = 0;
if (l1i_cache_size != 0 || l1d_cache_size != 0) {
/* Assume L1 caches are private to each core */
threads_per_l1 = 1;
l1_count = mach_topology.threads / threads_per_l1;
cpuinfo_log_debug("detected %"PRIu32" L1 caches", l1_count);
}
uint32_t threads_per_l2 = 0, l2_count = 0;
if (l2_cache_size != 0) {
/* Assume L2 cache is shared between all cores */
threads_per_l2 = mach_topology.cores;
l2_count = 1;
cpuinfo_log_debug("detected %"PRIu32" L2 caches", l2_count);
}
uint32_t threads_per_l3 = 0, l3_count = 0;
if (l3_cache_size != 0) {
/* Assume L3 cache is shared between all cores */
threads_per_l3 = mach_topology.cores;
l3_count = 1;
cpuinfo_log_debug("detected %"PRIu32" L3 caches", l3_count);
}
if (l1i_cache_size != 0) {
l1i = calloc(l1_count, sizeof(struct cpuinfo_cache));
if (l1i == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L1I caches",
l1_count * sizeof(struct cpuinfo_cache), l1_count);
goto cleanup;
}
for (uint32_t c = 0; c < l1_count; c++) {
l1i[c] = (struct cpuinfo_cache) {
.size = l1i_cache_size,
.associativity = l1_cache_associativity,
.sets = l1i_cache_size / (l1_cache_associativity * cacheline_size),
.partitions = cache_partitions,
.line_size = cacheline_size,
.flags = cache_flags,
.processor_start = c * threads_per_l1,
.processor_count = threads_per_l1,
};
}
for (uint32_t t = 0; t < mach_topology.threads; t++) {
processors[t].cache.l1i = &l1i[t / threads_per_l1];
}
}
if (l1d_cache_size != 0) {
l1d = calloc(l1_count, sizeof(struct cpuinfo_cache));
if (l1d == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L1D caches",
l1_count * sizeof(struct cpuinfo_cache), l1_count);
goto cleanup;
}
for (uint32_t c = 0; c < l1_count; c++) {
l1d[c] = (struct cpuinfo_cache) {
.size = l1d_cache_size,
.associativity = l1_cache_associativity,
.sets = l1d_cache_size / (l1_cache_associativity * cacheline_size),
.partitions = cache_partitions,
.line_size = cacheline_size,
.flags = cache_flags,
.processor_start = c * threads_per_l1,
.processor_count = threads_per_l1,
};
}
for (uint32_t t = 0; t < mach_topology.threads; t++) {
processors[t].cache.l1d = &l1d[t / threads_per_l1];
}
}
if (l2_count != 0) {
l2 = calloc(l2_count, sizeof(struct cpuinfo_cache));
if (l2 == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L2 caches",
l2_count * sizeof(struct cpuinfo_cache), l2_count);
goto cleanup;
}
for (uint32_t c = 0; c < l2_count; c++) {
l2[c] = (struct cpuinfo_cache) {
.size = l2_cache_size,
.associativity = l2_cache_associativity,
.sets = l2_cache_size / (l2_cache_associativity * cacheline_size),
.partitions = cache_partitions,
.line_size = cacheline_size,
.flags = cache_flags,
.processor_start = c * threads_per_l2,
.processor_count = threads_per_l2,
};
}
for (uint32_t t = 0; t < mach_topology.threads; t++) {
processors[t].cache.l2 = &l2[0];
}
}
if (l3_count != 0) {
l3 = calloc(l3_count, sizeof(struct cpuinfo_cache));
if (l3 == NULL) {
cpuinfo_log_error("failed to allocate %zu bytes for descriptions of %"PRIu32" L3 caches",
l3_count * sizeof(struct cpuinfo_cache), l3_count);
goto cleanup;
}
for (uint32_t c = 0; c < l3_count; c++) {
l3[c] = (struct cpuinfo_cache) {
.size = l3_cache_size,
.associativity = l3_cache_associativity,
.sets = l3_cache_size / (l3_cache_associativity * cacheline_size),
.partitions = cache_partitions,
.line_size = cacheline_size,
.flags = cache_flags,
.processor_start = c * threads_per_l3,
.processor_count = threads_per_l3,
};
}
for (uint32_t t = 0; t < mach_topology.threads; t++) {
processors[t].cache.l3 = &l3[0];
}
}
/* Commit changes */
cpuinfo_processors = processors;
cpuinfo_cores = cores;
cpuinfo_clusters = clusters;
cpuinfo_packages = packages;
cpuinfo_uarchs = uarchs;
cpuinfo_cache[cpuinfo_cache_level_1i] = l1i;
cpuinfo_cache[cpuinfo_cache_level_1d] = l1d;
cpuinfo_cache[cpuinfo_cache_level_2] = l2;
cpuinfo_cache[cpuinfo_cache_level_3] = l3;
cpuinfo_processors_count = mach_topology.threads;
cpuinfo_cores_count = mach_topology.cores;
cpuinfo_clusters_count = num_clusters;
cpuinfo_packages_count = mach_topology.packages;
cpuinfo_uarchs_count = num_clusters;
cpuinfo_cache_count[cpuinfo_cache_level_1i] = l1_count;
cpuinfo_cache_count[cpuinfo_cache_level_1d] = l1_count;
cpuinfo_cache_count[cpuinfo_cache_level_2] = l2_count;
cpuinfo_cache_count[cpuinfo_cache_level_3] = l3_count;
cpuinfo_max_cache_size = cpuinfo_compute_max_cache_size(&processors[0]);
__sync_synchronize();
cpuinfo_is_initialized = true;
processors = NULL;
cores = NULL;
clusters = NULL;
packages = NULL;
uarchs = NULL;
l1i = l1d = l2 = l3 = NULL;
cleanup:
free(processors);
free(cores);
free(clusters);
free(packages);
free(uarchs);
free(l1i);
free(l1d);
free(l2);
free(l3);
}
-262
View File
@@ -1,262 +0,0 @@
#pragma once
#include <stdint.h>
#define CPUINFO_ARM_MIDR_IMPLEMENTER_MASK UINT32_C(0xFF000000)
#define CPUINFO_ARM_MIDR_VARIANT_MASK UINT32_C(0x00F00000)
#define CPUINFO_ARM_MIDR_ARCHITECTURE_MASK UINT32_C(0x000F0000)
#define CPUINFO_ARM_MIDR_PART_MASK UINT32_C(0x0000FFF0)
#define CPUINFO_ARM_MIDR_REVISION_MASK UINT32_C(0x0000000F)
#define CPUINFO_ARM_MIDR_IMPLEMENTER_OFFSET 24
#define CPUINFO_ARM_MIDR_VARIANT_OFFSET 20
#define CPUINFO_ARM_MIDR_ARCHITECTURE_OFFSET 16
#define CPUINFO_ARM_MIDR_PART_OFFSET 4
#define CPUINFO_ARM_MIDR_REVISION_OFFSET 0
#define CPUINFO_ARM_MIDR_ARM1156 UINT32_C(0x410FB560)
#define CPUINFO_ARM_MIDR_CORTEX_A7 UINT32_C(0x410FC070)
#define CPUINFO_ARM_MIDR_CORTEX_A9 UINT32_C(0x410FC090)
#define CPUINFO_ARM_MIDR_CORTEX_A15 UINT32_C(0x410FC0F0)
#define CPUINFO_ARM_MIDR_CORTEX_A17 UINT32_C(0x410FC0E0)
#define CPUINFO_ARM_MIDR_CORTEX_A35 UINT32_C(0x410FD040)
#define CPUINFO_ARM_MIDR_CORTEX_A53 UINT32_C(0x410FD030)
#define CPUINFO_ARM_MIDR_CORTEX_A55 UINT32_C(0x410FD050)
#define CPUINFO_ARM_MIDR_CORTEX_A57 UINT32_C(0x410FD070)
#define CPUINFO_ARM_MIDR_CORTEX_A72 UINT32_C(0x410FD080)
#define CPUINFO_ARM_MIDR_CORTEX_A73 UINT32_C(0x410FD090)
#define CPUINFO_ARM_MIDR_CORTEX_A75 UINT32_C(0x410FD0A0)
#define CPUINFO_ARM_MIDR_KRYO280_GOLD UINT32_C(0x51AF8001)
#define CPUINFO_ARM_MIDR_KRYO280_SILVER UINT32_C(0x51AF8014)
#define CPUINFO_ARM_MIDR_KRYO385_GOLD UINT32_C(0x518F802D)
#define CPUINFO_ARM_MIDR_KRYO385_SILVER UINT32_C(0x518F803C)
#define CPUINFO_ARM_MIDR_KRYO_SILVER_821 UINT32_C(0x510F2010)
#define CPUINFO_ARM_MIDR_KRYO_GOLD UINT32_C(0x510F2050)
#define CPUINFO_ARM_MIDR_KRYO_SILVER_820 UINT32_C(0x510F2110)
#define CPUINFO_ARM_MIDR_EXYNOS_M1_M2 UINT32_C(0x530F0010)
#define CPUINFO_ARM_MIDR_DENVER2 UINT32_C(0x4E0F0030)
inline static uint32_t midr_set_implementer(uint32_t midr, uint32_t implementer) {
return (midr & ~CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) |
((implementer << CPUINFO_ARM_MIDR_IMPLEMENTER_OFFSET) & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK);
}
inline static uint32_t midr_set_variant(uint32_t midr, uint32_t variant) {
return (midr & ~CPUINFO_ARM_MIDR_VARIANT_MASK) |
((variant << CPUINFO_ARM_MIDR_VARIANT_OFFSET) & CPUINFO_ARM_MIDR_VARIANT_MASK);
}
inline static uint32_t midr_set_architecture(uint32_t midr, uint32_t architecture) {
return (midr & ~CPUINFO_ARM_MIDR_ARCHITECTURE_MASK) |
((architecture << CPUINFO_ARM_MIDR_ARCHITECTURE_OFFSET) & CPUINFO_ARM_MIDR_ARCHITECTURE_MASK);
}
inline static uint32_t midr_set_part(uint32_t midr, uint32_t part) {
return (midr & ~CPUINFO_ARM_MIDR_PART_MASK) |
((part << CPUINFO_ARM_MIDR_PART_OFFSET) & CPUINFO_ARM_MIDR_PART_MASK);
}
inline static uint32_t midr_set_revision(uint32_t midr, uint32_t revision) {
return (midr & ~CPUINFO_ARM_MIDR_REVISION_MASK) |
((revision << CPUINFO_ARM_MIDR_REVISION_OFFSET) & CPUINFO_ARM_MIDR_REVISION_MASK);
}
inline static uint32_t midr_get_variant(uint32_t midr) {
return (midr & CPUINFO_ARM_MIDR_VARIANT_MASK) >> CPUINFO_ARM_MIDR_VARIANT_OFFSET;
}
inline static uint32_t midr_get_implementer(uint32_t midr) {
return (midr & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) >> CPUINFO_ARM_MIDR_IMPLEMENTER_OFFSET;
}
inline static uint32_t midr_get_part(uint32_t midr) {
return (midr & CPUINFO_ARM_MIDR_PART_MASK) >> CPUINFO_ARM_MIDR_PART_OFFSET;
}
inline static uint32_t midr_get_revision(uint32_t midr) {
return (midr & CPUINFO_ARM_MIDR_REVISION_MASK) >> CPUINFO_ARM_MIDR_REVISION_OFFSET;
}
inline static uint32_t midr_copy_implementer(uint32_t midr, uint32_t other_midr) {
return (midr & ~CPUINFO_ARM_MIDR_IMPLEMENTER_MASK) | (other_midr & CPUINFO_ARM_MIDR_IMPLEMENTER_MASK);
}
inline static uint32_t midr_copy_variant(uint32_t midr, uint32_t other_midr) {
return (midr & ~CPUINFO_ARM_MIDR_VARIANT_MASK) | (other_midr & CPUINFO_ARM_MIDR_VARIANT_MASK);
}
inline static uint32_t midr_copy_architecture(uint32_t midr, uint32_t other_midr) {
return (midr & ~CPUINFO_ARM_MIDR_ARCHITECTURE_MASK) | (other_midr & CPUINFO_ARM_MIDR_ARCHITECTURE_MASK);
}
inline static uint32_t midr_copy_part(uint32_t midr, uint32_t other_midr) {
return (midr & ~CPUINFO_ARM_MIDR_PART_MASK) | (other_midr & CPUINFO_ARM_MIDR_PART_MASK);
}
inline static uint32_t midr_copy_revision(uint32_t midr, uint32_t other_midr) {
return (midr & ~CPUINFO_ARM_MIDR_REVISION_MASK) | (other_midr & CPUINFO_ARM_MIDR_REVISION_MASK);
}
inline static bool midr_is_arm1156(uint32_t midr) {
const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_ARM1156 & uarch_mask);
}
inline static bool midr_is_arm11(uint32_t midr) {
return (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | 0x0000F000)) == UINT32_C(0x4100B000);
}
inline static bool midr_is_cortex_a9(uint32_t midr) {
const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_CORTEX_A9 & uarch_mask);
}
inline static bool midr_is_scorpion(uint32_t midr) {
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
case UINT32_C(0x510000F0):
case UINT32_C(0x510002D0):
return true;
default:
return false;
}
}
inline static bool midr_is_krait(uint32_t midr) {
switch (midr & (CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK)) {
case UINT32_C(0x510004D0):
case UINT32_C(0x510006F0):
return true;
default:
return false;
}
}
inline static bool midr_is_cortex_a53(uint32_t midr) {
const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_CORTEX_A53 & uarch_mask);
}
inline static bool midr_is_qualcomm_cortex_a53_silver(uint32_t midr) {
const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_KRYO280_SILVER & uarch_mask);
}
inline static bool midr_is_qualcomm_cortex_a55_silver(uint32_t midr) {
const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_KRYO385_SILVER & uarch_mask);
}
inline static bool midr_is_kryo280_gold(uint32_t midr) {
const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_KRYO280_GOLD & uarch_mask);
}
inline static bool midr_is_kryo_silver(uint32_t midr) {
const uint32_t uarch_mask =
CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_ARCHITECTURE_MASK | CPUINFO_ARM_MIDR_PART_MASK;
switch (midr & uarch_mask) {
case CPUINFO_ARM_MIDR_KRYO_SILVER_820:
case CPUINFO_ARM_MIDR_KRYO_SILVER_821:
return true;
default:
return false;
}
}
inline static bool midr_is_kryo_gold(uint32_t midr) {
const uint32_t uarch_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
return (midr & uarch_mask) == (CPUINFO_ARM_MIDR_KRYO_GOLD & uarch_mask);
}
inline static uint32_t midr_score_core(uint32_t midr) {
const uint32_t core_mask = CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_PART_MASK;
switch (midr & core_mask) {
case UINT32_C(0x53000030): /* Exynos M4 */
case UINT32_C(0x53000040): /* Exynos M5 */
case UINT32_C(0x4100D440): /* Cortex-X1 */
case UINT32_C(0x4100D480): /* Cortex-X2 */
case UINT32_C(0x4100D4E0): /* Cortex-X3 */
/* These cores are in big role w.r.t Cortex-A75/-A76/-A77/-A78/-A710/-A715 */
return 6;
case UINT32_C(0x4100D080): /* Cortex-A72 */
case UINT32_C(0x4100D090): /* Cortex-A73 */
case UINT32_C(0x4100D0A0): /* Cortex-A75 */
case UINT32_C(0x4100D0B0): /* Cortex-A76 */
case UINT32_C(0x4100D0D0): /* Cortex-A77 */
case UINT32_C(0x4100D0E0): /* Cortex-A76AE */
case UINT32_C(0x4100D410): /* Cortex-A78 */
case UINT32_C(0x4100D470): /* Cortex-A710 */
case UINT32_C(0x4100D4D0): /* Cortex-A715 */
case UINT32_C(0x4800D400): /* Cortex-A76 (HiSilicon) */
case UINT32_C(0x4E000030): /* Denver 2 */
case UINT32_C(0x51002050): /* Kryo Gold */
case UINT32_C(0x51008000): /* Kryo 260 / 280 Gold */
case UINT32_C(0x51008020): /* Kryo 385 Gold */
case UINT32_C(0x51008040): /* Kryo 485 Gold / Gold Prime */
case UINT32_C(0x53000010): /* Exynos M1 and Exynos M2 */
case UINT32_C(0x53000020): /* Exynos M3 */
#if CPUINFO_ARCH_ARM
case UINT32_C(0x4100C0F0): /* Cortex-A15 */
case UINT32_C(0x4100C0E0): /* Cortex-A17 */
case UINT32_C(0x4100C0D0): /* Rockchip RK3288 cores */
case UINT32_C(0x4100C0C0): /* Cortex-A12 */
#endif /* CPUINFO_ARCH_ARM */
/* These cores are always in big role */
return 5;
case UINT32_C(0x4100D070): /* Cortex-A57 */
/* Cortex-A57 can be in LITTLE role w.r.t. Denver 2, or in big role w.r.t. Cortex-A53 */
return 4;
#if CPUINFO_ARCH_ARM64
case UINT32_C(0x4100D060): /* Cortex-A65 */
#endif /* CPUINFO_ARCH_ARM64 */
case UINT32_C(0x4100D030): /* Cortex-A53 */
case UINT32_C(0x4100D050): /* Cortex-A55 */
case UINT32_C(0x4100D460): /* Cortex-A510 */
/* Cortex-A53 is usually in LITTLE role, but can be in big role w.r.t. Cortex-A35 */
return 2;
case UINT32_C(0x4100D040): /* Cortex-A35 */
#if CPUINFO_ARCH_ARM
case UINT32_C(0x4100C070): /* Cortex-A7 */
#endif /* CPUINFO_ARCH_ARM */
case UINT32_C(0x51008050): /* Kryo 485 Silver */
case UINT32_C(0x51008030): /* Kryo 385 Silver */
case UINT32_C(0x51008010): /* Kryo 260 / 280 Silver */
case UINT32_C(0x51002110): /* Kryo Silver (Snapdragon 820) */
case UINT32_C(0x51002010): /* Kryo Silver (Snapdragon 821) */
/* These cores are always in LITTLE core */
return 1;
default:
/*
* Unknown cores, or cores which do not have big/LITTLE roles.
* To be future-proof w.r.t. cores not yet recognized in cpuinfo, assume position between
* Cortex-A57/A72/A73/A75 and Cortex-A53/A55. Then at least future cores paired with
* one of these known cores will be properly scored.
*/
return 3;
}
}
inline static uint32_t midr_little_core_for_big(uint32_t midr) {
const uint32_t core_mask =
CPUINFO_ARM_MIDR_IMPLEMENTER_MASK | CPUINFO_ARM_MIDR_ARCHITECTURE_MASK | CPUINFO_ARM_MIDR_PART_MASK;
switch (midr & core_mask) {
case CPUINFO_ARM_MIDR_CORTEX_A75:
return CPUINFO_ARM_MIDR_CORTEX_A55;
case CPUINFO_ARM_MIDR_CORTEX_A73:
case CPUINFO_ARM_MIDR_CORTEX_A72:
case CPUINFO_ARM_MIDR_CORTEX_A57:
case CPUINFO_ARM_MIDR_EXYNOS_M1_M2:
return CPUINFO_ARM_MIDR_CORTEX_A53;
case CPUINFO_ARM_MIDR_CORTEX_A17:
case CPUINFO_ARM_MIDR_CORTEX_A15:
return CPUINFO_ARM_MIDR_CORTEX_A7;
case CPUINFO_ARM_MIDR_KRYO280_GOLD:
return CPUINFO_ARM_MIDR_KRYO280_SILVER;
case CPUINFO_ARM_MIDR_KRYO_GOLD:
return CPUINFO_ARM_MIDR_KRYO_SILVER_820;
case CPUINFO_ARM_MIDR_DENVER2:
return CPUINFO_ARM_MIDR_CORTEX_A57;
default:
return midr;
}
}

Some files were not shown because too many files have changed in this diff Show More