xref: /openbmc/linux/rust/kernel/print.rs (revision 695c312ec5a68e4373d063ee649c7b925ffb5da7)
1247b365dSWedson Almeida Filho // SPDX-License-Identifier: GPL-2.0
2247b365dSWedson Almeida Filho 
3247b365dSWedson Almeida Filho //! Printing facilities.
4247b365dSWedson Almeida Filho //!
5247b365dSWedson Almeida Filho //! C header: [`include/linux/printk.h`](../../../../include/linux/printk.h)
6247b365dSWedson Almeida Filho //!
7247b365dSWedson Almeida Filho //! Reference: <https://www.kernel.org/doc/html/latest/core-api/printk-basics.html>
8247b365dSWedson Almeida Filho 
9247b365dSWedson Almeida Filho use core::{
10247b365dSWedson Almeida Filho     ffi::{c_char, c_void},
11247b365dSWedson Almeida Filho     fmt,
12247b365dSWedson Almeida Filho };
13247b365dSWedson Almeida Filho 
14247b365dSWedson Almeida Filho use crate::str::RawFormatter;
15247b365dSWedson Almeida Filho 
16247b365dSWedson Almeida Filho #[cfg(CONFIG_PRINTK)]
17247b365dSWedson Almeida Filho use crate::bindings;
18247b365dSWedson Almeida Filho 
19247b365dSWedson Almeida Filho // Called from `vsprintf` with format specifier `%pA`.
20247b365dSWedson Almeida Filho #[no_mangle]
rust_fmt_argument( buf: *mut c_char, end: *mut c_char, ptr: *const c_void, ) -> *mut c_char21c682e4c3SDavid Gow unsafe extern "C" fn rust_fmt_argument(
22c682e4c3SDavid Gow     buf: *mut c_char,
23c682e4c3SDavid Gow     end: *mut c_char,
24c682e4c3SDavid Gow     ptr: *const c_void,
25c682e4c3SDavid Gow ) -> *mut c_char {
26247b365dSWedson Almeida Filho     use fmt::Write;
27247b365dSWedson Almeida Filho     // SAFETY: The C contract guarantees that `buf` is valid if it's less than `end`.
28247b365dSWedson Almeida Filho     let mut w = unsafe { RawFormatter::from_ptrs(buf.cast(), end.cast()) };
29247b365dSWedson Almeida Filho     let _ = w.write_fmt(unsafe { *(ptr as *const fmt::Arguments<'_>) });
30247b365dSWedson Almeida Filho     w.pos().cast()
31247b365dSWedson Almeida Filho }
32247b365dSWedson Almeida Filho 
33247b365dSWedson Almeida Filho /// Format strings.
34247b365dSWedson Almeida Filho ///
35247b365dSWedson Almeida Filho /// Public but hidden since it should only be used from public macros.
36247b365dSWedson Almeida Filho #[doc(hidden)]
37247b365dSWedson Almeida Filho pub mod format_strings {
38247b365dSWedson Almeida Filho     use crate::bindings;
39247b365dSWedson Almeida Filho 
40247b365dSWedson Almeida Filho     /// The length we copy from the `KERN_*` kernel prefixes.
41247b365dSWedson Almeida Filho     const LENGTH_PREFIX: usize = 2;
42247b365dSWedson Almeida Filho 
43247b365dSWedson Almeida Filho     /// The length of the fixed format strings.
44247b365dSWedson Almeida Filho     pub const LENGTH: usize = 10;
45247b365dSWedson Almeida Filho 
46247b365dSWedson Almeida Filho     /// Generates a fixed format string for the kernel's [`_printk`].
47247b365dSWedson Almeida Filho     ///
48247b365dSWedson Almeida Filho     /// The format string is always the same for a given level, i.e. for a
49247b365dSWedson Almeida Filho     /// given `prefix`, which are the kernel's `KERN_*` constants.
50247b365dSWedson Almeida Filho     ///
51247b365dSWedson Almeida Filho     /// [`_printk`]: ../../../../include/linux/printk.h
generate(is_cont: bool, prefix: &[u8; 3]) -> [u8; LENGTH]52247b365dSWedson Almeida Filho     const fn generate(is_cont: bool, prefix: &[u8; 3]) -> [u8; LENGTH] {
53247b365dSWedson Almeida Filho         // Ensure the `KERN_*` macros are what we expect.
54247b365dSWedson Almeida Filho         assert!(prefix[0] == b'\x01');
55247b365dSWedson Almeida Filho         if is_cont {
56247b365dSWedson Almeida Filho             assert!(prefix[1] == b'c');
57247b365dSWedson Almeida Filho         } else {
58247b365dSWedson Almeida Filho             assert!(prefix[1] >= b'0' && prefix[1] <= b'7');
59247b365dSWedson Almeida Filho         }
60247b365dSWedson Almeida Filho         assert!(prefix[2] == b'\x00');
61247b365dSWedson Almeida Filho 
62247b365dSWedson Almeida Filho         let suffix: &[u8; LENGTH - LENGTH_PREFIX] = if is_cont {
63247b365dSWedson Almeida Filho             b"%pA\0\0\0\0\0"
64247b365dSWedson Almeida Filho         } else {
65247b365dSWedson Almeida Filho             b"%s: %pA\0"
66247b365dSWedson Almeida Filho         };
67247b365dSWedson Almeida Filho 
68247b365dSWedson Almeida Filho         [
69247b365dSWedson Almeida Filho             prefix[0], prefix[1], suffix[0], suffix[1], suffix[2], suffix[3], suffix[4], suffix[5],
70247b365dSWedson Almeida Filho             suffix[6], suffix[7],
71247b365dSWedson Almeida Filho         ]
72247b365dSWedson Almeida Filho     }
73247b365dSWedson Almeida Filho 
74247b365dSWedson Almeida Filho     // Generate the format strings at compile-time.
75247b365dSWedson Almeida Filho     //
76247b365dSWedson Almeida Filho     // This avoids the compiler generating the contents on the fly in the stack.
77247b365dSWedson Almeida Filho     //
78247b365dSWedson Almeida Filho     // Furthermore, `static` instead of `const` is used to share the strings
79247b365dSWedson Almeida Filho     // for all the kernel.
80247b365dSWedson Almeida Filho     pub static EMERG: [u8; LENGTH] = generate(false, bindings::KERN_EMERG);
814c7f9499SMiguel Ojeda     pub static ALERT: [u8; LENGTH] = generate(false, bindings::KERN_ALERT);
824c7f9499SMiguel Ojeda     pub static CRIT: [u8; LENGTH] = generate(false, bindings::KERN_CRIT);
834c7f9499SMiguel Ojeda     pub static ERR: [u8; LENGTH] = generate(false, bindings::KERN_ERR);
844c7f9499SMiguel Ojeda     pub static WARNING: [u8; LENGTH] = generate(false, bindings::KERN_WARNING);
854c7f9499SMiguel Ojeda     pub static NOTICE: [u8; LENGTH] = generate(false, bindings::KERN_NOTICE);
86247b365dSWedson Almeida Filho     pub static INFO: [u8; LENGTH] = generate(false, bindings::KERN_INFO);
874c7f9499SMiguel Ojeda     pub static DEBUG: [u8; LENGTH] = generate(false, bindings::KERN_DEBUG);
88fc6c7cacSMiguel Ojeda     pub static CONT: [u8; LENGTH] = generate(true, bindings::KERN_CONT);
89247b365dSWedson Almeida Filho }
90247b365dSWedson Almeida Filho 
91247b365dSWedson Almeida Filho /// Prints a message via the kernel's [`_printk`].
92247b365dSWedson Almeida Filho ///
93247b365dSWedson Almeida Filho /// Public but hidden since it should only be used from public macros.
94247b365dSWedson Almeida Filho ///
95247b365dSWedson Almeida Filho /// # Safety
96247b365dSWedson Almeida Filho ///
97247b365dSWedson Almeida Filho /// The format string must be one of the ones in [`format_strings`], and
98247b365dSWedson Almeida Filho /// the module name must be null-terminated.
99247b365dSWedson Almeida Filho ///
100247b365dSWedson Almeida Filho /// [`_printk`]: ../../../../include/linux/_printk.h
101247b365dSWedson Almeida Filho #[doc(hidden)]
102247b365dSWedson Almeida Filho #[cfg_attr(not(CONFIG_PRINTK), allow(unused_variables))]
call_printk( format_string: &[u8; format_strings::LENGTH], module_name: &[u8], args: fmt::Arguments<'_>, )103247b365dSWedson Almeida Filho pub unsafe fn call_printk(
104247b365dSWedson Almeida Filho     format_string: &[u8; format_strings::LENGTH],
105247b365dSWedson Almeida Filho     module_name: &[u8],
106247b365dSWedson Almeida Filho     args: fmt::Arguments<'_>,
107247b365dSWedson Almeida Filho ) {
108247b365dSWedson Almeida Filho     // `_printk` does not seem to fail in any path.
109247b365dSWedson Almeida Filho     #[cfg(CONFIG_PRINTK)]
110247b365dSWedson Almeida Filho     unsafe {
111247b365dSWedson Almeida Filho         bindings::_printk(
112247b365dSWedson Almeida Filho             format_string.as_ptr() as _,
113247b365dSWedson Almeida Filho             module_name.as_ptr(),
114247b365dSWedson Almeida Filho             &args as *const _ as *const c_void,
115247b365dSWedson Almeida Filho         );
116247b365dSWedson Almeida Filho     }
117247b365dSWedson Almeida Filho }
118247b365dSWedson Almeida Filho 
119fc6c7cacSMiguel Ojeda /// Prints a message via the kernel's [`_printk`] for the `CONT` level.
120fc6c7cacSMiguel Ojeda ///
121fc6c7cacSMiguel Ojeda /// Public but hidden since it should only be used from public macros.
122fc6c7cacSMiguel Ojeda ///
123fc6c7cacSMiguel Ojeda /// [`_printk`]: ../../../../include/linux/printk.h
124fc6c7cacSMiguel Ojeda #[doc(hidden)]
125fc6c7cacSMiguel Ojeda #[cfg_attr(not(CONFIG_PRINTK), allow(unused_variables))]
call_printk_cont(args: fmt::Arguments<'_>)126fc6c7cacSMiguel Ojeda pub fn call_printk_cont(args: fmt::Arguments<'_>) {
127fc6c7cacSMiguel Ojeda     // `_printk` does not seem to fail in any path.
128fc6c7cacSMiguel Ojeda     //
129fc6c7cacSMiguel Ojeda     // SAFETY: The format string is fixed.
130fc6c7cacSMiguel Ojeda     #[cfg(CONFIG_PRINTK)]
131fc6c7cacSMiguel Ojeda     unsafe {
132fc6c7cacSMiguel Ojeda         bindings::_printk(
133fc6c7cacSMiguel Ojeda             format_strings::CONT.as_ptr() as _,
134fc6c7cacSMiguel Ojeda             &args as *const _ as *const c_void,
135fc6c7cacSMiguel Ojeda         );
136fc6c7cacSMiguel Ojeda     }
137fc6c7cacSMiguel Ojeda }
138fc6c7cacSMiguel Ojeda 
139247b365dSWedson Almeida Filho /// Performs formatting and forwards the string to [`call_printk`].
140247b365dSWedson Almeida Filho ///
141247b365dSWedson Almeida Filho /// Public but hidden since it should only be used from public macros.
142247b365dSWedson Almeida Filho #[doc(hidden)]
143247b365dSWedson Almeida Filho #[cfg(not(testlib))]
144247b365dSWedson Almeida Filho #[macro_export]
145247b365dSWedson Almeida Filho #[allow(clippy::crate_in_macro_def)]
146247b365dSWedson Almeida Filho macro_rules! print_macro (
147247b365dSWedson Almeida Filho     // The non-continuation cases (most of them, e.g. `INFO`).
148fc6c7cacSMiguel Ojeda     ($format_string:path, false, $($arg:tt)+) => (
1496618d69aSMiguel Ojeda         // To remain sound, `arg`s must be expanded outside the `unsafe` block.
1506618d69aSMiguel Ojeda         // Typically one would use a `let` binding for that; however, `format_args!`
1516618d69aSMiguel Ojeda         // takes borrows on the arguments, but does not extend the scope of temporaries.
1526618d69aSMiguel Ojeda         // Therefore, a `match` expression is used to keep them around, since
1536618d69aSMiguel Ojeda         // the scrutinee is kept until the end of the `match`.
1546618d69aSMiguel Ojeda         match format_args!($($arg)+) {
155247b365dSWedson Almeida Filho             // SAFETY: This hidden macro should only be called by the documented
156247b365dSWedson Almeida Filho             // printing macros which ensure the format string is one of the fixed
157247b365dSWedson Almeida Filho             // ones. All `__LOG_PREFIX`s are null-terminated as they are generated
158247b365dSWedson Almeida Filho             // by the `module!` proc macro or fixed values defined in a kernel
159247b365dSWedson Almeida Filho             // crate.
1606618d69aSMiguel Ojeda             args => unsafe {
161247b365dSWedson Almeida Filho                 $crate::print::call_printk(
162247b365dSWedson Almeida Filho                     &$format_string,
163247b365dSWedson Almeida Filho                     crate::__LOG_PREFIX,
1646618d69aSMiguel Ojeda                     args,
165247b365dSWedson Almeida Filho                 );
166247b365dSWedson Almeida Filho             }
1676618d69aSMiguel Ojeda         }
168247b365dSWedson Almeida Filho     );
169fc6c7cacSMiguel Ojeda 
170fc6c7cacSMiguel Ojeda     // The `CONT` case.
171fc6c7cacSMiguel Ojeda     ($format_string:path, true, $($arg:tt)+) => (
172fc6c7cacSMiguel Ojeda         $crate::print::call_printk_cont(
173fc6c7cacSMiguel Ojeda             format_args!($($arg)+),
174fc6c7cacSMiguel Ojeda         );
175fc6c7cacSMiguel Ojeda     );
176247b365dSWedson Almeida Filho );
177247b365dSWedson Almeida Filho 
178247b365dSWedson Almeida Filho /// Stub for doctests
179247b365dSWedson Almeida Filho #[cfg(testlib)]
180247b365dSWedson Almeida Filho #[macro_export]
181247b365dSWedson Almeida Filho macro_rules! print_macro (
182247b365dSWedson Almeida Filho     ($format_string:path, $e:expr, $($arg:tt)+) => (
183247b365dSWedson Almeida Filho         ()
184247b365dSWedson Almeida Filho     );
185247b365dSWedson Almeida Filho );
186247b365dSWedson Almeida Filho 
187247b365dSWedson Almeida Filho // We could use a macro to generate these macros. However, doing so ends
188247b365dSWedson Almeida Filho // up being a bit ugly: it requires the dollar token trick to escape `$` as
189247b365dSWedson Almeida Filho // well as playing with the `doc` attribute. Furthermore, they cannot be easily
190247b365dSWedson Almeida Filho // imported in the prelude due to [1]. So, for the moment, we just write them
191247b365dSWedson Almeida Filho // manually, like in the C side; while keeping most of the logic in another
192247b365dSWedson Almeida Filho // macro, i.e. [`print_macro`].
193247b365dSWedson Almeida Filho //
194247b365dSWedson Almeida Filho // [1]: https://github.com/rust-lang/rust/issues/52234
195247b365dSWedson Almeida Filho 
196247b365dSWedson Almeida Filho /// Prints an emergency-level message (level 0).
197247b365dSWedson Almeida Filho ///
198247b365dSWedson Almeida Filho /// Use this level if the system is unusable.
199247b365dSWedson Almeida Filho ///
200247b365dSWedson Almeida Filho /// Equivalent to the kernel's [`pr_emerg`] macro.
201247b365dSWedson Almeida Filho ///
202247b365dSWedson Almeida Filho /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and
203247b365dSWedson Almeida Filho /// `alloc::format!` for information about the formatting syntax.
204247b365dSWedson Almeida Filho ///
205247b365dSWedson Almeida Filho /// [`pr_emerg`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_emerg
206247b365dSWedson Almeida Filho /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
207247b365dSWedson Almeida Filho ///
208247b365dSWedson Almeida Filho /// # Examples
209247b365dSWedson Almeida Filho ///
210247b365dSWedson Almeida Filho /// ```
211247b365dSWedson Almeida Filho /// pr_emerg!("hello {}\n", "there");
212247b365dSWedson Almeida Filho /// ```
213247b365dSWedson Almeida Filho #[macro_export]
214247b365dSWedson Almeida Filho macro_rules! pr_emerg (
215247b365dSWedson Almeida Filho     ($($arg:tt)*) => (
216fc6c7cacSMiguel Ojeda         $crate::print_macro!($crate::print::format_strings::EMERG, false, $($arg)*)
217247b365dSWedson Almeida Filho     )
218247b365dSWedson Almeida Filho );
219247b365dSWedson Almeida Filho 
2204c7f9499SMiguel Ojeda /// Prints an alert-level message (level 1).
2214c7f9499SMiguel Ojeda ///
2224c7f9499SMiguel Ojeda /// Use this level if action must be taken immediately.
2234c7f9499SMiguel Ojeda ///
2244c7f9499SMiguel Ojeda /// Equivalent to the kernel's [`pr_alert`] macro.
2254c7f9499SMiguel Ojeda ///
2264c7f9499SMiguel Ojeda /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and
2274c7f9499SMiguel Ojeda /// `alloc::format!` for information about the formatting syntax.
2284c7f9499SMiguel Ojeda ///
2294c7f9499SMiguel Ojeda /// [`pr_alert`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_alert
2304c7f9499SMiguel Ojeda /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
2314c7f9499SMiguel Ojeda ///
2324c7f9499SMiguel Ojeda /// # Examples
2334c7f9499SMiguel Ojeda ///
2344c7f9499SMiguel Ojeda /// ```
2354c7f9499SMiguel Ojeda /// pr_alert!("hello {}\n", "there");
2364c7f9499SMiguel Ojeda /// ```
2374c7f9499SMiguel Ojeda #[macro_export]
2384c7f9499SMiguel Ojeda macro_rules! pr_alert (
2394c7f9499SMiguel Ojeda     ($($arg:tt)*) => (
240fc6c7cacSMiguel Ojeda         $crate::print_macro!($crate::print::format_strings::ALERT, false, $($arg)*)
2414c7f9499SMiguel Ojeda     )
2424c7f9499SMiguel Ojeda );
2434c7f9499SMiguel Ojeda 
2444c7f9499SMiguel Ojeda /// Prints a critical-level message (level 2).
2454c7f9499SMiguel Ojeda ///
2464c7f9499SMiguel Ojeda /// Use this level for critical conditions.
2474c7f9499SMiguel Ojeda ///
2484c7f9499SMiguel Ojeda /// Equivalent to the kernel's [`pr_crit`] macro.
2494c7f9499SMiguel Ojeda ///
2504c7f9499SMiguel Ojeda /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and
2514c7f9499SMiguel Ojeda /// `alloc::format!` for information about the formatting syntax.
2524c7f9499SMiguel Ojeda ///
2534c7f9499SMiguel Ojeda /// [`pr_crit`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_crit
2544c7f9499SMiguel Ojeda /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
2554c7f9499SMiguel Ojeda ///
2564c7f9499SMiguel Ojeda /// # Examples
2574c7f9499SMiguel Ojeda ///
2584c7f9499SMiguel Ojeda /// ```
2594c7f9499SMiguel Ojeda /// pr_crit!("hello {}\n", "there");
2604c7f9499SMiguel Ojeda /// ```
2614c7f9499SMiguel Ojeda #[macro_export]
2624c7f9499SMiguel Ojeda macro_rules! pr_crit (
2634c7f9499SMiguel Ojeda     ($($arg:tt)*) => (
264fc6c7cacSMiguel Ojeda         $crate::print_macro!($crate::print::format_strings::CRIT, false, $($arg)*)
2654c7f9499SMiguel Ojeda     )
2664c7f9499SMiguel Ojeda );
2674c7f9499SMiguel Ojeda 
2684c7f9499SMiguel Ojeda /// Prints an error-level message (level 3).
2694c7f9499SMiguel Ojeda ///
2704c7f9499SMiguel Ojeda /// Use this level for error conditions.
2714c7f9499SMiguel Ojeda ///
2724c7f9499SMiguel Ojeda /// Equivalent to the kernel's [`pr_err`] macro.
2734c7f9499SMiguel Ojeda ///
2744c7f9499SMiguel Ojeda /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and
2754c7f9499SMiguel Ojeda /// `alloc::format!` for information about the formatting syntax.
2764c7f9499SMiguel Ojeda ///
2774c7f9499SMiguel Ojeda /// [`pr_err`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_err
2784c7f9499SMiguel Ojeda /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
2794c7f9499SMiguel Ojeda ///
2804c7f9499SMiguel Ojeda /// # Examples
2814c7f9499SMiguel Ojeda ///
2824c7f9499SMiguel Ojeda /// ```
2834c7f9499SMiguel Ojeda /// pr_err!("hello {}\n", "there");
2844c7f9499SMiguel Ojeda /// ```
2854c7f9499SMiguel Ojeda #[macro_export]
2864c7f9499SMiguel Ojeda macro_rules! pr_err (
2874c7f9499SMiguel Ojeda     ($($arg:tt)*) => (
288fc6c7cacSMiguel Ojeda         $crate::print_macro!($crate::print::format_strings::ERR, false, $($arg)*)
2894c7f9499SMiguel Ojeda     )
2904c7f9499SMiguel Ojeda );
2914c7f9499SMiguel Ojeda 
2924c7f9499SMiguel Ojeda /// Prints a warning-level message (level 4).
2934c7f9499SMiguel Ojeda ///
2944c7f9499SMiguel Ojeda /// Use this level for warning conditions.
2954c7f9499SMiguel Ojeda ///
2964c7f9499SMiguel Ojeda /// Equivalent to the kernel's [`pr_warn`] macro.
2974c7f9499SMiguel Ojeda ///
2984c7f9499SMiguel Ojeda /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and
2994c7f9499SMiguel Ojeda /// `alloc::format!` for information about the formatting syntax.
3004c7f9499SMiguel Ojeda ///
3014c7f9499SMiguel Ojeda /// [`pr_warn`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_warn
3024c7f9499SMiguel Ojeda /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
3034c7f9499SMiguel Ojeda ///
3044c7f9499SMiguel Ojeda /// # Examples
3054c7f9499SMiguel Ojeda ///
3064c7f9499SMiguel Ojeda /// ```
3074c7f9499SMiguel Ojeda /// pr_warn!("hello {}\n", "there");
3084c7f9499SMiguel Ojeda /// ```
3094c7f9499SMiguel Ojeda #[macro_export]
3104c7f9499SMiguel Ojeda macro_rules! pr_warn (
3114c7f9499SMiguel Ojeda     ($($arg:tt)*) => (
312fc6c7cacSMiguel Ojeda         $crate::print_macro!($crate::print::format_strings::WARNING, false, $($arg)*)
3134c7f9499SMiguel Ojeda     )
3144c7f9499SMiguel Ojeda );
3154c7f9499SMiguel Ojeda 
3164c7f9499SMiguel Ojeda /// Prints a notice-level message (level 5).
3174c7f9499SMiguel Ojeda ///
3184c7f9499SMiguel Ojeda /// Use this level for normal but significant conditions.
3194c7f9499SMiguel Ojeda ///
3204c7f9499SMiguel Ojeda /// Equivalent to the kernel's [`pr_notice`] macro.
3214c7f9499SMiguel Ojeda ///
3224c7f9499SMiguel Ojeda /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and
3234c7f9499SMiguel Ojeda /// `alloc::format!` for information about the formatting syntax.
3244c7f9499SMiguel Ojeda ///
3254c7f9499SMiguel Ojeda /// [`pr_notice`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_notice
3264c7f9499SMiguel Ojeda /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
3274c7f9499SMiguel Ojeda ///
3284c7f9499SMiguel Ojeda /// # Examples
3294c7f9499SMiguel Ojeda ///
3304c7f9499SMiguel Ojeda /// ```
3314c7f9499SMiguel Ojeda /// pr_notice!("hello {}\n", "there");
3324c7f9499SMiguel Ojeda /// ```
3334c7f9499SMiguel Ojeda #[macro_export]
3344c7f9499SMiguel Ojeda macro_rules! pr_notice (
3354c7f9499SMiguel Ojeda     ($($arg:tt)*) => (
336fc6c7cacSMiguel Ojeda         $crate::print_macro!($crate::print::format_strings::NOTICE, false, $($arg)*)
3374c7f9499SMiguel Ojeda     )
3384c7f9499SMiguel Ojeda );
3394c7f9499SMiguel Ojeda 
340247b365dSWedson Almeida Filho /// Prints an info-level message (level 6).
341247b365dSWedson Almeida Filho ///
342247b365dSWedson Almeida Filho /// Use this level for informational messages.
343247b365dSWedson Almeida Filho ///
344247b365dSWedson Almeida Filho /// Equivalent to the kernel's [`pr_info`] macro.
345247b365dSWedson Almeida Filho ///
346247b365dSWedson Almeida Filho /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and
347247b365dSWedson Almeida Filho /// `alloc::format!` for information about the formatting syntax.
348247b365dSWedson Almeida Filho ///
349247b365dSWedson Almeida Filho /// [`pr_info`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_info
350247b365dSWedson Almeida Filho /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
351247b365dSWedson Almeida Filho ///
352247b365dSWedson Almeida Filho /// # Examples
353247b365dSWedson Almeida Filho ///
354247b365dSWedson Almeida Filho /// ```
355247b365dSWedson Almeida Filho /// pr_info!("hello {}\n", "there");
356247b365dSWedson Almeida Filho /// ```
357247b365dSWedson Almeida Filho #[macro_export]
358247b365dSWedson Almeida Filho #[doc(alias = "print")]
359247b365dSWedson Almeida Filho macro_rules! pr_info (
360247b365dSWedson Almeida Filho     ($($arg:tt)*) => (
361fc6c7cacSMiguel Ojeda         $crate::print_macro!($crate::print::format_strings::INFO, false, $($arg)*)
362247b365dSWedson Almeida Filho     )
363247b365dSWedson Almeida Filho );
3644c7f9499SMiguel Ojeda 
3654c7f9499SMiguel Ojeda /// Prints a debug-level message (level 7).
3664c7f9499SMiguel Ojeda ///
3674c7f9499SMiguel Ojeda /// Use this level for debug messages.
3684c7f9499SMiguel Ojeda ///
3694c7f9499SMiguel Ojeda /// Equivalent to the kernel's [`pr_debug`] macro, except that it doesn't support dynamic debug
3704c7f9499SMiguel Ojeda /// yet.
3714c7f9499SMiguel Ojeda ///
3724c7f9499SMiguel Ojeda /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and
3734c7f9499SMiguel Ojeda /// `alloc::format!` for information about the formatting syntax.
3744c7f9499SMiguel Ojeda ///
3754c7f9499SMiguel Ojeda /// [`pr_debug`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_debug
3764c7f9499SMiguel Ojeda /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
3774c7f9499SMiguel Ojeda ///
3784c7f9499SMiguel Ojeda /// # Examples
3794c7f9499SMiguel Ojeda ///
3804c7f9499SMiguel Ojeda /// ```
3814c7f9499SMiguel Ojeda /// pr_debug!("hello {}\n", "there");
3824c7f9499SMiguel Ojeda /// ```
3834c7f9499SMiguel Ojeda #[macro_export]
3844c7f9499SMiguel Ojeda #[doc(alias = "print")]
3854c7f9499SMiguel Ojeda macro_rules! pr_debug (
3864c7f9499SMiguel Ojeda     ($($arg:tt)*) => (
3874c7f9499SMiguel Ojeda         if cfg!(debug_assertions) {
388fc6c7cacSMiguel Ojeda             $crate::print_macro!($crate::print::format_strings::DEBUG, false, $($arg)*)
3894c7f9499SMiguel Ojeda         }
3904c7f9499SMiguel Ojeda     )
3914c7f9499SMiguel Ojeda );
392fc6c7cacSMiguel Ojeda 
393fc6c7cacSMiguel Ojeda /// Continues a previous log message in the same line.
394fc6c7cacSMiguel Ojeda ///
395fc6c7cacSMiguel Ojeda /// Use only when continuing a previous `pr_*!` macro (e.g. [`pr_info!`]).
396fc6c7cacSMiguel Ojeda ///
397fc6c7cacSMiguel Ojeda /// Equivalent to the kernel's [`pr_cont`] macro.
398fc6c7cacSMiguel Ojeda ///
399fc6c7cacSMiguel Ojeda /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and
400fc6c7cacSMiguel Ojeda /// `alloc::format!` for information about the formatting syntax.
401fc6c7cacSMiguel Ojeda ///
402*aacae446SMiguel Ojeda /// [`pr_info!`]: crate::pr_info!
403fc6c7cacSMiguel Ojeda /// [`pr_cont`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_cont
404fc6c7cacSMiguel Ojeda /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
405fc6c7cacSMiguel Ojeda ///
406fc6c7cacSMiguel Ojeda /// # Examples
407fc6c7cacSMiguel Ojeda ///
408fc6c7cacSMiguel Ojeda /// ```
409fc6c7cacSMiguel Ojeda /// # use kernel::pr_cont;
410fc6c7cacSMiguel Ojeda /// pr_info!("hello");
411fc6c7cacSMiguel Ojeda /// pr_cont!(" {}\n", "there");
412fc6c7cacSMiguel Ojeda /// ```
413fc6c7cacSMiguel Ojeda #[macro_export]
414fc6c7cacSMiguel Ojeda macro_rules! pr_cont (
415fc6c7cacSMiguel Ojeda     ($($arg:tt)*) => (
416fc6c7cacSMiguel Ojeda         $crate::print_macro!($crate::print::format_strings::CONT, true, $($arg)*)
417fc6c7cacSMiguel Ojeda     )
418fc6c7cacSMiguel Ojeda );
419