rk: arm64: support build kernel.img and resource.img
[firefly-linux-kernel-4.4.55.git] / scripts / mod / file2alias.c
index 45f9a3377dcd8d60f1df08542ca804537e443225..5b96206e9aab833f9a666bc7cf52d57662929b3d 100644 (file)
@@ -34,6 +34,9 @@ typedef Elf64_Addr    kernel_ulong_t;
 typedef uint32_t       __u32;
 typedef uint16_t       __u16;
 typedef unsigned char  __u8;
+typedef struct {
+       __u8 b[16];
+} uuid_le;
 
 /* Big exception to the "don't include kernel headers into userspace, which
  * even potentially has different endianness and word sizes, since
@@ -42,7 +45,7 @@ typedef unsigned char __u8;
 
 /* This array collects all instances that use the generic do_table */
 struct devtable {
-       const char *device_id; /* name of table, __mod_<name>_device_table. */
+       const char *device_id; /* name of table, __mod_<name>__*_device_table. */
        unsigned long id_size;
        void *function;
 };
@@ -79,10 +82,12 @@ struct devtable **__start___devtable, **__stop___devtable;
 extern struct devtable *__start___devtable[], *__stop___devtable[];
 #endif /* __MACH__ */
 
-#if __GNUC__ == 3 && __GNUC_MINOR__ < 3
-# define __used                        __attribute__((__unused__))
-#else
-# define __used                        __attribute__((__used__))
+#if !defined(__used)
+# if __GNUC__ == 3 && __GNUC_MINOR__ < 3
+#  define __used                       __attribute__((__unused__))
+# else
+#  define __used                       __attribute__((__used__))
+# endif
 #endif
 
 /* Define a variable f that holds the value of field f of struct devid
@@ -129,6 +134,17 @@ static inline void add_wildcard(char *str)
                strcat(str + len, "*");
 }
 
+static inline void add_uuid(char *str, uuid_le uuid)
+{
+       int len = strlen(str);
+
+       sprintf(str + len, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+               uuid.b[3], uuid.b[2], uuid.b[1], uuid.b[0],
+               uuid.b[5], uuid.b[4], uuid.b[7], uuid.b[6],
+               uuid.b[8], uuid.b[9], uuid.b[10], uuid.b[11],
+               uuid.b[12], uuid.b[13], uuid.b[14], uuid.b[15]);
+}
+
 /**
  * Check that sizeof(device_id type) are consistent with size of section
  * in .o file. If in-consistent then userspace and kernel does not agree
@@ -144,7 +160,8 @@ static void device_id_check(const char *modname, const char *device_id,
 
        if (size % id_size || size < id_size) {
                fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo "
-                     "of the size of section __mod_%s_device_table=%lu.\n"
+                     "of the size of "
+                     "section __mod_%s__<identifier>_device_table=%lu.\n"
                      "Fix definition of struct %s_device_id "
                      "in mod_devicetable.h\n",
                      modname, device_id, id_size, device_id, size, device_id);
@@ -208,8 +225,8 @@ static void do_usb_entry(void *symval,
                                range_lo < 0x9 ? "[%X-9" : "[%X",
                                range_lo);
                        sprintf(alias + strlen(alias),
-                               range_hi > 0xA ? "a-%X]" : "%X]",
-                               range_lo);
+                               range_hi > 0xA ? "A-%X]" : "%X]",
+                               range_hi);
                }
        }
        if (bcdDevice_initial_digits < (sizeof(bcdDevice_lo) * 2 - 1))
@@ -508,12 +525,40 @@ static int do_serio_entry(const char *filename,
 }
 ADD_TO_DEVTABLE("serio", serio_device_id, do_serio_entry);
 
-/* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */
+/* looks like: "acpi:ACPI0003" or "acpi:PNP0C0B" or "acpi:LNXVIDEO" or
+ *             "acpi:bbsspp" (bb=base-class, ss=sub-class, pp=prog-if)
+ *
+ * NOTE: Each driver should use one of the following : _HID, _CIDs
+ *       or _CLS. Also, bb, ss, and pp can be substituted with ??
+ *       as don't care byte.
+ */
 static int do_acpi_entry(const char *filename,
                        void *symval, char *alias)
 {
        DEF_FIELD_ADDR(symval, acpi_device_id, id);
-       sprintf(alias, "acpi*:%s:*", *id);
+       DEF_FIELD_ADDR(symval, acpi_device_id, cls);
+       DEF_FIELD_ADDR(symval, acpi_device_id, cls_msk);
+
+       if (id && strlen((const char *)*id))
+               sprintf(alias, "acpi*:%s:*", *id);
+       else if (cls) {
+               int i, byte_shift, cnt = 0;
+               unsigned int msk;
+
+               sprintf(&alias[cnt], "acpi*:");
+               cnt = 6;
+               for (i = 1; i <= 3; i++) {
+                       byte_shift = 8 * (3-i);
+                       msk = (*cls_msk >> byte_shift) & 0xFF;
+                       if (msk)
+                               sprintf(&alias[cnt], "%02x",
+                                       (*cls >> byte_shift) & 0xFF);
+                       else
+                               sprintf(&alias[cnt], "??");
+                       cnt += 2;
+               }
+               sprintf(&alias[cnt], ":*");
+       }
        return 1;
 }
 ADD_TO_DEVTABLE("acpi", acpi_device_id, do_acpi_entry);
@@ -641,28 +686,26 @@ ADD_TO_DEVTABLE("pcmcia", pcmcia_device_id, do_pcmcia_entry);
 
 static int do_of_entry (const char *filename, void *symval, char *alias)
 {
-    int len;
-    char *tmp;
-    DEF_FIELD_ADDR(symval, of_device_id, name);
-    DEF_FIELD_ADDR(symval, of_device_id, type);
-    DEF_FIELD_ADDR(symval, of_device_id, compatible);
-
-    len = sprintf (alias, "of:N%sT%s",
-                    (*name)[0] ? *name : "*",
-                    (*type)[0] ? *type : "*");
-
-    if (compatible[0])
-        sprintf (&alias[len], "%sC%s",
-                     (*type)[0] ? "*" : "",
-                     *compatible);
-
-    /* Replace all whitespace with underscores */
-    for (tmp = alias; tmp && *tmp; tmp++)
-        if (isspace (*tmp))
-            *tmp = '_';
-
-    add_wildcard(alias);
-    return 1;
+       int len;
+       char *tmp;
+       DEF_FIELD_ADDR(symval, of_device_id, name);
+       DEF_FIELD_ADDR(symval, of_device_id, type);
+       DEF_FIELD_ADDR(symval, of_device_id, compatible);
+
+       len = sprintf(alias, "of:N%sT%s", (*name)[0] ? *name : "*",
+                     (*type)[0] ? *type : "*");
+
+       if (compatible[0])
+               sprintf(&alias[len], "%sC%s", (*type)[0] ? "*" : "",
+                       *compatible);
+
+       /* Replace all whitespace with underscores */
+       for (tmp = alias; tmp && *tmp; tmp++)
+               if (isspace (*tmp))
+                       *tmp = '_';
+
+       add_wildcard(alias);
+       return 1;
 }
 ADD_TO_DEVTABLE("of", of_device_id, do_of_entry);
 
@@ -1108,7 +1151,23 @@ static int do_amba_entry(const char *filename,
 }
 ADD_TO_DEVTABLE("amba", amba_id, do_amba_entry);
 
-/* LOOKS like x86cpu:vendor:VVVV:family:FFFF:model:MMMM:feature:*,FEAT,*
+/*
+ * looks like: "mipscdmm:tN"
+ *
+ * N is exactly 2 digits, where each is an upper-case hex digit, or
+ *     a ? or [] pattern matching exactly one digit.
+ */
+static int do_mips_cdmm_entry(const char *filename,
+                             void *symval, char *alias)
+{
+       DEF_FIELD(symval, mips_cdmm_device_id, type);
+
+       sprintf(alias, "mipscdmm:t%02X*", type);
+       return 1;
+}
+ADD_TO_DEVTABLE("mipscdmm", mips_cdmm_device_id, do_mips_cdmm_entry);
+
+/* LOOKS like cpu:type:x86,venVVVVfamFFFFmodMMMM:feature:*,FEAT,*
  * All fields are numbers. It would be nicer to use strings for vendor
  * and feature, but getting those out of the build system here is too
  * complicated.
@@ -1122,10 +1181,10 @@ static int do_x86cpu_entry(const char *filename, void *symval,
        DEF_FIELD(symval, x86_cpu_id, model);
        DEF_FIELD(symval, x86_cpu_id, vendor);
 
-       strcpy(alias, "x86cpu:");
-       ADD(alias, "vendor:",  vendor != X86_VENDOR_ANY, vendor);
-       ADD(alias, ":family:", family != X86_FAMILY_ANY, family);
-       ADD(alias, ":model:",  model  != X86_MODEL_ANY,  model);
+       strcpy(alias, "cpu:type:x86,");
+       ADD(alias, "ven", vendor != X86_VENDOR_ANY, vendor);
+       ADD(alias, "fam", family != X86_FAMILY_ANY, family);
+       ADD(alias, "mod", model  != X86_MODEL_ANY,  model);
        strcat(alias, ":feature:*");
        if (feature != X86_FEATURE_ANY)
                sprintf(alias + strlen(alias), "%04X*", feature);
@@ -1133,18 +1192,85 @@ static int do_x86cpu_entry(const char *filename, void *symval,
 }
 ADD_TO_DEVTABLE("x86cpu", x86_cpu_id, do_x86cpu_entry);
 
-/* Looks like: mei:S */
+/* LOOKS like cpu:type:*:feature:*FEAT* */
+static int do_cpu_entry(const char *filename, void *symval, char *alias)
+{
+       DEF_FIELD(symval, cpu_feature, feature);
+
+       sprintf(alias, "cpu:type:*:feature:*%04X*", feature);
+       return 1;
+}
+ADD_TO_DEVTABLE("cpu", cpu_feature, do_cpu_entry);
+
+/* Looks like: mei:S:uuid:N:* */
 static int do_mei_entry(const char *filename, void *symval,
                        char *alias)
 {
        DEF_FIELD_ADDR(symval, mei_cl_device_id, name);
+       DEF_FIELD_ADDR(symval, mei_cl_device_id, uuid);
+       DEF_FIELD(symval, mei_cl_device_id, version);
+
+       sprintf(alias, MEI_CL_MODULE_PREFIX);
+       sprintf(alias + strlen(alias), "%s:",  (*name)[0]  ? *name : "*");
+       add_uuid(alias, *uuid);
+       ADD(alias, ":", version != MEI_CL_VERSION_ANY, version);
 
-       sprintf(alias, MEI_CL_MODULE_PREFIX "%s", *name);
+       strcat(alias, ":*");
 
        return 1;
 }
 ADD_TO_DEVTABLE("mei", mei_cl_device_id, do_mei_entry);
 
+/* Looks like: rapidio:vNdNavNadN */
+static int do_rio_entry(const char *filename,
+                       void *symval, char *alias)
+{
+       DEF_FIELD(symval, rio_device_id, did);
+       DEF_FIELD(symval, rio_device_id, vid);
+       DEF_FIELD(symval, rio_device_id, asm_did);
+       DEF_FIELD(symval, rio_device_id, asm_vid);
+
+       strcpy(alias, "rapidio:");
+       ADD(alias, "v", vid != RIO_ANY_ID, vid);
+       ADD(alias, "d", did != RIO_ANY_ID, did);
+       ADD(alias, "av", asm_vid != RIO_ANY_ID, asm_vid);
+       ADD(alias, "ad", asm_did != RIO_ANY_ID, asm_did);
+
+       add_wildcard(alias);
+       return 1;
+}
+ADD_TO_DEVTABLE("rapidio", rio_device_id, do_rio_entry);
+
+/* Looks like: ulpi:vNpN */
+static int do_ulpi_entry(const char *filename, void *symval,
+                        char *alias)
+{
+       DEF_FIELD(symval, ulpi_device_id, vendor);
+       DEF_FIELD(symval, ulpi_device_id, product);
+
+       sprintf(alias, "ulpi:v%04xp%04x", vendor, product);
+
+       return 1;
+}
+ADD_TO_DEVTABLE("ulpi", ulpi_device_id, do_ulpi_entry);
+
+/* Looks like: hdaudio:vNrNaN */
+static int do_hda_entry(const char *filename, void *symval, char *alias)
+{
+       DEF_FIELD(symval, hda_device_id, vendor_id);
+       DEF_FIELD(symval, hda_device_id, rev_id);
+       DEF_FIELD(symval, hda_device_id, api_version);
+
+       strcpy(alias, "hdaudio:");
+       ADD(alias, "v", vendor_id != 0, vendor_id);
+       ADD(alias, "r", rev_id != 0, rev_id);
+       ADD(alias, "a", api_version != 0, api_version);
+
+       add_wildcard(alias);
+       return 1;
+}
+ADD_TO_DEVTABLE("hdaudio", hda_device_id, do_hda_entry);
+
 /* Does namelen bytes of name exactly match the symbol? */
 static bool sym_is(const char *name, unsigned namelen, const char *symbol)
 {
@@ -1184,7 +1310,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
 {
        void *symval;
        char *zeros = NULL;
-       const char *name;
+       const char *name, *identifier;
        unsigned int namelen;
 
        /* We're looking for a section relative symbol */
@@ -1195,7 +1321,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
        if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
                return;
 
-       /* All our symbols are of form <prefix>__mod_XXX_device_table. */
+       /* All our symbols are of form <prefix>__mod_<name>__<identifier>_device_table. */
        name = strstr(symname, "__mod_");
        if (!name)
                return;
@@ -1205,7 +1331,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
                return;
        if (strcmp(name + namelen - strlen("_device_table"), "_device_table"))
                return;
-       namelen -= strlen("_device_table");
+       identifier = strstr(name, "__");
+       if (!identifier)
+               return;
+       namelen = identifier - name;
 
        /* Handle all-NULL symbols allocated into .bss */
        if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {