summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/base/cprintf.cc17
-rw-r--r--src/base/cprintf.hh35
-rw-r--r--src/base/cprintf_formats.hh4
-rw-r--r--src/unittest/cprintftest.cc9
-rw-r--r--util/m5/m5.c317
-rw-r--r--util/mkblankimage.sh219
6 files changed, 471 insertions, 130 deletions
diff --git a/src/base/cprintf.cc b/src/base/cprintf.cc
index d4ba9ca21..5c11e501c 100644
--- a/src/base/cprintf.cc
+++ b/src/base/cprintf.cc
@@ -40,7 +40,7 @@ using namespace std;
namespace cp {
Print::Print(std::ostream &stream, const std::string &format)
- : stream(stream), format(format.c_str()), ptr(format.c_str())
+ : stream(stream), format(format.c_str()), ptr(format.c_str()), cont(false)
{
saved_flags = stream.flags();
saved_fill = stream.fill();
@@ -48,7 +48,7 @@ Print::Print(std::ostream &stream, const std::string &format)
}
Print::Print(std::ostream &stream, const char *format)
- : stream(stream), format(format), ptr(format)
+ : stream(stream), format(format), ptr(format), cont(false)
{
saved_flags = stream.flags();
saved_fill = stream.fill();
@@ -60,8 +60,10 @@ Print::~Print()
}
void
-Print::process(Format &fmt)
+Print::process()
{
+ fmt.clear();
+
size_t len;
while (*ptr) {
@@ -221,8 +223,15 @@ Print::process(Format &fmt)
number = number * 10 + (*ptr - '0');
break;
+ case '*':
+ if (have_precision)
+ fmt.get_precision = true;
+ else
+ fmt.get_width = true;
+ break;
+
case '%':
- assert("we shouldn't get here");
+ assert(false && "we shouldn't get here");
break;
default:
diff --git a/src/base/cprintf.hh b/src/base/cprintf.hh
index cff73a228..2920e210d 100644
--- a/src/base/cprintf.hh
+++ b/src/base/cprintf.hh
@@ -51,24 +51,53 @@ struct Print
std::ostream &stream;
const char *format;
const char *ptr;
+ bool cont;
std::ios::fmtflags saved_flags;
char saved_fill;
int saved_precision;
- void process(Format &fmt);
+ Format fmt;
+ void process();
public:
Print(std::ostream &stream, const std::string &format);
Print(std::ostream &stream, const char *format);
~Print();
+ int
+ get_number(int data)
+ {
+ return data;
+ }
+
+ template <typename T>
+ int
+ get_number(const T& data)
+ {
+ return 0;
+ }
+
template <typename T>
void
add_arg(const T &data)
{
- Format fmt;
- process(fmt);
+ if (!cont)
+ process();
+
+ if (fmt.get_width) {
+ fmt.get_width = false;
+ cont = true;
+ fmt.width = get_number(data);
+ return;
+ }
+
+ if (fmt.get_precision) {
+ fmt.get_precision = false;
+ cont = true;
+ fmt.precision = get_number(data);
+ return;
+ }
switch (fmt.format) {
case Format::character:
diff --git a/src/base/cprintf_formats.hh b/src/base/cprintf_formats.hh
index 75157a540..6bf6b2b66 100644
--- a/src/base/cprintf_formats.hh
+++ b/src/base/cprintf_formats.hh
@@ -50,6 +50,8 @@ struct Format
enum { best, fixed, scientific } float_format;
int precision;
int width;
+ bool get_precision;
+ bool get_width;
Format() { clear(); }
@@ -65,6 +67,8 @@ struct Format
format = none;
precision = -1;
width = 0;
+ get_precision = false;
+ get_width = false;
}
};
diff --git a/src/unittest/cprintftest.cc b/src/unittest/cprintftest.cc
index 1438f194b..6722ce6a3 100644
--- a/src/unittest/cprintftest.cc
+++ b/src/unittest/cprintftest.cc
@@ -167,6 +167,13 @@ main()
cprintf("%c %c\n", 'c', 65);
- cout << '9';
+ cout << '9' << endl;
+
+ cout << endl;
+
+ cprintf("%08.4f\n", 99.99);
+ cprintf("%0*.*f\n", 8, 4, 99.99);
+ cprintf("%07.*f\n", 4, 1.234);
+ cprintf("%#0*x\n", 9, 123412);
return 0;
}
diff --git a/util/m5/m5.c b/util/m5/m5.c
index b103796a8..7747fc0bc 100644
--- a/util/m5/m5.c
+++ b/util/m5/m5.c
@@ -28,7 +28,14 @@
* Authors: Nathan Binkert
*/
+#ifdef linux
+#define _GNU_SOURCE
+#include <sched.h>
+#endif
+
#include <inttypes.h>
+#include <err.h>
+#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -37,154 +44,220 @@
#include "m5op.h"
char *progname;
+char *command = "unspecified";
+void usage();
void
-usage()
+parse_int_args(int argc, char *argv[], uint64_t ints[], int len)
{
- printf("usage: m5 initparam\n"
- " m5 sw99param\n"
- " m5 exit [delay]\n"
- " m5 resetstats [delay [period]]\n"
- " m5 dumpstats [delay [period]]\n"
- " m5 dumpresetstats [delay [period]]\n"
- " m5 checkpoint [delay [period]]\n"
- " m5 readfile\n"
- "\n"
- "All times in nanoseconds!\n");
- exit(1);
-}
+ if (argc > len)
+ usage();
-#define COMPARE(X) (strcmp(X, command) == 0)
+ int i;
+ for (i = 0; i < len; ++i)
+ ints[i] = (i < argc) ? strtoul(argv[i], NULL, 0) : 0;
+}
int
-main(int argc, char *argv[])
+read_file(int dest_fid)
{
- char *command;
- uint64_t param;
- uint64_t arg1 = 0;
- uint64_t arg2 = 0;
+ char buf[256*1024];
+ int offset = 0;
+ int len;
- progname = argv[0];
- if (argc < 2)
+ while ((len = m5_readfile(buf, sizeof(buf), offset)) > 0) {
+ write(dest_fid, buf, len);
+ offset += len;
+ }
+}
+
+void
+do_exit(int argc, char *argv[])
+{
+ if (argc > 1)
usage();
- command = argv[1];
+ m5_exit((argc > 0) ? strtoul(argv[0], NULL, 0) : 0);
+}
- if (COMPARE("initparam")) {
- if (argc != 2)
- usage();
+void
+do_reset_stats(int argc, char *argv[])
+{
+ uint64_t ints[2];
+ parse_int_args(argc, argv, ints, 2);
+ m5_reset_stats(ints[0], ints[1]);
+}
- printf("%ld", m5_initparam());
- return 0;
- }
+void
+do_dump_stats(int argc, char *argv[])
+{
+ uint64_t ints[2];
+ parse_int_args(argc, argv, ints, 2);
+ m5_dump_stats(ints[0], ints[1]);
+}
- if (COMPARE("sw99param")) {
- if (argc != 2)
- usage();
+void
+do_dump_reset_stats(int argc, char *argv[])
+{
+ uint64_t ints[2];
+ parse_int_args(argc, argv, ints, 2);
+ m5_dumpreset_stats(ints[0], ints[1]);
+}
- param = m5_initparam();
- // run-time, rampup-time, rampdown-time, warmup-time, connections
- printf("%d %d %d %d %d", (param >> 48) & 0xfff,
- (param >> 36) & 0xfff, (param >> 24) & 0xfff,
- (param >> 12) & 0xfff, (param >> 0) & 0xfff);
+void
+do_read_file(int argc, char *argv[])
+{
+ if (argc > 0)
+ usage();
- return 0;
- }
+ read_file(STDOUT_FILENO);
+}
- if (COMPARE("exit")) {
- switch (argc) {
- case 3:
- arg1 = strtoul(argv[2], NULL, 0);
- case 2:
- m5_exit(arg1);
- return 0;
-
- default:
- usage();
- }
- }
+void
+do_exec_file(int argc, char *argv[])
+{
+ if (argc > 0)
+ usage();
- if (COMPARE("resetstats")) {
- switch (argc) {
- case 4:
- arg2 = strtoul(argv[3], NULL, 0);
- case 3:
- arg1 = strtoul(argv[2], NULL, 0);
- case 2:
- m5_reset_stats(arg1, arg2);
- return 0;
-
- default:
- usage();
- }
- }
+ const char *destname = "/tmp/execfile";
- if (COMPARE("dumpstats")) {
- switch (argc) {
- case 4:
- arg2 = strtoul(argv[3], NULL, 0);
- case 3:
- arg1 = strtoul(argv[2], NULL, 0);
- case 2:
- m5_dump_stats(arg1, arg2);
- return 0;
-
- default:
- usage();
- }
+ int fid = open(destname, O_WRONLY, 0777);
+ int len = read_file(fid);
+ close(fid);
+ if (len > 0) {
+ execl(destname, "execfile", NULL);
+ err(1, "execl failed!");
}
+}
- if (COMPARE("dumpresetstats")) {
- switch (argc) {
- case 4:
- arg2 = strtoul(argv[3], NULL, 0);
- case 3:
- arg1 = strtoul(argv[2], NULL, 0);
- case 2:
- m5_dumpreset_stats(arg1, arg2);
- return 0;
-
- default:
- usage();
- }
- }
+void
+do_checkpoint(int argc, char *argv[])
+{
+ uint64_t ints[2];
+ parse_int_args(argc, argv, ints, 2);
+ m5_checkpoint(ints[0], ints[1]);
+}
+
+void
+do_load_symbol(int argc, char *argv[])
+{
+ if (argc != 2)
+ usage();
- if (COMPARE("readfile")) {
- char buf[256*1024];
- int offset = 0;
- int len;
+ uint64_t addr = strtoul(argv[0], NULL, 0);
+ char *symbol = argv[1];
+ m5_loadsymbol(addr, symbol);
+}
- if (argc != 2)
- usage();
+void
+do_initparam(int argc, char *argv[])
+{
+ if (argc != 0)
+ usage();
- while ((len = m5_readfile(buf, sizeof(buf), offset)) > 0) {
- write(STDOUT_FILENO, buf, len);
- offset += len;
- }
+
+ printf("%ld", m5_initparam());
+}
- return 0;
- }
+void
+do_sw99param(int argc, char *argv[])
+{
+ if (argc != 0)
+ usage();
+
+ uint64_t param = m5_initparam();
+
+ // run-time, rampup-time, rampdown-time, warmup-time, connections
+ printf("%d %d %d %d %d", (param >> 48) & 0xfff,
+ (param >> 36) & 0xfff, (param >> 24) & 0xfff,
+ (param >> 12) & 0xfff, (param >> 0) & 0xfff);
+}
+
+#ifdef linux
+void
+do_pin(int argc, char *argv[])
+{
+ if (argc < 2)
+ usage();
+
+ cpu_set_t mask;
+ CPU_ZERO(&mask);
+
+ const char *sep = ",";
+ char *target = strtok(argv[0], sep);
+ while (target) {
+ CPU_SET(atoi(target), &mask);
+ target = strtok(NULL, sep);
+ }
+
+ if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) < 0)
+ err(1, "setaffinity");
+
+ execvp(argv[1], &argv[1]);
+ err(1, "execvp failed!");
+}
+#endif
+
+struct MainFunc
+{
+ char *name;
+ void (*func)(int argc, char *argv[]);
+ char *usage;
+};
- if (COMPARE("checkpoint")) {
- switch (argc) {
- case 4:
- arg2 = strtoul(argv[3], NULL, 0);
- case 3:
- arg1 = strtoul(argv[2], NULL, 0);
- case 2:
- m5_checkpoint(arg1, arg2);
- return 0;
-
- default:
- usage();
- }
-
- return 0;
+struct MainFunc mainfuncs[] = {
+ { "exit", do_exit, "[delay]" },
+ { "resetstats", do_reset_stats, "[delay [period]]" },
+ { "dumpstats", do_dump_stats, "[delay [period]]" },
+ { "dumpresetstats", do_dump_reset_stats, "[delay [period]]" },
+ { "readfile", do_read_file, "[filename]" },
+ { "execfile", do_exec_file, "<filename>" },
+ { "checkpoint", do_checkpoint, "[delay [period]]" },
+ { "loadsymbol", do_load_symbol, "<address> <symbol>" },
+ { "initparam", do_initparam, "" },
+ { "sw99param", do_sw99param, "" },
+#ifdef linux
+ { "pin", do_pin, "<cpu> <program> [args ...]" }
+#endif
+};
+int numfuncs = sizeof(mainfuncs) / sizeof(mainfuncs[0]);
+
+void
+usage()
+{
+ int i;
+
+ for (i = 0; i < numfuncs; ++i) {
+ char *header = i ? "" : "usage:";
+ fprintf(stderr, "%-6s %s %s %s\n",
+ header, progname, mainfuncs[i].name, mainfuncs[i].usage);
}
+ fprintf(stderr, "\n");
+ fprintf(stderr, "All times in nanoseconds!\n");
+
+ exit(1);
+}
- if (COMPARE("loadsymbol")) {
- m5_loadsymbol(arg1);
- return 0;
+int
+main(int argc, char *argv[])
+{
+ progname = argv[0];
+ if (argc < 2)
+ usage(1);
+
+ command = argv[1];
+
+ argv += 2;
+ argc -= 2;
+
+ int i;
+ for (i = 0; i < numfuncs; ++i) {
+ if (strcmp(command, mainfuncs[i].name) != 0)
+ continue;
+
+ mainfuncs[i].func(argc, argv);
+ exit(0);
}
- usage();
+
+ usage(1);
}
diff --git a/util/mkblankimage.sh b/util/mkblankimage.sh
new file mode 100644
index 000000000..43a3cca29
--- /dev/null
+++ b/util/mkblankimage.sh
@@ -0,0 +1,219 @@
+#!/bin/sh
+#
+# makeblankimage.sh
+# Make a blank M5 disk image
+#
+
+while getopts "m" OPT
+do
+ case "$OPT" in
+ m) MOUNT_IT=1
+ esac
+done
+
+DEBUG=0
+
+if [ $DEBUG -ne 0 ]; then
+ set -x -e
+ OUTPUT=""
+else
+ OUTPUT="> /dev/null 2>&1"
+fi
+
+abort() {
+ echo $@
+ exec /bin/false
+}
+
+find_prog() {
+ PROG_PATH=`which $1`
+ if [ $? -ne 0 ]; then
+ abort "Unable to find program $1, check your PATH variable"
+ fi
+ echo $PROG_PATH
+}
+
+run_priv() {
+ if [ "$HAVE_SUDO" = "y" ]; then
+ eval $SUDO $@ $OUTPUT
+ else
+ eval $@ $OUTPUT
+ fi
+
+ if [ $? -ne 0 ]; then
+ abort "Failed to run $@ as root"
+ fi
+}
+
+usage() {
+ abort "Usage: $0 [root-path to copy] [extra ownership commands ...]"
+}
+
+# Setup PATH to look in the sbins
+export PATH=$PATH:/sbin:/usr/sbin
+
+# Get all of the programs needed, or exit
+DD=`find_prog dd`
+SFDISK=`find_prog sfdisk`
+LOSETUP=`find_prog losetup`
+SUDO=`find_prog sudo`
+MKE2FS=`find_prog mke2fs`
+MKDIR=`find_prog mkdir`
+MOUNT=`find_prog mount`
+UMOUNT=`find_prog umount`
+WHOAMI=`find_prog whoami`
+CP=`find_prog cp`
+CHOWN=`find_prog chown`
+
+# Prompt for the root password, if needed
+CUR_USER=`$WHOAMI`
+
+if [ $# -ge 1 ]; then
+ if [ ! $MOUNT_IT ]; then
+ ROOT_PATH=$1
+
+ if [ ! -d $ROOT_PATH ]; then
+ usage
+ fi
+ else
+ ROOT_PATH=""
+ fi
+else
+ ROOT_PATH=""
+fi
+
+if [ ! "$CUR_USER" = "root" ]; then
+ echo -n "Do you have sudo access? [y/n] "
+ read HAVE_SUDO
+
+ if [ ! "$HAVE_SUDO" = "y" ]; then
+ abort "You must have sudo access or run this script as root"
+ fi
+fi
+
+echo -n "How large do you want this disk image (in MB): "
+read USER_SIZE_MB
+
+# size in bytes = SIZE_MB * 1024 * 1024
+# size in blocks = SIZE_BYTE / 512
+let BLK_SIZE=$USER_SIZE_MB*1024*2
+
+let MAX_LBA=16383*16*63
+
+if [ $BLK_SIZE -ge $MAX_LBA ]; then
+ CYLS=16383
+ HEADS=16
+ SECTORS=63
+else
+ # Set Sectors
+ if [ $BLK_SIZE -ge 63 ]; then
+ SECTORS=63
+ else
+ SECTORS=$BLK_SIZE
+ fi
+
+ # Set Heads
+ let HEAD_SIZE=$BLK_SIZE/$SECTORS
+
+ if [ $HEAD_SIZE -ge 16 ]; then
+ HEADS=16
+ else
+ HEADS=$BLK_SIZE
+ fi
+
+ # Set Cylinders
+ let SEC_HEAD=$SECTORS*$HEADS
+ let CYLS=$BLK_SIZE/$SEC_HEAD
+fi
+
+# Recalculate number of sectors
+let BLK_SIZE=$CYLS*$HEADS*$SECTORS
+
+# Get the name of the file and directory to build in
+echo -n "What directory would you like to build the image in? "
+read IMAGE_DIR
+
+if [ ! -d $IMAGE_DIR ]; then
+ abort "The directory $IMAGE_DIR does not exist"
+fi
+
+echo -n "What would you like to name the image? "
+read IMAGE_NAME
+
+IMAGE_FILE=$IMAGE_DIR/$IMAGE_NAME
+
+# DD the blank image
+echo
+echo "dd'ing the blank image (this make take a while)..."
+eval $DD if=/dev/zero of=$IMAGE_FILE bs=512 count=$BLK_SIZE $OUTPUT
+if [ $? -ne 0 ]; then
+ abort "Unable to create the blank image $IMAGE_NAME in $IMAGE_DIR"
+fi
+
+# losetup the image with no offset to do the fdisk
+echo
+echo "Binding the image and partitioning..."
+run_priv $LOSETUP /dev/loop0 $IMAGE_FILE
+if [ $? -ne 0 ]; then
+ abort "losetup to /dev/loop0 failed, make sure nothing is setup on loop0 (check by typing 'mount') "
+fi
+
+# fdisk the image
+run_priv $SFDISK --no-reread -D -C $CYLS -H $HEADS -S $SECTORS /dev/loop0 <<EOF
+0,
+;
+;
+;
+EOF
+
+# Un-losetup the image
+run_priv $LOSETUP -d /dev/loop0
+
+# Mount the image with an offset and make the filesystem
+echo
+echo "Remounting image and formatting..."
+let BASE_OFFSET=63*512
+
+run_priv $LOSETUP -o $BASE_OFFSET /dev/loop0 $IMAGE_FILE
+
+run_priv $MKE2FS /dev/loop0
+
+# If a root path was specified then copy the root path into the image
+if [ ! -z "$ROOT_PATH" ]; then
+ echo "Copying root from $ROOT_PATH to image file"
+
+ run_priv $MKDIR -p /tmp/mnt
+
+ run_priv $MOUNT /dev/loop0 /tmp/mnt
+
+ run_priv $CP -a $ROOT_PATH/* /tmp/mnt
+
+ run_priv $CHOWN -R root.root /tmp/mnt
+
+ # run extra permissions while disk is mounted
+ TOPDIR=`pwd`
+ cd /tmp/mnt
+ i=2
+ while [ $i -le $# ]; do
+ run_priv ${!i}
+ let i=i+1
+ done
+ cd $TOPDIR
+
+ run_priv $UMOUNT /tmp/mnt
+fi
+
+run_priv $LOSETUP -d /dev/loop0
+
+
+if [ $MOUNT_IT -eq 1 ]; then
+ run_priv mount -o loop,offset=$BASE_OFFSET $IMAGE_FILE /tmp/mnt
+else
+ echo
+ echo "Disk image creation complete."
+ echo "To mount the image, run the following commands:"
+ echo "# $MOUNT -o loop,offset=$BASE_OFFSET $IMAGE_FILE /mount/point"
+ echo
+ echo "And to unmount the image, run:"
+ echo "# $UMOUNT /mount/point"
+fi;