diff options
Diffstat (limited to 'usr/src/cmd')
116 files changed, 3874 insertions, 5049 deletions
diff --git a/usr/src/cmd/Makefile.cmd b/usr/src/cmd/Makefile.cmd index 791f10dbbd..4730cb6506 100644 --- a/usr/src/cmd/Makefile.cmd +++ b/usr/src/cmd/Makefile.cmd @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -208,7 +208,6 @@ ROOTSVCNETWORKSECURITY= $(ROOTSVCNETWORK)/security ROOTSVCNETWORKSSL= $(ROOTSVCNETWORK)/ssl ROOTSVCNETWORKSHARES= $(ROOTSVCNETWORK)/shares ROOTSVCPLATFORM= $(ROOTVARSVCMANIFEST)/platform -ROOTSVCPLATFORMI86PC= $(ROOTSVCPLATFORM)/i86pc ROOTSVCPLATFORMSUN4U= $(ROOTSVCPLATFORM)/sun4u ROOTSVCPLATFORMSUN4V= $(ROOTSVCPLATFORM)/sun4v ROOTSVCAPPLICATION= $(ROOTVARSVCMANIFEST)/application @@ -385,9 +384,6 @@ $(ROOTSVCAPPLICATIONPRINT)/%: % $(ROOTSVCPLATFORM)/%: % $(INS.file) -$(ROOTSVCPLATFORMI86PC)/%: % - $(INS.file) - $(ROOTSVCPLATFORMSUN4U)/%: % $(INS.file) diff --git a/usr/src/cmd/boot/Makefile b/usr/src/cmd/boot/Makefile index a1dcfd5a18..51b1ebf3d8 100644 --- a/usr/src/cmd/boot/Makefile +++ b/usr/src/cmd/boot/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -35,7 +35,8 @@ COMMON_SUBDIRS= \ i386_SUBDIRS= \ installgrub \ - mbr + mbr \ + symdef sparc_SUBDIRS= @@ -43,7 +44,8 @@ COMMON_LINTSUBDIRS= \ bootadm i386_LINTSUBDIRS= \ - installgrub + installgrub \ + symdef sparc_LINTSUBDIRS= diff --git a/usr/src/cmd/boot/bootadm/Makefile b/usr/src/cmd/boot/bootadm/Makefile index a71f5bf32a..fc4a370cef 100644 --- a/usr/src/cmd/boot/bootadm/Makefile +++ b/usr/src/cmd/boot/bootadm/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -31,7 +31,7 @@ i386_DATA= filelist.ramdisk filelist.safe SBINLINKS= $(PROG) -OBJS = bootadm.o +OBJS= bootadm.o bootadm_upgrade.o SRCS = $(OBJS:.o=.c) include ../Makefile.com @@ -52,9 +52,13 @@ LDLIBS += -lnvpair CFLAGS += $(XSTRCONST) CPPFLAGS += -D_FILE_OFFSET_BITS=64 +# Add paths to pick up headers +CFLAGS += -I../../../uts/common +LINTFLAGS += -I../../../uts/common + all: $(PROG) -$(PROG): $(OBJS) +$(PROG): $(OBJS) bootadm.h $(LINK.c) -o $@ $(OBJS) $(LDLIBS) $(POST_PROCESS) @@ -64,9 +68,10 @@ $(ROOTUSRSBINLINKS): install: all $(ROOTSBINPROG) $(ROOTBOOTSOLARISDATA) .WAIT $(ROOTUSRSBINLINKS) clean: + -$(RM) $(OBJS) _msg: -lint: lint_PROG +lint: lint_SRCS include ../Makefile.targ diff --git a/usr/src/cmd/boot/bootadm/bootadm.c b/usr/src/cmd/boot/bootadm/bootadm.c index 80c2b75592..2475aba1d3 100644 --- a/usr/src/cmd/boot/bootadm/bootadm.c +++ b/usr/src/cmd/boot/bootadm/bootadm.c @@ -58,12 +58,12 @@ #include <grp.h> #include <device_info.h> -#include <libintl.h> #include <locale.h> #include <assert.h> #include "message.h" +#include "bootadm.h" #ifndef TEXT_DOMAIN #define TEXT_DOMAIN "SUNW_OST_OSCMD" @@ -77,56 +77,12 @@ typedef enum { BAM_ARCHIVE } subcmd_t; -/* GRUB menu per-line classification */ -typedef enum { - BAM_INVALID = 0, - BAM_EMPTY, - BAM_COMMENT, - BAM_GLOBAL, - BAM_ENTRY, - BAM_TITLE -} menu_flag_t; - -/* struct for menu.lst contents */ -typedef struct line { - int lineNum; /* Line number in menu.lst */ - int entryNum; /* menu boot entry #. ENTRY_INIT if not applicable */ - char *cmd; - char *sep; - char *arg; - char *line; - menu_flag_t flags; - struct line *next; - struct line *prev; -} line_t; - -typedef struct entry { - struct entry *next; - struct entry *prev; - line_t *start; - line_t *end; -} entry_t; - -typedef struct { - line_t *start; - line_t *end; - line_t *curdefault; /* line containing default */ - line_t *olddefault; /* old default line (commented) */ - entry_t *entries; /* os entries */ -} menu_t; - typedef enum { OPT_ABSENT = 0, /* No option */ OPT_REQ, /* option required */ OPT_OPTIONAL /* option may or may not be present */ } option_t; -typedef enum { - BAM_ERROR = -1, /* Must be negative. add_boot_entry() depends on it */ - BAM_SUCCESS = 0, - BAM_WRITE = 2 -} error_t; - typedef struct { char *subcmd; option_t option; @@ -134,16 +90,11 @@ typedef struct { int unpriv; /* is this an unprivileged command */ } subcmd_defn_t; - -#define BAM_MAXLINE 8192 - #define LINE_INIT 0 /* lineNum initial value */ #define ENTRY_INIT -1 /* entryNum initial value */ #define ALL_ENTRIES -2 /* selects all boot entries */ #define GRUB_DIR "/boot/grub" -#define MULTI_BOOT "/platform/i86pc/multiboot" -#define BOOT_ARCHIVE "/platform/i86pc/boot_archive" #define GRUB_MENU "/boot/grub/menu.lst" #define MENU_TMP "/boot/grub/menu.lst.tmp" #define RAMDISK_SPECIAL "/ramdisk" @@ -180,26 +131,19 @@ typedef struct { * Menu related * menu_cmd_t and menu_cmds must be kept in sync */ -typedef enum { - DEFAULT_CMD = 0, - TIMEOUT_CMD, - TITLE_CMD, - ROOT_CMD, - KERNEL_CMD, - MODULE_CMD, - SEP_CMD, - COMMENT_CMD -} menu_cmd_t; - -static char *menu_cmds[] = { +char *menu_cmds[] = { "default", /* DEFAULT_CMD */ "timeout", /* TIMEOUT_CMD */ "title", /* TITLE_CMD */ "root", /* ROOT_CMD */ "kernel", /* KERNEL_CMD */ + "kernel$", /* KERNEL_DOLLAR_CMD */ "module", /* MODULE_CMD */ + "module$", /* MODULE_DOLLAR_CMD */ " ", /* SEP_CMD */ "#", /* COMMENT_CMD */ + "chainloader", /* CHAINLOADER_CMD */ + "args", /* ARGS_CMD */ NULL }; @@ -221,11 +165,9 @@ typedef struct { #define DIR_PERMS (S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) #define FILE_STAT_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) -#define BAM_HDR "---------- ADDED BY BOOTADM - DO NOT EDIT ----------" -#define BAM_FTR "---------------------END BOOTADM--------------------" -#define BAM_OLDDEF "BOOTADM SAVED DEFAULT: " - /* Globals */ +int bam_verbose; +int bam_force; static char *prog; static subcmd_t bam_cmd; static char *bam_root; @@ -237,8 +179,6 @@ static char *bam_opt; static int bam_debug; static char **bam_argv; static int bam_argc; -static int bam_force; -static int bam_verbose; static int bam_check; static int bam_smf_check; static int bam_lock_fd = -1; @@ -251,7 +191,6 @@ static void parse_args(int argc, char *argv[]); static error_t bam_menu(char *subcmd, char *opt, int argc, char *argv[]); static error_t bam_archive(char *subcmd, char *opt); -static void bam_error(char *format, ...); static void bam_print(char *format, ...); static void bam_exit(int excode); static void bam_lock(void); @@ -280,12 +219,13 @@ static error_t update_all(char *root, char *opt); static error_t read_list(char *root, filelist_t *flistp); static error_t set_global(menu_t *mp, char *globalcmd, int val); static error_t set_option(menu_t *mp, char *globalcmd, char *opt); +static error_t set_kernel(menu_t *mp, menu_cmd_t optnum, char *path, + char *buf, size_t bufsize); +static char *expand_path(const char *partial_path); static long s_strtol(char *str); -static char *s_fgets(char *buf, int n, FILE *fp); static int s_fputs(char *str, FILE *fp); -static void *s_calloc(size_t nelem, size_t sz); static char *s_strdup(char *str); static int is_readonly(char *); static int is_amd64(void); @@ -302,6 +242,7 @@ static subcmd_defn_t menu_subcmds[] = { "delete_all_entries", OPT_ABSENT, delete_all_entries, 0, /* PVT */ "update_entry", OPT_REQ, update_entry, 0, /* menu */ "update_temp", OPT_OPTIONAL, update_temp, 0, /* reboot */ + "upgrade", OPT_ABSENT, upgrade_menu, 0, /* menu */ NULL, 0, NULL, 0 /* must be last */ }; @@ -325,7 +266,7 @@ struct safefile { struct safefile *next; }; -struct safefile *safefiles = NULL; +static struct safefile *safefiles = NULL; #define NEED_UPDATE_FILE "/etc/svc/volatile/boot_archive_needs_update" static void @@ -487,7 +428,7 @@ parse_args_internal(int argc, char *argv[]) opterr = 0; error = 0; - while ((c = getopt(argc, argv, "a:d:fm:no:vCR:")) != -1) { + while ((c = getopt(argc, argv, "a:d:fm:no:vCR:xX")) != -1) { switch (c) { case 'a': if (bam_cmd) { @@ -942,6 +883,7 @@ bam_menu(char *subcmd, char *opt, int largc, char *largv[]) { error_t ret; char menu_path[PATH_MAX]; + char path[PATH_MAX]; menu_t *menu; char *mntpt, *menu_root, *logslice, *fstype; struct stat sb; @@ -961,17 +903,26 @@ bam_menu(char *subcmd, char *opt, int largc, char *largv[]) logslice = fstype = NULL; /* - * If the user provides an alternate root, we - * assume they know what they are doing and we - * use it. Else we check if there is an - * alternate location (other than /boot/grub) - * for the GRUB menu + * Check for the menu.list file: + * + * 1. Check for a GRUB_slice file, be it on / or + * on the user-provided alternate root. + * 2. Use the alternate root, if given. + * 3. Check /stubboot + * 4. Use / */ if (bam_alt_root) { - menu_root = bam_root; - } else if (stat(GRUB_slice, &sb) == 0) { + (void) snprintf(path, sizeof (path), "%s%s", bam_root, + GRUB_slice); + } else { + (void) snprintf(path, sizeof (path), "%s", GRUB_slice); + } + + if (stat(path, &sb) == 0) { mntpt = mount_grub_slice(&mnted, NULL, &logslice, &fstype); menu_root = mntpt; + } else if (bam_alt_root) { + menu_root = bam_root; } else if (stat(STUBBOOT, &sb) == 0) { menu_root = use_stubboot(); } else { @@ -1015,11 +966,16 @@ bam_menu(char *subcmd, char *opt, int largc, char *largv[]) return (BAM_ERROR); } + ret = dboot_or_multiboot(bam_root); + if (ret != BAM_SUCCESS) + return (ret); + /* * Once the sub-cmd handler has run * only the line field is guaranteed to have valid values */ - if (strcmp(subcmd, "update_entry") == 0) + if ((strcmp(subcmd, "update_entry") == 0) || + (strcmp(subcmd, "upgrade") == 0)) ret = f(menu, bam_root, opt); else ret = f(menu, menu_path, opt); @@ -1068,6 +1024,10 @@ bam_archive( sparc_abort(); #endif + ret = dboot_or_multiboot(rootbuf); + if (ret != BAM_SUCCESS) + return (ret); + /* * Check archive not supported with update_all * since it is awkward to display out-of-sync @@ -1089,7 +1049,7 @@ bam_archive( } /*PRINTFLIKE1*/ -static void +void bam_error(char *format, ...) { va_list ap; @@ -1111,6 +1071,17 @@ bam_print(char *format, ...) va_end(ap); } +/*PRINTFLIKE1*/ +void +bam_print_stderr(char *format, ...) +{ + va_list ap; + + va_start(ap, format); + (void) vfprintf(stderr, format, ap); + va_end(ap); +} + static void bam_exit(int excode) { @@ -1501,13 +1472,24 @@ check_flags_and_files(char *root) /* * If archive is missing, create archive */ - (void) snprintf(path, sizeof (path), "%s%s", root, BOOT_ARCHIVE); + (void) snprintf(path, sizeof (path), "%s%s", root, + DIRECT_BOOT_ARCHIVE_32); if (stat(path, &sb) != 0) { if (bam_verbose && !bam_check) bam_print(UPDATE_ARCH_MISS, path); walk_arg.need_update = 1; return; } + if (bam_direct == BAM_DIRECT_DBOOT) { + (void) snprintf(path, sizeof (path), "%s%s", root, + DIRECT_BOOT_ARCHIVE_64); + if (stat(path, &sb) != 0) { + if (bam_verbose && !bam_check) + bam_print(UPDATE_ARCH_MISS, path); + walk_arg.need_update = 1; + return; + } + } } static error_t @@ -1891,11 +1873,20 @@ create_ramdisk(char *root) /* * Verify that the archive has been created */ - (void) snprintf(path, sizeof (path), "%s%s", root, BOOT_ARCHIVE); + (void) snprintf(path, sizeof (path), "%s%s", root, + DIRECT_BOOT_ARCHIVE_32); if (stat(path, &sb) != 0) { bam_error(ARCHIVE_NOT_CREATED, path); return (BAM_ERROR); } + if (bam_direct == BAM_DIRECT_DBOOT) { + (void) snprintf(path, sizeof (path), "%s%s", root, + DIRECT_BOOT_ARCHIVE_64); + if (stat(path, &sb) != 0) { + bam_error(ARCHIVE_NOT_CREATED, path); + return (BAM_ERROR); + } + } return (BAM_SUCCESS); } @@ -2248,7 +2239,13 @@ update_all(char *root, char *opt) (void) snprintf(rootbuf, sizeof (rootbuf), "%s/", mnt.mnt_mountp); bam_rootlen = strlen(rootbuf); - if (update_archive(rootbuf, opt) != BAM_SUCCESS) + + /* + * It's possible that other mounts may be an alternate boot + * architecture, so check it again. + */ + if ((dboot_or_multiboot(rootbuf) != BAM_SUCCESS) || + (update_archive(rootbuf, opt) != BAM_SUCCESS)) ret = BAM_ERROR; } @@ -2352,6 +2349,7 @@ line_parser(menu_t *mp, char *str, int *lineNum, int *entryNum) */ static line_t *prev = NULL; static entry_t *curr_ent = NULL; + static int in_liveupgrade = 0; line_t *lp; char *cmd, *sep, *arg; @@ -2377,6 +2375,11 @@ line_parser(menu_t *mp, char *str, int *lineNum, int *entryNum) sep = NULL; arg = s_strdup(str + 1); flag = BAM_COMMENT; + if (strstr(arg, BAM_LU_HDR) != NULL) { + in_liveupgrade = 1; + } else if (strstr(arg, BAM_LU_FTR) != NULL) { + in_liveupgrade = 0; + } } else if (*str == '\0') { /* blank line */ cmd = sep = arg = NULL; flag = BAM_EMPTY; @@ -2429,12 +2432,17 @@ line_parser(menu_t *mp, char *str, int *lineNum, int *entryNum) lp->entryNum = ++(*entryNum); lp->flags = BAM_TITLE; if (prev && prev->flags == BAM_COMMENT && - prev->arg && strcmp(prev->arg, BAM_HDR) == 0) { + prev->arg && strcmp(prev->arg, BAM_BOOTADM_HDR) == 0) { prev->entryNum = lp->entryNum; curr_ent = boot_entry_new(mp, prev, lp); + curr_ent->flags = BAM_ENTRY_BOOTADM; } else { curr_ent = boot_entry_new(mp, lp, lp); + if (in_liveupgrade) { + curr_ent->flags = BAM_ENTRY_LU; + } } + curr_ent->entryNum = *entryNum; } else if (flag != BAM_INVALID) { /* * For header comments, the entry# is "fixed up" @@ -2444,7 +2452,29 @@ line_parser(menu_t *mp, char *str, int *lineNum, int *entryNum) lp->flags = flag; } else { lp->entryNum = *entryNum; - lp->flags = (*entryNum == ENTRY_INIT) ? BAM_GLOBAL : BAM_ENTRY; + + if (*entryNum == ENTRY_INIT) { + lp->flags = BAM_GLOBAL; + } else { + lp->flags = BAM_ENTRY; + + if (cmd && arg) { + /* + * We only compare for the length of "module" + * so that "module$" will also match. + */ + if ((strncmp(cmd, menu_cmds[MODULE_CMD], + strlen(menu_cmds[MODULE_CMD])) == 0) && + (strcmp(arg, MINIROOT) == 0)) + curr_ent->flags |= BAM_ENTRY_MINIROOT; + else if (strcmp(cmd, menu_cmds[ROOT_CMD]) == 0) + curr_ent->flags |= BAM_ENTRY_ROOT; + else if (strcmp(cmd, + menu_cmds[CHAINLOADER_CMD]) == 0) + curr_ent->flags |= + BAM_ENTRY_CHAINLOADER; + } + } } /* record default, old default, and entry line ranges */ @@ -2454,8 +2484,12 @@ line_parser(menu_t *mp, char *str, int *lineNum, int *entryNum) } else if (lp->flags == BAM_COMMENT && strncmp(lp->arg, BAM_OLDDEF, strlen(BAM_OLDDEF)) == 0) { mp->olddefault = lp; + } else if (lp->flags == BAM_COMMENT && + strncmp(lp->arg, BAM_OLD_RC_DEF, strlen(BAM_OLD_RC_DEF)) == 0) { + mp->old_rc_default = lp; } else if (lp->flags == BAM_ENTRY || - (lp->flags == BAM_COMMENT && strcmp(lp->arg, BAM_FTR) == 0)) { + (lp->flags == BAM_COMMENT && + strcmp(lp->arg, BAM_BOOTADM_FTR) == 0)) { boot_entry_addline(curr_ent, lp); } append_line(mp, lp); @@ -2522,7 +2556,8 @@ update_numbering(menu_t *mp) lp->entryNum = ++entryNum; /* fixup the bootadm header */ if (prev && prev->flags == BAM_COMMENT && - prev->arg && strcmp(prev->arg, BAM_HDR) == 0) { + prev->arg && + strcmp(prev->arg, BAM_BOOTADM_HDR) == 0) { prev->entryNum = lp->entryNum; } } else { @@ -2727,6 +2762,7 @@ add_boot_entry(menu_t *mp, { int lineNum, entryNum; char linebuf[BAM_MAXLINE]; + menu_cmd_t k_cmd, m_cmd; assert(mp); @@ -2738,8 +2774,36 @@ add_boot_entry(menu_t *mp, return (BAM_ERROR); } if (module == NULL) { - bam_error(SUBOPT_MISS, menu_cmds[MODULE_CMD]); - return (BAM_ERROR); + if (bam_direct != BAM_DIRECT_DBOOT) { + bam_error(SUBOPT_MISS, menu_cmds[MODULE_CMD]); + return (BAM_ERROR); + } + + /* Figure the commands out from the kernel line */ + if (strstr(kernel, "$ISADIR") != NULL) { + module = DIRECT_BOOT_ARCHIVE; + k_cmd = KERNEL_DOLLAR_CMD; + m_cmd = MODULE_DOLLAR_CMD; + } else if (strstr(kernel, "amd64") != NULL) { + module = DIRECT_BOOT_ARCHIVE_64; + k_cmd = KERNEL_CMD; + m_cmd = MODULE_CMD; + } else { + module = DIRECT_BOOT_ARCHIVE_32; + k_cmd = KERNEL_CMD; + m_cmd = MODULE_CMD; + } + } else if ((bam_direct == BAM_DIRECT_DBOOT) && + (strstr(kernel, "$ISADIR") != NULL)) { + /* + * If it's a non-failsafe dboot kernel, use the "kernel$" + * command. Otherwise, use "kernel". + */ + k_cmd = KERNEL_DOLLAR_CMD; + m_cmd = MODULE_DOLLAR_CMD; + } else { + k_cmd = KERNEL_CMD; + m_cmd = MODULE_CMD; } if (mp->start) { @@ -2755,7 +2819,7 @@ add_boot_entry(menu_t *mp, * The syntax for comments is #<comment> */ (void) snprintf(linebuf, sizeof (linebuf), "%s%s", - menu_cmds[COMMENT_CMD], BAM_HDR); + menu_cmds[COMMENT_CMD], BAM_BOOTADM_HDR); line_parser(mp, linebuf, &lineNum, &entryNum); (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s", @@ -2769,15 +2833,15 @@ add_boot_entry(menu_t *mp, } (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s", - menu_cmds[KERNEL_CMD], menu_cmds[SEP_CMD], kernel); + menu_cmds[k_cmd], menu_cmds[SEP_CMD], kernel); line_parser(mp, linebuf, &lineNum, &entryNum); (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s", - menu_cmds[MODULE_CMD], menu_cmds[SEP_CMD], module); + menu_cmds[m_cmd], menu_cmds[SEP_CMD], module); line_parser(mp, linebuf, &lineNum, &entryNum); (void) snprintf(linebuf, sizeof (linebuf), "%s%s", - menu_cmds[COMMENT_CMD], BAM_FTR); + menu_cmds[COMMENT_CMD], BAM_BOOTADM_FTR); line_parser(mp, linebuf, &lineNum, &entryNum); return (entryNum); @@ -2797,7 +2861,7 @@ do_delete(menu_t *mp, int entryNum) lp = ent->start; /* check entry number and make sure it's a bootadm entry */ if (lp->flags != BAM_COMMENT || - strcmp(lp->arg, BAM_HDR) != 0 || + strcmp(lp->arg, BAM_BOOTADM_HDR) != 0 || (entryNum != ALL_ENTRIES && lp->entryNum != entryNum)) { ent = ent->next; continue; @@ -3003,7 +3067,7 @@ get_title(char *rootdir) return (cp == NULL ? "Solaris" : cp); } -static char * +char * get_special(char *mountp) { FILE *mntfp; @@ -3027,7 +3091,7 @@ get_special(char *mountp) return (s_strdup(mp.mnt_special)); } -static char * +char * os_to_grubdisk(char *osdisk, int on_bootdev) { FILE *fp; @@ -3092,7 +3156,8 @@ find_boot_entry(menu_t *mp, char *title, char *root, char *module, /* first line of entry must be bootadm comment */ lp = ent->start; - if (lp->flags != BAM_COMMENT || strcmp(lp->arg, BAM_HDR) != 0) { + if (lp->flags != BAM_COMMENT || + strcmp(lp->arg, BAM_BOOTADM_HDR) != 0) { continue; } @@ -3125,8 +3190,9 @@ find_boot_entry(menu_t *mp, char *title, char *root, char *module, /* check for matching module entry (failsafe or normal) */ lp = lp->next; /* advance to module line */ - if (strcmp(lp->cmd, menu_cmds[MODULE_CMD]) != 0 || - strcmp(lp->arg, module) != 0) { + if ((strncmp(lp->cmd, menu_cmds[MODULE_CMD], + strlen(menu_cmds[MODULE_CMD])) != 0) || + (strcmp(lp->arg, module) != 0)) { continue; } break; /* match found */ @@ -3140,13 +3206,24 @@ static int update_boot_entry(menu_t *mp, char *title, char *root, char *kernel, char *module, int root_opt) { - int i; + int i, change_kernel = 0; entry_t *ent; line_t *lp; char linebuf[BAM_MAXLINE]; /* note: don't match on title, it's updated on upgrade */ ent = find_boot_entry(mp, NULL, root, module, root_opt, &i); + if ((ent == NULL) && (bam_direct == BAM_DIRECT_DBOOT)) { + /* + * We may be upgrading a kernel from multiboot to + * directboot. Look for a multiboot entry. + */ + ent = find_boot_entry(mp, NULL, root, MULTI_BOOT_ARCHIVE, + root_opt, &i); + if (ent != NULL) { + change_kernel = 1; + } + } if (ent == NULL) return (add_boot_entry(mp, title, root_opt ? NULL : root, kernel, module)); @@ -3171,6 +3248,32 @@ update_boot_entry(menu_t *mp, char *title, char *root, char *kernel, } else lp = lp->next; } + + if (change_kernel) { + /* + * We're upgrading from multiboot to directboot. + */ + if (strcmp(lp->cmd, menu_cmds[KERNEL_CMD]) == 0) { + (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s", + menu_cmds[KERNEL_DOLLAR_CMD], menu_cmds[SEP_CMD], + kernel); + free(lp->arg); + free(lp->line); + lp->arg = s_strdup(kernel); + lp->line = s_strdup(linebuf); + lp = lp->next; + } + if (strcmp(lp->cmd, menu_cmds[MODULE_CMD]) == 0) { + (void) snprintf(linebuf, sizeof (linebuf), "%s%s%s", + menu_cmds[MODULE_DOLLAR_CMD], menu_cmds[SEP_CMD], + module); + free(lp->arg); + free(lp->line); + lp->arg = s_strdup(module); + lp->line = s_strdup(linebuf); + lp = lp->next; + } + } return (i); } @@ -3207,19 +3310,24 @@ update_entry(menu_t *mp, char *menu_root, char *opt) } /* add the entry for normal Solaris */ - entry = update_boot_entry(mp, title, grubdisk, - "/platform/i86pc/multiboot", - "/platform/i86pc/boot_archive", - osroot == menu_root); + if (bam_direct == BAM_DIRECT_DBOOT) { + entry = update_boot_entry(mp, title, grubdisk, + DIRECT_BOOT_KERNEL, DIRECT_BOOT_ARCHIVE, + osroot == menu_root); + } else { + entry = update_boot_entry(mp, title, grubdisk, + MULTI_BOOT, MULTI_BOOT_ARCHIVE, + osroot == menu_root); + } /* add the entry for failsafe archive */ - (void) snprintf(failsafe, sizeof (failsafe), - "%s/boot/x86.miniroot-safe", osroot); - if (stat(failsafe, &sbuf) == 0) - (void) update_boot_entry(mp, "Solaris failsafe", grubdisk, - "/boot/multiboot kernel/unix -s", - "/boot/x86.miniroot-safe", - osroot == menu_root); + (void) snprintf(failsafe, sizeof (failsafe), "%s%s", osroot, MINIROOT); + if (stat(failsafe, &sbuf) == 0) { + (void) update_boot_entry(mp, FAILSAFE_TITLE, grubdisk, + (bam_direct == BAM_DIRECT_DBOOT) ? + DIRECT_BOOT_FAILSAFE_LINE : MULTI_BOOT_FAILSAFE_LINE, + MINIROOT, osroot == menu_root); + } free(grubdisk); if (entry == BAM_ERROR) { @@ -3276,7 +3384,7 @@ read_grub_root(void) } static void -save_default_entry(menu_t *mp) +save_default_entry(menu_t *mp, const char *which) { int lineNum, entryNum; int entry = 0; /* default is 0 */ @@ -3294,26 +3402,24 @@ save_default_entry(menu_t *mp) if (lp) entry = s_strtol(lp->arg); - (void) snprintf(linebuf, sizeof (linebuf), "#%s%d", BAM_OLDDEF, entry); + (void) snprintf(linebuf, sizeof (linebuf), "#%s%d", which, entry); line_parser(mp, linebuf, &lineNum, &entryNum); } static void -restore_default_entry(menu_t *mp) +restore_default_entry(menu_t *mp, const char *which, line_t *lp) { int entry; char *str; - line_t *lp = mp->olddefault; if (lp == NULL) return; /* nothing to restore */ - str = lp->arg + strlen(BAM_OLDDEF); + str = lp->arg + strlen(which); entry = s_strtol(str); (void) set_global(mp, menu_cmds[DEFAULT_CMD], entry); /* delete saved old default line */ - mp->olddefault = NULL; unlink_line(mp, lp); line_free(lp); } @@ -3333,8 +3439,9 @@ static error_t update_temp(menu_t *mp, char *menupath, char *opt) { int entry; - char *grubdisk, *rootdev; - char kernbuf[1024]; + char *grubdisk, *rootdev, *path; + char kernbuf[BUFSIZ]; + char args_buf[BUFSIZ]; struct stat sb; assert(mp); @@ -3346,7 +3453,8 @@ update_temp(menu_t *mp, char *menupath, char *opt) if (ent == NULL) /* not found is ok */ return (BAM_SUCCESS); (void) do_delete(mp, entry); - restore_default_entry(mp); + restore_default_entry(mp, BAM_OLDDEF, mp->olddefault); + mp->olddefault = NULL; return (BAM_WRITE); } @@ -3385,10 +3493,47 @@ update_temp(menu_t *mp, char *menupath, char *opt) } /* add an entry for Solaris reboot */ - (void) snprintf(kernbuf, sizeof (kernbuf), - "/platform/i86pc/multiboot %s", opt); - entry = add_boot_entry(mp, REBOOT_TITLE, grubdisk, kernbuf, - "/platform/i86pc/boot_archive"); + if (bam_direct == BAM_DIRECT_DBOOT) { + if (opt[0] == '-') { + /* It's an option - first see if boot-file is set */ + if (set_kernel(mp, KERNEL_CMD, NULL, kernbuf, BUFSIZ) + != BAM_SUCCESS) + return (BAM_ERROR); + if (kernbuf[0] == '\0') + (void) strncpy(kernbuf, DIRECT_BOOT_KERNEL, + BUFSIZ); + (void) strlcat(kernbuf, " ", BUFSIZ); + (void) strlcat(kernbuf, opt, BUFSIZ); + } else if (opt[0] == '/') { + /* It's a full path - write it out and go home */ + (void) strlcpy(kernbuf, opt, BUFSIZ); + } else { + path = expand_path(opt); + if (path != NULL) { + (void) strlcpy(kernbuf, path, BUFSIZ); + free(path); + if (strcmp(opt, "kmdb") == 0) { + if (set_kernel(mp, ARGS_CMD, NULL, + args_buf, BUFSIZ) != BAM_SUCCESS) + return (BAM_ERROR); + + if (args_buf[0] != '\0') { + (void) strlcat(kernbuf, " ", + BUFSIZ); + (void) strlcat(kernbuf, + args_buf, BUFSIZ); + } + } + } + } + entry = add_boot_entry(mp, REBOOT_TITLE, grubdisk, kernbuf, + NULL); + } else { + (void) snprintf(kernbuf, sizeof (kernbuf), "%s %s", + MULTI_BOOT, opt); + entry = add_boot_entry(mp, REBOOT_TITLE, grubdisk, kernbuf, + MULTI_BOOT_ARCHIVE); + } free(grubdisk); if (entry == BAM_ERROR) { @@ -3396,7 +3541,7 @@ update_temp(menu_t *mp, char *menupath, char *opt) return (BAM_ERROR); } - save_default_entry(mp); + save_default_entry(mp, BAM_OLDDEF); (void) set_global(mp, menu_cmds[DEFAULT_CMD], entry); return (BAM_WRITE); } @@ -3482,35 +3627,418 @@ set_global(menu_t *mp, char *globalcmd, int val) return (BAM_WRITE); /* need a write to menu */ } +/* + * partial_path may be anything like "kernel/unix" or "kmdb". Try to + * expand it to a full unix path. + */ +static char * +expand_path(const char *partial_path) +{ + int new_path_len; + char *new_path, new_path2[PATH_MAX]; + struct stat sb; + + new_path_len = strlen(partial_path) + 64; + new_path = s_calloc(1, new_path_len); + + /* First, try the simplest case - something like "kernel/unix" */ + (void) snprintf(new_path, new_path_len, "/platform/i86pc/%s", + partial_path); + if (stat(new_path, &sb) == 0) { + return (new_path); + } + + if (strcmp(partial_path, "kmdb") == 0) { + (void) snprintf(new_path, new_path_len, "%s -k", + DIRECT_BOOT_KERNEL); + return (new_path); + } + + /* + * We've quickly reached unsupported usage. Try once more to + * see if we were just given a glom name. + */ + (void) snprintf(new_path, new_path_len, "/platform/i86pc/%s/unix", + partial_path); + (void) snprintf(new_path2, PATH_MAX, "/platform/i86pc/%s/amd64/unix", + partial_path); + if (stat(new_path, &sb) == 0) { + if (stat(new_path2, &sb) == 0) { + /* + * We matched both, so we actually + * want to write the $ISADIR version. + */ + (void) snprintf(new_path, new_path_len, + "/platform/i86pc/kernel/%s/$ISADIR/unix", + partial_path); + } + return (new_path); + } + + bam_error(UNKNOWN_KERNEL, partial_path); + free(new_path); + return (NULL); +} + +/* + * The kernel cmd and arg have been changed, so + * check whether the archive line needs to change. + */ +static void +set_archive_line(entry_t *entryp, line_t *kernelp) +{ + line_t *lp = entryp->start; + char *new_archive; + menu_cmd_t m_cmd; + + for (; lp != NULL; lp = lp->next) { + if (strncmp(lp->cmd, menu_cmds[MODULE_CMD], + sizeof (menu_cmds[MODULE_CMD]) - 1) == 0) { + break; + } + if (lp == entryp->end) + return; + } + if (lp == NULL) + return; + + if (strstr(kernelp->arg, "$ISADIR") != NULL) { + new_archive = DIRECT_BOOT_ARCHIVE; + m_cmd = MODULE_DOLLAR_CMD; + } else if (strstr(kernelp->arg, "amd64") != NULL) { + new_archive = DIRECT_BOOT_ARCHIVE_64; + m_cmd = MODULE_CMD; + } else { + new_archive = DIRECT_BOOT_ARCHIVE_32; + m_cmd = MODULE_CMD; + } + + if (strcmp(lp->arg, new_archive) == 0) + return; + + if (strcmp(lp->cmd, menu_cmds[m_cmd]) != 0) { + free(lp->cmd); + lp->cmd = s_strdup(menu_cmds[m_cmd]); + } + + free(lp->arg); + lp->arg = s_strdup(new_archive); + update_line(lp); +} + +/* + * Title for an entry to set properties that once went in bootenv.rc. + */ +#define BOOTENV_RC_TITLE "Solaris bootenv rc" + +/* + * If path is NULL, return the kernel (optnum == KERNEL_CMD) or arguments + * (optnum == ARGS_CMD) in the argument buf. If path is a zero-length + * string, reset the value to the default. If path is a non-zero-length + * string, set the kernel or arguments. + */ +static error_t +set_kernel(menu_t *mp, menu_cmd_t optnum, char *path, char *buf, size_t bufsize) +{ + int entryNum, rv = BAM_SUCCESS, free_new_path = 0; + entry_t *entryp; + line_t *ptr, *kernelp; + char *new_arg, *old_args, *space; + char *grubdisk, *rootdev, *new_path; + char old_space; + size_t old_kernel_len, new_str_len; + struct stat sb; + + assert(bufsize > 0); + + ptr = kernelp = NULL; + new_arg = old_args = space = NULL; + grubdisk = rootdev = new_path = NULL; + buf[0] = '\0'; + + if (bam_direct != BAM_DIRECT_DBOOT) { + bam_error(NOT_DBOOT, optnum == KERNEL_CMD ? "kernel" : "args"); + return (BAM_ERROR); + } + + /* + * If a user changed the default entry to a non-bootadm controlled + * one, we don't want to mess with it. Just print an error and + * return. + */ + if (mp->curdefault) { + entryNum = s_strtol(mp->curdefault->arg); + for (entryp = mp->entries; entryp; entryp = entryp->next) { + if (entryp->entryNum == entryNum) + break; + } + if ((entryp != NULL) && + ((entryp->flags & (BAM_ENTRY_BOOTADM|BAM_ENTRY_LU)) == 0)) { + bam_error(DEFAULT_NOT_BAM); + return (BAM_ERROR); + } + } + + entryNum = -1; + entryp = find_boot_entry(mp, BOOTENV_RC_TITLE, NULL, NULL, 0, + &entryNum); + + if (entryp != NULL) { + for (ptr = entryp->start; ptr && ptr != entryp->end; + ptr = ptr->next) { + if (strncmp(ptr->cmd, menu_cmds[KERNEL_CMD], + sizeof (menu_cmds[KERNEL_CMD]) - 1) == 0) { + kernelp = ptr; + break; + } + } + if (kernelp == NULL) { + bam_error(NO_KERNEL, entryNum); + return (BAM_ERROR); + } + + old_kernel_len = strcspn(kernelp->arg, " \t"); + space = old_args = kernelp->arg + old_kernel_len; + while ((*old_args == ' ') || (*old_args == '\t')) + old_args++; + } + + if (path == NULL) { + /* Simply report what was found */ + if (kernelp == NULL) + return (BAM_SUCCESS); + + if (optnum == ARGS_CMD) { + if (old_args[0] != '\0') + (void) strlcpy(buf, old_args, bufsize); + } else { + /* + * We need to print the kernel, so we just turn the + * first space into a '\0' and print the beginning. + * We don't print anything if it's the default kernel. + */ + old_space = *space; + *space = '\0'; + if (strcmp(kernelp->arg, DIRECT_BOOT_KERNEL) != 0) + (void) strlcpy(buf, kernelp->arg, bufsize); + *space = old_space; + } + return (BAM_SUCCESS); + } + + /* + * First, check if we're resetting an entry to the default. + */ + if ((path[0] == '\0') || + ((optnum == KERNEL_CMD) && + (strcmp(path, DIRECT_BOOT_KERNEL) == 0))) { + if ((entryp == NULL) || (kernelp == NULL)) { + /* No previous entry, it's already the default */ + return (BAM_SUCCESS); + } + + /* + * Check if we can delete the entry. If we're resetting the + * kernel command, and the args is already empty, or if we're + * resetting the args command, and the kernel is already the + * default, we can restore the old default and delete the entry. + */ + if (((optnum == KERNEL_CMD) && + ((old_args == NULL) || (old_args[0] == '\0'))) || + ((optnum == ARGS_CMD) && + (strncmp(kernelp->arg, DIRECT_BOOT_KERNEL, + sizeof (DIRECT_BOOT_KERNEL) - 1) == 0))) { + kernelp = NULL; + (void) do_delete(mp, entryNum); + restore_default_entry(mp, BAM_OLD_RC_DEF, + mp->old_rc_default); + mp->old_rc_default = NULL; + rv = BAM_WRITE; + goto done; + } + + if (optnum == KERNEL_CMD) { + /* + * At this point, we've already checked that old_args + * and entryp are valid pointers. The "+ 2" is for + * a space a the string termination character. + */ + new_str_len = (sizeof (DIRECT_BOOT_KERNEL) - 1) + + strlen(old_args) + 2; + new_arg = s_calloc(1, new_str_len); + (void) snprintf(new_arg, new_str_len, "%s %s", + DIRECT_BOOT_KERNEL, old_args); + free(kernelp->arg); + kernelp->arg = new_arg; + + /* + * We have changed the kernel line, so we may need + * to update the archive line as well. + */ + set_archive_line(entryp, kernelp); + } else { + /* + * We're resetting the boot args to nothing, so + * we only need to copy the kernel. We've already + * checked that the kernel is not the default. + */ + new_arg = s_calloc(1, old_kernel_len + 1); + (void) snprintf(new_arg, old_kernel_len + 1, "%s", + kernelp->arg); + free(kernelp->arg); + kernelp->arg = new_arg; + } + rv = BAM_WRITE; + goto done; + } + + /* + * Expand the kernel file to a full path, if necessary + */ + if ((optnum == KERNEL_CMD) && (path[0] != '/')) { + new_path = expand_path(path); + if (new_path == NULL) { + return (BAM_ERROR); + } + free_new_path = 1; + } else { + new_path = path; + free_new_path = 0; + } + + /* + * At this point, we know we're setting a new value. First, take care + * of the case where there was no previous entry. + */ + if (entryp == NULL) { + /* Similar to code in update_temp */ + if (stat(GRUB_slice, &sb) != 0) { + /* + * 1. First get root disk name from mnttab + * 2. Translate disk name to grub name + * 3. Add the new menu entry + */ + rootdev = get_special("/"); + if (rootdev) { + grubdisk = os_to_grubdisk(rootdev, 1); + free(rootdev); + } + } else { + /* + * This is an LU BE. The GRUB_root file + * contains entry for GRUB's "root" cmd. + */ + grubdisk = read_grub_root(); + } + if (grubdisk == NULL) { + bam_error(REBOOT_WITH_ARGS_FAILED); + rv = BAM_ERROR; + goto done; + } + if (optnum == KERNEL_CMD) { + entryNum = add_boot_entry(mp, BOOTENV_RC_TITLE, + grubdisk, new_path, NULL); + } else { + new_str_len = strlen(DIRECT_BOOT_KERNEL) + + strlen(path) + 8; + new_arg = s_calloc(1, new_str_len); + + (void) snprintf(new_arg, new_str_len, "%s %s", + DIRECT_BOOT_KERNEL, path); + entryNum = add_boot_entry(mp, BOOTENV_RC_TITLE, + grubdisk, new_arg, DIRECT_BOOT_ARCHIVE); + } + save_default_entry(mp, BAM_OLD_RC_DEF); + (void) set_global(mp, menu_cmds[DEFAULT_CMD], entryNum); + rv = BAM_WRITE; + goto done; + } + + /* + * There was already an bootenv entry which we need to edit. + */ + if (optnum == KERNEL_CMD) { + new_str_len = strlen(new_path) + strlen(old_args) + 2; + new_arg = s_calloc(1, new_str_len); + (void) snprintf(new_arg, new_str_len, "%s %s", new_path, + old_args); + free(kernelp->arg); + kernelp->arg = new_arg; + + /* + * If we have changed the kernel line, we may need to update + * the archive line as well. + */ + set_archive_line(entryp, kernelp); + } else { + new_str_len = old_kernel_len + strlen(path) + 8; + new_arg = s_calloc(1, new_str_len); + (void) strncpy(new_arg, kernelp->arg, old_kernel_len); + (void) strlcat(new_arg, " ", new_str_len); + (void) strlcat(new_arg, path, new_str_len); + free(kernelp->arg); + kernelp->arg = new_arg; + } + rv = BAM_WRITE; + +done: + if ((rv == BAM_WRITE) && kernelp) + update_line(kernelp); + if (free_new_path) + free(new_path); + return (rv); +} + /*ARGSUSED*/ static error_t set_option(menu_t *mp, char *menu_path, char *opt) { int optnum, optval; char *val; + char buf[BUFSIZ] = ""; + error_t rv; assert(mp); assert(opt); val = strchr(opt, '='); - if (val == NULL) { - bam_error(INVALID_ENTRY, opt); - return (BAM_ERROR); + if (val != NULL) { + *val = '\0'; } - *val = '\0'; if (strcmp(opt, "default") == 0) { optnum = DEFAULT_CMD; } else if (strcmp(opt, "timeout") == 0) { optnum = TIMEOUT_CMD; + } else if (strcmp(opt, menu_cmds[KERNEL_CMD]) == 0) { + optnum = KERNEL_CMD; + } else if (strcmp(opt, menu_cmds[ARGS_CMD]) == 0) { + optnum = ARGS_CMD; } else { bam_error(INVALID_ENTRY, opt); return (BAM_ERROR); } - optval = s_strtol(val + 1); - *val = '='; - return (set_global(mp, menu_cmds[optnum], optval)); + /* + * kernel and args are allowed without "=new_value" strings. All + * others cause errors + */ + if ((val == NULL) && (optnum != KERNEL_CMD) && (optnum != ARGS_CMD)) { + bam_error(INVALID_ENTRY, opt); + return (BAM_ERROR); + } else if (val != NULL) { + *val = '='; + } + + if ((optnum == KERNEL_CMD) || (optnum == ARGS_CMD)) { + rv = set_kernel(mp, optnum, val ? val + 1 : NULL, buf, BUFSIZ); + if ((rv == BAM_SUCCESS) && (buf[0] != '\0')) + (void) printf("%s\n", buf); + return (rv); + } else { + optval = s_strtol(val + 1); + return (set_global(mp, menu_cmds[optnum], optval)); + } } /* @@ -3766,7 +4294,7 @@ s_fputs(char *str, FILE *fp) /* * Wrapper around fgets, that strips newlines returned by fgets */ -static char * +char * s_fgets(char *buf, int buflen, FILE *fp) { int n; @@ -3782,7 +4310,7 @@ s_fgets(char *buf, int buflen, FILE *fp) return (buf); } -static void * +void * s_calloc(size_t nelem, size_t sz) { void *ptr; @@ -3795,6 +4323,17 @@ s_calloc(size_t nelem, size_t sz) return (ptr); } +void * +s_realloc(void *ptr, size_t sz) +{ + ptr = realloc(ptr, sz); + if (ptr == NULL) { + bam_error(NO_MEM, sz); + bam_exit(1); + } + return (ptr); +} + static char * s_strdup(char *str) { diff --git a/usr/src/cmd/boot/bootadm/bootadm.h b/usr/src/cmd/boot/bootadm/bootadm.h new file mode 100644 index 0000000000..80309501cb --- /dev/null +++ b/usr/src/cmd/boot/bootadm/bootadm.h @@ -0,0 +1,184 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _BOOTADM_H +#define _BOOTADM_H + +#pragma ident "%Z%%M% %I% %E% SMI" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef TEXT_DOMAIN +#define TEXT_DOMAIN "SUNW_OST_OSCMD" +#endif /* TEXT_DOMAIN */ + +/* Type definitions */ + +/* GRUB menu per-line classification */ +typedef enum { + BAM_INVALID = 0, + BAM_EMPTY, + BAM_COMMENT, + BAM_GLOBAL, + BAM_ENTRY, + BAM_TITLE +} menu_flag_t; + +/* struct for menu.lst contents */ +typedef struct line { + int lineNum; /* Line number in menu.lst */ + int entryNum; /* menu boot entry #. ENTRY_INIT if not applicable */ + char *cmd; + char *sep; + char *arg; + char *line; + menu_flag_t flags; + struct line *next; + struct line *prev; +} line_t; + +typedef struct entry { + struct entry *next; + struct entry *prev; + line_t *start; + line_t *end; + int entryNum; + uint8_t flags; +} entry_t; + +/* For flags value in entry_t */ +#define BAM_ENTRY_BOOTADM 0x01 /* entry created by bootadm */ +#define BAM_ENTRY_LU 0x02 /* entry created by Live Upgrade */ +#define BAM_ENTRY_CHAINLOADER 0x04 /* chainloader entry; do not disturb */ +#define BAM_ENTRY_ROOT 0x08 /* entry has a root line */ +#define BAM_ENTRY_MINIROOT 0x10 /* entry uses the failsafe miniroot */ +#define BAM_ENTRY_DBOOT 0x20 /* Is a dboot entry */ +#define BAM_ENTRY_32BIT 0x40 /* Is a 32-bit entry */ + +typedef struct { + line_t *start; + line_t *end; + line_t *curdefault; /* line containing default */ + line_t *olddefault; /* old default line (commented) */ + line_t *old_rc_default; /* old default line for bootenv.rc */ + entry_t *entries; /* os entries */ +} menu_t; + +typedef enum { + BAM_ERROR = -1, /* Must be negative. add_boot_entry() depends on it */ + BAM_SUCCESS = 0, + BAM_WRITE = 2, + BAM_SKIP /* Used by upgrade_menu() */ +} error_t; + +/* + * Menu related + * menu_cmd_t and menu_cmds must be kept in sync + */ +typedef enum { + DEFAULT_CMD = 0, + TIMEOUT_CMD, + TITLE_CMD, + ROOT_CMD, + KERNEL_CMD, + KERNEL_DOLLAR_CMD, + MODULE_CMD, + MODULE_DOLLAR_CMD, + SEP_CMD, + COMMENT_CMD, + CHAINLOADER_CMD, + ARGS_CMD +} menu_cmd_t; + +extern char *menu_cmds[]; + +/* For multi- or direct-boot */ +typedef enum { + BAM_DIRECT_NOT_SET, + BAM_DIRECT_MULTIBOOT, + BAM_DIRECT_DBOOT +} direct_or_multi_t; + +extern int bam_verbose; +extern int bam_force; +extern direct_or_multi_t bam_direct; + +extern error_t upgrade_menu(menu_t *, char *, char *); +extern void *s_calloc(size_t, size_t); +extern void *s_realloc(void *, size_t); +extern char *s_fgets(char *buf, int n, FILE *fp); +extern void bam_error(char *format, ...); +extern void bam_print_stderr(char *format, ...); +extern error_t dboot_or_multiboot(const char *); +extern char *get_special(char *); +extern char *os_to_grubdisk(char *, int); +extern void update_line(line_t *); + +#define BAM_MAXLINE 8192 + +/* menu.lst comments created by bootadm */ +#define BAM_BOOTADM_HDR "---------- ADDED BY BOOTADM - DO NOT EDIT ----------" +#define BAM_BOOTADM_FTR "---------------------END BOOTADM--------------------" + +/* + * menu.lst comments create by Live Upgrade. Note that these are the end of + * the comment strings - there will be other text before them. + */ +#define BAM_LU_HDR " - ADDED BY LIVE UPGRADE - DO NOT EDIT -----" +#define BAM_LU_FTR " -------------- END LIVE UPGRADE ------------" + +#define BAM_OLDDEF "BOOTADM SAVED DEFAULT: " +#define BAM_OLD_RC_DEF "BOOTADM RC SAVED DEFAULT: " + +/* Title used for failsafe entries */ +#define FAILSAFE_TITLE "Solaris failsafe" + +/* multiboot */ +#define MULTI_BOOT "/platform/i86pc/multiboot" +#define MULTI_BOOT_FAILSAFE "/boot/multiboot" +#define MULTI_BOOT_FAILSAFE_UNIX "kernel/unix" +#define MULTI_BOOT_FAILSAFE_LINE "/boot/multiboot kernel/unix -s" + +/* directboot kernels */ +#define DIRECT_BOOT_32 "/platform/i86pc/kernel/unix" +#define DIRECT_BOOT_64 "/platform/i86pc/kernel/amd64/unix" +#define DIRECT_BOOT_KERNEL "/platform/i86pc/kernel/$ISADIR/unix" +#define DIRECT_BOOT_FAILSAFE_KERNEL "/boot/platform/i86pc/kernel/unix" +#define DIRECT_BOOT_FAILSAFE_LINE DIRECT_BOOT_FAILSAFE_KERNEL " -s" + +/* Boot archives */ +#define DIRECT_BOOT_ARCHIVE "/platform/i86pc/$ISADIR/boot_archive" +#define DIRECT_BOOT_ARCHIVE_32 "/platform/i86pc/boot_archive" +#define DIRECT_BOOT_ARCHIVE_64 "/platform/i86pc/amd64/boot_archive" +#define MULTI_BOOT_ARCHIVE DIRECT_BOOT_ARCHIVE_32 +#define MINIROOT "/boot/x86.miniroot-safe" + +#ifdef __cplusplus +} +#endif + +#endif /* _BOOTADM_H */ diff --git a/usr/src/cmd/boot/bootadm/bootadm_upgrade.c b/usr/src/cmd/boot/bootadm/bootadm_upgrade.c new file mode 100644 index 0000000000..0b375b7fd0 --- /dev/null +++ b/usr/src/cmd/boot/bootadm/bootadm_upgrade.c @@ -0,0 +1,575 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <limits.h> +#include <fcntl.h> +#include <strings.h> + +#include <sys/mman.h> +#include <sys/elf.h> +#include <sys/multiboot.h> + +#include "message.h" +#include "bootadm.h" + +direct_or_multi_t bam_direct = BAM_DIRECT_NOT_SET; + +error_t +dboot_or_multiboot(const char *root) +{ + char fname[PATH_MAX]; + char *image; + uchar_t *ident; + int fd, m; + multiboot_header_t *mbh; + + (void) snprintf(fname, PATH_MAX, "%s/%s", root, + "platform/i86pc/kernel/unix"); + fd = open(fname, O_RDONLY); + if (fd < 0) { + bam_error(OPEN_FAIL, fname, strerror(errno)); + return (BAM_ERROR); + } + + /* + * mmap the first 8K + */ + image = mmap(NULL, 8192, PROT_READ, MAP_SHARED, fd, 0); + if (image == MAP_FAILED) { + bam_error(MMAP_FAIL, fname, strerror(errno)); + return (BAM_ERROR); + } + + ident = (uchar_t *)image; + if (ident[EI_MAG0] != ELFMAG0 || ident[EI_MAG1] != ELFMAG1 || + ident[EI_MAG2] != ELFMAG2 || ident[EI_MAG3] != ELFMAG3) { + bam_error(NOT_ELF_FILE, fname); + return (BAM_ERROR); + } + if (ident[EI_CLASS] != ELFCLASS32) { + bam_error(WRONG_ELF_CLASS, fname, ident[EI_CLASS]); + return (BAM_ERROR); + } + + /* + * The GRUB multiboot header must be 32-bit aligned and completely + * contained in the 1st 8K of the file. If the unix binary has + * a multiboot header, then it is a 'dboot' kernel. Otherwise, + * this kernel must be booted via multiboot -- we call this a + * 'multiboot' kernel. + */ + bam_direct = BAM_DIRECT_MULTIBOOT; + for (m = 0; m < 8192 - sizeof (multiboot_header_t); m += 4) { + mbh = (void *)(image + m); + if (mbh->magic == MB_HEADER_MAGIC) { + bam_direct = BAM_DIRECT_DBOOT; + break; + } + } + (void) munmap(image, 8192); + (void) close(fd); + return (BAM_SUCCESS); +} + +#define INST_RELEASE "var/sadm/system/admin/INST_RELEASE" + +/* + * Return true if root has been bfu'ed. bfu will blow away + * var/sadm/system/admin/INST_RELEASE, so if it's still there, we can + * assume the system has not been bfu'ed. + */ +static int +is_bfu_system(const char *root) +{ + static int is_bfu = -1; + char path[PATH_MAX]; + struct stat sb; + + if (is_bfu != -1) + return (is_bfu); + + (void) snprintf(path, sizeof (path), "%s/%s", root, INST_RELEASE); + if (stat(path, &sb) != 0) { + is_bfu = 1; + } else { + is_bfu = 0; + } + return (is_bfu); +} + +#define MENU_URL(root) (is_bfu_system(root) ? \ + "http://www.sun.com/msg/SUNOS-8000-CF" : \ + "http://www.sun.com/msg/SUNOS-8000-AK") + +/* + * Simply allocate a new line and copy in cmd + sep + arg + */ +void +update_line(line_t *linep) +{ + size_t size; + + free(linep->line); + size = strlen(linep->cmd) + strlen(linep->sep) + strlen(linep->arg) + 1; + linep->line = s_calloc(1, size); + (void) snprintf(linep->line, size, "%s%s%s", linep->cmd, linep->sep, + linep->arg); +} + +/* + * The parse_kernel_line function examines a menu.lst kernel line. For + * multiboot, this is: + * + * kernel <multiboot path> <flags1> <kernel path> <flags2> + * + * <multiboot path> is either /platform/i86pc/multiboot or /boot/multiboot + * + * <kernel path> may be missing, or may be any full or relative path to unix. + * We check for it by looking for a word ending in "/unix". If it ends + * in "kernel/unix", we upgrade it to a 32-bit entry. If it ends in + * "kernel/amd64/unix", we upgrade it to the default entry. Otherwise, + * it's a custom kernel, and we skip it. + * + * <flags*> are anything that doesn't fit either of the above - these will be + * copied over. + * + * For direct boot, the defaults are + * + * kernel$ <kernel path> <flags> + * + * <kernel path> is one of: + * /platform/i86pc/kernel/$ISADIR/unix + * /platform/i86pc/kernel/unix + * /platform/i86pc/kernel/amd64/unix + * /boot/platform/i86pc/kernel/unix + * + * If <kernel path> is any of the last three, the command may also be "kernel". + * + * <flags> is anything that isn't <kernel path>. + * + * This function is only called if it applies to our target boot environment. + * If we can't make any sense of the kernel line, an error is printed and + * BAM_ERROR is returned. + * + * The desired install type is given in the global variable bam_direct. + * If the kernel line is of a different install type, we change it to the + * preferred type. If the kernel line is already of the correct install + * type, we do nothing. Either way, BAM_SUCCESS is returned. + * + * For safety, we do one more check: if the kernel path starts with /boot, + * we verify that the new kernel exists before changing it. This is mainly + * done for bfu, as it may cause the failsafe archives to be a different + * boot architecture from the newly bfu'ed system. + */ +static error_t +parse_kernel_line(line_t *linep, const char *root, uint8_t *flags) +{ + char path[PATH_MAX]; + int len, left, total_len; + struct stat sb; + char *new_ptr, *new_arg, *old_ptr; + menu_cmd_t which; + + /* Used when changing a multiboot line to dboot */ + char *unix_ptr, *flags1_ptr, *flags2_ptr; + + /* + * Note that BAM_ENTRY_DBOOT refers to the entry we're looking at, not + * necessarily the system type. + */ + if (strncmp(linep->arg, DIRECT_BOOT_32, + sizeof (DIRECT_BOOT_32) - 1) == 0) { + *flags |= BAM_ENTRY_DBOOT | BAM_ENTRY_32BIT; + } else if ((strncmp(linep->arg, DIRECT_BOOT_KERNEL, + sizeof (DIRECT_BOOT_KERNEL) - 1) == 0) || + (strncmp(linep->arg, DIRECT_BOOT_64, + sizeof (DIRECT_BOOT_64) - 1) == 0) || + (strncmp(linep->arg, DIRECT_BOOT_FAILSAFE_KERNEL, + sizeof (DIRECT_BOOT_FAILSAFE_KERNEL) - 1) == 0)) { + *flags |= BAM_ENTRY_DBOOT; + } else if ((strncmp(linep->arg, MULTI_BOOT, + sizeof (MULTI_BOOT) - 1) == 0) || + (strncmp(linep->arg, MULTI_BOOT_FAILSAFE, + sizeof (MULTI_BOOT_FAILSAFE) - 1) == 0)) { + *flags &= ~BAM_ENTRY_DBOOT; + } else { + bam_error(NO_KERNEL_MATCH, linep->lineNum, MENU_URL(root)); + return (BAM_ERROR); + } + + if (((*flags & BAM_ENTRY_DBOOT) && (bam_direct == BAM_DIRECT_DBOOT)) || + (((*flags & BAM_ENTRY_DBOOT) == 0) && + (bam_direct == BAM_DIRECT_MULTIBOOT))) { + + /* No action needed */ + return (BAM_SUCCESS); + } + + if (*flags & BAM_ENTRY_MINIROOT) { + /* + * We're changing boot architectures - make sure + * the multiboot failsafe still exists. + */ + (void) snprintf(path, PATH_MAX, "%s%s", root, + (*flags & BAM_ENTRY_DBOOT) ? MULTI_BOOT_FAILSAFE : + DIRECT_BOOT_FAILSAFE_KERNEL); + if (stat(path, &sb) != 0) { + if (bam_verbose) { + bam_error(FAILSAFE_MISSING, linep->lineNum); + } + return (BAM_SUCCESS); + } + } + + /* + * Make sure we have the correct cmd - either kernel or kernel$ + * The failsafe entry should always be KERNEL_CMD. + */ + which = ((bam_direct == BAM_DIRECT_MULTIBOOT) || + (*flags & BAM_ENTRY_MINIROOT)) ? KERNEL_CMD : KERNEL_DOLLAR_CMD; + free(linep->cmd); + len = strlen(menu_cmds[which]) + 1; + linep->cmd = s_calloc(1, len); + (void) strncpy(linep->cmd, menu_cmds[which], len); + + /* + * Since all arguments are copied, the new arg string should be close + * in size to the old one. Just add 32 to cover the difference in + * the boot path. + */ + total_len = strlen(linep->arg) + 32; + new_arg = s_calloc(1, total_len); + old_ptr = strchr(linep->arg, ' '); + if (old_ptr != NULL) + old_ptr++; + + /* + * Transitioning from dboot to multiboot is pretty simple. We + * copy in multiboot and any args. + */ + if (bam_direct == BAM_DIRECT_MULTIBOOT) { + if (old_ptr == NULL) { + (void) snprintf(new_arg, total_len, "%s", + (*flags & BAM_ENTRY_MINIROOT) ? + MULTI_BOOT_FAILSAFE : MULTI_BOOT); + } else { + (void) snprintf(new_arg, total_len, "%s %s", + (*flags & BAM_ENTRY_MINIROOT) ? + MULTI_BOOT_FAILSAFE : MULTI_BOOT, old_ptr); + } + goto done; + } + + /* + * Transitioning from multiboot to directboot is a bit more + * complicated, since we may have two sets of arguments to + * copy and a unix path to parse. + * + * First, figure out if there's a unix path. + */ + if ((old_ptr != NULL) && + ((unix_ptr = strstr(old_ptr, "/unix")) != NULL)) { + /* See if there's anything past unix */ + flags2_ptr = unix_ptr + sizeof ("/unix"); + if (*flags2_ptr == '\0') { + flags2_ptr = NULL; + } + + while ((unix_ptr > old_ptr) && (*unix_ptr != ' ')) + unix_ptr--; + + if (unix_ptr == old_ptr) { + flags1_ptr = NULL; + } else { + flags1_ptr = old_ptr; + } + + if (strstr(unix_ptr, "kernel/unix") != NULL) { + *flags |= BAM_ENTRY_32BIT; + } else if ((strstr(unix_ptr, "kernel/amd64/unix") == NULL) && + (!bam_force)) { + /* + * If the above strstr returns NULL, but bam_force is + * set, we'll be upgrading an Install kernel. The + * result probably won't be what was intended, but we'll + * try it anyways. + */ + return (BAM_SKIP); + } + } else if (old_ptr != NULL) { + flags1_ptr = old_ptr; + unix_ptr = flags1_ptr + strlen(old_ptr); + flags2_ptr = NULL; + } else { + unix_ptr = flags1_ptr = flags2_ptr = NULL; + } + + if (*flags & BAM_ENTRY_MINIROOT) { + (void) snprintf(new_arg, total_len, "%s", + DIRECT_BOOT_FAILSAFE_KERNEL); + } else if (*flags & BAM_ENTRY_32BIT) { + (void) snprintf(new_arg, total_len, "%s", DIRECT_BOOT_32); + } else { + (void) snprintf(new_arg, total_len, "%s", DIRECT_BOOT_KERNEL); + } + + /* + * We now want to copy flags1_ptr through unix_ptr, and + * flags2_ptr through the end of the string + */ + if (flags1_ptr != NULL) { + len = strlcat(new_arg, " ", total_len); + left = total_len - len; + new_ptr = new_arg + len; + + if ((unix_ptr - flags1_ptr) < left) + left = (unix_ptr - flags1_ptr) + 1; + (void) strlcpy(new_ptr, flags1_ptr, left); + } + if (flags2_ptr != NULL) { + (void) strlcat(new_arg, " ", total_len); + (void) strlcat(new_arg, flags2_ptr, total_len); + } + +done: + free(linep->arg); + linep->arg = new_arg; + update_line(linep); + return (BAM_SUCCESS); +} + +/* + * Similar to above, except this time we're looking at a module line, + * which is quite a bit simpler. + * + * Under multiboot, the archive line is: + * + * module /platform/i86pc/boot_archive + * + * Under directboot, the archive line is: + * + * module$ /platform/i86pc/$ISADIR/boot_archive + * + * which may be specified exactly as either of: + * + * module /platform/i86pc/boot_archive + * module /platform/i86pc/amd64/boot_archive + * + * For either dboot or multiboot, the failsafe is: + * + * module /boot/x86.miniroot-safe + */ +static error_t +parse_module_line(line_t *linep, const char *root, uint8_t flags) +{ + int len; + menu_cmd_t which; + char *new; + + /* + * If necessary, BAM_ENTRY_MINIROOT was already set in flags + * in upgrade_menu(). We re-check BAM_ENTRY_DBOOT here in here + * in case the kernel and module lines differ. + */ + if ((strcmp(linep->arg, DIRECT_BOOT_ARCHIVE) == 0) || + (strcmp(linep->arg, DIRECT_BOOT_ARCHIVE_64) == 0)) { + flags |= BAM_ENTRY_DBOOT; + } else if ((strcmp(linep->arg, MULTI_BOOT_ARCHIVE) == 0) || + (strcmp(linep->arg, MINIROOT) == 0)) { + flags &= ~BAM_ENTRY_DBOOT; + } else { + bam_error(NO_MODULE_MATCH, linep->lineNum, MENU_URL(root)); + return (BAM_ERROR); + } + + if (((flags & BAM_ENTRY_DBOOT) && (bam_direct == BAM_DIRECT_DBOOT)) || + (((flags & BAM_ENTRY_DBOOT) == 0) && + (bam_direct == BAM_DIRECT_MULTIBOOT)) || + ((flags & BAM_ENTRY_MINIROOT) && + (strcmp(linep->cmd, menu_cmds[MODULE_CMD]) == 0))) { + + /* No action needed */ + return (BAM_SUCCESS); + } + + /* + * Make sure we have the correct cmd - either module or module$ + * The failsafe entry should always be MODULE_CMD. + */ + which = ((bam_direct == BAM_DIRECT_MULTIBOOT) || + (flags & BAM_ENTRY_MINIROOT)) ? MODULE_CMD : MODULE_DOLLAR_CMD; + free(linep->cmd); + len = strlen(menu_cmds[which]) + 1; + linep->cmd = s_calloc(1, len); + (void) strncpy(linep->cmd, menu_cmds[which], len); + + if (flags & BAM_ENTRY_MINIROOT) { + new = MINIROOT; + } else if ((bam_direct == BAM_DIRECT_DBOOT) && + ((flags & BAM_ENTRY_32BIT) == 0)) { + new = DIRECT_BOOT_ARCHIVE; + } else { + new = MULTI_BOOT_ARCHIVE; + } + + free(linep->arg); + len = strlen(new) + 1; + linep->arg = s_calloc(1, len); + (void) strncpy(linep->arg, new, len); + update_line(linep); + + return (BAM_SUCCESS); +} + +/*ARGSUSED*/ +error_t +upgrade_menu(menu_t *mp, char *root, char *opt) +{ + entry_t *cur_entry; + line_t *cur_line; + int i, skipit = 0, num_entries = 0; + int *hand_entries = NULL; + boolean_t found_kernel = B_FALSE; + error_t rv; + char *rootdev, *grubdisk = NULL; + + rootdev = get_special(root); + if (rootdev) { + grubdisk = os_to_grubdisk(rootdev, strlen(root) == 1); + free(rootdev); + rootdev = NULL; + } + + /* Loop through all OS entries in the menu.lst file */ + for (cur_entry = mp->entries; cur_entry != NULL; + cur_entry = cur_entry->next, skipit = 0) { + + if ((cur_entry->flags & BAM_ENTRY_CHAINLOADER) || + ((cur_entry->flags & BAM_ENTRY_MINIROOT) && !bam_force)) + continue; + + /* + * We only change entries added by bootadm and live upgrade, + * and warn on the rest, unless the -f flag was passed. + */ + if ((!(cur_entry->flags & (BAM_ENTRY_BOOTADM|BAM_ENTRY_LU))) && + !bam_force) { + if (num_entries == 0) { + hand_entries = s_calloc(1, sizeof (int)); + } else { + hand_entries = s_realloc(hand_entries, + (num_entries + 1) * sizeof (int)); + } + hand_entries[num_entries++] = cur_entry->entryNum; + continue; + } + + /* + * We make two loops through the lines. First, we check if + * there is a root entry, and if so, whether we should be + * checking this entry. + */ + if ((grubdisk != NULL) && (cur_entry->flags & BAM_ENTRY_ROOT)) { + for (cur_line = cur_entry->start; cur_line != NULL; + cur_line = cur_line->next) { + if ((cur_line->cmd == NULL) || + (cur_line->arg == NULL)) + continue; + + if (strcmp(cur_line->cmd, + menu_cmds[ROOT_CMD]) == 0) { + if (strcmp(cur_line->arg, + grubdisk) != 0) { + /* A different slice */ + skipit = 1; + } + break; + } + if (cur_line == cur_entry->end) + break; + } + } + if (skipit) + continue; + + for (cur_line = cur_entry->start; cur_line != NULL; + cur_line = cur_line->next) { + + /* + * We only compare for the length of KERNEL_CMD, + * so that KERNEL_DOLLAR_CMD will also match. + */ + if (strncmp(cur_line->cmd, menu_cmds[KERNEL_CMD], + strlen(menu_cmds[KERNEL_CMD])) == 0) { + rv = parse_kernel_line(cur_line, root, + &(cur_entry->flags)); + if (rv == BAM_SKIP) { + break; + } else if (rv != BAM_SUCCESS) { + return (rv); + } + found_kernel = B_TRUE; + } else if (strncmp(cur_line->cmd, + menu_cmds[MODULE_CMD], + strlen(menu_cmds[MODULE_CMD])) == 0) { + rv = parse_module_line(cur_line, root, + cur_entry->flags); + if (rv != BAM_SUCCESS) { + return (rv); + } + } + if (cur_line == cur_entry->end) + break; + } + } + + /* + * We only want to output one error, to avoid confusing a user. We + * rank "No kernels changed" as a higher priority than "will not + * update hand-added entries", since the former implies the latter. + */ + if (found_kernel == B_FALSE) { + bam_error(NO_KERNELS_FOUND, MENU_URL(root)); + return (BAM_ERROR); + } else if (num_entries > 0) { + bam_error(HAND_ADDED_ENTRY, MENU_URL(root)); + bam_print_stderr("Entry Number%s: ", (num_entries > 1) ? + "s" : ""); + for (i = 0; i < num_entries; i++) { + bam_print_stderr("%d ", hand_entries[i]); + } + bam_print_stderr("\n"); + } + return (BAM_WRITE); +} diff --git a/usr/src/cmd/boot/bootadm/message.h b/usr/src/cmd/boot/bootadm/message.h index 0eb28e12b4..6d6dee45d2 100644 --- a/usr/src/cmd/boot/bootadm/message.h +++ b/usr/src/cmd/boot/bootadm/message.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -32,6 +32,8 @@ extern "C" { #endif +#include <libintl.h> + #define FILE_MISS gettext("file not found: %s\n") #define ARCH_EXEC_MISS gettext("archive creation file not found: %s: %s\n") @@ -130,6 +132,8 @@ extern "C" { #define INVALID_ROOT gettext("invalid root entry: %s\n") +#define NO_KERNEL gettext("No kernel line found in entry %d\n") + #define INVALID_KERNEL gettext("invalid kernel entry: %s\n") #define INVALID_MODULE gettext("invalid module entry: %s\n") @@ -179,6 +183,8 @@ extern "C" { #define UNLOCK_FAIL gettext("failed to unlock file: %s: %s\n") +#define MMAP_FAIL gettext("failed to mmap file: %s: %s\n") + #define FILE_LOCKED gettext("Another instance of bootadm (pid %u) is running\n") #define FLIST_FAIL \ @@ -198,7 +204,7 @@ extern "C" { #define RDONLY_FS gettext("read-only filesystem: %s\n") -#define ARCHIVE_FAIL gettext("failed to create boot archive: %s\n") +#define ARCHIVE_FAIL gettext("Command '%s' failed to create boot archive\n") #define ARCHIVE_NOT_CREATED gettext("couldn't create boot archive: %s\n") @@ -321,6 +327,44 @@ the failsafe archive unbootable\n") #define FILE_REMOVE_FAILED \ gettext("Failed to delete one or more of (%s,%s). Remove manually.\n") +#define UNKNOWN_KERNEL gettext("Unable to expand %s to a full file path.\n") + +#define NOT_DBOOT \ + gettext("bootadm set-menu %s may only be run on directboot kernels.\n") + +#define DEFAULT_NOT_BAM \ +gettext("Default menu.lst entry is not controlled by bootadm. Exiting\n") + +#define NO_KERNEL_MATCH \ +gettext("Unexpected kernel command on line %d.\n\ +** YOU MUST MANUALLY CORRECT menu.lst BEFORE REBOOT! **\n\ +For details, see %s\n") + +#define NO_MODULE_MATCH \ +gettext("Unexpected module command on line %d.\n\ +** YOU MUST MANUALLY CORRECT menu.lst BEFORE REBOOT! **\n\ +For details, see %s\n") + +#define NO_KERNELS_FOUND \ +gettext("Could not find any kernel lines to update. Only entries created by\n\ +bootadm(1M) and lu(1M) can be updated. All other must be manually changed.\n\ +** YOU MUST MANUALLY CORRECT menu.lst BEFORE REBOOT! **\n\ +For details on updating entries, see %s\n") + +#define HAND_ADDED_ENTRY \ +gettext("On upgrades, bootadm(1M) will only upgrade entries added by\n\ +bootadm(1M) or lu(1M). The following entry or entries in menu.lst will\n\ +not be upgraded. For details on updating entries, see\n\ +%s\n") + +#define NOT_ELF_FILE gettext("%s is not an ELF file.\n") + +#define WRONG_ELF_CLASS gettext("%s is wrong ELF class 0x%x\n") + +#define FAILSAFE_MISSING \ +gettext("bootadm -m upgrade run, but the failsafe archives have not been\n\ +updated. Not updating line %d\n") + #ifdef __cplusplus } #endif diff --git a/usr/src/cmd/boot/scripts/Makefile.com b/usr/src/cmd/boot/scripts/Makefile.com index 8cd77a555d..b8fe31bc54 100644 --- a/usr/src/cmd/boot/scripts/Makefile.com +++ b/usr/src/cmd/boot/scripts/Makefile.com @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -30,7 +30,7 @@ MANIFEST= boot-archive-update.xml SVCMETHOD= boot-archive-update -PROG= create_ramdisk create_diskmap +PROG= create_ramdisk create_diskmap update_grub METHODPROG= boot-archive-update SBINPROG= root_archive diff --git a/usr/src/cmd/boot/scripts/create_ramdisk.ksh b/usr/src/cmd/boot/scripts/create_ramdisk.ksh index f26dde26a1..85a5082780 100644 --- a/usr/src/cmd/boot/scripts/create_ramdisk.ksh +++ b/usr/src/cmd/boot/scripts/create_ramdisk.ksh @@ -20,33 +20,39 @@ # CDDL HEADER END # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # ident "%Z%%M% %I% %E% SMI" format=ufs ALT_ROOT= -NO_AMD64= +compress=yes +SPLIT=unknown +ERROR=0 BOOT_ARCHIVE=platform/i86pc/boot_archive +BOOT_ARCHIVE_64=platform/i86pc/amd64/boot_archive export PATH=$PATH:/usr/sbin:/usr/bin:/sbin # # Parse options # -while getopts R: OPT 2> /dev/null +while [ "$1" != "" ] do - case $OPT in - R) ALT_ROOT="$OPTARG" + case $1 in + -R) shift + ALT_ROOT="$1" if [ "$ALT_ROOT" != "/" ]; then echo "Creating ram disk for $ALT_ROOT" fi ;; - ?) echo Usage: ${0##*/}: [-R \<root\>] + -n|--nocompress) compress=no ;; + *) echo Usage: ${0##*/}: [-R \<root\>] [--nocompress] exit ;; esac + shift done if [ -x /usr/bin/mkisofs -o -x /tmp/bfubin/mkisofs ] ; then @@ -59,7 +65,7 @@ fi # release=`uname -r` if [ "$release" = "5.8" ]; then - format=ufs + format=ufs fi shift `expr $OPTIND - 1` @@ -69,18 +75,34 @@ if [ $# -eq 1 ]; then echo "Creating ram disk for $ALT_ROOT" fi +rundir=`dirname $0` +if [ ! -x $rundir/symdef ]; then + # Shouldn't happen + echo "Warning: $rundir/symdef not present." + echo "Creating single archive at $ALT_ROOT/platform/i86pc/boot_archive" + SPLIT=no + compress=no +elif $rundir/symdef "$ALT_ROOT"/platform/i86pc/kernel/unix \ + dboot_image 2>/dev/null; then + SPLIT=yes +else + SPLIT=no + compress=no +fi + +[ -x /usr/bin/gzip ] || compress=no + function cleanup { - umount -f "$rdmnt" 2>/dev/null - lofiadm -d "$rdfile" 2>/dev/null + umount -f "$rdmnt32" 2>/dev/null + umount -f "$rdmnt64" 2>/dev/null + lofiadm -d "$rdfile32" 2>/dev/null + lofiadm -d "$rdfile64" 2>/dev/null rm -fr "$rddir" 2> /dev/null } function getsize { - # should we exclude amd64 binaries? - [ $is_amd64 -eq 0 ] && NO_AMD64="-type d -name amd64 -prune -o" - # Estimate image size and add %10 overhead for ufs stuff. # Note, we can't use du here in case we're on a filesystem, e.g. zfs, # in which the disk usage is less than the sum of the file sizes. @@ -93,87 +115,225 @@ function getsize # with directories. This results in a total size that's slightly # bigger than if du was called on a ufs directory. total_size=$(cd "/$ALT_ROOT" - find $filelist $NO_AMD64 -ls 2>/dev/null | nawk ' + find $filelist -ls 2>/dev/null | nawk ' {t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7} END {print int(t * 1.10 / 1024)}') } +# +# The first argument can be: +# +# "both" - create an archive with both 32-bit and 64-bit binaries +# "32-bit" - create an archive with only 32-bit binaries +# "64-bit" - create an archive with only 64-bit binaries +# function create_ufs { + which=$1 + archive=$2 + lofidev=$3 + # should we exclude amd64 binaries? - [ $is_amd64 -eq 0 ] && NO_AMD64="-type d -name amd64 -prune -o" + if [ "$which" = "32-bit" ]; then + NO_AMD64="-type d -name amd64 -prune -o" + rdfile="$rdfile32" + rdmnt="$rdmnt32" + elif [ "$which" = "64-bit" ]; then + NO_AMD64="" + rdfile="$rdfile64" + rdmnt="$rdmnt64" + else + NO_AMD64="" + rdfile="$rdfile32" + rdmnt="$rdmnt32" + fi - mkfile ${total_size}k "$rdfile" - lofidev=`lofiadm -a "$rdfile"` newfs $lofidev < /dev/null 2> /dev/null mkdir "$rdmnt" mount -F mntfs mnttab /etc/mnttab > /dev/null 2>&1 mount -o nologging $lofidev "$rdmnt" + files= # do the actual copy cd "/$ALT_ROOT" - find $filelist $NO_AMD64 -print 2> /dev/null | \ - cpio -pdum "$rdmnt" 2> /dev/null + for path in `find $filelist $NO_AMD64 -type f -print 2> /dev/null` + do + if [ "$which" = "both" ]; then + files="$files $path" + else + filetype=`file $path 2>/dev/null |\ + awk '/ELF/ { print \$3 }'` + if [ -z "$filetype" ] || [ "$filetype" = "$which" ] + then + files="$files $path" + fi + fi + done + if [ $compress = yes ]; then + ls $files | while read path + do + dir="${path%/*}" + mkdir -p "$rdmnt/$dir" + /usr/bin/gzip -c "$path" > "$rdmnt/$path" + done + else + ls $files | cpio -pdum "$rdmnt" 2> /dev/null + fi umount "$rdmnt" - lofiadm -d "$rdfile" rmdir "$rdmnt" + # # Check if gzip exists in /usr/bin, so we only try to run gzip # on systems that have gzip. Then run gzip out of the patch to # pick it up from bfubin or something like that if needed. # - if [ -x /usr/bin/gzip ] ; then - gzip -c "$rdfile" > "$ALT_ROOT/$BOOT_ARCHIVE-new" + # If compress is set, the individual files in the archive are + # compressed, and the final compression will accomplish very + # little. To save time, we skip the gzip in this case. + # + if [ $compress = no ] && [ -x /usr/bin/gzip ] ; then + gzip -c "$rdfile" > "${archive}-new" else - cat "$rdfile" > "$ALT_ROOT/$BOOT_ARCHIVE-new" + cat "$rdfile" > "${archive}-new" fi } +# +# The first argument can be: +# +# "both" - create an archive with both 32-bit and 64-bit binaries +# "32-bit" - create an archive with only 32-bit binaries +# "64-bit" - create an archive with only 64-bit binaries +# function create_isofs { + which=$1 + archive=$2 + # should we exclude amd64 binaries? - [ $is_amd64 = 0 ] && NO_AMD64="-m amd64" + if [ "$which" = "32-bit" ]; then + NO_AMD64="-type d -name amd64 -prune -o" + rdmnt="$rdmnt32" + errlog="$errlog32" + elif [ "$which" = "64-bit" ]; then + NO_AMD64="" + rdmnt="$rdmnt64" + errlog="$errlog64" + else + NO_AMD64="" + rdmnt="$rdmnt32" + errlog="$errlog32" + fi # create image directory seed with graft points mkdir "$rdmnt" files= - isocmd="mkisofs -quiet -graft-points -dlrDJN -relaxed-filenames $NO_AMD64" - for path in $filelist + isocmd="mkisofs -quiet -graft-points -dlrDJN -relaxed-filenames" + + cd "/$ALT_ROOT" + for path in `find $filelist $NO_AMD64 -type f -print 2> /dev/null` do - if [ -d "$ALT_ROOT/$path" ]; then - isocmd="$isocmd $path/=\"$ALT_ROOT/$path\"" - mkdir -p "$rdmnt/$path" - elif [ -f "$ALT_ROOT/$path" ]; then + if [ "$which" = "both" ]; then files="$files $path" + else + filetype=`file $path 2>/dev/null |\ + awk '/ELF/ { print \$3 }'` + if [ -z "$filetype" ] || [ "$filetype" = "$which" ] + then + files="$files $path" + fi fi done - cd "/$ALT_ROOT" - find $files 2> /dev/null | cpio -pdum "$rdmnt" 2> /dev/null + if [ $compress = yes ]; then + ls $files | while read path + do + dir="${path%/*}" + mkdir -p "$rdmnt/$dir" + /usr/bin/gzip -c "$path" > "$rdmnt/$path" + done + else + ls $files | cpio -pdum "$rdmnt" 2> /dev/null + fi isocmd="$isocmd \"$rdmnt\"" rm -f "$errlog" + # # Check if gzip exists in /usr/bin, so we only try to run gzip # on systems that have gzip. Then run gzip out of the patch to # pick it up from bfubin or something like that if needed. # - if [ -x /usr/bin/gzip ] ; then + # If compress is set, the individual files in the archive are + # compressed, and the final compression will accomplish very + # little. To save time, we skip the gzip in this case. + # + if [ $compress = no ] && [ -x /usr/bin/gzip ] ; then ksh -c "$isocmd" 2> "$errlog" | \ - gzip > "$ALT_ROOT/$BOOT_ARCHIVE-new" + gzip > "${archive}-new" else - ksh -c "$isocmd" 2> "$errlog" > "$ALT_ROOT/$BOOT_ARCHIVE-new" + ksh -c "$isocmd" 2> "$errlog" > "${archive}-new" fi if [ -s "$errlog" ]; then grep Error: "$errlog" >/dev/null 2>&1 if [ $? -eq 0 ]; then grep Error: "$errlog" - rm -f "$ALT_ROOT/$BOOT_ARCHIVE-new" + rm -f "${archive}-new" fi fi rm -f "$errlog" } +function create_archive +{ + which=$1 + archive=$2 + lofidev=$3 + + echo "updating $archive...this may take a minute" + + if [ "$format" = "ufs" ]; then + create_ufs "$which" "$archive" "$lofidev" + else + create_isofs "$which" "$archive" + fi + + # sanity check the archive before moving it into place + # + ARCHIVE_SIZE=`du -k "${archive}-new" | cut -f 1` + if [ $compress = yes ] + then + # + # 'file' will report "English text" for uncompressed + # boot_archives. Checking for that doesn't seem stable, + # so we just check that the file exists. + # + ls "${archive}-new" >/dev/null 2>&1 + else + # + # the file type check also establishes that the + # file exists at all + # + file "${archive}-new" | grep gzip > /dev/null + fi + + if [ $? = 1 ] && [ -x /usr/bin/gzip ] || [ $ARCHIVE_SIZE -lt 5000 ] + then + # + # Two of these functions may be run in parallel. We + # need to allow the other to clean up, so we can't + # exit immediately. Instead, we set a flag. + # + echo "update of $archive failed" + ERROR=1 + else + lockfs -f "/$ALT_ROOT" 2>/dev/null + mv "${archive}-new" "$archive" + lockfs -f "/$ALT_ROOT" 2>/dev/null + fi + +} + # # get filelist # @@ -186,33 +346,35 @@ then fi filelist=$(sort -u $files) -# -# decide if cpu is amd64 capable -# -prtconf -v /devices | grep CPU_not_amd64 > /dev/null 2>&1 -is_amd64=$? - scratch=tmp if [ $format = ufs ] ; then # calculate image size getsize + # We do two mkfile's of total_size, so double the space + (( tmp_needed = total_size * 2 )) + # check to see if there is sufficient space in tmpfs # tmp_free=`df -b /tmp | tail -1 | awk '{ printf ($2) }'` (( tmp_free = tmp_free / 2 )) - if [ $total_size -gt $tmp_free ] ; then + if [ $tmp_needed -gt $tmp_free ] ; then # assumes we have enough scratch space on $ALT_ROOT scratch="$ALT_ROOT" fi fi rddir="/$scratch/create_ramdisk.$$.tmp" -rdfile="$rddir/rd.file" -rdmnt="$rddir/rd.mount" -errlog="$rddir/rd.errlog" +rdfile32="$rddir/rd.file.32" +rdfile64="$rddir/rd.file.64" +rdmnt32="$rddir/rd.mount.32" +rdmnt64="$rddir/rd.mount.64" +errlog32="$rddir/rd.errlog.32" +errlog64="$rddir/rd.errlog.64" +lofidev32="" +lofidev64="" # make directory for temp files safely rm -rf "$rddir" @@ -221,46 +383,46 @@ mkdir "$rddir" # Clean up upon exit. trap 'cleanup' EXIT -echo "updating $ALT_ROOT/$BOOT_ARCHIVE...this may take a minute" - -if [ $format = "ufs" ]; then - create_ufs +if [ $SPLIT = yes ]; then + # + # We can't run lofiadm commands in parallel, so we have to do + # them here. + # + if [ "$format" = "ufs" ]; then + mkfile ${total_size}k "$rdfile32" + lofidev32=`lofiadm -a "$rdfile32"` + mkfile ${total_size}k "$rdfile64" + lofidev64=`lofiadm -a "$rdfile64"` + fi + create_archive "32-bit" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32 & + create_archive "64-bit" "$ALT_ROOT/$BOOT_ARCHIVE_64" $lofidev64 + wait + if [ "$format" = "ufs" ]; then + lofiadm -d "$rdfile32" + lofiadm -d "$rdfile64" + fi else - create_isofs + if [ "$format" = "ufs" ]; then + mkfile ${total_size}k "$rdfile32" + lofidev32=`lofiadm -a "$rdfile32"` + fi + create_archive "both" "$ALT_ROOT/$BOOT_ARCHIVE" $lofidev32 + [ "$format" = "ufs" ] && lofiadm -d "$rdfile32" fi - -# Make sure $BOOT_ARCHIVE-new created by either create_ufs or creat_isofs -# above is flushed to the backing store before we do anything with it. -lockfs -f "/$ALT_ROOT" - -# sanity check the archive before moving it into place -# the file type check also establishes that the file exists at all -# -ARCHIVE_SIZE=$(/bin/ls -l "$ALT_ROOT/$BOOT_ARCHIVE-new" | - nawk '{print int($5 / 1024)}') -file "$ALT_ROOT/$BOOT_ARCHIVE-new" | grep gzip > /dev/null - -if [ $? = 1 ] && [ -x /usr/bin/gzip ] || [ $ARCHIVE_SIZE -lt 5000 ]; then - echo "update of $ALT_ROOT/$BOOT_ARCHIVE failed" - rm -rf "$rddir" +if [ $ERROR = 1 ]; then + cleanup exit 1 fi # # For the diskless case, hardlink archive to /boot to make it # visible via tftp. /boot is lofs mounted under /tftpboot/<hostname>. -# NOTE: this script must work on both client and server +# NOTE: this script must work on both client and server. # grep "[ ]/[ ]*nfs[ ]" "$ALT_ROOT/etc/vfstab" > /dev/null if [ $? = 0 ]; then - mv "$ALT_ROOT/$BOOT_ARCHIVE-new" "$ALT_ROOT/$BOOT_ARCHIVE" - rm -f "$ALT_ROOT/boot/boot_archive" + rm -f "$ALT_ROOT/boot/boot_archive" "$ALT_ROOT/boot/amd64/boot_archive" ln "$ALT_ROOT/$BOOT_ARCHIVE" "$ALT_ROOT/boot/boot_archive" - rm -rf "$rddir" - exit + ln "$ALT_ROOT/$BOOT_ARCHIVE_64" "$ALT_ROOT/boot/amd64/boot_archive" fi - -mv "$ALT_ROOT/$BOOT_ARCHIVE-new" "$ALT_ROOT/$BOOT_ARCHIVE" -lockfs -f "/$ALT_ROOT" - rm -rf "$rddir" diff --git a/usr/src/cmd/boot/scripts/root_archive.ksh b/usr/src/cmd/boot/scripts/root_archive.ksh index 40bd1cd755..7321c23e2c 100644 --- a/usr/src/cmd/boot/scripts/root_archive.ksh +++ b/usr/src/cmd/boot/scripts/root_archive.ksh @@ -20,7 +20,7 @@ # CDDL HEADER END # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -111,7 +111,7 @@ packmedia() RELEASE=`basename "$RELEASE"` mkdir -p "$MEDIA/$RELEASE/Tools/Boot" - mkdir -p "$MEDIA/boot" + mkdir -p "$MEDIA/boot/platform/i86pc/kernel" # archive package databases to conserve memory # @@ -134,6 +134,8 @@ packmedia() archive_X "$MEDIA" "$MINIROOT" cp "$MINIROOT/platform/i86pc/multiboot" "$MEDIA/boot" + cp "$MINIROOT/platform/i86pc/kernel/unix" \ + "$MEDIA/boot/platform/i86pc/kernel/unix" # copy the install menu to menu.lst so we have a menu # on the install media diff --git a/usr/src/cmd/boot/scripts/update_grub.ksh b/usr/src/cmd/boot/scripts/update_grub.ksh new file mode 100644 index 0000000000..86a2ee65c8 --- /dev/null +++ b/usr/src/cmd/boot/scripts/update_grub.ksh @@ -0,0 +1,125 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# ident "%Z%%M% %I% %E% SMI" + +PATH="/usr/bin:/usr/sbin:${PATH}"; export PATH +ALT_ROOT= + +while getopts R: OPT 2>/dev/null +do + case $OPT in + R) ALT_ROOT="$OPTARG" + ;; + ?) echo "Usage: ${0##*/}: [-R \<root\>]" + ;; + esac +done + +ARCH=`uname -p` + +is_pcfs_boot=yes + +check_pcfs_boot() +{ + bootdev=`grep -v "^#" "$ALT_ROOT"/etc/vfstab | grep pcfs \ + | grep "[ ]/stubboot[ ]" | nawk '{print $1}'` + if [ X"$bootdev" = "X" ]; then + is_pcfs_boot=no + fi +} + +# +# Detect SVM root and return the list of raw devices under the mirror +# +get_rootdev_list() +{ + if [ -f "$ALT_ROOT"/etc/lu/GRUB_slice ]; then + grep '^PHYS_SLICE' "$ALT_ROOT"/etc/lu/GRUB_slice | cut -d= -f2 + else + metadev=`grep -v "^#" "$ALT_ROOT"/etc/vfstab | \ + grep "[ ]/[ ]" | nawk '{print $2}'` + if [[ $metadev = /dev/rdsk/* ]]; then + rootdevlist=`echo "$metadev" | sed -e "s#/dev/rdsk/##"` + elif [[ $metadev = /dev/md/rdsk/* ]]; then + metavol=`echo "$metadev" | sed -e "s#/dev/md/rdsk/##"` + rootdevlist=`metastat -p $metavol |\ + grep -v "^$metavol[ ]" | nawk '{print $4}'` + fi + for rootdev in $rootdevlist + do + echo /dev/rdsk/$rootdev + done + fi +} + +# +# multiboot: install grub on the boot slice +# +install_grub() +{ + # Stage 2 blocks must remain untouched + STAGE1="$ALT_ROOT"/boot/grub/stage1 + STAGE2="$ALT_ROOT"/boot/grub/stage2 + + if [ $is_pcfs_boot = yes ]; then + # + # Note: /stubboot/boot/grub/stage2 must stay untouched. + # + mkdir -p "$ALT_ROOT"/stubboot/boot/grub + cp "$ALT_ROOT"/boot/grub/menu.lst "$ALT_ROOT"/stubboot/boot/grub + bootdev=`grep -v "^#" "$ALT_ROOT"/etc/vfstab | grep pcfs | \ + grep "[ ]/stubboot[ ]" | nawk '{print $1}'` + rpcfsdev=`echo "$bootdev" | sed -e "s/dev\/dsk/dev\/rdsk/"` + if [ X"$rpcfsdev" != X ]; then + print "Installing grub on $rpcfsdev" + "$ALT_ROOT"/sbin/installgrub $STAGE1 $STAGE2 $rpcfsdev + fi + fi + + get_rootdev_list | while read rootdev + do + if [ X"$rpcfsdev" != X ]; then + echo "create GRUB menu in "$ALT_ROOT"/stubboot" + "$ALT_ROOT"/sbin/bootadm update-menu \ + -R "$ALT_ROOT"/stubboot -o $rootdev,"$ALT_ROOT" + else + echo "Creating GRUB menu in ${ALT_ROOT:-/}" + $ALT_ROOT/sbin/bootadm update-menu -R ${ALT_ROOT:-/} \ + -o $rootdev + fi + print "Installing grub on $rootdev" + "$ALT_ROOT"/sbin/installgrub $STAGE1 $STAGE2 $rootdev + done +} + +if [ -f "$ALT_ROOT"/platform/i86pc/multiboot -a "$ARCH" = i386 ] ; then + check_pcfs_boot + install_grub +fi + +exit 0 diff --git a/usr/src/cmd/eeprom/i386/i86pc/Makefile b/usr/src/cmd/boot/symdef/Makefile index da26f7f3a7..dba76dea89 100644 --- a/usr/src/cmd/eeprom/i386/i86pc/Makefile +++ b/usr/src/cmd/boot/symdef/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,28 +19,40 @@ # CDDL HEADER END # # -# Copyright 1993, 2002 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" -# -# Platform specific Makefile for the eeprom command. -# -# PLATFORM is the target for the binary instalation. -# -# PLATLINKS is a list of platforms which are to be linked to this binary -# at the file level. -# -SRCDIR = ../.. -PLATFORM = i86pc -PLATLINKS = +# + +PROG= symdef + +OBJS= symdef.o +SRCS = $(OBJS:.o=.c) -include $(SRCDIR)/Makefile.com +include ../Makefile.com .KEEP_STATE: -all: $(PROG) +LDLIBS += -lelf + +# Writing into string literals is incorrect. We need to match gcc's +# behavior, which causes us to take SIGSEGV on such a write. +CFLAGS += $(XSTRCONST) + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) $(LDLIBS) + $(POST_PROCESS) + +install: all $(ROOTBOOTSOLARISBINPROG) + +clean: + -$(RM) $(OBJS) + +_msg: -include $(SRCDIR)/Makefile.targ +lint: lint_SRCS -LDLIBS += -lgen +include ../Makefile.targ diff --git a/usr/src/cmd/boot/symdef/symdef.c b/usr/src/cmd/boot/symdef/symdef.c new file mode 100644 index 0000000000..4a0ddbc1a1 --- /dev/null +++ b/usr/src/cmd/boot/symdef/symdef.c @@ -0,0 +1,117 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <libelf.h> +#include <gelf.h> +#include <errno.h> + +/* + * symdef is a very simplified version of nm. It is used by upgrade and + * create_ramdisk in situations where we can't guarantee that nm will be around. + * + * Two arguments are expected: a binary and a symbol name. If the symbol is + * found in the name table of the binary, 0 is returned. If it is not found, + * 1 is returned. If an error occurs, a message is printed to stderr and -1 + * is returned. + */ + + +static void +usage(void) +{ + (void) fprintf(stderr, "USAGE: symdef file_name symbol\n"); +} + +int +main(int argc, char *argv[]) +{ + int fd = 0; + int rv = 1; + uint_t cnt, symcnt; + Elf *elfp = NULL; + Elf_Scn *scn = NULL; + size_t shstrndx; + GElf_Ehdr ehdr; + GElf_Shdr shdr; + GElf_Sym sym; + Elf32_Word shndx; + Elf_Data *symdata, *shndxdata; + + if (argc != 3) { + usage(); + return (-1); + } + + fd = open(argv[1], O_RDONLY); + if (fd == -1) { + (void) fprintf(stderr, "%s\n", strerror(errno)); + rv = -1; + goto done; + } + if (elf_version(EV_CURRENT) == EV_NONE) { + (void) fprintf(stderr, "Elf library version out of date\n"); + rv = -1; + goto done; + } + elfp = elf_begin(fd, ELF_C_READ, NULL); + if ((elfp == NULL) || (elf_kind(elfp) != ELF_K_ELF) || + ((gelf_getehdr(elfp, &ehdr)) == NULL) || + (elf_getshstrndx(elfp, &shstrndx) == 0)) + goto done; + + while ((scn = elf_nextscn(elfp, scn)) != NULL) { + if ((gelf_getshdr(scn, &shdr) == NULL) || + ((shdr.sh_type != SHT_SYMTAB) && + (shdr.sh_type != SHT_DYNSYM)) || + ((symdata = elf_getdata(scn, NULL)) == NULL)) + continue; + symcnt = shdr.sh_size / shdr.sh_entsize; + shndxdata = NULL; + for (cnt = 0; cnt < symcnt; cnt++) { + if ((gelf_getsymshndx(symdata, shndxdata, cnt, + &sym, &shndx) != NULL) && + (strcmp(argv[2], elf_strptr(elfp, shdr.sh_link, + sym.st_name)) == 0)) { + rv = 0; + goto done; + } + } + } +done: + if (elfp) + (void) elf_end(elfp); + if (fd != -1) + (void) close(fd); + return (rv); +} diff --git a/usr/src/cmd/devfsadm/i386/misc_link_i386.c b/usr/src/cmd/devfsadm/i386/misc_link_i386.c index f855486dee..95fb5895e8 100644 --- a/usr/src/cmd/devfsadm/i386/misc_link_i386.c +++ b/usr/src/cmd/devfsadm/i386/misc_link_i386.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -48,6 +48,7 @@ static int smbios(di_minor_t minor, di_node_t node); static int agp_process(di_minor_t minor, di_node_t node); static int drm_node(di_minor_t minor, di_node_t node); static int mc_node(di_minor_t minor, di_node_t node); +static int xsvc(di_minor_t minor, di_node_t node); static devfsadm_create_t misc_cbt[] = { { "vt00", "ddi_display", NULL, @@ -89,6 +90,9 @@ static devfsadm_create_t misc_cbt[] = { { "agp", "ddi_agp:master", NULL, TYPE_EXACT, ILEVEL_0, agp_process }, + { "pseudo", "ddi_pseudo", NULL, + TYPE_EXACT, ILEVEL_0, xsvc + }, { "memory-controller", "ddi_mem_ctrl", NULL, TYPE_EXACT, ILEVEL_0, mc_node } @@ -548,3 +552,22 @@ mc_node(di_minor_t minor, di_node_t node) (void) devfsadm_mklink(linkpath, node, minor, 0); return (DEVFSADM_CONTINUE); } + +/* + * Creates \M0 devlink for xsvc node + */ +static int +xsvc(di_minor_t minor, di_node_t node) +{ + char *mn; + + if (strcmp(di_node_name(node), "xsvc") != 0) + return (DEVFSADM_CONTINUE); + + mn = di_minor_name(minor); + if (mn == NULL) + return (DEVFSADM_CONTINUE); + + (void) devfsadm_mklink(mn, node, minor, 0); + return (DEVFSADM_CONTINUE); +} diff --git a/usr/src/cmd/eeprom/Makefile b/usr/src/cmd/eeprom/Makefile index 47011aeb75..9cda9fbd7b 100644 --- a/usr/src/cmd/eeprom/Makefile +++ b/usr/src/cmd/eeprom/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -27,31 +27,18 @@ # SUBDIRS= $(MACH) -MANIFEST=eeprom.xml - include ../Makefile.cmd -ROOTMANIFESTDIR = $(ROOTSVCPLATFORMI86PC) - -all:= TARGET= all -install:= TARGET= install -clean:= TARGET= clean -clobber:= TARGET= clobber -lint:= TARGET= lint - -PROG = eeprom -FILEMODE = 555 -GROUP = sys +all := TARGET= all +install := TARGET= install +clean := TARGET= clean +clobber := TARGET= clobber +lint := TARGET= lint +check := TARGET= check .KEEP_STATE: -all install clean clobber lint : $(SUBDIRS) - -install: $(SUBDIRS) $(ROOTMANIFEST) - $(RM) $(ROOTUSRSBINPROG) - $(LN) $(PLATEXEC) $(ROOTUSRSBINPROG) - -check: $(CHKMANIFEST) +all install clean clobber lint check: $(SUBDIRS) $(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(TARGET) diff --git a/usr/src/cmd/eeprom/Makefile.com b/usr/src/cmd/eeprom/Makefile.com index cc5944fd6f..0cc0be6f29 100644 --- a/usr/src/cmd/eeprom/Makefile.com +++ b/usr/src/cmd/eeprom/Makefile.com @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,12 +21,10 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright (c) 1993,1998 by Sun Microsystems, Inc. -# All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # -# cmd/eeprom/Makefile.com -# - + # # Create default so empty rules don't # confuse make @@ -35,7 +32,6 @@ CLASS = 32 include $(SRCDIR)/../Makefile.cmd -include $(SRCDIR)/../../Makefile.psm PROG = eeprom @@ -43,44 +39,15 @@ FILEMODE = 02555 DIRMODE = 755 GROUP = sys -# -# Sparc program implementation supports openprom machines. identical versions -# are installed in /usr/platform for each machine type -# because (at this point in time) we have no guarantee that a common version -# will be available for all potential sparc machines (eg: ICL, solbourne ,...). -# -# The identical binary is installed several times (rather than linking them -# together) because they will be in separate packages. -# -# Now that it should be obvious that little (if anything) was gained from -# this `fix-impl' implementation style, maybe somebody will unroll this in -# distinct, small and simpler versions for each PROM type. -# -IMPL = $(PLATFORM:sun%=sun) +OBJS = error.o -prep_OBJS = openprom.o loadlogo.o -sun_OBJS = openprom.o loadlogo.o -i86pc_OBJS = benv.o benv_kvm.o benv_sync.o -OBJS = error.o -OBJS += $($(IMPL)_OBJS) LINT_OBJS = $(OBJS:%.o=%.ln) - -prep_SOURCES = openprom.c loadlogo.c -sun_SOURCES = openprom.c loadlogo.c -i86pc_SOURCES = benv.c benv_kvm.c benv_syn.c -SOURCES = error.c -SOURCES += $($(IMPL)_SOURCES) +SOURCES = $(OBJS:%.o=%.c) .PARALLEL: $(OBJS) -%.o: ../common/%.c - $(COMPILE.c) -o $@ $< - %.o: $(SRCDIR)/common/%.c $(COMPILE.c) -o $@ $< %.ln: ../common/%.c $(LINT.c) -c $@ $< - -%.ln: $(SRCDIR)/common/%.c - $(LINT.c) -c $@ $< diff --git a/usr/src/cmd/eeprom/Makefile.targ b/usr/src/cmd/eeprom/Makefile.targ index 538108a183..1d819bdabc 100644 --- a/usr/src/cmd/eeprom/Makefile.targ +++ b/usr/src/cmd/eeprom/Makefile.targ @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,11 +21,13 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright (c) 1993 by Sun Microsystems, Inc. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # # cmd/eeprom/Makefile.targ # -install: all $(USR_PSM_SBIN_PROG) $(USR_PSM_SBIN_PROG_LINKS) + +install: all $(ROOTUSRSBIN) $(ROOTUSRSBINPROG) $(PROG): $(OBJS) $(LINK.c) -o $@ $(OBJS) $(LDLIBS) @@ -35,9 +36,11 @@ $(PROG): $(OBJS) clean: -$(RM) $(OBJS) -$(RM) $(LINT_OBJS) + -$(RM) $(PROG) lint: $(LINT_OBJS) $(LINT.c) $(LINT_OBJS) +check: + include $(SRCDIR)/../Makefile.targ -include $(SRCDIR)/../../Makefile.psm.targ diff --git a/usr/src/cmd/eeprom/common/Makefile b/usr/src/cmd/eeprom/common/Makefile deleted file mode 100644 index 9828df5a79..0000000000 --- a/usr/src/cmd/eeprom/common/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright (c) 1995,1998 by Sun Microsystems, Inc. -# All rights reserved. -# -# cmd/eeprom/common/Makefile -# -include ../../Makefile.cmd - -PROG = eeprom -FILEMODE = 555 -GROUP = sys - -.KEEP_STATE: - -all install : $(ROOTUSRSBINPROG) - -clean clobber : FRC - $(RM) $(ROOTUSRSBINPROG) - -FRC: diff --git a/usr/src/cmd/eeprom/eeprom.xml b/usr/src/cmd/eeprom/eeprom.xml deleted file mode 100644 index 48db9f3599..0000000000 --- a/usr/src/cmd/eeprom/eeprom.xml +++ /dev/null @@ -1,81 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> -<!-- - Copyright 2005 Sun Microsystems, Inc. All rights reserved. - Use is subject to license terms. - - CDDL HEADER START - - The contents of this file are subject to the terms of the - Common Development and Distribution License, Version 1.0 only - (the "License"). You may not use this file except in compliance - with the License. - - You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - or http://www.opensolaris.org/os/licensing. - See the License for the specific language governing permissions - and limitations under the License. - - When distributing Covered Code, include this CDDL HEADER in each - file and include the License file at usr/src/OPENSOLARIS.LICENSE. - If applicable, add the following below this CDDL HEADER, with the - fields enclosed by brackets "[]" replaced with your own identifying - information: Portions Copyright [yyyy] [name of copyright owner] - - CDDL HEADER END - - ident "%Z%%M% %I% %E% SMI" - - NOTE: This service manifest is not editable; its contents will - be overwritten by package or patch operations, including - operating system upgrade. Make customizations in a different - file. ---> - -<service_bundle type='manifest' name='SUNWos86r:eeprom'> - -<service - name='platform/i86pc/eeprom' - type='service' - version='1'> - - <create_default_instance enabled='false' /> - - <single_instance /> - - <dependency - name='usr' - type='service' - grouping='require_all' - restart_on='none'> - <service_fmri value='svc:/system/filesystem/usr' /> - </dependency> - - <exec_method - type='method' - name='start' - exec='/usr/sbin/eeprom -I' - timeout_seconds='60'> - </exec_method> - - <property_group name='startd' type='framework'> - <propval name='duration' type='astring' - value='transient' /> - </property_group> - - <stability value='Unstable' /> - - <template> - <common_name> - <loctext xml:lang='C'> - EEPROM emulation - </loctext> - </common_name> - <documentation> - <manpage title='eeprom' section='1M' - manpath='/usr/share/man' /> - </documentation> - </template> -</service> - -</service_bundle> diff --git a/usr/src/cmd/eeprom/i386/Makefile b/usr/src/cmd/eeprom/i386/Makefile index 33c7bc2ccf..4c28dce186 100644 --- a/usr/src/cmd/eeprom/i386/Makefile +++ b/usr/src/cmd/eeprom/i386/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,23 +21,22 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright (c) 1993 by Sun Microsystems, Inc. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # -# cmd/eeprom/i386/Makefile -# -SUBDIRS= i86pc -all:= TARGET= all -install:= TARGET= install -clean:= TARGET= clean -clobber:= TARGET= clobber -lint:= TARGET= lint +SRCDIR = .. -.KEEP_STATE: +include $(SRCDIR)/Makefile.com + +# We "borrow" some error messages from bootadm. Add the path to pick these up +CFLAGS += -I../../boot/bootadm +LINTFLAGS += -I../../boot/bootadm -all install clean clobber lint : $(SUBDIRS) +OBJS += benv.o benv_kvm.o + +.KEEP_STATE: -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) +all: $(PROG) -FRC: +include $(SRCDIR)/Makefile.targ diff --git a/usr/src/cmd/eeprom/i386/common/benv.c b/usr/src/cmd/eeprom/i386/benv.c index a1d9809bcc..3e44469f9a 100644 --- a/usr/src/cmd/eeprom/i386/common/benv.c +++ b/usr/src/cmd/eeprom/i386/benv.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,17 +19,20 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include "benv.h" +#include "message.h" #include <ctype.h> #include <stdarg.h> #include <sys/mman.h> #include <unistd.h> +#include <signal.h> +#include <sys/wait.h> /* * Usage: % eeprom [-v] [-f prom_dev] [-] @@ -40,7 +42,6 @@ extern void get_kbenv(void); extern void close_kbenv(void); extern caddr_t get_propval(char *name, char *node); -extern void sync_benv(void); extern void setprogname(char *prog); char *boottree; @@ -48,7 +49,6 @@ struct utsname uts_buf; static int test; int verbose; -static char *bootargs; /* * Concatenate a NULL terminated list of strings into @@ -69,7 +69,7 @@ strcats(char *s, ...) } else { len += strlen(cp); ret = realloc(ret, len); - strcat(ret, cp); + (void) strcat(ret, cp); } } va_end(ap); @@ -187,15 +187,262 @@ get_var(char *name, eplist_t *list) return (NULL); } +/*PRINTFLIKE1*/ +static void +eeprom_error(const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + (void) fprintf(stderr, "eeprom: "); + (void) vfprintf(stderr, format, ap); + va_end(ap); +} + +static int +exec_cmd(char *cmdline, char *output, int64_t osize) +{ + char buf[BUFSIZ]; + int ret; + size_t len; + FILE *ptr; + sigset_t set; + void (*disp)(int); + + if (output) + output[0] = '\0'; + + /* + * For security + * - only absolute paths are allowed + * - set IFS to space and tab + */ + if (*cmdline != '/') { + eeprom_error(ABS_PATH_REQ, cmdline); + return (-1); + } + (void) putenv("IFS= \t"); + + /* + * We may have been exec'ed with SIGCHLD blocked + * unblock it here + */ + (void) sigemptyset(&set); + (void) sigaddset(&set, SIGCHLD); + if (sigprocmask(SIG_UNBLOCK, &set, NULL) != 0) { + eeprom_error(FAILED_SIG, strerror(errno)); + return (-1); + } + + /* + * Set SIGCHLD disposition to SIG_DFL for popen/pclose + */ + disp = sigset(SIGCHLD, SIG_DFL); + if (disp == SIG_ERR) { + eeprom_error(FAILED_SIG, strerror(errno)); + return (-1); + } + if (disp == SIG_HOLD) { + eeprom_error(BLOCKED_SIG, cmdline); + return (-1); + } + + ptr = popen(cmdline, "r"); + if (ptr == NULL) { + eeprom_error(POPEN_FAIL, cmdline, strerror(errno)); + return (-1); + } + + /* + * If we simply do a pclose() following a popen(), pclose() + * will close the reader end of the pipe immediately even + * if the child process has not started/exited. pclose() + * does wait for cmd to terminate before returning though. + * When the executed command writes its output to the pipe + * there is no reader process and the command dies with + * SIGPIPE. To avoid this we read repeatedly until read + * terminates with EOF. This indicates that the command + * (writer) has closed the pipe and we can safely do a + * pclose(). + * + * Since pclose() does wait for the command to exit, + * we can safely reap the exit status of the command + * from the value returned by pclose() + */ + while (fgets(buf, sizeof (buf), ptr) != NULL) { + if (output && osize > 0) { + (void) snprintf(output, osize, "%s", buf); + len = strlen(buf); + output += len; + osize -= len; + } + } + + /* + * If there's a "\n" at the end, we want to chop it off + */ + if (output) { + len = strlen(output) - 1; + if (output[len] == '\n') + output[len] = '\0'; + } + + ret = pclose(ptr); + if (ret == -1) { + eeprom_error(PCLOSE_FAIL, cmdline, strerror(errno)); + return (-1); + } + + if (WIFEXITED(ret)) { + return (WEXITSTATUS(ret)); + } else { + eeprom_error(EXEC_FAIL, cmdline, ret); + return (-1); + } +} + +#define BOOTADM_STR "bootadm: " + +/* + * bootadm starts all error messages with "bootadm: ". + * Add a note so users don't get confused on how they ran bootadm. + */ +static void +output_error_msg(const char *msg) +{ + size_t len = sizeof (BOOTADM_STR) - 1; + + if (strncmp(msg, BOOTADM_STR, len) == 0) { + eeprom_error("error returned from %s\n", msg); + } else if (msg[0] != '\0') { + eeprom_error("%s\n", msg); + } +} + +static char * +get_bootadm_value(char *name) +{ + char *ptr, *ret_str, *end_ptr, *orig_ptr; + char output[BUFSIZ]; + int is_console, is_kernel = 0; + size_t len; + + is_console = (strcmp(name, "console") == 0); + + if (strcmp(name, "boot-file") == 0) { + is_kernel = 1; + ptr = "/sbin/bootadm set-menu kernel 2>&1"; + } else if (is_console || (strcmp(name, "boot-args") == 0)) { + ptr = "/sbin/bootadm set-menu args 2>&1"; + } else { + eeprom_error("Unknown value in get_bootadm_value: %s\n", name); + return (NULL); + } + + if (exec_cmd(ptr, output, BUFSIZ) != 0) { + output_error_msg(output); + return (NULL); + } + + if (is_console) { + if ((ptr = strstr(output, "console=")) == NULL) { + return (NULL); + } + ptr += strlen("console="); + + /* + * -B may have comma-separated values. It may also be + * followed by other flags. + */ + len = strcspn(ptr, " \t,"); + ret_str = calloc(len + 1, 1); + if (ret_str == NULL) { + eeprom_error(NO_MEM, len + 1); + return (NULL); + } + (void) strncpy(ret_str, ptr, len); + return (ret_str); + } else if (is_kernel) { + ret_str = strdup(output); + if (ret_str == NULL) + eeprom_error(NO_MEM, strlen(output) + 1); + return (ret_str); + } else { + /* If there's no console setting, we can return */ + if ((orig_ptr = strstr(output, "console=")) == NULL) { + return (strdup(output)); + } + len = strcspn(orig_ptr, " \t,"); + ptr = orig_ptr; + end_ptr = orig_ptr + len + 1; + + /* Eat up any white space */ + while ((*end_ptr == ' ') || (*end_ptr == '\t')) + end_ptr++; + + /* + * If there's data following the console string, copy it. + * If not, cut off the new string. + */ + if (*end_ptr == '\0') + *ptr = '\0'; + + while (*end_ptr != '\0') { + *ptr = *end_ptr; + ptr++; + end_ptr++; + } + *ptr = '\0'; + if ((strchr(output, '=') == NULL) && + (strncmp(output, "-B ", 3) == 0)) { + /* + * Since we removed the console setting, we no + * longer need the initial "-B " + */ + orig_ptr = output + 3; + } else { + orig_ptr = output; + } + + ret_str = strdup(orig_ptr); + if (ret_str == NULL) + eeprom_error(NO_MEM, strlen(orig_ptr) + 1); + return (ret_str); + } +} + +/* + * If quiet is 1, print nothing if there is no value. If quiet is 0, print + * a message. + */ +static void +print_bootadm_value(char *name, int quiet) +{ + char *value = get_bootadm_value(name); + + if ((value != NULL) && (value[0] != '\0')) { + (void) printf("%s=%s\n", name, value); + } else if (quiet == 0) { + (void) printf("%s: data not available.\n", name); + } + + if (value != NULL) + free(value); +} + static void print_var(char *name, eplist_t *list) { benv_ent_t *p; - if ((p = get_var(name, list)) == NULL) - printf("%s: data not available.\n", name); + if ((strcmp(name, "boot-file") == 0) || + (strcmp(name, "boot-args") == 0) || + (strcmp(name, "console") == 0)) { + print_bootadm_value(name, 0); + } else if ((p = get_var(name, list)) == NULL) + (void) printf("%s: data not available.\n", name); else - printf("%s=%s\n", name, p->val ? p->val : ""); + (void) printf("%s=%s\n", name, p->val ? p->val : ""); } static void @@ -206,9 +453,19 @@ print_vars(eplist_t *list) for (e = list->next; e != list; e = e->next) { p = (benv_ent_t *)e->item; - if (p->name != NULL) - printf("%s=%s\n", p->name, p->val ? p->val : ""); + if (p->name != NULL) { + if ((strcmp(p->name, "boot-file") == 0) || + (strcmp(p->name, "boot-args") == 0) || + (strcmp(p->name, "console") == 0)) { + /* handle these separately */ + continue; + } + (void) printf("%s=%s\n", p->name, p->val ? p->val : ""); + } } + print_bootadm_value("boot-file", 1); + print_bootadm_value("boot-args", 1); + print_bootadm_value("console", 1); } /* @@ -219,35 +476,91 @@ print_vars(eplist_t *list) static void put_quoted(FILE *fp, char *val) { - putc('\'', fp); + (void) putc('\'', fp); while (*val) { switch (*val) { case '\'': case '\\': - putc('\\', fp); + (void) putc('\\', fp); /* FALLTHROUGH */ default: - putc(*val, fp); + (void) putc(*val, fp); break; } val++; } - putc('\'', fp); + (void) putc('\'', fp); } static void -write_bargs(char *name, char *val) +set_bootadm_var(char *name, char *value) { - FILE *fp; + char buf[BUFSIZ]; + char output[BUFSIZ] = ""; + char *ptr, *console, *args; + int is_console; - if ((fp = fopen(bootargs, "w")) == NULL) - exit(_error(PERROR, "cannot open %s", bootargs)); + if (verbose) { + (void) printf("old:"); + print_bootadm_value(name, 0); + } - fprintf(fp, "setprop %s ", name); - put_quoted(fp, val); - fprintf(fp, "\n"); + /* + * For security, we single-quote whatever we run on the command line, + * and we don't allow single quotes in the string. + */ + if ((ptr = strchr(value, '\'')) != NULL) { + eeprom_error("Single quotes are not allowed " + "in the %s property.\n", name); + return; + } - fclose(fp); + is_console = (strcmp(name, "console") == 0); + if (strcmp(name, "boot-file") == 0) { + (void) snprintf(buf, BUFSIZ, "/sbin/bootadm set-menu " + "kernel='%s' 2>&1", value); + } else if (is_console || (strcmp(name, "boot-args") == 0)) { + if (is_console) { + args = get_bootadm_value("boot-args"); + console = value; + } else { + args = value; + console = get_bootadm_value("console"); + } + if (((args == NULL) || (args[0] == '\0')) && + ((console == NULL) || (console[0] == '\0'))) { + (void) snprintf(buf, BUFSIZ, "/sbin/bootadm set-menu " + "args= 2>&1"); + } else if ((args == NULL) || (args[0] == '\0')) { + (void) snprintf(buf, BUFSIZ, "/sbin/bootadm " + "set-menu args='-B console=%s' 2>&1", + console); + } else if ((console == NULL) || (console[0] == '\0')) { + (void) snprintf(buf, BUFSIZ, "/sbin/bootadm " + "set-menu args='%s' 2>&1", args); + } else if (strncmp(args, "-B ", 3) != 0) { + (void) snprintf(buf, BUFSIZ, "/sbin/bootadm " + "set-menu args='-B console=%s %s' 2>&1", + console, args); + } else { + (void) snprintf(buf, BUFSIZ, "/sbin/bootadm " + "set-menu args='-B console=%s,%s' 2>&1", + console, args + 3); + } + } else { + eeprom_error("Unknown value in set_bootadm_value: %s\n", name); + return; + } + + if (exec_cmd(buf, output, BUFSIZ) != 0) { + output_error_msg(output); + return; + } + + if (verbose) { + (void) printf("new:"); + print_bootadm_value(name, 0); + } } static void @@ -255,8 +568,15 @@ set_var(char *name, char *val, eplist_t *list) { benv_ent_t *p; + if ((strcmp(name, "boot-file") == 0) || + (strcmp(name, "boot-args") == 0) || + (strcmp(name, "console") == 0)) { + set_bootadm_var(name, val); + return; + } + if (verbose) { - printf("old:"); + (void) printf("old:"); print_var(name, list); } @@ -267,7 +587,7 @@ set_var(char *name, char *val, eplist_t *list) add_bent(list, NULL, "setprop", name, val); if (verbose) { - printf("new:"); + (void) printf("new:"); print_var(name, list); } } @@ -307,8 +627,6 @@ init_benv(benv_des_t *bd, char *file) bd->name = file; else bd->name = strcats(boottree, "/solaris/bootenv.rc", NULL); - - bootargs = strcats(boottree, "/solaris/bootargs.rc", NULL); } static void @@ -636,25 +954,22 @@ write_benv(benv_des_t *bd) for (e = list->next; e != list; e = e->next) { bent = (benv_ent_t *)e->item; name = bent->name; - if (name) - if (strcmp(name, "bootargs") == 0) { - /* - * Write "bootargs" to bootargs.rc file. - */ - write_bargs(name, bent->val); - } else if (bent->val) { - fprintf(fp, "%s %s ", + if (name) { + if (bent->val) { + (void) fprintf(fp, "%s %s ", bent->cmd, bent->name); put_quoted(fp, bent->val); - fprintf(fp, "\n"); - } else - fprintf(fp, "%s %s\n", + (void) fprintf(fp, "\n"); + } else { + (void) fprintf(fp, "%s %s\n", bent->cmd, bent->name); - else - fprintf(fp, "%s\n", bent->cmd); + } + } else { + (void) fprintf(fp, "%s\n", bent->cmd); + } } - fclose(fp); + (void) fclose(fp); } static char * @@ -679,23 +994,12 @@ get_line(void) return (NULL); } -void -init_eeprom(void) -{ - - /* ignore truncate failure */ - (void) truncate(bootargs, 0); - - sync_benv(); -} - int main(int argc, char **argv) { int c; - int init = 0; int updates = 0; - char *usage = "Usage: %s [-I] [-v] [-f prom-device]" + char *usage = "Usage: %s [-v] [-f prom-device]" " [variable[=value] ...]"; eplist_t *elist; benv_des_t *bd; @@ -705,9 +1009,6 @@ main(int argc, char **argv) while ((c = getopt(argc, argv, "f:Itv")) != -1) switch (c) { - case 'I': - init++; - break; case 'v': verbose++; break; @@ -733,9 +1034,7 @@ main(int argc, char **argv) elist = bd->elist; - if (init) - init_eeprom(); - else if (optind >= argc) { + if (optind >= argc) { print_vars(elist); return (0); } else @@ -761,7 +1060,7 @@ main(int argc, char **argv) * don't write benv if we are processing delayed writes since * it is likely that the delayed writes changes bootenv.rc anyway... */ - if (!init && updates) + if (updates) write_benv(bd); close_kbenv(); diff --git a/usr/src/cmd/eeprom/i386/common/benv.h b/usr/src/cmd/eeprom/i386/benv.h index ec031e67c6..ec031e67c6 100644 --- a/usr/src/cmd/eeprom/i386/common/benv.h +++ b/usr/src/cmd/eeprom/i386/benv.h diff --git a/usr/src/cmd/eeprom/i386/common/benv_kvm.c b/usr/src/cmd/eeprom/i386/benv_kvm.c index b7b912eb73..b7b912eb73 100644 --- a/usr/src/cmd/eeprom/i386/common/benv_kvm.c +++ b/usr/src/cmd/eeprom/i386/benv_kvm.c diff --git a/usr/src/cmd/eeprom/i386/common/benv_sync.c b/usr/src/cmd/eeprom/i386/common/benv_sync.c deleted file mode 100644 index 5faf7e68ab..0000000000 --- a/usr/src/cmd/eeprom/i386/common/benv_sync.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "benv.h" -#include <unistd.h> -#include <sys/sunddi.h> -#include <sys/ddi_impldefs.h> - -extern ddi_prop_t *get_proplist(char *name); -extern int verbose; - -/* - * Delayed-write descriptor. - */ -typedef struct dw_des { - char *path; /* file path */ - eplist_t *wlist; /* list of writes to the file */ -} dw_des_t; - -/* - * Delayed-write request. - */ -typedef struct dw_req { - caddr_t adr; /* data address */ - uint_t len; /* data length */ - int num; /* write number */ -} dw_req_t; - -static dw_des_t * -new_dwd(char *path) -{ - dw_des_t *dwd; - - dwd = (dw_des_t *)malloc(sizeof (dw_des_t)); - (void) memset(dwd, 0, sizeof (dw_des_t)); - - dwd->path = path; - dwd->wlist = new_list(); - - return (dwd); -} - -/* - * Parse a delayed-write property into a delayed-write request. - * The property name is of the form 'writeN' where N represents - * the Nth write request to the pathname encoded in the property's value. - */ -static void -parse_dw(ddi_prop_t *prop, char **path, dw_req_t **dwrp) -{ - int plen; - caddr_t tok; - dw_req_t *dwr; - - dwr = (dw_req_t *)malloc(sizeof (dw_req_t)); - dwr->num = atoi(&prop->prop_name[5]); - - tok = prop->prop_val; - plen = *((int *)tok); - tok += 4; - *path = (char *)tok; - tok += plen; - dwr->len = *((int *)tok); - tok += 4; - dwr->adr = tok; - - *dwrp = dwr; -} - -/* - * Sync a delayed-write out request to a file. - */ -static void -sync_dwr(char *relpath, dw_req_t *dwr) -{ - int fd; - char *p, *path; - - path = strcats(boottree, "/", relpath, NULL); - p = strrchr(path, '/'); - *p = NULL; - - - if (access(path, F_OK) != 0) { - if (mkdirp(path, 755) == -1) - exit(_error(PERROR, "cannot mkdir %s", path)); - } - - *p = '/'; - - if ((fd = open(path, O_RDWR|O_CREAT|O_TRUNC, 0644)) == -1) - exit(_error(PERROR, "cannot open %s", path)); - - - if (write(fd, dwr->adr, dwr->len) != dwr->len) - exit(_error(PERROR, "cannot write %s", path)); - - if (verbose) - printf("sync \"%s\" size %d data <%s>\n", - path, dwr->len, dwr->adr); - - close(fd); - free(path); -} - -/* - * Sync all delayed-write requests from the boot. - */ -void -sync_benv(void) -{ - ddi_prop_t *prop, *plist; - eplist_t *dwlp, *pl, *wl; - dw_des_t *dwd; - dw_req_t *dwr, *dwrlast; - - if ((plist = get_proplist("delayed-writes")) == NULL) { - if (verbose) - printf("no delayed writes.\n"); - return; - } - - dwlp = new_list(); - - /* - * Parse each property into a delayed-write request for - * for a given file. - */ - for (prop = plist; prop != NULL; prop = prop->prop_next) { - if (strncmp(prop->prop_name, "write", 5) == 0) { - char *path; - - parse_dw(prop, &path, &dwr); - - if (verbose) - printf("write \"%s\"\n", path); - - /* - * Get a delayed-write descriptor for each - * new file. Add all delayed-write requests - * for a given file to the descriptor's request - * list. - */ - for (pl = dwlp->next; pl != dwlp; pl = pl->next) { - dwd = (dw_des_t *)pl->item; - - if (strcmp(dwd->path, path) == 0) - break; - } - - if (pl == dwlp) { - dwd = new_dwd(path); - add_item((void *)dwd, dwlp); - } - - add_item((void *)dwr, dwd->wlist); - } - } - - /* - * Process the last request for each path. We only need to - * do the last request since the writes are destructive and - * overwrite all previous file contents. - */ - for (pl = dwlp->next; pl != dwlp; pl = pl->next) { - dwd = (dw_des_t *)(pl->item); - dwrlast = NULL; - - for (wl = dwd->wlist->next; wl != dwd->wlist; wl = wl->next) { - dwr = (dw_req_t *)(wl->item); - if (dwrlast == NULL || dwr->num >= dwrlast->num) - dwrlast = dwr; - } - - if (dwrlast != NULL) - sync_dwr(dwd->path, dwrlast); - } -} diff --git a/usr/src/cmd/eeprom/sparc/Makefile b/usr/src/cmd/eeprom/sparc/Makefile index e3579bd4dc..7215f7466a 100644 --- a/usr/src/cmd/eeprom/sparc/Makefile +++ b/usr/src/cmd/eeprom/sparc/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,26 +21,18 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# cmd/eeprom/sparc/Makefile -# -SRCDIR=.. -SUBDIRS= sun4u sun4v +SRCDIR = .. -all:= TARGET= all -install:= TARGET= install -clean:= TARGET= clean -clobber:= TARGET= clobber -lint:= TARGET= lint +include $(SRCDIR)/Makefile.com -.KEEP_STATE: +OBJS += openprom.o loadlogo.o -all install clean clobber lint : $(SUBDIRS) +.KEEP_STATE: -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) +all: $(PROG) -FRC: +include $(SRCDIR)/Makefile.targ diff --git a/usr/src/cmd/eeprom/common/loadlogo.c b/usr/src/cmd/eeprom/sparc/loadlogo.c index ebd30f324e..ebd30f324e 100644 --- a/usr/src/cmd/eeprom/common/loadlogo.c +++ b/usr/src/cmd/eeprom/sparc/loadlogo.c diff --git a/usr/src/cmd/eeprom/common/openprom.c b/usr/src/cmd/eeprom/sparc/openprom.c index 36bf325a62..36bf325a62 100644 --- a/usr/src/cmd/eeprom/common/openprom.c +++ b/usr/src/cmd/eeprom/sparc/openprom.c diff --git a/usr/src/cmd/eeprom/sparc/sun4u/Makefile b/usr/src/cmd/eeprom/sparc/sun4u/Makefile deleted file mode 100644 index 2cb9c73cfb..0000000000 --- a/usr/src/cmd/eeprom/sparc/sun4u/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright (c) 1993 by Sun Microsystems, Inc. -# -# cmd/eeprom/sparc/sun4u/Makefile -# -# Platform specific Makefile for the eeprom command. -# -# PLATFORM is the target for the binary instalation. -# -# PLATLINKS is a list of platforms which are to be linked to this binary -# at the file level. -# -SRCDIR = ../.. -PLATFORM = sun4u -#PLATLINKS = SUNW,SPARCstation-fusion - -include $(SRCDIR)/Makefile.com - -.KEEP_STATE: - -all: $(PROG) - -include $(SRCDIR)/Makefile.targ diff --git a/usr/src/cmd/eeprom/sparc/sun4v/Makefile b/usr/src/cmd/eeprom/sparc/sun4v/Makefile deleted file mode 100644 index d4cb137cff..0000000000 --- a/usr/src/cmd/eeprom/sparc/sun4v/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -#ident "%Z%%M% %I% %E% SMI" -# -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# cmd/eeprom/sparc/sun4v/Makefile -# -# Platform specific Makefile for the eeprom command. -# -# PLATFORM is the target for the binary instalation. -# -# PLATLINKS is a list of platforms which are to be linked to this binary -# at the file level. -# -SRCDIR = ../.. -PLATFORM = sun4v - -include $(SRCDIR)/Makefile.com - -.KEEP_STATE: - -all: $(PROG) - -include $(SRCDIR)/Makefile.targ diff --git a/usr/src/cmd/mdb/common/kmdb/kaif_start.c b/usr/src/cmd/mdb/common/kmdb/kaif_start.c index 17f136b307..6c0fc810bb 100644 --- a/usr/src/cmd/mdb/common/kmdb/kaif_start.c +++ b/usr/src/cmd/mdb/common/kmdb/kaif_start.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -80,6 +80,13 @@ kaif_lock_exit(uintptr_t *lock) membar_producer(); } +static void +kaif_start_slaves(int cmd) +{ + kaif_slave_cmd = cmd; + kmdb_kdi_start_slaves(); +} + static int kaif_master_loop(kaif_cpusave_t *cpusave) { @@ -90,6 +97,12 @@ kaif_master_loop(kaif_cpusave_t *cpusave) #endif kaif_trap_set_debugger(); + /* + * If we re-entered due to a ::switch, we need to tell the slave CPUs + * to sleep again. + */ + kmdb_kdi_stop_slaves(cpusave->krs_cpu_id, 0); + master_loop: switch (kmdb_dpi_reenter()) { case KMDB_DPI_CMD_SWITCH_CPU: @@ -112,7 +125,7 @@ master_loop: */ kaif_trap_set_saved(cpusave); - kaif_slave_cmd = KAIF_SLAVE_CMD_SWITCH; + kaif_start_slaves(KAIF_SLAVE_CMD_SWITCH); /* The new master is now awake */ return (KAIF_CPU_CMD_SWITCH); @@ -124,7 +137,7 @@ master_loop: */ kaif_master_cpuid = KAIF_MASTER_CPUID_UNSET; membar_producer(); - kaif_slave_cmd = KAIF_SLAVE_CMD_RESUME; + kaif_start_slaves(KAIF_SLAVE_CMD_RESUME); if (kmdb_dpi_work_required()) kmdb_dpi_wrintr_fire(); @@ -141,7 +154,7 @@ master_loop: return (KAIF_CPU_CMD_RESUME_MASTER); case KMDB_DPI_CMD_FLUSH_CACHES: - kaif_slave_cmd = KAIF_SLAVE_CMD_FLUSH; + kaif_start_slaves(KAIF_SLAVE_CMD_FLUSH); /* * Wait for the other cpus to finish flushing their caches. @@ -170,9 +183,9 @@ master_loop: * afraid that I don't want to know the answer. */ if (cpusave->krs_cpu_id == 0) - return (KAIF_CPU_CMD_REBOOT); + kmdb_kdi_reboot(); - kaif_slave_cmd = KAIF_SLAVE_CMD_REBOOT; + kaif_start_slaves(KAIF_SLAVE_CMD_REBOOT); /* * Spin forever, waiting for CPU 0 (apparently a slave) to @@ -223,7 +236,8 @@ kaif_slave_loop(kaif_cpusave_t *cpusave) #if defined(__i386) || defined(__amd64) } else if (slavecmd == KAIF_SLAVE_CMD_REBOOT && cpusave->krs_cpu_id == 0) { - rv = KAIF_CPU_CMD_REBOOT; + rv = 0; + kmdb_kdi_reboot(); break; #endif @@ -238,6 +252,8 @@ kaif_slave_loop(kaif_cpusave_t *cpusave) cpusave->krs_cpu_acked = 0; #endif } + + kmdb_kdi_slave_wait(); } #if defined(__sparc) @@ -260,9 +276,7 @@ kaif_select_master(kaif_cpusave_t *cpusave) membar_producer(); - kmdb_kdi_stop_other_cpus(cpusave->krs_cpu_id, - kaif_slave_entry); - + kmdb_kdi_stop_slaves(cpusave->krs_cpu_id, 1); } else { /* The master was already chosen - go be a slave */ cpusave->krs_cpu_state = KAIF_CPU_STATE_SLAVE; @@ -405,7 +419,7 @@ kaif_slave_loop_barrier(void) int not_acked; int timeout_count = 0; - kaif_slave_cmd = KAIF_SLAVE_CMD_ACK; + kaif_start_slaves(KAIF_SLAVE_CMD_ACK); /* * Wait for slave cpus to explicitly acknowledge diff --git a/usr/src/cmd/mdb/common/kmdb/kaif_start.h b/usr/src/cmd/mdb/common/kmdb/kaif_start.h index a0234cb493..40ddc252b5 100644 --- a/usr/src/cmd/mdb/common/kmdb/kaif_start.h +++ b/usr/src/cmd/mdb/common/kmdb/kaif_start.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -30,7 +29,7 @@ #pragma ident "%Z%%M% %I% %E% SMI" #include <sys/types.h> -#include <kmdb/kaif_regs.h> +#include <kmdb/kaif.h> #ifdef __cplusplus extern "C" { @@ -40,6 +39,12 @@ extern int kaif_main_loop(kaif_cpusave_t *); extern int kaif_master_cpuid; +#define KAIF_MASTER_CPUID_UNSET -1 + +#define KAIF_CPU_CMD_RESUME 0 +#define KAIF_CPU_CMD_RESUME_MASTER 1 +#define KAIF_CPU_CMD_SWITCH 2 + #ifdef __cplusplus } #endif diff --git a/usr/src/cmd/mdb/common/kmdb/kctl/kctl.h b/usr/src/cmd/mdb/common/kmdb/kctl/kctl.h index 612ed8db13..8c082d6649 100644 --- a/usr/src/cmd/mdb/common/kmdb/kctl/kctl.h +++ b/usr/src/cmd/mdb/common/kmdb/kctl/kctl.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -49,7 +49,6 @@ typedef enum { KCTL_ST_MOD_NOTIFIERS, /* krtld module notifiers registered */ KCTL_ST_THREAD_STARTED, /* WR queue thread started */ KCTL_ST_DBG_ACTIVATED, /* kmdb activated */ - KCTL_ST_KCTL_ACTIVATED, /* kctl activated */ KCTL_ST_ACTIVE, /* kernel is aware of kmdb activation */ KCTL_ST_DEACTIVATING /* debugger is being deactivated */ } kctl_state_t; @@ -93,9 +92,8 @@ extern void kctl_dprintf(const char *, ...); extern void kctl_warn(const char *, ...); extern int kctl_preactivate_isadep(void); -extern int kctl_activate_isadep(kdi_debugvec_t *); +extern void kctl_activate_isadep(kdi_debugvec_t *); extern void kctl_depreactivate_isadep(void); -extern void kctl_deactivate_isadep(void); extern void kctl_cleanup(void); extern void *kctl_boot_tmpinit(void); diff --git a/usr/src/cmd/mdb/common/kmdb/kctl/kctl_auxv.c b/usr/src/cmd/mdb/common/kmdb/kctl/kctl_auxv.c index 1ea1216ae6..773a088783 100644 --- a/usr/src/cmd/mdb/common/kmdb/kctl/kctl_auxv.c +++ b/usr/src/cmd/mdb/common/kmdb/kctl/kctl_auxv.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -83,28 +82,15 @@ kctl_auxv_init(kmdb_auxv_t *kav, const char *cfg, const char **argv, void *romp) kav->kav_config = cfg; kav->kav_argv = argv; + kav->kav_modpath = kobj_module_path; - if (kctl.kctl_boot_loaded) { - /* - * default_path hasn't been set yet, so we have to fetch the - * path from OBP. - */ - ssize_t sz; - - if ((sz = BOP_GETPROPLEN(kctl.kctl_boot_ops, - "module-path")) != -1) { - kav->kav_modpath = kobj_alloc(sz, KM_TMP); - (void) BOP_GETPROP(kctl.kctl_boot_ops, "module-path", - (char *)kav->kav_modpath); - } + kctl_dprintf("kctl_auxv_init: modpath '%s'", kav->kav_modpath); + if (kctl.kctl_boot_loaded) { kav->kav_lookup_by_name = kctl_boot_lookup_by_name; kav->kav_flags |= KMDB_AUXV_FL_NOUNLOAD; - } else { - kav->kav_modpath = default_path; - + } else kav->kav_lookup_by_name = kctl_lookup_by_name; - } if (kctl.kctl_flags & KMDB_F_TRAP_NOSWITCH) kav->kav_flags |= KMDB_AUXV_FL_NOTRPSWTCH; diff --git a/usr/src/cmd/mdb/common/kmdb/kctl/kctl_dmod.c b/usr/src/cmd/mdb/common/kmdb/kctl/kctl_dmod.c index 76fc32bdc6..36a088e437 100644 --- a/usr/src/cmd/mdb/common/kmdb/kctl/kctl_dmod.c +++ b/usr/src/cmd/mdb/common/kmdb/kctl/kctl_dmod.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -76,7 +76,7 @@ kctl_find_module(char *modname, char *fullname, size_t fullnamelen) /* If they gave us an absolute path, we don't need to search */ if (modname[0] == '/') { if (strlen(modname) + 1 > fullnamelen) { - cmn_err(CE_WARN, "Can't load dmod %s - name too long\n", + cmn_err(CE_WARN, "Can't load dmod %s - name too long", modname); return (0); } @@ -343,7 +343,7 @@ kctl_dmod_unload(kmdb_wr_unload_t *dur) int rc; if ((rc = kctl_dmod_unload_common(dur->dur_modctl)) != 0) { - cmn_err(CE_WARN, "unexpected dmod unload failure: %d\n", rc); + cmn_err(CE_WARN, "unexpected dmod unload failure: %d", rc); dur->dur_errno = rc; } } diff --git a/usr/src/cmd/mdb/common/kmdb/kctl/kctl_main.c b/usr/src/cmd/mdb/common/kmdb/kctl/kctl_main.c index 13992c6ae2..11b6ec8231 100644 --- a/usr/src/cmd/mdb/common/kmdb/kctl/kctl_main.c +++ b/usr/src/cmd/mdb/common/kmdb/kctl/kctl_main.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -192,17 +191,13 @@ kctl_memavail(void) * If we're going to wedge the machine during debugger startup, * at least let them know why it's going to wedge. */ - cmn_err(CE_WARN, "retrying of kmdb allocation of 0x%lx bytes\n", + cmn_err(CE_WARN, "retrying of kmdb allocation of 0x%lx bytes", (ulong_t)needed); base = kmem_zalloc(needed, KM_SLEEP); } - if (kdi_dvec->dv_memavail(base, needed) < 0) { - cmn_err(CE_WARN, "failed to add memory to debugger\n"); - kmem_free(base, needed); - } - + kdi_dvec->dv_memavail(base, needed); kctl.kctl_mrbase = base; kctl.kctl_mrsize = needed; } @@ -223,10 +218,6 @@ kctl_cleanup(void) kdi_dvec = NULL; /*FALLTHROUGH*/ - case KCTL_ST_KCTL_ACTIVATED: - kctl_deactivate_isadep(); - /*FALLTHROUGH*/ - case KCTL_ST_DBG_ACTIVATED: KCTL_PROM_LOCK; kmdb_deactivate(); @@ -375,10 +366,7 @@ kctl_startup_activate(uint_t flags) dvec->dv_kctl_thravail = kctl_startup_thread; dvec->dv_kctl_memavail = kctl_memavail; - if (kctl_activate_isadep(dvec) != 0) - return (EIO); - - (void) kctl_set_state(KCTL_ST_KCTL_ACTIVATED); + kctl_activate_isadep(dvec); kdi_dvec = dvec; membar_producer(); @@ -425,7 +413,7 @@ kctl_deactivate(void) goto deactivate_done; kmdb_kdi_set_unload_request(); - kdi_dvec_enter(); + kmdb_kdi_kmdb_enter(); /* * The debugger will pass the request to the work thread, which will @@ -487,13 +475,14 @@ kctl_boot_activate(struct bootops *ops, void *romp, size_t memsz, if (memsz == 0) memsz = KCTL_MEM_GOALSZ; - kctl.kctl_dseg = (caddr_t)SEGDEBUGBASE; - kctl.kctl_dseg_size = (memsz > SEGDEBUGSIZE ? SEGDEBUGSIZE : memsz); + kctl.kctl_dseg = kdi_segdebugbase; + kctl.kctl_dseg_size = + memsz > kdi_segdebugsize ? kdi_segdebugsize : memsz; kctl.kctl_memgoalsz = memsz; if (kctl_boot_dseg_alloc(kctl.kctl_dseg, kctl.kctl_dseg_size) < 0) { - kctl_warn("kmdb: failed to allocate %d-byte debugger area at " - "%x", kctl.kctl_dseg_size, kctl.kctl_dseg); + kctl_warn("kmdb: failed to allocate %lu-byte debugger area at " + "%p", kctl.kctl_dseg_size, (void *)kctl.kctl_dseg); return (-1); } @@ -510,9 +499,10 @@ kctl_boot_activate(struct bootops *ops, void *romp, size_t memsz, kctl_dprintf("finished with kmdb initialization"); - kctl.kctl_boot_ops = NULL; kctl_boot_tmpfini(old); + kctl.kctl_boot_ops = NULL; + return (0); } @@ -525,7 +515,7 @@ kctl_modload_activate(size_t memsz, const char *cfg, uint_t flags) if ((rc = kctl_state_check(kctl.kctl_state, KCTL_ST_INACTIVE)) != 0) { if ((flags & KMDB_F_AUTO_ENTRY) && rc == EMDB_KACTIVE) { - kdi_dvec_enter(); + kmdb_kdi_kmdb_enter(); rc = 0; } @@ -538,8 +528,9 @@ kctl_modload_activate(size_t memsz, const char *cfg, uint_t flags) if (memsz == 0) memsz = KCTL_MEM_GOALSZ; - kctl.kctl_dseg = (caddr_t)SEGDEBUGBASE; - kctl.kctl_dseg_size = (memsz > SEGDEBUGSIZE ? SEGDEBUGSIZE : memsz); + kctl.kctl_dseg = kdi_segdebugbase; + kctl.kctl_dseg_size = + memsz > kdi_segdebugsize ? kdi_segdebugsize : memsz; kctl.kctl_memgoalsz = memsz; if ((rc = kctl_dseg_alloc(kctl.kctl_dseg, kctl.kctl_dseg_size)) != 0) @@ -559,7 +550,7 @@ kctl_modload_activate(size_t memsz, const char *cfg, uint_t flags) kctl_memavail(); /* Must be after kdi_dvec is set */ if (kctl.kctl_flags & KMDB_F_AUTO_ENTRY) - kdi_dvec_enter(); + kmdb_kdi_kmdb_enter(); mutex_exit(&kctl.kctl_lock); return (0); diff --git a/usr/src/cmd/mdb/common/kmdb/kctl/kctl_wr.c b/usr/src/cmd/mdb/common/kmdb/kctl/kctl_wr.c index 0b8103ae70..b9d54edc02 100644 --- a/usr/src/cmd/mdb/common/kmdb/kctl/kctl_wr.c +++ b/usr/src/cmd/mdb/common/kmdb/kctl/kctl_wr.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -256,7 +255,7 @@ kctl_wr_thread(void *arg) * debugger for processing, so we need to wake the debugger up. */ if (kctl_wr_process() > 0) - kdi_dvec_enter(); + kmdb_kdi_kmdb_enter(); } /* diff --git a/usr/src/cmd/mdb/common/kmdb/kmdb_dpi_impl.h b/usr/src/cmd/mdb/common/kmdb/kmdb_dpi_impl.h index fe4bd9458b..a94cfae990 100644 --- a/usr/src/cmd/mdb/common/kmdb/kmdb_dpi_impl.h +++ b/usr/src/cmd/mdb/common/kmdb/kmdb_dpi_impl.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -95,10 +94,8 @@ struct dpi_ops { void (*dpo_dump_crumbs)(uintptr_t, int); - int (*dpo_memrange_add)(caddr_t, size_t); - #if defined(__i386) || defined(__amd64) - void (*dpo_msr_add)(const kmdb_msr_t *); + void (*dpo_msr_add)(const kdi_msr_t *); uint64_t (*dpo_msr_get)(int, uint_t); #endif diff --git a/usr/src/cmd/mdb/common/kmdb/kmdb_kdi.c b/usr/src/cmd/mdb/common/kmdb/kmdb_kdi.c index 7d2f674748..c9e3358af9 100644 --- a/usr/src/cmd/mdb/common/kmdb/kmdb_kdi.c +++ b/usr/src/cmd/mdb/common/kmdb/kmdb_kdi.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -50,7 +49,7 @@ #include <sys/kdi_impl.h> -#include <kmdb/kmdb_kdi_impl.h> +#include <kmdb/kmdb_kdi.h> #include <kmdb/kmdb_dpi.h> #include <kmdb/kmdb_kvm.h> #include <kmdb/kmdb_promif.h> @@ -221,6 +220,12 @@ kmdb_kdi_get_polled_io(void) return (mdb.m_kdi->kdi_get_polled_io()); } +void +kmdb_kdi_kmdb_enter(void) +{ + mdb.m_kdi->kdi_kmdb_enter(); +} + int kmdb_kdi_vtop(uintptr_t va, physaddr_t *pap) { @@ -284,8 +289,6 @@ kmdb_kdi_init(kdi_t *kdi, kmdb_auxv_t *kav) kdi_auxv = kav; kmdb_kdi_init_isadep(kdi, kav); - - kdi_cpu_init(); } void diff --git a/usr/src/cmd/mdb/common/kmdb/kmdb_kdi.h b/usr/src/cmd/mdb/common/kmdb/kmdb_kdi.h index 8ffd0f2cab..28f047a33a 100644 --- a/usr/src/cmd/mdb/common/kmdb/kmdb_kdi.h +++ b/usr/src/cmd/mdb/common/kmdb/kmdb_kdi.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -69,7 +68,10 @@ extern int kmdb_kdi_mod_haschanged(struct modctl *, struct module *, struct modctl *, struct module *); extern ssize_t kmdb_kdi_pread(void *, size_t, physaddr_t); extern ssize_t kmdb_kdi_pwrite(void *, size_t, physaddr_t); -extern void kmdb_kdi_stop_other_cpus(int, void (*)(void)); /* Driver OK */ +extern void kmdb_kdi_stop_slaves(int, int); +extern void kmdb_kdi_start_slaves(void); +extern void kmdb_kdi_slave_wait(void); +extern void kmdb_kdi_kmdb_enter(void); /* Driver OK */ extern void kmdb_kdi_system_claim(void); extern void kmdb_kdi_system_release(void); extern size_t kmdb_kdi_range_is_nontoxic(uintptr_t, size_t, int); diff --git a/usr/src/cmd/mdb/common/kmdb/kmdb_kdi_impl.h b/usr/src/cmd/mdb/common/kmdb/kmdb_kdi_impl.h deleted file mode 100644 index 3ff5deb4ee..0000000000 --- a/usr/src/cmd/mdb/common/kmdb/kmdb_kdi_impl.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _KMDB_KDI_IMPL_H -#define _KMDB_KDI_IMPL_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <kmdb/kmdb_kdi.h> - -#ifdef __cplusplus -extern "C" { -#endif - -extern void kdi_cpu_init(void); -extern void kdi_usecwait(clock_t); - -#ifdef __cplusplus -} -#endif - -#endif /* _KMDB_KDI_IMPL_H */ diff --git a/usr/src/cmd/mdb/common/kmdb/kmdb_kvm.c b/usr/src/cmd/mdb/common/kmdb/kmdb_kvm.c index 18f0d4eb7c..a79d455af1 100644 --- a/usr/src/cmd/mdb/common/kmdb/kmdb_kvm.c +++ b/usr/src/cmd/mdb/common/kmdb/kmdb_kvm.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -977,7 +976,7 @@ kmt_lookup_by_name(mdb_tgt_t *t, const char *obj, const char *name, break; case (uintptr_t)MDB_TGT_OBJ_RTLD: - obj = KMT_RTLD_NAME; + obj = kmt->kmt_rtld_name; /*FALLTHROUGH*/ default: @@ -1081,7 +1080,7 @@ kmt_symbol_iter(mdb_tgt_t *t, const char *obj, uint_t which, uint_t type, return (0); case (uintptr_t)MDB_TGT_OBJ_RTLD: - obj = KMT_RTLD_NAME; + obj = kmt->kmt_rtld_name; /*FALLTHROUGH*/ default: @@ -1197,6 +1196,20 @@ kmt_addr_to_map(mdb_tgt_t *t, uintptr_t addr) return (NULL); } +static kmt_module_t * +kmt_module_by_name(kmt_data_t *kmt, const char *name) +{ + kmt_module_t *km; + + for (km = mdb_list_next(&kmt->kmt_modlist); km != NULL; + km = mdb_list_next(km)) { + if (strcmp(name, km->km_name) == 0) + return (km); + } + + return (NULL); +} + static const mdb_map_t * kmt_name_to_map(mdb_tgt_t *t, const char *name) { @@ -1214,13 +1227,10 @@ kmt_name_to_map(mdb_tgt_t *t, const char *name) } if (name == MDB_TGT_OBJ_RTLD) - name = KMT_RTLD_NAME; /* replace MDB_TGT_OBJ_RTLD with krtld */ + name = kmt->kmt_rtld_name; - for (km = mdb_list_next(&kmt->kmt_modlist); km != NULL; - km = mdb_list_next(km)) { - if (strcmp(name, km->km_name) == 0) - return (kmt_mod_to_map(km, &m)); - } + if ((km = kmt_module_by_name(kmt, name)) != NULL) + return (kmt_mod_to_map(km, &m)); (void) set_errno(EMDB_NOOBJ); return (NULL); @@ -1300,19 +1310,16 @@ kmt_name_to_ctf(mdb_tgt_t *t, const char *name) kmt_module_t *km; if (name == MDB_TGT_OBJ_EXEC) { - name = KMT_CTFPARENT; /* base CTF data is kept in genunix */ + name = KMT_CTFPARENT; } else if (name == MDB_TGT_OBJ_RTLD) { - name = KMT_RTLD_NAME; /* replace with krtld */ + name = kt->kmt_rtld_name; } else if (strncmp(name, "DMOD`", 5) == 0) { /* Request for CTF data for a DMOD symbol */ return (kmdb_module_name_to_ctf(name + 5)); } - for (km = mdb_list_next(&kt->kmt_modlist); km != NULL; - km = mdb_list_next(km)) { - if (strcmp(name, km->km_name) == 0) - return (kmt_load_ctfdata(t, km)); - } + if ((km = kmt_module_by_name(kt, name)) != NULL) + return (kmt_load_ctfdata(t, km)); (void) set_errno(EMDB_NOOBJ); return (NULL); @@ -2344,6 +2351,12 @@ kmt_activate(mdb_tgt_t *t) (void) mdb_tgt_register_dcmds(t, &kmt_dcmds[0], MDB_MOD_FORCE); mdb_tgt_register_regvars(t, kmt->kmt_rds, &kmt_reg_disc, 0); + + /* + * Force load of the MDB krtld module, in case it's been rolled into + * unix. + */ + (void) mdb_module_load(KMT_RTLD_NAME, MDB_MOD_SILENT | MDB_MOD_DEFER); } static void @@ -2525,6 +2538,8 @@ create_err: void kmdb_kvm_startup(void) { + kmt_data_t *kmt = mdb.m_target->t_data; + mdb_dprintf(MDB_DBG_KMOD, "kmdb_kvm startup\n"); kmt_sync(mdb.m_target); @@ -2538,6 +2553,11 @@ kmdb_kvm_startup(void) * startup. */ (void) mdb_tgt_sespec_activate_all(mdb.m_target); + + kmt->kmt_rtld_name = KMT_RTLD_NAME; + + if (kmt_module_by_name(kmt, KMT_RTLD_NAME) == NULL) + kmt->kmt_rtld_name = "unix"; } /* diff --git a/usr/src/cmd/mdb/common/kmdb/kmdb_promif.c b/usr/src/cmd/mdb/common/kmdb/kmdb_promif.c index 0757ccb48d..135a22e4d0 100644 --- a/usr/src/cmd/mdb/common/kmdb/kmdb_promif.c +++ b/usr/src/cmd/mdb/common/kmdb/kmdb_promif.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -52,24 +52,31 @@ static char kmdb_prom_readbuf[KMDB_PROM_READBUF_SIZE]; static int kmdb_prom_readbuf_head; static int kmdb_prom_readbuf_tail; -static ssize_t -kmdb_prom_polled_read(caddr_t buf, size_t len) +static int +kmdb_prom_getchar(int wait) { - uintptr_t arg = (uintptr_t)mdb.m_pio->cons_polledio_argument; - uintptr_t ischar = (uintptr_t)mdb.m_pio->cons_polledio_ischar; - int nread = 0; - int c; + struct cons_polledio *pio = mdb.m_pio; + uintptr_t ischar; + uintptr_t getchar; + uintptr_t arg; + + if (pio == NULL || pio->cons_polledio_getchar == NULL) { + int c; + while ((c = prom_mayget()) == -1) { + if (!wait) + return (-1); + } + return (c); + } - while ((ischar == NULL || kmdb_dpi_call(ischar, 1, &arg)) && - nread < len) { - c = kmdb_dpi_call((uintptr_t)mdb.m_pio->cons_polledio_getchar, - 1, &arg); + ischar = (uintptr_t)pio->cons_polledio_ischar; + getchar = (uintptr_t)pio->cons_polledio_getchar; + arg = (uintptr_t)pio->cons_polledio_argument; - *buf++ = (char)c; - nread++; - } + if (!wait && ischar != NULL && !kmdb_dpi_call(ischar, 1, &arg)) + return (-1); - return (nread); + return ((int)kmdb_dpi_call(getchar, 1, &arg)); } static ssize_t @@ -90,17 +97,18 @@ kmdb_prom_polled_write(caddr_t buf, size_t len) } static ssize_t -kmdb_prom_reader(caddr_t buf, size_t len) +kmdb_prom_reader(caddr_t buf, size_t len, int wait) { int nread = 0; int c; - if (mdb.m_pio != NULL && mdb.m_pio->cons_polledio_getchar != NULL) - return (kmdb_prom_polled_read(buf, len)); + while (nread < len) { + if ((c = kmdb_prom_getchar(wait)) == -1) + break; - while (nread < len && (c = prom_mayget()) != -1) { *buf++ = (char)c; nread++; + wait = 0; } return (nread); @@ -217,7 +225,7 @@ check_int(char *buf, size_t len) * delivering an interrupt directly if we find one. */ static void -kmdb_prom_fill_readbuf(int check_for_int) +kmdb_prom_fill_readbuf(int check_for_int, int wait) { int oldhead, left, n; @@ -238,7 +246,7 @@ kmdb_prom_fill_readbuf(int check_for_int) * the common code handle the second. */ if ((n = kmdb_prom_reader(kmdb_prom_readbuf + - kmdb_prom_readbuf_head, left)) <= 0) + kmdb_prom_readbuf_head, left, wait)) <= 0) return; oldhead = kmdb_prom_readbuf_head; @@ -255,7 +263,7 @@ kmdb_prom_fill_readbuf(int check_for_int) left = kmdb_prom_readbuf_tail - kmdb_prom_readbuf_head - 1; if (left > 0) { if ((n = kmdb_prom_reader(kmdb_prom_readbuf + - kmdb_prom_readbuf_head, left)) <= 0) + kmdb_prom_readbuf_head, left, wait)) <= 0) return; oldhead = kmdb_prom_readbuf_head; @@ -272,7 +280,7 @@ kmdb_prom_fill_readbuf(int check_for_int) if (check_for_int) { char c; - while (kmdb_prom_reader(&c, 1) == 1) + while (kmdb_prom_reader(&c, 1, 0) == 1) check_int(&c, 1); } } @@ -280,7 +288,7 @@ kmdb_prom_fill_readbuf(int check_for_int) void kmdb_prom_check_interrupt(void) { - kmdb_prom_fill_readbuf(1); + kmdb_prom_fill_readbuf(1, 0); } /* @@ -294,9 +302,10 @@ kmdb_prom_read(void *buf, size_t len, struct termios *tio) size_t totread = 0; size_t thisread; char *c = (char *)buf; + int wait = 1; for (;;) { - kmdb_prom_fill_readbuf(0); + kmdb_prom_fill_readbuf(0, wait); thisread = kmdb_prom_drain_readbuf(c, len); len -= thisread; totread += thisread; @@ -306,6 +315,8 @@ kmdb_prom_read(void *buf, size_t len, struct termios *tio) if (totread == 0) continue; + wait = 0; + /* * We're done if we've exhausted available input or if we've * filled the provided buffer. diff --git a/usr/src/cmd/mdb/common/kmdb/kvm.h b/usr/src/cmd/mdb/common/kmdb/kvm.h index 4c1786dbf6..414a79eca9 100644 --- a/usr/src/cmd/mdb/common/kmdb/kvm.h +++ b/usr/src/cmd/mdb/common/kmdb/kvm.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -80,6 +80,7 @@ typedef struct kmt_data { const mdb_tgt_regdesc_t *kmt_rds; /* Register description table */ mdb_nv_t kmt_modules; /* Hash table of modules */ mdb_list_t kmt_modlist; /* List of mods in load order */ + const char *kmt_rtld_name; /* Module containing krtld */ caddr_t kmt_writemap; /* Used to map PAs for writes */ size_t kmt_writemapsz; /* Size of same */ mdb_map_t kmt_map; /* Persistant map for callers */ diff --git a/usr/src/cmd/mdb/common/mdb/mdb_ks.h b/usr/src/cmd/mdb/common/mdb/mdb_ks.h index bb3038dcd8..3ea1343492 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_ks.h +++ b/usr/src/cmd/mdb/common/mdb/mdb_ks.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -65,7 +65,7 @@ extern int mdb_devinfo2statep(uintptr_t, char *, uintptr_t *); extern int mdb_cpu2cpuid(uintptr_t); -extern int mdb_cpuset_find(uintptr_t cpusetp); +extern int mdb_cpuset_find(uintptr_t); /* * Returns a pointer to the top of the soft state struct for the instance diff --git a/usr/src/cmd/mdb/common/mdb/mdb_kvm.c b/usr/src/cmd/mdb/common/mdb/mdb_kvm.c index c2e71bb643..853feb80d1 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_kvm.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_kvm.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -90,7 +89,6 @@ typedef struct kt_maparg { void *map_data; /* Callback function argument */ } kt_maparg_t; -static const char KT_RTLD_NAME[] = "krtld"; static const char KT_MODULE[] = "mdb_ks"; static const char KT_CTFPARENT[] = "genunix"; @@ -491,6 +489,19 @@ reg_disc_get(const mdb_var_t *v) return (r); } +static kt_module_t * +kt_module_by_name(kt_data_t *kt, const char *name) +{ + kt_module_t *km; + + for (km = mdb_list_next(&kt->k_modlist); km; km = mdb_list_next(km)) { + if (strcmp(name, km->km_name) == 0) + return (km); + } + + return (NULL); +} + void kt_activate(mdb_tgt_t *t) { @@ -546,9 +557,23 @@ kt_activate(mdb_tgt_t *t) mdb_iob_flush(mdb.m_out); } - if (!(t->t_flags & MDB_TGT_F_NOLOAD)) + if (!(t->t_flags & MDB_TGT_F_NOLOAD)) { kt_load_modules(kt, t); + /* + * Determine where the CTF data for krtld is. If krtld + * is rolled into unix, force load the MDB krtld + * module. + */ + kt->k_rtld_name = "krtld"; + + if (kt_module_by_name(kt, "krtld") == NULL) { + (void) mdb_module_load("krtld", MDB_MOD_SILENT); + kt->k_rtld_name = "unix"; + } + } + + if (t->t_flags & MDB_TGT_F_PRELOAD) { mdb_iob_puts(mdb.m_out, " ]\n"); mdb_iob_setflags(mdb.m_out, oflag); @@ -778,7 +803,7 @@ kt_lookup_by_name(mdb_tgt_t *t, const char *obj, const char *name, break; case (uintptr_t)MDB_TGT_OBJ_RTLD: - obj = KT_RTLD_NAME; + obj = kt->k_rtld_name; /*FALLTHRU*/ default: @@ -964,7 +989,7 @@ kt_symbol_iter(mdb_tgt_t *t, const char *obj, uint_t which, uint_t type, break; case (uintptr_t)MDB_TGT_OBJ_RTLD: - obj = KT_RTLD_NAME; + obj = kt->k_rtld_name; /*FALLTHRU*/ default: @@ -1092,12 +1117,10 @@ kt_name_to_map(mdb_tgt_t *t, const char *name) return (kt_module_to_map(mdb_list_next(&kt->k_modlist), &m)); if (name == MDB_TGT_OBJ_RTLD) - name = KT_RTLD_NAME; /* replace MDB_TGT_OBJ_RTLD with krtld */ + name = kt->k_rtld_name; - for (km = mdb_list_next(&kt->k_modlist); km; km = mdb_list_next(km)) { - if (strcmp(name, km->km_name) == 0) - return (kt_module_to_map(km, &m)); - } + if ((km = kt_module_by_name(kt, name)) != NULL) + return (kt_module_to_map(km, &m)); (void) set_errno(EMDB_NOOBJ); return (NULL); @@ -1200,14 +1223,12 @@ kt_name_to_ctf(mdb_tgt_t *t, const char *name) kt_module_t *km; if (name == MDB_TGT_OBJ_EXEC) - name = KT_CTFPARENT; /* base CTF data is kept in genunix */ + name = KT_CTFPARENT; else if (name == MDB_TGT_OBJ_RTLD) - name = KT_RTLD_NAME; /* replace MDB_TGT_OBJ_RTLD with krtld */ + name = kt->k_rtld_name; - for (km = mdb_list_next(&kt->k_modlist); km; km = mdb_list_next(km)) { - if (strcmp(name, km->km_name) == 0) - return (kt_load_ctfdata(t, km)); - } + if ((km = kt_module_by_name(kt, name)) != NULL) + return (kt_load_ctfdata(t, km)); (void) set_errno(EMDB_NOOBJ); return (NULL); diff --git a/usr/src/cmd/mdb/common/mdb/mdb_kvm.h b/usr/src/cmd/mdb/common/mdb/mdb_kvm.h index 9e4ca6f774..ef85d9179e 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_kvm.h +++ b/usr/src/cmd/mdb/common/mdb/mdb_kvm.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -79,6 +78,7 @@ typedef struct kt_data { int (*k_dump_find_curproc)(); /* mdb_ks dump_find_curproc routine */ char *k_symfile; /* Symbol table pathname */ char *k_kvmfile; /* Core file pathname */ + const char *k_rtld_name; /* module containing krtld */ mdb_map_t k_map; /* Persistant map for callers */ kvm_t *k_cookie; /* Cookie for libkvm routines */ struct as *k_as; /* Kernel VA of kas struct */ diff --git a/usr/src/cmd/mdb/common/modules/genunix/Makefile.files b/usr/src/cmd/mdb/common/modules/genunix/Makefile.files new file mode 100644 index 0000000000..b125e5f21b --- /dev/null +++ b/usr/src/cmd/mdb/common/modules/genunix/Makefile.files @@ -0,0 +1,68 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" + +# +# This file simply contains the list of sources files compiled together +# to create the genunix mdb module. Having them in one place saves +# a bunch of unnecessary replication. +# +GENUNIX_SRCS = \ + avl.c \ + bio.c \ + contract.c \ + cpupart.c \ + ctxop.c \ + cyclic.c \ + devinfo.c \ + findstack.c \ + fm.c \ + genunix.c \ + group.c \ + kgrep.c \ + kmem.c \ + ldi.c \ + leaky.c \ + leaky_subr.c \ + lgrp.c \ + list.c \ + log.c \ + mdi.c \ + memory.c \ + mmd.c \ + modhash.c \ + ndievents.c \ + net.c \ + nvpair.c \ + pg.c \ + rctl.c \ + sobj.c \ + streams.c \ + sysevent.c \ + thread.c \ + tsd.c \ + tsol.c \ + vfs.c \ + zone.c diff --git a/usr/src/cmd/mdb/common/modules/libc/libc.c b/usr/src/cmd/mdb/common/modules/libc/libc.c index a24a8bf6b4..acfa8ad884 100644 --- a/usr/src/cmd/mdb/common/modules/libc/libc.c +++ b/usr/src/cmd/mdb/common/modules/libc/libc.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -566,13 +566,12 @@ d_ulwp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) prt_addr(ulwp.ul_schedctl_called, 1), prt_addr((void *)ulwp.ul_schedctl, 0)); - HD("bindflags gs stsd &ftsd"); + HD("bindflags pad2 stsd &ftsd"); mdb_printf(OFFSTR, OFFSET(ul_bindflags)); mdb_printf(ulwp.ul_bindflags? "0x%-8x " : "%-10d ", ulwp.ul_bindflags); - mdb_printf(ulwp.ul_gs? "0x%-8x " : "%-10d ", - ulwp.ul_gs); + mdb_printf("%-10d ", ulwp.ul_pad2); mdb_printf("%s %s\n", prt_addr(ulwp.ul_stsd, 1), prt_addr((void *)(addr + OFFSET(ul_ftsd[0])), 0)); diff --git a/usr/src/cmd/mdb/i86pc/modules/uppc/intr_common.c b/usr/src/cmd/mdb/i86pc/modules/common/intr_common.c index 9fb1f0e3d3..36f0f78bb7 100644 --- a/usr/src/cmd/mdb/i86pc/modules/uppc/intr_common.c +++ b/usr/src/cmd/mdb/i86pc/modules/common/intr_common.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -29,12 +29,33 @@ #include <sys/multidata.h> #include <sys/gld.h> #include <sys/gldpriv.h> -#include <sys/ddi_intr_impl.h> -#include <sys/cpuvar.h> -int option_flags; -uintptr_t gld_intr_addr; -static struct av_head softvec_tbl[LOCK_LEVEL + 1]; +int option_flags; +uintptr_t gld_intr_addr; +static struct av_head softvec_tbl[LOCK_LEVEL + 1]; + +static char *businfo_array[] = { + " ", + "CBUS", + "CBUSII", + "EISA", + "FUTURE", + "INTERN", + "ISA", + "MBI", + "MBII", + "PCIe", + "MPI", + "MPSA", + "NUBUS", + "PCI", + "PCMCIA", + "TC", + "VL", + "VME", + "XPRESS", + " " +}; void interrupt_help(void) @@ -55,42 +76,6 @@ soft_interrupt_help(void) " -d instead of ISR, print <driver_name><instance#>\n"); } -void -interrupt_print_isr(uintptr_t vector, uintptr_t arg1, uintptr_t dip) -{ - uintptr_t isr_addr = vector; - struct dev_info dev_info; - - /* - * figure out the real ISR function name from gld_intr() - */ - if (isr_addr == gld_intr_addr) { - gld_mac_info_t macinfo; - - if (mdb_vread(&macinfo, sizeof (gld_mac_info_t), arg1) != -1) { - /* verify gld data structure and get the real ISR */ - if (macinfo.gldm_GLD_version == GLD_VERSION) - isr_addr = (uintptr_t)macinfo.gldm_intr; - } - } - - if ((option_flags & INTR_DISPLAY_DRVR_INST) && dip) { - char drvr_name[MODMAXNAMELEN + 1]; - - if (dip && mdb_devinfo2driver(dip, drvr_name, - sizeof (drvr_name)) == 0) { - (void) mdb_vread(&dev_info, sizeof (dev_info), dip); - mdb_printf("%s#%d", drvr_name, dev_info.devi_instance); - } else { - mdb_printf("%a", isr_addr); - } - - } else { - mdb_printf("%a", isr_addr); - } -} - - /* * This is copied from avintr.c * NOTE: Ensure that this definition stays in sync @@ -152,3 +137,164 @@ soft_interrupt_dump(uintptr_t addr, uint_t flags, int argc, return (DCMD_OK); } + +void +interrupt_print_isr(uintptr_t vector, uintptr_t arg1, uintptr_t dip) +{ + uintptr_t isr_addr = vector; + struct dev_info dev_info; + + /* + * figure out the real ISR function name from gld_intr() + */ + if (isr_addr == gld_intr_addr) { + gld_mac_info_t macinfo; + + if (mdb_vread(&macinfo, sizeof (gld_mac_info_t), arg1) != -1) { + /* verify gld data structure and get the real ISR */ + if (macinfo.gldm_GLD_version == GLD_VERSION) + isr_addr = (uintptr_t)macinfo.gldm_intr; + } + } + + if ((option_flags & INTR_DISPLAY_DRVR_INST) && dip) { + char drvr_name[MODMAXNAMELEN + 1]; + + if (dip && mdb_devinfo2driver(dip, drvr_name, + sizeof (drvr_name)) == 0) { + (void) mdb_vread(&dev_info, sizeof (dev_info), dip); + mdb_printf("%s#%d", drvr_name, dev_info.devi_instance); + } else { + mdb_printf("%a", isr_addr); + } + + } else { + mdb_printf("%a", isr_addr); + } +} + +/* + * get_interrupt_type: + * + * Get some interrupt related useful information + * + * NOTE: a0 is clock, c0/d0/e0 are x-calls, e1 is apic_error_intr + * d1/d3 are cbe_fire interrupts + */ +static char * +get_interrupt_type(short index) +{ + if (index == RESERVE_INDEX) + return ("IPI"); + else if (index == ACPI_INDEX) + return ("Fixed"); + else if (index == MSI_INDEX) + return ("MSI"); + else if (index == MSIX_INDEX) + return ("MSI-X"); + else + return ("Fixed"); +} + +void +apic_interrupt_dump(apic_irq_t *irqp, struct av_head *avp, + int i, ushort_t *evtchnp, char level) +{ + int bus_type; + int j; + char *intr_type; + char ioapic_iline[10]; + char ipl[3]; + char cpu_assigned[4]; + char evtchn[8]; + uchar_t assigned_cpu; + struct autovec avhp; + + /* If invalid index; continue */ + if (!irqp->airq_mps_intr_index || + irqp->airq_mps_intr_index == FREE_INDEX) + return; + + /* Figure out interrupt type and trigger information */ + intr_type = get_interrupt_type(irqp->airq_mps_intr_index); + + /* Figure out IOAPIC number and ILINE number */ + if (APIC_IS_MSI_OR_MSIX_INDEX(irqp->airq_mps_intr_index)) + (void) mdb_snprintf(ioapic_iline, 10, "- "); + else { + if (!irqp->airq_ioapicindex && !irqp->airq_intin_no) { + if (strcmp(intr_type, "Fixed") == 0) + (void) mdb_snprintf(ioapic_iline, 10, + "0x%x/0x%x", irqp->airq_ioapicindex, + irqp->airq_intin_no); + else if (irqp->airq_mps_intr_index == RESERVE_INDEX) + (void) mdb_snprintf(ioapic_iline, 10, "- "); + else + (void) mdb_snprintf(ioapic_iline, 10, " "); + } else + (void) mdb_snprintf(ioapic_iline, 10, "0x%x/0x%x", + irqp->airq_ioapicindex, irqp->airq_intin_no); + } + + evtchn[0] = '\0'; + if (evtchnp != NULL) + (void) mdb_snprintf(evtchn, 8, "%-7hd", *evtchnp); + + assigned_cpu = irqp->airq_temp_cpu; + if (assigned_cpu == IRQ_UNINIT || assigned_cpu == IRQ_UNBOUND) + assigned_cpu = irqp->airq_cpu; + bus_type = irqp->airq_iflag.bustype; + + if (irqp->airq_mps_intr_index == RESERVE_INDEX) { + (void) mdb_snprintf(cpu_assigned, 4, "all"); + (void) mdb_snprintf(ipl, 3, "%d", avp->avh_hi_pri); + } else { + (void) mdb_snprintf(cpu_assigned, 4, "%d", assigned_cpu); + (void) mdb_snprintf(ipl, 3, "%d", irqp->airq_ipl); + } + + /* Print each interrupt entry */ + if (option_flags & INTR_DISPLAY_INTRSTAT) + mdb_printf("%-4s", cpu_assigned); + else + mdb_printf("%-3d 0x%x %s%-3s %-6s %-3s %-6s %-4s%-3d %-9s ", + i, irqp->airq_vector, evtchn, ipl, + (bus_type ? businfo_array[bus_type] : " "), + (level ? "Lvl" : "Edg"), + intr_type, cpu_assigned, irqp->airq_share, ioapic_iline); + + /* If valid dip found; print driver name */ + if (irqp->airq_dip) { + (void) mdb_vread(&avhp, sizeof (struct autovec), + (uintptr_t)avp->avh_link); + + /* + * Loop thru all the shared IRQs + */ + if (irqp->airq_share) + interrupt_print_isr((uintptr_t)avhp.av_vector, + (uintptr_t)avhp.av_intarg1, (uintptr_t)avhp.av_dip); + + for (j = 1; irqp->airq_mps_intr_index != FREE_INDEX && + j < irqp->airq_share; j++) { + if (mdb_vread(&avhp, sizeof (struct autovec), + (uintptr_t)avhp.av_link) != -1) { + mdb_printf(", "); + interrupt_print_isr((uintptr_t)avhp.av_vector, + (uintptr_t)avhp.av_intarg1, + (uintptr_t)avhp.av_dip); + } else { + break; + } + } + + } else { + if (irqp->airq_mps_intr_index == RESERVE_INDEX && + !irqp->airq_share) + mdb_printf("poke_cpu"); + else if (mdb_vread(&avhp, sizeof (struct autovec), + (uintptr_t)avp->avh_link) != -1) + mdb_printf("%a", avhp.av_vector); + } + mdb_printf("\n"); +} diff --git a/usr/src/cmd/mdb/i86pc/modules/uppc/intr_common.h b/usr/src/cmd/mdb/i86pc/modules/common/intr_common.h index 74a0b44668..19c90f04bc 100644 --- a/usr/src/cmd/mdb/i86pc/modules/uppc/intr_common.h +++ b/usr/src/cmd/mdb/i86pc/modules/common/intr_common.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -39,16 +39,18 @@ extern "C" { #include <sys/avintr.h> #include <sys/psm_common.h> #include <sys/pic.h> -#include <io/pcplusmp/apic.h> +#include <sys/apic.h> /* * Function prototypes */ -void interrupt_help(void); -void soft_interrupt_help(void); -void interrupt_print_isr(uintptr_t vector, uintptr_t arg1, uintptr_t dip); -int soft_interrupt_dump(uintptr_t addr, uint_t flags, int argc, - const mdb_arg_t *argv); +void interrupt_help(void); +void interrupt_print_isr(uintptr_t, uintptr_t, uintptr_t); +void apic_interrupt_dump(apic_irq_t *, struct av_head *, int i, + ushort_t *, char); + +void soft_interrupt_help(void); +int soft_interrupt_dump(uintptr_t, uint_t, int, const mdb_arg_t *); /* * ::interrupts usage related defines and variables diff --git a/usr/src/cmd/mdb/i86pc/modules/pcplusmp/amd64/Makefile b/usr/src/cmd/mdb/i86pc/modules/pcplusmp/amd64/Makefile index fddfa8db13..88bf7fd4c8 100644 --- a/usr/src/cmd/mdb/i86pc/modules/pcplusmp/amd64/Makefile +++ b/usr/src/cmd/mdb/i86pc/modules/pcplusmp/amd64/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -35,10 +35,10 @@ include ../../../../intel/Makefile.amd64 include ../../../Makefile.i86pc include ../../../../Makefile.module -MODSRCS_DIR = ../../uppc +MODSRCS_DIR = ../../common CPPFLAGS += -DMP -D_MACHDEP CPPFLAGS += -I../../../../common -CPPFLAGS += -I../../uppc +CPPFLAGS += -I../../common CPPFLAGS += -I$(SRC)/uts/intel CPPFLAGS += -I$(SRC)/uts/i86pc diff --git a/usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c b/usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c index c2c9b6538d..fb8824855a 100644 --- a/usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c +++ b/usr/src/cmd/mdb/i86pc/modules/pcplusmp/apic.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -30,154 +30,9 @@ /* * Globals */ -static char *businfo_array[] = { - " ", - "CBUS", - "CBUSII", - "EISA", - "FUTURE", - "INTERN", - "ISA", - "MBI", - "MBII", - "PCIe", - "MPI", - "MPSA", - "NUBUS", - "PCI", - "PCMCIA", - "TC", - "VL", - "VME", - "XPRESS", - " " -}; - static struct av_head avec_tbl[APIC_MAX_VECTOR+1]; - -/* - * get_interrupt_type: - * - * Get some interrupt related useful information - * - * NOTE: a0 is clock, c0/d0/e0 are x-calls, e1 is apic_error_intr - * d1/d3 are cbe_fire interrupts - */ -static char * -get_interrupt_type(short index) -{ - if (index == RESERVE_INDEX) - return ("IPI"); - else if (index == ACPI_INDEX) - return ("Fixed"); - else if (index == MSI_INDEX) - return ("MSI"); - else if (index == MSIX_INDEX) - return ("MSI-X"); - else - return ("Fixed"); -} - -/* - * interrupt_display_info: - * - * Dump interrupt information including shared interrupts. - */ -static void -interrupt_display_info(apic_irq_t irqp, int i) -{ - int bus_type; - int j; - char *intr_type; - char ioapic_iline[10]; - char ipl[3]; - char cpu_assigned[4]; - uchar_t assigned_cpu; - struct autovec avhp; - - /* If invalid index; continue */ - if (!irqp.airq_mps_intr_index || irqp.airq_mps_intr_index == FREE_INDEX) - return; - - /* Figure out interrupt type and trigger information */ - intr_type = get_interrupt_type(irqp.airq_mps_intr_index); - - /* Figure out IOAPIC number and ILINE number */ - if (APIC_IS_MSI_OR_MSIX_INDEX(irqp.airq_mps_intr_index)) - (void) mdb_snprintf(ioapic_iline, 10, "- "); - else { - if (!irqp.airq_ioapicindex && !irqp.airq_intin_no) { - if (strcmp(intr_type, "Fixed") == 0) - (void) mdb_snprintf(ioapic_iline, 10, - "0x%x/0x%x", irqp.airq_ioapicindex, - irqp.airq_intin_no); - else if (irqp.airq_mps_intr_index == RESERVE_INDEX) - (void) mdb_snprintf(ioapic_iline, 10, "- "); - else - (void) mdb_snprintf(ioapic_iline, 10, " "); - } else - (void) mdb_snprintf(ioapic_iline, 10, "0x%x/0x%x", - irqp.airq_ioapicindex, irqp.airq_intin_no); - } - - assigned_cpu = irqp.airq_temp_cpu; - if (assigned_cpu == IRQ_UNINIT || assigned_cpu == IRQ_UNBOUND) - assigned_cpu = irqp.airq_cpu; - bus_type = irqp.airq_iflag.bustype; - - if (irqp.airq_mps_intr_index == RESERVE_INDEX) { - (void) mdb_snprintf(cpu_assigned, 4, "ALL"); - (void) mdb_snprintf(ipl, 3, "%d", avec_tbl[i].avh_hi_pri); - } else { - (void) mdb_snprintf(cpu_assigned, 4, "%d", assigned_cpu); - (void) mdb_snprintf(ipl, 3, "%d", irqp.airq_ipl); - } - - /* Print each interrupt entry */ - if (option_flags & INTR_DISPLAY_INTRSTAT) - mdb_printf("cpu%s\t", cpu_assigned); - else - mdb_printf("%-3d 0x%x %-3s %-5s %-6s%-4s%-3d %-9s ", - i, irqp.airq_vector, ipl, - (bus_type ? businfo_array[bus_type] : " "), - intr_type, cpu_assigned, irqp.airq_share, ioapic_iline); - - /* If valid dip found; print driver name */ - if (irqp.airq_dip) { - (void) mdb_vread(&avhp, sizeof (struct autovec), - (uintptr_t)avec_tbl[i].avh_link); - - /* - * Loop thru all the shared IRQs - */ - if (irqp.airq_share) - interrupt_print_isr((uintptr_t)avhp.av_vector, - (uintptr_t)avhp.av_intarg1, (uintptr_t)avhp.av_dip); - - for (j = 1; irqp.airq_mps_intr_index != FREE_INDEX && - j < irqp.airq_share; j++) { - if (mdb_vread(&avhp, sizeof (struct autovec), - (uintptr_t)avhp.av_link) != -1) { - mdb_printf(", "); - interrupt_print_isr((uintptr_t)avhp.av_vector, - (uintptr_t)avhp.av_intarg1, - (uintptr_t)avhp.av_dip); - } else { - break; - } - } - - } else { - if (irqp.airq_mps_intr_index == RESERVE_INDEX && - !irqp.airq_share) - mdb_printf("poke_cpu"); - else if (mdb_vread(&avhp, sizeof (struct autovec), - (uintptr_t)avec_tbl[i].avh_link) != -1) - mdb_printf("%a", avhp.av_vector); - } - mdb_printf("\n"); -} - +static apic_irq_t *irq_tbl[APIC_MAX_VECTOR+1], airq; +static char level_tbl[APIC_MAX_VECTOR+1]; /* * interrupt_dump: @@ -189,7 +44,6 @@ int interrupt_dump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { int i; - apic_irq_t *irq_tbl[APIC_MAX_VECTOR+1], irqp; option_flags = 0; if (mdb_getopts(argc, argv, @@ -203,6 +57,11 @@ interrupt_dump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) return (DCMD_ERR); } + if (mdb_readvar(&level_tbl, "apic_level_intr") == -1) { + mdb_warn("failed to read apic_level_intr"); + return (DCMD_ERR); + } + if (mdb_readvar(&avec_tbl, "autovect") == -1) { mdb_warn("failed to read autovect"); return (DCMD_ERR); @@ -210,21 +69,21 @@ interrupt_dump(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) /* Print the header first */ if (option_flags & INTR_DISPLAY_INTRSTAT) - mdb_printf("%<u>CPU\t "); + mdb_printf("%<u>CPU "); else mdb_printf( - "%<u>IRQ Vector IPL Bus Type CPU Share APIC/INT# "); + "%<u>IRQ Vect IPL Bus Trg Type CPU Share APIC/INT# "); mdb_printf("%s %</u>\n", option_flags & INTR_DISPLAY_DRVR_INST ? "Driver Name(s)" : "ISR(s)"); /* Walk all the entries */ for (i = 0; i < APIC_MAX_VECTOR + 1; i++) { /* Read the entry */ - if (mdb_vread(&irqp, sizeof (apic_irq_t), + if (mdb_vread(&airq, sizeof (apic_irq_t), (uintptr_t)irq_tbl[i]) == -1) continue; - interrupt_display_info(irqp, i); + apic_interrupt_dump(&airq, &avec_tbl[i], i, NULL, level_tbl[i]); } return (DCMD_OK); diff --git a/usr/src/cmd/mdb/i86pc/modules/pcplusmp/ia32/Makefile b/usr/src/cmd/mdb/i86pc/modules/pcplusmp/ia32/Makefile index 3964bf6bde..e0e8edc45b 100644 --- a/usr/src/cmd/mdb/i86pc/modules/pcplusmp/ia32/Makefile +++ b/usr/src/cmd/mdb/i86pc/modules/pcplusmp/ia32/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -34,10 +34,10 @@ include ../../../../intel/Makefile.ia32 include ../../../Makefile.i86pc include ../../../../Makefile.module -MODSRCS_DIR = ../../uppc +MODSRCS_DIR = ../../common CPPFLAGS += -DMP -D_MACHDEP CPPFLAGS += -I../../../../common -CPPFLAGS += -I../../uppc +CPPFLAGS += -I../../common CPPFLAGS += -I$(SRC)/uts/intel CPPFLAGS += -I$(SRC)/uts/i86pc diff --git a/usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile b/usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile index 7ed692a12b..08cbabf3e1 100644 --- a/usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile +++ b/usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -38,5 +37,5 @@ include ../../../../Makefile.module CPPFLAGS += -DMP -D_MACHDEP CPPFLAGS += -I../../../../common -CPPFLAGS += -I$(SRC)/uts/intel CPPFLAGS += -I$(SRC)/uts/i86pc +CPPFLAGS += -I$(SRC)/uts/intel diff --git a/usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.c b/usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.c index 05577a6cc8..161bd9d9a1 100644 --- a/usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.c +++ b/usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.c @@ -19,10 +19,9 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ - #pragma ident "%Z%%M% %I% %E% SMI" /* @@ -37,6 +36,7 @@ #include <sys/types.h> #include <sys/machparam.h> #include <sys/controlregs.h> +#include <sys/mach_mmu.h> #include <vm/as.h> #include <mdb/mdb_modapi.h> @@ -50,7 +50,7 @@ struct pfn2pp { page_t *pp; }; -static int do_va2pfn(uintptr_t, struct as *, int, physaddr_t *); +static int do_va2pa(uintptr_t, struct as *, int, physaddr_t *, pfn_t *); static void get_mmu(void); int @@ -66,7 +66,7 @@ platform_vtop(uintptr_t addr, struct as *asp, physaddr_t *pap) if (mmu.num_level == 0) return (DCMD_ERR); - return (do_va2pfn(addr, asp, 0, pap)); + return (do_va2pa(addr, asp, 0, pap, NULL)); } @@ -134,9 +134,6 @@ page_num2pp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) } - - - /* * ::memseg_list dcmd and walker to implement it. */ @@ -221,20 +218,7 @@ memseg_walk_fini(mdb_walk_state_t *wsp) } /* - * HAT related dcmds: - * - * ::pte [-p XXXXXXXX] [-l 0/1/2/3] - * - * dcmd that interprets the -p argument as a page table entry and - * prints it in more human readable form. The PTE is assumed to be in - * a level 0 page table, unless -l specifies another level. - * - * ::vatopfn [-v] [-a as] - * - * Given a virtual address, returns the PFN, if any, mapped at the address. - * -v shows the intermediate htable/page table entries used to resolve the - * mapping. By default the virtual address is assumed to be in the kernel's - * address space. -a is used to specify a different address space. + * Now HAT related dcmds. */ struct hat *khat; /* value of kas.a_hat */ @@ -261,6 +245,21 @@ get_mmu(void) khat = kas.a_hat; } +#define mdb_ma_to_pa(ma) (ma) +#define mdb_mfn_to_pfn(mfn) (mfn) +#define mdb_pfn_to_mfn(pfn) (pfn) + +static pfn_t +pte2mfn(x86pte_t pte, uint_t level) +{ + pfn_t mfn; + if (level > 0 && (pte & PT_PAGESIZE)) + mfn = mmu_btop(pte & PT_PADDR_LGPG); + else + mfn = mmu_btop(pte & PT_PADDR); + return (mfn); +} + /* * Print a PTE in more human friendly way. The PTE is assumed to be in * a level 0 page table, unless -l specifies another level. @@ -275,12 +274,14 @@ do_pte_dcmd(int level, uint64_t pte) "wrback", "wrthru", "uncached", "uncached", "wrback", "wrthru", "wrcombine", "uncached"}; int pat_index = 0; + pfn_t mfn; - mdb_printf("PTE=%llx: ", pte); + mdb_printf("pte=%llr: ", pte); if (PTE_GET(pte, mmu.pt_nx)) mdb_printf("noexec "); - mdb_printf("page=0x%llx ", PTE2PFN(pte, level)); + mfn = pte2mfn(pte, level); + mdb_printf("%s=0x%lr ", "pfn", mfn); if (PTE_GET(pte, PT_NOCONSIST)) mdb_printf("noconsist "); @@ -387,8 +388,43 @@ pte_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) return (do_pte_dcmd(level, pte)); } +static size_t +va2entry(htable_t *htable, uintptr_t addr) +{ + size_t entry = (addr - htable->ht_vaddr); + + entry >>= mmu.level_shift[htable->ht_level]; + return (entry & HTABLE_NUM_PTES(htable) - 1); +} + +static x86pte_t +get_pte(hat_t *hat, htable_t *htable, uintptr_t addr) +{ + x86pte_t buf; + x86pte32_t *pte32 = (x86pte32_t *)&buf; + size_t len; + + if (htable->ht_flags & HTABLE_VLP) { + uintptr_t ptr = (uintptr_t)hat->hat_vlp_ptes; + ptr += va2entry(htable, addr) << mmu.pte_size_shift; + len = mdb_vread(&buf, mmu.pte_size, ptr); + } else { + paddr_t paddr = mmu_ptob((paddr_t)htable->ht_pfn); + paddr += va2entry(htable, addr) << mmu.pte_size_shift; + len = mdb_pread(&buf, mmu.pte_size, paddr); + } + + if (len != mmu.pte_size) + return (0); + + if (mmu.pte_size == sizeof (x86pte_t)) + return (buf); + return (*pte32); +} + static int -do_va2pfn(uintptr_t addr, struct as *asp, int print_level, physaddr_t *pap) +do_va2pa(uintptr_t addr, struct as *asp, int print_level, physaddr_t *pap, + pfn_t *mfnp) { struct as as; struct hat *hatp; @@ -400,10 +436,7 @@ do_va2pfn(uintptr_t addr, struct as *asp, int print_level, physaddr_t *pap) int level; int found = 0; x86pte_t pte; - x86pte_t buf; - x86pte32_t *pte32 = (x86pte32_t *)&buf; physaddr_t paddr; - size_t len; if (asp != NULL) { if (mdb_vread(&as, sizeof (as), (uintptr_t)asp) == -1) { @@ -426,9 +459,8 @@ do_va2pfn(uintptr_t addr, struct as *asp, int print_level, physaddr_t *pap) /* * read the htable hashtable */ - *pap = 0; for (level = 0; level <= mmu.max_level; ++level) { - if (level == mmu.max_level) + if (level == TOP_LEVEL(&hat)) base = 0; else base = addr & mmu.level_mask[level + 1]; @@ -445,38 +477,38 @@ do_va2pfn(uintptr_t addr, struct as *asp, int print_level, physaddr_t *pap) mdb_warn("Couldn't read htable\n"); return (DCMD_ERR); } + if (htable.ht_vaddr != base || htable.ht_level != level) continue; - /* - * found - read the page table entry - */ - paddr = htable.ht_pfn << MMU_PAGESHIFT; - paddr += ((addr - base) >> - mmu.level_shift[level]) << - mmu.pte_size_shift; - len = mdb_pread(&buf, mmu.pte_size, paddr); - if (len != mmu.pte_size) - return (DCMD_ERR); - if (mmu.pte_size == sizeof (x86pte_t)) - pte = buf; - else - pte = *pte32; + pte = get_pte(&hat, &htable, addr); - if (!found) { - if (PTE_IS_LGPG(pte, level)) - paddr = pte & PT_PADDR_LGPG; - else - paddr = pte & PT_PADDR; - paddr += addr & mmu.level_offset[level]; - *pap = paddr; - found = 1; + if (print_level) { + mdb_printf("\tlevel=%d htable=%p " + "pte=%llr\n", level, ht, pte); } - if (print_level == 0) + + if (!PTE_ISVALID(pte)) { + mdb_printf("Address %p is unmapped.\n", + addr); + return (DCMD_ERR); + } + + if (found) continue; - mdb_printf("\tlevel=%d htable=%p pte=%llx\n", - level, ht, pte); + + if (PTE_IS_LGPG(pte, level)) + paddr = mdb_ma_to_pa(pte & + PT_PADDR_LGPG); + else + paddr = mdb_ma_to_pa(pte & PT_PADDR); + paddr += addr & mmu.level_offset[level]; + if (pap != NULL) + *pap = paddr; + if (mfnp != NULL) + *mfnp = pte2mfn(pte, level); + found = 1; } } } @@ -492,7 +524,9 @@ va2pfn_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { uintptr_t addrspace; char *addrspace_str = NULL; - uint64_t physaddr; + int piped = flags & DCMD_PIPE_OUT; + pfn_t pfn; + pfn_t mfn; int rc; /* @@ -517,12 +551,26 @@ va2pfn_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) else addrspace = 0; - rc = do_va2pfn(addr, (struct as *)addrspace, 1, &physaddr); + rc = do_va2pa(addr, (struct as *)addrspace, !piped, NULL, &mfn); + + if (rc != DCMD_OK) + return (rc); + + if ((pfn = mdb_mfn_to_pfn(mfn)) == -(pfn_t)1) { + mdb_warn("Invalid mfn %lr\n", mfn); + return (DCMD_ERR); + } + + if (piped) { + mdb_printf("0x%lr\n", pfn); + return (DCMD_OK); + } - if (rc == DCMD_OK) - mdb_printf("Virtual %p maps Physical %llx\n", addr, physaddr); + mdb_printf("Virtual address 0x%p maps pfn 0x%lr", addr, pfn); - return (rc); + mdb_printf("\n"); + + return (DCMD_OK); } /* @@ -596,8 +644,9 @@ do_report_maps(pfn_t pfn) level = htable.ht_level; if (level > mmu.max_page_level) continue; - paddr = htable.ht_pfn << MMU_PAGESHIFT; - for (entry = 0; entry < htable.ht_num_ptes; + paddr = mmu_ptob((physaddr_t)htable.ht_pfn); + for (entry = 0; + entry < HTABLE_NUM_PTES(&htable); ++entry) { base = htable.ht_vaddr + entry * @@ -625,7 +674,7 @@ do_report_maps(pfn_t pfn) pte &= PT_PADDR; else pte &= PT_PADDR_LGPG; - if ((pte >> MMU_PAGESHIFT) != pfn) + if (mmu_btop(mdb_ma_to_pa(pte)) != pfn) continue; mdb_printf("hat=%p maps addr=%p\n", hatp, (caddr_t)base); @@ -645,6 +694,9 @@ done: int report_maps_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { + pfn_t pfn; + uint_t mflag = 0; + /* * The kernel has to at least have made it thru mmu_init() */ @@ -655,12 +707,17 @@ report_maps_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) if ((flags & DCMD_ADDRSPEC) == 0) return (DCMD_USAGE); - return (do_report_maps((pfn_t)addr)); + if (mdb_getopts(argc, argv, + 'm', MDB_OPT_SETBITS, TRUE, &mflag, NULL) != argc) + return (DCMD_USAGE); + + pfn = (pfn_t)addr; + if (mflag) + pfn = mdb_mfn_to_pfn(pfn); + + return (do_report_maps(pfn)); } -/* - * Dump the page table at the given PFN - */ static int do_ptable_dcmd(pfn_t pfn) { @@ -730,7 +787,7 @@ found_it: pagesize = MMU_PAGESIZE; } - paddr = pfn << MMU_PAGESHIFT; + paddr = mmu_ptob((physaddr_t)pfn); for (entry = 0; entry < mmu.ptes_per_table; ++entry) { len = mdb_pread(&buf, mmu.pte_size, paddr + entry * mmu.pte_size); @@ -753,12 +810,82 @@ done: } /* - * given a PFN as its address argument, prints out the uses of it + * Dump the page table at the given PFN */ /*ARGSUSED*/ int ptable_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { + pfn_t pfn; + uint_t mflag = 0; + + /* + * The kernel has to at least have made it thru mmu_init() + */ + get_mmu(); + if (mmu.num_level == 0) + return (DCMD_ERR); + + if ((flags & DCMD_ADDRSPEC) == 0) + return (DCMD_USAGE); + + if (mdb_getopts(argc, argv, + 'm', MDB_OPT_SETBITS, TRUE, &mflag, NULL) != argc) + return (DCMD_USAGE); + + pfn = (pfn_t)addr; + if (mflag) + pfn = mdb_mfn_to_pfn(pfn); + + return (do_ptable_dcmd(pfn)); +} + +static int +do_htables_dcmd(hat_t *hatp) +{ + struct hat hat; + htable_t *ht; + htable_t htable; + int h; + + /* + * read the hat and its hash table + */ + if (mdb_vread(&hat, sizeof (hat), (uintptr_t)hatp) == -1) { + mdb_warn("Couldn't read struct hat\n"); + return (DCMD_ERR); + } + + /* + * read the htable hashtable + */ + for (h = 0; h < hat.hat_num_hash; ++h) { + if (mdb_vread(&ht, sizeof (htable_t *), + (uintptr_t)(hat.hat_ht_hash + h)) == -1) { + mdb_warn("Couldn't read htable ptr\\n"); + return (DCMD_ERR); + } + for (; ht != NULL; ht = htable.ht_next) { + mdb_printf("%p\n", ht); + if (mdb_vread(&htable, sizeof (htable_t), + (uintptr_t)ht) == -1) { + mdb_warn("Couldn't read htable\n"); + return (DCMD_ERR); + } + } + } + return (DCMD_OK); +} + +/* + * Dump the htables for the given hat + */ +/*ARGSUSED*/ +int +htables_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +{ + hat_t *hat; + /* * The kernel has to at least have made it thru mmu_init() */ @@ -769,5 +896,7 @@ ptable_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) if ((flags & DCMD_ADDRSPEC) == 0) return (DCMD_USAGE); - return (do_ptable_dcmd((pfn_t)addr)); + hat = (hat_t *)addr; + + return (do_htables_dcmd(hat)); } diff --git a/usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.h b/usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.h index 6b01d31c47..5f86f0fd5e 100644 --- a/usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.h +++ b/usr/src/cmd/mdb/i86pc/modules/unix/i86mmu.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -39,6 +38,9 @@ extern int pte_dcmd(uintptr_t addr, uint_t flags, int argc, extern int report_maps_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv); +extern int htables_dcmd(uintptr_t addr, uint_t flags, int argc, + const mdb_arg_t *argv); + extern int ptable_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv); diff --git a/usr/src/cmd/mdb/i86pc/modules/unix/ia32/Makefile b/usr/src/cmd/mdb/i86pc/modules/unix/ia32/Makefile index edb2d65a68..8121af9b49 100644 --- a/usr/src/cmd/mdb/i86pc/modules/unix/ia32/Makefile +++ b/usr/src/cmd/mdb/i86pc/modules/unix/ia32/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -37,5 +36,5 @@ include ../../../../Makefile.module CPPFLAGS += -DMP -D_MACHDEP CPPFLAGS += -I../../../../common -CPPFLAGS += -I$(SRC)/uts/intel CPPFLAGS += -I$(SRC)/uts/i86pc +CPPFLAGS += -I$(SRC)/uts/intel diff --git a/usr/src/cmd/mdb/i86pc/modules/unix/unix.c b/usr/src/cmd/mdb/i86pc/modules/unix/unix.c index 21921df599..d251ee9e11 100644 --- a/usr/src/cmd/mdb/i86pc/modules/unix/unix.c +++ b/usr/src/cmd/mdb/i86pc/modules/unix/unix.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -31,6 +30,7 @@ #include <sys/cpuvar.h> #include <sys/systm.h> #include <sys/traptrace.h> +#include <sys/x_call.h> #include <sys/avintr.h> #include <sys/systm.h> #include <sys/trap.h> @@ -186,11 +186,10 @@ ttrace_syscall(trap_trace_rec_t *rec) uintptr_t addr; struct sysent sys; - mdb_printf("%s%-*x", sysnum < 0x10 ? " " : "", - sysnum < 0x10 ? 2 : 3, sysnum); + mdb_printf("%-3x", sysnum); if (rec->ttr_sysnum > NSYSCALL) { - mdb_printf("%-*d", TT_HDLR_WIDTH, rec->ttr_sysnum); + mdb_printf(" %-*d", TT_HDLR_WIDTH, rec->ttr_sysnum); return (0); } @@ -211,7 +210,7 @@ ttrace_syscall(trap_trace_rec_t *rec) return (-1); } - mdb_printf("%-*a", TT_HDLR_WIDTH, sys.sy_callc); + mdb_printf(" %-*a", TT_HDLR_WIDTH, sys.sy_callc); return (0); } @@ -224,12 +223,15 @@ ttrace_interrupt(trap_trace_rec_t *rec) struct av_head hd; struct autovec av; - if (rec->ttr_regs.r_trapno == T_SOFTINT) { - mdb_printf("%2s %-*s", "-", TT_HDLR_WIDTH, "(fakesoftint)"); + switch (rec->ttr_regs.r_trapno) { + case T_SOFTINT: + mdb_printf("%-3s %-*s", "-", TT_HDLR_WIDTH, "(fakesoftint)"); return (0); + default: + break; } - mdb_printf("%2x ", rec->ttr_vector); + mdb_printf("%-3x ", rec->ttr_vector); if (mdb_lookup_by_name("autovect", &sym) == -1) { mdb_warn("\ncouldn't find 'autovect'"); @@ -250,7 +252,10 @@ ttrace_interrupt(trap_trace_rec_t *rec) } if (hd.avh_link == NULL) { - mdb_printf("%-*s", TT_HDLR_WIDTH, "(spurious)"); + if (rec->ttr_ipl == XC_CPUPOKE_PIL) + mdb_printf("%-*s", TT_HDLR_WIDTH, "(cpupoke)"); + else + mdb_printf("%-*s", TT_HDLR_WIDTH, "(spurious)"); } else { if (mdb_vread(&av, sizeof (av), (uintptr_t)hd.avh_link) == -1) { mdb_warn("couldn't read autovec at %p", @@ -286,6 +291,17 @@ static struct { { T_ALIGNMENT, "alignment-check" }, { T_MCE, "machine-check" }, { T_SIMDFPE, "sse-exception" }, + + { T_DBGENTR, "debug-enter" }, + { T_FASTTRAP, "fasttrap-0xd2" }, + { T_SYSCALLINT, "syscall-0x91" }, + { T_DTRACE_RET, "dtrace-ret" }, + { T_SOFTINT, "softint" }, + { T_INTERRUPT, "interrupt" }, + { T_FAULT, "fault" }, + { T_AST, "ast" }, + { T_SYSCALL, "syscall" }, + { 0, NULL } }; @@ -294,7 +310,10 @@ ttrace_trap(trap_trace_rec_t *rec) { int i; - mdb_printf("%2x ", rec->ttr_regs.r_trapno); + if (rec->ttr_regs.r_trapno == T_AST) + mdb_printf("%-3s ", "-"); + else + mdb_printf("%-3x ", rec->ttr_regs.r_trapno); for (i = 0; ttrace_traps[i].tt_name != NULL; i++) { if (rec->ttr_regs.r_trapno == ttrace_traps[i].tt_trapno) @@ -310,6 +329,137 @@ ttrace_trap(trap_trace_rec_t *rec) } static struct { + int tt_type; + char *tt_name; +} ttrace_xcalls[] = { + { TT_XC_SVC_BEGIN, "<svc-begin>" }, + { TT_XC_SVC_END, "<svc-end>" }, + { TT_XC_START, "<start>" }, + { TT_XC_WAIT, "<wait>" }, + { TT_XC_ACK, "<ack>" }, + { TT_XC_CAPTURE, "<capture>" }, + { TT_XC_RELEASE, "<release>" }, + { TT_XC_POKE_CPU, "<poke-cpu>" }, + { TT_XC_CBE_FIRE, "<cbe-fire>" }, + { TT_XC_CBE_XCALL, "<cbe-xcall>" }, + { 0, NULL } +}; + +static int +ttrace_xcall(trap_trace_rec_t *rec) +{ + struct _xc_entry *xce = &(rec->ttr_info.xc_entry); + int i; + + for (i = 0; ttrace_xcalls[i].tt_name != NULL; i++) + if (ttrace_xcalls[i].tt_type == xce->xce_marker) + break; + + switch (xce->xce_marker) { + case TT_XC_SVC_BEGIN: + case TT_XC_SVC_END: + mdb_printf("%3s ", "-"); + break; + default: + mdb_printf("%3x ", (int)xce->xce_arg); + break; + } + + if (ttrace_xcalls[i].tt_name == NULL) + mdb_printf("%-*s", TT_HDLR_WIDTH, "(unknown)"); + else + mdb_printf("%-*s", TT_HDLR_WIDTH, ttrace_xcalls[i].tt_name); + return (0); +} + +static char * +xc_pri_to_str(int pri) +{ + switch (pri) { + case X_CALL_LOPRI: + return (" low"); + case X_CALL_MEDPRI: + return (" med"); + case X_CALL_HIPRI: + return ("high"); + default: + return ("bad?"); + } +} + +static char * +xc_state_to_str(uint8_t state) +{ + switch (state) { + case XC_DONE: + return ("done"); + case XC_HOLD: + return ("hold"); + case XC_SYNC_OP: + return ("sync"); + case XC_CALL_OP: + return ("call"); + case XC_WAIT: + return ("wait"); + default: + return ("bad?"); + } +} + +static void +ttrace_intr_detail(trap_trace_rec_t *rec) +{ + mdb_printf("\tirq %x ipl %d oldpri %d basepri %d\n", rec->ttr_vector, + rec->ttr_ipl, rec->ttr_pri, rec->ttr_spl); +} + +static void +ttrace_xcall_detail(trap_trace_rec_t *rec) +{ + struct _xc_entry *xce = &(rec->ttr_info.xc_entry); + + if ((uint_t)xce->xce_pri < X_CALL_LEVELS) + mdb_printf("\t%s pri [%s] ", xc_pri_to_str(xce->xce_pri), + xc_state_to_str(xce->xce_state)); + else + mdb_printf("\t"); + + switch (xce->xce_marker) { + case TT_XC_SVC_BEGIN: + if (xce->xce_pri != X_CALL_MEDPRI && xce->xce_func != NULL) + mdb_printf("call %a() ..", xce->xce_func); + break; + case TT_XC_SVC_END: + if (xce->xce_arg == DDI_INTR_UNCLAIMED) + mdb_printf("[spurious]"); + else if (xce->xce_pri != X_CALL_MEDPRI && + xce->xce_func != NULL) + mdb_printf(".. called %a() returned %d", + xce->xce_func, xce->xce_retval); + break; + case TT_XC_START: + case TT_XC_CAPTURE: + mdb_printf("--> cpu%d", (int)xce->xce_arg); + break; + case TT_XC_RELEASE: + case TT_XC_WAIT: + case TT_XC_ACK: + mdb_printf("<-- cpu%d", (int)xce->xce_arg); + break; + case TT_XC_POKE_CPU: + case TT_XC_CBE_FIRE: + case TT_XC_CBE_XCALL: + mdb_printf("--> cpu%d", (int)xce->xce_arg); + break; + default: + mdb_printf("tag %d? arg 0x%lx", + xce->xce_marker, xce->xce_arg); + break; + } + mdb_printf("\n\n"); +} + +static struct { uchar_t t_marker; char *t_name; int (*t_hdlr)(trap_trace_rec_t *); @@ -320,6 +470,8 @@ static struct { { TT_SYSC64, "sc64", ttrace_syscall }, { TT_INTERRUPT, "intr", ttrace_interrupt }, { TT_TRAP, "trap", ttrace_trap }, + { TT_EVENT, "evnt", ttrace_trap }, + { TT_XCALL, "xcal", ttrace_xcall }, { 0, NULL, NULL } }; @@ -333,7 +485,6 @@ typedef struct ttrace_dcmd { #define DUMP(reg) #reg, regs->r_##reg #define THREEREGS " %3s: %16lx %3s: %16lx %3s: %16lx\n" -#define TWOREGS " %3s: %16lx %3s: %16lx\n" static void ttrace_dumpregs(trap_trace_rec_t *rec) @@ -345,12 +496,10 @@ ttrace_dumpregs(trap_trace_rec_t *rec) mdb_printf(THREEREGS, DUMP(rax), DUMP(rbx), DUMP(rbp)); mdb_printf(THREEREGS, DUMP(r10), DUMP(r11), DUMP(r12)); mdb_printf(THREEREGS, DUMP(r13), DUMP(r14), DUMP(r15)); - mdb_printf(THREEREGS, "fsb", regs->r_fsbase, "gsb", regs->r_gsbase, - DUMP(ds)); - mdb_printf(THREEREGS, DUMP(es), DUMP(fs), DUMP(gs)); - mdb_printf(THREEREGS, "trp", regs->r_trapno, DUMP(err), DUMP(rip)); - mdb_printf(THREEREGS, DUMP(cs), DUMP(rfl), DUMP(rsp)); - mdb_printf(TWOREGS, DUMP(ss), "cr2", rec->ttr_cr2); + mdb_printf(THREEREGS, DUMP(ds), DUMP(es), DUMP(fs)); + mdb_printf(THREEREGS, DUMP(gs), "trp", regs->r_trapno, DUMP(err)); + mdb_printf(THREEREGS, DUMP(rip), DUMP(cs), DUMP(rfl)); + mdb_printf(THREEREGS, DUMP(rsp), DUMP(ss), "cr2", rec->ttr_cr2); mdb_printf("\n"); } @@ -408,12 +557,17 @@ ttrace_walk(uintptr_t addr, trap_trace_rec_t *rec, ttrace_dcmd_t *dcmd) return (WALK_ERR); } - mdb_printf("%a\n", regs->r_pc); + mdb_printf(" %a\n", regs->r_pc); if (dcmd->ttd_extended == FALSE) return (WALK_NEXT); - ttrace_dumpregs(rec); + if (rec->ttr_marker == TT_XCALL) + ttrace_xcall_detail(rec); + else if (rec->ttr_marker == TT_INTERRUPT) + ttrace_intr_detail(rec); + else + ttrace_dumpregs(rec); if (rec->ttr_sdepth > 0) { for (i = 0; i < rec->ttr_sdepth; i++) { @@ -459,8 +613,8 @@ ttrace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) if (DCMD_HDRSPEC(flags)) { mdb_printf("%3s %15s %4s %2s %-*s%s\n", "CPU", - "TIMESTAMP", "TYPE", "VC", TT_HDLR_WIDTH, "HANDLER", - "EIP"); + "TIMESTAMP", "TYPE", "Vec", TT_HDLR_WIDTH, "HANDLER", + " EIP"); } if (flags & DCMD_ADDRSPEC) { @@ -618,15 +772,47 @@ idt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) return (DCMD_OK); } +static void +htables_help(void) +{ + mdb_printf( + "Given a (hat_t *), generates the list of all (htable_t *)s\n" + "that correspond to that address space\n"); +} + +static void +report_maps_help(void) +{ + mdb_printf( + "Given a PFN, report HAT structures that map the page, or use\n" + "the page as a pagetable.\n" + "\n" + "-m Interpret the PFN as a Xen MFN (machine frame number)\n"); +} + +static void +ptable_help(void) +{ + mdb_printf( + "Given a PFN holding a page table, print its contents, and\n" + "the address of the corresponding htable structure.\n" + "\n" + "-m Interpret the PFN as a Xen MFN (machine frame number)\n"); +} + static const mdb_dcmd_t dcmds[] = { { "gate_desc", ":", "dump a gate descriptor", gate_desc }, { "idt", ":[-v]", "dump an IDT", idt }, { "ttrace", "[-x]", "dump trap trace buffers", ttrace }, { "vatopfn", ":[-a as]", "translate address to physical page", va2pfn_dcmd }, - { "report_maps", "", "Given PFN, report mappings / page table usage", - report_maps_dcmd }, - { "ptable", "", "Dump contents of a page table", ptable_dcmd }, + { "report_maps", ":[-m]", + "Given PFN, report mappings / page table usage", + report_maps_dcmd, report_maps_help }, + { "htables", "", "Given hat_t *, lists all its htable_t * values", + htables_dcmd, htables_help }, + { "ptable", ":[-m]", "Given PFN, dump contents of a page table", + ptable_dcmd, ptable_help }, { "pte", ":[-p XXXXX] [-l N]", "print human readable page table entry", pte_dcmd }, { "page_num2pp", ":", "page frame number to page structure", diff --git a/usr/src/cmd/mdb/i86pc/modules/uppc/amd64/Makefile b/usr/src/cmd/mdb/i86pc/modules/uppc/amd64/Makefile index 0bcf1cd107..501eecf8c5 100644 --- a/usr/src/cmd/mdb/i86pc/modules/uppc/amd64/Makefile +++ b/usr/src/cmd/mdb/i86pc/modules/uppc/amd64/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -35,7 +35,10 @@ include ../../../../intel/Makefile.amd64 include ../../../Makefile.i86pc include ../../../../Makefile.module +MODSRCS_DIR = ../../common + CPPFLAGS += -DMP -D_MACHDEP +CPPFLAGS += -I../../common CPPFLAGS += -I../../../../common CPPFLAGS += -I$(SRC)/uts/intel CPPFLAGS += -I$(SRC)/uts/i86pc diff --git a/usr/src/cmd/mdb/i86pc/modules/uppc/ia32/Makefile b/usr/src/cmd/mdb/i86pc/modules/uppc/ia32/Makefile index e7778d3e05..f10ce9e177 100644 --- a/usr/src/cmd/mdb/i86pc/modules/uppc/ia32/Makefile +++ b/usr/src/cmd/mdb/i86pc/modules/uppc/ia32/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -34,7 +34,10 @@ include ../../../../intel/Makefile.ia32 include ../../../Makefile.i86pc include ../../../../Makefile.module +MODSRCS_DIR = ../../common + CPPFLAGS += -DMP -D_MACHDEP +CPPFLAGS += -I../../common CPPFLAGS += -I../../../../common CPPFLAGS += -I$(SRC)/uts/intel CPPFLAGS += -I$(SRC)/uts/i86pc diff --git a/usr/src/cmd/mdb/i86pc/modules/uppc/uppc.c b/usr/src/cmd/mdb/i86pc/modules/uppc/uppc.c index be910bbcb7..fee48b58f5 100644 --- a/usr/src/cmd/mdb/i86pc/modules/uppc/uppc.c +++ b/usr/src/cmd/mdb/i86pc/modules/uppc/uppc.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -110,7 +110,7 @@ uppc_interrupt_dump(uintptr_t addr, uint_t flags, int argc, /* Print the header first */ if (option_flags & INTR_DISPLAY_INTRSTAT) - mdb_printf("%<u>CPU\t "); + mdb_printf("%<u>CPU "); else mdb_printf("%<u>IRQ Vector IPL(lo/hi) Bus Share "); mdb_printf("%s %</u>\n", option_flags & INTR_DISPLAY_DRVR_INST ? diff --git a/usr/src/cmd/mdb/intel/Makefile.kmdb b/usr/src/cmd/mdb/intel/Makefile.kmdb index 67c6d7c92b..7026ef906c 100644 --- a/usr/src/cmd/mdb/intel/Makefile.kmdb +++ b/usr/src/cmd/mdb/intel/Makefile.kmdb @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -34,9 +34,6 @@ PROMSRCS += \ KMDBSRCS += \ kaif.c \ - kaif_activate.c \ - kaif_idt.c \ - kaif_start_isadep.c \ kmdb_dpi_isadep.c \ kmdb_fault_isadep.c \ kmdb_kdi_isadep.c \ @@ -46,7 +43,6 @@ KMDBSRCS += \ kvm_isadep.c KMDBML += \ - kaif_idthdl.s \ kmdb_asmutil.s \ kmdb_setcontext.s diff --git a/usr/src/cmd/mdb/intel/amd64/Makefile.kmdb b/usr/src/cmd/mdb/intel/amd64/Makefile.kmdb index 93e99f8aa6..324572a024 100644 --- a/usr/src/cmd/mdb/intel/amd64/Makefile.kmdb +++ b/usr/src/cmd/mdb/intel/amd64/Makefile.kmdb @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,27 +19,18 @@ # CDDL HEADER END # # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" # KMDBML += \ - kaif_asmutil.s \ kaif_invoke.s \ - kaif_resume.s \ - kaif_startup.s \ kmdb_start.s KMDBSRCS += \ kmdb_makecontext.c \ mdb_amd64util.c -REGOFFUSERS = \ - kaif_resume.o \ - kaif_startup.o - SACPPFLAGS = -D__$(MACH64) -U__$(MACH) - -$(REGOFFUSERS) $(REGOFFUSERS:%.o=%.ln): kaif_off.h diff --git a/usr/src/cmd/mdb/intel/amd64/genunix/Makefile b/usr/src/cmd/mdb/intel/amd64/genunix/Makefile index 801d16db46..980d83ae29 100644 --- a/usr/src/cmd/mdb/intel/amd64/genunix/Makefile +++ b/usr/src/cmd/mdb/intel/amd64/genunix/Makefile @@ -29,43 +29,10 @@ MODULE = genunix.so MDBTGT = kvm +include ../../../common/modules/genunix/Makefile.files + COMMONSRCS = \ - avl.c \ - bio.c \ - contract.c \ - cpupart.c \ - ctxop.c \ - cyclic.c \ - devinfo.c \ - findstack.c \ - fm.c \ - genunix.c \ - group.c \ - kgrep.c \ - kmem.c \ - ldi.c \ - leaky.c \ - leaky_subr.c \ - lgrp.c \ - list.c \ - log.c \ - mdi.c \ - memory.c \ - mmd.c \ - modhash.c \ - ndievents.c \ - net.c \ - nvpair.c \ - pg.c \ - rctl.c \ - sobj.c \ - streams.c \ - sysevent.c \ - thread.c \ - tsd.c \ - tsol.c \ - vfs.c \ - zone.c + $(GENUNIX_SRCS) KMODSRCS = \ $(COMMONSRCS) diff --git a/usr/src/cmd/mdb/intel/amd64/kmdb/Makefile b/usr/src/cmd/mdb/intel/amd64/kmdb/Makefile index e5094fc27b..c22ed7a256 100644 --- a/usr/src/cmd/mdb/intel/amd64/kmdb/Makefile +++ b/usr/src/cmd/mdb/intel/amd64/kmdb/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -88,9 +88,6 @@ lintprom: $(PROMOBJS:%.o=%.ln) lintkctl: $(KCTLOBJS:%.o=%.ln) $(LINT) $(ALLLINTFLAGS) $(KCTLOBJS:%.o=%.ln) -kaif_off.h: ../../kmdb/kaif_off.in - $(OFFSETS_CREATE) <../../kmdb/kaif_off.in >$@ - kmdb_context_off.h: ../../kmdb/kmdb_context_off.in $(OFFSETS_CREATE) <../../kmdb/kmdb_context_off.in >$@ diff --git a/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.h b/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.h deleted file mode 100644 index 6abe1ba166..0000000000 --- a/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _KAIF_ASMUTIL_H -#define _KAIF_ASMUTIL_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/segments.h> - -#include <kmdb/kaif_regs.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _ASM - -/* - * Multiple CPUs won't be present until cross-call initialization has - * completed. Until that time, we just assume we're CPU zero. - * - * This macro returns the CPUID in %rax, and doesn't clobber any other - * registers. - */ -#define GET_CPUID \ - call kmdb_kdi_xc_initialized; \ - cmpq $0, %rax; \ - je 1f; \ - movzbq %gs:CPU_ID, %rax; \ - jmp 2f; \ -1: \ - clrq %rax; \ -2: - -/* clobbers %rdx, %rcx, returns addr in %rax, CPU ID in %rbx */ -#define GET_CPUSAVE_ADDR \ - GET_CPUID; \ - movq %rax, %rbx; \ - movq $KRS_SIZE, %rcx; \ - mulq %rcx; \ - movq $kaif_cpusave, %rdx; \ - /*CSTYLED*/ \ - addq (%rdx), %rax - -/* - * Save copies of the IDT and GDT descriptors. Note that we only save the IDT - * and GDT if the IDT isn't ours, as we may be legitimately re-entering the - * debugger through the trap handler. We don't want to clobber the saved IDT - * in the process, as we'd end up resuming the world on our IDT. - * - * assumes cpusave in %rax, clobbers %rcx - */ -#define SAVE_IDTGDT \ - sidt KRS_TMPDESC(%rax); \ - movq KRS_TMPDESC+2(%rax), %rcx; \ - cmpq $kaif_idt, %rcx; \ - je 1f; \ - sidt KRS_IDTR(%rax); \ - sgdt KRS_GDTR(%rax); \ -1: - -/* %ss, %rsp, %rflags, %cs, %rip, %err, %trapno already on stack */ -#define KAIF_SAVE_REGS(base) \ - movq %rdi, REG_OFF(KREG_RDI)(base); \ - movq %rsi, REG_OFF(KREG_RSI)(base); \ - movq %rdx, REG_OFF(KREG_RDX)(base); \ - movq %rcx, REG_OFF(KREG_RCX)(base); \ - movq %r8, REG_OFF(KREG_R8)(base); \ - movq %r9, REG_OFF(KREG_R9)(base); \ - movq %rax, REG_OFF(KREG_RAX)(base); \ - movq %rbx, REG_OFF(KREG_RBX)(base); \ - movq %rbp, REG_OFF(KREG_RBP)(base); \ - movq %r10, REG_OFF(KREG_R10)(base); \ - movq %r11, REG_OFF(KREG_R11)(base); \ - movq %r12, REG_OFF(KREG_R12)(base); \ - movq %r13, REG_OFF(KREG_R13)(base); \ - movq %r14, REG_OFF(KREG_R14)(base); \ - movq %r15, REG_OFF(KREG_R15)(base); \ - movq %rbp, REG_OFF(KREG_SAVFP)(base); \ - movq REG_OFF(KREG_RIP)(base), %rax; \ - movq %rax, REG_OFF(KREG_SAVPC)(base); \ - \ - movl $MSR_AMD_FSBASE, %ecx; \ - rdmsr; \ - movl %eax, REG_OFF(KREG_FSBASE)(base); \ - movl %edx, _CONST(REG_OFF(KREG_FSBASE)+4)(base); \ - \ - movl $MSR_AMD_GSBASE, %ecx; \ - rdmsr; \ - movl %eax, REG_OFF(KREG_GSBASE)(base); \ - movl %edx, _CONST(REG_OFF(KREG_GSBASE)+4)(base); \ - \ - movl $MSR_AMD_KGSBASE, %ecx; \ - rdmsr; \ - movl %eax, REG_OFF(KREG_KGSBASE)(base); \ - movl %edx, _CONST(REG_OFF(KREG_KGSBASE)+4)(base); \ - \ - clrq %rax; \ - movw %ds, %ax; \ - movq %rax, REG_OFF(KREG_DS)(base); \ - movw %es, %ax; \ - movq %rax, REG_OFF(KREG_ES)(base); \ - movw %fs, %ax; \ - movq %rax, REG_OFF(KREG_FS)(base); \ - movw %gs, %ax; \ - movq %rax, REG_OFF(KREG_GS)(base) - -#define KAIF_RESTORE_REGS(base) \ - movq base, %rdi; \ - movq REG_OFF(KREG_GS)(%rdi), %rax; \ - movw %ax, %gs; \ - movq REG_OFF(KREG_FS)(%rdi), %rax; \ - movw %ax, %fs; \ - movq REG_OFF(KREG_ES)(%rdi), %rax; \ - movw %ax, %es; \ - movq REG_OFF(KREG_DS)(%rdi), %rax; \ - movw %ax, %ds; \ - \ - movl $MSR_AMD_KGSBASE, %ecx; \ - movl REG_OFF(KREG_KGSBASE)(%rdi), %eax; \ - movl _CONST(REG_OFF(KREG_KGSBASE)+4)(%rdi), %edx; \ - wrmsr; \ - \ - movl $MSR_AMD_GSBASE, %ecx; \ - movl REG_OFF(KREG_GSBASE)(%rdi), %eax; \ - movl _CONST(REG_OFF(KREG_GSBASE)+4)(%rdi), %edx; \ - wrmsr; \ - \ - movl $MSR_AMD_FSBASE, %ecx; \ - movl REG_OFF(KREG_FSBASE)(%rdi), %eax; \ - movl _CONST(REG_OFF(KREG_FSBASE)+4)(%rdi), %edx; \ - wrmsr; \ - \ - movq REG_OFF(KREG_R15)(%rdi), %r15; \ - movq REG_OFF(KREG_R14)(%rdi), %r14; \ - movq REG_OFF(KREG_R13)(%rdi), %r13; \ - movq REG_OFF(KREG_R12)(%rdi), %r12; \ - movq REG_OFF(KREG_R11)(%rdi), %r11; \ - movq REG_OFF(KREG_R10)(%rdi), %r10; \ - movq REG_OFF(KREG_RBP)(%rdi), %rbp; \ - movq REG_OFF(KREG_RBX)(%rdi), %rbx; \ - movq REG_OFF(KREG_RAX)(%rdi), %rax; \ - movq REG_OFF(KREG_R9)(%rdi), %r9; \ - movq REG_OFF(KREG_R8)(%rdi), %r8; \ - movq REG_OFF(KREG_RCX)(%rdi), %rcx; \ - movq REG_OFF(KREG_RDX)(%rdi), %rdx; \ - movq REG_OFF(KREG_RSI)(%rdi), %rsi; \ - movq REG_OFF(KREG_RDI)(%rdi), %rdi - -/* - * Each cpusave buffer has an area set aside for a ring buffer of breadcrumbs. - * The following macros manage the buffer. - */ - -/* Advance the ring buffer */ -#define ADVANCE_CRUMB_POINTER(cpusave, tmp1, tmp2) \ - movq KRS_CURCRUMBIDX(cpusave), tmp1; \ - cmpq $[KAIF_NCRUMBS - 1], tmp1; \ - jge 1f; \ - /* Advance the pointer and index */ \ - addq $1, tmp1; \ - movq tmp1, KRS_CURCRUMBIDX(cpusave); \ - movq KRS_CURCRUMB(cpusave), tmp1; \ - addq $KRM_SIZE, tmp1; \ - jmp 2f; \ -1: /* Reset the pointer and index */ \ - movq $0, KRS_CURCRUMBIDX(cpusave); \ - leaq KRS_CRUMBS(cpusave), tmp1; \ -2: movq tmp1, KRS_CURCRUMB(cpusave); \ - /* Clear the new crumb */ \ - movq $KAIF_NCRUMBS, tmp2; \ -3: movq $0, -4(tmp1, tmp2, 4); \ - decq tmp2; \ - jnz 3b - -/* Set a value in the current breadcrumb buffer */ -#define ADD_CRUMB(cpusave, offset, value, tmp) \ - movq KRS_CURCRUMB(cpusave), tmp; \ - movq value, offset(tmp) - -/* Patch point for MSR clearing. */ -#define KAIF_MSR_PATCH \ - nop; nop; nop; nop; \ - nop; nop; nop; nop; \ - nop; nop; nop; nop; \ - nop; nop; nop; nop; \ - nop - -#endif /* _ASM */ - -#define KAIF_MSR_PATCHSZ 17 /* bytes in KAIF_MSR_PATCH, above */ -#define KAIF_MSR_PATCHOFF 8 /* bytes of code before patch point */ - -#ifdef __cplusplus -} -#endif - -#endif /* _KAIF_ASMUTIL_H */ diff --git a/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.s b/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.s deleted file mode 100644 index 4861bcc476..0000000000 --- a/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_asmutil.s +++ /dev/null @@ -1,86 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/asm_linkage.h> -#include <sys/trap.h> - -#include <kmdb/kaif_asmutil.h> - -#if defined(__lint) -void -kaif_enter(void) -{ -} -#else - - ENTRY(kaif_enter) - pushq %rbp - movq %rsp, %rbp - - pushfq - cli - - int $T_DBGENTR - - popfq - - leave - ret - SET_SIZE(kaif_enter) - -#endif - -#if defined(__lint) -/*ARGSUSED*/ -void -get_idt(desctbr_t *idt) -{ -} -#else - - ENTRY(get_idt) - sidt (%rdi) - ret - SET_SIZE(get_idt) - -#endif - -#if defined(__lint) -/*ARGSUSED*/ -void -set_idt(desctbr_t *idt) -{ -} -#else - - ENTRY(set_idt) - lidt (%rdi) - ret - SET_SIZE(set_idt) - -#endif diff --git a/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_resume.s b/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_resume.s deleted file mode 100644 index 8574be2336..0000000000 --- a/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_resume.s +++ /dev/null @@ -1,239 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/asm_linkage.h> -#include <sys/uadmin.h> -#include <sys/reg.h> -#include <sys/segments.h> -#include <sys/x86_archext.h> -#include <sys/controlregs.h> - -#include <kmdb/kaif.h> -#include <kmdb/kaif_asmutil.h> -#include <kmdb/kaif_off.h> -#include <kmdb/kmdb_dpi_isadep.h> -#include <mdb/mdb_kreg.h> - -/* - * Given the address of the current CPU's cpusave area in %rax, the following - * macro restores the debugging state to said CPU. Restored state includes - * the debug registers from the global %dr variables, and debugging MSRs from - * the CPU save area. This code would be in a separate routine, but for the - * fact that some of the MSRs are jump-sensitive. As such, we need to minimize - * the number of jumps taken subsequent to the update of said MSRs. We can - * remove one jump (the ret) by using a macro instead of a function for the - * debugging state restoration code. - * - * Takes the cpusave area in %rdi as a parameter, clobbers %rax-%rdx - */ -#define KAIF_RESTORE_DEBUGGING_STATE \ - leaq kaif_drreg, %rbx; \ - movq DR_CTL(%rbx), %rcx; \ - movq %rcx, %dr7; \ - movq $KREG_DRSTAT_RESERVED, %rcx; \ - movq %rcx, %dr6; \ - movq DRADDR_OFF(0)(%rbx), %rcx; \ - movq %rcx, %dr0; \ - movq DRADDR_OFF(1)(%rbx), %rcx; \ - movq %rcx, %dr1; \ - movq DRADDR_OFF(2)(%rbx), %rcx; \ - movq %rcx, %dr2; \ - movq DRADDR_OFF(3)(%rbx), %rcx; \ - movq %rcx, %dr3; \ - \ - /* \ - * Write any requested MSRs. \ - */ \ - movq KRS_MSR(%rdi), %rbx; \ - cmpq $0, %rbx; \ - je 3f; \ -1: \ - movl MSR_NUM(%rbx), %ecx; \ - cmpl $0, %ecx; \ - je 3f; \ - \ - movl MSR_TYPE(%rbx), %edx; \ - cmpl $KMDB_MSR_WRITE, %edx; \ - jne 2f; \ - \ - movq MSR_VALP(%rbx), %rdx; \ - movl 0(%rdx), %eax; \ - movl 4(%rdx), %edx; \ - wrmsr; \ -2: \ - addq $MSR_SIZE, %rbx; \ - jmp 1b; \ -3: \ - /* \ - * We must not branch after re-enabling LBR. If \ - * kaif_wsr_wrexit_msr is set, it contains the number \ - * of the MSR that controls LBR. kaif_wsr_wrexit_valp \ - * contains the value that is to be written to enable \ - * LBR. \ - */ \ - movl kaif_msr_wrexit_msr, %ecx; \ - cmpl $0, %ecx; \ - je 1f; \ - \ - movq kaif_msr_wrexit_valp, %rdx; \ - movl 0(%rdx), %eax; \ - movl 4(%rdx), %edx; \ - \ - wrmsr; \ -1: - -#if defined(__lint) -/*ARGSUSED*/ -void -kaif_cpu_debug_init(kaif_cpusave_t *save) -{ -} -#else /* __lint */ - - ENTRY_NP(kaif_cpu_debug_init) - pushq %rbp - movq %rsp, %rbp - - pushq %rbx /* macro will clobber %rbx */ - KAIF_RESTORE_DEBUGGING_STATE - popq %rbx - - leave - ret - - SET_SIZE(kaif_cpu_debug_init) -#endif /* !__lint */ - - /* - * Resume the world. The code that calls kaif_resume has already - * decided whether or not to restore the IDT. - */ -#if defined(__lint) -void -kaif_resume(void) -{ -} -#else /* __lint */ - - ENTRY_NP(kaif_resume) - - /* cpusave in %rdi, debugger command in %rsi */ - - cmpq $KAIF_CPU_CMD_PASS_TO_KERNEL, %rsi - je kaif_pass_to_kernel - - cmpq $KAIF_CPU_CMD_REBOOT, %rsi - je kaif_reboot - - /* - * Send this CPU back into the world - */ - - movq KRS_CR0(%rdi), %rdx - movq %rdx, %cr0 - - KAIF_RESTORE_DEBUGGING_STATE - - movq KRS_GREGS(%rdi), %rsp - KAIF_RESTORE_REGS(%rsp) - addq $REG_OFF(KREG_RIP), %rsp /* Discard state, trapno, err */ - - iretq - - SET_SIZE(kaif_resume) - -#endif /* __lint */ - -#if !defined(__lint) - - ENTRY_NP(kaif_pass_to_kernel) - - /* cpusave is still in %rdi */ - - movq KRS_CR0(%rdi), %rdx - movq %rdx, %cr0 - - /* - * When we replaced the kernel's handlers in the IDT, we made note of - * the handlers being replaced, thus allowing us to pass traps directly - * to said handlers here. We won't have any registers available for use - * after we start popping, and we know we're single-threaded here, so - * we have to use a global to store the handler address. - */ - movq KRS_GREGS(%rdi), %rsp - movq REG_OFF(KREG_TRAPNO)(%rsp), %rdi - call kaif_kernel_trap2hdlr - movq %rax, kaif_kernel_handler - - /* - * The trap handler will expect the stack to be in trap order, with - * %rip being the last entry. Our stack is currently in mdb_kreg.h - * order, so we'll need to pop (and restore) our way back down. - */ - KAIF_RESTORE_REGS(%rsp) - addq $REG_OFF(KREG_RIP), %rsp /* Discard state, trapno, err */ - - jmp *%cs:kaif_kernel_handler - /*NOTREACHED*/ - - SET_SIZE(kaif_pass_to_kernel) - - /* - * Reboot the system. This routine is to be called only by the master - * CPU. - */ - ENTRY_NP(kaif_reboot) - - movq kmdb_kdi_shutdownp, %rax - movq (%rax), %rax - cmpq $0, %rax - je 1f - - /* psm_shutdown is set in the kernel, so we'll try it */ - pushq $AD_BOOT - pushq $A_SHUTDOWN - call *%rax - addq $16, %rsp - -1: /* - * psm_shutdown didn't work or, it wasn't set. Let's try the time- - * honored method for getting things done on Intel machines -- - * sacrifice random bits to random BIOS gods. - */ - ALTENTRY(reset) - movw $0x64, %dx - movb $0xfe, %al - outb (%dx) - - hlt - /*NOTREACHED*/ - - SET_SIZE(reset) - SET_SIZE(kaif_reboot) - -#endif /* !__lint */ diff --git a/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_startup.s b/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_startup.s deleted file mode 100644 index 658f564e02..0000000000 --- a/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_startup.s +++ /dev/null @@ -1,323 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Debugger entry for both master and slave CPUs - */ - -#if defined(__lint) -#include <sys/types.h> -#endif - -#include <sys/segments.h> -#include <sys/asm_linkage.h> -#include <sys/controlregs.h> -#include <sys/x86_archext.h> - -#include <mdb/mdb_kreg.h> -#include <kmdb/kaif.h> -#include <kmdb/kaif_asmutil.h> -#include <kmdb/kaif_regs.h> -#include <kmdb/kaif_off.h> -#include <kmdb/kmdb_dpi_isadep.h> - -#if !defined(__lint) - - /* XXX implement me */ - ENTRY_NP(kaif_nmiint) - clrq %rcx - movq (%rcx), %rcx - SET_SIZE(kaif_nmiint) - - ENTRY_NP(kaif_save_common_state) - - /* - * The state of the world: - * - * The stack has a complete set of saved registers and segment - * selectors, arranged in the order given in mdb_kreg.h. It also has a - * pointer to our cpusave area. - * - * We need to save, into the cpusave area, a pointer to these saved - * registers. After that, we save a few more registers, ready the - * machine for debugger entry, and enter the debugger. - */ - - popq %rax /* the cpusave area */ - movq %rsp, KRS_GREGS(%rax) /* save ptr to current saved regs */ - - SAVE_IDTGDT - - /* Save off %cr0, and clear write protect */ - movq %cr0, %rcx - movq %rcx, KRS_CR0(%rax) - andq $_BITNOT(CR0_WP), %rcx - movq %rcx, %cr0 - - /* Save the debug registers and disable any active watchpoints */ - movq %dr7, %rcx - movq %rcx, KRS_DRCTL(%rax) - andq $_BITNOT(KREG_DRCTL_WPALLEN_MASK), %rcx - movq %rcx, %dr7 - - movq %dr6, %rcx - movq %rcx, KRS_DRSTAT(%rax) - - movq %dr0, %rcx - movq %rcx, KRS_DROFF(0)(%rax) - movq %dr1, %rcx - movq %rcx, KRS_DROFF(1)(%rax) - movq %dr2, %rcx - movq %rcx, KRS_DROFF(2)(%rax) - movq %dr3, %rcx - movq %rcx, KRS_DROFF(3)(%rax) - - /* - * Save any requested MSRs. - */ - movq KRS_MSR(%rax), %rcx - cmpq $0, %rcx - je no_msr - - pushq %rax /* rdmsr clobbers %eax */ - movq %rcx, %rbx - -1: - movl MSR_NUM(%rbx), %ecx - cmpl $0, %ecx - je msr_done - - movl MSR_TYPE(%rbx), %edx - cmpl $KMDB_MSR_READ, %edx - jne msr_next - - rdmsr /* addr in %ecx, value into %edx:%eax */ - movl %eax, MSR_VAL(%rbx) - movl %edx, _CONST(MSR_VAL + 4)(%rbx) - -msr_next: - addq $MSR_SIZE, %rbx - jmp 1b - -msr_done: - popq %rax - -no_msr: - clrq %rbp /* stack traces should end here */ - - pushq %rax - movq %rax, %rdi /* cpusave */ - - call kaif_debugger_entry - - /* Pass cpusave and debugger return code for "call" to resume */ - popq %rdi - movq %rax, %rsi - - jmp kaif_resume - - SET_SIZE(kaif_save_common_state) - -#endif /* !__lint */ - -/* - * The main entry point for master CPUs. It also serves as the trap handler - * for all traps and interrupts taken during single-step. - */ -#if defined(__lint) -void -kaif_cmnint(void) -{ -} -#else /* __lint */ - - ENTRY_NP(kaif_cmnint) - ALTENTRY(kaif_master_entry) - - cli - - /* Save current register state */ - subq $REG_OFF(KREG_TRAPNO), %rsp - KAIF_SAVE_REGS(%rsp) - - /* - * Switch to the kernel's GSBASE. Neither GSBASE nor the ill-named - * KGSBASE can be trusted, as the kernel may or may not have already - * done a swapgs. All is not lost, as the kernel can divine the correct - * value for us. - */ - movq mdb+MDB_KDI, %rax - movq MKDI_GDT2GSBASE(%rax), %rax - subq $10, %rsp - sgdt (%rsp) - movq 2(%rsp), %rdi /* gdt base now in %rdi */ - addq $10, %rsp - call *%rax /* returns kernel's GSBASE in %rax */ - - movq %rax, %rdx - shrq $32, %rdx - movl $MSR_AMD_GSBASE, %ecx - wrmsr - - GET_CPUSAVE_ADDR /* %rax = cpusave, %rbx = CPU ID */ - - ADVANCE_CRUMB_POINTER(%rax, %rcx, %rdx) - - ADD_CRUMB(%rax, KRM_CPU_STATE, $KAIF_CPU_STATE_MASTER, %rdx) - - movq REG_OFF(KREG_RIP)(%rsp), %rcx - ADD_CRUMB(%rax, KRM_PC, %rcx, %rdx) - ADD_CRUMB(%rax, KRM_SP, %rsp, %rdx) - movq REG_OFF(KREG_TRAPNO)(%rsp), %rcx - ADD_CRUMB(%rax, KRM_TRAPNO, %rcx, %rdx) - - movq %rsp, %rbp - pushq %rax - - /* - * Were we in the debugger when we took the trap (i.e. was %esp in one - * of the debugger's memory ranges)? - */ - leaq kaif_memranges, %rcx - movl kaif_nmemranges, %edx -1: cmpq MR_BASE(%rcx), %rsp - jl 2f /* below this range -- try the next one */ - cmpq MR_LIM(%rcx), %rsp - jg 2f /* above this range -- try the next one */ - jmp 3f /* matched within this range */ - -2: decl %edx - jz kaif_save_common_state /* %rsp not within debugger memory */ - addq $MR_SIZE, %rcx - jmp 1b - -3: /* - * The master is still set. That should only happen if we hit a trap - * while running in the debugger. Note that it may be an intentional - * fault. kmdb_dpi_handle_fault will sort it all out. - */ - - movq REG_OFF(KREG_TRAPNO)(%rbp), %rdi - movq REG_OFF(KREG_RIP)(%rbp), %rsi - movq REG_OFF(KREG_RSP)(%rbp), %rdx - movq %rbx, %rcx /* cpuid */ - - call kmdb_dpi_handle_fault - - /* - * If we're here, we ran into a debugger problem, and the user - * elected to solve it by having the debugger debug itself. The - * state we're about to save is that of the debugger when it took - * the fault. - */ - - jmp kaif_save_common_state - - SET_SIZE(kaif_master_entry) - SET_SIZE(kaif_cmnint) - -#endif /* __lint */ - -/* - * The cross-call handler for slave CPUs. - * - * The debugger is single-threaded, so only one CPU, called the master, may be - * running it at any given time. The other CPUs, known as slaves, spin in a - * busy loop until there's something for them to do. This is the entry point - * for the slaves - they'll be sent here in response to a cross-call sent by the - * master. - */ - -#if defined(__lint) -char kaif_slave_entry_patch; - -void -kaif_slave_entry(void) -{ -} -#else /* __lint */ - .globl kaif_slave_entry_patch; - - ENTRY_NP(kaif_slave_entry) - - /* kaif_msr_add_clrentry knows where this is */ -kaif_slave_entry_patch: - KAIF_MSR_PATCH; - - /* - * Cross calls are implemented as function calls, so our stack currently - * looks like one you'd get from a zero-argument function call. That - * is, there's the return %rip at %rsp, and that's about it. We need - * to make it look like an interrupt stack. When we first save, we'll - * reverse the saved %ss and %rip, which we'll fix back up when we've - * freed up some general-purpose registers. We'll also need to fix up - * the saved %rsp. - */ - - pushq %rsp /* pushed value off by 8 */ - pushfq - cli - clrq %rax - movw %cs, %ax - pushq %rax - movw %ss, %ax - pushq %rax /* rip should be here */ - pushq $-1 /* phony trap error code */ - pushq $-1 /* phony trap number */ - - subq $REG_OFF(KREG_TRAPNO), %rsp - KAIF_SAVE_REGS(%rsp) - - movq REG_OFF(KREG_SS)(%rsp), %rax - xchgq REG_OFF(KREG_RIP)(%rsp), %rax - movq %rax, REG_OFF(KREG_SS)(%rsp) - - movq REG_OFF(KREG_RSP)(%rsp), %rax - addq $8, %rax - movq %rax, REG_OFF(KREG_RSP)(%rsp) - - /* - * We've saved all of the general-purpose registers, and have a stack - * that is irettable (after we strip down to the error code) - */ - - GET_CPUSAVE_ADDR /* %rax = cpusave, %rbx = CPU ID */ - - ADVANCE_CRUMB_POINTER(%rax, %rcx, %rdx) - - ADD_CRUMB(%rax, KRM_CPU_STATE, $KAIF_CPU_STATE_SLAVE, %rdx) - - movq REG_OFF(KREG_RIP)(%rsp), %rcx - ADD_CRUMB(%rax, KRM_PC, %rcx, %rdx) - - pushq %rax - jmp kaif_save_common_state - - SET_SIZE(kaif_slave_entry) - -#endif /* __lint */ diff --git a/usr/src/cmd/mdb/intel/ia32/Makefile.kmdb b/usr/src/cmd/mdb/intel/ia32/Makefile.kmdb index d9b792bc58..53b19b535d 100644 --- a/usr/src/cmd/mdb/intel/ia32/Makefile.kmdb +++ b/usr/src/cmd/mdb/intel/ia32/Makefile.kmdb @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,17 +19,14 @@ # CDDL HEADER END # # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" # KMDBML += \ - kaif_asmutil.s \ kaif_invoke.s \ - kaif_resume.s \ - kaif_startup.s \ kmdb_start.s KMDBSRCS += \ @@ -38,10 +34,4 @@ KMDBSRCS += \ kmdb_makecontext.c \ kvm_cpu_p6.c -REGOFFUSERS = \ - kaif_resume.o \ - kaif_startup.o - SACPPFLAGS = -D__$(MACH) - -$(REGOFFUSERS) $(REGOFFUSERS:%.o=%.ln): kaif_off.h diff --git a/usr/src/cmd/mdb/intel/ia32/genunix/Makefile b/usr/src/cmd/mdb/intel/ia32/genunix/Makefile index 63609d42b2..7ca684b524 100644 --- a/usr/src/cmd/mdb/intel/ia32/genunix/Makefile +++ b/usr/src/cmd/mdb/intel/ia32/genunix/Makefile @@ -29,43 +29,10 @@ MODULE = genunix.so MDBTGT = kvm +include ../../../common/modules/genunix/Makefile.files + COMMONSRCS = \ - avl.c \ - bio.c \ - contract.c \ - cpupart.c \ - ctxop.c \ - cyclic.c \ - devinfo.c \ - findstack.c \ - fm.c \ - genunix.c \ - group.c \ - kgrep.c \ - kmem.c \ - ldi.c \ - leaky.c \ - leaky_subr.c \ - lgrp.c \ - list.c \ - log.c \ - mdi.c \ - memory.c \ - mmd.c \ - modhash.c \ - ndievents.c \ - net.c \ - nvpair.c \ - pg.c \ - rctl.c \ - sobj.c \ - streams.c \ - sysevent.c \ - thread.c \ - tsd.c \ - tsol.c \ - vfs.c \ - zone.c + $(GENUNIX_SRCS) KMODSRCS = \ $(COMMONSRCS) diff --git a/usr/src/cmd/mdb/intel/ia32/kmdb/Makefile b/usr/src/cmd/mdb/intel/ia32/kmdb/Makefile index ccd4b446c4..594594ecb5 100644 --- a/usr/src/cmd/mdb/intel/ia32/kmdb/Makefile +++ b/usr/src/cmd/mdb/intel/ia32/kmdb/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -79,9 +79,6 @@ lintprom: $(PROMOBJS:%.o=%.ln) lintkctl: $(KCTLOBJS:%.o=%.ln) $(LINT) $(ALLLINTFLAGS) $(KCTLOBJS:%.o=%.ln) -kaif_off.h: ../../kmdb/kaif_off.in - $(OFFSETS_CREATE) <../../kmdb/kaif_off.in >$@ - kmdb_context_off.h: ../../kmdb/kmdb_context_off.in $(OFFSETS_CREATE) <../../kmdb/kmdb_context_off.in >$@ diff --git a/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.h b/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.h deleted file mode 100644 index 0ed570f1d2..0000000000 --- a/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _KAIF_ASMUTIL_H -#define _KAIF_ASMUTIL_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/segments.h> - -#include <kmdb/kaif_regs.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef _ASM - -/* - * Multiple CPUs won't be present until a) we're on the kernel's %gs and - * b) cross-call initialization has completed. Until that time, we just assume - * we're CPU zero. - * - * This macro returns the CPUID in %eax, and doesn't clobber any other - * registers. - */ -#define GET_CPUID \ - call kmdb_kdi_xc_initialized; \ - cmpl $0, %eax; \ - je 1f; \ - movw %gs, %ax; \ - cmpw $KGS_SEL, %ax; \ - jne 1f; \ - verr %ax; \ - jnz 1f; \ - ; \ - movzbl %gs:CPU_ID, %eax; \ - jmp 2f; \ -1: \ - clr %eax; \ -2: - -/* clobbers %edx, %ecx, returns addr in %eax, cpu id in %ebx */ -#define GET_CPUSAVE_ADDR \ - GET_CPUID; \ - movl %eax, %ebx; \ - movl $KRS_SIZE, %ecx; \ - mull %ecx; \ - movl $kaif_cpusave, %edx; \ - /*CSTYLED*/ \ - addl (%edx), %eax - -/* - * Save copies of the IDT and GDT descriptors. Note that we only save the IDT - * and GDT if the IDT isn't ours, as we may be legitimately re-entering the - * debugger through the trap handler. We don't want to clobber the saved IDT - * in the process, as we'd end up resuming the world on our IDT. - * - * assumes cpusave in %eax, clobbers %ecx - */ -#define SAVE_IDTGDT \ - sidt KRS_TMPDESC(%eax); \ - movl KRS_TMPDESC+2(%eax), %ecx; \ - cmpl $kaif_idt, %ecx; \ - je 1f; \ - sidt KRS_IDTR(%eax); \ - sgdt KRS_GDTR(%eax); \ -1: - -/* - * Each cpusave buffer has an area set aside for a ring buffer of breadcrumbs. - * The following macros manage the buffer. - */ - -/* Advance the ring buffer */ -#define ADVANCE_CRUMB_POINTER(cpusave, tmp1, tmp2) \ - movl KRS_CURCRUMBIDX(cpusave), tmp1; \ - cmpl $[KAIF_NCRUMBS - 1], tmp1; \ - jge 1f; \ - /* Advance the pointer and index */ \ - addl $1, tmp1; \ - movl tmp1, KRS_CURCRUMBIDX(cpusave); \ - movl KRS_CURCRUMB(cpusave), tmp1; \ - addl $KRM_SIZE, tmp1; \ - jmp 2f; \ -1: /* Reset the pointer and index */ \ - movw $0, KRS_CURCRUMBIDX(cpusave); \ - leal KRS_CRUMBS(cpusave), tmp1; \ -2: movl tmp1, KRS_CURCRUMB(cpusave); \ - /* Clear the new crumb */ \ - movl $KAIF_NCRUMBS, tmp2; \ -3: movl $0, -4(tmp1, tmp2, 4); \ - decl tmp2; \ - jnz 3b - -/* Set a value in the current breadcrumb buffer */ -#define ADD_CRUMB(cpusave, offset, value, tmp) \ - movl KRS_CURCRUMB(cpusave), tmp; \ - movl value, offset(tmp) - -/* Patch point for MSR clearing. */ -#define KAIF_MSR_PATCH \ - nop; nop; nop; nop; \ - nop; nop; nop; nop; \ - nop; nop; nop; nop; \ - nop - -#endif /* _ASM */ - -#define KAIF_MSR_PATCHSZ 13 /* bytes in KAIF_MSR_PATCH, above */ -#define KAIF_MSR_PATCHOFF 8 /* bytes of code before patch point */ - -#ifdef __cplusplus -} -#endif - -#endif /* _KAIF_ASMUTIL_H */ diff --git a/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.s b/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.s deleted file mode 100644 index f695047c52..0000000000 --- a/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_asmutil.s +++ /dev/null @@ -1,92 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/asm_linkage.h> -#include <sys/trap.h> - -#include <kmdb/kaif_asmutil.h> - -#if defined(__lint) -void -kaif_enter(void) -{ -} -#else - - ENTRY(kaif_enter) - pushl %ebp - movl %esp, %ebp - - pushfl - cli - int $T_DBGENTR - popfl - - leave - ret - SET_SIZE(kaif_enter) - -#endif - -#if defined(__lint) -/*ARGSUSED*/ -void -get_idt(desctbr_t *idt) -{ -} -#else - - ENTRY(get_idt) - pushl %ebp - movl %esp, %ebp - movl 8(%ebp), %edx - sidt (%edx) - leave - ret - SET_SIZE(get_idt) - -#endif - -#if defined(__lint) -/*ARGSUSED*/ -void -set_idt(desctbr_t *idt) -{ -} -#else - - ENTRY(set_idt) - pushl %ebp - movl %esp, %ebp - movl 8(%ebp), %edx - lidt (%edx) - leave - ret - SET_SIZE(set_idt) - -#endif diff --git a/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_resume.s b/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_resume.s deleted file mode 100644 index c9693b8212..0000000000 --- a/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_resume.s +++ /dev/null @@ -1,253 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/asm_linkage.h> -#include <sys/uadmin.h> -#include <sys/reg.h> -#include <sys/segments.h> -#include <sys/x86_archext.h> - -#include <kmdb/kaif.h> -#include <kmdb/kaif_asmutil.h> -#include <kmdb/kaif_off.h> -#include <kmdb/kmdb_dpi_isadep.h> -#include <mdb/mdb_kreg.h> - -/* - * Given the address of the current CPU's cpusave area in %eax, the following - * macro restores the debugging state to said CPU. Restored state includes - * the debug registers from the global %dr variables, and debugging MSRs from - * the CPU save area. This code would be in a separate routine, but for the - * fact that some of the MSRs are jump-sensitive. As such, we need to minimize - * the number of jumps taken subsequent to the update of said MSRs. We can - * remove one jump (the ret) by using a macro instead of a function for the - * debugging state restoration code. - * - * Takes the cpusave area in %eax as a parameter, clobbers %eax-%edx - */ -#define KAIF_RESTORE_DEBUGGING_STATE \ - leal kaif_drreg, %ebx; \ - movl DR_CTL(%ebx), %ecx; \ - movl %ecx, %dr7; \ - movl $KREG_DRSTAT_RESERVED, %ecx; \ - movl %ecx, %dr6; \ - movl DRADDR_OFF(0)(%ebx), %ecx; \ - movl %ecx, %dr0; \ - movl DRADDR_OFF(1)(%ebx), %ecx; \ - movl %ecx, %dr1; \ - movl DRADDR_OFF(2)(%ebx), %ecx; \ - movl %ecx, %dr2; \ - movl DRADDR_OFF(3)(%ebx), %ecx; \ - movl %ecx, %dr3; \ - \ - /* \ - * Write any requested MSRs. \ - */ \ - movl KRS_MSR(%eax), %ebx; \ - cmpl $0, %ebx; \ - je 3f; \ -1: \ - movl MSR_NUM(%ebx), %ecx; \ - cmpl $0, %ecx; \ - je 3f; \ - \ - movl MSR_TYPE(%ebx), %edx; \ - cmpl $KMDB_MSR_WRITE, %edx; \ - jne 2f; \ - \ - movl MSR_VALP(%ebx), %edx; \ - movl 0(%edx), %eax; \ - movl 4(%edx), %edx; \ - wrmsr; \ -2: \ - addl $MSR_SIZE, %ebx; \ - jmp 1b; \ -3: \ - /* \ - * We must not branch after re-enabling LBR. If \ - * kaif_wsr_wrexit_msr is set, it contains the number \ - * of the MSR that controls LBR. kaif_wsr_wrexit_valp \ - * contains the value that is to be written to enable \ - * LBR. \ - */ \ - movl kaif_msr_wrexit_msr, %ecx; \ - cmpl $0, %ecx; \ - je 1f; \ - \ - movl kaif_msr_wrexit_valp, %edx; \ - movl 0(%edx), %eax; \ - movl 4(%edx), %edx; \ - \ - wrmsr; \ -1: - -#if defined(__lint) -/*ARGSUSED*/ -void -kaif_cpu_debug_init(kaif_cpusave_t *save) -{ -} -#else /* __lint */ - - ENTRY_NP(kaif_cpu_debug_init) - pushl %ebp - movl %esp, %ebp - - movl 8(%ebp), %eax - - pushl %ebx - KAIF_RESTORE_DEBUGGING_STATE - popl %ebx - - leave - ret - - SET_SIZE(kaif_cpu_debug_init) -#endif /* !__lint */ - - /* - * Resume the world. The code that calls kaif_resume has already - * decided whether or not to restore the IDT. - */ -#if defined(__lint) -void -kaif_resume(void) -{ -} -#else /* __lint */ - - ENTRY_NP(kaif_resume) - popl %ebx /* command */ - popl %eax /* cpusave */ - - cmpl $KAIF_CPU_CMD_PASS_TO_KERNEL, %ebx - je kaif_pass_to_kernel - - cmpl $KAIF_CPU_CMD_REBOOT, %ebx - je kaif_reboot - - /* - * Send this CPU back into the world - */ - - movl KRS_CR0(%eax), %edx - movl %edx, %cr0 - - KAIF_RESTORE_DEBUGGING_STATE - - addl $8, %esp /* Discard savfp and savpc */ - - popl %ss - popl %gs - popl %fs - popl %es - popl %ds - popal - - addl $8, %esp /* Discard TRAPNO and ERROR */ - - iret - - SET_SIZE(kaif_resume) -#endif /* __lint */ - -#if !defined(__lint) - - ENTRY_NP(kaif_pass_to_kernel) - - /* cpusave is still in %eax */ - - movl KRS_CR0(%eax), %edx - movl %edx, %cr0 - - /* - * When we replaced the kernel's handlers in the IDT, we made note of - * the handlers being replaced, thus allowing us to pass traps directly - * to said handlers here. We won't have any registers available for use - * after we start popping, and we know we're single-threaded here, so - * we have to use a global to store the handler address. - */ - pushl REG_OFF(KREG_TRAPNO)(%esp) - call kaif_kernel_trap2hdlr - addl $4, %esp - movl %eax, kaif_kernel_handler - - /* - * The trap handler will expect the stack to be in trap order, with - * %eip being the last entry. Our stack is currently in mdb_kreg.h - * order, so we'll need to pop (and restore) our way back down. - */ - addl $8, %esp /* Discard savfp and savpc */ - popl %ss - popl %gs - popl %fs - popl %es - popl %ds - popal - addl $8, %esp /* Discard trapno and err */ - - ljmp $KCS_SEL, $1f -1: jmp *%cs:kaif_kernel_handler - /*NOTREACHED*/ - - SET_SIZE(kaif_pass_to_kernel) - - /* - * Reboot the system. This routine is to be called only by the master - * CPU. - */ - ENTRY_NP(kaif_reboot) - - movl kmdb_kdi_shutdownp, %eax - movl (%eax), %eax - cmpl $0, %eax - je 1f - - /* psm_shutdown is set in the kernel, so we'll try it */ - pushl $AD_BOOT - pushl $A_SHUTDOWN - call *%eax - addl $8, %esp - -1: /* - * psm_shutdown didn't work or, it wasn't set. Let's try the time- - * honored method for getting things done on Intel machines -- - * sacrifice random bits to random BIOS gods. - */ - ALTENTRY(reset) - movw $0x64, %dx - movb $0xfe, %al - outb (%dx) - - hlt - /*NOTREACHED*/ - - SET_SIZE(reset) - SET_SIZE(kaif_reboot) - -#endif /* !__lint */ diff --git a/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_startup.s b/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_startup.s deleted file mode 100644 index 196c3b26c4..0000000000 --- a/usr/src/cmd/mdb/intel/ia32/kmdb/kaif_startup.s +++ /dev/null @@ -1,369 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Debugger entry for both master and slave CPUs - */ - -#if defined(__lint) -#include <sys/types.h> -#endif - -#include <sys/segments.h> -#include <sys/asm_linkage.h> -#include <sys/controlregs.h> -#include <sys/x86_archext.h> - -#include <mdb/mdb_kreg.h> -#include <kmdb/kaif.h> -#include <kmdb/kaif_asmutil.h> -#include <kmdb/kaif_regs.h> -#include <kmdb/kaif_off.h> -#include <kmdb/kmdb_dpi_isadep.h> - -#if !defined(__lint) - - /* XXX implement me */ - ENTRY_NP(kaif_nmiint) - clr %ecx - movl (%ecx), %ecx - SET_SIZE(kaif_nmiint) - - ENTRY_NP(kaif_save_common_state) - - /* - * The state of the world: - * - * The stack has a complete set of saved registers and segment - * selectors, arranged in `struct regs' order (or vice-versa), up to - * and including EFLAGS. It also has a pointer to our cpusave area. - * - * We need to save a pointer to these saved registers. We also want - * to adjust the saved %esp - it should point just beyond the saved - * registers to the last frame of the thread we interrupted. Finally, - * we want to clear out bits 16-31 of the saved selectors, as the - * selector pushls don't automatically clear them. - */ - popl %eax /* the cpusave area */ - - movl %esp, KRS_GREGS(%eax) /* save ptr to current saved regs */ - - SAVE_IDTGDT - - addl $REG_OFF(KREG_EFLAGS - KREG_EAX), KREG_OFF(KREG_ESP)(%esp) - - andl $0xffff, KREG_OFF(KREG_SS)(%esp) - andl $0xffff, KREG_OFF(KREG_GS)(%esp) - andl $0xffff, KREG_OFF(KREG_FS)(%esp) - andl $0xffff, KREG_OFF(KREG_ES)(%esp) - andl $0xffff, KREG_OFF(KREG_DS)(%esp) - - /* Save off %cr0, and clear write protect */ - movl %cr0, %ecx - movl %ecx, KRS_CR0(%eax) - andl $_BITNOT(CR0_WP), %ecx - movl %ecx, %cr0 - - /* Save the debug registers and disable any active watchpoints */ - movl %dr7, %ecx - movl %ecx, KRS_DRCTL(%eax) - andl $_BITNOT(KREG_DRCTL_WPALLEN_MASK), %ecx - movl %ecx, %dr7 - - movl %dr6, %ecx - movl %ecx, KRS_DRSTAT(%eax) - - movl %dr0, %ecx - movl %ecx, KRS_DROFF(0)(%eax) - movl %dr1, %ecx - movl %ecx, KRS_DROFF(1)(%eax) - movl %dr2, %ecx - movl %ecx, KRS_DROFF(2)(%eax) - movl %dr3, %ecx - movl %ecx, KRS_DROFF(3)(%eax) - - /* - * Save any requested MSRs. - */ - movl KRS_MSR(%eax), %ecx - cmpl $0, %ecx - je no_msr - - pushl %eax /* rdmsr clobbers %eax */ - movl %ecx, %ebx - -1: - movl MSR_NUM(%ebx), %ecx - cmpl $0, %ecx - je msr_done - - movl MSR_TYPE(%ebx), %edx - cmpl $KMDB_MSR_READ, %edx - jne msr_next - - rdmsr /* addr in %ecx, value into %edx:%eax */ - movl %eax, MSR_VAL(%ebx) - movl %edx, _CONST(MSR_VAL + 4)(%ebx) - -msr_next: - addl $MSR_SIZE, %ebx - jmp 1b - -msr_done: - popl %eax - -no_msr: - clr %ebp /* stack traces should end here */ - - pushl %eax - call kaif_debugger_entry - pushl %eax /* leave cpusave on the stack */ - - jmp kaif_resume - - SET_SIZE(kaif_save_common_state) - -#endif /* !__lint */ - -/* - * The main entry point for master CPUs. It also serves as the trap handler - * for all traps and interrupts taken during single-step. - */ -#if defined(__lint) -void -kaif_cmnint(void) -{ -} -#else /* __lint */ - - ENTRY_NP(kaif_cmnint) - ALTENTRY(kaif_master_entry) - - cli - - /* Save all registers and selectors */ - pushal - pushl %ds - pushl %es - pushl %fs - pushl %gs - pushl %ss - - subl $8, %esp - movl %ebp, REG_OFF(KREG_SAVFP)(%esp) - movl REG_OFF(KREG_EIP)(%esp), %eax - movl %eax, REG_OFF(KREG_SAVPC)(%esp) - - /* - * If the kernel has started using its own selectors, we should too. - * Update our saved selectors if they haven't been updated already. - */ - movw %cs, %ax - cmpw $KCS_SEL, %ax - jne 1f /* The kernel hasn't switched yet */ - - movw $KDS_SEL, %ax - movw %ax, %ds - movw kaif_cs, %ax - cmpw $KCS_SEL, %ax - je 1f /* We already switched */ - - /* - * The kernel switched, but we haven't. Update our saved selectors - * to match the kernel's copies for use below. - */ - movl $KCS_SEL, kaif_cs - movl $KDS_SEL, kaif_ds - movl $KFS_SEL, kaif_fs - movl $KGS_SEL, kaif_gs - -1: - /* - * Set the selectors to a known state. If we come in from kmdb's IDT, - * we'll be on boot's %cs. This will cause GET_CPUSAVE_ADDR to return - * CPU 0's cpusave, regardless of which CPU we're on, and chaos will - * ensue. So, if we've got $KCSSEL in kaif_cs, switch to it. The other - * selectors are restored normally. - */ - movw %cs:kaif_cs, %ax - cmpw $KCS_SEL, %ax - jne 1f - ljmp $KCS_SEL, $1f -1: - movw %cs:kaif_ds, %ds - movw kaif_ds, %es - movw kaif_fs, %fs - movw kaif_gs, %gs - movw kaif_ds, %ss - - GET_CPUSAVE_ADDR /* %eax = cpusave, %ebx = CPU ID */ - - ADVANCE_CRUMB_POINTER(%eax, %ecx, %edx) - - ADD_CRUMB(%eax, KRM_CPU_STATE, $KAIF_CPU_STATE_MASTER, %edx) - - movl REG_OFF(KREG_EIP)(%esp), %ecx - ADD_CRUMB(%eax, KRM_PC, %ecx, %edx) - ADD_CRUMB(%eax, KRM_SP, %esp, %edx) - movl REG_OFF(KREG_TRAPNO)(%esp), %ecx - ADD_CRUMB(%eax, KRM_TRAPNO, %ecx, %edx) - - movl %esp, %ebp - pushl %eax - - /* - * Were we in the debugger when we took the trap (i.e. was %esp in one - * of the debugger's memory ranges)? - */ - leal kaif_memranges, %ecx - movl kaif_nmemranges, %edx -1: cmpl MR_BASE(%ecx), %esp - jl 2f /* below this range -- try the next one */ - cmpl MR_LIM(%ecx), %esp - jg 2f /* above this range -- try the next one */ - jmp 3f /* matched within this range */ - -2: decl %edx - jz kaif_save_common_state /* %esp not within debugger memory */ - addl $MR_SIZE, %ecx - jmp 1b - -3: /* - * %esp was within one of the debugger's memory ranges. This should only - * happen when we take a trap while running in the debugger. - * kmdb_dpi_handle_fault will determine whether or not it was an expected - * trap, and will take the appropriate action. - */ - - pushl %ebx /* cpuid */ - - movl REG_OFF(KREG_ESP)(%ebp), %ecx - addl $REG_OFF(KREG_EFLAGS - KREG_EAX), %ecx - pushl %ecx - - pushl REG_OFF(KREG_EIP)(%ebp) - pushl REG_OFF(KREG_TRAPNO)(%ebp) - - call kmdb_dpi_handle_fault - addl $16, %esp - - /* - * If we're here, we ran into a debugger problem, and the user - * elected to solve it by having the debugger debug itself. The - * state we're about to save is that of the debugger when it took - * the fault. - */ - - jmp kaif_save_common_state - - SET_SIZE(kaif_master_entry) - SET_SIZE(kaif_cmnint) - -#endif /* __lint */ - -/* - * The cross-call handler for slave CPUs. - * - * The debugger is single-threaded, so only one CPU, called the master, may be - * running it at any given time. The other CPUs, known as slaves, spin in a - * busy loop until there's something for them to do. This is the entry point - * for the slaves - they'll be sent here in response to a cross-call sent by the - * master. - */ - -#if defined(__lint) -char kaif_slave_entry_patch; - -void -kaif_slave_entry(void) -{ -} -#else /* __lint */ - .globl kaif_slave_entry_patch; - - ENTRY_NP(kaif_slave_entry) - - /* kaif_msr_add_clrentry knows where this is */ -kaif_slave_entry_patch: - KAIF_MSR_PATCH; - - /* - * Cross calls are implemented as function calls, so our stack currently - * looks like one you'd get from a zero-argument function call. There's - * an %eip at %esp, and that's about it. We want to make it look like the - * master CPU's stack. By doing this, we can use the same resume code for - * both master and slave. We need to make our stack look like a `struct - * regs' before we jump into the common save routine. - */ - - pushl %cs - pushfl - cli - pushl $-1 /* A phony trap error code */ - pushl $-1 /* A phony trap number */ - pushal - pushl %ds - pushl %es - pushl %fs - pushl %gs - pushl %ss - - subl $8, %esp - movl %ebp, REG_OFF(KREG_SAVFP)(%esp) - movl REG_OFF(KREG_EIP)(%esp), %eax - movl %eax, REG_OFF(KREG_SAVPC)(%esp) - - /* Swap our saved EFLAGS and %eip. Each is where the other should be */ - movl REG_OFF(KREG_EFLAGS)(%esp), %eax - xchgl REG_OFF(KREG_EIP)(%esp), %eax - movl %eax, REG_OFF(KREG_EFLAGS)(%esp) - - /* Our stack now matches struct regs, and is irettable */ - - /* Load sanitized segment selectors */ - movw kaif_ds, %ds - movw kaif_ds, %es - movw kaif_fs, %fs - movw kaif_gs, %gs - movw kaif_ds, %ss - - GET_CPUSAVE_ADDR /* %eax = cpusave, %ebx = CPU ID */ - - ADVANCE_CRUMB_POINTER(%eax, %ecx, %edx) - - ADD_CRUMB(%eax, KRM_CPU_STATE, $KAIF_CPU_STATE_SLAVE, %edx) - - movl REG_OFF(KREG_EIP)(%esp), %ecx - ADD_CRUMB(%eax, KRM_PC, %ecx, %edx) - - pushl %eax - jmp kaif_save_common_state - - SET_SIZE(kaif_slave_entry) - -#endif /* __lint */ diff --git a/usr/src/cmd/mdb/intel/ia32/kmdb/kvm_cpu_p6.c b/usr/src/cmd/mdb/intel/ia32/kmdb/kvm_cpu_p6.c index 732142e85a..b3c3982ca6 100644 --- a/usr/src/cmd/mdb/intel/ia32/kmdb/kvm_cpu_p6.c +++ b/usr/src/cmd/mdb/intel/ia32/kmdb/kvm_cpu_p6.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -91,13 +90,13 @@ kmt_p6_branches(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) * MSRs that we want to track. These will be read each time the debugger is * entered. */ -static const kmdb_msr_t kmt_p6_msr[] = { - { MSR_DEBUGCTL, KMDB_MSR_CLEARENTRY }, - { MSR_DEBUGCTL, KMDB_MSR_WRITEDELAY, &kmt_cpu_p6.p6_debugctl }, - { MSR_LBR_TO, KMDB_MSR_READ }, - { MSR_LBR_FROM, KMDB_MSR_READ }, - { MSR_LEX_TO, KMDB_MSR_READ }, - { MSR_LEX_FROM, KMDB_MSR_READ }, +static const kdi_msr_t kmt_p6_msr[] = { + { MSR_DEBUGCTL, KDI_MSR_CLEARENTRY }, + { MSR_DEBUGCTL, KDI_MSR_WRITEDELAY, &kmt_cpu_p6.p6_debugctl }, + { MSR_LBR_TO, KDI_MSR_READ }, + { MSR_LBR_FROM, KDI_MSR_READ }, + { MSR_LEX_TO, KDI_MSR_READ }, + { MSR_LEX_FROM, KDI_MSR_READ }, { NULL } }; diff --git a/usr/src/cmd/mdb/intel/kmdb/kaif.c b/usr/src/cmd/mdb/intel/kmdb/kaif.c index ceedccc96f..207ddca12a 100644 --- a/usr/src/cmd/mdb/intel/kmdb/kaif.c +++ b/usr/src/cmd/mdb/intel/kmdb/kaif.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -28,58 +28,43 @@ /* * The debugger/"PROM" interface layer * - * (it makes more sense on SPARC) + * It makes more sense on SPARC. In reality, these interfaces deal with three + * things: setting break/watchpoints, stepping, and interfacing with the KDI to + * set up kmdb's IDT handlers. */ #include <kmdb/kmdb_dpi_impl.h> #include <kmdb/kmdb_kdi.h> #include <kmdb/kmdb_umemglue.h> #include <kmdb/kaif.h> -#include <kmdb/kaif_asmutil.h> #include <kmdb/kmdb_io.h> +#include <kmdb/kaif_start.h> #include <mdb/mdb_err.h> #include <mdb/mdb_debug.h> #include <mdb/mdb_isautil.h> #include <mdb/mdb_io_impl.h> -#include <mdb/mdb_kreg.h> +#include <mdb/mdb_kreg_impl.h> #include <mdb/mdb.h> #include <sys/types.h> -#include <sys/segments.h> #include <sys/bitmap.h> #include <sys/termios.h> +#include <sys/kdi_impl.h> -kaif_cpusave_t *kaif_cpusave; +/* + * This is the area containing the saved state when we enter + * via kmdb's IDT entries. + */ +kdi_cpusave_t *kaif_cpusave; int kaif_ncpusave; - -kaif_drreg_t kaif_drreg; +kdi_drreg_t kaif_drreg; uint32_t kaif_waptmap; -#ifndef __amd64 -/* Used to track the current set of valid kernel selectors. */ -uint32_t kaif_cs; -uint32_t kaif_ds; -uint32_t kaif_fs; -uint32_t kaif_gs; -#endif - -uint_t kaif_msr_wrexit_msr; -uint64_t *kaif_msr_wrexit_valp; - -uintptr_t kaif_kernel_handler; -uintptr_t kaif_sys_sysenter; -uintptr_t kaif_brand_sys_sysenter; - int kaif_trap_switch; void (*kaif_modchg_cb)(struct modctl *, int); -#define KAIF_MEMRANGES_MAX 2 - -kaif_memrange_t kaif_memranges[KAIF_MEMRANGES_MAX]; -int kaif_nmemranges; - enum { M_SYSRET = 0x07, /* after M_ESC */ M_ESC = 0x0f, @@ -181,15 +166,25 @@ kaif_get_master_cpuid(void) return (kaif_master_cpuid); } -static const mdb_tgt_gregset_t * -kaif_get_gregs(int cpuid) +static mdb_tgt_gregset_t * +kaif_kdi_to_gregs(int cpuid) { kaif_cpusave_t *save; if ((save = kaif_cpuid2save(cpuid)) == NULL) return (NULL); /* errno is set for us */ - return (save->krs_gregs); + /* + * The saved registers are actually identical to an mdb_tgt_gregset, + * so we can directly cast here. + */ + return ((mdb_tgt_gregset_t *)save->krs_gregs); +} + +static const mdb_tgt_gregset_t * +kaif_get_gregs(int cpuid) +{ + return (kaif_kdi_to_gregs(cpuid)); } typedef struct kaif_reg_synonyms { @@ -212,11 +207,11 @@ kaif_find_regp(const char *regname) #endif { "tt", "trapno" } }; - - kaif_cpusave_t *save; + mdb_tgt_gregset_t *regs; int i; - save = kaif_cpuid2save(DPI_MASTER_CPUID); + if ((regs = kaif_kdi_to_gregs(DPI_MASTER_CPUID)) == NULL) + return (NULL); for (i = 0; i < sizeof (synonyms) / sizeof (synonyms[0]); i++) { if (strcmp(synonyms[i].rs_syn, regname) == 0) @@ -227,7 +222,7 @@ kaif_find_regp(const char *regname) const mdb_tgt_regdesc_t *rd = &mdb_isa_kregs[i]; if (strcmp(rd->rd_name, regname) == 0) - return (&save->krs_gregs->kregs[rd->rd_num]); + return (®s->kregs[rd->rd_num]); } (void) set_errno(ENOENT); @@ -361,7 +356,7 @@ kaif_wapt_reserve(kmdb_wapt_t *wp) { int id; - for (id = 0; id <= KREG_MAXWPIDX; id++) { + for (id = 0; id <= KDI_MAXWPIDX; id++) { if (!BT_TEST(&kaif_waptmap, id)) { /* found one */ BT_SET(&kaif_waptmap, id); @@ -405,6 +400,7 @@ kaif_wapt_arm(kmdb_wapt_t *wp) kaif_drreg.dr_ctl &= ~KREG_DRCTL_WP_MASK(hwid); kaif_drreg.dr_ctl |= KREG_DRCTL_WP_LENRW(hwid, wp->wp_size - 1, rw); kaif_drreg.dr_ctl |= KREG_DRCTL_WPEN(hwid); + kmdb_kdi_update_drreg(&kaif_drreg); } /*ARGSUSED*/ @@ -418,6 +414,7 @@ kaif_wapt_disarm(kmdb_wapt_t *wp) kaif_drreg.dr_addr[hwid] = 0; kaif_drreg.dr_ctl &= ~(KREG_DRCTL_WP_MASK(hwid) | KREG_DRCTL_WPEN_MASK(hwid)); + kmdb_kdi_update_drreg(&kaif_drreg); } /*ARGSUSED*/ @@ -523,7 +520,7 @@ kaif_step(void) case M_POPF: /* * popfl will restore a pushed EFLAGS from the stack, and could - * in so doing cause IF to be turned on, if only for a a brief + * in so doing cause IF to be turned on, if only for a brief * period. To avoid this, we'll secretly replace the stack's * EFLAGS with our decaffeinated brand. We'll then manually * load our EFLAGS copy with the real verion after the step. @@ -646,12 +643,12 @@ kaif_call(uintptr_t funcva, uint_t argc, const uintptr_t argv[]) } static void -dump_crumb(kaif_crumb_t *krmp) +dump_crumb(kdi_crumb_t *krmp) { - kaif_crumb_t krm; + kdi_crumb_t krm; - if (mdb_vread(&krm, sizeof (kaif_crumb_t), (uintptr_t)krmp) != - sizeof (kaif_crumb_t)) { + if (mdb_vread(&krm, sizeof (kdi_crumb_t), (uintptr_t)krmp) != + sizeof (kdi_crumb_t)) { warn("failed to read crumb at %p", krmp); return; } @@ -677,8 +674,8 @@ dump_crumbs(kaif_cpusave_t *save) { int i; - for (i = KAIF_NCRUMBS; i > 0; i--) { - uint_t idx = (save->krs_curcrumbidx + i) % KAIF_NCRUMBS; + for (i = KDI_NCRUMBS; i > 0; i--) { + uint_t idx = (save->krs_curcrumbidx + i) % KDI_NCRUMBS; dump_crumb(&save->krs_crumbs[idx]); } } @@ -690,7 +687,7 @@ kaif_dump_crumbs(uintptr_t addr, int cpuid) if (addr != NULL) { /* dump_crumb will protect us against bogus addresses */ - dump_crumb((kaif_crumb_t *)addr); + dump_crumb((kdi_crumb_t *)addr); } else if (cpuid != -1) { if (cpuid < 0 || cpuid >= kaif_ncpusave) @@ -727,101 +724,32 @@ kaif_modchg_cancel(void) kaif_modchg_cb = NULL; } -void -kaif_mod_loaded(struct modctl *modp) -{ - if (kaif_modchg_cb != NULL) - kaif_modchg_cb(modp, 1); -} - -void -kaif_mod_unloading(struct modctl *modp) -{ - if (kaif_modchg_cb != NULL) - kaif_modchg_cb(modp, 0); -} - -/* - * On some processors, we'll need to clear a certain MSR before proceeding into - * the debugger. Complicating matters, this MSR must be cleared before we take - * any branches. We have patch points in every trap handler, which will cover - * all entry paths for master CPUs. We also have a patch point in the slave - * entry code. - */ static void -kaif_msr_add_clrentry(uint_t msr) +kaif_msr_add(const kdi_msr_t *msrs) { -#ifdef __amd64 - uchar_t code[] = { - 0x51, 0x50, 0x52, /* pushq %rcx, %rax, %rdx */ - 0xb9, 0x00, 0x00, 0x00, 0x00, /* movl $MSRNUM, %ecx */ - 0x31, 0xc0, /* clr %eax */ - 0x31, 0xd2, /* clr %edx */ - 0x0f, 0x30, /* wrmsr */ - 0x5a, 0x58, 0x59 /* popq %rdx, %rax, %rcx */ - }; - uchar_t *patch = &code[4]; -#else - uchar_t code[] = { - 0x60, /* pushal */ - 0xb9, 0x00, 0x00, 0x00, 0x00, /* movl $MSRNUM, %ecx */ - 0x31, 0xc0, /* clr %eax */ - 0x31, 0xd2, /* clr %edx */ - 0x0f, 0x30, /* wrmsr */ - 0x61 /* popal */ - }; - uchar_t *patch = &code[2]; -#endif - - bcopy(&msr, patch, sizeof (uint32_t)); - - kaif_idt_patch((caddr_t)code, sizeof (code)); - - bcopy(code, &kaif_slave_entry_patch, sizeof (code)); -} - -static void -kaif_msr_add_wrexit(uint_t msr, uint64_t *valp) -{ - kaif_msr_wrexit_msr = msr; - kaif_msr_wrexit_valp = valp; -} - -static void -kaif_msr_add(const kmdb_msr_t *msrs) -{ - kmdb_msr_t *save; - int nmsrs, i; - - ASSERT(kaif_cpusave[0].krs_msr == NULL); + kdi_msr_t *save; + size_t nr_msrs = 0; + size_t i; - for (i = 0; msrs[i].msr_num != 0; i++) { - switch (msrs[i].msr_type) { - case KMDB_MSR_CLEARENTRY: - kaif_msr_add_clrentry(msrs[i].msr_num); - break; + while (msrs[nr_msrs].msr_num != 0) + nr_msrs++; + /* we want to copy the terminating kdi_msr_t too */ + nr_msrs++; - case KMDB_MSR_WRITEDELAY: - kaif_msr_add_wrexit(msrs[i].msr_num, msrs[i].msr_valp); - break; - } - } - nmsrs = i + 1; /* we want to copy the terminating kmdb_msr_t too */ - - save = mdb_zalloc(sizeof (kmdb_msr_t) * nmsrs * kaif_ncpusave, + save = mdb_zalloc(sizeof (kdi_msr_t) * nr_msrs * kaif_ncpusave, UM_SLEEP); - for (i = 0; i < kaif_ncpusave; i++) { - bcopy(msrs, &save[nmsrs * i], sizeof (kmdb_msr_t) * nmsrs); - kaif_cpusave[i].krs_msr = &save[nmsrs * i]; - } + for (i = 0; i < kaif_ncpusave; i++) + bcopy(msrs, &save[nr_msrs * i], sizeof (kdi_msr_t) * nr_msrs); + + kmdb_kdi_set_debug_msrs(save); } static uint64_t kaif_msr_get(int cpuid, uint_t num) { - kaif_cpusave_t *save; - kmdb_msr_t *msr; + kdi_cpusave_t *save; + kdi_msr_t *msr; int i; if ((save = kaif_cpuid2save(cpuid)) == NULL) @@ -830,109 +758,115 @@ kaif_msr_get(int cpuid, uint_t num) msr = save->krs_msr; for (i = 0; msr[i].msr_num != 0; i++) { - if (msr[i].msr_num == num && - (msr[i].msr_type & KMDB_MSR_READ)) - return (msr[i].msr_val); + if (msr[i].msr_num == num && (msr[i].msr_type & KDI_MSR_READ)) + return (msr[i].kdi_msr_val); } return (0); } -int -kaif_memrange_add(caddr_t base, size_t len) +void +kaif_trap_set_debugger(void) { - kaif_memrange_t *mr = &kaif_memranges[kaif_nmemranges]; + kmdb_kdi_idt_switch(NULL); +} - if (kaif_nmemranges == KAIF_MEMRANGES_MAX) - return (set_errno(ENOSPC)); +void +kaif_trap_set_saved(kaif_cpusave_t *cpusave) +{ + kmdb_kdi_idt_switch(cpusave); +} +static void +kaif_vmready(void) +{ +} + +void +kaif_memavail(caddr_t base, size_t len) +{ + int ret; /* * In the unlikely event that someone is stepping through this routine, - * we need to make sure that kaif_memranges knows about the new range - * before umem gets it. That way the entry code can recognize stacks + * we need to make sure that the KDI knows about the new range before + * umem gets it. That way the entry code can recognize stacks * allocated from the new region. */ - mr->mr_base = base; - mr->mr_lim = base + len - 1; - kaif_nmemranges++; + kmdb_kdi_memrange_add(base, len); + ret = mdb_umem_add(base, len); + ASSERT(ret == 0); +} - if (mdb_umem_add(base, len) < 0) { - kaif_nmemranges--; - return (-1); /* errno is set for us */ - } +void +kaif_mod_loaded(struct modctl *modp) +{ + if (kaif_modchg_cb != NULL) + kaif_modchg_cb(modp, 1); +} - return (0); +void +kaif_mod_unloading(struct modctl *modp) +{ + if (kaif_modchg_cb != NULL) + kaif_modchg_cb(modp, 0); } void -kaif_trap_set_debugger(void) +kaif_handle_fault(greg_t trapno, greg_t pc, greg_t sp, int cpuid) +{ + kmdb_dpi_handle_fault((kreg_t)trapno, (kreg_t)pc, + (kreg_t)sp, cpuid); +} + +static kdi_debugvec_t kaif_dvec = { + NULL, /* dv_kctl_vmready */ + NULL, /* dv_kctl_memavail */ + NULL, /* dv_kctl_modavail */ + NULL, /* dv_kctl_thravail */ + kaif_vmready, + kaif_memavail, + kaif_mod_loaded, + kaif_mod_unloading, + kaif_handle_fault +}; + +void +kaif_kdi_entry(kdi_cpusave_t *cpusave) { - set_idt(&kaif_idtr); + int ret = kaif_main_loop(cpusave); + ASSERT(ret == KAIF_CPU_CMD_RESUME || + ret == KAIF_CPU_CMD_RESUME_MASTER); } +/*ARGSUSED*/ void -kaif_trap_set_saved(kaif_cpusave_t *cpusave) +kaif_activate(kdi_debugvec_t **dvecp, uint_t flags) { - set_idt(&cpusave->krs_idtr); + kmdb_kdi_activate(kaif_kdi_entry, kaif_cpusave, kaif_ncpusave); + *dvecp = &kaif_dvec; } static int kaif_init(kmdb_auxv_t *kav) { - int i; - /* Allocate the per-CPU save areas */ kaif_cpusave = mdb_zalloc(sizeof (kaif_cpusave_t) * kav->kav_ncpu, UM_SLEEP); kaif_ncpusave = kav->kav_ncpu; - for (i = 0; i < kaif_ncpusave; i++) { - kaif_cpusave_t *save = &kaif_cpusave[i]; - - save->krs_cpu_id = i; - save->krs_curcrumbidx = KAIF_NCRUMBS - 1; - save->krs_curcrumb = &save->krs_crumbs[save->krs_curcrumbidx]; - } - - kaif_idt_init(); - - /* The initial selector set. Updated by the debugger-entry code */ -#ifndef __amd64 - kaif_cs = BOOTCODE_SEL; - kaif_ds = kaif_fs = kaif_gs = BOOTFLAT_SEL; -#endif - - kaif_memranges[0].mr_base = kav->kav_dseg; - kaif_memranges[0].mr_lim = kav->kav_dseg + kav->kav_dseg_size - 1; - kaif_nmemranges = 1; - kaif_modchg_cb = NULL; kaif_waptmap = 0; - kaif_drreg.dr_ctl = KREG_DRCTL_RESERVED; - kaif_drreg.dr_stat = KREG_DRSTAT_RESERVED; - - kaif_msr_wrexit_msr = 0; - kaif_msr_wrexit_valp = NULL; - kaif_trap_switch = (kav->kav_flags & KMDB_AUXV_FL_NOTRPSWTCH) == 0; - if ((kaif_sys_sysenter = kmdb_kdi_lookup_by_name("unix", - "sys_sysenter")) == NULL) - return (set_errno(ENOENT)); - - if ((kaif_brand_sys_sysenter = kmdb_kdi_lookup_by_name("unix", - "brand_sys_sysenter")) == NULL) - return (set_errno(ENOENT)); - return (0); } dpi_ops_t kmdb_dpi_ops = { kaif_init, kaif_activate, - kaif_deactivate, + kmdb_kdi_deactivate, kaif_enter_mon, kaif_modchg_register, kaif_modchg_cancel, @@ -953,7 +887,6 @@ dpi_ops_t kmdb_dpi_ops = { kaif_step_branch, kaif_call, kaif_dump_crumbs, - kaif_memrange_add, kaif_msr_add, kaif_msr_get, }; diff --git a/usr/src/cmd/mdb/intel/kmdb/kaif.h b/usr/src/cmd/mdb/intel/kmdb/kaif.h index c5392e7889..a7af3a6911 100644 --- a/usr/src/cmd/mdb/intel/kmdb/kaif.h +++ b/usr/src/cmd/mdb/intel/kmdb/kaif.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -32,84 +32,32 @@ #include <sys/kdi.h> #include <sys/types.h> #include <sys/segments.h> -#include <kmdb/kaif_regs.h> +#include <sys/kdi_machimpl.h> #endif #ifdef __cplusplus extern "C" { #endif -#define KAIF_MASTER_CPUID_UNSET -1 +typedef kdi_cpusave_t kaif_cpusave_t; -#define KAIF_CPU_CMD_RESUME 0 -#define KAIF_CPU_CMD_RESUME_MASTER 1 -#define KAIF_CPU_CMD_SWITCH 2 -#define KAIF_CPU_CMD_PASS_TO_KERNEL 3 -#define KAIF_CPU_CMD_REBOOT 4 - -#define KAIF_CPU_STATE_NONE 0 -#define KAIF_CPU_STATE_MASTER 1 -#define KAIF_CPU_STATE_SLAVE 2 +#define KAIF_CPU_STATE_NONE KDI_CPU_STATE_NONE +#define KAIF_CPU_STATE_MASTER KDI_CPU_STATE_MASTER +#define KAIF_CPU_STATE_SLAVE KDI_CPU_STATE_SLAVE #ifndef _ASM -typedef struct kaif_memrange { - caddr_t mr_base; - caddr_t mr_lim; -} kaif_memrange_t; - -extern kaif_memrange_t kaif_memranges[]; -extern int kaif_nmemranges; - -extern kaif_cpusave_t *kaif_cpusave; +extern kdi_cpusave_t *kaif_cpusave; extern int kaif_ncpusave; extern int kaif_master_cpuid; -extern uint32_t kaif_cs; -extern uint32_t kaif_ds; -extern uint32_t kaif_fs; -extern uint32_t kaif_gs; - -extern char kaif_slave_entry_patch; - -extern struct gate_desc kaif_idt[]; -extern desctbr_t kaif_idtr; -extern size_t kaif_ivct_size; extern int kaif_trap_switch; -extern uintptr_t kaif_kernel_handler; -extern uintptr_t kaif_sys_sysenter; -extern uintptr_t kaif_brand_sys_sysenter; - extern void kaif_trap_set_debugger(void); -extern void kaif_trap_set_saved(kaif_cpusave_t *); +extern void kaif_trap_set_saved(kdi_cpusave_t *); extern uintptr_t kaif_invoke(uintptr_t, uint_t, const uintptr_t[]); -extern void kaif_nmiint(void); -extern void kaif_cmnint(void); -extern void kaif_enter(void); -extern void kaif_slave_entry(void); -extern int kaif_debugger_entry(kaif_cpusave_t *); - -extern void kaif_mod_loaded(struct modctl *); -extern void kaif_mod_unloading(struct modctl *); - -extern void kaif_cpu_debug_init(kaif_cpusave_t *); - -extern void kaif_idt_init(void); -extern void kaif_idt_write(gate_desc_t *, uint_t); -extern void kaif_idt_patch(caddr_t, size_t); -extern uintptr_t kaif_kernel_trap2hdlr(int); - -extern void kaif_activate(kdi_debugvec_t **, uint_t); -extern void kaif_deactivate(void); - -extern int kaif_memrange_add(caddr_t, size_t); - -extern void get_idt(desctbr_t *); -extern void set_idt(desctbr_t *); - #endif #ifdef __cplusplus diff --git a/usr/src/cmd/mdb/intel/kmdb/kaif_activate.c b/usr/src/cmd/mdb/intel/kmdb/kaif_activate.c deleted file mode 100644 index 17294e5bb7..0000000000 --- a/usr/src/cmd/mdb/intel/kmdb/kaif_activate.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * The debugger/"PROM" interface layer - debugger activation - * - * Debugger activation has two flavors, which cover the cases where KMDB is - * loaded at boot, and when it is loaded after boot. In brief, in both cases, - * to interpose upon several handlers in the IDT. When mod-loaded KMDB is - * deactivated, we undo the IDT interposition, restoring the handlers to what - * they were before we started. - * - * Boot-loaded KMDB - * - * When we're first activated, we're running on boot's IDT. We need to be able - * to function in this world, so we'll install our handlers into boot's IDT. - * Later, when we're about to switch to the kernel's IDT, it'll call us, - * allowing us to add our handlers to the new IDT. While boot-loaded KMDB can't - * be unloaded, we still need to save the descriptors we replace so we can pass - * traps back to the kernel as necessary. - * - * The last phase of boot-loaded KMDB activation occurs at non-boot CPU startup. - * We will be called on each non-boot CPU, thus allowing us to set up any - * watchpoints that may have been configured on the boot CPU and interpose on - * the given CPU's IDT. We don't save the interposed descriptors in this - * case -- see kaif_cpu_init() for details. - * - * Mod-loaded KMDB - * - * This style of activation is much simpler, as the CPUs are already running, - * and are using their own copy of the kernel's IDT. We simply interpose upon - * each CPU's IDT. We save the handlers we replace, both for deactivation and - * for passing traps back to the kernel. - */ - -#include <kmdb/kmdb_asmutil.h> -#include <kmdb/kmdb_start.h> -#include <kmdb/kmdb_kdi.h> -#include <kmdb/kaif_asmutil.h> -#include <kmdb/kaif_regs.h> -#include <kmdb/kaif.h> - -#include <strings.h> -#include <sys/types.h> -#include <sys/segments.h> -#include <sys/trap.h> -#include <sys/cpuvar.h> -#include <sys/machcpuvar.h> -#include <sys/kdi_impl.h> - -#define KAIF_GATE_NVECS 3 - -#define KAIF_IDT_NOSAVE 0 -#define KAIF_IDT_SAVEOLD 1 - -#define KAIF_IDT_DTYPE_KERNEL 0 -#define KAIF_IDT_DTYPE_BOOT 1 - -typedef struct kaif_gate_spec { - uint_t kgs_vec; - uint_t kgs_dpl; -} kaif_gate_spec_t; - -static const kaif_gate_spec_t kaif_gate_specs[KAIF_GATE_NVECS] = { - { T_SGLSTP, SEL_KPL }, - { T_BPTFLT, SEL_UPL }, - { T_DBGENTR, SEL_KPL } -}; - -static gate_desc_t kaif_kgates[KAIF_GATE_NVECS]; - -static void -kaif_idt_gates_create(gate_desc_t *gates, int useboot) -{ - int i; - - for (i = 0; i < KAIF_GATE_NVECS; i++) { - const kaif_gate_spec_t *gs = &kaif_gate_specs[i]; - kmdb_kdi_idt_init_gate(&gates[i], - (void (*)())GATESEG_GETOFFSET(&kaif_idt[gs->kgs_vec]), - gs->kgs_dpl, useboot); - } -} - -static void -kaif_idt_gates_install(gate_desc_t *idt, gate_desc_t *gates, int saveold) -{ - int i; - - for (i = 0; i < KAIF_GATE_NVECS; i++) { - uint_t vec = kaif_gate_specs[i].kgs_vec; - - if (saveold) - kmdb_kdi_idt_read(idt, &kaif_kgates[i], vec); - - kmdb_kdi_idt_write(idt, &gates[i], vec); - } -} - -static void -kaif_idt_gates_install_by_cpu(cpu_t *cp, gate_desc_t *gates, int saveold) -{ - kaif_idt_gates_install(kmdb_kdi_cpu2idt(cp), gates, saveold); -} - -static void -kaif_idt_gates_restore(cpu_t *cp) -{ - gate_desc_t *idt = kmdb_kdi_cpu2idt(cp); - int i; - - for (i = 0; i < KAIF_GATE_NVECS; i++) { - kmdb_kdi_idt_write(idt, &kaif_kgates[i], - kaif_gate_specs[i].kgs_vec); - } -} - -/* - * Used by the code which passes traps back to the kernel to retrieve the - * address of the kernel's handler for a given trap. We get this address - * from the descriptor save area, which we populated when we loaded the - * debugger (mod-loaded) or initialized the kernel's IDT (boot-loaded). - */ -uintptr_t -kaif_kernel_trap2hdlr(int vec) -{ - int i; - - for (i = 0; i < KAIF_GATE_NVECS; i++) { - if (kaif_gate_specs[i].kgs_vec == vec) - return (GATESEG_GETOFFSET(&kaif_kgates[i])); - } - - return (NULL); -} - -/* - * We're still in single-CPU mode on CPU zero. Install our handlers in the - * current IDT. - */ -static void -kaif_boot_activate(void) -{ - gate_desc_t gates[KAIF_GATE_NVECS]; - - kaif_idt_gates_create(gates, KAIF_IDT_DTYPE_BOOT); - kaif_idt_gates_install(NULL, gates, KAIF_IDT_NOSAVE); -} - -/* Per-CPU debugger activation for boot-loaded and mod-loaded KMDB */ -/*ARGSUSED*/ -static void -kaif_cpu_activate(cpu_t *cp, uint_t saveold) -{ - gate_desc_t gates[KAIF_GATE_NVECS]; - - kaif_idt_gates_create(gates, KAIF_IDT_DTYPE_KERNEL); - kaif_idt_gates_install_by_cpu(cp, gates, saveold); -} - -/* Per-CPU debugger de-activation for mod-loaded KMDB */ -/*ARGSUSED*/ -static void -kaif_cpu_deactivate(cpu_t *cp, uint_t arg) -{ - kaif_idt_gates_restore(cp); -} - -/* - * Called on each non-boot CPU during CPU initialization. We saved the kernel's - * descriptors when we initialized the boot CPU, so we don't want to do it - * again. Saving the handlers from this CPU's IDT would actually be dangerous - * with the CPU initialization method in use at the time of this writing. With - * that method, the startup code creates the IDTs for slave CPUs by copying - * the one used by the boot CPU, which has already been interposed upon by - * KMDB. Were we to interpose again, we'd replace the kernel's descriptors - * with our own in the save area. By not saving, but still overwriting, we'll - * work in the current world, and in any future world where the IDT is generated - * from scratch. - */ -/*ARGSUSED*/ -static void -kaif_cpu_init(cpu_t *cp) -{ - kaif_cpu_activate(cp, KAIF_IDT_NOSAVE); - - /* Load the debug registers and MSRs */ - kaif_cpu_debug_init(&kaif_cpusave[cp->cpu_id]); -} - -/* - * Called very early in _start, just before we switch to the kernel's IDT. We - * need to interpose on the kernel's IDT entries and we need to update our copy - * of the #df handler. - */ -static void -kaif_idt_sync(gate_desc_t *idt) -{ - gate_desc_t gates[KAIF_GATE_NVECS]; - gate_desc_t kdfgate; - - kaif_idt_gates_create(gates, KAIF_IDT_DTYPE_KERNEL); - kaif_idt_gates_install(idt, gates, KAIF_IDT_SAVEOLD); - - kmdb_kdi_idt_read(idt, &kdfgate, T_DBLFLT); - kaif_idt_write(&kdfgate, T_DBLFLT); -} - -static void -kaif_vmready(void) -{ -} - -static kdi_debugvec_t kaif_dvec = { - kaif_enter, - kaif_cpu_init, - NULL, /* dv_kctl_cpu_init */ - kaif_idt_sync, - kaif_vmready, - NULL, /* dv_kctl_vmready */ - NULL, /* dv_kctl_memavail */ - kaif_memrange_add, - NULL, /* dv_kctl_modavail */ - NULL, /* dv_kctl_thravail */ - kaif_mod_loaded, - kaif_mod_unloading -}; - -void -kaif_activate(kdi_debugvec_t **dvecp, uint_t flags) -{ - gate_desc_t kdfgate; - - /* Copy the kernel's #df handler to our IDT */ - kmdb_kdi_idt_read(NULL, &kdfgate, T_DBLFLT); - kaif_idt_write(&kdfgate, T_DBLFLT); - - if (flags & KMDB_ACT_F_BOOT) - kaif_boot_activate(); - else - kmdb_kdi_cpu_iter(kaif_cpu_activate, KAIF_IDT_SAVEOLD); - - *dvecp = &kaif_dvec; -} - -void -kaif_deactivate(void) -{ - kmdb_kdi_cpu_iter(kaif_cpu_deactivate, 0); -} diff --git a/usr/src/cmd/mdb/intel/kmdb/kaif_idt.c b/usr/src/cmd/mdb/intel/kmdb/kaif_idt.c deleted file mode 100644 index 43e218e1a6..0000000000 --- a/usr/src/cmd/mdb/intel/kmdb/kaif_idt.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * kmdb's IDT - */ - -#include <sys/types.h> -#include <sys/segments.h> -#include <sys/trap.h> -#include <strings.h> - -#include <kmdb/kaif.h> -#include <mdb/mdb_debug.h> -#include <kmdb/kaif_asmutil.h> - -#if defined(__amd64) -#define KMDBCODE_SEL B64CODE_SEL -#else -#define KMDBCODE_SEL BOOTCODE_SEL -#endif - -typedef void idt_hdlr_f(void); - -extern idt_hdlr_f kaif_trap0, kaif_trap1, kaif_int2, kaif_trap3, kaif_trap4; -extern idt_hdlr_f kaif_trap5, kaif_trap6, kaif_trap7, kaif_traperr8, kaif_trap9; -extern idt_hdlr_f kaif_traperr10, kaif_traperr11, kaif_traperr12; -extern idt_hdlr_f kaif_traperr13, kaif_traperr14, kaif_trap16, kaif_trap17; -extern idt_hdlr_f kaif_trap18, kaif_trap19, kaif_trap20, kaif_ivct32; -extern idt_hdlr_f kaif_invaltrap; - -gate_desc_t kaif_idt[NIDT]; -desctbr_t kaif_idtr; - -struct idt_description { - uint_t id_low; - uint_t id_high; - idt_hdlr_f *id_basehdlr; - size_t *id_incrp; - uint_t id_type; -} idt_description[] = { - { T_ZERODIV, 0, kaif_trap0, NULL, SDT_SYSIGT }, - { T_SGLSTP, 0, kaif_trap1, NULL, SDT_SYSIGT }, - { T_NMIFLT, 0, kaif_int2, NULL, SDT_SYSIGT }, - { T_BPTFLT, 0, kaif_trap3, NULL, SDT_SYSIGT }, - { T_OVFLW, 0, kaif_trap4, NULL, SDT_SYSIGT }, - { T_BOUNDFLT, 0, kaif_trap5, NULL, SDT_SYSIGT }, - { T_ILLINST, 0, kaif_trap6, NULL, SDT_SYSIGT }, - { T_NOEXTFLT, 0, kaif_trap7, NULL, SDT_SYSIGT }, - { T_DBLFLT, 0, kaif_traperr8, NULL, SDT_SYSIGT }, - { T_EXTOVRFLT, 0, kaif_trap9, NULL, SDT_SYSIGT }, - { T_TSSFLT, 0, kaif_traperr10, NULL, SDT_SYSIGT }, - { T_SEGFLT, 0, kaif_traperr11, NULL, SDT_SYSIGT }, - { T_STKFLT, 0, kaif_traperr12, NULL, SDT_SYSIGT }, - { T_GPFLT, 0, kaif_traperr13, NULL, SDT_SYSIGT }, - { T_PGFLT, 0, kaif_traperr14, NULL, SDT_SYSIGT }, - { 15, 0, kaif_invaltrap, NULL, SDT_SYSIGT }, - { T_EXTERRFLT, 0, kaif_trap16, NULL, SDT_SYSIGT }, - { T_ALIGNMENT, 0, kaif_trap17, NULL, SDT_SYSIGT }, - { T_MCE, 0, kaif_trap18, NULL, SDT_SYSIGT }, - { T_SIMDFPE, 0, kaif_trap19, NULL, SDT_SYSIGT }, - { T_DBGENTR, 0, kaif_trap20, NULL, SDT_SYSIGT }, - { 21, 31, kaif_invaltrap, NULL, SDT_SYSIGT }, - { 32, 255, kaif_ivct32, &kaif_ivct_size, SDT_SYSIGT }, - { 0, 0, NULL }, -}; - -static void -kaif_set_gatesegd(gate_desc_t *dp, void (*func)(void), selector_t sel, - uint_t type) -{ - bzero(dp, sizeof (gate_desc_t)); - - dp->sgd_looffset = ((uintptr_t)func) & 0xffff; - dp->sgd_hioffset = ((uintptr_t)func >> 16) & 0xffff; -#ifdef __amd64 - dp->sgd_hi64offset = (uintptr_t)func >> 32; -#endif - - dp->sgd_selector = (uint16_t)sel; - dp->sgd_type = type; - dp->sgd_dpl = SEL_KPL; - dp->sgd_p = 1; - -#ifdef __amd64 - dp->sgd_ist = 0; -#else - dp->sgd_stkcpy = 0; -#endif -} - -void -kaif_idt_init(void) -{ - struct idt_description *id; - int i; - - for (id = idt_description; id->id_basehdlr != NULL; id++) { - uint_t high = id->id_high != 0 ? id->id_high : id->id_low; - size_t incr = id->id_incrp != NULL ? *id->id_incrp : 0; - - for (i = id->id_low; i <= high; i++) { - caddr_t hdlr = (caddr_t)id->id_basehdlr + - incr * (i - id->id_low); - kaif_set_gatesegd(&kaif_idt[i], (void (*)(void))hdlr, - KMDBCODE_SEL, id->id_type); - } - } - - kaif_idtr.dtr_limit = sizeof (kaif_idt) - 1; - kaif_idtr.dtr_base = (uint64_t)kaif_idt; -} - -/* - * Patch caller-provided code into the debugger's IDT handlers. This code is - * used to save MSRs that must be saved before the first branch. All handlers - * are essentially the same, and end with a branch to kaif_cmnint. To save the - * MSR, we need to patch in before the branch. The handlers have the following - * structure: KAIF_MSR_PATCHOFF bytes of code, KAIF_MSR_PATCHSZ bytes of - * patchable space, followed by more code. - */ -void -kaif_idt_patch(caddr_t code, size_t sz) -{ - int i; - - ASSERT(sz <= KAIF_MSR_PATCHSZ); - - for (i = 0; i < sizeof (kaif_idt) / sizeof (struct gate_desc); i++) { - gate_desc_t *gd; - uchar_t *patch; - - if (i == T_DBLFLT) - continue; /* uses kernel's handler */ - - gd = &kaif_idt[i]; - patch = (uchar_t *)GATESEG_GETOFFSET(gd) + KAIF_MSR_PATCHOFF; - - /* - * We can't ASSERT that there's a nop here, because this may be - * a debugger restart. In that case, we're copying the new - * patch point over the old one. - */ - bcopy(code, patch, sz); - - /* Fill the rest with nops to be sure */ - while (sz < KAIF_MSR_PATCHSZ) - patch[sz++] = 0x90; /* nop */ - } -} - -void -kaif_idt_write(gate_desc_t *gate, uint_t vec) -{ - kaif_idt[vec] = *gate; -} diff --git a/usr/src/cmd/mdb/intel/kmdb/kaif_idthdl.s b/usr/src/cmd/mdb/intel/kmdb/kaif_idthdl.s deleted file mode 100644 index 45fdba6c78..0000000000 --- a/usr/src/cmd/mdb/intel/kmdb/kaif_idthdl.s +++ /dev/null @@ -1,226 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Companion to kaif_idt.c - the implementation of the trap and interrupt - * handlers. For the most part, these handlers do the same thing - they - * push a trap number onto the stack, followed by a jump to kaif_cmnint. - * Each trap and interrupt has its own handler because each one pushes a - * different number. - */ - -#include <sys/asm_linkage.h> -#include <kmdb/kaif_asmutil.h> - -/* Nothing in this file is of interest to lint. */ -#if !defined(__lint) - -/* - * The default ASM_ENTRY_ALIGN (16) wastes far too much space. Pay no - * attention to the fleet of nop's we're adding to each handler. - */ -#undef ASM_ENTRY_ALIGN -#define ASM_ENTRY_ALIGN 8 - -/* - * We need the .align in ENTRY_NP (defined to be ASM_ENTRY_ALIGN) to match our - * manual .align (KAIF_MSR_PATCHOFF) in order to ensure that the space reserved - * at the beginning of the handler for code is exactly KAIF_MSR_PATCHOFF bytes - * long. Note that the #error below isn't supported by the preprocessor invoked - * by as(1), and won't stop the build, but it'll emit a noticeable error message - * which won't escape the filters. - */ -#if ASM_ENTRY_ALIGN != KAIF_MSR_PATCHOFF -#error "ASM_ENTRY_ALIGN != KAIF_MSR_PATCHOFF" -this won't assemble -#endif - -/* - * kaif_idt_patch will, on certain processors, replace the patch points below - * with MSR-clearing code. kaif_id_patch has intimate knowledge of the size of - * the nop hole, as well as the structure of the handlers. Do not change - * anything here without also changing kaif_idt_patch. - */ - -/* - * Generic trap and interrupt handlers. - */ - -#if defined(__amd64) - -#define TRAP_NOERR(trapno) \ - pushq $trapno - -#define TRAP_ERR(trapno) \ - pushq $0; \ - pushq $trapno - -#else /* __i386 */ - -#define TRAP_NOERR(trapno) \ - pushl $trapno - -#define TRAP_ERR(trapno) \ - pushl $0; \ - pushl $trapno - -#endif - - -#define MKIVCT(n) \ - ENTRY_NP(kaif_ivct/**/n/**/); \ - TRAP_ERR(n); \ - .align KAIF_MSR_PATCHOFF; \ - KAIF_MSR_PATCH; \ - jmp kaif_cmnint; \ - SET_SIZE(kaif_ivct/**/n/**/) - -#define MKTRAPHDLR(n) \ - ENTRY_NP(kaif_trap/**/n); \ - TRAP_ERR(n); \ - .align KAIF_MSR_PATCHOFF; \ - KAIF_MSR_PATCH; \ - jmp kaif_cmnint; \ - SET_SIZE(kaif_trap/**/n/**/) - -#define MKTRAPERRHDLR(n) \ - ENTRY_NP(kaif_traperr/**/n); \ - TRAP_NOERR(n); \ - .align KAIF_MSR_PATCHOFF; \ - KAIF_MSR_PATCH; \ - jmp kaif_cmnint; \ - SET_SIZE(kaif_traperr/**/n) - -#define MKNMIHDLR \ - ENTRY_NP(kaif_int2); \ - TRAP_NOERR(2); \ - .align KAIF_MSR_PATCHOFF; \ - KAIF_MSR_PATCH; \ - jmp kaif_nmiint; \ - SET_SIZE(kaif_int2) - -#define MKINVALHDLR \ - ENTRY_NP(kaif_invaltrap); \ - TRAP_NOERR(255); \ - .align KAIF_MSR_PATCHOFF; \ - KAIF_MSR_PATCH; \ - jmp kaif_cmnint; \ - SET_SIZE(kaif_invaltrap) - -/* - * The handlers themselves - */ - - MKINVALHDLR - MKTRAPHDLR(0) - MKTRAPHDLR(1) - MKNMIHDLR/*2*/ - MKTRAPHDLR(3) - MKTRAPHDLR(4) - MKTRAPHDLR(5) - MKTRAPHDLR(6) - MKTRAPHDLR(7) - MKTRAPHDLR(9) - MKTRAPHDLR(15) - MKTRAPHDLR(16) - MKTRAPHDLR(17) - MKTRAPHDLR(18) - MKTRAPHDLR(19) - MKTRAPHDLR(20) - - MKTRAPERRHDLR(8) - MKTRAPERRHDLR(10) - MKTRAPERRHDLR(11) - MKTRAPERRHDLR(12) - MKTRAPERRHDLR(13) - MKTRAPERRHDLR(14) - - .globl kaif_ivct_size -kaif_ivct_size: - .NWORD [kaif_ivct33-kaif_ivct32] - - /* 10 billion and one interrupt handlers */ -kaif_ivct_base: - MKIVCT(32); MKIVCT(33); MKIVCT(34); MKIVCT(35); - MKIVCT(36); MKIVCT(37); MKIVCT(38); MKIVCT(39); - MKIVCT(40); MKIVCT(41); MKIVCT(42); MKIVCT(43); - MKIVCT(44); MKIVCT(45); MKIVCT(46); MKIVCT(47); - MKIVCT(48); MKIVCT(49); MKIVCT(50); MKIVCT(51); - MKIVCT(52); MKIVCT(53); MKIVCT(54); MKIVCT(55); - MKIVCT(56); MKIVCT(57); MKIVCT(58); MKIVCT(59); - MKIVCT(60); MKIVCT(61); MKIVCT(62); MKIVCT(63); - MKIVCT(64); MKIVCT(65); MKIVCT(66); MKIVCT(67); - MKIVCT(68); MKIVCT(69); MKIVCT(70); MKIVCT(71); - MKIVCT(72); MKIVCT(73); MKIVCT(74); MKIVCT(75); - MKIVCT(76); MKIVCT(77); MKIVCT(78); MKIVCT(79); - MKIVCT(80); MKIVCT(81); MKIVCT(82); MKIVCT(83); - MKIVCT(84); MKIVCT(85); MKIVCT(86); MKIVCT(87); - MKIVCT(88); MKIVCT(89); MKIVCT(90); MKIVCT(91); - MKIVCT(92); MKIVCT(93); MKIVCT(94); MKIVCT(95); - MKIVCT(96); MKIVCT(97); MKIVCT(98); MKIVCT(99); - MKIVCT(100); MKIVCT(101); MKIVCT(102); MKIVCT(103); - MKIVCT(104); MKIVCT(105); MKIVCT(106); MKIVCT(107); - MKIVCT(108); MKIVCT(109); MKIVCT(110); MKIVCT(111); - MKIVCT(112); MKIVCT(113); MKIVCT(114); MKIVCT(115); - MKIVCT(116); MKIVCT(117); MKIVCT(118); MKIVCT(119); - MKIVCT(120); MKIVCT(121); MKIVCT(122); MKIVCT(123); - MKIVCT(124); MKIVCT(125); MKIVCT(126); MKIVCT(127); - MKIVCT(128); MKIVCT(129); MKIVCT(130); MKIVCT(131); - MKIVCT(132); MKIVCT(133); MKIVCT(134); MKIVCT(135); - MKIVCT(136); MKIVCT(137); MKIVCT(138); MKIVCT(139); - MKIVCT(140); MKIVCT(141); MKIVCT(142); MKIVCT(143); - MKIVCT(144); MKIVCT(145); MKIVCT(146); MKIVCT(147); - MKIVCT(148); MKIVCT(149); MKIVCT(150); MKIVCT(151); - MKIVCT(152); MKIVCT(153); MKIVCT(154); MKIVCT(155); - MKIVCT(156); MKIVCT(157); MKIVCT(158); MKIVCT(159); - MKIVCT(160); MKIVCT(161); MKIVCT(162); MKIVCT(163); - MKIVCT(164); MKIVCT(165); MKIVCT(166); MKIVCT(167); - MKIVCT(168); MKIVCT(169); MKIVCT(170); MKIVCT(171); - MKIVCT(172); MKIVCT(173); MKIVCT(174); MKIVCT(175); - MKIVCT(176); MKIVCT(177); MKIVCT(178); MKIVCT(179); - MKIVCT(180); MKIVCT(181); MKIVCT(182); MKIVCT(183); - MKIVCT(184); MKIVCT(185); MKIVCT(186); MKIVCT(187); - MKIVCT(188); MKIVCT(189); MKIVCT(190); MKIVCT(191); - MKIVCT(192); MKIVCT(193); MKIVCT(194); MKIVCT(195); - MKIVCT(196); MKIVCT(197); MKIVCT(198); MKIVCT(199); - MKIVCT(200); MKIVCT(201); MKIVCT(202); MKIVCT(203); - MKIVCT(204); MKIVCT(205); MKIVCT(206); MKIVCT(207); - MKIVCT(208); MKIVCT(209); MKIVCT(210); MKIVCT(211); - MKIVCT(212); MKIVCT(213); MKIVCT(214); MKIVCT(215); - MKIVCT(216); MKIVCT(217); MKIVCT(218); MKIVCT(219); - MKIVCT(220); MKIVCT(221); MKIVCT(222); MKIVCT(223); - MKIVCT(224); MKIVCT(225); MKIVCT(226); MKIVCT(227); - MKIVCT(228); MKIVCT(229); MKIVCT(230); MKIVCT(231); - MKIVCT(232); MKIVCT(233); MKIVCT(234); MKIVCT(235); - MKIVCT(236); MKIVCT(237); MKIVCT(238); MKIVCT(239); - MKIVCT(240); MKIVCT(241); MKIVCT(242); MKIVCT(243); - MKIVCT(244); MKIVCT(245); MKIVCT(246); MKIVCT(247); - MKIVCT(248); MKIVCT(249); MKIVCT(250); MKIVCT(251); - MKIVCT(252); MKIVCT(253); MKIVCT(254); MKIVCT(255); - -#endif diff --git a/usr/src/cmd/mdb/intel/kmdb/kaif_off.in b/usr/src/cmd/mdb/intel/kmdb/kaif_off.in deleted file mode 100644 index ed1a65605b..0000000000 --- a/usr/src/cmd/mdb/intel/kmdb/kaif_off.in +++ /dev/null @@ -1,99 +0,0 @@ -\ -\ Copyright 2005 Sun Microsystems, Inc. All rights reserved. -\ Use is subject to license terms. -\ -\ CDDL HEADER START -\ -\ The contents of this file are subject to the terms of the -\ Common Development and Distribution License, Version 1.0 only -\ (the "License"). You may not use this file except in compliance -\ with the License. -\ -\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -\ or http://www.opensolaris.org/os/licensing. -\ See the License for the specific language governing permissions -\ and limitations under the License. -\ -\ When distributing Covered Code, include this CDDL HEADER in each -\ file and include the License file at usr/src/OPENSOLARIS.LICENSE. -\ If applicable, add the following below this CDDL HEADER, with the -\ fields enclosed by brackets "[]" replaced with your own identifying -\ information: Portions Copyright [yyyy] [name of copyright owner] -\ -\ CDDL HEADER END -\ -\ ident "%Z%%M% %I% %E% SMI" -\ -\ CPU-save structure offsets for use in assembly code. -\ -\ Keep in sync with kaif_regs.h -\ - -#include <sys/cpuvar.h> -#include <sys/kdi_impl.h> - -#include <kmdb/kaif.h> -#include <kmdb/kaif_regs.h> -#include <mdb/mdb.h> - -kaif_memrange_t MR_SIZE - mr_base - mr_lim - -kaif_crumb_t KRM_SIZE - krm_cpu_state - krm_pc - krm_sp - krm_trapno - krm_flag - -kaif_drreg_t - dr_ctl - dr_stat - dr_addr - -kmdb_msr_t MSR_SIZE - msr_num - msr_type - _u._msr_valp MSR_VALP - _u._msr_val MSR_VAL - -kaif_cpusave_t KRS_SIZE - krs_gregs - krs_dr - krs_dr.dr_ctl KRS_DRCTL - krs_dr.dr_stat KRS_DRSTAT - krs_gdtr - krs_idtr - krs_tmpdesc - krs_cr0 - krs_msr - krs_cpu_state - krs_curcrumbidx - krs_curcrumb - krs_crumbs - -cpu - cpu_id - -#if defined(__amd64) -mdb_t - m_kdi MDB_KDI - -kdi_t - kdi_mach.mkdi_gdt2gsbase MKDI_GDT2GSBASE -#endif - -kreg_t KREG_SIZE - -#if defined(__amd64) -\#define REG_SHIFT 3 -#else -\#define REG_SHIFT 2 -#endif - -\#define DRADDR_IDX(num) _CONST(_MUL(num, DR_ADDR_INCR)) -\#define DRADDR_OFF(num) _CONST(DRADDR_IDX(num) + DR_ADDR) -\#define KRS_DROFF(num) _CONST(DRADDR_OFF(num) + KRS_DR) -\#define REG_OFF(reg) _CONST(_CONST(reg) << REG_SHIFT) -\#define KREG_OFF(reg) _CONST(_MUL(KREG_SIZE, reg) + KRS_GREGS) diff --git a/usr/src/cmd/mdb/intel/kmdb/kaif_regs.h b/usr/src/cmd/mdb/intel/kmdb/kaif_regs.h deleted file mode 100644 index 9d5b64a240..0000000000 --- a/usr/src/cmd/mdb/intel/kmdb/kaif_regs.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _KAIF_REGS_H -#define _KAIF_REGS_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifndef _ASM -#include <sys/types.h> -#include <sys/segments.h> - -#include <mdb/mdb_kreg_impl.h> -#include <mdb/mdb_target.h> -#include <kmdb/kmdb_dpi.h> -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#define KAIF_NCRUMBS 5 - -#ifndef _ASM - -/* - * We maintain a ring buffer of bread crumbs for debugging purposes. The - * current buffer pointer is advanced along the ring with each intercepted - * trap (debugger entry, invalid memory access, fault during step, etc). - * The macros used to populate the crumb buffers assume that all members are - * 32 bits wide. - */ -typedef struct kaif_crumb { - kreg_t krm_cpu_state; /* This CPU's state at last entry */ - kreg_t krm_pc; /* Instruction pointer at trap */ - kreg_t krm_sp; /* Stack pointer at trap */ - kreg_t krm_trapno; /* The last trap number */ - kreg_t krm_flag; /* KAIF_CRUMB_F_* */ -} kaif_crumb_t; - -/* - * Storage for %dr0-3, %dr6, and %dr7. - */ -typedef struct kaif_drreg { - kreg_t dr_ctl; - kreg_t dr_stat; - kreg_t dr_addr[KREG_MAXWPIDX + 1]; -} kaif_drreg_t; - -/* - * Data structure used to hold all of the state for a given CPU. - */ -typedef struct kaif_cpusave { - mdb_tgt_gregset_t *krs_gregs; /* saved registers */ - - kaif_drreg_t krs_dr; /* saved debug registers */ - - desctbr_t krs_gdtr; /* saved GDT register */ - desctbr_t krs_idtr; /* saved IDT register */ - desctbr_t krs_tmpdesc; /* pre-save *DT comparisons */ - - kreg_t krs_cr0; /* saved %cr0 */ - - kmdb_msr_t *krs_msr; /* ptr to MSR save area */ - - uint_t krs_cpu_state; /* KAIF_CPU_STATE_* mstr/slv */ - uint_t krs_cpu_flushed; /* Have caches been flushed? */ - uint_t krs_cpu_id; /* this CPU's ID */ - - /* Bread crumb ring buffer */ - ulong_t krs_curcrumbidx; /* Current krs_crumbs idx */ - kaif_crumb_t *krs_curcrumb; /* Pointer to current crumb */ - kaif_crumb_t krs_crumbs[KAIF_NCRUMBS]; /* Crumbs */ -} kaif_cpusave_t; - -#endif /* !_ASM */ - -#ifdef __cplusplus -} -#endif - -#endif /* _KAIF_REGS_H */ diff --git a/usr/src/cmd/mdb/intel/kmdb/kaif_start_isadep.c b/usr/src/cmd/mdb/intel/kmdb/kaif_start_isadep.c deleted file mode 100644 index 708cbb390c..0000000000 --- a/usr/src/cmd/mdb/intel/kmdb/kaif_start_isadep.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * The Intel-specific interface to the main CPU-control loops - */ - -#include <sys/types.h> -#include <sys/trap.h> -#include <sys/segments.h> -#include <ia32/sys/psw.h> - -#include <kmdb/kaif.h> -#include <kmdb/kaif_regs.h> -#include <kmdb/kaif_start.h> -#include <kmdb/kmdb_dpi_impl.h> -#include <kmdb/kmdb_kdi.h> -#include <mdb/mdb.h> - -/* - * We receive all breakpoints and single step traps. Some of them, - * including those from userland and those induced by DTrace providers, - * are intended for the kernel, and must be processed there. We adopt - * this ours-until-proven-otherwise position due to the painful - * consequences of sending the kernel an unexpected breakpoint or - * single step. Unless someone can prove to us that the kernel is - * prepared to handle the trap, we'll assume there's a problem and will - * give the user a chance to debug it. - */ -static int -kaif_trap_pass(kaif_cpusave_t *cpusave) -{ - kreg_t tt = cpusave->krs_gregs->kregs[KREG_TRAPNO]; - kreg_t pc = cpusave->krs_gregs->kregs[KREG_PC]; - kreg_t cs = cpusave->krs_gregs->kregs[KREG_CS]; - - if (tt != T_BPTFLT && tt != T_SGLSTP) - return (0); - - if (USERMODE(cs)) - return (1); - - if (tt == T_BPTFLT && kmdb_kdi_dtrace_get_state() == - KDI_DTSTATE_DTRACE_ACTIVE) - return (1); - - /* - * See the comments in the kernel's T_SGLSTP handler for why we need to - * do this. - */ - if (tt == T_SGLSTP && - (pc == kaif_sys_sysenter || pc == kaif_brand_sys_sysenter)) - return (1); - - return (0); -} - -/* - * State has been saved, and all CPUs are on the CPU-specific stacks. All - * CPUs enter here, and head off to the slave spin loop or into the debugger - * as appropriate. This routine also handles the various flavors of resume. - * - * Returns 1 for the master CPU if there's work to be done by the driver, 0 - * otherwise. - */ -int -kaif_debugger_entry(kaif_cpusave_t *cpusave) -{ - if (kaif_trap_pass(cpusave)) { - cpusave->krs_cpu_state = KAIF_CPU_STATE_NONE; - return (KAIF_CPU_CMD_PASS_TO_KERNEL); - } - - /* - * BPTFLT gives us control with %eip set to the instruction *after* - * the int 3. Back it off, so we're looking at the instruction that - * triggered the fault. - */ - if (cpusave->krs_gregs->kregs[KREG_TRAPNO] == T_BPTFLT) - cpusave->krs_gregs->kregs[KREG_PC]--; - - return (kaif_main_loop(cpusave)); -} diff --git a/usr/src/cmd/mdb/intel/kmdb/kctl/kctl_isadep.c b/usr/src/cmd/mdb/intel/kmdb/kctl/kctl_isadep.c index 542b5b69e1..44b2248755 100644 --- a/usr/src/cmd/mdb/intel/kmdb/kctl/kctl_isadep.c +++ b/usr/src/cmd/mdb/intel/kmdb/kctl/kctl_isadep.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -38,16 +38,11 @@ #include <sys/controlregs.h> #include <sys/archsystm.h> -#if defined(__i386) -/* Copied from stand/i386/sys/bootdef.h */ -#define GS_GDT 0x38 /* dummy cpu_t pointer descriptor */ -#endif - static int kctl_boot_prop_read(char *pname, char *prop_buf, int buf_len) { - int len; struct bootops *ops = kctl.kctl_boot_ops; + int len; len = BOP_GETPROPLEN(ops, pname); if (len > 0 && len <= buf_len) { @@ -144,12 +139,6 @@ kctl_pcache_destroy(kmdb_auxv_nv_t *pnv) kobj_free(pnv, sizeof (kmdb_auxv_nv_t) * KCTL_PROPNV_NENT); } -/*ARGSUSED*/ -static void -kctl_cpu_init(void) -{ -} - void kctl_auxv_init_isadep(kmdb_auxv_t *kav, void *romp) { @@ -171,16 +160,13 @@ kctl_preactivate_isadep(void) } /*ARGSUSED*/ -int +void kctl_activate_isadep(kdi_debugvec_t *dvec) { - dvec->dv_kctl_cpu_init = kctl_cpu_init; dvec->dv_kctl_vmready = hat_kdi_init; if (!kctl.kctl_boot_loaded) hat_kdi_init(); - - return (0); } void @@ -188,64 +174,20 @@ kctl_depreactivate_isadep(void) { } -void -kctl_deactivate_isadep(void) -{ - hat_kdi_fini(); -} - -#if defined(__amd64) -void * -kctl_boot_tmpinit(void) -{ - /* - * Many common kernel functions assume that GSBASE has been initialized, - * and fail horribly if it hasn't. We'll install a pointer to a dummy - * cpu_t for use during our initialization. - */ - cpu_t *old = (cpu_t *)rdmsr(MSR_AMD_GSBASE); - - wrmsr(MSR_AMD_GSBASE, (uint64_t)kobj_zalloc(sizeof (cpu_t), KM_TMP)); - return (old); -} - -void -kctl_boot_tmpfini(void *old) -{ - wrmsr(MSR_AMD_GSBASE, (uint64_t)old); -} - -#else - +/* + * Many common kernel functions assume that %gs can be deferenced, and + * fail horribly if it cannot. Ask the kernel to set up a temporary + * mapping to a fake cpu_t so that we can call such functions during + * initialization. + */ void * kctl_boot_tmpinit(void) { - /* - * Many common kernel functions assume that %gs has been initialized, - * and fail horribly if it hasn't. Boot has reserved a descriptor for - * us (GS_GDT) in its GDT, a descriptor which we'll use to describe our - * dummy cpu_t. We then set %gs to refer to this descriptor. - */ - cpu_t *cpu = kobj_zalloc(sizeof (cpu_t), KM_TMP); - uintptr_t old; - desctbr_t bgdt; - user_desc_t *gsdesc; - - rd_gdtr(&bgdt); - gsdesc = (user_desc_t *)(bgdt.dtr_base + GS_GDT); - - USEGD_SETBASE(gsdesc, (uintptr_t)cpu); - USEGD_SETLIMIT(gsdesc, sizeof (cpu_t)); - - old = getgs(); - setgs(GS_GDT); - - return ((void *)old); + return (boot_kdi_tmpinit()); } void kctl_boot_tmpfini(void *old) { - setgs((uintptr_t)old); + boot_kdi_tmpfini(old); } -#endif diff --git a/usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.c b/usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.c index f5b7a3a679..719e36b8dc 100644 --- a/usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.c +++ b/usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -145,7 +144,7 @@ kmdb_dpi_reboot(void) } void -kmdb_dpi_msr_add(const kmdb_msr_t *msrs) +kmdb_dpi_msr_add(const kdi_msr_t *msrs) { mdb.m_dpi->dpo_msr_add(msrs); } diff --git a/usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.h b/usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.h index 952960060f..2565c1f843 100644 --- a/usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.h +++ b/usr/src/cmd/mdb/intel/kmdb/kmdb_dpi_isadep.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -31,36 +30,20 @@ #ifndef _ASM #include <mdb/mdb_isautil.h> +#include <sys/kdi_machimpl.h> #endif #ifdef __cplusplus extern "C" { #endif -#define KMDB_MSR_READ 0x1 /* read during entry (unlimited) */ -#define KMDB_MSR_WRITE 0x2 /* write during exit (unlimited) */ -#define KMDB_MSR_WRITEDELAY 0x4 /* write after last branch (<= 1) */ -#define KMDB_MSR_CLEARENTRY 0x3 /* clear before 1st branch (<= 1) */ - #ifndef _ASM -typedef struct kmdb_msr { - uint_t msr_num; - uint_t msr_type; - union { - uint64_t *_msr_valp; - uint64_t _msr_val; - } _u; -} kmdb_msr_t; - -#define msr_val _u._msr_val -#define msr_valp _u._msr_valp - extern void kmdb_dpi_handle_fault(kreg_t, kreg_t, kreg_t, int); extern void kmdb_dpi_reboot(void) __NORETURN; -extern void kmdb_dpi_msr_add(const kmdb_msr_t *); +extern void kmdb_dpi_msr_add(const kdi_msr_t *); extern uint64_t kmdb_dpi_msr_get(uint_t); extern uint64_t kmdb_dpi_msr_get_by_cpu(int, uint_t); diff --git a/usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.c b/usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.c index ef001fff68..a556c90041 100644 --- a/usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.c +++ b/usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -35,30 +34,26 @@ #include <mdb/mdb_err.h> #include <mdb/mdb_umem.h> #include <kmdb/kmdb_dpi.h> -#include <kmdb/kmdb_kdi_impl.h> #include <mdb/mdb.h> -void (**kmdb_kdi_shutdownp)(int, int); - -int -kmdb_kdi_xc_initialized(void) +/*ARGSUSED*/ +void +kmdb_kdi_stop_slaves(int my_cpuid, int doxc) { - return (mdb.m_kdi->mkdi_xc_initialized()); + /* Stop other CPUs if there are CPUs to stop */ + mdb.m_kdi->mkdi_stop_slaves(my_cpuid, doxc); } -/*ARGSUSED*/ void -kmdb_kdi_stop_other_cpus(int my_cpuid, void (*slave_saver)(void)) +kmdb_kdi_start_slaves(void) { - /* Stop other CPUs if there are CPUs to stop */ - if (mdb.m_kdi->mkdi_xc_initialized()) - mdb.m_kdi->mkdi_xc_others(my_cpuid, slave_saver); + mdb.m_kdi->mkdi_start_slaves(); } void -kmdb_kdi_cpu_iter(void (*iter)(struct cpu *, uint_t), uint_t arg) +kmdb_kdi_slave_wait(void) { - mdb.m_kdi->mkdi_cpu_iter(iter, arg); + mdb.m_kdi->mkdi_slave_wait(); } uintptr_t @@ -67,51 +62,61 @@ kmdb_kdi_get_userlimit(void) return (mdb.m_kdi->mkdi_get_userlimit()); } -void -kmdb_kdi_idt_init_gate(gate_desc_t *gate, void (*hdlr)(void), uint_t dpl, - int useboot) +int +kmdb_kdi_get_cpuinfo(uint_t *vendorp, uint_t *familyp, uint_t *modelp) { - mdb.m_kdi->mkdi_idt_init_gate(gate, hdlr, dpl, useboot); + int err; + + if ((err = mdb.m_kdi->mkdi_get_cpuinfo(vendorp, familyp, modelp)) != 0) + return (set_errno(err)); + + return (0); } +/*ARGSUSED*/ void -kmdb_kdi_idt_read(gate_desc_t *idt, gate_desc_t *gatep, uint_t vec) +kmdb_kdi_init_isadep(kdi_t *kdi, kmdb_auxv_t *kav) { - mdb.m_kdi->mkdi_idt_read(idt, gatep, vec); } void -kmdb_kdi_idt_write(gate_desc_t *idt, gate_desc_t *gate, uint_t vec) +kmdb_kdi_activate(kdi_main_t main, kdi_cpusave_t *cpusave, int ncpusave) { - mdb.m_kdi->mkdi_idt_write(idt, gate, vec); + mdb.m_kdi->mkdi_activate(main, cpusave, ncpusave); } -gate_desc_t * -kmdb_kdi_cpu2idt(cpu_t *cp) +void +kmdb_kdi_deactivate(void) { - return (mdb.m_kdi->mkdi_cpu2idt(cp)); + mdb.m_kdi->mkdi_deactivate(); } -int -kmdb_kdi_get_cpuinfo(uint_t *vendorp, uint_t *familyp, uint_t *modelp) +void +kmdb_kdi_idt_switch(kdi_cpusave_t *cpusave) { - int err; + mdb.m_kdi->mkdi_idt_switch(cpusave); +} - if ((err = mdb.m_kdi->mkdi_get_cpuinfo(vendorp, familyp, modelp)) != 0) - return (set_errno(err)); +void +kmdb_kdi_update_drreg(kdi_drreg_t *drreg) +{ + mdb.m_kdi->mkdi_update_drreg(drreg); +} - return (0); +void +kmdb_kdi_set_debug_msrs(kdi_msr_t *msrs) +{ + mdb.m_kdi->mkdi_set_debug_msrs(msrs); } -/*ARGSUSED*/ void -kdi_cpu_init(void) +kmdb_kdi_memrange_add(caddr_t base, size_t len) { + mdb.m_kdi->mkdi_memrange_add(base, len); } -/*ARGSUSED1*/ void -kmdb_kdi_init_isadep(kdi_t *kdi, kmdb_auxv_t *kav) +kmdb_kdi_reboot(void) { - kmdb_kdi_shutdownp = kdi->mkdi_shutdownp; + mdb.m_kdi->mkdi_reboot(); } diff --git a/usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.h b/usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.h index 6807a4809c..1813b382e3 100644 --- a/usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.h +++ b/usr/src/cmd/mdb/intel/kmdb/kmdb_kdi_isadep.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -30,6 +29,7 @@ #pragma ident "%Z%%M% %I% %E% SMI" #include <sys/types.h> +#include <sys/kdi_machimpl.h> #include <mdb/mdb_target.h> @@ -39,24 +39,21 @@ extern "C" { struct gate_desc; -extern void (**kdi_shutdownp)(int, int); +extern void kmdb_kdi_activate(kdi_main_t, kdi_cpusave_t *, int); +extern void kmdb_kdi_deactivate(void); -extern uintptr_t kmdb_kdi_get_userlimit(void); -extern int kmdb_kdi_xc_initialized(void); +extern void kmdb_kdi_idt_switch(kdi_cpusave_t *); + +extern void kmdb_kdi_update_drreg(kdi_drreg_t *); +extern void kmdb_kdi_set_debug_msrs(kdi_msr_t *); -extern void kmdb_kdi_idt_init_gate(struct gate_desc *, void (*)(void), uint_t, - int); -extern void kmdb_kdi_idt_read(struct gate_desc *, struct gate_desc *, uint_t); -extern void kmdb_kdi_idt_write(struct gate_desc *, struct gate_desc *, uint_t); -extern struct gate_desc *kmdb_kdi_cpu2idt(struct cpu *); +extern uintptr_t kmdb_kdi_get_userlimit(void); extern int kmdb_kdi_get_cpuinfo(uint_t *, uint_t *, uint_t *); -/* - * To be used only when the kernel is running - */ -extern void kmdb_kdi_cpu_iter(void (*)(struct cpu *, uint_t), - uint_t); +extern void kmdb_kdi_memrange_add(caddr_t, size_t); + +extern void kmdb_kdi_reboot(void); #ifdef __cplusplus } diff --git a/usr/src/cmd/mdb/intel/kmdb/kvm_cpu_amd.c b/usr/src/cmd/mdb/intel/kmdb/kvm_cpu_amd.c index 7d05c02265..6b67853220 100644 --- a/usr/src/cmd/mdb/intel/kmdb/kvm_cpu_amd.c +++ b/usr/src/cmd/mdb/intel/kmdb/kvm_cpu_amd.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -41,7 +40,7 @@ typedef struct kmt_cpu_amd { uint64_t amd_debugctl; /* value for debugctl MSR */ - const kmdb_msr_t *amd_msrs; /* MSR r/w list */ + const kdi_msr_t *amd_msrs; /* MSR r/w list */ uint_t amd_family; /* CPUID family */ uint_t amd_model; /* CPUID model */ } kmt_cpu_amd_t; @@ -72,22 +71,22 @@ kmt_amd_branch(uint_t cpuid, const char *label, uint_t msr) * MSRs for AMD processors with simple branch tracing facilities. We'll use * this array if we can access listed LBR/LEX MSRs. */ -static const kmdb_msr_t kmt_amd_msrs[] = { - { MSR_DEBUGCTL, KMDB_MSR_CLEARENTRY }, - { MSR_DEBUGCTL, KMDB_MSR_WRITEDELAY, &kmt_cpu_amd.amd_debugctl }, - { MSR_LBR_TO, KMDB_MSR_READ }, - { MSR_LBR_FROM, KMDB_MSR_READ }, - { MSR_LEX_TO, KMDB_MSR_READ }, - { MSR_LEX_FROM, KMDB_MSR_READ }, +static const kdi_msr_t kmt_amd_msrs[] = { + { MSR_DEBUGCTL, KDI_MSR_CLEARENTRY }, + { MSR_DEBUGCTL, KDI_MSR_WRITEDELAY, &kmt_cpu_amd.amd_debugctl }, + { MSR_LBR_TO, KDI_MSR_READ }, + { MSR_LBR_FROM, KDI_MSR_READ }, + { MSR_LEX_TO, KDI_MSR_READ }, + { MSR_LEX_FROM, KDI_MSR_READ }, { NULL } }; /* * Fallback MSR list for use if we can't read the LBR/LEX MSRs. */ -static const kmdb_msr_t kmt_amdunk_msrs[] = { - { MSR_DEBUGCTL, KMDB_MSR_CLEARENTRY }, - { MSR_DEBUGCTL, KMDB_MSR_WRITEDELAY, &kmt_cpu_amd.amd_debugctl }, +static const kdi_msr_t kmt_amdunk_msrs[] = { + { MSR_DEBUGCTL, KDI_MSR_CLEARENTRY }, + { MSR_DEBUGCTL, KDI_MSR_WRITEDELAY, &kmt_cpu_amd.amd_debugctl }, { NULL } }; diff --git a/usr/src/cmd/mdb/intel/kmdb/kvm_cpu_p4.c b/usr/src/cmd/mdb/intel/kmdb/kvm_cpu_p4.c index 39d5ea175a..653b4a31f5 100644 --- a/usr/src/cmd/mdb/intel/kmdb/kvm_cpu_p4.c +++ b/usr/src/cmd/mdb/intel/kmdb/kvm_cpu_p4.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -51,7 +50,7 @@ */ typedef struct kmt_p4_flavor { const char *p4f_name; /* name for CPU support */ - const kmdb_msr_t *p4f_msrs; /* MSR r/w list */ + const kdi_msr_t *p4f_msrs; /* MSR r/w list */ int (*p4f_branches)(const struct kmt_p4_flavor *, uint_t, intptr_t, int); /* dumper for CPU branch stk */ uint_t p4f_msr_tos; /* branch stk index MSR */ @@ -164,14 +163,14 @@ kmt_p4_branches_split(const kmt_p4_flavor_t *p4f, uint_t tos, intptr_t cpuid, } #ifndef __amd64 -static const kmdb_msr_t kmt_p4orig_msrs[] = { - { MSR_DEBUGCTL, KMDB_MSR_CLEARENTRY }, - { MSR_DEBUGCTL, KMDB_MSR_WRITEDELAY, &kmt_cpu_p4.p4_debugctl }, - { MSR_P4_LBSTK_TOS, KMDB_MSR_READ }, - { MSR_P4_LBSTK_0, KMDB_MSR_READ }, - { MSR_P4_LBSTK_1, KMDB_MSR_READ }, - { MSR_P4_LBSTK_2, KMDB_MSR_READ }, - { MSR_P4_LBSTK_3, KMDB_MSR_READ }, +static const kdi_msr_t kmt_p4orig_msrs[] = { + { MSR_DEBUGCTL, KDI_MSR_CLEARENTRY }, + { MSR_DEBUGCTL, KDI_MSR_WRITEDELAY, &kmt_cpu_p4.p4_debugctl }, + { MSR_P4_LBSTK_TOS, KDI_MSR_READ }, + { MSR_P4_LBSTK_0, KDI_MSR_READ }, + { MSR_P4_LBSTK_1, KDI_MSR_READ }, + { MSR_P4_LBSTK_2, KDI_MSR_READ }, + { MSR_P4_LBSTK_3, KDI_MSR_READ }, { NULL } }; @@ -181,18 +180,18 @@ static const kmt_p4_flavor_t kmt_p4_original = { MSR_P4_LBSTK_0, MSR_P4_LBSTK_0, 4 }; -static const kmdb_msr_t kmt_p6m_msrs[] = { - { MSR_DEBUGCTL, KMDB_MSR_CLEARENTRY }, - { MSR_DEBUGCTL, KMDB_MSR_WRITEDELAY, &kmt_cpu_p4.p4_debugctl }, - { MSR_P6M_LBSTK_TOS, KMDB_MSR_READ }, - { MSR_P6M_LBSTK_0, KMDB_MSR_READ }, - { MSR_P6M_LBSTK_1, KMDB_MSR_READ }, - { MSR_P6M_LBSTK_2, KMDB_MSR_READ }, - { MSR_P6M_LBSTK_3, KMDB_MSR_READ }, - { MSR_P6M_LBSTK_4, KMDB_MSR_READ }, - { MSR_P6M_LBSTK_5, KMDB_MSR_READ }, - { MSR_P6M_LBSTK_6, KMDB_MSR_READ }, - { MSR_P6M_LBSTK_7, KMDB_MSR_READ }, +static const kdi_msr_t kmt_p6m_msrs[] = { + { MSR_DEBUGCTL, KDI_MSR_CLEARENTRY }, + { MSR_DEBUGCTL, KDI_MSR_WRITEDELAY, &kmt_cpu_p4.p4_debugctl }, + { MSR_P6M_LBSTK_TOS, KDI_MSR_READ }, + { MSR_P6M_LBSTK_0, KDI_MSR_READ }, + { MSR_P6M_LBSTK_1, KDI_MSR_READ }, + { MSR_P6M_LBSTK_2, KDI_MSR_READ }, + { MSR_P6M_LBSTK_3, KDI_MSR_READ }, + { MSR_P6M_LBSTK_4, KDI_MSR_READ }, + { MSR_P6M_LBSTK_5, KDI_MSR_READ }, + { MSR_P6M_LBSTK_6, KDI_MSR_READ }, + { MSR_P6M_LBSTK_7, KDI_MSR_READ }, { NULL } }; @@ -203,42 +202,42 @@ static const kmt_p4_flavor_t kmt_p6_m = { }; #endif /* __amd64 */ -static const kmdb_msr_t kmt_prp4_msrs[] = { - { MSR_DEBUGCTL, KMDB_MSR_CLEARENTRY }, - { MSR_DEBUGCTL, KMDB_MSR_WRITEDELAY, &kmt_cpu_p4.p4_debugctl }, - { MSR_PRP4_LBSTK_TOS, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_FROM_0, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_FROM_1, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_FROM_2, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_FROM_3, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_FROM_4, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_FROM_5, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_FROM_6, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_FROM_7, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_FROM_8, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_FROM_9, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_FROM_10, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_FROM_11, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_FROM_12, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_FROM_13, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_FROM_14, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_FROM_15, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_TO_0, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_TO_1, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_TO_2, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_TO_3, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_TO_4, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_TO_5, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_TO_6, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_TO_7, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_TO_8, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_TO_9, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_TO_10, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_TO_11, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_TO_12, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_TO_13, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_TO_14, KMDB_MSR_READ }, - { MSR_PRP4_LBSTK_TO_15, KMDB_MSR_READ }, +static const kdi_msr_t kmt_prp4_msrs[] = { + { MSR_DEBUGCTL, KDI_MSR_CLEARENTRY }, + { MSR_DEBUGCTL, KDI_MSR_WRITEDELAY, &kmt_cpu_p4.p4_debugctl }, + { MSR_PRP4_LBSTK_TOS, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_FROM_0, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_FROM_1, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_FROM_2, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_FROM_3, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_FROM_4, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_FROM_5, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_FROM_6, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_FROM_7, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_FROM_8, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_FROM_9, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_FROM_10, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_FROM_11, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_FROM_12, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_FROM_13, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_FROM_14, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_FROM_15, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_TO_0, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_TO_1, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_TO_2, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_TO_3, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_TO_4, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_TO_5, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_TO_6, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_TO_7, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_TO_8, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_TO_9, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_TO_10, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_TO_11, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_TO_12, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_TO_13, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_TO_14, KDI_MSR_READ }, + { MSR_PRP4_LBSTK_TO_15, KDI_MSR_READ }, { NULL } }; @@ -248,9 +247,9 @@ static const kmt_p4_flavor_t kmt_p4_prescott = { MSR_PRP4_LBSTK_FROM_0, MSR_PRP4_LBSTK_TO_0, 16 }; -static const kmdb_msr_t kmt_p4unk_msrs[] = { - { MSR_DEBUGCTL, KMDB_MSR_CLEARENTRY }, - { MSR_DEBUGCTL, KMDB_MSR_WRITEDELAY, &kmt_cpu_p4.p4_debugctl }, +static const kdi_msr_t kmt_p4unk_msrs[] = { + { MSR_DEBUGCTL, KDI_MSR_CLEARENTRY }, + { MSR_DEBUGCTL, KDI_MSR_WRITEDELAY, &kmt_cpu_p4.p4_debugctl }, { NULL } }; diff --git a/usr/src/cmd/mdb/intel/kmdb/kvm_isadep.c b/usr/src/cmd/mdb/intel/kmdb/kvm_isadep.c index e80b2243ef..3f32502080 100644 --- a/usr/src/cmd/mdb/intel/kmdb/kvm_isadep.c +++ b/usr/src/cmd/mdb/intel/kmdb/kvm_isadep.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -377,7 +377,7 @@ kmt_wrmsr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) } int -kmt_msr_validate(const kmdb_msr_t *msr) +kmt_msr_validate(const kdi_msr_t *msr) { uint64_t val; diff --git a/usr/src/cmd/mdb/intel/kmdb/kvm_isadep.h b/usr/src/cmd/mdb/intel/kmdb/kvm_isadep.h index d03ae5eafa..e944c6ca8b 100644 --- a/usr/src/cmd/mdb/intel/kmdb/kvm_isadep.h +++ b/usr/src/cmd/mdb/intel/kmdb/kvm_isadep.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -46,8 +45,7 @@ extern int kmt_wrmsr(uintptr_t, uint_t, int, const mdb_arg_t *); extern int kmt_rdpcicfg(uintptr_t, uint_t, int, const mdb_arg_t *); extern int kmt_wrpcicfg(uintptr_t, uint_t, int, const mdb_arg_t *); - -extern int kmt_msr_validate(const kmdb_msr_t *); +extern int kmt_msr_validate(const kdi_msr_t *); #ifdef __cplusplus } diff --git a/usr/src/cmd/mdb/intel/mdb/kvm_amd64dep.c b/usr/src/cmd/mdb/intel/mdb/kvm_amd64dep.c index a2f965f424..43468af924 100644 --- a/usr/src/cmd/mdb/intel/mdb/kvm_amd64dep.c +++ b/usr/src/cmd/mdb/intel/mdb/kvm_amd64dep.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -320,8 +319,6 @@ kt_amd64_init(mdb_tgt_t *t) kregs[KREG_R13] = regs.r_r13; kregs[KREG_R14] = regs.r_r14; kregs[KREG_R15] = regs.r_r15; - kregs[KREG_FSBASE] = regs.r_fsbase; - kregs[KREG_GSBASE] = regs.r_gsbase; kregs[KREG_DS] = regs.r_ds; kregs[KREG_ES] = regs.r_es; kregs[KREG_FS] = regs.r_fs; diff --git a/usr/src/cmd/mdb/intel/mdb/mdb_amd64util.c b/usr/src/cmd/mdb/intel/mdb/mdb_amd64util.c index 93ab6bf92b..303923f236 100644 --- a/usr/src/cmd/mdb/intel/mdb/mdb_amd64util.c +++ b/usr/src/cmd/mdb/intel/mdb/mdb_amd64util.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -64,9 +64,6 @@ const mdb_tgt_regdesc_t mdb_amd64_kregs[] = { { "r13", KREG_R13, MDB_TGT_R_EXPORT }, { "r14", KREG_R14, MDB_TGT_R_EXPORT }, { "r15", KREG_R15, MDB_TGT_R_EXPORT }, - { "fsbase", KREG_FSBASE, MDB_TGT_R_EXPORT | MDB_TGT_R_PRIV }, - { "gsbase", KREG_GSBASE, MDB_TGT_R_EXPORT | MDB_TGT_R_PRIV }, - { "kgsbase", KREG_KGSBASE, MDB_TGT_R_EXPORT | MDB_TGT_R_PRIV }, { "ds", KREG_DS, MDB_TGT_R_EXPORT }, { "es", KREG_ES, MDB_TGT_R_EXPORT }, { "fs", KREG_FS, MDB_TGT_R_EXPORT }, @@ -134,10 +131,10 @@ mdb_amd64_printregs(const mdb_tgt_gregset_t *gregs) mdb_printf("%24s%%cs = 0x%04x\t%%ds = 0x%04x\t%%es = 0x%04x\n", " ", kregs[KREG_CS], kregs[KREG_DS], kregs[KREG_ES]); - mdb_printf("%%trapno = 0x%x\t\t%%fs = 0x%04x\tfsbase = 0x%0?p\n", - kregs[KREG_TRAPNO], (kregs[KREG_FS] & 0xffff), kregs[KREG_FSBASE]); - mdb_printf(" %%err = 0x%x\t\t%%gs = 0x%04x\tgsbase = 0x%0?p\n", - kregs[KREG_ERR], (kregs[KREG_GS] & 0xffff), kregs[KREG_GSBASE]); + mdb_printf("%%trapno = 0x%x\t\t%%fs = 0x%04x\t%%gs = 0x%04x\n", + kregs[KREG_TRAPNO], (kregs[KREG_FS] & 0xffff), + (kregs[KREG_GS] & 0xffff)); + mdb_printf(" %%err = 0x%x\n", kregs[KREG_ERR]); } diff --git a/usr/src/cmd/mdb/intel/mdb/mdb_kreg.h b/usr/src/cmd/mdb/intel/mdb/mdb_kreg.h index 3e7d79f462..4ba5fb567c 100644 --- a/usr/src/cmd/mdb/intel/mdb/mdb_kreg.h +++ b/usr/src/cmd/mdb/intel/mdb/mdb_kreg.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -29,6 +28,7 @@ #pragma ident "%Z%%M% %I% %E% SMI" +#include <sys/kdi_regs.h> #ifndef _ASM #include <sys/types.h> #endif @@ -37,51 +37,51 @@ extern "C" { #endif -#ifdef __amd64 -#define KREG_NGREG 31 #ifndef _ASM +#ifdef __amd64 typedef uint64_t kreg_t; -#endif /* !_ASM */ #else /* __amd64 */ -#define KREG_NGREG 21 -#ifndef _ASM typedef uint32_t kreg_t; -#endif /* !_ASM */ #endif /* __amd64 */ +#endif /* !_ASM */ + +#define KREG_NGREG KDIREG_NGREG + +/* + * The order of these registers corresponds to a slightly altered struct regs, + * in the order kmdb entry pushes onto the stack. + */ #ifdef __amd64 -#define KREG_SAVFP 0 -#define KREG_SAVPC 1 -#define KREG_RDI 2 -#define KREG_RSI 3 -#define KREG_RDX 4 -#define KREG_RCX 5 -#define KREG_R8 6 -#define KREG_R9 7 -#define KREG_RAX 8 -#define KREG_RBX 9 -#define KREG_RBP 10 -#define KREG_R10 11 -#define KREG_R11 12 -#define KREG_R12 13 -#define KREG_R13 14 -#define KREG_R14 15 -#define KREG_R15 16 -#define KREG_FSBASE 17 -#define KREG_GSBASE 18 -#define KREG_KGSBASE 19 -#define KREG_DS 20 -#define KREG_ES 21 -#define KREG_FS 22 -#define KREG_GS 23 -#define KREG_TRAPNO 24 -#define KREG_ERR 25 -#define KREG_RIP 26 -#define KREG_CS 27 -#define KREG_RFLAGS 28 -#define KREG_RSP 29 -#define KREG_SS 30 +#define KREG_SAVFP KDIREG_SAVFP +#define KREG_SAVPC KDIREG_SAVPC +#define KREG_RDI KDIREG_RDI +#define KREG_RSI KDIREG_RSI +#define KREG_RDX KDIREG_RDX +#define KREG_RCX KDIREG_RCX +#define KREG_R8 KDIREG_R8 +#define KREG_R9 KDIREG_R9 +#define KREG_RAX KDIREG_RAX +#define KREG_RBX KDIREG_RBX +#define KREG_RBP KDIREG_RBP +#define KREG_R10 KDIREG_R10 +#define KREG_R11 KDIREG_R11 +#define KREG_R12 KDIREG_R12 +#define KREG_R13 KDIREG_R13 +#define KREG_R14 KDIREG_R14 +#define KREG_R15 KDIREG_R15 +#define KREG_DS KDIREG_DS +#define KREG_ES KDIREG_ES +#define KREG_FS KDIREG_FS +#define KREG_GS KDIREG_GS +#define KREG_TRAPNO KDIREG_TRAPNO +#define KREG_ERR KDIREG_ERR +#define KREG_RIP KDIREG_RIP +#define KREG_CS KDIREG_CS +#define KREG_RFLAGS KDIREG_RFLAGS +#define KREG_RSP KDIREG_RSP +#define KREG_SS KDIREG_SS #define KREG_PC KREG_RIP #define KREG_SP KREG_RSP @@ -89,33 +89,27 @@ typedef uint32_t kreg_t; #else /* __amd64 */ -/* - * The order of these registers corresponds to a slightly altered struct regs. - * %ss appears first, and is followed by the remainder of the struct regs. This - * change is necessary to support kmdb state saving. - */ - -#define KREG_SAVFP 0 -#define KREG_SAVPC 1 -#define KREG_SS 2 -#define KREG_GS 3 -#define KREG_FS 4 -#define KREG_ES 5 -#define KREG_DS 6 -#define KREG_EDI 7 -#define KREG_ESI 8 -#define KREG_EBP 9 -#define KREG_ESP 10 -#define KREG_EBX 11 -#define KREG_EDX 12 -#define KREG_ECX 13 -#define KREG_EAX 14 -#define KREG_TRAPNO 15 -#define KREG_ERR 16 -#define KREG_EIP 17 -#define KREG_CS 18 -#define KREG_EFLAGS 19 -#define KREG_UESP 20 +#define KREG_SAVFP KDIREG_SAVFP +#define KREG_SAVPC KDIREG_SAVPC +#define KREG_SS KDIREG_SS +#define KREG_GS KDIREG_GS +#define KREG_FS KDIREG_FS +#define KREG_ES KDIREG_ES +#define KREG_DS KDIREG_DS +#define KREG_EDI KDIREG_EDI +#define KREG_ESI KDIREG_ESI +#define KREG_EBP KDIREG_EBP +#define KREG_ESP KDIREG_ESP +#define KREG_EBX KDIREG_EBX +#define KREG_EDX KDIREG_EDX +#define KREG_ECX KDIREG_ECX +#define KREG_EAX KDIREG_EAX +#define KREG_TRAPNO KDIREG_TRAPNO +#define KREG_ERR KDIREG_ERR +#define KREG_EIP KDIREG_EIP +#define KREG_CS KDIREG_CS +#define KREG_EFLAGS KDIREG_EFLAGS +#define KREG_UESP KDIREG_UESP #define KREG_PC KREG_EIP #define KREG_SP KREG_ESP @@ -174,8 +168,6 @@ typedef uint32_t kreg_t; #define KREG_EFLAGS_CF_MASK 0x00000001 #define KREG_EFLAGS_CF_SHIFT 0 -#define KREG_MAXWPIDX 3 - /* %dr7 */ #define KREG_DRCTL_WP_BASESHIFT 16 #define KREG_DRCTL_WP_INCRSHIFT 4 @@ -199,12 +191,6 @@ typedef uint32_t kreg_t; (3 << (KREG_DRCTL_WPEN_INCRSHIFT * (n))) #define KREG_DRCTL_WPEN(n) KREG_DRCTL_WPEN_MASK(n) -#define KREG_DRCTL_WPALLEN_MASK 0x000000ff - -#define KREG_DRCTL_GD_MASK 0x00002000 - -#define KREG_DRCTL_RESERVED 0x00000700 - /* %dr6 */ #define KREG_DRSTAT_BT_MASK 0x00008000 #define KREG_DRSTAT_BS_MASK 0x00004000 @@ -212,8 +198,6 @@ typedef uint32_t kreg_t; #define KREG_DRSTAT_WP_MASK(n) (1 << (n)) -#define KREG_DRSTAT_RESERVED 0xffff0ff0 - #ifdef __cplusplus } #endif diff --git a/usr/src/cmd/mdb/sparc/kmdb/kaif.c b/usr/src/cmd/mdb/sparc/kmdb/kaif.c index 92eaec51f1..729d1fdd1d 100644 --- a/usr/src/cmd/mdb/sparc/kmdb/kaif.c +++ b/usr/src/cmd/mdb/sparc/kmdb/kaif.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -875,14 +875,6 @@ kaif_mod_unloading(struct modctl *modp) kaif_modchg_cb(modp, 0); } -/*ARGSUSED*/ -int -kaif_memrange_add(caddr_t base, size_t len) -{ - /* We don't support multiple memory ranges on SPARC */ - return (set_errno(ENOTSUP)); -} - void kaif_trap_set_debugger(void) { @@ -1017,6 +1009,5 @@ dpi_ops_t kmdb_dpi_ops = { kaif_step, kaif_call, kaif_dump_crumbs, - kaif_memrange_add, kaif_kernpanic }; diff --git a/usr/src/cmd/mdb/sparc/kmdb/kaif.h b/usr/src/cmd/mdb/sparc/kmdb/kaif.h index 98d196192c..50445df8a3 100644 --- a/usr/src/cmd/mdb/sparc/kmdb/kaif.h +++ b/usr/src/cmd/mdb/sparc/kmdb/kaif.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -41,16 +41,10 @@ extern "C" { #endif -#define KAIF_MASTER_CPUID_UNSET -1 - #define KAIF_CPU_STATE_NONE 0 #define KAIF_CPU_STATE_MASTER 1 #define KAIF_CPU_STATE_SLAVE 2 -#define KAIF_CPU_CMD_RESUME 0 -#define KAIF_CPU_CMD_RESUME_MASTER 1 -#define KAIF_CPU_CMD_SWITCH 2 - #define KAIF_LSUCTL_VWAPT_MASK (LSU_VM|LSU_VR|LSU_VW) #define KAIF_LSUCTL_PWAPT_MASK (LSU_PM|LSU_PR|LSU_PW) #define KAIF_LSUCTL_WAPT_MASK (LSU_PM|LSU_VM|LSU_PR|LSU_PW|LSU_VR|LSU_VW) @@ -111,8 +105,6 @@ extern void kaif_slave_entry(void); extern void kaif_prom_rearm(void); extern void kaif_debugger_entry(kaif_cpusave_t *); -extern int kaif_memrange_add(caddr_t, size_t); - extern void kaif_slave_loop_barrier(void); #endif diff --git a/usr/src/cmd/mdb/sparc/kmdb/kaif_activate.c b/usr/src/cmd/mdb/sparc/kmdb/kaif_activate.c index a17431d53f..e7bcf7e68f 100644 --- a/usr/src/cmd/mdb/sparc/kmdb/kaif_activate.c +++ b/usr/src/cmd/mdb/sparc/kmdb/kaif_activate.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -278,18 +278,17 @@ kaif_cpr_restart(void) } static kdi_debugvec_t kaif_dvec = { - kaif_enter, - kaif_cpu_init, - NULL, /* dv_kctl_cpu_init */ - kaif_vmready, NULL, /* dv_kctl_vmready */ NULL, /* dv_kctl_memavail */ - kaif_memrange_add, - kaif_cpr_restart, NULL, /* dv_kctl_modavail */ NULL, /* dv_kctl_thravail */ + kaif_vmready, + NULL, /* dv_memavail */ kaif_mod_loaded, - kaif_mod_unloading + kaif_mod_unloading, + NULL, /* dv_kctl_cpu_init */ + kaif_cpu_init, + kaif_cpr_restart }; /*ARGSUSED1*/ diff --git a/usr/src/cmd/mdb/sparc/kmdb/kaif_enter.s b/usr/src/cmd/mdb/sparc/kmdb/kaif_enter.s deleted file mode 100644 index 4275773a71..0000000000 --- a/usr/src/cmd/mdb/sparc/kmdb/kaif_enter.s +++ /dev/null @@ -1,48 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/asm_linkage.h> - -#if defined(__lint) -#include <kmdb/kaif.h> -#endif /* __lint */ - -#if defined(__lint) -void -kaif_enter(void) -{ -} -#else /* __lint */ - - ENTRY(kaif_enter) - t ST_KMDB_TRAP - retl - nop - SET_SIZE(kaif_enter) - -#endif diff --git a/usr/src/cmd/mdb/sparc/kmdb/kctl/kctl_isadep.c b/usr/src/cmd/mdb/sparc/kmdb/kctl/kctl_isadep.c index 5ae674e26e..f50016389c 100644 --- a/usr/src/cmd/mdb/sparc/kmdb/kctl/kctl_isadep.c +++ b/usr/src/cmd/mdb/sparc/kmdb/kctl/kctl_isadep.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -195,18 +195,11 @@ kctl_depreactivate_isadep(void) kdi_watchdog_restore(); } -int +void kctl_activate_isadep(kdi_debugvec_t *dvec) { dvec->dv_kctl_cpu_init = kctl_cpu_init; dvec->dv_kctl_vmready = kctl_ttable_init; - - return (0); -} - -void -kctl_deactivate_isadep(void) -{ } void diff --git a/usr/src/cmd/mdb/sparc/kmdb/kmdb_kdi_isadep.c b/usr/src/cmd/mdb/sparc/kmdb/kmdb_kdi_isadep.c index c82095ada5..15ceeeff1f 100644 --- a/usr/src/cmd/mdb/sparc/kmdb/kmdb_kdi_isadep.c +++ b/usr/src/cmd/mdb/sparc/kmdb/kmdb_kdi_isadep.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -32,7 +32,7 @@ #include <sys/types.h> #include <sys/kdi_impl.h> -#include <kmdb/kmdb_kdi_impl.h> +#include <kmdb/kaif.h> #include <kmdb/kmdb_dpi.h> #include <kmdb/kmdb_promif.h> #include <mdb/mdb_debug.h> @@ -49,6 +49,8 @@ static size_t kdi_icache_linesize; static uint_t kdi_max_cpu_freq; static uint_t kdi_sticks_per_usec; +/* XXX needs to go into a header */ + void kdi_usecwait(clock_t n) { @@ -139,36 +141,6 @@ kdi_init_cpus_cb(pnode_t node, void *arg, void *result) return (0); } -void -kdi_cpu_init(void) -{ - kdi_dcache_size = kdi_dcache_linesize = - kdi_icache_size = kdi_icache_linesize = 0; - - kdi_max_cpu_freq = kdi_sticks_per_usec = 0; - - mdb_dprintf(MDB_DBG_KDI, "Initializing CPUs\n"); - - kmdb_prom_walk_cpus(kdi_init_cpus_cb, NULL, NULL); - - /* - * If we can't find one, guess high. The CPU frequency is going to be - * used to determine the length of various delays, such as the mondo - * interrupt retry delay. Too long is generally better than too short. - */ - if (kdi_max_cpu_freq == 0) { - mdb_dprintf(MDB_DBG_KDI, "No CPU freq found - assuming " - "500MHz\n"); - kdi_max_cpu_freq = 500 * MICROSEC; - } - - kdi_sticks_per_usec = - MAX((kdi_max_cpu_freq + (MICROSEC - 1)) / MICROSEC, 1); - - mdb.m_kdi->mkdi_cpu_init(kdi_dcache_size, kdi_dcache_linesize, - kdi_icache_size, kdi_icache_linesize); -} - /* * Called on an individual CPU. Tries to send it off to the state saver if it * hasn't already entered the debugger. Returns non-zero if it *fails* to stop @@ -217,12 +189,13 @@ kdi_report_unhalted(int cpuid, void *junk) /*ARGSUSED*/ void -kmdb_kdi_stop_other_cpus(int my_cpuid, void (*slave_saver)(void)) +kmdb_kdi_stop_slaves(int my_cpuid, int doxc) { int i; for (i = 0; i < KDI_XC_RETRIES; i++) { - if (kdi_cpu_ready_iter(kdi_halt_cpu, (void *)slave_saver) == 0) + if (kdi_cpu_ready_iter(kdi_halt_cpu, + (void *)kaif_slave_entry) == 0) break; kdi_usecwait(2000); @@ -230,6 +203,16 @@ kmdb_kdi_stop_other_cpus(int my_cpuid, void (*slave_saver)(void)) (void) kdi_cpu_ready_iter(kdi_report_unhalted, NULL); } +void +kmdb_kdi_start_slaves(void) +{ +} + +void +kmdb_kdi_slave_wait(void) +{ +} + int kmdb_kdi_get_stick(uint64_t *stickp) { @@ -257,4 +240,29 @@ kmdb_kdi_kernpanic(struct regs *regs, uint_t tt) void kmdb_kdi_init_isadep(kdi_t *kdi, kmdb_auxv_t *kav) { + kdi_dcache_size = kdi_dcache_linesize = + kdi_icache_size = kdi_icache_linesize = 0; + + kdi_max_cpu_freq = kdi_sticks_per_usec = 0; + + mdb_dprintf(MDB_DBG_KDI, "Initializing CPUs\n"); + + kmdb_prom_walk_cpus(kdi_init_cpus_cb, NULL, NULL); + + /* + * If we can't find one, guess high. The CPU frequency is going to be + * used to determine the length of various delays, such as the mondo + * interrupt retry delay. Too long is generally better than too short. + */ + if (kdi_max_cpu_freq == 0) { + mdb_dprintf(MDB_DBG_KDI, "No CPU freq found - assuming " + "500MHz\n"); + kdi_max_cpu_freq = 500 * MICROSEC; + } + + kdi_sticks_per_usec = + MAX((kdi_max_cpu_freq + (MICROSEC - 1)) / MICROSEC, 1); + + mdb.m_kdi->mkdi_cpu_init(kdi_dcache_size, kdi_dcache_linesize, + kdi_icache_size, kdi_icache_linesize); } diff --git a/usr/src/cmd/mdb/sparc/v9/genunix/Makefile b/usr/src/cmd/mdb/sparc/v9/genunix/Makefile index 2cf7038d9e..564244d298 100644 --- a/usr/src/cmd/mdb/sparc/v9/genunix/Makefile +++ b/usr/src/cmd/mdb/sparc/v9/genunix/Makefile @@ -29,43 +29,10 @@ MODULE = genunix.so MDBTGT = kvm +include ../../../common/modules/genunix/Makefile.files + COMMONSRCS = \ - avl.c \ - bio.c \ - contract.c \ - cpupart.c \ - ctxop.c \ - cyclic.c \ - devinfo.c \ - findstack.c \ - fm.c \ - genunix.c \ - group.c \ - kgrep.c \ - kmem.c \ - ldi.c \ - leaky.c \ - leaky_subr.c \ - lgrp.c \ - list.c \ - log.c \ - mdi.c \ - memory.c \ - mmd.c \ - modhash.c \ - ndievents.c \ - net.c \ - nvpair.c \ - pg.c \ - rctl.c \ - sobj.c \ - streams.c \ - sysevent.c \ - thread.c \ - tsd.c \ - tsol.c \ - vfs.c \ - zone.c + $(GENUNIX_SRCS) KMODSRCS = \ $(COMMONSRCS) diff --git a/usr/src/cmd/mdb/sun4u/Makefile.kmdb b/usr/src/cmd/mdb/sun4u/Makefile.kmdb index 43471fe808..152e0e736b 100644 --- a/usr/src/cmd/mdb/sun4u/Makefile.kmdb +++ b/usr/src/cmd/mdb/sun4u/Makefile.kmdb @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -63,7 +62,6 @@ KMDBSRCS += \ kvm_isadep.c KMDBML += \ - kaif_enter.s \ kmdb_asmutil.s KCTLSRCS += \ diff --git a/usr/src/cmd/mdb/sun4v/Makefile.kmdb b/usr/src/cmd/mdb/sun4v/Makefile.kmdb index d307d5f6f8..52ea632d90 100644 --- a/usr/src/cmd/mdb/sun4v/Makefile.kmdb +++ b/usr/src/cmd/mdb/sun4v/Makefile.kmdb @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -71,7 +71,6 @@ KMDBSRCS += \ kvm_isadep.c KMDBML += \ - kaif_enter.s \ kmdb_asmutil.s KCTLSRCS += \ diff --git a/usr/src/cmd/prtdiag/Makefile b/usr/src/cmd/prtdiag/Makefile index 2265dbd099..5a094f0213 100644 --- a/usr/src/cmd/prtdiag/Makefile +++ b/usr/src/cmd/prtdiag/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -21,7 +20,7 @@ # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -42,10 +41,6 @@ _msg := TARGET = _msg all install clean clobber lint _msg: $(SUBDIRS) -install: $(SUBDIRS) - $(RM) $(ROOTUSRSBINPROG) - $(LN) $(PLATEXEC) $(ROOTUSRSBINPROG) - $(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(TARGET) diff --git a/usr/src/cmd/prtdiag/Makefile.com b/usr/src/cmd/prtdiag/Makefile.com index 732ab9e7eb..46d21d2338 100644 --- a/usr/src/cmd/prtdiag/Makefile.com +++ b/usr/src/cmd/prtdiag/Makefile.com @@ -20,7 +20,7 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -37,13 +37,13 @@ DIRMODE = 755 OWNER = root GROUP = sys -LINTFILES = $(OBJS:%.o=%.ln) -POFILE = prtdiag_$(PLATFORM).po +LINT_OBJS = $(OBJS:%.o=%.ln) +POFILE = prtdiag.po POFILES = $(OBJS:%.o=%.po) LIBPRTDIAG = $(SRC)/lib/libprtdiag -.PARALLEL: $(OBJS) $(LINTFILES) +.PARALLEL: $(OBJS) $(LINT_OBJS) %.o: %.c $(COMPILE.c) -o $@ $< diff --git a/usr/src/cmd/prtdiag/i386/Makefile b/usr/src/cmd/prtdiag/i386/Makefile index 985fd3411a..10bbed0d40 100644 --- a/usr/src/cmd/prtdiag/i386/Makefile +++ b/usr/src/cmd/prtdiag/i386/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -19,27 +18,22 @@ # # CDDL HEADER END # - # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +#ident "%Z%%M% %I% %E% SMI" +# +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#ident "%Z%%M% %I% %E% SMI" -SUBDIRS = i86pc +SRCDIR = .. -all := TARGET = all -install := TARGET = install -clean := TARGET = clean -clobber := TARGET = clobber -lint := TARGET = lint -_msg := TARGET = _msg +include $(SRCDIR)/Makefile.com -.KEEP_STATE: +OBJS += smbios.o +LDLIBS += -lsmbios -all install clean clobber lint _msg: $(SUBDIRS) +.KEEP_STATE: -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) +all: $(PROG) -FRC: +include $(SRCDIR)/i386/Makefile.targ diff --git a/usr/src/cmd/prtdiag/i386/i86pc/Makefile b/usr/src/cmd/prtdiag/i386/Makefile.targ index 77891ef8e4..61b0ad98da 100644 --- a/usr/src/cmd/prtdiag/i386/i86pc/Makefile +++ b/usr/src/cmd/prtdiag/i386/Makefile.targ @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -21,23 +20,27 @@ # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" -SRCDIR = ../.. -PLATFORM = i86pc -PLATLINKS = +install: all $(ROOTUSRSBIN) $(ROOTUSRSBINPROG) -include $(SRCDIR)/Makefile.com +$(PROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) $(LDLIBS) + $(POST_PROCESS) -FILEMODE = 555 -LDLIBS += -lsmbios -OBJS += smbios.o +clean: + -$(RM) $(OBJS) + -$(RM) $(LINT_OBJS) + -$(RM) $(PROG) -.KEEP_STATE: +lint: $(LINT_OBJS) + $(LINT.c) $(LINT_OBJS) $(LDLIBS) -all: $(PROG) +$(POFILE): $(POFILES) + $(RM) $@ + cat $(POFILES) > $@ -include $(SRCDIR)/Makefile.targ +include $(SRCDIR)/../Makefile.targ diff --git a/usr/src/cmd/prtdiag/i386/i86pc/smbios.c b/usr/src/cmd/prtdiag/i386/smbios.c index 819cd04551..819cd04551 100644 --- a/usr/src/cmd/prtdiag/i386/i86pc/smbios.c +++ b/usr/src/cmd/prtdiag/i386/smbios.c diff --git a/usr/src/cmd/prtdiag/Makefile.targ b/usr/src/cmd/prtdiag/sparc/Makefile.targ index 4cc5938f24..19a930a8ec 100644 --- a/usr/src/cmd/prtdiag/Makefile.targ +++ b/usr/src/cmd/prtdiag/sparc/Makefile.targ @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -21,22 +20,24 @@ # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" install: all $(USR_PSM_SBIN_PROG) $(USR_PSM_SBIN_PROG_LINKS) + $(RM) $(ROOTUSRSBINPROG) + $(LN) $(PLATEXEC) $(ROOTUSRSBINPROG) $(PROG): $(OBJS) $(LINK.c) -o $@ $(OBJS) $(LDLIBS) $(POST_PROCESS) clean: - -$(RM) $(OBJS) $(LINTFILES) + -$(RM) $(OBJS) $(LINT_OBJS) $(PROG) -lint: $(LINTFILES) - $(LINT) $(LINTFILES) $(LDLIBS) +lint: $(LINT_OBJS) + $(LINT) $(LINT_OBJS) $(LDLIBS) $(POFILE): $(POFILES) $(RM) $@ diff --git a/usr/src/cmd/prtdiag/sparc/sun4u/Makefile b/usr/src/cmd/prtdiag/sparc/sun4u/Makefile index 17f6f71ac7..c7c6157dad 100644 --- a/usr/src/cmd/prtdiag/sparc/sun4u/Makefile +++ b/usr/src/cmd/prtdiag/sparc/sun4u/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -48,4 +47,4 @@ LINTFLAGS += -u all: $(LIBPRTDIAG) $(PROG) -include $(SRCDIR)/Makefile.targ +include $(SRCDIR)/sparc/Makefile.targ diff --git a/usr/src/cmd/prtdiag/sparc/sun4v/Makefile b/usr/src/cmd/prtdiag/sparc/sun4v/Makefile index 04deb33a76..1da627801a 100644 --- a/usr/src/cmd/prtdiag/sparc/sun4v/Makefile +++ b/usr/src/cmd/prtdiag/sparc/sun4v/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -48,4 +47,4 @@ LINTFLAGS += -u all: $(LIBPRTDIAG) $(PROG) -include $(SRCDIR)/Makefile.targ +include $(SRCDIR)/sparc/Makefile.targ diff --git a/usr/src/cmd/svc/profile/Makefile b/usr/src/cmd/svc/profile/Makefile index d193399b68..18b1e40f87 100644 --- a/usr/src/cmd/svc/profile/Makefile +++ b/usr/src/cmd/svc/profile/Makefile @@ -20,7 +20,7 @@ # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" @@ -50,7 +50,6 @@ PROFILESRCS = \ platform_SUNW,Sun-Fire.xml \ platform_SUNW,Ultra-Enterprise-10000.xml \ platform_SUNW,UltraSPARC-IIi-Netract.xml \ - platform_i86pc.xml \ platform_none.xml \ platform_sun4v.xml diff --git a/usr/src/cmd/svc/profile/platform_i86pc.xml b/usr/src/cmd/svc/profile/platform_i86pc.xml deleted file mode 100644 index 3c196487c1..0000000000 --- a/usr/src/cmd/svc/profile/platform_i86pc.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version='1.0'?> -<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'> -<!-- - Copyright 2005 Sun Microsystems, Inc. All rights reserved. - Use is subject to license terms. - - CDDL HEADER START - - The contents of this file are subject to the terms of the - Common Development and Distribution License, Version 1.0 only - (the "License"). You may not use this file except in compliance - with the License. - - You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - or http://www.opensolaris.org/os/licensing. - See the License for the specific language governing permissions - and limitations under the License. - - When distributing Covered Code, include this CDDL HEADER in each - file and include the License file at usr/src/OPENSOLARIS.LICENSE. - If applicable, add the following below this CDDL HEADER, with the - fields enclosed by brackets "[]" replaced with your own identifying - information: Portions Copyright [yyyy] [name of copyright owner] - - CDDL HEADER END - - ident "%Z%%M% %I% %E% SMI" - - NOTE: This service profile is not editable; its contents will be - overwritten by package or patch operations, including operating - system upgrade. - - Platform service profile for the i86pc platform. ---> -<service_bundle type='profile' name='i86pc'> - <service name='platform/i86pc/eeprom' version='1' type='service'> - <instance name='default' enabled='true'/> - </service> -</service_bundle> |