From 54bdb3419da2a81b881fe0ce7cdcab7514fc2cad Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Wed, 4 Oct 2017 11:48:39 +0900 Subject: [PATCH] hfi1 generated headers: - split headers into one file per struct - add filedata - fix s/modprobe/modinfo/ for guessed .ko path --- kernel/include/hfi1/hfi.h | 77 +++---- kernel/include/hfi1/hfi1_generated_ctxtdata.h | 41 ++++ ...ted_structs.h => hfi1_generated_devdata.h} | 49 +---- .../include/hfi1/hfi1_generated_pportdata.h | 9 + kernel/script/dwarf-extract-struct.c | 200 ++++++++++-------- kernel/script/regenerate_hfi1_header.sh | 18 +- 6 files changed, 202 insertions(+), 192 deletions(-) create mode 100644 kernel/include/hfi1/hfi1_generated_ctxtdata.h rename kernel/include/hfi1/{hfi1_generated_structs.h => hfi1_generated_devdata.h} (52%) create mode 100644 kernel/include/hfi1/hfi1_generated_pportdata.h diff --git a/kernel/include/hfi1/hfi.h b/kernel/include/hfi1/hfi.h index b7c4ab6b..a29fc7d5 100644 --- a/kernel/include/hfi1/hfi.h +++ b/kernel/include/hfi1/hfi.h @@ -137,6 +137,12 @@ struct exp_tid_set { u32 count; }; +#ifndef __HFI1_ORIG__ + +#include + +#endif /* !__HFI1_ORIG__ */ + /* * Get/Set IB link-level config parameters for f_get/set_ib_cfg() * Mostly for MADs that set or query link parameters, also ipath @@ -277,6 +283,12 @@ static inline void incr_cntr32(u32 *cntr) #define MAX_NAME_SIZE 64 +#ifndef __HFI1_ORIG__ + +#include + +#endif /* __HFI1_ORIG__ */ + struct rcv_array_data { u8 group_size; u16 ngroups; @@ -291,6 +303,8 @@ struct rcv_array_data { #define BOARD_VERS_MAX 96 /* how long the version string can be */ #define SERIAL_MAX 16 /* length of the serial number */ +#include + #endif /* !__HFI1_ORIG__ */ /* 8051 firmware version helper */ @@ -310,29 +324,7 @@ struct mmu_rb_handler; struct tid_rb_node; -/* Original size on linux is 96 bytes */ -/* Private data for file operations */ - -struct hfi1_filedata { - struct hfi1_devdata *dd; - struct hfi1_ctxtdata *uctxt; - struct hfi1_user_sdma_comp_q *cq; - struct hfi1_user_sdma_pkt_q *pq; - u16 subctxt; - /* for cpu affinity; -1 if none */ - int rec_cpu_num; - u32 tid_n_pinned; - void *handler; //struct mmu_rb_handler *handler; - struct tid_rb_node **entry_to_rb; - spinlock_t tid_lock; /* protect tid_[limit,used] counters */ - u32 tid_limit; - u32 tid_used; - u32 *invalid_tids; - u32 invalid_tid_idx; - /* protect invalid_tids array and invalid_tid_idx */ - spinlock_t invalid_lock; - void *mm; //struct mm_struct *mm; -}; +#include int hfi1_map_device_addresses(struct hfi1_filedata *fd); @@ -510,6 +502,23 @@ static inline void pause_for_credit_return(struct hfi1_devdata *dd) udelay(usec ? usec : 1); } +#endif /* __HFI1_ORIG__ */ + +#define OPA_MAX_SCS 32 // from opa_smi.h + +/** + * sc_to_vlt() reverse lookup sc to vl + * @dd - devdata + * @sc5 - 5 bit sc + */ +static inline u8 sc_to_vlt(struct hfi1_devdata *dd, u8 sc5) +{ + if (sc5 >= OPA_MAX_SCS) + return (u8)(0xff); + + return *(((u8 *)dd->sc2vl) + sc5); +} +#ifdef __HFI1_ORIG__ #define PKEY_MEMBER_MASK 0x8000 #define PKEY_LOW_15_MASK 0x7fff @@ -1220,26 +1229,4 @@ __print_symbolic(opcode, \ ib_opcode_name(CNP)) #endif /* __HFI1_ORIG__ */ - -/* This include is at the end of this file on purpose, - * because it needs other structs defined here. - * Except for static inlines that need these types. - */ -#include - -#define OPA_MAX_SCS 32 // from opa_smi.h - -/** - * sc_to_vlt() reverse lookup sc to vl - * @dd - devdata - * @sc5 - 5 bit sc - */ -static inline u8 sc_to_vlt(struct hfi1_devdata *dd, u8 sc5) -{ - if (sc5 >= OPA_MAX_SCS) - return (u8)(0xff); - - return *(((u8 *)dd->sc2vl) + sc5); -} - #endif /* _HFI1_KERNEL_H */ diff --git a/kernel/include/hfi1/hfi1_generated_ctxtdata.h b/kernel/include/hfi1/hfi1_generated_ctxtdata.h new file mode 100644 index 00000000..c9152a17 --- /dev/null +++ b/kernel/include/hfi1/hfi1_generated_ctxtdata.h @@ -0,0 +1,41 @@ +struct hfi1_ctxtdata { + union { + char whole_struct[1456]; + struct { + char padding0[144]; + unsigned int ctxt; + }; + struct { + char padding1[172]; + u32 rcv_array_groups; + }; + struct { + char padding2[176]; + u32 eager_base; + }; + struct { + char padding3[180]; + u32 expected_count; + }; + struct { + char padding4[184]; + u32 expected_base; + }; + struct { + char padding5[192]; + struct exp_tid_set tid_group_list; + }; + struct { + char padding6[216]; + struct exp_tid_set tid_used_list; + }; + struct { + char padding7[240]; + struct exp_tid_set tid_full_list; + }; + struct { + char padding8[432]; + struct hfi1_devdata *dd; + }; + }; +}; diff --git a/kernel/include/hfi1/hfi1_generated_structs.h b/kernel/include/hfi1/hfi1_generated_devdata.h similarity index 52% rename from kernel/include/hfi1/hfi1_generated_structs.h rename to kernel/include/hfi1/hfi1_generated_devdata.h index 25a04116..e5eb2f05 100644 --- a/kernel/include/hfi1/hfi1_generated_structs.h +++ b/kernel/include/hfi1/hfi1_generated_devdata.h @@ -1,53 +1,6 @@ -struct hfi1_pportdata { - union { - struct { - char padding0[1907]; - u8 vls_operational; - }; - }; -}; -struct hfi1_ctxtdata { - union { - struct { - char padding0[144]; - unsigned int ctxt; - }; - struct { - char padding1[172]; - u32 rcv_array_groups; - }; - struct { - char padding2[176]; - u32 eager_base; - }; - struct { - char padding3[180]; - u32 expected_count; - }; - struct { - char padding4[184]; - u32 expected_base; - }; - struct { - char padding5[192]; - struct exp_tid_set tid_group_list; - }; - struct { - char padding6[216]; - struct exp_tid_set tid_used_list; - }; - struct { - char padding7[240]; - struct exp_tid_set tid_full_list; - }; - struct { - char padding8[432]; - struct hfi1_devdata *dd; - }; - }; -}; struct hfi1_devdata { union { + char whole_struct[7232]; struct { char padding0[2984]; u8 *kregbase1; diff --git a/kernel/include/hfi1/hfi1_generated_pportdata.h b/kernel/include/hfi1/hfi1_generated_pportdata.h new file mode 100644 index 00000000..4006a67d --- /dev/null +++ b/kernel/include/hfi1/hfi1_generated_pportdata.h @@ -0,0 +1,9 @@ +struct hfi1_pportdata { + union { + char whole_struct[12544]; + struct { + char padding0[1907]; + u8 vls_operational; + }; + }; +}; diff --git a/kernel/script/dwarf-extract-struct.c b/kernel/script/dwarf-extract-struct.c index 1ade375e..57e7bbdf 100644 --- a/kernel/script/dwarf-extract-struct.c +++ b/kernel/script/dwarf-extract-struct.c @@ -23,15 +23,16 @@ static void parse_dwarf(Dwarf_Debug dbg, const char *struct_name, const char *field_names[], int field_count); static void find_struct(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, const char *field_names[], int field_count, int level); -static void find_fields(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, - const char *field_names[], int field_count, int level); +static void find_fields(Dwarf_Debug dbg, Dwarf_Die struct_die, Dwarf_Die die, + const char *struct_name, const char *field_names[], + int field_count, int level); static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, int pad_num); int debug = 0; void usage(const char *argv[]) { - fprintf(stderr, "%s debug_file struct_name field [field...]\n", + fprintf(stderr, "%s debug_file struct_name [field [field...]]\n", argv[0]); } @@ -45,7 +46,7 @@ int main(int argc, const char *argv[]) { Dwarf_Handler errhand = 0; Dwarf_Ptr errarg = 0; - if(argc < 4) { + if(argc < 3) { usage(argv); exit(1); } @@ -171,8 +172,9 @@ static void find_struct(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, if (rc == DW_DLV_OK) { if (tag == DW_TAG_structure_type && name && strcasecmp(name, struct_name) == 0) { - find_fields(dbg, next, struct_name, field_names, - field_count, level + 1); + find_fields(dbg, die, next, struct_name, + field_names, field_count, + level + 1); fprintf(stderr, "Found struct %s but it did not have all members given!\nMissing:\n", struct_name); @@ -201,79 +203,6 @@ static void find_struct(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, } while (die); } -static void find_fields(Dwarf_Debug dbg, Dwarf_Die die, const char *struct_name, - const char *field_names[], int field_count, int level) { - Dwarf_Die next; - Dwarf_Error err; - int rc, i, printed_count = 0; - - printf("struct %s {\n\tunion {\n", - struct_name); - - do { - char *name; - const char *tag_name; - Dwarf_Half tag; - - rc = dwarf_diename(die, &name, &err); - if (rc == DW_DLV_NO_ENTRY) { - name = NULL; - } else if (rc != DW_DLV_OK) { - fprintf(stderr, "dwarf_diename error: %d %s\n", - rc, dwarf_errmsg(err)); - exit(1); - } - - rc = dwarf_tag(die, &tag, &err); - if (rc != DW_DLV_OK) { - fprintf(stderr, "dwarf_tag error: %d %s\n", - rc, dwarf_errmsg(err)); - exit(1); - } - - if (debug) { - rc = dwarf_get_TAG_name(tag, &tag_name); - if (rc != DW_DLV_OK) { - fprintf(stderr, - "dwarf_get_TAG_name error: %d\n", rc); - exit(1); - } - - printf("<%d> %p <%d> %s: %s\n", level, die, tag, - tag_name, name ? name : ""); - } - - if (tag == DW_TAG_member && name) { - for (i = 0; i < field_count; i++) { - if (!field_names[i]) - continue; - if (strcasecmp(name, field_names[i]) == 0) { - print_field(dbg, die, field_names[i], - printed_count); - field_names[i] = NULL; - printed_count++; - break; - } - } - if (printed_count == field_count) { - printf("\t};\n};\n"); - exit(0); - } - } - - rc = dwarf_siblingof(dbg, die, &next, &err); - dwarf_dealloc(dbg, die, DW_DLA_DIE); - if (name) - dwarf_dealloc(dbg, name, DW_DLA_STRING); - - if (rc != DW_DLV_OK) - break; - - die = next; - } while (die); -} - - static int dwarf_get_offset(Dwarf_Debug dbg, Dwarf_Die die, int *poffset, Dwarf_Error *perr) { Dwarf_Attribute attr; @@ -412,6 +341,88 @@ static int deref_type(Dwarf_Debug dbg, Dwarf_Die type_die, return rc; } +static void find_fields(Dwarf_Debug dbg, Dwarf_Die struct_die, Dwarf_Die die, + const char *struct_name, const char *field_names[], + int field_count, int level) { + Dwarf_Die next; + Dwarf_Error err; + int rc, i, printed_count = 0; + int size; + + printf("struct %s {\n\tunion {\n", + struct_name); + + rc = dwarf_get_size(dbg, struct_die, &size, &err); + if (rc != DW_DLV_OK) { + fprintf(stderr, "could not get size for struct %s: %s\n", + struct_name, dwarf_errmsg(err)); + exit(1); + } + printf("\t\tchar whole_struct[%d];\n", size); + + do { + char *name; + const char *tag_name; + Dwarf_Half tag; + + rc = dwarf_diename(die, &name, &err); + if (rc == DW_DLV_NO_ENTRY) { + name = NULL; + } else if (rc != DW_DLV_OK) { + fprintf(stderr, "dwarf_diename error: %d %s\n", + rc, dwarf_errmsg(err)); + exit(1); + } + + rc = dwarf_tag(die, &tag, &err); + if (rc != DW_DLV_OK) { + fprintf(stderr, "dwarf_tag error: %d %s\n", + rc, dwarf_errmsg(err)); + exit(1); + } + + if (debug) { + rc = dwarf_get_TAG_name(tag, &tag_name); + if (rc != DW_DLV_OK) { + fprintf(stderr, + "dwarf_get_TAG_name error: %d\n", rc); + exit(1); + } + + printf("<%d> %p <%d> %s: %s\n", level, die, tag, + tag_name, name ? name : ""); + } + + if (tag == DW_TAG_member && name) { + for (i = 0; i < field_count; i++) { + if (!field_names[i]) + continue; + if (strcasecmp(name, field_names[i]) == 0) { + print_field(dbg, die, field_names[i], + printed_count); + field_names[i] = NULL; + printed_count++; + break; + } + } + if (printed_count == field_count) { + printf("\t};\n};\n"); + exit(0); + } + } + + rc = dwarf_siblingof(dbg, die, &next, &err); + dwarf_dealloc(dbg, die, DW_DLA_DIE); + if (name) + dwarf_dealloc(dbg, name, DW_DLA_STRING); + + if (rc != DW_DLV_OK) + break; + + die = next; + } while (die); +} + static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, int padnum) { Dwarf_Attribute attr; @@ -419,6 +430,7 @@ static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, int offset = 0; char type_buf[1024]; char array_buf[128] = ""; + char pointer_buf[128] = ""; int rc; rc = dwarf_get_offset(dbg, die, &offset, &err); @@ -471,24 +483,26 @@ static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, exit(7); } - if (type_tag == DW_TAG_pointer_type) { + while (type_tag == DW_TAG_pointer_type) { + pointer_buf[pointer++] = '*'; + rc = deref_type(dbg, type_die, &next, &type_tag, &err); /* No entry here means void* */ - if (rc != DW_DLV_NO_ENTRY) { - if (rc != DW_DLV_OK) { - fprintf(stderr, - "Could not deref type for %s: %s\n", - field_name, dwarf_errmsg(err)); - exit(7); - } + if (rc == DW_DLV_NO_ENTRY) + break; - dwarf_dealloc(dbg, type_die, DW_DLA_DIE); - type_die = next; + if (rc != DW_DLV_OK) { + fprintf(stderr, + "Could not deref type for %s: %s\n", + field_name, dwarf_errmsg(err)); + exit(7); } - pointer++; + dwarf_dealloc(dbg, type_die, DW_DLA_DIE); + type_die = next; } + if (type_tag == DW_TAG_array_type) { int next_offset, size; @@ -581,13 +595,13 @@ static void print_field(Dwarf_Debug dbg, Dwarf_Die die, const char *field_name, if (type_tag == DW_TAG_structure_type) { snprintf(type_buf, 1024, "struct %s %s", - type_name, pointer ? "*" : ""); + type_name, pointer_buf); } else if (type_tag == DW_TAG_base_type || type_tag == DW_TAG_typedef) { snprintf(type_buf, 1024, "%s %s", type_name, - pointer ? "*" : ""); + pointer_buf); } else if (type_tag == DW_TAG_pointer_type) { - snprintf(type_buf, 1024, "void *"); + snprintf(type_buf, 1024, "void %s", pointer_buf); } else { const char *tag_name; diff --git a/kernel/script/regenerate_hfi1_header.sh b/kernel/script/regenerate_hfi1_header.sh index b61dc1a8..2b1ec48e 100755 --- a/kernel/script/regenerate_hfi1_header.sh +++ b/kernel/script/regenerate_hfi1_header.sh @@ -6,19 +6,19 @@ SCRIPT_PATH="${BASH_SOURCE[0]}" ROOTDIR=$(readlink -m "$SCRIPT_PATH") ROOTDIR=$(dirname "$ROOTDIR") -set -e +set -e -u # static configuration-ish declare -r DES_BIN="${ROOTDIR}/dwarf-extract-struct" declare -r DES_SRC="${DES_BIN}.c" -declare -r HDR="${ROOTDIR}/../include/hfi1/hfi1_generated_structs.h" +declare -r HDR_PREFIX="${ROOTDIR}/../include/hfi1/hfi1_generated_" error() { echo "$@" >&2 exit 1 } -HFI1_KO="${1-$(modprobe -n hfi1)}" || \ +HFI1_KO="${1-$(modinfo -n hfi1)}" || \ error "Could not find hfi1 module and no argument given. Usage: $0 [hfi1.ko]" @@ -26,13 +26,19 @@ HFI1_KO="${1-$(modprobe -n hfi1)}" || \ gcc -o "$DES_BIN" -g -ldwarf "$DES_SRC" || \ error "Could not compile, install libdwarf-devel ?" -"$DES_BIN" "$HFI1_KO" hfi1_pportdata vls_operational > "$HDR" +"$DES_BIN" "$HFI1_KO" hfi1_pportdata \ + vls_operational > "${HDR_PREFIX}pportdata.h" "$DES_BIN" "$HFI1_KO" hfi1_ctxtdata \ ctxt rcv_array_groups eager_base expected_count expected_base \ - tid_group_list tid_used_list tid_full_list dd >> "$HDR" + tid_group_list tid_used_list tid_full_list dd \ + > "${HDR_PREFIX}ctxtdata.h" "$DES_BIN" "$HFI1_KO" hfi1_devdata \ per_sdma sdma_pad_phys sdma_map pport chip_rcv_array_count \ kregbase1 piobase physaddr rcvarray_wc default_desc1 flags \ - sc2vl >> "$HDR" + sc2vl > "${HDR_PREFIX}devdata.h" + +"$DES_BIN" "$HFI1_KO" hfi1_filedata \ + uctxt pq cq dd subctxt entry_to_rb tid_lock tid_used \ + > "${HDR_PREFIX}filedata.h"