Changeset ff3b3197 in mainline for generic/src/main/kconsole.c
- Timestamp:
- 2005-11-25T22:58:38Z (20 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f4338d2
- Parents:
- 78c32b4
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/src/main/kconsole.c
r78c32b4 rff3b3197 31 31 #include <console/chardev.h> 32 32 #include <print.h> 33 #include <panic.h> 33 34 #include <typedefs.h> 34 35 #include <arch/types.h> 36 #include <list.h> 37 #include <arch.h> 38 #include <func.h> 39 #include <macros.h> 40 41 #define MAX_CMDLINE 256 42 43 /** Simple kernel console. 44 * 45 * The console is realized by kernel thread kconsole. 46 * It doesn't understand any commands on its own, but 47 * makes it possible for other kernel subsystems to 48 * register their own commands. 49 */ 50 51 /** Locking. 52 * 53 * There is a list of cmd_info_t structures. This list 54 * is protected by cmd_lock spinlock. Note that specially 55 * the link elements of cmd_info_t are protected by 56 * this lock. 57 * 58 * Each cmd_info_t also has its own lock, which protects 59 * all elements thereof except the link element. 60 * 61 * cmd_lock must be acquired before any cmd_info lock. 62 * When locking two cmd info structures, structure with 63 * lower address must be locked first. 64 */ 65 66 spinlock_t cmd_lock; /**< Lock protecting command list. */ 67 link_t cmd_head; /**< Command list. */ 68 69 static cmd_info_t *parse_cmdline(char *cmdline, size_t len); 70 static int cmd_help(cmd_arg_t *cmd); 71 72 static cmd_info_t help_info; 73 74 /** Initialize kconsole data structures. */ 75 void kconsole_init(void) 76 { 77 spinlock_initialize(&cmd_lock); 78 list_initialize(&cmd_head); 79 80 help_info.name = "help"; 81 help_info.description = "List supported commands."; 82 help_info.func = cmd_help; 83 help_info.argc = 0; 84 help_info.argv = NULL; 85 86 spinlock_initialize(&help_info.lock); 87 link_initialize(&help_info.link); 88 89 if (!cmd_register(&help_info)) 90 panic("could not register command\n"); 91 } 92 93 94 /** Register kconsole command. 95 * 96 * @param cmd Structure describing the command. 97 * 98 * @return 0 on failure, 1 on success. 99 */ 100 int cmd_register(cmd_info_t *cmd) 101 { 102 ipl_t ipl; 103 link_t *cur; 104 105 ipl = interrupts_disable(); 106 spinlock_lock(&cmd_lock); 107 108 /* 109 * Make sure the command is not already listed. 110 */ 111 for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) { 112 cmd_info_t *hlp; 113 114 hlp = list_get_instance(cur, cmd_info_t, link); 115 116 if (hlp == cmd) { 117 /* The command is already there. */ 118 spinlock_unlock(&cmd_lock); 119 interrupts_restore(ipl); 120 return 0; 121 } 122 123 /* Avoid deadlock. */ 124 if (hlp < cmd) { 125 spinlock_lock(&hlp->lock); 126 spinlock_lock(&cmd->lock); 127 } else { 128 spinlock_lock(&cmd->lock); 129 spinlock_lock(&hlp->lock); 130 } 131 132 if ((strcmp(hlp->name, cmd->name, strlen(cmd->name)) == 0)) { 133 /* The command is already there. */ 134 spinlock_unlock(&hlp->lock); 135 spinlock_unlock(&cmd->lock); 136 spinlock_unlock(&cmd_lock); 137 interrupts_restore(ipl); 138 return 0; 139 } 140 141 spinlock_unlock(&hlp->lock); 142 spinlock_unlock(&cmd->lock); 143 } 144 145 /* 146 * Now the command can be added. 147 */ 148 list_append(&cmd->link, &cmd_head); 149 150 spinlock_unlock(&cmd_lock); 151 interrupts_restore(ipl); 152 return 1; 153 } 35 154 36 155 /** Kernel console managing thread. … … 40 159 void kconsole(void *arg) 41 160 { 42 __u8 buf[CHARDEV_BUFLEN]; 161 char cmdline[MAX_CMDLINE+1]; 162 cmd_info_t *cmd_info; 163 count_t len; 43 164 44 165 if (!stdin) { … … 49 170 while (true) { 50 171 printf("%s> ", __FUNCTION__); 51 gets(stdin, buf, sizeof(buf)); 52 printf("?\n"); 53 } 54 } 172 len = gets(stdin, cmdline, sizeof(cmdline)); 173 cmdline[len] = '\0'; 174 cmd_info = parse_cmdline(cmdline, len); 175 if (!cmd_info) { 176 printf("?\n"); 177 continue; 178 } 179 (void) cmd_info->func(cmd_info->argv); 180 } 181 } 182 183 /** Parse command line. 184 * 185 * @param cmdline Command line as read from input device. 186 * @param len Command line length. 187 * 188 * @return Structure describing the command. 189 */ 190 cmd_info_t *parse_cmdline(char *cmdline, size_t len) 191 { 192 index_t start = 0, end = 0; 193 bool found_start = false; 194 cmd_info_t *cmd = NULL; 195 link_t *cur; 196 ipl_t ipl; 197 int i; 198 199 for (i = 0; i < len; i++) { 200 if (!found_start) { 201 if (is_white(cmdline[i])) 202 start++; 203 else 204 found_start = true; 205 } else { 206 if (is_white(cmdline[i])) 207 break; 208 } 209 } 210 end = i - 1; 211 212 if (!found_start) { 213 /* Command line did not contain alphanumeric word. */ 214 return NULL; 215 } 216 217 ipl = interrupts_disable(); 218 spinlock_lock(&cmd_lock); 219 220 for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) { 221 cmd_info_t *hlp; 222 223 hlp = list_get_instance(cur, cmd_info_t, link); 224 spinlock_lock(&hlp->lock); 225 226 if (strcmp(hlp->name, &cmdline[start], (end - start) + 1) == 0) { 227 cmd = hlp; 228 break; 229 } 230 231 spinlock_unlock(&hlp->lock); 232 } 233 234 spinlock_unlock(&cmd_lock); 235 236 if (!cmd) { 237 /* Unknown command. */ 238 interrupts_restore(ipl); 239 return NULL; 240 } 241 242 /* cmd == hlp is locked */ 243 244 /* 245 * TODO: 246 * The command line must be further analyzed and 247 * the parameters therefrom must be matched and 248 * converted to those specified in the cmd info 249 * structure. 250 */ 251 252 spinlock_unlock(&cmd->lock); 253 interrupts_restore(ipl); 254 return cmd; 255 } 256 257 /** List supported commands. 258 * 259 * @param cmd Argument vector. 260 * 261 * @return 0 on failure, 1 on success. 262 */ 263 int cmd_help(cmd_arg_t *cmd) 264 { 265 link_t *cur; 266 ipl_t ipl; 267 268 ipl = interrupts_disable(); 269 spinlock_lock(&cmd_lock); 270 271 for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) { 272 cmd_info_t *hlp; 273 274 hlp = list_get_instance(cur, cmd_info_t, link); 275 spinlock_lock(&hlp->lock); 276 277 printf("%s\t%s\n", hlp->name, hlp->description); 278 279 spinlock_unlock(&hlp->lock); 280 } 281 282 spinlock_unlock(&cmd_lock); 283 interrupts_restore(ipl); 284 285 return 1; 286 }
Note:
See TracChangeset
for help on using the changeset viewer.