nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | #include <plugin.h> |
2 | #include <tree.h> |
||
3 | #include <print-tree.h> |
||
4 | #include <stdio.h> |
||
5 | #include <string.h> |
||
6 | #include <arpa/inet.h> |
||
7 | #include <c-family/c-pragma.h> |
||
8 | |||
9 | static tree handle_nexmon_place_at_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attr); |
||
10 | |||
11 | int plugin_is_GPL_compatible = 1; |
||
12 | |||
13 | static const char *objfile = "patch.o"; |
||
14 | static const char *fwfile = "fw_bcmdhd.bin"; |
||
15 | static const char *prefile = "nexmon.generated.pre"; |
||
16 | static const char *targetregion = NULL; |
||
17 | static unsigned int ramstart = 0x180000; |
||
18 | static unsigned int chipver = 0; |
||
19 | static unsigned int fwver = 0; |
||
20 | |||
21 | static FILE *pre_fp; |
||
22 | |||
23 | static struct attribute_spec user_attr = |
||
24 | { |
||
25 | .name = "at", |
||
26 | .min_length = 1, |
||
27 | .max_length = 4, |
||
28 | .decl_required = true, |
||
29 | .type_required = false, |
||
30 | .function_type_required = false, |
||
31 | .handler = handle_nexmon_place_at_attribute, |
||
32 | .affects_type_identity = false, |
||
33 | }; |
||
34 | |||
35 | static tree |
||
36 | handle_nexmon_place_at_attribute(tree *node, tree name, tree args, int flags, bool *no_add_attr) |
||
37 | { |
||
38 | //tree itr; |
||
39 | tree tmp_tree; |
||
40 | |||
41 | const char *decl_name = IDENTIFIER_POINTER(DECL_NAME(*node)); |
||
42 | //const char *attr_name = IDENTIFIER_POINTER(name); |
||
43 | //const char *param1_str = TREE_STRING_POINTER(TREE_VALUE(args)); |
||
44 | const char *region = NULL; |
||
45 | unsigned int addr = 0; |
||
46 | bool is_dummy = false; |
||
47 | bool is_region = false; |
||
48 | bool is_flashpatch = false; |
||
49 | unsigned int chipver_local = 0; |
||
50 | unsigned int fwver_local = 0; |
||
51 | |||
52 | if (TREE_CODE(TREE_VALUE(args)) == STRING_CST) { |
||
53 | region = TREE_STRING_POINTER(TREE_VALUE(args)); |
||
54 | is_region = true; |
||
55 | } else if (TREE_CODE(TREE_VALUE(args)) == INTEGER_CST) { |
||
56 | addr = TREE_INT_CST_LOW(TREE_VALUE(args)); |
||
57 | } |
||
58 | |||
59 | tmp_tree = TREE_CHAIN(args); |
||
60 | if(tmp_tree != NULL_TREE) { |
||
61 | is_dummy = strstr(TREE_STRING_POINTER(TREE_VALUE(tmp_tree)), "dummy"); |
||
62 | is_flashpatch = strstr(TREE_STRING_POINTER(TREE_VALUE(tmp_tree)), "flashpatch"); |
||
63 | |||
64 | tmp_tree = TREE_CHAIN(tmp_tree); |
||
65 | if(tmp_tree != NULL_TREE) { |
||
66 | chipver_local = TREE_INT_CST_LOW(TREE_VALUE(tmp_tree)); |
||
67 | |||
68 | tmp_tree = TREE_CHAIN(tmp_tree); |
||
69 | if(tmp_tree != NULL_TREE) { |
||
70 | fwver_local = TREE_INT_CST_LOW(TREE_VALUE(tmp_tree)); |
||
71 | } |
||
72 | } |
||
73 | } |
||
74 | |||
75 | printf("decl_name: %s\n", decl_name); |
||
76 | |||
77 | //printf("attr_name: %s\n", attr_name); |
||
78 | |||
79 | //printf("align: %d\n", DECL_COMMON_CHECK (*node)->decl_common.align); |
||
80 | if (DECL_COMMON_CHECK (*node)->decl_common.align == 32 && (addr & 1)) |
||
81 | DECL_COMMON_CHECK (*node)->decl_common.align = 8; |
||
82 | |||
83 | if (DECL_COMMON_CHECK (*node)->decl_common.align == 32 && (addr & 2)) |
||
84 | DECL_COMMON_CHECK (*node)->decl_common.align = 16; |
||
85 | //printf("align: %d\n", DECL_COMMON_CHECK (*node)->decl_common.align); |
||
86 | |||
87 | //for(itr = args; itr != NULL_TREE; itr = TREE_CHAIN(itr)) { |
||
88 | // printf("arg: %s %08x\n", TREE_STRING_POINTER(TREE_VALUE(itr)), (unsigned int) strtol(TREE_STRING_POINTER(TREE_VALUE(itr)), NULL, 0)); |
||
89 | //debug_tree(itr); |
||
90 | //debug_tree(TREE_VALUE(itr)); |
||
91 | //} |
||
92 | |||
93 | if ((chipver == 0 || chipver_local == 0 || chipver == chipver_local) && (fwver == 0 || fwver_local == 0 || fwver == fwver_local)) { |
||
94 | if (is_region) { |
||
95 | fprintf(pre_fp, "%s REGION %s %s\n", region, objfile, decl_name); |
||
96 | } else if (is_flashpatch) { |
||
97 | fprintf(pre_fp, "0x%08x FLASHPATCH %s %s\n", addr, objfile, decl_name); |
||
98 | } else if (is_dummy) { |
||
99 | fprintf(pre_fp, "0x%08x DUMMY %s %s\n", addr, objfile, decl_name); |
||
100 | } else { |
||
101 | fprintf(pre_fp, "0x%08x PATCH %s %s\n", addr, objfile, decl_name); |
||
102 | } |
||
103 | } |
||
104 | |||
105 | //debug_tree(*node); |
||
106 | //debug_tree(name); |
||
107 | return NULL_TREE; |
||
108 | } |
||
109 | |||
110 | static void |
||
111 | register_attributes(void *event_data, void *data) |
||
112 | { |
||
113 | register_attribute(&user_attr); |
||
114 | } |
||
115 | |||
116 | static void |
||
117 | handle_pragma_targetregion(cpp_reader *dummy) |
||
118 | { |
||
119 | tree message = 0; |
||
120 | if (pragma_lex(&message) != CPP_STRING) { |
||
121 | printf ("<#pragma NEXMON targetregion> is not a string"); |
||
122 | return; |
||
123 | } |
||
124 | |||
125 | if (TREE_STRING_LENGTH (message) > 1) { |
||
126 | targetregion = TREE_STRING_POINTER (message); |
||
127 | fprintf(pre_fp, "%s TARGETREGION %s\n", targetregion, objfile); |
||
128 | } |
||
129 | } |
||
130 | |||
131 | static void |
||
132 | register_pragmas(void *event_data, void *data) |
||
133 | { |
||
134 | c_register_pragma("NEXMON", "targetregion", handle_pragma_targetregion); |
||
135 | } |
||
136 | |||
137 | static void |
||
138 | handle_plugin_finish(void *event_data, void *data) |
||
139 | { |
||
140 | fclose(pre_fp); |
||
141 | } |
||
142 | |||
143 | int |
||
144 | plugin_init(struct plugin_name_args *info, struct plugin_gcc_version *ver) |
||
145 | { |
||
146 | int i = 0; |
||
147 | for (i = 0; i < info->argc; i++) { |
||
148 | if (!strcmp(info->argv[i].key, "objfile")) { |
||
149 | objfile = info->argv[i].value; |
||
150 | } else if (!strcmp(info->argv[i].key, "prefile")) { |
||
151 | prefile = info->argv[i].value; |
||
152 | } else if (!strcmp(info->argv[i].key, "fwfile")) { |
||
153 | fwfile = info->argv[i].value; |
||
154 | } else if (!strcmp(info->argv[i].key, "ramstart")) { |
||
155 | ramstart = (unsigned int) strtol(info->argv[i].value, NULL, 0); |
||
156 | } else if (!strcmp(info->argv[i].key, "chipver")) { |
||
157 | chipver = (unsigned int) strtol(info->argv[i].value, NULL, 0); |
||
158 | } else if (!strcmp(info->argv[i].key, "fwver")) { |
||
159 | fwver = (unsigned int) strtol(info->argv[i].value, NULL, 0); |
||
160 | } |
||
161 | } |
||
162 | |||
163 | pre_fp = fopen(prefile, "a"); |
||
164 | |||
165 | if (!pre_fp) { |
||
166 | fprintf(stderr, "gcc_nexmon_plugin: Pre file not writeable! (error)\n"); |
||
167 | return -1; |
||
168 | } |
||
169 | |||
170 | register_callback("nexmon", PLUGIN_ATTRIBUTES, register_attributes, NULL); |
||
171 | register_callback("nexmon", PLUGIN_PRAGMAS, register_pragmas, NULL); |
||
172 | register_callback("nexmon", PLUGIN_FINISH, handle_plugin_finish, NULL); |
||
173 | |||
174 | return 0; |
||
175 | } |