/*
 * Copyright 1999 Silicon Graphics, Inc. All rights reserved.
 */
#include <lcrash.h>

/*
 * page_cmd() -- Run the 'page' command.
 */
int
page_cmd(command_t *cmd)
{
	int i, page_cnt = 0, mode, first_time = TRUE;
	void  *pp;
	kaddr_t p;
	uint64_t value;

	pp = kl_alloc_block(PAGE_SZ, K_TEMP);
	if (KL_ERROR) {
		return(1);
	}
	if (cmd->nargs == 0) {
		for (i = 0; i < NUM_PHYSPAGES; i++) {
			p = MEM_MAP + (i * PAGE_SZ); 
			GET_BLOCK(p, PAGE_SZ, pp);
			if (KL_ERROR) {
				continue;
			}
			if (first_time || (cmd->flags & (C_FULL|C_NEXT))) {
				page_banner(cmd->ofp, BANNER|SMAJOR);
				first_time = FALSE;
			}
			print_page(p, pp, cmd->flags, cmd->ofp);
			page_cnt++;
		}
	} else {
		for (i = 0; i < cmd->nargs; i++) {
			kl_get_value(cmd->args[i], 
				&mode, NUM_PHYSPAGES, &value);
			if (KL_ERROR) {
				continue;
			}
			if (mode == 1) {
				/* Get the page by page number
				 */
				p = MEM_MAP + (value * PAGE_SZ); 
			} else if (mode == 2) {
				/* Get the page by mem_map_t address
				 */
				p = (kaddr_t)value;
			} else {
				fprintf(KL_ERRORFP, "Invalid page struct "
					"value: %s\n", cmd->args[i]);
				continue;
			}
			if (((p - MEM_MAP)/PAGE_SZ) >= NUM_PHYSPAGES) {
				if (mode == 1) {
					fprintf(KL_ERRORFP, "Invalid page "
						"number : %"FMT64"d\n", value);
				} else {
					fprintf(KL_ERRORFP, "Invalid page "
						"struct address: "
						"0x%"FMTPTR"x\n", p);
				}
				continue;
			}
			GET_BLOCK(p, PAGE_SZ, pp);
			if (KL_ERROR) {
				continue;
			}
			if (first_time || (cmd->flags & (C_FULL|C_NEXT))) {
				page_banner(cmd->ofp, BANNER|SMAJOR);
				first_time = FALSE;
			}
			print_page(p, pp, cmd->flags, cmd->ofp);
			page_cnt++;
		}
	}
	kl_free_block(pp);
	if (page_cnt) {
		page_banner(cmd->ofp, SMAJOR);
	}
	PLURAL("active page struct", page_cnt, cmd->ofp);
	return(0);
}

#define _PAGE_USAGE "[-f] [-n] [-w outfile] [page_list]"

/*
 * page_usage() -- Print the usage string for the 'page' command.
 */
void
page_usage(command_t *cmd)
{
	CMD_USAGE(cmd, _PAGE_USAGE);
}

/*
 * page_help() -- Print the help information for the 'page' command.
 */
void
page_help(command_t *cmd)
{
	CMD_HELP(cmd, _PAGE_USAGE,
        "Display relevant information from the page struct for each entry "
	"in page_list. Entries in page_list can take the form of a page "
	"number (following a '#') or a virtual address of a page struct "
	"in memory. If no entries are specified, an entry for every "
	"page of physical memory will be displayed.");
}

/*
 * page_parse() -- Parse the command line arguments for 'page'.
 */
int
page_parse(command_t *cmd)
{
	if (set_cmd_flags(cmd, (C_FULL|C_NEXT|C_WRITE), 0)) {
		return(1);
	}
	return(0);
}

/*
 * page_complete() -- Complete arguments of 'page' command.
 */
char *
page_complete(command_t *cmd)
{
	char *ret;

	/* complete standard options (for example, -w option) arguments
	 */
	if ((ret = complete_standard_options(cmd)) != NOT_COMPLETED) {
		return(ret);
	}
	fprintf(cmd->ofp, "\n");
	page_usage(cmd);
	return(DRAW_NEW_ENTIRE_LINE);
}
