-
Notifications
You must be signed in to change notification settings - Fork 15.5k
[libc] Add baremetal printf #94078
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
michaelrj-google
merged 3 commits into
llvm:main
from
michaelrj-google:libcBaremetalPrintf
Jun 7, 2024
Merged
[libc] Add baremetal printf #94078
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| //===-- Implementation of printf for baremetal ------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "src/stdio/printf.h" | ||
| #include "src/__support/arg_list.h" | ||
| #include "src/stdio/printf_core/core_structs.h" | ||
| #include "src/stdio/printf_core/printf_main.h" | ||
| #include "src/stdio/printf_core/writer.h" | ||
|
|
||
| #include <stdarg.h> | ||
|
|
||
| // TODO(https://github.com/llvm/llvm-project/issues/94685) unify baremetal hooks | ||
|
|
||
| // This is intended to be provided by the vendor. | ||
| extern "C" size_t __llvm_libc_raw_write(const char *s, size_t size); | ||
|
|
||
| namespace LIBC_NAMESPACE { | ||
|
|
||
| namespace { | ||
|
|
||
| LIBC_INLINE int raw_write_hook(cpp::string_view new_str, void *) { | ||
michaelrj-google marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| size_t written = __llvm_libc_raw_write(new_str.data(), new_str.size()); | ||
| if (written != new_str.size()) | ||
| return printf_core::FILE_WRITE_ERROR; | ||
| return printf_core::WRITE_OK; | ||
| } | ||
|
|
||
| } // namespace | ||
|
|
||
| LLVM_LIBC_FUNCTION(int, printf, (const char *__restrict format, ...)) { | ||
| va_list vlist; | ||
| va_start(vlist, format); | ||
| internal::ArgList args(vlist); // This holder class allows for easier copying | ||
| // and pointer semantics, as well as handling | ||
| // destruction automatically. | ||
| va_end(vlist); | ||
| constexpr size_t BUFF_SIZE = 1024; | ||
| char buffer[BUFF_SIZE]; | ||
|
|
||
| printf_core::WriteBuffer wb(buffer, BUFF_SIZE, &raw_write_hook, nullptr); | ||
| printf_core::Writer writer(&wb); | ||
|
|
||
| int retval = printf_core::printf_main(&writer, format, args); | ||
|
|
||
| int flushval = wb.overflow_write(""); | ||
| if (flushval != printf_core::WRITE_OK) | ||
| retval = flushval; | ||
|
|
||
| return retval; | ||
| } | ||
|
|
||
| } // namespace LIBC_NAMESPACE | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is this different from the
write_to_stderrhook we already use? I guess the size is different. For the GPU I useFILEas a simple opaque handle basically, don't know if that's relevant here.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd say
raw_writeandwrite_to_stderrare (in my mind) different in the same waystdoutandstderrare. The intent forstdoutis for normal output, whereas the intent forstderris error messages. That being said, I should probably move this toOSUtilso that it's in the same place aswrite_to_stderr.As for using
FILEas an opaque handle, that probably would work, but the request from @petrhosek was for a printf that only writes to the provided function.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
write_to_stderris a private C++ API, for vendor integration we need an internal C API. So far we only have__llvm_libc_log_writedefined in baremetalOSUtil, and this change introduces__llvm_libc_raw_write. It's a question whether this API should be specific only to baremetal target or should be made more generic, but I'm fine starting with just baremetal and generalizing it as needed. It'd be also helpful to define all internal API in a single header that's extensively documented. There are also open questions around naming, versioning, prior art, etc. This is a broader topic that we should probably discuss on Discourse, but I'm fine landing this change in the meantime and refining the API later.Regarding opaque
FILE, for baremetal I think we'll need both. Most baremetal targets have some support for writing out characters, typically over serial. This would typically be used to implementprintf(or similar API for logging). Many baremetal targets also support semihosting which allows file system access and I'd like to implementFILEfor baremetal through semihosting. We could also use semihosting to implementprintf(usingSYS_WRITEsyscall) but that has a downside of requiring a debugger and so I don't think it should be the default implementation.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
having thought about it some more, I think the best solution might be to add a
write_to_stdoutthat can be used by not justprintfbut alsoputsandputcharin future. I'll update this PR with what I currently have and then try making a version with this new design so that we can compare.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I messed around with the design a bit and realized it's out of scope for this patch. I've filed an issue to track this further (#94685), but for now I'm going to land this patch as-is.