void i860_cpu_device::run_cycle() { CLEAR_FLOW(); m_dim_cc_valid = false; m_flow &= ~DIM_OP; UINT64 insn64 = ifetch64(m_pc); if(!(m_pc & 4)) { UINT32 savepc = m_pc; #if ENABLE_DEBUGGER if(m_single_stepping) debugger(0,0); #endif UINT32 insnLow = insn64; if(insnLow == INSN_FNOP_DIM) { if(m_dim) m_flow |= DIM_OP; else m_flow &= ~DIM_OP; } else if((insnLow & INSN_MASK_DIM) == INSN_FP_DIM) m_flow |= DIM_OP; decode_exec(insnLow); if (PENDING_TRAP()) { handle_trap(savepc); goto done; } else if(GET_PC_UPDATED()) { goto done; } else { // If the PC wasn't updated by a control flow instruction, just bump to next sequential instruction. m_pc += 4; CLEAR_FLOW(); } } if(m_pc & 4) { UINT32 savepc = m_pc; #if ENABLE_DEBUGGER if(m_single_stepping && !(m_dim)) debugger(0,0); #endif UINT32 insnHigh= insn64 >> 32; decode_exec(insnHigh); // only check for external interrupts // - on high-word (speedup) // - not DIM (safety :-) // - when no other traps are pending if(!(m_dim) && !(PENDING_TRAP())) { if(m_flow & EXT_INTR) { m_flow &= ~EXT_INTR; gen_interrupt(); } else clr_interrupt(); } if (PENDING_TRAP()) { handle_trap(savepc); } else if (GET_PC_UPDATED()) { goto done; } else { // If the PC wasn't updated by a control flow instruction, just bump to next sequential instruction. m_pc += 4; } }
/* * Read the configuration file. * If parameter "all" == 0 then ignore everything except path info * Return -1 if any error. * Error messages generated. */ static int do_read(int all, char *force_ver, char *base_dir, char *conf_file, int depth) { #define MAX_LEVEL 20 FILE *fin; GLOB_LIST g; int i; int assgn; int drop_default_paths = 1; int lineno = 0; int ret = 0; int state[MAX_LEVEL + 1]; /* nested "if" */ int level = 0; int sizebuf; char *buf = NULL; char tmpline[PATH_MAX]; char **pathp; char *envpath; char *version; char *type; char **glb; char old_name[] = "/etc/conf.modules"; int conf_file_specified = 0; /* * The configuration file is optional. * No error is printed if it is missing. * If it is missing the following content is assumed. * * path[boot]=/lib/modules/boot * * path[toplevel]=/lib/modules/`uname -r` * * path[toplevel]=/lib/modules/`kernelversion` * (where kernelversion gives the major kernel version: "2.0", "2.2"...) * * path[toplevel]=/lib/modules/default * * path[kernel]=/lib/modules/kernel * path[fs]=/lib/modules/fs * path[net]=/lib/modules/net * path[scsi]=/lib/modules/scsi * path[block]=/lib/modules/block * path[cdrom]=/lib/modules/cdrom * path[ipv4]=/lib/modules/ipv4 * path[ipv6]=/lib/modules/ipv6 * path[sound]=/lib/modules/sound * path[fc4]=/lib/modules/fc4 * path[video]=/lib/modules/video * path[misc]=/lib/modules/misc * path[pcmcia]=/lib/modules/pcmcia * path[atm]=/lib/modules/atm * path[usb]=/lib/modules/usb * path[ide]=/lib/modules/ide * path[ieee1394]=/lib/modules/ieee1394 * path[mtd]=/lib/modules/mtd * * The idea is that modprobe will look first if the * modules are compiled for the current release of the kernel. * If not found, it will look for modules that fit for the * general kernelversion (2.0, 2.2 and so on). * If still not found, it will look into the default release. * And if still not found, it will look in the other directories. * * The strategy should be like this: * When you install a new linux kernel, the modules should go * into a directory related to the release (version) of the kernel. * Then you can do a symlink "default" to this directory. * * Each time you compile a new kernel, the make modules_install * will create a new directory, but it won't change thee default. * * When you get a module unrelated to the kernel distribution * you can place it in one of the last three directory types. * * This is the default strategy. Of course you can overide * this in /etc/modules.conf. * * 2.3.15 added a new file tree walk algorithm which made it possible to * point at a top level directory and get the same behaviour as earlier * versions of modutils. 2.3.16 takes this one stage further, it * removes all the individual directory names from most of the scans, * only pointing at the top level directory. The only exception is the * last ditch scan, scanning all of /lib/modules would be a bad idea(TM) * so the last ditch scan still runs individual directory names under * /lib/modules. * * Additional syntax: * * [add] above module module1 ... * Specify additional modules to pull in on top of a module * * [add] below module module1 ... * Specify additional modules needed to be able to load a module * * [add] prune filename ... * * [add] probe name module1 ... * When "name" is requested, modprobe tries to install each * module in the list until it succeeds. * * [add] probeall name module1 ... * When "name" is requested, modprobe tries to install all * modules in the list. * If any module is installed, the command has succeeded. * * [add] options module option_list * * For all of the above, the optional "add" prefix is used to * add to a list instead of replacing the contents. * * include FILE_TO_INCLUDE * This does what you expect. No limitation on include levels. * * persistdir=persist_directory * Name the directory to save persistent data from modules. * * In the following WORD is a sequence if non-white characters. * If ' " or ` is found in the string, all characters up to the * matching ' " or ` will also be included, even whitespace. * Every WORD will then be expanded w.r.t. meta-characters. * If the expanded result gives more than one word, then only * the first word of the result will be used. * * * define CODE WORD * Do a putenv("CODE=WORD") * * EXPRESSION below can be: * WORD compare_op WORD * where compare_op is one of == != < <= >= > * The string values of the WORDs are compared * or * -n WORD compare_op WORD * where compare_op is one of == != < <= >= > * The numeric values of the WORDs are compared * or * WORD * if the expansion of WORD fails, or if the * expansion is "0" (zero), "false" or "" (empty) * then the expansion has the value FALSE. * Otherwise the expansion has the value TRUE * or * -f FILENAME * Test if the file FILENAME exists * or * -k * Test if "autoclean" (i.e. called from the kernel) * or * ! EXPRESSION * A negated expression is also an expression * * if EXPRESSION * any config line * ... * elseif EXPRESSION * any config line * ... * else * any config line * ... * endif * * The else and elseif keywords are optional. * "if"-statements nest up to 20 levels. */ state[0] = 1; if (force_ver) version = force_ver; else version = uts_info.release; config_version = xstrdup(version); /* Only read the default entries on the first file */ if (depth == 0) { maxpath = 100; modpath = (struct PATH_TYPE *)xmalloc(maxpath * sizeof(struct PATH_TYPE)); nmodpath = 0; maxexecs = 10; execs = (struct EXEC_TYPE *)xmalloc(maxexecs * sizeof(struct EXEC_TYPE)); nexecs = 0; /* * Build predef options */ if (all && optlist[0]) n_opt_list = build_list(optlist, &opt_list, version, 1); /* * Build predef above */ if (all && above[0]) n_abovelist = build_list(above, &abovelist, version, 0); /* * Build predef below */ if (all && below[0]) n_belowlist = build_list(below, &belowlist, version, 0); /* * Build predef prune list */ if (prune[0]) n_prunelist = build_list(prune, &prunelist, version, 0); /* * Build predef aliases */ if (all && aliaslist[0]) n_aliases = build_list(aliaslist, &aliases, version, 0); /* Order and priority is now: (MODPATH + modules.conf) || (predefs + modules.conf) */ if ((envpath = getenv("MODPATH")) != NULL && !safemode) { size_t len; char *p; char *path; /* Make a copy so's we can mung it with strtok. */ len = strlen(envpath) + 1; p = alloca(len); memcpy(p, envpath, len); path = alloca(PATH_MAX); for (p = strtok(p, ":"); p != NULL; p = strtok(NULL, ":")) { len = snprintf(path, PATH_MAX, p, version); modpath[nmodpath].path = xstrdup(path); if ((type = strrchr(path, '/')) != NULL) type += 1; else type = "misc"; modpath[nmodpath].type = xstrdup(type); if (++nmodpath >= maxpath) { maxpath += 100; modpath = (struct PATH_TYPE *)xrealloc(modpath, maxpath * sizeof(struct PATH_TYPE)); } } } else { /* * Build the default "path[type]" configuration */ int n; char *k; /* The first entry in the path list */ modpath[nmodpath].type = xstrdup("boot"); snprintf(tmpline, sizeof(tmpline), "%s/lib/modules/boot", base_dir); modpath[nmodpath].path = xstrdup(tmpline); ++nmodpath; /* The second entry in the path list, `uname -r` */ modpath[nmodpath].type = xstrdup("toplevel"); snprintf(tmpline, sizeof(tmpline), "%s/lib/modules/%s", base_dir, version); modpath[nmodpath].path = xstrdup(tmpline); ++nmodpath; /* The third entry in the path list, `kernelversion` */ modpath[nmodpath].type = xstrdup("toplevel"); for (n = 0, k = version; *k; ++k) { if (*k == '.' && ++n == 2) break; } snprintf(tmpline, sizeof(tmpline), "%s/lib/modules/%.*s", base_dir, (/* typecast for Alpha */ int)(k - version), version); modpath[nmodpath].path = xstrdup(tmpline); ++nmodpath; /* The rest of the entries in the path list */ for (pathp = tbpath; *pathp; ++pathp) { char **type; for (type = tbtype; *type; ++type) { char path[PATH_MAX]; snprintf(path, sizeof(path), "%s%s/%s", base_dir, *pathp, *type); if (meta_expand(path, &g, NULL, version, ME_ALL)) { ret = -1; goto out; } for (glb = g.pathv; glb && *glb; ++glb) { modpath[nmodpath].type = xstrdup(*type); modpath[nmodpath].path = *glb; if (++nmodpath >= maxpath) { maxpath += 100; modpath = (struct PATH_TYPE *)xrealloc(modpath, maxpath * sizeof(struct PATH_TYPE)); } } } } } /* Environment overrides for testing only, undocumented */ for (i = 0; i < gen_file_count; ++i) gen_file_env(gen_file+i); } /* End of depth == 0 */ if (conf_file || ((conf_file = getenv("MODULECONFIG")) != NULL && *conf_file && !safemode)) { if (!(fin = fopen(conf_file, "r"))) { error("Can't open %s", conf_file); ret = -1; goto out; } conf_file_specified = 1; } else { if (!(fin = fopen((conf_file = ETC_MODULES_CONF), "r"))) { /* Fall back to non-standard name */ if ((fin = fopen((conf_file = old_name), "r"))) { fprintf(stderr, "Warning: modutils is reading from %s because\n" " %s does not exist. The use of %s is\n" " deprecated, please rename %s to %s\n" " as soon as possible. Command\n" " mv %s %s\n", old_name, ETC_MODULES_CONF, old_name, old_name, ETC_MODULES_CONF, old_name, ETC_MODULES_CONF); } /* So what... use the default configuration */ } } if (fin) { struct stat statbuf1, statbuf2; if (fstat(fileno(fin), &statbuf1) == 0) config_mtime = statbuf1.st_mtime; config_file = xstrdup(conf_file); /* Save name actually used */ if (!conf_file_specified && stat(ETC_MODULES_CONF, &statbuf1) == 0 && stat(old_name, &statbuf2) == 0) { /* Both /etc files exist */ if (statbuf1.st_dev == statbuf2.st_dev && statbuf1.st_ino == statbuf2.st_ino) { if (lstat(ETC_MODULES_CONF, &statbuf1) == 0 && S_ISLNK(statbuf1.st_mode)) fprintf(stderr, "Warning: You do not need a link from %s to\n" " %s. The use of %s is deprecated,\n" " please remove %s and rename %s\n" " to %s as soon as possible. Commands.\n" " rm %s\n" " mv %s %s\n", ETC_MODULES_CONF, old_name, old_name, ETC_MODULES_CONF, old_name, ETC_MODULES_CONF, ETC_MODULES_CONF, old_name, ETC_MODULES_CONF); else { #ifndef NO_WARN_ON_OLD_LINK fprintf(stderr, "Warning: You do not need a link from %s to\n" " %s. The use of %s is deprecated,\n" " please remove %s as soon as possible. Command\n" " rm %s\n", old_name, ETC_MODULES_CONF, old_name, old_name, old_name); #endif } } else fprintf(stderr, "Warning: modutils is reading from %s and\n" " ignoring %s. The use of %s is deprecated,\n" " please remove %s as soon as possible. Command\n" " rm %s\n", ETC_MODULES_CONF, old_name, old_name, old_name, old_name); } } /* * Finally, decode the file */ while (fin && fgets_strip(&buf, &sizebuf, fin, &lineno) != NULL) { char *arg2; char *parm = buf; char *arg; int one_err = 0; int adding; while (isspace(*parm)) parm++; if (strncmp(parm, "add", 3) == 0) { adding = 1; parm += 3; while (isspace(*parm)) parm++; } else adding = 0; arg = parm; if (*parm == '\0') continue; one_err = 1; while (*arg > ' ' && *arg != '=') arg++; if (*arg == '=') assgn = 1; else assgn = 0; *arg++ = '\0'; while (isspace(*arg)) arg++; /* * endif */ if (!assgn && strcmp(parm, "endif") == 0) { if (level > 0) --level; else { error("unmatched endif in line %d", lineno); ret = -1; goto out; } continue; } /* * else */ if (!assgn && strcmp(parm, "else") == 0) { if (level <= 0) { error("else without if in line %d", lineno); ret = -1; goto out; } state[level] = !state[level]; continue; } /* * elseif */ if (!assgn && strcmp(parm, "elseif") == 0) { if (level <= 0) { error("elseif without if in line %d", lineno); ret = -1; goto out; } if (state[level] != 0) { /* * We have already found a TRUE * if statement in this "chain". * That's what "2" means. */ state[level] = 2; continue; } /* else: No TRUE if has been found, cheat */ /* * The "if" handling increments level, * but this is the _same_ level as before. * So, compensate for it. */ --level; parm = "if"; /* Fallthru to "if" */ } /* * if */ if (strcmp(parm, "if") == 0) { char *cmp; int not = 0; int numeric = 0; if (level >= MAX_LEVEL) { error("Too many nested if's in line %d\n", lineno); ret = -1; goto out; } state[++level] = 0; /* default false */ if (*arg == '!') { not = 1; arg = next_word(arg); } if (strncmp(arg, "-k", 2) == 0) { state[level] = flag_autoclean; continue; } if (strncmp(arg, "-f", 2) == 0) { char *file = next_word(arg); meta_expand(file, &g, NULL, version, ME_ALL); if (access(g.pathc ? g.pathv[0] : file, R_OK) == 0) state[level] = !not; else state[level] = not; continue; } if (strncmp(arg, "-n", 2) == 0) { numeric = 1; arg = next_word(arg); } cmp = next_word(arg); if (*cmp) { GLOB_LIST g2; long n1 = 0; long n2 = 0; char *w1 = ""; char *w2 = ""; arg2 = next_word(cmp); meta_expand(arg, &g, NULL, version, ME_ALL); if (g.pathc && g.pathv[0]) w1 = g.pathv[0]; meta_expand(arg2, &g2, NULL, version, ME_ALL); if (g2.pathc && g2.pathv[0]) w2 = g2.pathv[0]; if (numeric) { n1 = strtol(w1, NULL, 0); n2 = strtol(w2, NULL, 0); } if (strcmp(cmp, "==") == 0 || strcmp(cmp, "=") == 0) { if (numeric) state[level] = (n1 == n2); else state[level] = strcmp(w1, w2) == 0; } else if (strcmp(cmp, "!=") == 0) { if (numeric) state[level] = (n1 != n2); else state[level] = strcmp(w1, w2) != 0; } else if (strcmp(cmp, ">=") == 0) { if (numeric) state[level] = (n1 >= n2); else state[level] = strcmp(w1, w2) >= 0; } else if (strcmp(cmp, "<=") == 0) { if (numeric) state[level] = (n1 <= n2); else state[level] = strcmp(w1, w2) <= 0; } else if (strcmp(cmp, ">") == 0) { if (numeric) state[level] = (n1 > n2); else state[level] = strcmp(w1, w2) > 0; } else if (strcmp(cmp, "<") == 0) { if (numeric) state[level] = (n1 < n2); else state[level] = strcmp(w1, w2) < 0; } } else { /* Check defined value, if any */ /* undef or defined as * "" or "0" or "false" => false * defined => true */ if (!meta_expand(arg, &g, NULL, version, ME_ALL) && g.pathc > 0 && strcmp(g.pathv[0], "0") != 0 && strcmp(g.pathv[0], "false") != 0 && strlen(g.pathv[0]) != 0) state[level] = 1; /* true */ } if (not) state[level] = !state[level]; continue; } /* * Should we bother? */ if (state[level] != 1) continue; /* * define */ if (!assgn && strcmp(parm, "define") == 0) { char env[PATH_MAX]; arg2 = next_word(arg); meta_expand(arg2, &g, NULL, version, ME_ALL); snprintf(env, sizeof(env), "%s=%s", arg, (g.pathc ? g.pathv[0] : "")); putenv(xstrdup(env)); one_err = 0; } /* * include */ if (!assgn && strcmp(parm, "include") == 0) { int inc_idx = 0; while (*arg) { arg2=next_word(arg); meta_expand(arg, &g, NULL, version, ME_ALL); if (g.pathc>0) { for ( ; inc_idx<g.pathc; inc_idx++) { if (!do_read(all, version, base_dir, g.pathv[inc_idx], depth+1)) one_err = 0; else error("include %s failed\n", g.pathv[inc_idx]); } } else { if (!do_read(all, version, base_dir, g.pathc ? g.pathv[0] : arg, depth+1)) one_err = 0; else error("include %s failed\n", arg); } arg = arg2; } } /* * above */ else if (all && !assgn && strcmp(parm, "above") == 0) { decode_list(&n_abovelist, &abovelist, arg, adding, version, 0); one_err = 0; } /* * below */ else if (all && !assgn && strcmp(parm, "below") == 0) { decode_list(&n_belowlist, &belowlist, arg, adding, version, 0); one_err = 0; } /* * prune */ else if (!assgn && strcmp(parm, "prune") == 0) { decode_list(&n_prunelist, &prunelist, arg, adding, version, 0); one_err = 0; } /* * probe */ else if (all && !assgn && strcmp(parm, "probe") == 0) { decode_list(&n_probe_list, &probe_list, arg, adding, version, 0); one_err = 0; } /* * probeall */ else if (all && !assgn && strcmp(parm, "probeall") == 0) { decode_list(&n_probeall_list, &probeall_list, arg, adding, version, 0); one_err = 0; } /* * options */ else if (all && !assgn && strcmp(parm, "options") == 0) { decode_list(&n_opt_list, &opt_list, arg, adding, version, 1); one_err = 0; } /* * alias */ else if (all && !assgn && strcmp(parm, "alias") == 0) { /* * Replace any previous (default) definitions * for the same module */ decode_list(&n_aliases, &aliases, arg, 0, version, 0); one_err = 0; } /* * Specification: /etc/modules.conf * The format of the commands in /etc/modules.conf are: * * pre-install module command * install module command * post-install module command * pre-remove module command * remove module command * post-remove module command * * The different words are separated by tabs or spaces. */ /* * pre-install */ else if (all && !assgn && (strcmp(parm, "pre-install") == 0)) { decode_exec(arg, EXEC_PRE_INSTALL); one_err = 0; } /* * install */ else if (all && !assgn && (strcmp(parm, "install") == 0)) { decode_exec(arg, EXEC_INSTALL); one_err = 0; } /* * post-install */ else if (all && !assgn && (strcmp(parm, "post-install") == 0)) { decode_exec(arg, EXEC_POST_INSTALL); one_err = 0; } /* * pre-remove */ else if (all && !assgn && (strcmp(parm, "pre-remove") == 0)) { decode_exec(arg, EXEC_PRE_REMOVE); one_err = 0; } /* * remove */ else if (all && !assgn && (strcmp(parm, "remove") == 0)) { decode_exec(arg, EXEC_REMOVE); one_err = 0; } /* * post-remove */ else if (all && !assgn && (strcmp(parm, "post-remove") == 0)) { decode_exec(arg, EXEC_POST_REMOVE); one_err = 0; } /* * insmod_opt= */ else if (assgn && (strcmp(parm, "insmod_opt") == 0)) { insmod_opt = xstrdup(arg); one_err = 0; } /* * keep */ else if (!assgn && (strcmp(parm, "keep") == 0)) { drop_default_paths = 0; one_err = 0; } /* * path...= */ else if (assgn && strncmp(parm, "path", 4) == 0) { /* * Specification: config file / path parameter * The path parameter specifies a directory to * search for modules. * This parameter may be repeated multiple times. * * Note that the actual path may be defined using * wildcards and other shell meta-chars, such as "*?`". * For example: * path[misc]=/lib/modules/1.1.5?/misc * * Optionally the path keyword carries a tag. * This tells us a little more about the purpose of * this directory and allows some automated operations. * A path is marked with a tag by adding the tag, * enclosed in square brackets, to the path keyword: * # * path[boot]=/lib/modules/boot * # * This case identifies the path a of directory * holding modules loadable a boot time. */ if (drop_default_paths) { int n; /* * Specification: config file / path / default * * Whenever there is a path[] specification * in the config file, all the default * path are reset. * * If one instead wants to _add_ to the default * set of paths, one has to have the option * keep * before the first path[]-specification line * in the configuration file. */ drop_default_paths = 0; for (n = 0; n < nmodpath; n++) { free(modpath[n].path); free(modpath[n].type); } nmodpath = 0; } /* * Get (the optional) tag * If the tag is missing, the word "misc" * is assumed. */ type = "misc"; if (parm[4] == '[') { char *pt_type = parm + 5; while (*pt_type != '\0' && *pt_type != ']') pt_type++; if (*pt_type == ']' && pt_type[1] == '\0') { *pt_type = '\0'; type = parm + 5; } /* else CHECKME */ } /* * Handle the actual path description */ if (meta_expand(arg, &g, base_dir, version, ME_ALL)) { ret = -1; goto out; } for (glb = g.pathv; glb && *glb; ++glb) { modpath[nmodpath].type = xstrdup(type); modpath[nmodpath].path = *glb; if (++nmodpath >= maxpath) { maxpath += 100; modpath = (struct PATH_TYPE *)xrealloc(modpath, maxpath * sizeof(struct PATH_TYPE)); } } one_err = 0; } /* * persistdir */ else if (assgn && strcmp(parm, "persistdir") == 0) { meta_expand(arg, &g, NULL, version, ME_ALL); persistdir = xstrdup(g.pathc ? g.pathv[0] : arg); one_err = 0; } /* Names for generated files in config file */ for (i = 0; one_err && i < gen_file_count; ++i) one_err = gen_file_conf(gen_file+i, assgn, parm, arg); /* * any errors so far? */ if (all == 0) one_err = 0; else if (one_err) { error("Invalid line %d in %s\n\t%s", lineno, conf_file, buf); ret = -1; } } if (fin) fclose(fin); if (level) { error("missing endif at %s EOF", conf_file); ret = -1; } if (ret) goto out; /* else */ if (depth == 0) { /* Check we have names for generated files */ for (i = 0; !ret && i < gen_file_count; ++i) ret = gen_file_check(gen_file+i, &g, base_dir, version); } out: return ret; }