Support kernel-doc comments in assembly language files for functions called by C functions. The comment must include a line containing: * Prototype: asmlinkage ... rest of C prototype... and that function name must match the name used in line like: SYM_FUNC_START(name) or SOMETHING name which is used in a few places in which SYM_FUNC_START is nested. Signed-off-by: Robert Elliott <elliott@xxxxxxx> --- v2 Add documentation for the new kernel-doc Prototype line. Rebased onto 6.1.0. Support new SYM_TYPED_FUNC_START macro. --- Documentation/doc-guide/kernel-doc.rst | 79 ++++++++++++++++++++++++++ scripts/kernel-doc | 49 +++++++++++++++- 2 files changed, 126 insertions(+), 2 deletions(-) diff --git a/Documentation/doc-guide/kernel-doc.rst b/Documentation/doc-guide/kernel-doc.rst index 1dcbd7332476..554694a15586 100644 --- a/Documentation/doc-guide/kernel-doc.rst +++ b/Documentation/doc-guide/kernel-doc.rst @@ -93,6 +93,9 @@ The brief description following the function name may span multiple lines, and ends with an argument description, a blank comment line, or the end of the comment block. +This may also be used to describe a functions in an assembly language file, +provided that a Prototype line is also present (see below). + Function parameters ~~~~~~~~~~~~~~~~~~~ @@ -171,6 +174,82 @@ named ``Return``. as a new section heading, which probably won't produce the desired effect. +Prototypes +~~~~~~~~~~ + +In assembly language files (.S files), functions callable by +C code are defined with:: + + SYM_FUNCTION_START(function_name) + assembly language code ... + +This does not list the arguments like a C function definition; that +information is implicit in the assembly language instructions that follow. + +To document that usage and how the function should be referenced by +C code, include the recommended Prototype like this:: + + /** + * crc_pcl - Calculate CRC32C using x86 CRC32 and PCLMULQDQ instructions + * @buffer: address of data (%rdi, bufp macro) + * @len: data size (%rsi, len macro) + * @crc_init: initial CRC32C value (%rdx, crc_init_arg macro); + * only using lower 32 bits + * + * This function supports 64-bit CPUs. + * It loops on 8-byte aligned QWORDs, but also supports unaligned + * addresses and all length values. + * + * Return: CRC32C value (upper 32 bits zero)(%rax) + * Prototype: asmlinkage unsigned int crc_pcl(const u8 *buffer, + * unsigned int len, + * unsigned int crc_init); + */ + SYM_FUNC_START(crc_pcl) + assembly language code ... + +scripts/kernel-doc ensures that the arguments match those in the +prototype and that the function name matches everywhere. + +Variants of SYM_FUNC_START like SYM_TYPED_FUNC_START and +SYM_FUNC_START_WEAK are also supprted. + +In a few cases, a macro is defined that contains the SYM_FUNC_START() +macro and code. scripts/kernel-doc recognizes that format as well:: + + .macro SHA1_VECTOR_ASM name + SYM_FUNC_START(\name) + assembly language code ... + + /** + * sha1_transform_ssse3 - Calculate SHA1 hash using the x86 SSSE3 feature set + * @digest: address of current 20-byte hash value (%rdi, CTX macro) + * @data: address of data (%rsi, BUF macro); + * data size must be a multiple of 64 bytes + * @blocks: number of 64-byte blocks (%rdx, CNT macro) + * + * This function supports 64-bit CPUs. + * + * Return: none + * Prototype: asmlinkage void sha1_transform_ssse3(u32 *digest, const u8 *data, int blocks) + */ + SHA1_VECTOR_ASM sha1_transform_ssse3 + + /** + * sha1_transform_avx - Calculate SHA1 hash using the x86 AVX feature set + * @digest: address of current 20-byte hash value (%rdi, CTX macro) + * @data: address of data (%rsi, BUF macro); + * data size must be a multiple of 64 bytes + * @blocks: number of 64-byte blocks (%rdx, CNT macro) + * + * This function supports 64-bit CPUs. + * + * Return: none + * Prototype: asmlinkage void sha1_transform_avx(u32 *digest, const u8 *data, int blocks) + */ + SHA1_VECTOR_ASM sha1_transform_avx + + Structure, union, and enumeration documentation ----------------------------------------------- diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 54b0893cae66..e23591d3c78c 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -174,6 +174,7 @@ my %nosymbol_table = (); my $declaration_start_line; my ($type, $declaration_name, $return_type); my ($newsection, $newcontents, $prototype, $brcount, %source_map); +my %asmprototypes; if (defined($ENV{'KBUILD_VERBOSE'})) { $verbose = "$ENV{'KBUILD_VERBOSE'}"; @@ -248,7 +249,7 @@ my $doc_decl = $doc_com . '(\w+)'; # while trying to not match literal block starts like "example::" # my $doc_sect = $doc_com . - '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:([^:].*)?$'; + '\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|prototype|notes?|examples?)\s*:([^:].*)?$'; my $doc_content = $doc_com_body . '(.*)'; my $doc_block = $doc_com . 'DOC:\s*(.*)?'; my $doc_inline_start = '^\s*/\*\*\s*$'; @@ -278,6 +279,7 @@ my $section_intro = "Introduction"; my $section = $section_default; my $section_context = "Context"; my $section_return = "Return"; +my $section_asmprototype = "Prototype"; my $undescribed = "-- undescribed --"; @@ -469,6 +471,13 @@ sub dump_section { $new_start_line = 0; } } + + if ($name eq $section_asmprototype) { + # extract the function name for future matching to SYM.*FUNC_START.*(name) + # since that doesn't include arguments like a C function call + my ($func) = ($contents =~ /^.*\s+(\S+)\(/); + $asmprototypes{$func} = $contents; + } } ## @@ -1865,9 +1874,32 @@ sub syscall_munge() { sub process_proto_function($$) { my $x = shift; my $file = shift; + my $funcname; $x =~ s@\/\/.*$@@gos; # strip C99-style comments to end of line + # support asm functions declared with one of these starting in + # the first column: + # SYM_FUNC_START(name) + # SYM_FUNC_START_LOCAL(name) + # SYM_FUNC_START_WEAK(name) + # SYM_TYPED_FUNC_START(name) + # or for nested macros: + # SOMESTRING<whitespace>name + if ($file =~ /\.S$/) { + if ($x =~ /^SYM.*FUNC_START/) { + ($funcname) = ($x =~ /^SYM.*FUNC_START.*\((.*)\)/); + } elsif ($x =~ /^[A-Za-z0-9_]+\s+[A-Za-z0-9_]+/) { + ($funcname) = ($x =~ /^[A-Za-z0-9_]+\s+([A-Za-z0-9_]+)/); + } + } + if (defined $funcname) { + $prototype = $asmprototypes{$funcname}; + dump_function($asmprototypes{$funcname}, $file); + reset_state(); + return; + } + if ($x =~ m#\s*/\*\s+MACDOC\s*#io || ($x =~ /^#/ && $x !~ /^#\s*define/)) { # do nothing } @@ -2106,6 +2138,8 @@ sub process_body($$) { $newsection = $section_default; } elsif ($newsection =~ m/^context$/i) { $newsection = $section_context; + } elsif ($newsection =~ m/^prototype$/i) { + $newsection = $section_asmprototype; } elsif ($newsection =~ m/^returns?$/i) { $newsection = $section_return; } elsif ($newsection =~ m/^\@return$/) { @@ -2156,6 +2190,16 @@ sub process_body($$) { $contents = ""; $new_start_line = $.; $state = STATE_BODY; + } elsif ($section eq $section_asmprototype) { + my ($protoline) = /Prototype:\s+(.+)$/; + my ($funcname) = $protoline =~ /Prototype\.*\s+(\S+)\(/; + + $asmprototypes{$funcname} = $protoline; + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + $new_start_line = $.; + $state = STATE_BODY; } else { if ($section ne $section_default) { $state = STATE_BODY_WITH_BLANK_LINE; @@ -2171,7 +2215,7 @@ sub process_body($$) { $declaration_purpose =~ s/\s+/ /g; } else { my $cont = $1; - if ($section =~ m/^@/ || $section eq $section_context) { + if ($section =~ m/^@/ || $section eq $section_context || $section eq $section_asmprototype) { if (!defined $leading_space) { if ($cont =~ m/^(\s+)/) { $leading_space = $1; @@ -2307,6 +2351,7 @@ sub process_file($) { } # Replace tabs by spaces while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; + # Hand this line to the appropriate state handler if ($state == STATE_NORMAL) { process_normal(); -- 2.38.1