changeset 441:dc0825c5ca65

Merge branch 'master' into loader Conflicts: cp/Makefile cp/include/loader.h cp/ipl/ipl_rdr.S cp/ipl/ipl_tape.S_in cp/ipl/linker.script cp/ipl/loader.c cp/ipl/loader_asm.S cp/ipl/setmode.S cp/scripts/gen_rdr_ccws.sh cp/scripts/gen_tape_ipl_s.sh loader/eckd.S loader/linker.script loader/loader_asm.S loader/setmode.S sys/ipl/ipl_rdr.S sys/ipl/linker.script sys/ipl/loader_asm.S sys/ipl/setmode.S
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Fri, 18 Jun 2010 20:41:48 -0400
parents b438de5471bc (current diff) 0c8d5e3e591f (diff)
children 3574cdf8705a
files Makefile cp/Makefile cp/scripts/Makefile.commands loader/Makefile sys/.gitignore sys/Makefile sys/cp/Makefile sys/cp/cmd_beginstop.c sys/cp/cmd_display.c sys/cp/cmd_enable.c sys/cp/cmd_helpers.c sys/cp/cmd_logon.c sys/cp/cmd_query.c sys/cp/cmd_set.c sys/cp/cmd_store.c sys/cp/cmd_system.c sys/cp/cmds.c sys/cp/directory.c sys/cp/disassm.c sys/cp/exception.c sys/cp/guest.c sys/cp/guest_ipl.S sys/cp/init.c sys/cp/instruction.c sys/cp/instruction_priv.c sys/cp/intercept.c sys/cp/reset.c sys/cp/splash.c sys/doc/.gitignore sys/doc/PSA.txt sys/doc/ipl.txt sys/doc/memory.txt sys/drivers/3215.c sys/drivers/Makefile sys/drivers/console.c sys/drivers/dasd.c sys/drivers/device.c sys/drivers/vdevice.c sys/fs/Makefile sys/fs/bdev.c sys/fs/edf.c sys/hvf.directory sys/include/atomic.h sys/include/bdev.h sys/include/buddy.h sys/include/channel.h sys/include/compiler.h sys/include/config.h sys/include/console.h sys/include/cp.h sys/include/cpu.h sys/include/dat.h sys/include/device.h sys/include/directory.h sys/include/disassm.h sys/include/ebcdic.h sys/include/edf.h sys/include/interrupt.h sys/include/io.h sys/include/list.h sys/include/magic.h sys/include/mm.h sys/include/mutex.h sys/include/nucleus.h sys/include/page.h sys/include/sched.h sys/include/sie.h sys/include/slab.h sys/include/spinlock.h sys/include/splash.h sys/include/vcpu.h sys/include/vdevice.h sys/mm/Makefile sys/mm/buddy.c sys/mm/dat.c sys/mm/page.c sys/mm/slab.c sys/nucleus/Makefile sys/nucleus/ebcdic.c sys/nucleus/ext.c sys/nucleus/init.c sys/nucleus/int.S sys/nucleus/io.c sys/nucleus/mutex.c sys/nucleus/pgm.c sys/nucleus/printf.c sys/nucleus/sched.c sys/nucleus/spinlock.c sys/nucleus/svc.c sys/scripts/Makefile.build sys/scripts/Makefile.commands sys/scripts/extract-version.sh sys/scripts/gen-dir.sh sys/scripts/gen-docs.sh sys/scripts/linker.script sys/scripts/pad.sh
diffstat 203 files changed, 10846 insertions(+), 10132 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Tue Dec 29 20:04:16 2009 -0500
+++ b/Makefile	Fri Jun 18 20:41:48 2010 -0400
@@ -8,7 +8,7 @@
 
 all:
 	make -C lib
-	make -C sys
+	make -C cp
 	make -C nss/8ball
 	make -C loader
 
@@ -17,7 +17,7 @@
 
 clean:
 	make -C lib clean
-	make -C sys clean
+	make -C cp clean
 	make -C nss/8ball clean
 	make -C loader clean
 	make -C doc/manual clean
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/.gitignore	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,9 @@
+*.o
+*.rto
+ipl/ipl_rdr_ccws.S
+ipl/ipl_tape.S
+shell/directory_structs.c
+hvf
+loader_rdr.bin
+loader_tape.bin
+cscope.out
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/Makefile	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,75 @@
+#
+# HVF: Hobbyist Virtualization Facility
+#
+# (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+#
+# This file is released under the GPLv2.  See the COPYING file for more
+# details.
+#
+
+VERSION=0.16-rc2
+
+AS=$(CROSS_COMPILE)as
+CC=$(CROSS_COMPILE)gcc
+LD=$(CROSS_COMPILE)ld
+OBJCOPY=$(CROSS_COMPILE)objcopy
+
+# By default, be terse
+V=0
+
+DISPLAYVERSION=$(shell ./scripts/extract-version.sh)
+
+MAKEFLAGS += -rR --no-print-directory
+CFLAGS=-DVERSION=\"$(DISPLAYVERSION)\" -g -fno-strict-aliasing -fno-builtin -nostdlib -Wall -m64 -I include/ -I ../include/ -O2 -include ../include/types.h
+NUCLEUSCFLAGS=-include include/nucleus.h
+LDFLAGS=-m elf64_s390
+
+LIBS=clock digest string
+
+export AS CC LD OBJCOPY
+export MAKEFLAGS CFLAGS NUCLEUSCFLAGS LDFLAGS
+
+TOP_DIRS=nucleus/ mm/ fs/ drivers/ shell/
+
+.PHONY: all build clean mrproper cleanup hvfclean tags
+.PHONY: $(TOP_DIRS)
+
+include scripts/Makefile.commands
+
+all: build hvf
+	@echo "Image is `stat -c %s hvf` bytes"
+
+hvf: $(patsubst %/,%/built-in.o,$(TOP_DIRS))
+	$(call link-hvf,$^ $(patsubst %,../lib/%.a,$(LIBS)),$@)
+
+docs:
+	./scripts/gen-docs.sh
+
+clean:
+	@$(MAKE) DIR=nucleus/ cleanup V=$V
+	@$(MAKE) DIR=mm/ cleanup V=$V
+	@$(MAKE) DIR=fs/ cleanup V=$V
+	@$(MAKE) DIR=drivers/ cleanup V=$V
+	@$(MAKE) DIR=shell/ cleanup V=$V
+	$(call clean,hvf)
+	$(call clean,shell/directory_structs.c)
+	$(call rclean,doc/commands)
+
+mrproper: clean
+	$(call clean,cscope.out ctags)
+
+cleanup:
+	$(call clean,$(DIR)*.o)
+
+build: $(TOP_DIRS)
+
+$(TOP_DIRS): %/:
+	@$(MAKE) -f scripts/Makefile.build DIR=$@ V=$V
+
+tags:
+	$(call cscope)
+
+#
+# Include Makefiles from all the top level directories
+#
+include $(patsubst %/,%/Makefile,$(TOP_DIRS))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/doc/.gitignore	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,1 @@
+commands
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/doc/PSA.txt	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,8 @@
+Aside from the architecture defined storage locations in the PSA, HVF uses
+the following addresses for special reasons:
+
+hex	dec	length	reason
+
+ 200	 512	128	interrupt handler GPR storage
+ 280	 640	16	PSW temporary storage
+ 290	 656	8	current pointer
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/doc/ipl.txt	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,94 @@
+This file attempts to describe what happens during IPL.
+
+NOTE: At the time, only IPL from tape and card reader is supported.
+
+1) system reads 24 bytes from the device 
+
+   a) bytes   0-7: new PSW, no interrupts, start address 0x800000 (8MB)
+
+   IPL from tape:
+
+      b) bytes  8-15: CCW to rewind the tape to previous TM
+
+      c) bytes 16-23: CCW to read the entire loader to 0x800000 (8 MB)
+
+   IPL from card reader:
+
+      b) bytes  8-15: CCW to read 80 bytes (containing up to 10 CCWs) to
+         0x18
+
+      c) bytes 16-23: CCW to read 24 bytes (containing up to 3 CCWs) to 0x68
+
+      Command chaining starts reading CCWs from addres 0x18 on. These read
+      the loader to 0x800000 (8 MB)
+
+2) arch mode is changed to z/Arch (see ipl/setmode.S)
+
+3) temporary stack is set up (R15 being the pointer) (see ipl/setmode.S)
+
+4) loader begins to execute: function load_nucleus (see ipl/loader.c)
+
+   NOTE: loader.c use static inlines extensively, and thefore stack usage is
+   minimal
+
+   a) If the IPL was from a tape, a CCW is issues to seek to the next TM
+
+   b) nucleus is read from tape to 0x400000 (4 MB)
+
+      NOTE: the data at 4MB just read is a 64-bit s390 ELF binary with Linux
+      ABI bits
+
+      i)   addition CCW address is set in the ORB
+
+      ii)  __readnucleus() is called; this function is implemented in
+           assembly (see ipl/loader_asm.S)
+
+      iii) IO interrupt handler is set up (implemented in asm, see
+           ipl/loader_asm.S)
+
+      iv)  ORB is sent to the subchannel
+
+      v)   interrupts are enabled
+
+      vi)  a new PSW with wait state bit set is loaded
+
+      vii) on IO interrupt
+
+           1) TSCH is issued to fill in a IRB
+
+           2) magic value (ORB int param) is checked
+
+	   3) Device End flag is checked in the IRB
+
+	      NOTE: more checks should be performed here
+
+	   4) If the device end flag is set, return to code that set up the
+              interrupt handler
+
+	   5) otherwise, load up the old IO PSW (the one with the wait
+              state)
+
+      viii)return to caller (back to ipl/loader.c)
+
+   c) verify ELF header magic number, machine, type, etc. values
+
+   d) traverse the section headers & copy data to final destination
+
+      i)   if the section type is PROGBITS (data stored in the ELF), copy
+           the data from it's temporary location to the desired location
+	   (destination, offset within file, and length are all stored in
+	   the section header) - this takes care of .text, .data, and
+	   .rodata sections
+
+      ii)  if the section type is NOBITS (uninitialized storage, e.g.,
+           .bss), do nothing, just assume that the location is a valid
+	   location in memory
+
+      iii) skip any other section types
+
+      NOTE: SYMTAB and STRTAB section types should be copied to a useful
+      location to allow for symbols to be looked up during nucleus execution
+
+   e) jump to the entry point as indicated by the ELF header
+
+At this point, the nucleus is executing.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/doc/memory.txt	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,62 @@
+Physical locations:
+
+-------------------  (2^64)-1  --
+|                 |              \
+|                 |               |
+         .                        |
+         .                        \
+         .                         >    Generic pages
+         .                        /
+         .                        |
+|                 |               |
+|                 |              /
+|-----------------|  f(memsize)--
+|                 |              \
+|                 |               |
+         .                        \
+         .                         >    struct page array (see below)
+         .                        /
+|                 |               |
+|                 |              /
+|-----------------|  4M        --
+|                 |              \
+|                 |               |
+         .                        \
+         .                         >    OS .text, .data, .rodata, .bss
+         .                        /
+|                 |               |
+|                 |              /
+|-----------------|  1M        --
+|                 |              \
+|                 |               |
+         .                        |
+         .                        |
+         .                        \
+|                 |                >    PSA for each CPU
+|                 |               /
+|-----------------|  8k           |
+|                 |               |
+|       PSA       |               |
+|                 |              /
+-------------------  0         --
+
+
+0 - 1MB:
+	Divided into up to 128 8KB chunks; nth chunk is nth CPU's PSA
+	(mapping done via the prefix register).
+
+1MB - 4MB:
+	OS .text
+	OS .data
+	OS .rodata
+	OS .bss
+
+4MB - (4MB + roundup((memsize >> PAGE_SIZE) * sizeof(struct page))):
+	This is an array of struct page entries for each page in the system.
+	The size varies based on the amount of memory installed.
+
+?? - (2^64)-1:
+	Generic pages; used for nucleus & process data
+
+	These pages are managed by the buddy allocator.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/drivers/3215.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,28 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <device.h>
+#include <console.h>
+#include <list.h>
+#include <sched.h>
+#include <directory.h>
+
+static struct device_type d3215 = {
+	.types		= LIST_HEAD_INIT(d3215.types),
+	.reg		= NULL,
+	.interrupt	= NULL,
+	.enable		= console_enable,
+	.snprintf	= NULL,
+	.type		= 0x3215,
+	.model		= 0,
+};
+
+int register_driver_3215(void)
+{
+	return register_device_type(&d3215);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/drivers/Makefile	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,1 @@
+objs-drivers := device.o console.o 3215.o dasd.o vdevice.o
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/drivers/console.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,394 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <console.h>
+#include <slab.h>
+#include <sched.h>
+#include <directory.h>
+#include <splash.h>
+#include <vsprintf.h>
+
+/*
+ * List of all consoles on the system
+ */
+static LIST_HEAD(consoles);
+static spinlock_t consoles_lock = SPIN_LOCK_UNLOCKED;
+
+static int read_io_int_handler(struct device *dev, struct io_op *ioop, struct irb *irb)
+{
+	struct console_line *cline;
+	struct ccw *ccw;
+	void *ptr;
+
+	/* Device End is set, we're done */
+	if (!(irb->scsw.dev_status & 0x04)) {
+		ioop->err = -EAGAIN;
+		return 0;
+	}
+
+	ccw = (struct ccw*) (u64) ioop->orb.addr;
+	ptr = (void*) (u64) ccw->addr;
+	cline = container_of(ptr, struct console_line, buf);
+
+	cline->len = strnlen((char*) cline->buf, CON_MAX_LINE_LEN-1);
+	cline->state = CON_STATE_IO;
+
+	ioop->err = 0;
+	return 0;
+}
+
+static void do_issue_read(struct console *con, struct io_op *ioop, struct ccw *ccws)
+{
+	struct console_line *cline;
+	int found;
+
+	found = 0;
+
+	atomic_dec(&con->dev->attention);
+
+	spin_lock(&con->lock);
+	list_for_each_entry(cline, &con->read_lines, lines) {
+		if (cline->state != CON_STATE_FREE)
+			continue;
+
+		cline->state = CON_STATE_PENDING;
+		found = 1;
+		break;
+	}
+
+	if (!found) {
+		/*
+		 * No unused console lines, time to allocate a new one
+		 */
+		cline = malloc(CON_LINE_ALLOC_SIZE, ZONE_NORMAL);
+		BUG_ON(!cline);
+
+		cline->state = CON_STATE_PENDING;
+		list_add_tail(&cline->lines, &con->read_lines);
+	}
+	spin_unlock(&con->lock);
+
+	/* clear the buffer to allow strlen on the result */
+	memset(cline->buf, 0, CON_MAX_LINE_LEN);
+
+	memset(ccws, 0, sizeof(struct ccw));
+
+	ccws[0].addr  = ADDR31(cline->buf);
+	ccws[0].count = CON_MAX_LINE_LEN - 1;
+	ccws[0].cmd   = 0x0a;
+	ccws[0].flags = CCW_FLAG_SLI;
+
+	memset(&ioop->orb, 0, sizeof(struct orb));
+	ioop->orb.lpm  = 0xff;
+	ioop->orb.addr = ADDR31(ccws);
+	ioop->orb.f    = 1;
+
+	ioop->handler = read_io_int_handler;
+	ioop->dtor = NULL;
+
+	submit_io(con->dev, ioop, CAN_SLEEP);
+}
+
+/**
+ * console_flusher - iterates over a console's buffers and initiates the IO
+ */
+static int console_flusher(void *data)
+{
+	struct console *con = data;
+	struct console_line *cline;
+	int free_count;
+	int ccw_count;
+
+	/* needed for the IO */
+	struct io_op ioop;
+	struct ccw ccws[CON_MAX_FLUSH_LINES];
+
+	for(;;) {
+		if (atomic_read(&con->dev->attention))
+			do_issue_read(con, &ioop, ccws);
+
+		spin_lock(&con->lock);
+
+		/*
+		 * free all the lines we just finished the IO for
+		 */
+		free_count = 0;
+		list_for_each_entry(cline, &con->write_lines, lines) {
+			if (cline->state != CON_STATE_IO)
+				continue;
+
+			cline->state = CON_STATE_FREE;
+			free_count++;
+
+			if (free_count > CON_MAX_FREE_LINES) {
+				list_del(&cline->lines);
+				free(cline);
+			}
+		}
+
+		/*
+		 * find at most CON_MAX_FLUSH_LINES of CON_STATE_PENDING
+		 * lines and shove necessary information into the right
+		 * CCW
+		 */
+		ccw_count = 0;
+		list_for_each_entry(cline, &con->write_lines, lines) {
+			if (ccw_count >= CON_MAX_FLUSH_LINES)
+				break;
+
+			if (cline->state != CON_STATE_PENDING)
+				continue;
+
+			cline->state = CON_STATE_IO;
+
+			ccws[ccw_count].addr = ADDR31(cline->buf);
+			ccws[ccw_count].count = cline->len;
+			ccws[ccw_count].cmd   = 0x01; /* write */
+			ccws[ccw_count].flags = CCW_FLAG_CC | CCW_FLAG_SLI;
+
+			ccw_count++;
+		}
+
+		/*
+		 * We don't need the lock anymore
+		 */
+		spin_unlock(&con->lock);
+
+		/*
+		 * Anything to do?
+		 */
+		if (!ccw_count) {
+			schedule();
+			continue;
+		}
+
+		/*
+		 * Clear Command-Chaining on the last CCW
+		 */
+		ccws[ccw_count-1].flags &= ~CCW_FLAG_CC;
+
+		/*
+		 * Now, set up the ORB and CCW
+		 */
+		memset(&ioop.orb, 0, sizeof(struct orb));
+		ioop.orb.lpm = 0xff;
+		ioop.orb.addr = ADDR31(ccws);
+		ioop.orb.f = 1;		/* format 1 CCW */
+
+		/*
+		 * Set up the operation handler pointers, and start the IO
+		 */
+		ioop.handler = NULL;
+		ioop.dtor = NULL;
+
+		submit_io(con->dev, &ioop, CAN_SLEEP);
+	}
+
+	return 0;
+}
+
+/**
+ * register_console - generic device registration callback
+ * @dev:	console device to register
+ */
+static int register_console(struct device *dev)
+{
+	struct console *con;
+	struct console_line *cline;
+
+	dev_get(dev);
+
+	con = malloc(sizeof(struct console), ZONE_NORMAL);
+	BUG_ON(!con);
+
+	con->sys    = NULL;
+	con->dev    = dev;
+	con->lock   = SPIN_LOCK_UNLOCKED;
+	INIT_LIST_HEAD(&con->write_lines);
+	INIT_LIST_HEAD(&con->read_lines);
+
+	/*
+	 * alloc one read-line
+	 */
+	cline = malloc(CON_LINE_ALLOC_SIZE, ZONE_NORMAL);
+	BUG_ON(!cline);
+	cline->state = CON_STATE_FREE;
+	list_add(&cline->lines, &con->read_lines);
+
+	spin_lock(&consoles_lock);
+	list_add_tail(&con->consoles, &consoles);
+	spin_unlock(&consoles_lock);
+
+	return 0;
+}
+
+static void print_splash(struct console *con)
+{
+	int i;
+
+	for(i = 0; splash[i]; i++)
+		con_printf(con, splash[i]);
+
+	con_printf(con, "HVF VERSION " VERSION "\n\n");
+}
+
+struct console* start_oper_console(void)
+{
+	struct device *dev;
+
+	/*
+	 * We only start the operator console
+	 */
+
+	dev = find_device_by_ccuu(OPER_CONSOLE_CCUU);
+	BUG_ON(IS_ERR(dev));
+
+	return console_enable(dev);
+}
+
+void* console_enable(struct device *dev)
+{
+	char name[TASK_NAME_LEN+1];
+	struct console *con;
+
+	con = find_console(dev);
+	if (!IS_ERR(con))
+		return con;
+
+	if (register_console(dev))
+		return ERR_PTR(-ENOMEM);
+
+	/* try again, this time, we should always find it! */
+	con = find_console(dev);
+	if (IS_ERR(con))
+		return con;
+
+	atomic_inc(&con->dev->in_use);
+
+	snprintf(name, TASK_NAME_LEN, "%05X-conflsh", con->dev->sch);
+
+	create_task(name, console_flusher, con);
+
+	print_splash(con);
+
+	return con;
+}
+
+int con_read_pending(struct console *con)
+{
+	struct console_line *cline;
+	int ret = 0;
+
+	spin_lock(&con->lock);
+
+	list_for_each_entry(cline, &con->read_lines, lines) {
+		if (cline->state == CON_STATE_IO) {
+			ret = 1;
+			break;
+		}
+	}
+
+	spin_unlock(&con->lock);
+
+	return ret;
+}
+
+int con_read(struct console *con, u8 *buf, int size)
+{
+	struct console_line *cline;
+	int len;
+
+	spin_lock(&con->lock);
+
+	list_for_each_entry(cline, &con->read_lines, lines) {
+		if (cline->state == CON_STATE_IO)
+			goto found;
+	}
+
+	spin_unlock(&con->lock);
+
+	return -1;
+
+found:
+	len = (size-1 < cline->len) ? size-1 : cline->len;
+
+	memcpy(buf, cline->buf, len);
+	buf[len] = '\0';
+
+	cline->state = CON_STATE_FREE;
+
+	spin_unlock(&con->lock);
+
+	return len;
+}
+
+int con_write(struct console *con, u8 *buf, int len)
+{
+	int bytes = 0;
+	struct console_line *cline;
+
+	spin_lock(&con->lock);
+
+	list_for_each_entry(cline, &con->write_lines, lines) {
+		if (cline->state == CON_STATE_FREE)
+			goto found;
+	}
+
+	/* None found, can we allocate a new one? */
+	cline = malloc(CON_LINE_ALLOC_SIZE, ZONE_NORMAL);
+	if (!cline)
+		goto abort;
+
+	list_add_tail(&cline->lines, &con->write_lines);
+
+found:
+	cline->state = CON_STATE_PENDING;
+
+	cline->len = (len < CON_MAX_LINE_LEN) ?  len : CON_MAX_LINE_LEN;
+	memcpy(cline->buf, buf, cline->len);
+
+	/*
+	 * All done here. The async thread will pick up the line of text,
+	 * and issue the IO.
+	 */
+
+abort:
+	spin_unlock(&con->lock);
+
+	return bytes;
+}
+
+void for_each_console(void (*f)(struct console *con))
+{
+	struct console *con;
+
+	if (!f)
+		return;
+
+	spin_lock(&consoles_lock);
+	list_for_each_entry(con, &consoles, consoles)
+		f(con);
+	spin_unlock(&consoles_lock);
+}
+
+struct console* find_console(struct device *dev)
+{
+	struct console *con;
+
+	if (!dev)
+		return ERR_PTR(-ENOENT);
+
+	spin_lock(&consoles_lock);
+	list_for_each_entry(con, &consoles, consoles) {
+		if (con->dev == dev)
+			goto found;
+	}
+	con = ERR_PTR(-ENOENT);
+found:
+	spin_unlock(&consoles_lock);
+	return con;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/drivers/dasd.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,283 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <device.h>
+#include <console.h>
+#include <list.h>
+#include <io.h>
+#include <sched.h>
+#include <vsprintf.h>
+
+static int d3390_snprintf(struct device *dev, char* buf, int len)
+{
+	return snprintf(buf, len, "%10d CYL ", dev->eckd.cyls);
+}
+
+static inline unsigned int ceil_quot(unsigned int d1, unsigned int d2)
+{
+        return (d1 + (d2 - 1)) / d2;
+}
+
+static inline int d3390_recs_per_track(int kl, int dl)
+{
+	int dn, kn;
+
+	dn = ceil_quot(dl + 6, 232) + 1;
+	if (kl) {
+		kn = ceil_quot(kl + 6, 232) + 1;
+		return 1729 / (10 + 9 + ceil_quot(kl + 6 * kn, 34) +
+			       9 + ceil_quot(dl + 6 * dn, 34));
+	} else
+		return 1729 / (10 + 9 + ceil_quot(dl + 6 * dn, 34));
+}
+
+static int d3390_reg(struct device *dev)
+{
+	struct io_op ioop;
+	struct ccw ccw;
+	int ret;
+	u8 buf[64];
+
+	switch(dev->model) {
+		case 0x02: /* 3390, 3390-1 */
+		case 0x06: /* 3390-2 */
+		case 0x0a: /* 3390-3 */
+		case 0x0c: /* 3390-9, 3390-27, 3390-J, 3390-54, 3390-JJ */
+			break;
+		default:
+			return -ENOENT;
+	}
+
+	/*
+	 * Set up IO op for Read Device Characteristics
+	 */
+	ioop.handler = NULL;
+	ioop.dtor = NULL;
+
+	memset(&ioop.orb, 0, sizeof(struct orb));
+	ioop.orb.lpm = 0xff;
+	ioop.orb.addr = ADDR31(&ccw);
+	ioop.orb.f = 1;
+
+	memset(&ccw, 0, sizeof(struct ccw));
+	ccw.cmd = 0x64; /* RDC */
+	ccw.flags = CCW_FLAG_SLI;
+	ccw.count = 64;
+	ccw.addr = ADDR31(buf);
+
+	/*
+	 * issue RDC
+	 */
+	ret = submit_io(dev, &ioop, CAN_LOOP);
+	if (ret)
+		return ret;
+
+	dev->eckd.cyls    = (buf[12] << 8) |
+		buf[13];
+	dev->eckd.tracks  = (buf[14] << 8) |
+		buf[15];
+	dev->eckd.recs    = d3390_recs_per_track(0, 4096);
+	dev->eckd.sectors = buf[16];
+	dev->eckd.len     = (buf[18] << 8) |
+		buf[19];
+
+	dev->eckd.formula = buf[22];
+	if (dev->eckd.formula == 1) {
+		dev->eckd.f1 = buf[23];
+		dev->eckd.f2 = (buf[24] << 8) |
+			buf[25];
+		dev->eckd.f3 = (buf[26] << 8) |
+			buf[27];
+		dev->eckd.f4 = 0;
+		dev->eckd.f5 = 0;
+	} else if (dev->eckd.formula == 2) {
+		dev->eckd.f1 = buf[23];
+		dev->eckd.f2 = buf[24];
+		dev->eckd.f3 = buf[25];
+		dev->eckd.f4 = buf[26];
+		dev->eckd.f5 = buf[27];
+	} else
+		return -EINVAL;
+
+	return 0;
+}
+
+static int d3390_read(struct device *dev, u8 *buf, int lba)
+{
+	struct io_op ioop;
+	struct ccw ccw[4];
+	u8 seek_data[6];
+	u8 search_data[5];
+	int ret;
+
+	u16 cc, hh, r;
+	int rpt = dev->eckd.recs;
+	int rpc = dev->eckd.tracks * rpt;
+
+	if (lba < 1)
+		return -EINVAL;
+
+	lba--;
+	cc = lba / rpc;
+	hh = (lba % rpc) / rpt;
+	r = (lba % rpc) % rpt;
+	r++;
+
+	/*
+	 * Set up IO op
+	 */
+	ioop.handler = NULL;
+	ioop.dtor = NULL;
+
+	memset(&ioop.orb, 0, sizeof(struct orb));
+	ioop.orb.lpm = 0xff;
+	ioop.orb.addr = ADDR31(ccw);
+	ioop.orb.f = 1;
+
+	memset(ccw, 0, sizeof(ccw));
+
+	/* SEEK */
+	ccw[0].cmd = 0x07;
+	ccw[0].flags = CCW_FLAG_CC | CCW_FLAG_SLI;
+	ccw[0].count = 6;
+	ccw[0].addr = ADDR31(seek_data);
+
+	seek_data[0] = 0;		/* zero */
+	seek_data[1] = 0;		/* zero */
+	seek_data[2] = cc >> 8;		/* Cc */
+	seek_data[3] = cc & 0xff;	/* cC */
+	seek_data[4] = hh >> 8;		/* Hh */
+	seek_data[5] = hh & 0xff;	/* hH */
+
+	/* SEARCH */
+	ccw[1].cmd = 0x31;
+	ccw[1].flags = CCW_FLAG_CC | CCW_FLAG_SLI;
+	ccw[1].count = 5;
+	ccw[1].addr = ADDR31(search_data);
+
+	search_data[0] = cc >> 8;
+	search_data[1] = cc & 0xff;
+	search_data[2] = hh >> 8;
+	search_data[3] = hh & 0xff;
+	search_data[4] = r;
+
+	/* TIC */
+	ccw[2].cmd = 0x08;
+	ccw[2].flags = 0;
+	ccw[2].count = 0;
+	ccw[2].addr = ADDR31(&ccw[1]);
+
+	/* READ DATA */
+	ccw[3].cmd = 0x86;
+	ccw[3].flags = 0;
+	ccw[3].count = 4096;
+	ccw[3].addr = ADDR31(buf);
+
+	/*
+	 * issue IO
+	 */
+	ret = submit_io(dev, &ioop, CAN_SLEEP);
+	return ret;
+}
+
+static struct device_type d3390 = {
+	.types		= LIST_HEAD_INIT(d3390.types),
+	.reg		= d3390_reg,
+	.interrupt	= NULL,
+	.enable		= NULL,
+	.snprintf	= d3390_snprintf,
+
+	.read		= d3390_read,
+
+	.type		= 0x3390,
+	.all_models	= 1,
+};
+
+/******************************************************************************/
+
+static int d9336_snprintf(struct device *dev, char* buf, int len)
+{
+	return snprintf(buf, len, "%10d BLK ", dev->fba.blks);
+}
+
+static int d9336_reg(struct device *dev)
+{
+	struct io_op ioop;
+	struct ccw ccw;
+	int ret;
+	u8 buf[64];
+
+	switch(dev->model) {
+		case 0x00: /* 9336-10 */
+		case 0x10: /* 9336-20 */
+			break;
+		default:
+			return -ENOENT;
+	}
+
+	/*
+	 * Set up IO op for Read Device Characteristics
+	 */
+	ioop.handler = NULL;
+	ioop.dtor = NULL;
+
+	memset(&ioop.orb, 0, sizeof(struct orb));
+	ioop.orb.lpm = 0xff;
+	ioop.orb.addr = ADDR31(&ccw);
+	ioop.orb.f = 1;
+
+	memset(&ccw, 0, sizeof(struct ccw));
+	ccw.cmd = 0x64; /* RDC */
+	ccw.flags = CCW_FLAG_SLI;
+	ccw.count = 64;
+	ccw.addr = ADDR31(buf);
+
+	/*
+	 * issue RDC
+	 */
+	ret = submit_io(dev, &ioop, CAN_LOOP);
+	if (ret)
+		return ret;
+
+	dev->fba.blk_size = (buf[4] << 8) | buf[5];
+	dev->fba.bpg = (buf[6] << 24)  |
+		(buf[7] << 16)  |
+		(buf[8] << 8)   |
+		buf[9];
+	dev->fba.bpp = (buf[10] << 24) |
+		(buf[11] << 16) |
+		(buf[12] << 8)  |
+		buf[13];
+	dev->fba.blks= (buf[14] << 24) |
+		(buf[15] << 16) |
+		(buf[16] << 8)  |
+		buf[17];
+
+	return 0;
+}
+
+static struct device_type d9336 = {
+	.types		= LIST_HEAD_INIT(d9336.types),
+	.reg		= d9336_reg,
+	.interrupt	= NULL,
+	.enable		= NULL,
+	.snprintf	= d9336_snprintf,
+	.type		= 0x9336,
+	.all_models	= 1,
+};
+
+int register_driver_dasd(void)
+{
+	int ret;
+
+	ret = register_device_type(&d3390);
+	if (ret)
+		return ret;
+
+	return register_device_type(&d9336);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/drivers/device.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,372 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <list.h>
+#include <channel.h>
+#include <io.h>
+#include <slab.h>
+#include <device.h>
+#include <spinlock.h>
+#include <sched.h>
+
+struct senseid_struct {
+	u8 __reserved;
+	u16 cu_type;
+	u8 cu_model;
+	u16 dev_type;
+	u8 dev_model;
+} __attribute__((packed));
+
+struct static_device {
+	u16 dev_num;
+	struct senseid_struct sense;
+};
+
+#define END_OF_STATIC_DEV_LIST	0xffff
+
+/*
+ * This defines staticly-configured devices - ugly but necessary for devices
+ * that fail to identify themseleves via Sense-ID
+ */
+static struct static_device static_device_list[] = {
+	{ .dev_num = 0x0009, .sense = { .dev_type = 0x3215, .dev_model = 0 } },
+	{ .dev_num = END_OF_STATIC_DEV_LIST },
+};
+
+/*
+ * We need this device temporarily because submit_io & friends assume that
+ * the device that's doing IO is on the device list. Unfortunately, that
+ * isn't the case during IO device scanning. We register this device type,
+ * and each device temporarily during the scan to make submit_io & friends
+ * happy. When we're done scanning, we unregister this type.
+ */
+static struct device_type __fake_dev_type = {
+	.types		= LIST_HEAD_INIT(__fake_dev_type.types),
+	.reg		= NULL,
+	.interrupt	= NULL,
+	.snprintf	= NULL,
+	.type		= 0,
+	.model		= 0,
+};
+
+static LIST_HEAD(device_types);
+static spinlock_t dev_types_lock;
+
+static LIST_HEAD(devices);
+static spinlock_t devs_lock;
+
+static void unregister_device_type(struct device_type *type)
+{
+	spin_lock(&dev_types_lock);
+	list_del(&type->types);
+	spin_unlock(&dev_types_lock);
+}
+
+/**
+ * register_device_type - register a new device type/model
+ * @dev:	device type to register
+ */
+int register_device_type(struct device_type *dev)
+{
+	struct device_type *entry;
+
+	spin_lock(&dev_types_lock);
+
+	list_for_each_entry(entry, &device_types, types) {
+		if (dev == entry ||
+		    (dev->type == entry->type && dev->model == entry->model)) {
+			spin_unlock(&dev_types_lock);
+			return -EEXIST;
+		}
+	}
+
+	list_add_tail(&dev->types, &device_types);
+
+	spin_unlock(&dev_types_lock);
+
+	return 0;
+}
+
+/**
+ * find_device_by_ccuu - find device struct by ccuu
+ * @ccuu:	device ccuu to find
+ */
+struct device *find_device_by_ccuu(u16 ccuu)
+{
+	struct device *dev;
+
+	spin_lock(&devs_lock);
+
+	list_for_each_entry(dev, &devices, devices) {
+		if (dev->ccuu == ccuu) {
+			dev_get(dev);
+			spin_unlock(&devs_lock);
+			return dev;
+		}
+	}
+
+	spin_unlock(&devs_lock);
+
+	return ERR_PTR(-ENOENT);
+}
+
+/**
+ * find_device_by_sch - find device struct by subchannel number
+ * @sch:	device subchannel
+ */
+struct device *find_device_by_sch(u32 sch)
+{
+	struct device *dev;
+
+	spin_lock(&devs_lock);
+
+	list_for_each_entry(dev, &devices, devices) {
+		if (dev->sch == sch) {
+			dev_get(dev);
+			spin_unlock(&devs_lock);
+			return dev;
+		}
+	}
+
+	spin_unlock(&devs_lock);
+
+	return ERR_PTR(-ENOENT);
+}
+
+/**
+ * find_device_by_type - find device struct by type/model
+ * @type:	device type to find
+ * @model:	device model to find
+ */
+struct device *find_device_by_type(u16 type, u8 model)
+{
+	struct device *dev;
+
+	spin_lock(&devs_lock);
+
+	list_for_each_entry(dev, &devices, devices) {
+		if (dev->type == type &&
+		    dev->model == model) {
+			dev_get(dev);
+			spin_unlock(&devs_lock);
+			return dev;
+		}
+	}
+
+	spin_unlock(&devs_lock);
+
+	return ERR_PTR(-ENOENT);
+}
+
+/**
+ * __register_device - helper to register a device
+ * @dev:	device to register
+ * @remove:	remove the device from the list first
+ */
+static int __register_device(struct device *dev, int remove)
+{
+	struct device_type *type;
+	int err = 0;
+
+	spin_double_lock(&devs_lock, &dev_types_lock);
+
+	list_for_each_entry(type, &device_types, types) {
+		if (type->type == dev->type &&
+		    (type->all_models ||
+		     type->model == dev->model))
+			goto found;
+	}
+
+	err = -ENOENT;
+	type = NULL;
+
+found:
+	spin_double_unlock(&devs_lock, &dev_types_lock);
+
+	atomic_set(&dev->refcnt, 1);
+	atomic_set(&dev->in_use, 0);
+
+	dev->dev = type;
+
+	if (type && type->reg) {
+		err = type->reg(dev);
+
+		if (err)
+			dev->dev = NULL;
+	}
+
+	spin_double_lock(&devs_lock, &dev_types_lock);
+	if (remove)
+		list_del(&dev->devices);
+	list_add_tail(&dev->devices, &devices);
+	spin_double_unlock(&devs_lock, &dev_types_lock);
+
+	return err;
+}
+
+static int do_sense_id(struct device *dev, u16 dev_num, struct senseid_struct *buf)
+{
+	struct io_op ioop;
+	struct ccw ccw;
+	int ret;
+	int idx;
+	struct static_device *sdev;
+
+	/*
+	 * Check static configuration; if device is found (by device
+	 * number), use that information instead of issuing sense-id
+	 */
+	for(idx = 0; sdev = &static_device_list[idx],
+	    sdev->dev_num != END_OF_STATIC_DEV_LIST; idx++) {
+		if (sdev->dev_num == dev_num) {
+			memcpy(buf, &sdev->sense, sizeof(struct senseid_struct));
+			return 0;
+		}
+	}
+
+	/*
+	 * Set up IO op for Sense-ID
+	 */
+	ioop.handler = NULL;
+	ioop.dtor = NULL;
+
+	memset(&ioop.orb, 0, sizeof(struct orb));
+	ioop.orb.lpm = 0xff;
+	ioop.orb.addr = ADDR31(&ccw);
+	ioop.orb.f = 1;
+
+	memset(&ccw, 0, sizeof(struct ccw));
+	ccw.cmd = 0xe4; /* Sense-ID */
+	ccw.flags = CCW_FLAG_SLI;
+	ccw.count = sizeof(struct senseid_struct);
+	ccw.addr = ADDR31(buf);
+
+	/*
+	 * issue SENSE-ID
+	 */
+	ret = submit_io(dev, &ioop, CAN_LOOP);
+	BUG_ON(ret);
+
+	return ioop.err;
+}
+
+/*
+ * Scan all subchannel ids, and register each device
+ */
+void scan_devices(void)
+{
+	struct schib schib;
+	struct device *dev = NULL;
+	struct senseid_struct buf;
+	u32 sch;
+	int ret;
+
+	BUG_ON(register_device_type(&__fake_dev_type));
+
+	memset(&schib, 0, sizeof(struct schib));
+
+	/*
+	 * For each possible subchannel id...
+	 */
+	for(sch = 0x10000; sch <= 0x1ffff; sch++) {
+		/*
+		 * ...call store subchannel, to find out whether or not
+		 * there is a device
+		 */
+		if (store_sch(sch, &schib))
+			continue;
+
+		if (!schib.pmcw.v)
+			continue;
+
+		/*
+		 * The following code tries to take the following steps:
+		 *   - alloc device struct
+		 *   - enable the subchannel
+		 *   - MSCH
+		 *   - issue SENSE-ID IO op & wait for completion
+		 *   - register device with apropriate subsystem
+		 */
+
+		if (!dev) {
+			dev = malloc(sizeof(struct device), ZONE_NORMAL);
+
+			/*
+			 * if we failed to allocate memory, there's not much we can
+			 * do
+			 */
+			BUG_ON(!dev);
+
+			atomic_set(&dev->attention, 0);
+			INIT_LIST_HEAD(&dev->q_out);
+			dev->dev = &__fake_dev_type;
+		}
+
+		schib.pmcw.e = 1;
+
+		if (modify_sch(sch, &schib))
+			continue;
+
+		dev->sch   = sch;
+		BUG_ON(__register_device(dev, 0));
+		BUG_ON(dev->dev != &__fake_dev_type);
+
+		/*
+		 * Find out what the device is - whichever way is necessary
+		 */
+		ret = do_sense_id(dev, schib.pmcw.dev_num, &buf);
+
+		if (ret)
+			continue;
+
+		dev->type  = buf.dev_type;
+		dev->model = buf.dev_model;
+		dev->ccuu  = schib.pmcw.dev_num;
+
+		/* __register_device will remove the fake entry! */
+		if (__register_device(dev, 1)) {
+			/*
+			 * error registering ... the device struct MUST NOT
+			 * be freed as it has been added onto the devices
+			 * list. All that needs to be done is to reset the
+			 * enabled bit.
+			 */
+			schib.pmcw.e = 0;
+
+			/* msch could fail, but it shouldn't be fatal */
+			modify_sch(sch, &schib);
+		}
+
+		/* to prevent a valid device struct from being free'd */
+		dev = NULL;
+	}
+
+	unregister_device_type(&__fake_dev_type);
+
+	free(dev);
+}
+
+void list_devices(struct console *con, void (*f)(struct console*, struct device*))
+{
+	struct device *dev;
+
+	spin_lock(&devs_lock);
+
+	list_for_each_entry(dev, &devices, devices) {
+		dev_get(dev);
+		f(con, dev);
+		dev_put(dev);
+	}
+
+	spin_unlock(&devs_lock);
+}
+
+void register_drivers(void)
+{
+	register_driver_3215();
+	register_driver_dasd();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/drivers/vdevice.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,85 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <slab.h>
+#include <list.h>
+#include <vdevice.h>
+
+static int __setup_vdev_ded(struct virt_sys *sys,
+			    struct directory_vdev *dirdev,
+			    struct virt_device *vdev)
+{
+	struct device *rdev;
+
+	rdev = find_device_by_ccuu(dirdev->u.dedicate.rdev);
+	if (IS_ERR(rdev))
+		return PTR_ERR(rdev);
+
+	atomic_inc(&rdev->in_use);
+
+	vdev->u.dedicate.rdev = rdev;
+	vdev->type = rdev->type;
+	vdev->model = rdev->model;
+
+	return 0;
+}
+
+int alloc_virt_dev(struct virt_sys *sys, struct directory_vdev *dirdev,
+		   u32 sch)
+{
+	struct virt_device *vdev;
+	int ret = 0;
+
+	vdev = malloc(sizeof(struct virt_device), ZONE_NORMAL);
+	if (!vdev)
+		return -ENOMEM;
+
+	vdev->vtype = dirdev->type;
+	vdev->sch = sch;
+	vdev->pmcw.v = 1;
+	vdev->pmcw.dev_num = dirdev->vdev;
+	vdev->pmcw.lpm = 0x80;
+	vdev->pmcw.pim = 0x80;
+	vdev->pmcw.pom = 0xff;
+	vdev->pmcw.pam = 0x80;
+
+	switch(dirdev->type) {
+		case VDEV_CONS:
+			vdev->type = 0x3215;
+			vdev->model = 0;
+			break;
+		case VDEV_DED:
+			ret = __setup_vdev_ded(sys, dirdev, vdev);
+			break;
+		case VDEV_SPOOL:
+			vdev->type = dirdev->u.spool.type;
+			vdev->model = dirdev->u.spool.model;
+			// FIXME: hook it up to the spooler
+			break;
+		case VDEV_MDISK:
+			vdev->type = 0x3390;
+			vdev->model = 3;
+			// FIXME: hook it up to mdisk driver
+			break;
+		case VDEV_LINK:
+			goto free;
+		case VDEV_INVAL:
+			goto out;
+	}
+
+	list_add_tail(&vdev->devices, &sys->virt_devs);
+
+	return ret;
+
+free:
+	free(vdev);
+	return 0;
+
+out:
+	free(vdev);
+	return -EINVAL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/fs/Makefile	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,1 @@
+objs-fs := bdev.o edf.o
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/fs/bdev.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,17 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <device.h>
+#include <bdev.h>
+
+int bdev_read_block(struct device *dev, void *buf, int lba)
+{
+	if (!dev->dev->read)
+		return -EINVAL;
+
+	return dev->dev->read(dev, buf, lba);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/fs/edf.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,178 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <mutex.h>
+#include <buddy.h>
+#include <slab.h>
+#include <device.h>
+#include <bdev.h>
+#include <ebcdic.h>
+#include <edf.h>
+
+struct fs *edf_mount(struct device *dev)
+{
+	struct page *page;
+	void *tmp;
+	struct fs *fs;
+	long ret;
+
+	page = alloc_pages(0, ZONE_NORMAL);
+	if (!page)
+		return ERR_PTR(-ENOMEM);
+	tmp = page_to_addr(page);
+
+	ret = -ENOMEM;
+	fs = malloc(sizeof(struct fs), ZONE_NORMAL);
+	if (!fs)
+		goto out_free;
+
+	/* First, read & verify the label */
+	ret = bdev_read_block(dev, tmp, EDF_LABEL_BLOCK_NO);
+	if (ret)
+		goto out_free;
+
+	mutex_init(&fs->lock);
+	INIT_LIST_HEAD(&fs->files);
+	fs->dev = dev;
+	fs->tmp_buf = tmp;
+
+	memcpy(&fs->ADT, tmp, sizeof(struct ADT));
+
+	ret = -EINVAL;
+	if ((fs->ADT.ADTIDENT != __ADTIDENT) ||
+	    (fs->ADT.ADTDBSIZ != EDF_SUPPORTED_BLOCK_SIZE) ||
+	    (fs->ADT.ADTOFFST != 0) ||
+	    (fs->ADT.ADTFSTSZ != sizeof(struct FST)))
+		goto out_free;
+
+	return fs;
+
+out_free:
+	free(fs);
+	free_pages(tmp, 0);
+	return ERR_PTR(ret);
+}
+
+extern struct console *oper_con;
+struct file *edf_lookup(struct fs *fs, char *fn, char *ft)
+{
+	char __fn[8];
+	char __ft[8];
+	struct page *page;
+	struct file *file;
+	struct file *tmpf;
+	struct FST *fst;
+	long ret;
+	int found;
+	int i;
+
+	file = malloc(sizeof(struct file), ZONE_NORMAL);
+	if (!file)
+		return ERR_PTR(-ENOMEM);
+
+	file->fs = fs;
+	file->buf = NULL;
+
+	memcpy(__fn, fn, 8);
+	memcpy(__ft, ft, 8);
+	ascii2ebcdic((u8 *) __fn, 8);
+	ascii2ebcdic((u8 *) __ft, 8);
+
+	mutex_lock(&fs->lock);
+
+	/* first, check the cache */
+	list_for_each_entry(tmpf, &fs->files, files) {
+		if (!memcmp((char*) tmpf->FST.FSTFNAME, __fn, 8) &&
+		    !memcmp((char*) tmpf->FST.FSTFTYPE, __ft, 8)) {
+			mutex_unlock(&fs->lock);
+			free(file);
+			return tmpf;
+		}
+	}
+
+	page = alloc_pages(0, ZONE_NORMAL);
+	if (!page) {
+		ret = -ENOMEM;
+		goto out_unlock;
+	}
+	file->buf = page_to_addr(page);
+
+	/* oh well, must do it the hard way ... read from disk */
+	ret = bdev_read_block(fs->dev, fs->tmp_buf, fs->ADT.ADTDOP);
+	if (ret)
+		goto out_unlock;
+
+	fst = fs->tmp_buf;
+
+	for(i=0,found=0; i<fs->ADT.ADTNFST; i++) {
+		if ((!memcmp(fst[i].FSTFNAME, __fn, 8)) &&
+		    (!memcmp(fst[i].FSTFTYPE, __ft, 8))) {
+			memcpy(&file->FST, &fst[i], sizeof(struct FST));
+			found = 1;
+			break;
+		}
+	}
+
+	if (!found) {
+		ret = -ENOENT;
+		goto out_unlock;
+	}
+
+	mutex_init(&file->lock);
+	list_add_tail(&file->files, &fs->files);
+
+	mutex_unlock(&fs->lock);
+
+	return file;
+
+out_unlock:
+	if (file && file->buf)
+		free_pages(file->buf, 0);
+	mutex_unlock(&fs->lock);
+	free(file);
+	return ERR_PTR(ret);
+}
+
+int edf_read_rec(struct file *file, char *buf, u32 recno)
+{
+	struct fs *fs = file->fs;
+	u32 fop, lrecl;
+	int ret;
+
+	if (file->FST.FSTNLVL != 0 ||
+	    file->FST.FSTPTRSZ != 4 ||
+	    file->FST.FSTLRECL > fs->ADT.ADTDBSIZ ||
+	    file->FST.FSTRECFM != FSTDFIX)
+		return -EINVAL;
+
+	mutex_lock(&file->lock);
+
+	fop = file->FST.FSTFOP;
+	lrecl = file->FST.FSTLRECL;
+
+	ret = bdev_read_block(fs->dev, file->buf, fop);
+	if (ret)
+		goto out;
+
+	memcpy(buf, file->buf + (recno * lrecl), lrecl);
+
+out:
+	mutex_unlock(&file->lock);
+
+	return ret;
+}
+
+void edf_file_free(struct file *file)
+{
+	struct fs *fs = file->fs;
+
+	mutex_lock(&fs->lock);
+	list_del(&file->files);
+	mutex_unlock(&fs->lock);
+
+	free(file);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/hvf.directory	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,26 @@
+USER OPERATOR A
+    MACHINE ESA 1
+    STORAGE 17M
+    CONSOLE 0009 3215
+    SPOOL 000C 3505 READER
+    SPOOL 000D 3525 PUNCH
+    SPOOL 000E 1403 PRINT
+    MDISK 0191 3390 15 100 0192
+
+USER JEFFPC A
+    MACHINE ESA 1
+    STORAGE 64M
+    CONSOLE 0009 3215
+    SPOOL 000C 3505 READER
+    SPOOL 000D 3525 PUNCH
+    SPOOL 000E 1403 PRINT
+    MDISK 0190 3390 15 100 0192
+
+USER OBIWAN G
+    MACHINE ESA 1
+    STORAGE 2M
+    CONSOLE 0009 3215
+    SPOOL 000C 3505 READER
+    SPOOL 000D 3525 PUNCH
+    SPOOL 000E 1403 PRINT
+    MDISK 0193 3390 15 100 0192
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/atomic.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,203 @@
+/*
+ * Based on atomic.h from Linux Kernel
+ */
+
+#ifndef __ARCH_S390_ATOMIC__
+#define __ARCH_S390_ATOMIC__
+
+/*
+ *  include/asm-s390/atomic.h
+ *
+ *  S390 version
+ *    Copyright (C) 1999-2005 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
+ *               Denis Joseph Barrow,
+ *		 Arnd Bergmann (arndb@de.ibm.com)
+ *
+ *  Derived from "include/asm-i386/bitops.h"
+ *    Copyright (C) 1992, Linus Torvalds
+ *
+ */
+
+/*
+ * Atomic operations that C can't guarantee us.  Useful for
+ * resource counting etc..
+ * S390 uses 'Compare And Swap' for atomicity in SMP enviroment
+ */
+
+typedef struct {
+	volatile int counter;
+} __attribute__ ((aligned (4))) atomic_t;
+#define ATOMIC_INIT(i)  { (i) }
+
+#define __CS_LOOP(ptr, op_val, op_string) ({				\
+	typeof(ptr->counter) old_val, new_val;				\
+	asm volatile(							\
+		"	l	%0,%2\n"				\
+		"0:	lr	%1,%0\n"				\
+		op_string "	%1,%3\n"				\
+		"	cs	%0,%1,%2\n"				\
+		"	jl	0b"					\
+		: "=&d" (old_val), "=&d" (new_val),			\
+		  "=Q" (((atomic_t *)(ptr))->counter)			\
+		: "d" (op_val),	 "Q" (((atomic_t *)(ptr))->counter)	\
+		: "cc", "memory");					\
+	new_val;							\
+})
+
+#define atomic_read(v)          ((v)->counter)
+#define atomic_set(v,i)         (((v)->counter) = (i))
+
+static __inline__ int atomic_add_return(int i, atomic_t * v)
+{
+	return __CS_LOOP(v, i, "ar");
+}
+#define atomic_add(_i, _v)		atomic_add_return(_i, _v)
+#define atomic_add_negative(_i, _v)	(atomic_add_return(_i, _v) < 0)
+#define atomic_inc(_v)			atomic_add_return(1, _v)
+#define atomic_inc_return(_v)		atomic_add_return(1, _v)
+#define atomic_inc_and_test(_v)		(atomic_add_return(1, _v) == 0)
+
+static __inline__ int atomic_sub_return(int i, atomic_t * v)
+{
+	return __CS_LOOP(v, i, "sr");
+}
+#define atomic_sub(_i, _v)		atomic_sub_return(_i, _v)
+#define atomic_sub_and_test(_i, _v)	(atomic_sub_return(_i, _v) == 0)
+#define atomic_dec(_v)			atomic_sub_return(1, _v)
+#define atomic_dec_return(_v)		atomic_sub_return(1, _v)
+#define atomic_dec_and_test(_v)		(atomic_sub_return(1, _v) == 0)
+
+static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t * v)
+{
+	       __CS_LOOP(v, ~mask, "nr");
+}
+
+static __inline__ void atomic_set_mask(unsigned long mask, atomic_t * v)
+{
+	       __CS_LOOP(v, mask, "or");
+}
+
+#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
+
+static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new)
+{
+	asm volatile(
+		"	cs	%0,%2,%1"
+		: "+d" (old), "=Q" (v->counter)
+		: "d" (new), "Q" (v->counter)
+		: "cc", "memory");
+	return old;
+}
+
+static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+{
+	int c, old;
+	c = atomic_read(v);
+	for (;;) {
+		if (unlikely(c == u))
+			break;
+		old = atomic_cmpxchg(v, c, c + a);
+		if (likely(old == c))
+			break;
+		c = old;
+	}
+	return c != u;
+}
+
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
+#undef __CS_LOOP
+
+typedef struct {
+	volatile long long counter;
+} __attribute__ ((aligned (8))) atomic64_t;
+#define ATOMIC64_INIT(i)  { (i) }
+
+#define __CSG_LOOP(ptr, op_val, op_string) ({				\
+	typeof(ptr->counter) old_val, new_val;				\
+	asm volatile(							\
+		"	lg	%0,%2\n"				\
+		"0:	lgr	%1,%0\n"				\
+		op_string "	%1,%3\n"				\
+		"	csg	%0,%1,%2\n"				\
+		"	jl	0b"					\
+		: "=&d" (old_val), "=&d" (new_val),			\
+		  "=Q" (((atomic_t *)(ptr))->counter)			\
+		: "d" (op_val),	"Q" (((atomic_t *)(ptr))->counter)	\
+		: "cc", "memory" );					\
+	new_val;							\
+})
+
+#define atomic64_read(v)          ((v)->counter)
+#define atomic64_set(v,i)         (((v)->counter) = (i))
+
+static __inline__ long long atomic64_add_return(long long i, atomic64_t * v)
+{
+	return __CSG_LOOP(v, i, "agr");
+}
+#define atomic64_add(_i, _v)		atomic64_add_return(_i, _v)
+#define atomic64_add_negative(_i, _v)	(atomic64_add_return(_i, _v) < 0)
+#define atomic64_inc(_v)		atomic64_add_return(1, _v)
+#define atomic64_inc_return(_v)		atomic64_add_return(1, _v)
+#define atomic64_inc_and_test(_v)	(atomic64_add_return(1, _v) == 0)
+
+static __inline__ long long atomic64_sub_return(long long i, atomic64_t * v)
+{
+	return __CSG_LOOP(v, i, "sgr");
+}
+#define atomic64_sub(_i, _v)		atomic64_sub_return(_i, _v)
+#define atomic64_sub_and_test(_i, _v)	(atomic64_sub_return(_i, _v) == 0)
+#define atomic64_dec(_v)		atomic64_sub_return(1, _v)
+#define atomic64_dec_return(_v)		atomic64_sub_return(1, _v)
+#define atomic64_dec_and_test(_v)	(atomic64_sub_return(1, _v) == 0)
+
+static __inline__ void atomic64_clear_mask(unsigned long mask, atomic64_t * v)
+{
+	       __CSG_LOOP(v, ~mask, "ngr");
+}
+
+static __inline__ void atomic64_set_mask(unsigned long mask, atomic64_t * v)
+{
+	       __CSG_LOOP(v, mask, "ogr");
+}
+
+#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
+
+static __inline__ long long atomic64_cmpxchg(atomic64_t *v,
+					     long long old, long long new)
+{
+	asm volatile(
+		"	csg	%0,%2,%1"
+		: "+d" (old), "=Q" (v->counter)
+		: "d" (new), "Q" (v->counter)
+		: "cc", "memory");
+	return old;
+}
+
+static __inline__ int atomic64_add_unless(atomic64_t *v,
+					  long long a, long long u)
+{
+	long long c, old;
+	c = atomic64_read(v);
+	for (;;) {
+		if (unlikely(c == u))
+			break;
+		old = atomic64_cmpxchg(v, c, c + a);
+		if (likely(old == c))
+			break;
+		c = old;
+	}
+	return c != u;
+}
+
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
+
+#undef __CSG_LOOP
+
+#define smp_mb__before_atomic_dec()	smp_mb()
+#define smp_mb__after_atomic_dec()	smp_mb()
+#define smp_mb__before_atomic_inc()	smp_mb()
+#define smp_mb__after_atomic_inc()	smp_mb()
+
+#endif /* __ARCH_S390_ATOMIC__  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/bdev.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,13 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __BDEV_H
+#define __BDEV_H
+
+extern int bdev_read_block(struct device *dev, void *buf, int lba);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/buddy.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,17 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __BUDDY_H
+#define __BUDDY_H
+
+#include <page.h>
+
+extern void init_buddy_alloc(u64 start);
+extern struct page *alloc_pages(int order, int type);
+extern void free_pages(void *ptr, int order);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/channel.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,309 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __CHANNEL_H
+#define __CHANNEL_H
+
+/*
+ * We only care about format-1 CCWs
+ */
+struct ccw {
+	u8 cmd;			/* Command code */
+	u8 flags;		/* Flags */
+	u16 count;		/* Count */
+	u32 addr;		/* Data Address */
+} __attribute__((packed,aligned(8)));
+
+struct ccw0 {
+	u8 cmd;			/* Command code */
+	u8 addr_hi;		/* Data Address (bits 8-15) */
+	u16 addr_lo;		/* Data Address (bits 16-31) */
+	u8 flags;		/* Flags */
+	u8 _res0;
+	u16 count;		/* Count */
+} __attribute__((packed,aligned(8)));
+
+#define CCW_CMD_IPL_READ	0x02
+#define CCW_CMD_NOP		0x03
+#define CCW_CMD_BASIC_SENSE	0x04
+#define CCW_CMD_SENSE_ID	0xe4
+#define CCW_CMD_TIC		0x08
+
+#define CCW_FLAG_CD		0x80	/* Chain-Data */
+#define CCW_FLAG_CC		0x40	/* Chain-Command */
+#define CCW_FLAG_SLI		0x20	/* Suppress-Length-Indication */
+#define CCW_FLAG_SKP		0x10	/* Skip */
+#define CCW_FLAG_PCI		0x08	/* Program-Controlled-Interruption */
+#define CCW_FLAG_IDA		0x04	/* Indirect-Data-Address */
+#define CCW_FLAG_S		0x02	/* Suspend */
+#define CCW_FLAG_MIDA		0x01	/* Modified-Indirect-Data-Address */
+
+/*
+ * ORB
+ */
+struct orb {
+	/* word 0 */
+	u32 param;		/* Interruption Parameter */
+
+	/* word 1 */
+	u8 key:4,		/* Subchannel Key */
+	   s:1,			/* Suspend */
+	   c:1,			/* Streaming-Mode Control */
+	   m:1,			/* Modification Control */
+	   y:1;			/* Synchronization Control */
+	u8 f:1,			/* Format Control */
+	   p:1,			/* Prefetch Control */
+	   i:1,			/* Initial-Status-Interruption Control */
+	   a:1,			/* Address-Limit-Checking control */
+	   u:1,			/* Suppress-Suspend-Interruption Control */
+	   __zero1:1,
+	   h:1,			/* Format-2-IDAW Control */
+	   t:1;			/* 2K-IDAW Control */
+	u8 lpm;			/* Logical-Path Mask */
+	u8 l:1,			/* Incorrect-Length-Suppression Mode */
+	   d:1,			/* Modified-CCW-Indirect-Data-Addressing Control */
+	   __zero2:5,
+	   x:1;			/* ORB-Extension Control */
+
+	/* word 2 */
+	u32 addr;		/* Channel-Program Address */
+
+	/* word 3 */
+	u8 css_prio;		/* Channel-Subsystem Priority */
+	u8 __reserved1;
+	u8 cu_prio;		/* Control-Unit Priority */
+	u8 __reserved2;
+
+	/* word 4 - 7 */
+	u32 __reserved3;
+	u32 __reserved4;
+	u32 __reserved5;
+	u32 __reserved6;
+} __attribute__((packed,aligned(4)));
+
+enum SCSW_FC {
+	FC_CLEAR	= 0x10,
+	FC_HALT		= 0x20,
+	FC_START	= 0x40,
+};
+
+enum SCSW_SC {
+	SC_STATUS	= 0x01,
+	SC_SECONDARY	= 0x02,
+	SC_PRIMARY	= 0x04,
+	SC_INTERMED	= 0x08,
+	SC_ALERT	= 0x10,
+};
+
+struct scsw {
+	/* word 0 */
+	u16 key:4,		/* Subchannel key */
+	    s:1,		/* Suspend control */
+	    l:1,		/* ESW format */
+	    cc:2,		/* Deferred condition code */
+	    f:1,		/* Format */
+	    p:1,		/* Prefetch */
+	    i:1,		/* Initial-status interruption control */
+	    a:1,		/* Address-limit-checking control */
+	    u:1,		/* Supress-suspended interruption */
+	    z:1,		/* Zero condition code */
+	    e:1,		/* Extended control */
+	    n:1;		/* Path no operational */
+	u16 __zero:1,
+	    fc:3,		/* Function control */
+	    ac:8,		/* Activity control */
+	    sc:4;		/* Status control */
+
+	/* word 1 */
+	u32 addr;		/* CCW Address */
+
+	/* word 2 */
+	u8 dev_status;		/* Device status */
+	u8 sch_status;		/* Subchannel status */
+	u16 count;		/* Count */
+} __attribute__((packed));
+
+/* needed by IRB */
+struct irb_ext_status {
+	/* TODO: not implemented */
+	u32 w0, w1, w2, w3, w4;
+} __attribute__((packed));
+
+/* needed by IRB */
+struct irb_ext_control {
+	/* TODO: not implemented */
+	u32 w0, w1, w2, w3, w4, w5, w6, w7;
+} __attribute__((packed));
+
+/* needed by IRB */
+struct irb_ext_measurement {
+	/* TODO: not implemented */
+	u32 w0, w1, w2, w3, w4, w5, w6, w7;
+} __attribute__((packed));
+
+struct irb {
+	struct scsw scsw;			/* Subchannel-Status */
+	struct irb_ext_status ext_status;	/* Extended-Status */
+	struct irb_ext_control ext_control;	/* Extended-Control */
+	struct irb_ext_measurement ext_measure;	/* Extended-Measurement */
+} __attribute__((packed,aligned(4)));
+
+/* Path Management Control Word */
+struct pmcw {
+	/* word 0 */
+	u32 interrupt_param;	/* Interruption Parameter */
+
+	/* word 1*/
+	u8 __zero1:2,
+	   isc:3,		/* I/O-Interruption-Subclass Code */
+	   __zero2:3;
+	u8 e:1,			/* Enabled */
+	   lm:2,		/* Limit Mode */
+	   mm:2,		/* Measurement-Mode Enable */
+	   d:1,			/* Multipath Mode */
+	   t:1,			/* Timing Facility */
+	   v:1;			/* Device Number Valid */
+	u16 dev_num;		/* Device Number */
+
+	/* word 2 */
+	u8 lpm;			/* Logical-Path Mask */
+	u8 pnom;		/* Path-Not-Operational Mask */
+	u8 lpum;		/* Last-Path-Used Mask */
+	u8 pim;			/* Path-Installed Mask */
+
+	/* word 3 */
+	u16 mbi;		/* Measurement-Block Index */
+	u8 pom;			/* Path-Operational Mask */
+	u8 pam;			/* Path-Available Mask */
+
+	/* word 4 & 5 */
+	u8 chpid[8];		/* Channel-Path Identifiers */
+
+	/* word 6 */
+	u16 __zero3;
+	u16 __zero4:13,
+	    f:1,		/* Measurement Block Format Control */
+	    x:1,		/* Extended Measurement Word Mode Enable */
+	    s:1;		/* Concurrent Sense */
+};
+
+/* needed by schib */
+struct schib_measurement_block {
+	/* TODO: not implemented */
+	u32 w0, w1;
+};
+
+struct schib {
+	struct pmcw pmcw;		/* Path Management Control Word */
+	struct scsw scsw;		/* Subchannel Status Word */
+	union {
+		struct schib_measurement_block measure_block;
+	};
+	u32 model_dep_area;
+} __attribute__((packed,aligned(4)));
+
+static inline int store_sch(u32 sch, struct schib *schib)
+{
+	int cc;
+
+	asm volatile(
+		"lr	%%r1,%2\n"
+		"stsch	%1\n"
+		"ipm	%0\n"
+		"srl	%0,28\n"
+		: /* output */
+		  "=d" (cc),
+		  "=Q" (*schib)
+		: /* input */
+		  "d" (sch)
+		: /* clobbered */
+		  "cc", "r1", "memory"
+	);
+
+	if (cc == 3)
+		return -EINVAL;
+	return 0;
+}
+
+static inline int modify_sch(u32 sch, struct schib *schib)
+{
+	int cc;
+
+	asm volatile(
+		"lr	%%r1,%1\n"
+		"msch	0(%2)\n"
+		"ipm	%0\n"
+		"srl	%0,28\n"
+		: /* output */
+		  "=d" (cc)
+		: /* input */
+		  "d" (sch),
+		  "a" (schib)
+		: /* clobbered */
+		  "cc", "r1"
+	);
+
+	if (cc == 1 || cc == 2)
+		return -EBUSY;
+	if (cc == 3)
+		return -EINVAL;
+	return 0;
+}
+
+static inline int start_sch(u32 sch, struct orb *orb)
+{
+	int cc;
+
+	asm volatile(
+		"	lr	%%r1,%1\n"
+		"	ssch	0(%2)\n"
+		"	ipm	%0\n"
+		"	srl	%0,28\n"
+		: /* output */
+		  "=d" (cc)
+		: /* input */
+		  "d" (sch),
+		  "a" (orb)
+		: /* clobbered */
+		  "cc", "r1"
+	);
+
+	if (cc == 1 || cc == 2)
+		return -EBUSY;
+	if (cc == 3)
+		return -EINVAL;
+
+	return 0;
+}
+
+static inline int test_sch(u32 sch, struct irb *irb)
+{
+	int cc;
+
+	asm volatile(
+		"	lr	%%r1,%1\n"
+		"	tsch	0(%2)\n"
+		"	ipm	%0\n"
+		"	srl	%0,28\n"
+	: /* output */
+	  "=d" (cc)
+	: /* input */
+	  "d" (sch),
+	  "a" (irb)
+	: /* clobbered */
+	  "cc", "r1"
+	);
+
+	if (cc == 3)
+		return -EINVAL;
+
+	return 0;
+}
+
+extern void scan_devices(void);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/compiler.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,17 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __COMPILER_H
+#define __COMPILER_H
+
+/*
+ * For compatibility with some Linux kernel code
+ */
+#define likely(x) (x)
+#define unlikely(x) (x)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/config.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,21 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * Base address within a guest's address space; used as the base address for
+ * the IPL helper code.
+ *
+ * NOTE: It must be >= 16M, but <2G
+ */
+#define GUEST_IPL_BASE		(16ULL * 1024ULL * 1024ULL)
+
+#define OPER_CONSOLE_CCUU	0x0009
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/console.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __CONSOLE_H
+#define __CONSOLE_H
+
+#include <device.h>
+#include <io.h>
+#include <spinlock.h>
+
+/* line allocation size */
+#define CON_LINE_ALLOC_SIZE	256
+
+/* maximum line length */
+#define CON_MAX_LINE_LEN	(CON_LINE_ALLOC_SIZE - sizeof(struct console_line))
+
+/* maximum number of free lines to keep around */
+#define CON_MAX_FREE_LINES	32
+
+/* number of lines of console text to flush at a time */
+#define CON_MAX_FLUSH_LINES	32
+
+/* line state */
+#define CON_STATE_FREE		0
+#define CON_STATE_PENDING	1
+#define CON_STATE_IO		2
+
+struct console_line {
+	struct list_head lines;
+	u16 len;
+	u16 state;
+	u8 buf[0];
+};
+
+struct console {
+	struct list_head consoles;
+	struct virt_sys *sys;
+	struct device *dev;
+	spinlock_t lock;
+	struct list_head write_lines;
+	struct list_head read_lines;
+};
+
+extern int console_interrupt(struct device *dev, struct irb *irb);
+extern struct console* start_oper_console(void);
+extern void* console_enable(struct device *dev);
+extern int con_read_pending(struct console *con);
+extern int con_read(struct console *con, u8 *buf, int size);
+extern int con_write(struct console *con, u8 *buf, int len);
+extern void for_each_console(void (*f)(struct console *con));
+extern struct console* find_console(struct device *dev);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/cpu.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,39 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __CPU_H
+#define __CPU_H
+
+static inline u64 getcpuid()
+{
+	u64 cpuid = ~0;
+
+	asm("stidp	0(%1)\n"
+	: /* output */
+	  "=m" (cpuid)
+	: /* input */
+	  "a" (&cpuid)
+	);
+
+	return cpuid;
+}
+
+static inline u16 getcpuaddr()
+{
+	u16 cpuaddr = ~0;
+
+	asm("stap	0(%1)\n"
+	: /* output */
+	  "=m" (cpuaddr)
+	: /* input */
+	  "a" (&cpuaddr)
+	);
+
+	return cpuaddr;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/dat.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,143 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __DAT_H
+#define __DAT_H
+
+struct address_space {
+	struct dat_rte *region_table;
+	struct dat_ste *segment_table;
+};
+
+/* region/segment-table destination */
+struct dat_td {
+	u64 origin:52,		/* region/segment table origin */
+	    __reserved0:2,
+	    g:1,		/* subspace-group control */
+	    p:1,		/* private-space control */
+	    s:1,		/* storage-alteration-event ctl */
+	    x:1,		/* space-switch-event control */
+	    r:1,		/* real-space control */
+	    __reserved1:1,
+	    dt:2,		/* designation-type control */
+	    tl:2;		/* table length */
+} __attribute__((packed));
+
+#define DAT_TD_DT_RFT		3	/* region-first */
+#define DAT_TD_DT_RST		2	/* region-second */
+#define DAT_TD_DT_RTT		1	/* region-third */
+#define DAT_TD_DT_ST		0	/* segment */
+
+/* region-table entries (first, second, and third) */
+struct dat_rte {
+	u64 origin:52,		/* next-level-table origin */
+	    __reserved0:4,
+	    tf:2,		/* table offset (next lower tbl) */
+	    i:1,		/* region invalid */
+	    __reserved1:1,
+	    tt:2,		/* table-type bits (current tbl) */
+	    tl:2;		/* table length (next lower tbl) */
+} __attribute__((packed));
+
+/*
+ * Constants for struct rte
+ */
+#define DAT_RTE_TT_RFT		3	/* region-first */
+#define DAT_RTE_TT_RST		2	/* region-second */
+#define DAT_RTE_TT_RTT		1	/* region-third */
+
+#define ADDR_TO_RTE_ORIGIN(a)	((a) >> 12)
+#define RTE_ORIGIN_TO_ADDR(o)	((void*)(((u64)(o)) << 12))
+
+/* segment-table entries */
+struct dat_ste {
+	u64 origin:53,		/* page-table origin */
+	    __reserved0:1,
+	    p:1,		/* page-protection bit */
+	    __reserved1:3,
+	    i:1,		/* segment-invalid bit */
+	    c:1,		/* common-segment bit */
+	    tt:2,		/* table-type bits */
+	    __reserved2:2;
+} __attribute__((packed));
+
+#define DAT_STE_TT_ST		0	/* segment-table */
+
+#define ADDR_TO_STE_ORIGIN(a)	((a) >> 11)
+#define STE_ORIGIN_TO_ADDR(o)	((void*)(((u64)(o)) << 11))
+
+/* page-table entries */
+struct dat_pte {
+	u64 pfra:52,		/* page-frame real address */
+	    __zero0:1,
+	    i:1,		/* page-invalid bit */
+	    p:1,		/* page-protection bit */
+	    __zero1:1,
+	    __reserved:8;
+} __attribute__((packed));
+
+#define DAT_RX(addr)	(((u64)(addr)) >> 31)
+#define DAT_SX(addr)	((((u64)(addr)) >> 20) & 0x7ff)
+#define DAT_PX(addr)	((((u64)(addr)) >> 12) & 0xff)
+#define DAT_BX(addr)	(((u64)(addr))& 0xfff)
+
+extern int dat_insert_page(struct address_space *as, u64 phy, u64 virt);
+extern void setup_dat(void);
+extern void load_as(struct address_space *as);
+
+extern int virt2phy(struct address_space *as, u64 virt, u64 *phy);
+
+static inline void store_pasce(u64 *pasce)
+{
+	asm volatile(
+		"	stctg	1,1,0(%0)\n"
+	: /* output */
+	: /* input */
+	  "a" (pasce)
+	);
+}
+
+static inline void load_pasce(u64 pasce)
+{
+	if (!pasce)
+		return;
+
+	asm volatile(
+		"	lctlg	1,1,%0\n"
+	: /* output */
+	: /* input */
+	  "m" (pasce)
+	);
+}
+
+/* get host real address from guest real, using the currently loaded ASCE */
+static inline int virt2phy_current(u64 virt, u64 *phy)
+{
+	u64 result;
+	int cc;
+
+	asm volatile(
+		"	lrag	%0,0(%%r0,%2)\n"
+		"	ipm	%1\n"
+		"	srl	%1,28\n"
+	: /* output */
+	  "=d" (result),
+	  "=d" (cc)
+	: /* input */
+	  "a" (virt)
+	: /* clobber */
+	  "cc"
+	);
+
+	if (cc != 0)
+		return -EFAULT;
+
+	*phy = result;
+	return 0;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/device.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,98 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __DEVICE_H
+#define __DEVICE_H
+
+#include <atomic.h>
+#include <spinlock.h>
+#include <list.h>
+
+struct device;
+struct irb;
+
+struct device_type {
+	struct list_head types;
+	int (*reg)(struct device *dev);
+	int (*interrupt)(struct device *dev, struct irb *irb);
+	void* (*enable)(struct device *dev);
+	int (*snprintf)(struct device *dev, char *buf, int len);
+
+	/* the following ops are for the bdev wrapper layer */
+	int (*read)(struct device *dev, u8 *buf, int len);
+
+	u16 type;
+	u8 model;
+	u8 all_models;
+};
+
+struct device {
+	struct list_head devices;
+	u32 sch;			/* subchannel id */
+	u16 type;			/* 3330, 3215, ... */
+	u8 model;
+	u16 ccuu;			/* device number */
+	struct device_type *dev;
+
+	spinlock_t q_lock;
+	struct io_op *q_cur;
+	struct list_head q_out;
+	atomic_t attention;
+
+	atomic_t in_use;		/* is the device in use by someone? */
+
+	atomic_t refcnt;		/* internal reference counter */
+
+	union {
+		struct {
+			u16 cyls;	/* cylinders */
+			u16 tracks;	/* tracks per cylinder */
+			u16 len;	/* track length */
+			u16 recs;	/* number of records */
+			u8  sectors;	/* # sectors per track */
+			u8  formula;	/* capacity formula */
+			u16 f1,		/* factor f1 */
+			    f2,		/* factor f2 */
+			    f3,		/* factor f3 */
+			    f4,		/* factor f4 */
+			    f5;		/* factor f5 */
+		} eckd;
+		struct {
+			u16 blk_size;	/* block size */
+			u32 bpg;	/* blocks per cyclical group */
+			u32 bpp;	/* blocks per access possition */
+			u32 blks;	/* blocks */
+		} fba;
+	};
+};
+
+extern struct device *find_device_by_type(u16 type, u8 model);
+extern struct device *find_device_by_ccuu(u16 ccuu);
+extern struct device *find_device_by_sch(u32 sch);
+extern int register_device_type(struct device_type *dev);
+extern void scan_devices(void);
+extern void list_devices(struct console *con,
+			 void (*f)(struct console*, struct device*));
+extern void register_drivers(void);
+
+static inline void dev_get(struct device *dev)
+{
+	BUG_ON(atomic_read(&dev->refcnt) < 1);
+	atomic_inc(&dev->refcnt);
+}
+
+static inline void dev_put(struct device *dev)
+{
+	atomic_dec(&dev->refcnt);
+	BUG_ON(atomic_read(&dev->refcnt) < 1);
+}
+
+/* device specific register functions */
+extern int register_driver_3215(void);
+extern int register_driver_dasd(void);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/directory.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,69 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __DIRECTORY_H
+#define __DIRECTORY_H
+
+#include <console.h>
+
+enum directory_vdevtype {
+	VDEV_INVAL = 0,			/* invalid */
+	VDEV_CONS,			/* a console */
+	VDEV_DED,			/* dedicated real device */
+	VDEV_SPOOL,			/* backed by the spool */
+	VDEV_MDISK,			/* a minidisk */
+	VDEV_LINK,			/* a link to another user's device */
+};
+
+struct directory_vdev {
+	enum directory_vdevtype type;	/* device type */
+	u16 vdev;			/* virtual dev # */
+
+	union {
+		/* VDEV_CONS */
+		struct {
+		} console;
+
+		/* VDEV_DED */
+		struct {
+			u16 rdev;	/* real device # */
+		} dedicate;
+
+		/* VDEV_SPOOL */
+		struct {
+			u16 type;
+			u8 model;
+		} spool;
+
+		/* VDEV_MDISK */
+		struct {
+			u16 cyloff;	/* first cylinder # */
+			u16 cylcnt;	/* cylinder count */
+			u16 rdev;	/* real DASD containing the mdisk */
+		} mdisk;
+
+		/* VDEV_LINK */
+		struct {
+		} link;
+	} u;
+};
+
+struct user {
+	char *userid;
+	struct task *task;
+
+	/* VM configuration */
+	u64 storage_size;
+
+	struct directory_vdev *devices;
+
+	u8 auth;
+};
+
+extern struct user *find_user_by_id(char *userid);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/disassm.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,76 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __DISASSM_H
+#define __DISASSM_H
+
+enum inst_fmt {
+	IF_INV = 0,
+	IF_VAR,
+	IF_E,
+	IF_I,
+	IF_RI1,
+	IF_RI2,
+	IF_RIE,
+	IF_RIL1,
+	IF_RIL2,
+	IF_RIS,
+	IF_RR,
+	IF_RR_MASK,
+	IF_RRE,
+	IF_RRF1,
+	IF_RRF2,
+	IF_RRF3,
+	IF_RRR,
+	IF_RRS,
+	IF_RS1,
+	IF_RS2,
+	IF_RSI,
+	IF_RSL,
+	IF_RSY1,
+	IF_RSY2,
+	IF_RX,
+	IF_RX_MASK,
+	IF_RXE,
+	IF_RXF,
+	IF_RXY,
+	IF_S,
+	IF_SI,
+	IF_SIL,
+	IF_SIY,
+	IF_SS1,
+	IF_SS2,
+	IF_SS3,
+	IF_SS4,
+	IF_SS5,
+	IF_SSE,
+	IF_SSF,
+	IF_DIAG,
+};
+
+struct disassm_instruction {
+	union {
+		char *name;	/* instruction name; inst only */
+
+		void *ptr;	/* next level table; table only */
+	} u;
+
+	/* all */
+	char fmt;		/* instruction format */
+
+	/* table only */
+	char len;		/* table len */
+	char loc;		/* sub-opcode location offset in bits */
+};
+
+#define DA_INST(idx,ifmt,iname)		[idx] = { .fmt = IF_##ifmt,	.u.name = #iname, }
+#define DA_INST_TBL(idx,itbl,ilen,iloc)	[idx] = { .fmt = IF_VAR,	.u.ptr = (itbl), \
+						  .len = (ilen),	.loc = (iloc), }
+
+extern int disassm(u8 *bytes, char *buf, int buflen);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/ebcdic.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,41 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __EBCDIC_H
+#define __EBCDIC_H
+
+extern u8 ascii2ebcdic_table[256];
+extern u8 ebcdic2ascii_table[256];
+
+/*
+ * Generic translate buffer function.
+ */
+static inline void __translate(u8 *buf, int len, const u8 *table)
+{
+	asm volatile(
+		"	sgr	%%r0,%%r0\n"		/* test byte = 0 */
+		"	la	%%r2,0(%0)\n"		/* buffer */
+		"	lgr	%%r3,%2\n"		/* length */
+		"	la	%%r4,0(%1)\n"		/* table */
+		"0:	tre	%%r2,%%r4\n"
+		"	brc	1,0b\n"
+		: /* output */
+		: /* input */
+		  "a" (buf),
+		  "a" (table),
+		  "d" (len)
+		: /* clobbered */
+		  "cc", "r0", "r2", "r3", "r4"
+	);
+}
+
+#define ascii2ebcdic(buf, len)	\
+			__translate((buf), (len), ascii2ebcdic_table)
+#define ebcdic2ascii(buf, len)  \
+			__translate((buf), (len), ebcdic2ascii_table)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/edf.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,107 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __EDF_H
+#define __EDF_H
+
+#include <mutex.h>
+#include <device.h>
+
+struct ADT {
+	u32     ADTIDENT;       /* VOL START / LABEL IDENTIFIER */
+#define __ADTIDENT 0xC3D4E2F1   /* 'CMS1' in EBCDIC */
+	u8      ADTID[6];       /* VOL START / VOL IDENTIFIER */
+	u8      ADTVER[2];      /* VERSION LEVEL */
+	u32     ADTDBSIZ;       /* DISK BLOCK SIZE */
+	u32     ADTDOP;         /* DISK ORIGIN POINTER */
+	u32     ADTCYL;         /* NUM OF FORMATTED CYL ON DISK */
+	u32     ADTMCYL;        /* MAX NUM FORMATTED CYL ON DISK */
+	u32     ADTNUM;         /* Number of Blocks on disk */
+	u32     ADTUSED;        /* Number of Blocks used */
+	u32     ADTFSTSZ;       /* SIZE OF FST */
+	u32     ADTNFST;        /* NUMBER OF FST'S PER BLOCK */
+	u8      ADTDCRED[6];    /* DISK CREATION DATE (YYMMDDHHMMSS) */
+	u8      ADTFLGL;        /* LABEL FLAG BYTE (ADTFLGL) */
+#define ADTCNTRY        0x01    /* Century for disk creation date (0=19, 1=20),
+	                         * corresponds to ADTDCRED. */
+	u8      reserved[1];
+	u32     ADTOFFST;       /* DISK OFFSET WHEN RESERVED */
+	u32     ADTAMNB;        /* ALLOC MAP BLOCK WITH NEXT HOLE */
+	u32     ADTAMND;        /* DISP INTO HBLK DATA OF NEXT HOLE */
+	u32     ADTAMUP;        /* DISP INTO USER PART OF ALLOC MAP */
+	u32     ADTOFCNT;       /* Count of SFS open files for this ADT */
+	u8      ADTSFNAM[8];    /* NAME OF SHARED SEGMENT */
+};
+
+struct FST {
+	u8    FSTFNAME[8];       /* filename */
+	u8    FSTFTYPE[8];       /* filetype */
+	u8    FSTDATEW[2];       /* DATE LAST WRITTEN - MMDD */
+	u8    FSTTIMEW[2];       /* TIME LAST WRITTEN - HHMM */
+	u16   FSTWRPNT;          /* WRITE POINTER - ITEM NUMBER */
+	u16   FSTRDPNT;          /* READ POINTER - ITEM NUMBER */
+	u8    FSTFMODE[2];       /* FILE MODE - LETTER AND NUMBER */
+	u16   FSTRECCT;          /* NUMBER OF LOGICAL RECORDS */
+	u16   FSTFCLPT;          /* FIRST CHAIN LINK POINTER */
+	u8    FSTRECFM;          /* F*1 - RECORD FORMAT - F OR V */
+#define FSTDFIX        0xC6 /* Fixed record format (EBCDIC 'F') */
+#define FSTDVAR        0xE5 /* Variable record format (EBCDIC 'V') */
+	u8    FSTFLAGS;          /* F*2 - FST FLAG BYTE */
+#define FSTRWDSK       0x80 /* READ/WRITE DISK */
+#define FSTRODSK       0x00 /* READ/ONLY DISK */
+#define FSTDSFS        0x10 /* Shared File FST */
+#define FSTXRDSK       0x40 /* EXTENSION OF R/O DISK */
+#define FSTXWDSK       0xC0 /* EXTENSION OF R/W DISK */
+#define FSTEPL         0x20 /* EXTENDED PLIST */
+#define FSTDIA         0x40 /* ITEM AVAILABLE */
+#define FSTDRA         0x01 /* PREVIOUS RECORD NULL */
+#define FSTCNTRY       0x08 /* Century for date last written (0=19, 1=20),\\
+			       corresponds to FSTYEARW, FSTADATI. */
+#define FSTACTRD       0x04 /* ACTIVE FOR READING */
+#define FSTACTWR       0x02 /* ACTIVE FOR WRITING */
+#define FSTACTPT       0x01 /* ACTIVE FROM A POINT */
+#define FSTFILEA       0x07 /* THE FILE IS ACTIVE */
+	u32   FSTLRECL;          /* LOGICAL RECORD LENGTH */
+	u16   FSTBLKCT;          /* NUMBER OF 800 BYTE BLOCKS */
+	u16   FSTYEARW;          /* YEAR LAST WRITTEN */
+	u32   FSTFOP;            /* ALT. FILE ORIGIN POINTER */
+	u32   FSTADBC;           /* ALT. NUMBER OF DATA BLOCKS */
+	u32   FSTAIC;            /* ALT. ITEM COUNT */
+	u8    FSTNLVL;           /* NUMBER OF POINTER BLOCK LEVELS */
+	u8    FSTPTRSZ;          /* LENGTH OF A POINTER ELEMENT */
+	u8    FSTADATI[6];       /* ALT. DATE/TIME(YY MM DD HH MM SS) */
+	u8    FSTREALM;          /* Real filemode */
+	u8    FSTFLAG2;          /* F*3 - FST FLAG BYTE 2 FSTFLAG2 */
+#define FSTPIPEU       0x10 /* Reserved for CMS PIPELINES usage */
+	u8    reserved[2];
+};
+
+#define EDF_LABEL_BLOCK_NO		3
+
+#define EDF_SUPPORTED_BLOCK_SIZE	4096
+
+struct fs {
+	struct ADT ADT;
+	struct list_head files;
+	mutex_t lock;
+	struct device *dev;
+	void *tmp_buf;
+};
+
+struct file {
+	struct FST FST;
+	struct list_head files;
+	mutex_t lock;
+	struct fs *fs;
+	char *buf;
+};
+
+extern struct fs *edf_mount(struct device *dev);
+extern struct file *edf_lookup(struct fs *fs, char *fn, char *ft);
+extern int edf_read_rec(struct file *file, char *buf, u32 recno);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/interrupt.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,103 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __INTERRUPT_H
+#define __INTERRUPT_H
+
+/*
+ * I/O interruptions specific constants & structures
+ */
+struct io_int_code {
+	u32 ssid;
+	u32 param;
+} __attribute__((packed));
+
+#define PSA_INT_GPR	((u64*) 0x200)
+#define PSA_TMP_PSW	((struct psw*) 0x280)
+
+#define IO_INT_OLD_PSW	((void*) 0x170)
+#define IO_INT_NEW_PSW	((void*) 0x1f0)
+#define IO_INT_CODE	((struct io_int_code*) 0xb8)
+
+#define EXT_INT_OLD_PSW	((void*) 0x130)
+#define EXT_INT_NEW_PSW	((void*) 0x1b0)
+#define EXT_INT_CODE	((u16*) 0x86)
+
+#define SVC_INT_OLD_PSW ((void*) 0x140)
+#define SVC_INT_NEW_PSW ((void*) 0x1c0)
+#define SVC_INT_CODE	((u16*) 0x8a)
+
+#define PGM_INT_OLD_PSW	((void*) 0x150)
+#define PGM_INT_NEW_PSW ((void*) 0x1d0)
+#define PGM_INT_ILC	((u8*) 0x8d)
+#define PGM_INT_CODE	((u16*) 0x8e)
+
+/*
+ * Assembly stubs to call the C-handlers
+ */
+extern void IO_INT(void);
+extern void EXT_INT(void);
+extern void SVC_INT(void);
+extern void PGM_INT(void);
+
+/**
+ * local_int_disable - disable interruptions & return old mask
+ */
+#define local_int_disable() ({ \
+	unsigned long __flags; \
+	__asm__ __volatile__ ( \
+		"stnsm 0(%1),0xfc" : "=m" (__flags) : "a" (&__flags) ); \
+	__flags; \
+	})
+
+/**
+ * local_int_restore - restore interrupt mask
+ * x:	mask to restore
+ */
+#define local_int_restore(x) \
+	__asm__ __volatile__("ssm   0(%0)" : : "a" (&x), "m" (x) : "memory")
+
+/**
+ * local_int_restore - restore interrupt mask
+ * x:	mask to restore
+ */
+static inline int interruptable()
+{
+	u8 x;
+
+	__asm__ __volatile__(
+		"stosm   0(%0),0x00"
+		: /* out */
+		: /* in */
+		 "a" (&x),
+		 "m" (x)
+		: /* clobber */
+		 "memory"
+	);
+
+	return (x & 0x43) != 0;
+}
+
+extern void set_timer(void);
+
+/*
+ * The Supervisor-Service call table
+ */
+#define SVC_SCHEDULE		0
+#define SVC_SCHEDULE_BLOCKED	1
+#define NR_SVC			2
+extern u64 svc_table[NR_SVC];
+
+/* Interrupt handlers */
+extern void __pgm_int_handler(void);
+extern void __ext_int_handler(void);
+extern void __io_int_handler(void);
+
+/* Interrupt handler stack pointer */
+extern u8 *int_stack_ptr;
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/io.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,40 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __IO_H
+#define __IO_H
+
+#include <channel.h>
+#include <atomic.h>
+#include <list.h>
+
+struct device;
+
+/*
+ * Defines an I/O operation
+ *
+ * This structure contains any and all state one should need to service any
+ * I/O interruption.
+ */
+struct io_op {
+	struct orb orb;		/* Operation Request Block */
+
+	struct list_head list;	/* list of in-flight operations */
+
+	int (*handler)(struct device *dev, struct io_op *ioop, struct irb *irb);
+				/* I/O specific callback */
+	void (*dtor)(struct device *dev, struct io_op *ioop);
+				/* I/O specific destructor */
+
+	int err;		/* return code */
+	atomic_t done;		/* has the operation completed */
+};
+
+extern void init_io(void);
+extern int submit_io(struct device *dev, struct io_op *oop, int flags);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/list.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,421 @@
+/*
+ * Based on list.h from Linux Kernel
+ */
+
+#ifndef _LINUX_LIST_H
+#define _LINUX_LIST_H
+
+#define LIST_POISON1	((void*) 0x8585858585858585ULL)
+#define LIST_POISON2	((void*) 0x8686868686868686ULL)
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+	struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+	struct list_head name = LIST_HEAD_INIT(name)
+
+static inline void INIT_LIST_HEAD(struct list_head *list)
+{
+	list->next = list;
+	list->prev = list;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_add(struct list_head *new,
+			      struct list_head *prev,
+			      struct list_head *next)
+{
+	next->prev = new;
+	new->next = next;
+	new->prev = prev;
+	prev->next = new;
+}
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+	__list_add(new, head, head->next);
+}
+
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+	__list_add(new, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+	next->prev = prev;
+	prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty() on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+static inline void list_del(struct list_head *entry)
+{
+	__list_del(entry->prev, entry->next);
+	entry->next = LIST_POISON1;
+	entry->prev = LIST_POISON2;
+}
+
+/**
+ * list_replace - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
+ *
+ * If @old was empty, it will be overwritten.
+ */
+static inline void list_replace(struct list_head *old,
+				struct list_head *new)
+{
+	new->next = old->next;
+	new->next->prev = new;
+	new->prev = old->prev;
+	new->prev->next = new;
+}
+
+static inline void list_replace_init(struct list_head *old,
+					struct list_head *new)
+{
+	list_replace(old, new);
+	INIT_LIST_HEAD(old);
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static inline void list_del_init(struct list_head *entry)
+{
+	__list_del(entry->prev, entry->next);
+	INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+	__list_del(list->prev, list->next);
+	list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(struct list_head *list,
+				  struct list_head *head)
+{
+	__list_del(list->prev, list->next);
+	list_add_tail(list, head);
+}
+
+/**
+ * list_is_last - tests whether @list is the last entry in list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static inline int list_is_last(const struct list_head *list,
+				const struct list_head *head)
+{
+	return list->next == head;
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+	return head->next == head;
+}
+
+/**
+ * list_empty_careful - tests whether a list is empty and not being modified
+ * @head: the list to test
+ *
+ * Description:
+ * tests whether a list is empty _and_ checks that no other CPU might be
+ * in the process of modifying either member (next or prev)
+ *
+ * NOTE: using list_empty_careful() without synchronization
+ * can only be safe if the only activity that can happen
+ * to the list entry is list_del_init(). Eg. it cannot be used
+ * if another CPU could re-list_add() it.
+ */
+static inline int list_empty_careful(const struct list_head *head)
+{
+	struct list_head *next = head->next;
+	return (next == head) && (next == head->prev);
+}
+
+static inline void __list_splice(struct list_head *list,
+				 struct list_head *head)
+{
+	struct list_head *first = list->next;
+	struct list_head *last = list->prev;
+	struct list_head *at = head->next;
+
+	first->prev = head;
+	head->next = first;
+
+	last->next = at;
+	at->prev = last;
+}
+
+/**
+ * list_splice - join two lists
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice(struct list_head *list, struct list_head *head)
+{
+	if (!list_empty(list))
+		__list_splice(list, head);
+}
+
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+				    struct list_head *head)
+{
+	if (!list_empty(list)) {
+		__list_splice(list, head);
+		INIT_LIST_HEAD(list);
+	}
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr:	the &struct list_head pointer.
+ * @type:	the type of the struct this is embedded in.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+	container_of(ptr, type, member)
+
+/**
+ * list_first_entry - get the first element from a list
+ * @ptr:	the list head to take the element from.
+ * @type:	the type of the struct this is embedded in.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+	list_entry((ptr)->next, type, member)
+
+/**
+ * list_for_each	-	iterate over a list
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @head:	the head for your list.
+ */
+#define list_for_each(pos, head) \
+	for (pos = (head)->next; prefetch(pos->next), pos != (head); \
+		pos = pos->next)
+
+/**
+ * __list_for_each	-	iterate over a list
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @head:	the head for your list.
+ *
+ * This variant differs from list_for_each() in that it's the
+ * simplest possible list iteration code, no prefetching is done.
+ * Use this for code that knows the list to be very short (empty
+ * or 1 entry) most of the time.
+ */
+#define __list_for_each(pos, head) \
+	for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_prev	-	iterate over a list backwards
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @head:	the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+	for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
+		pos = pos->prev)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @n:		another &struct list_head to use as temporary storage
+ * @head:	the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+	for (pos = (head)->next, n = pos->next; pos != (head); \
+		pos = n, n = pos->next)
+
+/**
+ * list_for_each_entry	-	iterate over list of given type
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member)				\
+	for (pos = list_entry((head)->next, typeof(*pos), member);	\
+	     &pos->member != (head);					\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member)			\
+	for (pos = list_entry((head)->prev, typeof(*pos), member);	\
+	     prefetch(pos->member.prev), &pos->member != (head);	\
+	     pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
+ * @pos:	the type * to use as a start point
+ * @head:	the head of the list
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
+ */
+#define list_prepare_entry(pos, head, member) \
+	((pos) ? : list_entry(head, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue - continue iteration over list of given type
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Continue to iterate over list of given type, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue(pos, head, member)			\
+	for (pos = list_entry(pos->member.next, typeof(*pos), member);	\
+	     prefetch(pos->member.next), &pos->member != (head);	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_from - iterate over list of given type from the current point
+ * @pos:	the type * to use as a loop cursor.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing from current position.
+ */
+#define list_for_each_entry_from(pos, head, member)			\
+	for (; prefetch(pos->member.next), &pos->member != (head);	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member)			\
+	for (pos = list_entry((head)->next, typeof(*pos), member),	\
+		n = list_entry(pos->member.next, typeof(*pos), member);	\
+	     &pos->member != (head);					\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_continue
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing after current point,
+ * safe against removal of list entry.
+ */
+#define list_for_each_entry_safe_continue(pos, n, head, member)			\
+	for (pos = list_entry(pos->member.next, typeof(*pos), member),		\
+		n = list_entry(pos->member.next, typeof(*pos), member);		\
+	     &pos->member != (head);						\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_from
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type from current point, safe against
+ * removal of list entry.
+ */
+#define list_for_each_entry_safe_from(pos, n, head, member)			\
+	for (n = list_entry(pos->member.next, typeof(*pos), member);		\
+	     &pos->member != (head);						\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_reverse
+ * @pos:	the type * to use as a loop cursor.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ *
+ * Iterate backwards over list of given type, safe against removal
+ * of list entry.
+ */
+#define list_for_each_entry_safe_reverse(pos, n, head, member)		\
+	for (pos = list_entry((head)->prev, typeof(*pos), member),	\
+		n = list_entry(pos->member.prev, typeof(*pos), member);	\
+	     &pos->member != (head);					\
+	     pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/magic.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,16 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __MAGIC_H
+#define __MAGIC_H
+
+#define MAGIC_PSW_IDLE_CODE		0x1D1E
+
+#define SLAB_MAGIC			0xe2d3c1c2
+#define SLAB_CONT_MAGIC			0xe2d3c1c3
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/mm.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,29 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __MM_H
+#define __MM_H
+
+extern u64 memsize;
+
+/* Turn Low-address protection on */
+static inline void lap_on(void)
+{
+	u64 cr0;
+
+	asm volatile(
+		"stctg	0,0,%0\n"	/* get cr0 */
+		"oi	%1,0x10\n"	/* enable */
+		"lctlg	0,0,%0\n"	/* reload cr0 */
+	: /* output */
+	: /* input */
+	  "m" (cr0),
+	  "m" (*(u64*) (((u8*)&cr0) + 4))
+	);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/mutex.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,74 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __MUTEX_H
+#define __MUTEX_H
+
+#include <list.h>
+#include <atomic.h>
+#include <spinlock.h>
+#include <sched.h>
+#include <interrupt.h>
+
+typedef struct {
+	atomic_t state;
+	spinlock_t queue_lock;
+	struct list_head queue;
+} mutex_t;
+
+#define UNLOCKED_MUTEX(name)	mutex_t name = { \
+			.state = ATOMIC_INIT(1), \
+			.queue = LIST_HEAD_INIT(name.queue), \
+			.queue_lock = SPIN_LOCK_UNLOCKED, \
+		}
+
+static inline void mutex_init(mutex_t *lock)
+{
+	atomic_set(&lock->state, 1);
+	INIT_LIST_HEAD(&lock->queue);
+	lock->queue_lock = SPIN_LOCK_UNLOCKED;
+}
+
+extern void __mutex_lock(mutex_t *lock);
+
+static inline void mutex_lock(mutex_t *lock)
+{
+	/*
+	 * if we are not interruptable, we shouldn't call any functions that
+	 * may sleep - e.g., mutex_lock
+	 */
+	BUG_ON(!interruptable());
+
+	if (unlikely(atomic_add_unless(&lock->state, -1, 0) == 0))
+		__mutex_lock(lock); /* the slow-path */
+}
+
+static inline void mutex_unlock(mutex_t *lock)
+{
+	struct task *task;
+
+	spin_lock(&lock->queue_lock);
+
+	if (likely(list_empty(&lock->queue))) {
+		/* no one is waiting on the queue */
+		atomic_inc(&lock->state);
+		spin_unlock(&lock->queue_lock);
+		return;
+	}
+
+	/*
+	 * someone is waiting on the queue, let's dequeue them & make them
+	 * runnable again
+	 */
+	task = list_first_entry(&lock->queue, struct task, blocked_list);
+	list_del(&task->blocked_list);
+	spin_unlock(&lock->queue_lock);
+
+	make_runnable(task);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/nucleus.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,83 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __NUCLEUS_H
+#define __NUCLEUS_H
+
+#include <config.h>
+#include <compiler.h>
+#include <errno.h>
+#include <string.h>
+
+extern volatile u64 ticks;
+
+extern struct datetime ipltime;
+
+/* The beginning of it all... */
+extern void start(u64 __memsize, u32 __iplsch);
+
+/* borrowed from Linux */
+#define container_of(ptr, type, member) ({                      \
+         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+         (type *)( (char *)__mptr - offsetof(type,member) );})
+
+/* borrowed from Linux */
+#define offsetof(type, member) __builtin_offsetof(type,member)
+
+static inline void lpswe(void *psw)
+{
+	asm volatile(
+		"	lpswe	0(%0)\n"
+	: /* output */
+	: /* input */
+	  "a" (psw)
+	: /* clobbered */
+	  "cc"
+	);
+}
+
+#define BUG()		do { \
+				asm volatile(".byte 0x00,0x00" : : : "memory"); \
+			} while(0)
+#define BUG_ON(cond)	do { \
+				if (unlikely(cond)) \
+					BUG(); \
+			} while(0)
+
+/*
+ * This should be as simple as a cast, but unfortunately, the BUG_ON check
+ * is there to make sure we never submit a truncated address to the channels
+ *
+ * In the future, the io code should check if IDA is necessary, and in that
+ * case allocate an IDAL & set the IDA ccw flag. Other parts of the system
+ * that require 31-bit address should do whatever their equivalent action
+ * is.
+ */
+static inline u32 ADDR31(void *ptr)
+{
+	u64 ip = (u64) ptr;
+
+	BUG_ON(ip & ~0x7fffffffull);
+
+	return (u32) ip;
+}
+
+/*
+ * stdio.h equivalents
+ */
+struct console;
+
+extern int vprintf(struct console *con, const char *fmt, va_list args)
+        __attribute__ ((format (printf, 2, 0)));
+extern int con_printf(struct console *con, const char *fmt, ...)
+        __attribute__ ((format (printf, 2, 3)));
+
+/*
+ * stdarg.h equivalents
+ */
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/page.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,74 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __PAGE_H
+#define __PAGE_H
+
+#include <list.h>
+
+#define PAGE_SHIFT	12
+#define PAGE_SIZE	(1<<PAGE_SHIFT)
+#define PAGE_MASK	(PAGE_SIZE-1)
+
+#define PAGE_INFO_BASE	((struct page*) 0x400000)
+
+#define ZONE_NORMAL	0
+#define ZONE_LOW	1
+
+#define ZONE_NORMAL_MAX_ORDER	(64-PAGE_SHIFT)
+#define ZONE_LOW_MAX_ORDER	(31-PAGE_SHIFT)
+
+/*
+ * This structure describes a page of memory
+ */
+struct page {
+	union {
+		struct list_head buddy;	/* buddy allocator list */
+		struct list_head guest;	/* guest storage list */
+	};
+};
+
+/*
+ * Externs
+ */
+extern void init_pages(void);
+
+/*
+ * Static inlines
+ */
+static inline struct page *page_num_to_ptr(u64 pnum)
+{
+	struct page *base = PAGE_INFO_BASE;
+
+	return &base[pnum];
+}
+
+static inline void *page_to_addr(struct page *page)
+{
+	u64 pagenum = (((u64) page) - ((u64) PAGE_INFO_BASE)) / sizeof(struct page);
+
+	return (void*) (pagenum << PAGE_SHIFT);
+}
+
+static inline struct page *addr_to_page(void *addr)
+{
+	struct page *base = PAGE_INFO_BASE;
+
+	return &base[((u64) addr) >> PAGE_SHIFT];
+}
+
+static inline int IS_LOW_ZONE(struct page *page)
+{
+	return ((u64) page_to_addr(page)) < (2UL*1024*1024*1024);
+}
+
+static inline int ZONE_TYPE(struct page *page)
+{
+	return IS_LOW_ZONE(page) ? ZONE_LOW : ZONE_NORMAL;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/sched.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,210 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __SCHED_H
+#define __SCHED_H
+
+#include <list.h>
+#include <page.h>
+#include <dat.h>
+#include <clock.h>
+#include <interrupt.h>
+
+#define CAN_SLEEP		1	/* safe to sleep */
+#define CAN_LOOP		2	/* safe to busy-wait */
+
+#define TASK_RUNNING		0
+#define TASK_SLEEPING		1
+#define TASK_LOCKED		2
+
+#define STACK_FRAME_SIZE	160
+
+#define SCHED_SLICE_MS		30	/* 30ms scheduler slice */
+#define SCHED_TICKS_PER_SLICE	(HZ / SCHED_SLICE_MS)
+
+#define HZ			100	/* number of ticks per second */
+
+struct psw {
+	u8 _zero0:1,
+	   r:1,			/* PER Mask (R)			*/
+	   _zero1:3,
+	   t:1,			/* DAT Mode (T)			*/
+	   io:1,		/* I/O Mask (IO)		*/
+	   ex:1;		/* External Mask (EX)		*/
+
+	u8 key:4,		/* Key				*/
+	   _zero2:1,
+	   m:1,			/* Machine-Check Mask (M)	*/
+	   w:1,			/* Wait State (W)		*/
+	   p:1;			/* Problem State (P)		*/
+
+	u8 as:2,		/* Address-Space Control (AS)	*/
+	   cc:2,		/* Condition Code (CC)		*/
+	   prog_mask:4;		/* Program Mask			*/
+
+	u8 _zero3:7,
+	   ea:1;		/* Extended Addressing (EA)	*/
+
+	u32 ba:1,		/* Basic Addressing (BA)	*/
+	    _zero4:31;
+
+	u64 ptr;
+};
+
+/*
+ * saved registers for guests
+ *
+ * NOTE: some registers are saved in the SIE control block!
+ */
+struct guest_regs {
+	u64 gpr[16];
+	u32 ar[16];
+	u64 fpr[64];
+	u32 fpcr;
+};
+
+/* saved registers for CP tasks */
+struct regs {
+	struct psw psw;
+	u64 gpr[16];
+	u64 cr1;
+};
+
+/*
+ * These states mirror those described in chapter 4 of SA22-7832-06
+ */
+enum virt_cpustate {
+	GUEST_STOPPED = 0,
+	GUEST_OPERATING,
+	GUEST_LOAD,
+	GUEST_CHECKSTOP,
+};
+
+#include <sie.h>
+
+struct virt_cpu {
+	/* the SIE control block is picky about alignment */
+	struct sie_cb sie_cb;
+
+	struct guest_regs regs;
+	u64 cpuid;
+
+	enum virt_cpustate state;
+};
+
+#define TASK_NAME_LEN		16
+
+/*
+ * This structure describes a running process.
+ */
+struct task {
+	struct regs regs;		/* saved registers */
+
+	struct list_head run_queue;	/* runnable list */
+	struct list_head proc_list;	/* processes list */
+	struct list_head blocked_list;	/* blocked on mutex/etc. list */
+
+	u64 slice_end_time;		/* end of slice time (ticks) */
+
+	struct virt_cpu *cpu;		/* guest cpu */
+
+	int state;			/* state */
+
+	char name[TASK_NAME_LEN+1];	/* task name */
+};
+
+struct virt_sys {
+	struct task *task;		/* the virtual CPU task */
+	struct user *directory;		/* the directory information */
+
+	struct console *con;		/* the login console */
+	int print_ts;			/* print timestamps */
+
+	struct list_head guest_pages;	/* list of guest pages */
+	struct list_head virt_devs;	/* list of guest virtual devs */
+	struct list_head online_users;	/* list of online users */
+
+	struct address_space as;	/* the guest storage */
+};
+
+extern void init_sched(void);		/* initialize the scheduler */
+extern struct task* create_task(char *name, int (*f)(void*), void*);
+					/* create a new task */
+extern void __schedule(struct psw *,
+		       int newstate);	/* scheduler helper - use with caution */
+extern void __schedule_svc(void);
+extern void __schedule_blocked_svc(void);
+
+extern void make_runnable(struct task *task);
+
+extern void list_tasks(struct console *con,
+		       void (*f)(struct console *, struct task*));
+
+/**
+ * current - the current task's task struct
+ */
+#define current		extract_task()
+
+#define PSA_CURRENT	((struct task**) 0x290)
+
+/**
+ * extract_task - return the current task struct
+ */
+static inline struct task *extract_task(void)
+{
+	return *PSA_CURRENT;
+}
+
+/**
+ * set_task_ptr - set the stack's task struct pointer
+ * @task:	task struct pointer to be made current
+ */
+static inline void set_task_ptr(struct task *task)
+{
+	*PSA_CURRENT = task;
+}
+
+/**
+ * schedule - used to explicitly yield the cpu
+ */
+static inline void schedule(void)
+{
+	/*
+	 * if we are not interruptable, we shouldn't call any functions that
+	 * may sleep - schedule() is guaranteed to sleep :)
+	 */
+	BUG_ON(!interruptable());
+
+	asm volatile(
+		"	svc	%0\n"
+	: /* output */
+	: /* input */
+	  "i" (SVC_SCHEDULE)
+	);
+}
+
+/**
+ * schedule_blocked - used to explicitly yield the cpu without readding the
+ * task to the runnable queue
+ */
+static inline void schedule_blocked(void)
+{
+	/*
+	 * if we are not interruptable, we shouldn't call any functions that
+	 * may sleep - schedule() is guaranteed to sleep :)
+	 */
+	BUG_ON(!interruptable());
+
+	asm volatile(
+		"	svc	%0\n"
+	: /* output */
+	: /* input */
+	  "i" (SVC_SCHEDULE_BLOCKED)
+	);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/shell.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,49 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __SHELL_H
+#define __SHELL_H
+
+#include <directory.h>
+
+#define SHELL_CMD_MAX_LEN	8
+
+/*
+ * This file should contain only externally (from CP's point of view)
+ * visible interfaces.
+ */
+extern struct console *oper_con;
+
+extern void spawn_oper_shell(struct console *con);
+extern void spawn_user_shell(struct console *con, struct user *u);
+extern int invoke_shell_cmd(struct virt_sys *sys, char *cmd, int len);
+extern int invoke_shell_logon(struct console *con, char *cmd, int len);
+
+extern void list_users(struct console *con, void (*f)(struct console *con,
+						      struct virt_sys *sys));
+
+/* All the different ways to reset the system */
+extern void guest_power_on_reset(struct virt_sys *sys);
+extern void guest_system_reset_normal(struct virt_sys *sys);
+extern void guest_system_reset_clear(struct virt_sys *sys);
+extern void guest_load_normal(struct virt_sys *sys);
+extern void guest_load_clear(struct virt_sys *sys);
+
+extern void run_guest(struct virt_sys *sys);
+extern void handle_interception(struct virt_sys *sys);
+
+extern int handle_instruction(struct virt_sys *sys);
+extern int handle_instruction_priv(struct virt_sys *sys);
+
+typedef int (*intercept_handler_t)(struct virt_sys *sys);
+
+#define SHELL_CMD_AUTH(s,a)	do { \
+					if ((s)->directory->auth > (a)) \
+						return -EPERM; \
+				} while(0)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/sie.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,82 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __SIE_H
+#define __SIE_H
+
+/*
+ * Taken from linux/arch/s390/include/asm/kvm_host.h
+ */
+
+#include <atomic.h>
+
+/*
+ * Constants for sie_cb->cpuflags
+ */
+#define CPUSTAT_HOST		0x80000000
+#define CPUSTAT_WAIT		0x10000000
+#define CPUSTAT_ECALL_PEND	0x08000000
+#define CPUSTAT_STOP_INT	0x04000000
+#define CPUSTAT_IO_INT		0x02000000
+#define CPUSTAT_EXT_INT		0x01000000
+#define CPUSTAT_RUNNING		0x00800000
+#define CPUSTAT_RETAINED	0x00400000
+#define CPUSTAT_TIMING_SUB	0x00020000
+#define CPUSTAT_SIE_SUB		0x00010000
+#define CPUSTAT_RRF		0x00008000
+#define CPUSTAT_SLSV		0x00004000
+#define CPUSTAT_SLSR		0x00002000
+#define CPUSTAT_ZARCH		0x00000800
+#define CPUSTAT_MCDS		0x00000100
+#define CPUSTAT_SM		0x00000080
+#define CPUSTAT_G		0x00000008
+#define CPUSTAT_J		0x00000002
+#define CPUSTAT_P		0x00000001
+
+struct sie_cb {
+	atomic_t	cpuflags;		/* 0x0000 */
+	u32		prefix;			/* 0x0004 */
+	u8		reserved8[32];		/* 0x0008 */
+	u64		cputm;			/* 0x0028 */
+	u64		ckc;			/* 0x0030 */
+	u64		epoch;			/* 0x0038 */
+	u8		reserved40[4];		/* 0x0040 */
+#define LCTL_CR0 0x8000
+	u16		lctl;			/* 0x0044 */
+	s16		icpua;			/* 0x0046 */
+	u32		ictl;			/* 0x0048 */
+	u32		eca;			/* 0x004c */
+	u8		icptcode;		/* 0x0050 */
+	u8		reserved51;		/* 0x0051 */
+	u16		ihcpu;			/* 0x0052 */
+	u8		reserved54[2];		/* 0x0054 */
+	u16		ipa;			/* 0x0056 */
+	u32		ipb;			/* 0x0058 */
+	u32		scaoh;			/* 0x005c */
+	u8		reserved60;		/* 0x0060 */
+	u8		ecb;			/* 0x0061 */
+	u8		reserved62[2];		/* 0x0062 */
+	u32		scaol;			/* 0x0064 */
+	u8		reserved68[4];		/* 0x0068 */
+	u32		todpr;			/* 0x006c */
+	u8		reserved70[16];		/* 0x0070 */
+	u64		gmsor;			/* 0x0080 */
+	u64		gmslm;			/* 0x0088 */
+	struct psw	gpsw;			/* 0x0090 */
+	u64		gg14;			/* 0x00a0 */
+	u64		gg15;			/* 0x00a8 */
+	u8		reservedb0[30];		/* 0x00b0 */
+	u16		iprcc;			/* 0x00ce */
+	u8		reservedd0[48];		/* 0x00d0 */
+	u64		gcr[16];		/* 0x0100 */
+	u64		gbea;			/* 0x0180 */
+	u8		reserved188[120];	/* 0x0188 */
+} __attribute__((aligned(256),packed));
+
+#define VCPU_ZARCH(vcpu)	(atomic_read(&((vcpu)->sie_cb.cpuflags)) & CPUSTAT_ZARCH)
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/slab.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,35 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __SLAB_H
+#define __SLAB_H
+
+#include <list.h>
+#include <spinlock.h>
+#include <page.h>
+
+struct slab {
+	u32 magic;			/* magic */
+	spinlock_t lock;		/* lock to protect entire slab */
+	struct list_head slab_pages;	/* list of pages */
+	struct slab *first;		/* pointer to first slab page */
+	u16 objsize;			/* effective object size */
+	u16 startoff;			/* first object offset */
+	u16 count;			/* number of objects in this page */
+	u16 used;			/* number of used objects */
+	u8 bitmap[0];			/* allocation bitmap */
+} __attribute__((packed));
+
+extern int init_slab(void);
+
+extern struct slab *create_slab(u16 objsize, u8 align);
+extern void free_slab(struct slab *slab);
+
+extern void *malloc(int size, int type);
+extern void free(void *ptr);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/spinlock.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,99 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __SPINLOCK_H
+#define __SPINLOCK_H
+
+/*
+ * Heavily based on Linux's spinlock implementation
+ */
+
+typedef struct {
+	volatile unsigned int lock;
+} spinlock_t;
+
+#define SPIN_LOCK_UNLOCKED	(spinlock_t) { 0 }
+
+static inline int __compare_and_swap(volatile unsigned int *lock,
+		unsigned int old, unsigned int new)
+{
+	asm volatile(
+		"	cs	%0,%3,%1"
+		: "=d" (old), "=Q" (*lock)
+		: "0" (old), "d" (new), "Q" (*lock)
+		: "cc", "memory" );
+	return old;
+}
+
+#define spin_is_locked(x) ((x)->lock != 0)
+
+#define SPIN_RETRY 1000
+
+extern void __spin_lock_wait(spinlock_t *lp, unsigned int pc);
+extern int __spin_trylock_retry(spinlock_t *lp, unsigned int pc);
+
+/**
+ * spin_lock - lock a spinlock
+ * @lock:	lock to lock
+ */
+static inline void spin_lock(spinlock_t *lock)
+{
+	unsigned long pc = 1 | (unsigned long) __builtin_return_address(0);
+
+	if (unlikely(__compare_and_swap(&lock->lock, 0, pc) != 0))
+		__spin_lock_wait(lock, pc);
+}
+
+/**
+ * spin_trylock - attempt to try to acquire a lock, but do not spin if
+ * acquisition would fail
+ * @lock:	lock to lock
+ */
+static inline int spin_trylock(spinlock_t *lock)
+{
+	unsigned long pc = 1 | (unsigned long) __builtin_return_address(0);
+
+	if (likely(__compare_and_swap(&lock->lock, 0, pc) == 0))
+		return 1;
+	return __spin_trylock_retry(lock, pc);
+}
+
+/**
+ * spin_unlock - unlock a lock
+ * @lock:	lock to unlock
+ */
+static inline void spin_unlock(spinlock_t *lock)
+{
+	__compare_and_swap(&lock->lock, lock->lock, 0);
+}
+
+extern void spin_lock_intsave(spinlock_t *lock, unsigned long *mask);
+extern void spin_unlock_intrestore(spinlock_t *lock, unsigned long mask);
+
+static inline void spin_double_lock(spinlock_t *l1, spinlock_t *l2)
+{
+	if (l1 < l2) {
+		spin_lock(l1);
+		spin_lock(l2);
+	} else {
+		spin_lock(l2);
+		spin_lock(l1);
+	}
+}
+
+static inline void spin_double_unlock(spinlock_t *l1, spinlock_t *l2)
+{
+	if (l1 < l2) {
+		spin_unlock(l2);
+		spin_unlock(l1);
+	} else {
+		spin_unlock(l1);
+		spin_unlock(l2);
+	}
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/splash.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,13 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __SPLASH_H
+#define __SPLASH_H
+
+extern char *splash[];
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/vcpu.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,74 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __VCPU_H
+#define __VCPU_H
+
+#include <sched.h>
+
+/*****************************************************************************/
+/* Guest exception queuing                                                   */
+
+enum PROG_EXCEPTION {
+	PROG_OPERAND		= 0x0001,
+	PROG_PRIV		= 0x0002,
+	PROG_EXEC		= 0x0003,
+	PROG_PROT		= 0x0004,
+	PROG_ADDR		= 0x0005,
+	PROG_SPEC		= 0x0006,
+	PROG_DATA		= 0x0007,
+};
+
+extern void queue_prog_exception(struct virt_sys *sys, enum PROG_EXCEPTION type, u64 param);
+
+/*****************************************************************************/
+/* Guest register reading & address calculation                              */
+
+static inline u64 __guest_gpr(struct virt_cpu *cpu, int gpr)
+{
+	u64 ret = cpu->regs.gpr[gpr];
+
+	if (!(atomic_read(&cpu->sie_cb.cpuflags) & CPUSTAT_ZARCH))
+		ret &= 0xffffffffULL;
+
+	return ret;
+}
+
+static inline u64 __guest_addr(struct virt_cpu *cpu, u64 disp, int x, int b)
+{
+	u64 mask;
+
+	if (cpu->sie_cb.gpsw.ea && cpu->sie_cb.gpsw.ba)
+		mask = ~0;
+	else if (!cpu->sie_cb.gpsw.ea && cpu->sie_cb.gpsw.ba)
+		mask = 0x7fffffff;
+	else if (!cpu->sie_cb.gpsw.ea && !cpu->sie_cb.gpsw.ba)
+		mask = 0x00ffffff;
+	else
+		BUG();
+
+	return (disp +
+		(x ? __guest_gpr(cpu, x) : 0) +
+		(b ? __guest_gpr(cpu, b) : 0)) & mask;
+}
+
+/*****************************************************************************/
+/* SIE Interception Param parsing & instruction decode                       */
+
+#define IP_TO_RAW(sie)		((((u64)(sie).ipa) << 32) | ((u64)(sie).ipb))
+
+static inline u64 RAW_S_1(struct virt_cpu *cpu)
+{
+	u64 raw = IP_TO_RAW(cpu->sie_cb);
+
+	return __guest_addr(cpu,
+			    (raw >> 16) & 0xfff,
+			    (raw) >> 28 & 0xf,
+			    0);
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/include/vdevice.h	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,36 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#ifndef __VDEVICE_H
+#define __VDEVICE_H
+
+#include <list.h>
+#include <directory.h>
+#include <sched.h>
+
+struct virt_device {
+	struct list_head devices;
+	enum directory_vdevtype vtype;	/* VDEV_CONS, VDEV_DED, ... */
+	u32 sch;			/* subchannel id */
+	u16 type;			/* 3330, 3215, ... */
+	u8 model;
+
+	union {
+		struct {
+			struct device *rdev;
+					/* real device */
+		} dedicate;
+	} u;
+
+	struct pmcw pmcw;		/* path info */
+	struct scsw scsw;		/* subchannel-status */
+};
+
+extern int alloc_virt_dev(struct virt_sys *sys,
+		struct directory_vdev *dirdev, u32 sch);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/mm/Makefile	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,1 @@
+objs-mm := buddy.o page.o slab.o dat.o
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/mm/buddy.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,212 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <list.h>
+#include <page.h>
+#include <mm.h>
+#include <buddy.h>
+#include <spinlock.h>
+
+/*
+ * Lists of free page ranges
+ */
+static struct list_head orders_normal[64-PAGE_SHIFT];
+static struct list_head orders_low[31-PAGE_SHIFT];
+
+static spinlock_t orders_lock = SPIN_LOCK_UNLOCKED;
+
+static void __init_buddy_alloc(u64 base, int pages, int max_order,
+			       struct list_head *orders)
+{
+	int order;
+	struct page *p;
+
+	for(order=0; order < max_order; order++) {
+		INIT_LIST_HEAD(&orders[order]);
+
+		if (pages & (1 << order)) {
+			p = addr_to_page(base);
+
+			list_add(&p->buddy, &orders[order]);
+
+			base += (PAGE_SIZE << order);
+		}
+	}
+}
+
+/*
+ * Initialize the buddy allocator. This is rather simple, and the only
+ * complication is that we must keep track of storage below 2GB separately
+ * since some IO related structures can address only the first 2GB. *sigh*
+ */
+void init_buddy_alloc(u64 start)
+{
+	u64 normal_pages;
+	u64 low_pages;
+
+	if (memsize > 2UL*1024*1024*1024) {
+		/* There are more than 2GB of storage */
+		low_pages = (2UL*1024*1024*1024 - start) >> PAGE_SHIFT;
+		normal_pages = (memsize - start) >> PAGE_SHIFT;
+		normal_pages -= low_pages;
+	} else {
+		/* All the storage is under the 2GB mark */
+		low_pages = (memsize - start) >> PAGE_SHIFT;
+		normal_pages = 0;
+	}
+
+	/* let's add all the free low storage to the lists */
+	__init_buddy_alloc(start, low_pages, ZONE_LOW_MAX_ORDER, orders_low);
+
+	/* now, let's add all the free storage above 2GB */
+	__init_buddy_alloc(2UL*1024*1024*1024, normal_pages, ZONE_NORMAL_MAX_ORDER,
+			   orders_normal);
+}
+
+static struct page *__do_alloc_pages(int order, struct list_head *orders)
+{
+	struct page *page;
+
+	if (!list_empty(&orders[order])) {
+		page = list_first_entry(&orders[order], struct page, buddy);
+
+		list_del(&page->buddy);
+
+		return page;
+	}
+
+	return NULL;
+}
+
+static struct page *__alloc_pages(int order, int type)
+{
+	struct page *p;
+
+	/* Do we have to use ZONE_LOW? */
+	if (type == ZONE_LOW)
+		goto zone_low;
+
+	p = __do_alloc_pages(order, orders_normal);
+	if (p)
+		return p;
+
+	/* If there was no ZONE_NORMAL page, let's try ZONE_LOW */
+
+zone_low:
+	return __do_alloc_pages(order, orders_low);
+}
+
+/*
+ * Split a given (actual) order allocation into an allocation of wanted
+ * order, and return the rest of pages to the unused lists
+ *
+ * E.g.,
+ *
+ * pages (base):
+ *
+ * +---+---+---+---+---+---+---+---+
+ * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
+ * +---+---+---+---+---+---+---+---+
+ *
+ * actual = 3
+ * wanted = 1
+ *
+ * return order 2 range back to free pool:
+ *
+ *                 +---+---+---+---+
+ *                 | 4 | 5 | 6 | 7 |
+ *                 +---+---+---+---+
+ *
+ * return order 1 range back to free pool:
+ *
+ *         +---+---+
+ *         | 2 | 3 |
+ *         +---+---+
+ *
+ * The End. Now, pages 2-7 are back in the free pool, and pages 0&1 are an
+ * order 1 allocation.
+ *
+ */
+static void __chip_pages(struct page *base, int actual, int wanted)
+{
+	struct page *p;
+	struct list_head *orders;
+
+	orders = (IS_LOW_ZONE(base) ? orders_low : orders_normal);
+
+	for(; actual > wanted; actual--) {
+		p = &base[1 << (actual-1)];
+		list_add(&p->buddy, &orders[actual-1]);
+	}
+}
+
+/**
+ * alloc_pages - allocate a series of consecutive pages
+ * @order:	allocate 2^order consecutive pages
+ * @type:	type of pages (<2GB, or anywhere)
+ */
+struct page *alloc_pages(int order, int type)
+{
+	struct page *page;
+	int gord;
+	unsigned long mask;
+	int max_order;
+
+	spin_lock_intsave(&orders_lock, &mask);
+
+	/* easy way */
+	page = __alloc_pages(order, type);
+	if (page)
+		goto out;
+
+	/*
+	 * There is no page-range of the given order, let's try to find the
+	 * smallest one larger and split it
+	 */
+
+	max_order = (type == ZONE_LOW ?
+			ZONE_LOW_MAX_ORDER : ZONE_NORMAL_MAX_ORDER);
+
+	for(gord=order+1; gord < max_order; gord++) {
+		if (gord >= max_order)
+			break;
+
+		page = __alloc_pages(gord, type);
+		if (!page)
+			continue;
+
+		__chip_pages(page, gord, order);
+
+		goto out;
+	}
+
+	/* alright, totally out of memory */
+	page = NULL;
+
+out:
+	spin_unlock_intrestore(&orders_lock, mask);
+
+	return page;
+}
+
+void free_pages(void *ptr, int order)
+{
+	struct page *base = addr_to_page(ptr);
+	unsigned long mask;
+	struct list_head *orders;
+
+	orders = IS_LOW_ZONE(base) ? orders_low : orders_normal;
+
+	spin_lock_intsave(&orders_lock, &mask);
+	list_add(&base->buddy, &orders[order]);
+	spin_unlock_intrestore(&orders_lock, mask);
+
+	/*
+	 * TODO: a more complex thing we could try is to coallesce adjecent
+	 * page ranges into one higher order one (defrag)
+	 */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/mm/dat.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,134 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <page.h>
+#include <buddy.h>
+#include <dat.h>
+#include <mm.h>
+
+static void *alloc_table(int order)
+{
+	struct page *p;
+
+	p = alloc_pages(order, ZONE_NORMAL);
+	BUG_ON(!p);
+	memset(page_to_addr(p), 0xff, PAGE_SIZE << order);
+
+	return page_to_addr(p);
+}
+
+/**
+ * dat_insert_page - insert a virt->phy mapping into an address space
+ * @as:		address space to add the mapping to
+ * @phy:	physical address to add
+ * @virt:	virtual address to add
+ */
+int dat_insert_page(struct address_space *as, u64 phy, u64 virt)
+{
+	struct dat_rte *region;
+	struct dat_ste *segment;
+	struct dat_pte *page;
+	void *ptr;
+
+	region = as->region_table;
+
+	if (!region) {
+		if (!as->segment_table)
+			/*
+			 * Need to allocate the segment table
+			 *
+			 * max of 2048 * 8-byte entries = 16 kbytes
+			 */
+			as->segment_table = alloc_table(2);
+
+		segment = as->segment_table;
+
+		goto walk_segment;
+	}
+
+	BUG_ON(DAT_RX(virt)); // FIXME: we don't support storage >2GB
+
+	if (region->origin == 0xfffffffffffffUL) {
+		/*
+		 * Need to allocate the segment table
+		 *
+		 * max of 2048 * 8-byte entries = 16 kbytes
+		 */
+		ptr = alloc_table(2);
+
+		region->origin = ADDR_TO_RTE_ORIGIN((u64) ptr);
+
+		region->tf = 0; /* FIXME: is this right? */
+		region->i = 0;
+		region->tt = DAT_RTE_TT_RTT;
+		region->tl = 3; /* FIXME: is this right? */
+		region->__reserved0 = 0;
+		region->__reserved1 = 0;
+	}
+
+	segment = RTE_ORIGIN_TO_ADDR(region->origin);
+
+walk_segment:
+	segment += DAT_SX(virt);
+
+	if (segment->origin == 0x1fffffffffffffUL) {
+		/*
+		 * Need to allocate the page table
+		 *
+		 * max of 256 * 8-byte entries = 2048 bytes
+		 */
+		ptr = alloc_table(0);
+
+		segment->origin = ADDR_TO_STE_ORIGIN((u64) ptr);
+		segment->p = 0;
+		segment->i = 0;
+		segment->c = 0;
+		segment->tt = DAT_STE_TT_ST;
+		segment->__reserved0 = 0;
+		segment->__reserved1 = 0;
+		segment->__reserved2 = 0;
+	}
+
+	page = STE_ORIGIN_TO_ADDR(segment->origin);
+	page += DAT_PX(virt);
+
+	page->pfra = phy >> PAGE_SHIFT;
+	page->i = 0;
+	page->p = 0;
+	page->__zero0 = 0;
+	page->__zero1 = 0;
+	page->__reserved = 0;
+
+	return 0;
+}
+
+void setup_dat(void)
+{
+	/* nothing to do! */
+}
+
+void load_as(struct address_space *as)
+{
+	struct dat_td cr1;
+
+	BUG_ON(!as->segment_table);
+
+	/*
+	 * Load up the PASCE (cr1)
+	 */
+	memset(&cr1, 0, sizeof(struct dat_td));
+	cr1.origin = ((u64)as->segment_table) >> 12;
+	cr1.dt = DAT_TD_DT_ST;
+	cr1.tl = 3;
+
+	asm volatile(
+		"	lctlg	1,1,%0\n"
+	: /* output */
+	: /* input */
+	  "m" (cr1)
+	);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/mm/page.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,35 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <list.h>
+#include <page.h>
+#include <mm.h>
+
+/*
+ * Main storage size
+ */
+u64 memsize;
+
+/*
+ * Initialize fields in a struct page
+ */
+static void __init_page(struct page *page)
+{
+	INIT_LIST_HEAD(&page->buddy);
+}
+
+/*
+ * Initialize struct page for each available page
+ */
+void init_pages(void)
+{
+	u64 pnum;
+
+	for(pnum=0; pnum < (memsize>>PAGE_SHIFT); pnum++)
+		__init_page(page_num_to_ptr(pnum));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/mm/slab.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,286 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <magic.h>
+#include <buddy.h>
+#include <slab.h>
+#include <page.h>
+
+static struct slab *generic[7];
+
+/*
+ * Create slab caches for 16, 32, 64, 128, and 256 byte allocations
+ */
+int init_slab(void)
+{
+	generic[0] = create_slab(16, 4);
+	if (!generic[0])
+		goto out_err;
+
+	generic[1] = create_slab(32, 4);
+	if (!generic[1])
+		goto out_err;
+
+	generic[2] = create_slab(64, 4);
+	if (!generic[2])
+		goto out_err;
+
+	generic[3] = create_slab(128, 4);
+	if (!generic[3])
+		goto out_err;
+
+	generic[4] = create_slab(256, 8);
+	if (!generic[4])
+		goto out_err;
+
+	generic[5] = create_slab(512, 8);
+	if (!generic[5])
+		goto out_err;
+
+	generic[6] = create_slab(1024, 8);
+	if (!generic[6])
+		goto out_err;
+
+	return 0;
+
+out_err:
+	free_slab(generic[0]);
+	free_slab(generic[1]);
+	free_slab(generic[2]);
+	free_slab(generic[3]);
+	free_slab(generic[4]);
+	free_slab(generic[5]);
+	free_slab(generic[6]);
+
+	return -ENOMEM;
+}
+
+/**
+ * create_slab - Create a new slab
+ * @objsize:	object size in bytes
+ * @align:	object alignment in bytes (must be a power of two)
+ */
+struct slab *create_slab(u16 objsize, u8 align)
+{
+	struct page *page;
+	struct slab *slab;
+
+	if (!objsize || !align)
+		return NULL;
+
+	page = alloc_pages(0, ZONE_NORMAL);
+	if (!page)
+		return NULL;
+
+	slab = page_to_addr(page);
+	memset(slab, 0, PAGE_SIZE);
+
+	slab->magic = SLAB_MAGIC;
+	slab->lock = SPIN_LOCK_UNLOCKED;
+	INIT_LIST_HEAD(&slab->slab_pages);
+	slab->first = slab;
+
+	align--; /* turn into a mask */
+
+	/* actual object size */
+	if (objsize & align)
+		objsize += align + 1 - (objsize & align);
+	slab->objsize = objsize;
+
+	/* number of objects in a page */
+	slab->count = 8 * (PAGE_SIZE - sizeof(struct slab)) / (8 * objsize + 1);
+
+	/* offset of the first object */
+	slab->startoff = sizeof(struct slab) + (slab->count + 4) / 8;
+	if (slab->startoff & align) {
+		u16 tmp;
+
+		slab->startoff += align + 1 - (slab->startoff & align);
+
+		/*
+		 * TODO: there's got to be a better way to ensure that we
+		 * fit into a single page
+		 */
+		tmp = slab->startoff + slab->count * slab->objsize;
+		if (tmp > PAGE_SIZE)
+			slab->count--;
+	}
+
+	slab->used = 0;
+
+	return slab;
+}
+
+void free_slab(struct slab *passed_slab)
+{
+	struct slab *slab;
+
+	if (!passed_slab)
+		return;
+
+	BUG_ON(passed_slab->magic != SLAB_MAGIC);
+	BUG_ON(passed_slab->used != 0);
+
+	list_for_each_entry(slab, &passed_slab->slab_pages, slab_pages) {
+		BUG_ON(slab->magic != SLAB_CONT_MAGIC);
+		BUG_ON(slab->used != 0);
+
+		/*
+		 * Theoretically, we should remove the page from the list,
+		 * but no one _really_ cares
+		 */
+
+		free_pages(slab, 0);
+	}
+
+	free_pages(passed_slab, 0);
+}
+
+static inline void *__alloc_slab_obj_newpage(struct slab *slab, int type)
+{
+	struct page *page;
+	struct slab *new;
+
+	page = alloc_pages(0, type);
+	if (!page)
+		return ERR_PTR(-ENOMEM);
+
+	new = page_to_addr(page);
+
+	memset(new, 0, PAGE_SIZE);
+	new->magic = SLAB_CONT_MAGIC;
+	new->first = slab;
+	new->objsize = slab->objsize;
+	new->startoff = slab->startoff;
+	new->count = slab->count;
+
+	/* add it to the current slab */
+	list_add_tail(&new->slab_pages, &slab->slab_pages);
+
+	return new;
+}
+
+static void *alloc_slab_obj(struct slab *passed_slab, int type)
+{
+	struct slab *slab = passed_slab;
+	void *obj = NULL;
+	int objidx;
+	u8 *bits;
+	u8 mask;
+	unsigned long int_mask;
+
+	if (!slab)
+		return NULL;
+
+	BUG_ON(passed_slab->magic != SLAB_MAGIC);
+
+	spin_lock_intsave(&passed_slab->lock, &int_mask);
+
+	/*
+	 * Does the first slab page have an unused object _AND_ is in the
+	 * right zone?
+	 */
+	if (slab->used < slab->count && ZONE_TYPE(addr_to_page(slab)) == type)
+		goto alloc;
+
+	/*
+	 * No. Find the first slab page that has unused objects
+	 */
+	list_for_each_entry(slab, &passed_slab->slab_pages, slab_pages)
+		if (slab->used < slab->count &&
+		    ZONE_TYPE(addr_to_page(slab)) == type)
+			goto alloc;
+
+	/*
+	 * None of the pages have an unused object. Let's allocate another
+	 * page
+	 */
+
+	slab = __alloc_slab_obj_newpage(passed_slab, type);
+	if (IS_ERR(slab))
+		/*
+		 * FIXME: if we tried to get a ZONE_NORMAL and failed,
+		 * shouldn't we retry with ZONE_LOW?
+		 */
+		goto out;
+
+
+alloc:
+	/* found a page */
+	for (objidx = 0; objidx < slab->count; objidx++) {
+		bits = slab->bitmap + (objidx/8);
+
+		mask = 1 << (7 - (objidx % 8));
+
+		if (*bits & mask)
+			continue;
+
+		slab->used++;
+		*bits |= mask;
+
+		obj = ((u8*) slab) + slab->startoff + slab->objsize * objidx;
+		break;
+	}
+
+out:
+	spin_unlock_intrestore(&passed_slab->lock, int_mask);
+
+	return obj;
+}
+
+static void free_slab_obj(void *ptr)
+{
+	struct slab *slab;
+	int objidx;
+	u8 *bits;
+	unsigned long int_mask;
+
+	/* get the slab object ptr */
+	slab = (struct slab *) (((u64) ptr) & ~0xfff);
+
+	spin_lock_intsave(&slab->first->lock, &int_mask);
+
+	/* calculate the object number */
+	objidx = (((u64) ptr) - ((u64) slab) - slab->startoff) / slab->objsize;
+
+	/* update the bitmap */
+	bits = slab->bitmap + (objidx/8);
+	*bits &= ~(1 << (7 - (objidx % 8)));
+
+	if (--slab->used) {
+		/* FIXME: free the page? */
+	}
+
+	spin_unlock_intrestore(&slab->first->lock, int_mask);
+}
+
+void *malloc(int size, int type)
+{
+	if (!size)
+		return NULL;
+	if (size <= 16)
+		return alloc_slab_obj(generic[0], type);
+	if (size <= 32)
+		return alloc_slab_obj(generic[1], type);
+	if (size <= 64)
+		return alloc_slab_obj(generic[2], type);
+	if (size <= 128)
+		return alloc_slab_obj(generic[3], type);
+	if (size <= 256)
+		return alloc_slab_obj(generic[4], type);
+	if (size <= 512)
+		return alloc_slab_obj(generic[5], type);
+	if (size <= 1024)
+		return alloc_slab_obj(generic[6], type);
+	return NULL;
+}
+
+void free(void *ptr)
+{
+	if (ptr)
+		free_slab_obj(ptr);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/nucleus/Makefile	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,2 @@
+objs-nucleus := init.o io.o printf.o ebcdic.o int.o ext.o svc.o pgm.o \
+	spinlock.o mutex.o sched.o
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/nucleus/ebcdic.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,161 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <ebcdic.h>
+
+/*
+ * Tables taken from Linux's arch/s390/kernel/ebcdic.c
+ */
+
+/*
+ * ASCII (IBM PC 437)  -> EBCDIC 037
+ */
+u8 ascii2ebcdic_table[256] =
+{
+ /*00 NUL   SOH   STX   ETX   EOT   ENQ   ACK   BEL */
+     0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
+ /*08  BS    HT    LF    VT    FF    CR    SO    SI */
+ /*              ->NL                               */
+     0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ /*10 DLE   DC1   DC2   DC3   DC4   NAK   SYN   ETB */
+     0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
+ /*18 CAN    EM   SUB   ESC    FS    GS    RS    US */
+ /*                               ->IGS ->IRS ->IUS */
+     0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F,
+ /*20  SP     !     "     #     $     %     &     ' */
+     0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
+ /*28   (     )     *     +     ,     -    .      / */
+     0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
+ /*30   0     1     2     3     4     5     6     7 */
+     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+ /*38   8     9     :     ;     <     =     >     ? */
+     0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
+ /*40   @     A     B     C     D     E     F     G */
+     0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+ /*48   H     I     J     K     L     M     N     O */
+     0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
+ /*50   P     Q     R     S     T     U     V     W */
+     0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
+ /*58   X     Y     Z     [     \     ]     ^     _ */
+     0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D,
+ /*60   `     a     b     c     d     e     f     g */
+     0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ /*68   h     i     j     k     l     m     n     o */
+     0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ /*70   p     q     r     s     t     u     v     w */
+     0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
+ /*78   x     y     z     {     |     }     ~    DL */
+     0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
+ /*80*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*88*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*90*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*98*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*A0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*A8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*B0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*B8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*C0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*C8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*D0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*D8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*E0        sz						*/
+     0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*E8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*F0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*F8*/
+     0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF
+};
+
+/*
+ * EBCDIC 037 -> ASCII (IBM PC 437)
+ */
+u8 ebcdic2ascii_table[256] =
+{
+ /* 0x00   NUL   SOH   STX   ETX  *SEL    HT  *RNL   DEL */
+          0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
+ /* 0x08   -GE  -SPS  -RPT    VT    FF    CR    SO    SI */
+          0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ /* 0x10   DLE   DC1   DC2   DC3  -RES   -NL    BS  -POC
+                                  -ENP  ->LF             */
+          0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
+ /* 0x18   CAN    EM  -UBS  -CU1  -IFS  -IGS  -IRS  -ITB
+                                                    -IUS */
+          0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ /* 0x20   -DS  -SOS    FS  -WUS  -BYP    LF   ETB   ESC
+                                  -INP                   */
+          0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
+ /* 0x28   -SA  -SFE   -SM  -CSP  -MFA   ENQ   ACK   BEL
+                       -SW                               */
+          0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
+ /* 0x30  ----  ----   SYN   -IR   -PP  -TRN  -NBS   EOT */
+          0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
+ /* 0x38  -SBS   -IT  -RFF  -CU3   DC4   NAK  ----   SUB */
+          0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
+ /* 0x40    SP   RSP           ä              ----       */
+          0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
+ /* 0x48                       .     <     (     +     | */
+          0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
+ /* 0x50     &                                      ---- */
+          0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
+ /* 0x58           ß     !     $     *     )     ;       */
+          0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
+ /* 0x60     -     /  ----     Ä  ----  ----  ----       */
+          0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
+ /* 0x68              ----     ,     %     _     >     ? */
+          0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
+ /* 0x70  ----        ----  ----  ----  ----  ----  ---- */
+          0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
+ /* 0x78     *     `     :     #     @     '     =     " */
+          0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
+ /* 0x80     *     a     b     c     d     e     f     g */
+          0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ /* 0x88     h     i              ----  ----  ----       */
+          0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
+ /* 0x90     °     j     k     l     m     n     o     p */
+          0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
+ /* 0x98     q     r                    ----        ---- */
+          0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
+ /* 0xA0           ~     s     t     u     v     w     x */
+          0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ /* 0xA8     y     z              ----  ----  ----  ---- */
+          0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
+ /* 0xB0     ^                    ----     §  ----       */
+          0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
+ /* 0xB8        ----     [     ]  ----  ----  ----  ---- */
+          0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
+ /* 0xC0     {     A     B     C     D     E     F     G */
+          0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ /* 0xC8     H     I  ----           ö              ---- */
+          0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
+ /* 0xD0     }     J     K     L     M     N     O     P */
+          0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
+ /* 0xD8     Q     R  ----           ü                   */
+          0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
+ /* 0xE0     \           S     T     U     V     W     X */
+          0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ /* 0xE8     Y     Z        ----     Ö  ----  ----  ---- */
+          0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
+ /* 0xF0     0     1     2     3     4     5     6     7 */
+          0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ /* 0xF8     8     9  ----  ----     Ü  ----  ----  ---- */
+          0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/nucleus/ext.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,51 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <interrupt.h>
+#include <sched.h>
+
+/*
+ * This is the tick counter, it starts at 0 when we initialize the nucleus
+ */
+volatile u64 ticks;
+
+void set_timer(void)
+{
+	u64 time = 1000 * 1000 * CLK_MICROSEC / HZ;
+
+	asm volatile(
+		"spt	%0\n"		/* set timer value */
+	: /* output */
+	: /* input */
+	  "m" (time)
+	);
+}
+
+void __ext_int_handler(void)
+{
+	if (*EXT_INT_CODE == 0x1005) {
+		/*
+		 * This is the timer, let's call the scheduler.
+		 */
+
+		ticks++;
+
+		set_timer();
+
+		/*
+		 * No need to save the registers, the assembly stub that
+		 * called this function already saved them at PSA_INT_GPR
+		 */
+		if (!(ticks % SCHED_TICKS_PER_SLICE)) {
+			__schedule(EXT_INT_OLD_PSW, TASK_SLEEPING);
+
+			/* unreachable */
+			BUG();
+		}
+	}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/nucleus/init.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,207 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <mm.h>
+#include <dat.h>
+#include <slab.h>
+#include <page.h>
+#include <buddy.h>
+#include <io.h>
+#include <sched.h>
+#include <device.h>
+#include <console.h>
+#include <interrupt.h>
+#include <magic.h>
+#include <shell.h>
+
+static struct psw new_io_psw = {
+	.ea	= 1,
+	.ba	= 1,
+
+	.ptr  = (u64) &IO_INT,
+};
+
+static struct psw new_ext_psw = {
+	.ea	= 1,
+	.ba	= 1,
+
+	.ptr	= (u64) &EXT_INT,
+};
+
+static struct psw new_svc_psw = {
+	.ea	= 1,
+	.ba	= 1,
+
+	.ptr	= (u64) &SVC_INT,
+};
+
+static struct psw new_pgm_psw = {
+	.ea	= 1,
+	.ba	= 1,
+
+	.ptr	= (u64) &PGM_INT,
+};
+
+u8 *int_stack_ptr;
+
+/* the time HVF got IPLd */
+struct datetime ipltime;
+
+static void init_int_stack(void)
+{
+	struct page *page;
+
+	page = alloc_pages(0, ZONE_NORMAL);
+	BUG_ON(!page);
+
+	int_stack_ptr = PAGE_SIZE + (u8*)page_to_addr(page);
+}
+
+static void idle_task_body(void)
+{
+	/*
+	 * Warning: hack alert! The following overrides what __init_task
+	 * set, this allows us to skip the usual start_task wrapper.
+	 */
+	current->regs.psw.w   = 1;
+	current->regs.psw.ptr = MAGIC_PSW_IDLE_CODE;
+
+	/*
+	 * Load the new PSW that'll wait with special magic code set
+	 */
+	lpswe(&current->regs.psw);
+
+	BUG();
+}
+
+/*
+ * This is where everything starts
+ */
+void start(u64 __memsize, u32 __iplsch)
+{
+	u64 first_free_page;
+	u64 struct_page_bytes;
+	struct psw psw;
+	struct console *opcon; /* operator's console */
+
+	/*
+	 * ticks starts at 0
+	 */
+	ticks = 0;
+
+	/*
+	 * save total system memory size
+	 */
+	memsize = __memsize;
+
+	/*
+	 * Initialize struct page entries
+	 */
+	init_pages();
+
+	/*
+	 * Calculate address of the first free page (we may have to round
+	 * up)
+	 */
+	struct_page_bytes = (memsize >> PAGE_SHIFT) * sizeof(struct page);
+
+	first_free_page = (u64) PAGE_INFO_BASE + struct_page_bytes;
+	if (struct_page_bytes & (PAGE_SIZE-1))
+		first_free_page += PAGE_SIZE - (struct_page_bytes & (PAGE_SIZE-1));
+
+	/*
+	 * Initialize the buddy allocator
+	 */
+	init_buddy_alloc(first_free_page);
+
+	/*
+	 * Initialize slab allocator default caches
+	 */
+	init_slab();
+
+	/*
+	 * Set up interrupt PSWs
+	 */
+	memcpy(IO_INT_NEW_PSW, &new_io_psw, sizeof(struct psw));
+	memcpy(EXT_INT_NEW_PSW, &new_ext_psw, sizeof(struct psw));
+	memcpy(SVC_INT_NEW_PSW, &new_svc_psw, sizeof(struct psw));
+	memcpy(PGM_INT_NEW_PSW, &new_pgm_psw, sizeof(struct psw));
+
+	/* Turn on Low-address Protection */
+	lap_on();
+
+	/*
+	 * Set up page table entries for the nucleus
+	 */
+	setup_dat();
+
+	/*
+	 * Allocate & initialize the interrupt stack
+	 */
+	init_int_stack();
+
+	/*
+	 * Initialize the io subsystem
+	 */
+	init_io();
+
+	/*
+	 * Register all the device drivers
+	 */
+	register_drivers();
+
+	/*
+	 * Time to enable interrupts => load new psw
+	 */
+	memset(&psw, 0, sizeof(struct psw));
+	psw.io	= 1;
+	psw.ea	= 1;
+	psw.ba	= 1;
+
+	asm volatile(
+		"	larl	%%r1,0f\n"
+		"	stg	%%r1,%0\n"
+		"	lpswe	%1\n"
+		"0:\n"
+	: /* output */
+	  "=m" (psw.ptr)
+	: /* input */
+	  "m" (psw)
+	: /* clobbered */
+	  "r1"
+	);
+
+	/*
+	 * Let's discover all the devices attached
+	 */
+	scan_devices();
+
+	/*
+	 * Initialize the process scheduler
+	 */
+	init_sched();
+
+	/*
+	 * IPL is more or less done
+	 */
+	get_parsed_tod(&ipltime);
+
+	opcon = start_oper_console();
+
+	con_printf(opcon, "NOW %02d:%02d:%02d UTC %04d-%02d-%02d\n\n",
+		   ipltime.th, ipltime.tm, ipltime.ts, ipltime.dy,
+		   ipltime.dm, ipltime.dd);
+
+	spawn_oper_shell(opcon);
+
+	/*
+	 * THIS IS WHERE THE IDLE TASK BEGINS
+	 */
+
+	idle_task_body();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/nucleus/int.S	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,121 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+.text
+
+#include <interrupt.h>
+
+#
+# IO Interrupt
+#
+	.align	4
+.globl IO_INT
+	.type	IO_INT, @function
+IO_INT:
+	# save regs
+	STMG	%r0,%r15,0x200(%r0)
+
+	# set up stack
+	LARL	%r15, int_stack_ptr
+	LG	%r15, 0(%r15)
+	AGHI	%r15,-160
+
+	LARL	%r14, __io_int_handler
+	BALR	%r14, %r14		# call the real handler
+
+	# restore regs
+	LMG	%r0,%r15,0x200(%r0)
+
+	LPSWE	0x170			# go back to what we interrupted
+
+
+#
+# External Interrupt
+#
+	.align 4
+.globl EXT_INT
+	.type	EXT_INT, @function
+EXT_INT:
+	# save regs
+	STMG	%r0,%r15,0x200(%r0)
+
+	# set up stack
+	LARL	%r15, int_stack_ptr
+	LG	%r15, 0(%r15)
+	AGHI	%r15,-160
+
+	LARL	%r14, __ext_int_handler
+	BALR	%r14, %r14		# call the real handler
+
+	#
+	# NOTE: we may never return from the C-interrupt handler if the
+	# interrupt was caused by the timer clock, in which case the
+	# scheduler kicks in, and gives control to someone else
+	#
+
+	# restore regs
+	LMG	%r0,%r15,0x200(%r0)
+
+	LPSWE	0x130			# go back to what we interrupted
+
+
+#
+# Supervisor-Call Interrupt
+#
+	.align 4
+.globl SVC_INT
+	.type	SVC_INT, @function
+SVC_INT:
+	# save regs
+	STMG	%r0,%r15,0x200(%r0)
+
+	# set up stack
+	LARL	%r15, int_stack_ptr
+	LG	%r15, 0(%r15)
+	AGHI	%r15,-160
+
+	# find the right handler
+	LARL	%r14, svc_table		# table address
+	LGH	%r2, 0x8a		# interruption code
+	SLL	%r2, 3
+					# byte offset into table
+	LG	%r14, 0(%r2,%r14)	# load value from table
+
+	BALR	%r14, %r14		# call the real handler
+
+	# restore regs
+	LMG	%r0,%r15,0x200(%r0)
+
+	LPSWE	0x140			# go back to what we interrupted
+
+
+#
+# Program Interrupt
+#
+	.align 4
+.globl PGM_INT
+	.type	PGM_INT, @function
+PGM_INT:
+	# save regs
+	STMG	%r0,%r15,0x200(%r0)
+
+	# set up stack
+	LARL	%r15, int_stack_ptr
+	LG	%r15, 0(%r15)
+	AGHI	%r15,-160
+
+	LARL	%r14, __pgm_int_handler
+	BALR	%r14, %r14		# call the real handler
+
+	#
+	# NOTE: we may never return from the C-interrupt handler
+	#
+
+	# restore regs
+	LMG	%r0,%r15,0x200(%r0)
+
+	LPSWE	0x150			# go back to what we interrupted
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/nucleus/io.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,213 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <channel.h>
+#include <io.h>
+#include <interrupt.h>
+#include <device.h>
+#include <sched.h>
+#include <atomic.h>
+#include <spinlock.h>
+#include <buddy.h>
+#include <sched.h>
+
+/*
+ * Helper function to make sure the io_op has everything set right
+ */
+static int __verify_io_op(struct io_op *ioop)
+{
+	// FIXME: check everything that makes sense to check
+	return 0;
+}
+
+static void __reset_reserved_fields(struct io_op *ioop)
+{
+	ioop->orb.__zero1 = 0;
+	ioop->orb.__zero2 = 0;
+
+	ioop->orb.__reserved1 = 0;
+	ioop->orb.__reserved2 = 0;
+	ioop->orb.__reserved3 = 0;
+	ioop->orb.__reserved4 = 0;
+	ioop->orb.__reserved5 = 0;
+	ioop->orb.__reserved6 = 0;
+}
+
+/* NOTE: assumes dev->q_lock is held */
+static void __submit_io(struct device *dev)
+{
+	struct io_op *ioop;
+	int err;
+
+	if (dev->q_cur)
+		return;
+
+	if (list_empty(&dev->q_out))
+		return;
+
+	ioop = list_entry(dev->q_out.next, struct io_op, list);
+
+	err = start_sch(dev->sch, &ioop->orb);
+	if (!err) {
+		list_del(&ioop->list);
+		dev->q_cur = ioop;
+	} else
+		ioop->err = err;
+}
+
+/*
+ * Submit an I/O request to a subchannel, and set up everything needed to
+ * handle the operation
+ */
+int submit_io(struct device *dev, struct io_op *ioop, int flags)
+{
+	static atomic_t op_id_counter;
+	unsigned long intmask;
+	int err = -EBUSY;
+
+	err = __verify_io_op(ioop);
+	if (err)
+		return 0;
+
+	/* make sure all reserved fields have the right values */
+	__reset_reserved_fields(ioop);
+
+	ioop->err = 0;
+	ioop->orb.param = atomic_inc_return(&op_id_counter);
+	atomic_set(&ioop->done, 0);
+
+	/* add it to the list of ops */
+	spin_lock_intsave(&dev->q_lock, &intmask);
+	list_add_tail(&ioop->list, &dev->q_out);
+
+	__submit_io(dev); /* try to submit an IO right now */
+	spin_unlock_intrestore(&dev->q_lock, intmask);
+
+	if (flags & CAN_LOOP) {
+		while(!atomic_read(&ioop->done))
+			;
+	} else if (flags & CAN_SLEEP) {
+		while(!atomic_read(&ioop->done))
+			schedule();
+	}
+
+	return 0;
+}
+
+/*
+ * Initialize the channel I/O subsystem
+ */
+void init_io(void)
+{
+	u64 cr6;
+
+	/* enable all I/O interrupt classes */
+	asm volatile(
+		"stctg	6,6,%0\n"	/* get cr6 */
+		"oi	%1,0xff\n"	/* enable all */
+		"lctlg	6,6,%0\n"	/* reload cr6 */
+	: /* output */
+	: /* input */
+	  "m" (cr6),
+	  "m" (*(u64*) (((u8*)&cr6) + 4))
+	);
+}
+
+static int default_io_handler(struct device *dev, struct io_op *ioop, struct irb *irb)
+{
+	ioop->err = -EAGAIN;
+
+	/* Unit check? */
+	if (irb->scsw.dev_status & 0x02)
+		ioop->err = -EUCHECK; /* FIXME: we should bail */
+
+	/* Device End is set, we're done */
+	if (irb->scsw.dev_status & 0x04)
+		ioop->err = 0;
+
+	return 0;
+}
+
+static void __cpu_initiated_io(struct device *dev, struct io_op *ioop, struct irb *irb)
+{
+	unsigned long intmask;
+
+	ioop->err = test_sch(dev->sch, irb);
+
+	if (!ioop->err && ioop->handler)
+		ioop->handler(dev, ioop, irb);
+	else if (!ioop->err)
+		default_io_handler(dev, ioop, irb);
+
+	/*
+	 * We can do this, because the test_sch function sets ->err, and
+	 * therefore regardless of ->handler being defined, ->err will have
+	 * a reasonable value
+	 */
+	if (ioop->err == -EAGAIN)
+		return; /* leave handler registered */
+
+	/* ...and remove it form the list */
+	spin_lock_intsave(&dev->q_lock, &intmask);
+	dev->q_cur = NULL;
+
+	__submit_io(dev); /* try to submit another IO */
+	spin_unlock_intrestore(&dev->q_lock, intmask);
+
+	/* flag io_op as done... */
+	atomic_set(&ioop->done, 1);
+
+	/* call the destructor if there is one */
+	if (ioop->dtor)
+		ioop->dtor(dev, ioop);
+}
+
+static void __dev_initiated_io(struct device *dev, struct irb *irb)
+{
+}
+
+/*
+ * I/O Interrupt handler (C portion)
+ */
+void __io_int_handler(void)
+{
+	unsigned long intmask;
+	struct io_op *ioop;
+	struct device *dev;
+	struct irb irb;
+
+	dev = find_device_by_sch(IO_INT_CODE->ssid);
+	BUG_ON(IS_ERR(dev));
+
+	spin_lock_intsave(&dev->q_lock, &intmask);
+	ioop = dev->q_cur;
+	spin_unlock_intrestore(&dev->q_lock, intmask);
+
+	if (ioop && ioop->orb.param == IO_INT_CODE->param &&
+	    dev->sch == IO_INT_CODE->ssid) {
+		/*
+		 * CPU-initiated operation
+		 */
+
+		__cpu_initiated_io(dev, ioop, &irb);
+		dev_put(dev);
+		return;
+	}
+
+	/*
+	 * device-initiated operation
+	 */
+	BUG_ON(test_sch(dev->sch, &irb));
+
+	atomic_inc(&dev->attention);
+
+	if (dev->dev->interrupt)
+		dev->dev->interrupt(dev, &irb);
+	else
+		__dev_initiated_io(dev, &irb);
+	dev_put(dev);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/nucleus/mutex.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,25 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <mutex.h>
+
+/* slow-path mutex locking */
+void __mutex_lock(mutex_t *lock)
+{
+	spin_lock(&lock->queue_lock);
+
+	if (unlikely(atomic_add_unless(&lock->state, -1, 0))) {
+		spin_unlock(&lock->queue_lock);
+		return; /* aha! someone released it & it's ours now! */
+	}
+
+	list_add_tail(&current->blocked_list, &lock->queue);
+
+	spin_unlock(&lock->queue_lock);
+
+	schedule_blocked();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/nucleus/pgm.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,69 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <interrupt.h>
+#include <ebcdic.h>
+#include <vsprintf.h>
+
+static char abend_msg_buf[1024];
+
+/*
+ * All is lost! All hands abandon ship!
+ *
+ * Try to write out a message to a special buffer to help debugging, and
+ * then stop the CPU.
+ */
+static void abend(void)
+{
+	int ret;
+
+	ret = snprintf(abend_msg_buf, 1024,
+		"ABEND       %04x"
+		"PSW        ILC %d"
+		"%016llx%016llx"
+		"GPR             "
+		"%016llx%016llx%016llx%016llx"
+		"%016llx%016llx%016llx%016llx"
+		"%016llx%016llx%016llx%016llx"
+		"%016llx%016llx%016llx%016llx",
+		*PGM_INT_CODE, (*PGM_INT_ILC) >> 1,
+		*((u64*) PGM_INT_OLD_PSW), *(((u64*) PGM_INT_OLD_PSW)+1),
+		PSA_INT_GPR[0],  PSA_INT_GPR[1],  PSA_INT_GPR[2],  PSA_INT_GPR[3],
+		PSA_INT_GPR[4],  PSA_INT_GPR[5],  PSA_INT_GPR[6],  PSA_INT_GPR[7],
+		PSA_INT_GPR[8],  PSA_INT_GPR[9],  PSA_INT_GPR[10], PSA_INT_GPR[11],
+		PSA_INT_GPR[12], PSA_INT_GPR[13], PSA_INT_GPR[14], PSA_INT_GPR[15]
+	);
+
+	if (ret)
+		ascii2ebcdic((u8 *) abend_msg_buf, ret);
+
+	/*
+	 * halt the cpu
+	 *
+	 * NOTE: we don't care about not clobbering registers as when this
+	 * code executes, the CPU will be stopped.
+	 */
+	asm volatile(
+		"LR	%%r15, %0		# buffer pointer\n"
+		"SR	%%r1, %%r1		# not used, but should be zero\n"
+		"SR	%%r3, %%r3 		# CPU Address\n"
+		"SIGP	%%r1, %%r3, 0x05	# Signal, order 0x05\n"
+	: /* out */
+	: /* in */
+	  "a" (abend_msg_buf)
+	);
+
+	/*
+	 * If SIGP failed, loop forever
+	 */
+	for(;;);
+}
+
+void __pgm_int_handler(void)
+{
+	abend();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/nucleus/printf.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,51 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <channel.h>
+#include <console.h>
+#include <directory.h>
+#include <ebcdic.h>
+#include <slab.h>
+#include <clock.h>
+#include <sched.h>
+#include <vsprintf.h>
+#include <stdarg.h>
+
+int vprintf(struct console *con, const char *fmt, va_list args)
+{
+	struct datetime dt;
+	char buf[128];
+	int off = 0;
+	int ret;
+
+	if (!con->sys || (con->sys && con->sys->print_ts)) {
+		memset(&dt, 0, sizeof(dt));
+		ret = get_parsed_tod(&dt);
+		off = snprintf(buf, 128, "%02d:%02d:%02d ", dt.th, dt.tm,
+			       dt.ts);
+	}
+
+	ret = vsnprintf(buf+off, 128-off, fmt, args);
+	if (ret) {
+		ascii2ebcdic((u8 *) buf, off+ret);
+		con_write(con, (u8 *) buf, off+ret);
+	}
+
+	return ret;
+}
+
+int con_printf(struct console *con, const char *fmt, ...)
+{
+	va_list args;
+	int r;
+
+	va_start(args, fmt);
+	r = vprintf(con, fmt, args);
+	va_end(args);
+
+	return r;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/nucleus/sched.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,299 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <sched.h>
+#include <page.h>
+#include <buddy.h>
+#include <slab.h>
+#include <magic.h>
+
+/* list of all runnable processes */
+static struct list_head runnable;
+
+/* list of all processes in the system */
+static struct list_head processes;
+
+/* idle task */
+static struct task idle_task;
+
+/**
+ * start_task - helper used to start the task's code
+ * @f:	function to execute
+ */
+static void start_task(int (*f)(void*), void *data)
+{
+	/*
+	 * Start executing the code
+	 */
+	if (f)
+		(*f)(data);
+
+	/*
+	 * Done, now, it's time to cleanup
+	 *
+	 * FIXME:
+	 *  - delete from processes list
+	 *  - free stack page
+	 *  - free struct
+	 *  - schedule
+	 */
+	BUG();
+}
+
+/**
+ * __init_task - helper to initialize the task structure
+ * @task:	task struct to initialize
+ * @f:		pointer to function to execute
+ * @stack:	pointer to the page for stack
+ */
+static void __init_task(struct task *task, void *f, void *data, void *stack)
+{
+	memset(task, 0, sizeof(struct task));
+
+	task->regs.psw.io	= 1;
+	task->regs.psw.ex	= 1;
+	task->regs.psw.ea	= 1;
+	task->regs.psw.ba	= 1;
+
+	/* code to execute */
+	task->regs.psw.ptr = (u64) start_task;
+
+	task->regs.gpr[2]  = (u64) f;
+	task->regs.gpr[3]  = (u64) data;
+	task->regs.gpr[15] = ((u64) stack) + PAGE_SIZE - STACK_FRAME_SIZE;
+
+	task->state = TASK_SLEEPING;
+}
+
+/**
+ * init_idle_task - initialize the idle task
+ *
+ * Since the initial thread of execution already has a stack, and the task
+ * struct is a global variable, all that is left for us to do is to
+ * associate the current stack with idle_task.
+ */
+static void init_idle_task(void)
+{
+	u64 stack;
+
+	stack = ((u64) &stack) & ~(PAGE_SIZE-1);
+
+	__init_task(&idle_task, NULL, NULL, (void*) stack);
+	set_task_ptr(&idle_task);
+
+	/*
+	 * NOTE: The idle task is _not_ supposed to be on either of the
+	 * two process lists.
+	 */
+}
+
+/**
+ * create_task - create a new task
+ * @name:	name for the task
+ * @f:		function pointer to where thread of execution should begin
+ * @data:	arbitrary data to pass to the task
+ */
+struct task* create_task(char *name, int (*f)(void *), void *data)
+{
+	struct page *page;
+	struct task *task;
+
+	/*
+	 * Allocate a page for stack, and struct task itself
+	 */
+	page = alloc_pages(0, ZONE_NORMAL);
+	task = malloc(sizeof(struct task), ZONE_NORMAL);
+	if (!page || !task)
+		goto out;
+
+	/*
+	 * Set up task's state
+	 */
+	__init_task(task, f, data, page_to_addr(page));
+
+	strncpy(task->name, name, TASK_NAME_LEN);
+
+	/*
+	 * Add the task to the scheduler lists
+	 */
+	list_add_tail(&task->proc_list, &processes);
+	list_add_tail(&task->run_queue, &runnable);
+
+	return task;
+
+out:
+	free(task);
+	free_pages(page_to_addr(page), 0);
+
+	return ERR_PTR(-ENOMEM);
+}
+
+/**
+ * __sched - core of the scheduler code. This decides which task to run
+ * next, and switches over to it
+ */
+static void __sched(int force_idle)
+{
+	struct task *next;
+
+	/*
+	 * If there are no runnable tasks, let's use the idle thread
+	 */
+	if (force_idle || list_empty(&runnable)) {
+		next = &idle_task;
+		goto run;
+	}
+
+	next = list_first_entry(&runnable, struct task, run_queue);
+	BUG_ON(!next);
+
+	/*
+	 * Remove the new task from the run queue & mark it as running
+	 */
+	list_del(&next->run_queue);
+	next->state = TASK_RUNNING;
+
+run:
+	next->slice_end_time = (force_idle) ? force_idle : ticks + SCHED_TICKS_PER_SLICE;
+
+	/*
+	 * NOTE: Because we need to load the registers _BEFORE_ we issue
+	 * lpswe, we have to place the new psw into PSA and use register 0
+	 */
+	memcpy(PSA_TMP_PSW, &next->regs.psw, sizeof(struct psw));
+	set_task_ptr(next);
+
+	load_pasce(next->regs.cr1);
+
+	/*
+	 * Load the next task
+	 *
+	 * FIXME: fp? ar? cr?
+	 */
+	asm volatile(
+		"lmg	%%r0,%%r15,%0\n"	/* load gpr */
+		"lpswe	%1\n"			/* load new psw */
+	: /* output */
+	: /* input */
+	  "m" (next->regs.gpr[0]),
+	  "m" (*PSA_TMP_PSW)
+	);
+
+	/* unreachable */
+	BUG();
+}
+
+/**
+ * schedule_preempted - called to switch tasks
+ */
+void __schedule(struct psw *old_psw, int newstate)
+{
+	struct task *prev;
+	int force_idle = 0;
+
+	/*
+	 * Save last process's state
+	 */
+
+	prev = current;
+	BUG_ON(!prev);
+
+	/*
+	 * Save the registers (gpr, psw, ...)
+	 *
+	 * FIXME: fp? ar? cr?
+	 */
+	memcpy(prev->regs.gpr, PSA_INT_GPR, sizeof(u64)*16);
+	memcpy(&prev->regs.psw, old_psw, sizeof(struct psw));
+
+	/*
+	 * Idle task doesn't get added back to the queue
+	 */
+	if (prev == &idle_task)
+		goto go;
+
+	store_pasce(&prev->regs.cr1);
+
+	/*
+	 * Add back on the queue
+	 */
+	prev->state = newstate;
+	if (newstate != TASK_LOCKED)
+		list_add_tail(&prev->run_queue, &runnable);
+
+	/*
+	 * If the previous task didn't use it's full slice, force idle_task
+	 * to take over.
+	 */
+	if (prev->slice_end_time >= (ticks + SCHED_TICKS_PER_SLICE))
+		force_idle = prev->slice_end_time;
+
+go:
+	/*
+	 * Run the rest of the scheduler that selects the next task and
+	 * context switches
+	 */
+	__sched(force_idle);
+}
+
+/**
+ * __schedule_svc - wrapper for the supervisor-service call handler
+ */
+void __schedule_svc(void)
+{
+	__schedule(SVC_INT_OLD_PSW, TASK_SLEEPING);
+}
+
+/**
+ * __schedule_blocked__svc - wrapper for the supervisor-service call handler
+ */
+void __schedule_blocked_svc(void)
+{
+	__schedule(SVC_INT_OLD_PSW, TASK_LOCKED);
+}
+
+/*
+ * Initialize the schduler, and all associated structures
+ */
+void init_sched(void)
+{
+	u64 cr0;
+
+	INIT_LIST_HEAD(&runnable);
+	INIT_LIST_HEAD(&processes);
+
+	init_idle_task();
+
+	/* enable cpu timer interrupt subclass */
+	asm volatile(
+		"stctg	0,0,%0\n"	/* get cr0 */
+		"oi	%1,0x04\n"	/* enable cpu timer subclass */
+		"ni	%1,0x7f\n"	/* disable clock comp */
+		"lctlg	0,0,%0\n"	/* reload cr0 */
+	: /* output */
+	: /* input */
+	  "m" (cr0),
+	  "m" (*(((u8*)&cr0) + 6))
+	);
+
+	set_timer();
+}
+
+void list_tasks(struct console *con,
+		void (*f)(struct console *, struct task*))
+{
+	struct task *t;
+
+	list_for_each_entry(t, &processes, proc_list)
+		f(con, t);
+}
+
+void make_runnable(struct task *task)
+{
+	task->state = TASK_SLEEPING;
+	list_add_tail(&task->run_queue, &runnable);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/nucleus/spinlock.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,50 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <interrupt.h>
+#include <spinlock.h>
+
+void __spin_lock_wait(spinlock_t *lp, unsigned int pc)
+{
+	while (1) {
+		if (__compare_and_swap(&lp->lock, 0, pc) == 0)
+			return;
+	}
+}
+
+int __spin_trylock_retry(spinlock_t *lp, unsigned int pc)
+{
+	int count = SPIN_RETRY;
+
+	while (count-- > 0)
+		if (__compare_and_swap(&lp->lock, 0, pc) == 0)
+			return 1;
+	return 0;
+}
+
+/**
+ * spin_lock_intsave - disable interrupts and lock
+ * @lock:	lock to lock
+ * @mask:	pointer to where interrupt mask will be stored
+ */
+void spin_lock_intsave(spinlock_t *lock, unsigned long *mask)
+{
+	*mask = local_int_disable();
+	spin_lock(lock);
+}
+
+/**
+ * spin_unlock_intrestore - unlock and restore interrupt flags flags
+ * @lock:	lock to unlock
+ * @mask:	mask to restore
+ */
+void spin_unlock_intrestore(spinlock_t *lock, unsigned long mask)
+{
+        spin_unlock(lock);
+        local_int_restore(mask);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/nucleus/svc.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,15 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <sched.h>
+#include <interrupt.h>
+
+u64 svc_table[NR_SVC] = {
+	(u64) __schedule_svc,
+	(u64) __schedule_blocked_svc,
+};
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/scripts/Makefile.build	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,41 @@
+#
+# (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+#
+# This file is released under the GPLv2.  See the COPYING file for more
+# details.
+#
+
+#
+# Build a single directory (built-in.o)
+#
+
+.PHONY: all
+
+.PRECIOUS: %.o
+
+include scripts/Makefile.commands
+
+override DIR := $(patsubst %/,%,$(DIR))
+include $(DIR)/Makefile
+
+OBJS := $(foreach obj,$(objs-$(DIR)),$(patsubst %,$(DIR)/%,$(obj)))
+
+all: $(DIR)/built-in.o
+	@echo -n
+
+%/built-in.o: $(OBJS)
+	$(call o-to-builtin,$(OBJS),$@)
+
+%.o: %.S
+	$(call s-to-o,$<,$@)
+
+%.s: %.c
+	$(call c-to-s,$<,$@)
+
+%.o: %.c
+	$(call c-to-o,$<,$@)
+
+shell/directory.c: shell/directory_structs.c
+
+shell/directory_structs.c: hvf.directory
+	$(call gendir,$<,$@)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/scripts/Makefile.commands	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,64 @@
+cmd-ar=$(AR) rc $(1) $(2)
+#
+# (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+#
+# This file is released under the GPLv2.  See the COPYING file for more
+# details.
+#
+cmd-c-to-o=$(CC) $(CFLAGS) $(NUCLEUSCFLAGS) -c -o $(2) $(1)
+cmd-c-to-s=$(CC) $(CFLAGS) $(NUCLEUSCFLAGS) -S -o $(2) $(1)
+cmd-s-to-o=$(AS) -m64 -o $(2) $(1)
+cmd-o-to-builtin=$(LD) $(LDFLAGS) -r -o $(2) $(1)
+cmd-link-hvf=$(LD) $(LDFLAGS) -T scripts/linker.script -o $(2) $(1)
+cmd-link-ipl=$(LD) -melf64_s390 -T linker.script -o $(2) $(1)
+cmd-objcopy-t=$(OBJCOPY) -O binary -j .text $(1) $(2)
+cmd-objcopy-tdr=$(OBJCOPY) -O binary -j .text -j .data -j .rodata -j .rodata.str1.2 $(1) $(2)
+cmd-genipl-rdr=bash scripts/gen_rdr_ccws.sh $(1)
+cmd-genipl-tape=bash scripts/gen_tape_ipl_s.sh $(1) $(2)
+cmd-concat=cat $(1) > $(2)
+cmd-pad=bash scripts/pad.sh $(1) $(2)
+cmd-clean=rm -f $(1)
+cmd-rclean=rm -rf $(1)
+cmd-cscope=cscope -R -b
+cmd-gendir=bash scripts/gen-dir.sh $(1) $(2)
+
+ifeq ($V,1)
+ar=$(cmd-ar)
+c-to-o=$(cmd-c-to-o)
+c-to-s=$(cmd-c-to-s)
+c-to-o-ipl=$(cmd-c-to-o-ipl)
+s-to-o=$(cmd-s-to-o)
+o-to-builtin=$(cmd-o-to-builtin)
+link-hvf=$(cmd-link-hvf)
+link-ipl=$(cmd-link-ipl)
+objcopy-t=$(cmd-objcopy-t)
+objcopy-tdr=$(cmd-objcopy-tdr)
+genipl-rdr=$(cmd-genipl-rdr)
+genipl-tape=$(cmd-genipl-tape)
+concat=$(cmd-concat)
+pad=$(cmd-pad)
+clean=$(cmd-clean)
+rclean=$(cmd-rclean)
+cscope=$(cmd-cscope)
+gendir=$(cmd-gendir)
+else
+ar=@echo "  [AR]      $(1)"; $(cmd-ar)
+c-to-o=@echo "  [CC]      $(2)"; $(cmd-c-to-o)
+c-to-s=@echo "  [CC]      $(2)"; $(cmd-c-to-s)
+c-to-o-ipl=@echo "  [CC]      $(2)"; $(cmd-c-to-o-ipl)
+s-to-o=@echo "  [AS]      $(2)"; $(cmd-s-to-o)
+o-to-builtin=@echo "  [LD]      $(2)"; $(cmd-o-to-builtin)
+link-hvf=@echo "  [LD]      hvf"; $(cmd-link-hvf)
+link-ipl=@echo "  [LD]      $2"; $(cmd-link-ipl)
+objcopy-t=@echo "  [OBJCOPY] $2"; $(cmd-objcopy-t)
+objcopy-tdr=@echo "  [OBJCOPY] $2"; $(cmd-objcopy-tdr)
+genipl-rdr=@echo "  [GENRDR]  $1"; $(cmd-genipl-rdr)
+genipl-tape=@echo "  [GENTAPE] $2"; $(cmd-genipl-tape)
+concat=@echo "  [CONCAT]  $2"; $(cmd-concat)
+pad=@echo "  [PAD]     $1 (multiple of $2 bytes)"; $(cmd-pad)
+clean=@echo "  [CLEAN]   $1"; $(cmd-clean)
+rclean=@echo "  [CLEAN]   $1"; $(cmd-rclean)
+cscope=@echo "  [CSCOPE]  cscope.out"; $(cmd-cscope)
+gendir=@echo "  [DIRECT]  $1 -> $2"; $(cmd-gendir)
+endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/scripts/extract-version.sh	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+v=`git describe 2> /dev/null`
+
+case "$v" in
+	"")
+		awk '/^VERSION=/ { print substr($0,9); exit; }' < Makefile
+		;;
+	*)
+		echo "$v"
+		;;
+esac
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/scripts/gen-dir.sh	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,99 @@
+#!/bin/sh
+
+if [ $# -ne 2 ]; then
+	echo "Usage: $0 <directory> <outfile>" >&2
+	exit 1
+fi
+
+userid=""
+
+close_devlist()
+{
+cat >> directory.devlist <<DONE
+	{ /* END   */ .type = VDEV_INVAL, },
+};
+DONE
+echo "	}," >> directory.userlist
+}
+
+parse_line()
+{
+	case "$1" in
+		USER)
+			[ ! -z "$userid" ] && close_devlist
+
+			echo "static struct directory_vdev __directory_$2[] = {" >> directory.devlist
+			echo "	{" >> directory.userlist
+			echo "		.userid = \"$2\"," >> directory.userlist
+			echo "		.auth = '$3'," >> directory.userlist
+			echo "		.devices = __directory_$2," >> directory.userlist
+
+			userid="$2"
+			;;
+		MACHINE)
+			;;
+		STORAGE)
+			tmp=`echo $2 | sed -e 's/[KMG]//g'`
+			case "$2" in
+				*K) size="${tmp}ULL * 1024ULL" ;;
+				*M) size="${tmp}ULL * 1024ULL * 1024ULL" ;;
+				*G) size="${tmp}ULL * 1024ULL * 1024ULL * 1024ULL" ;;
+				*)  size="$2ULL" ;;
+			esac
+			echo "		.storage_size = $size," >> directory.userlist
+			;;
+		CONSOLE)
+			echo "	{ /* CON   */ .type = VDEV_CONS,  .vdev = 0x$2, }," >> directory.devlist
+			;;
+		SPOOL)
+			case "$4" in
+				READER)
+					echo "	{ /* RDR   */ .type = VDEV_SPOOL, .vdev = 0x$2, .u.spool = { .type = 0x$3, .model = 1 }, }," >> directory.devlist
+					;;
+				PUNCH)
+					echo "	{ /* PUN   */ .type = VDEV_SPOOL, .vdev = 0x$2, .u.spool = { .type = 0x$3, .model = 1 }, }," >> directory.devlist
+					;;
+				PRINT)
+					echo "	{ /* PRT   */ .type = VDEV_SPOOL, .vdev = 0x$2, .u.spool = { .type = 0x$3, .model = 1 }, }," >> directory.devlist
+					;;
+			esac
+			;;
+		MDISK)
+			echo "	{ /* MDISK */ .type = VDEV_MDISK, .vdev = 0x$2, .u.mdisk = { .rdev = 0x$6, .cyloff = $4, .cylcnt = $5, }, }," >> directory.devlist
+			;;
+		DEDICATE)
+			echo "	{ /* DED   */ .type = VDEV_DED,   .vdev = 0x$2, .u.dedicate = { .rdev = 0x$3, }, }," >> directory.devlist
+			;;
+		*)
+			echo "Error near:" "$@" >&2
+			exit 2
+			;;
+	esac
+}
+
+open_userlist()
+{
+	echo "static struct user directory[] = {" > directory.userlist
+}
+
+close_userlist()
+{
+cat >> directory.userlist <<DONE
+	{ /* END */ .userid = NULL, },
+};
+DONE
+}
+
+rm -f directory.devlist
+open_userlist
+cat "$1" | while read line ; do
+	[ -z "$line" ] && continue
+
+	parse_line $line
+done
+close_devlist
+close_userlist
+
+cat directory.devlist directory.userlist > $2
+
+rm -f directory.devlist directory.userlist
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/scripts/gen-docs.sh	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,101 @@
+write_docs()
+{
+cat "$1" | awk -v fmt="$2" '
+BEGIN{
+	docdir = "doc/commands";
+
+	if (fmt == "txt") {
+		cmd_title_open = "";
+		cmd_title_close = "";
+		sec_hdr_open = "";
+		sec_hdr_close = "";
+		par_open = "";
+		par_close = "";
+		pre_open = "";
+		pre_close = "";
+	} else if (fmt == "html") {
+		cmd_title_open = "<h1>";
+		cmd_title_close = "</h1>";
+		sec_hdr_open = "<h2>";
+		sec_hdr_close = "</h2>";
+		par_open = "<p>";
+		par_close = "</p>";
+		pre_open = "<pre>";
+		pre_close = "</pre>";
+	} else {
+		printf "ERROR: unknown format \"%s\"\n", fmt;
+		exit;
+	}
+
+	fname = "";
+}
+
+/^[/ ]\*!!! / {
+	# begin a new command
+	if (fname != "")
+		close(fname);
+
+	name="";
+	fname="";
+	for(i=2; i<=NF; i+=1) {
+		name = name $i " ";
+		fname = fname $i "_";
+	}
+	name = substr(name, 1, length(name)-1);
+	fname = docdir "/" fmt "/" substr(fname, 1, length(fname)-1) "." fmt;
+
+	print "Writing out ", fname;
+
+	print cmd_title_open > fname;
+	print name >> fname;
+	print cmd_title_close >> fname;
+}
+
+/^[/ ]\*!! AUTH / {
+	# output an authorization block
+	print sec_hdr_open >> fname;
+	print "Authorization" >> fname;
+	print sec_hdr_close par_open >> fname;
+	print $3 >> fname;
+	printf par_close >> fname;
+}
+
+/^[/ ]\*!! PURPOSE$/ {
+	# output purpose section header
+	print sec_hdr_open >> fname;
+	print "Purpose" >> fname;
+	print sec_hdr_close >> fname;
+}
+
+/^[/ ]\*!! NOTES$/ {
+	# output notes section header
+	print sec_hdr_open >> fname;
+	print "Usage Notes" >> fname;
+	print sec_hdr_close >> fname;
+}
+
+/^[/ ]\*!p / {
+	# preformated verbatim line
+	print pre_open substr($0, 6) pre_close >> fname;
+}
+
+/^[/ ]\*! / {
+	# verbatim line
+	print substr($0, 5) >> fname;
+}
+
+/^[/ ]\*!$/ {
+	# just make a new paragraph
+	print substr($0, 5) >> fname;
+}
+'
+}
+
+mkdir -p doc/commands/txt
+mkdir -p doc/commands/html
+
+for srcf in shell/cmd_*.c ; do
+	echo "Inspecting $srcf..."
+	write_docs $srcf txt
+	write_docs $srcf html
+done
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/scripts/linker.script	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,8 @@
+SECTIONS
+{
+  ENTRY(start)
+  . = 0x100000;
+  .text : { *(.text) }
+  .data : { *(.data) }
+  .bss : { *(.bss) }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/scripts/pad.sh	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+# pad <fname> <multiple>
+
+len=`stat -c %s "$1"`
+dif=`expr $len % "$2"`
+
+if [ $dif -ne 0 ]; then
+	dif=`expr "$2" - $dif`
+	dd if=/dev/zero bs=1 count=$dif 2> /dev/null >> "$1"
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/Makefile	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,2 @@
+objs-shell := init.o directory.o cmds.o disassm.o guest.o reset.o intercept.o \
+	      guest_ipl.o exception.o instruction.o instruction_priv.o splash.o
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/cmd_beginstop.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,36 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+/*
+ *!!! BEGIN
+ *!! SYNTAX
+ *! \tok{\sc BEgin}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Starts/resumes virtual machine execution.
+ */
+static int cmd_begin(struct virt_sys *sys, char *cmd, int len)
+{
+	sys->task->cpu->state = GUEST_OPERATING;
+	return 0;
+}
+
+/*
+ *!!! STOP
+ *!! SYNTAX
+ *! \tok{\sc STOP}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Stops virtual machine execution.
+ */
+static int cmd_stop(struct virt_sys *sys, char *cmd, int len)
+{
+	sys->task->cpu->state = GUEST_STOPPED;
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/cmd_display.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,558 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+static char* parse_addrspec(u64 *val, u64 *len, char *s)
+{
+	u64 tmp;
+	int parsed = 0;
+
+	tmp = 0;
+	while(!(*s == '\0' ||
+		*s == ' ' ||
+		*s == '\t')) {
+		if (*s >= '0' && *s <= '9')
+			tmp = 16*tmp + (*s - '0');
+		else if ((*s >= 'A' && *s <= 'F') ||
+			 (*s >= 'a' && *s <= 'f'))
+			tmp = 16*tmp + 10 + ((*s & ~0x20) - 'A');
+		else if (*s == '.' && parsed)
+			break;
+		else
+			return ERR_PTR(-EINVAL);
+
+		s++;
+		parsed = 1;
+	}
+
+	if (len) {
+		*len = 0;
+		if (*s == '.') {
+			s = __extract_hex(s+1, len);
+			if (IS_ERR(s))
+				parsed = 0;
+		}
+	}
+
+	*val = tmp;
+
+	return (parsed == 1 ? s : ERR_PTR(-EINVAL));
+}
+
+enum display_fmt {
+	FMT_NUMERIC = 0,
+	FMT_INSTRUCT,
+};
+
+static void __display_storage_instruct(struct virt_sys *sys, u64 guest_addr,
+				       u64 mlen)
+{
+	int ret;
+	char buf[64];
+	int ilen;
+	u64 val;
+	u64 host_addr;
+
+	u64 end_addr;
+
+	/* walk the page tables to find the real page frame */
+	ret = virt2phy_current(guest_addr, &host_addr);
+	if (ret) {
+		con_printf(sys->con, "DISPLAY: Specified address is not part of "
+			   "guest configuration (RC=%d,%d)\n", -EFAULT, ret);
+		return;
+	}
+
+	if (!mlen)
+		mlen = 1;
+
+	end_addr = guest_addr + mlen;
+
+	while(guest_addr < end_addr) {
+		/*
+		 * FIXME: make sure crossing page-boundary doesn't break
+		 * give us garbage
+		 */
+		ilen = disassm((unsigned char*) host_addr, buf, 64);
+
+		if ((host_addr & PAGE_MASK) >= (PAGE_SIZE-ilen)) {
+			con_printf(sys->con, "DISPLAY: Instruction spans page "
+				   "boundary - not supported\n");
+			break;
+		}
+
+		/* load the dword at the address, and shift it to the LSB part */
+		val = *((u64*)host_addr) >> 8*(sizeof(u64) - ilen);
+
+		con_printf(sys->con, "R%016llX  %0*llX%*s  %s\n", guest_addr,
+			   2*ilen, val,			/* inst hex dump */
+			   12-2*ilen, "",		/* spacer */
+			   buf);
+
+		host_addr += ilen;
+		guest_addr += ilen;
+	}
+}
+
+static void __display_storage_numeric(struct virt_sys *sys, u64 guest_addr,
+				      u64 mlen)
+{
+	char buf[80];
+	char *bp;
+
+	u64 host_addr;
+	int this_len;
+
+	int ret;
+
+	/* round down */
+	guest_addr &= ~((u64) 0x3);
+
+	/* walk the page tables to find the real page frame */
+	ret = virt2phy_current(guest_addr, &host_addr);
+	if (ret)
+		goto fault;
+
+	if (mlen > 4)
+		mlen = (mlen >> 2) + !!(mlen & 0x3);
+	else
+		mlen = 1;
+
+	while(mlen && !ret) {
+		this_len = (mlen > 4) ? 4 : mlen;
+
+		mlen -= this_len;
+
+		bp = buf;
+		bp += snprintf(bp, 80, "R%016llX  ", guest_addr);
+
+		while(this_len) {
+			bp += snprintf(bp, 80 - (bp - buf), "%08X ",
+				       *(u32*)host_addr);
+
+			guest_addr += 4;
+			host_addr += 4;
+			this_len--;
+
+			/* loop if we're not crossing a page, or if we're done */
+			if (((guest_addr & PAGE_MASK) != 0) || !mlen)
+				continue;
+
+			/*
+			 * We will attempt to walk further along guest
+			 * storage, and are about to cross a page boundary,
+			 * walk the page tables to find the real page frame
+			 */
+			ret = virt2phy_current(guest_addr, &host_addr);
+			if (ret)
+				break;
+		}
+
+		con_printf(sys->con, "%s\n", buf);
+	}
+
+fault:
+	if (ret)
+		con_printf(sys->con, "DISPLAY: The address %016llX is not part of "
+			   "guest configuration (RC=%d,%d)\n", guest_addr, -EFAULT, ret);
+}
+
+/*
+ *!!! DISPLAY STORAGE
+ *!! SYNTAX
+ *! \tok{\sc Display} \tok{\sc STOrage}
+ *! \begin{stack} \\ \deftok{N} \\ \tok{I} \end{stack}
+ *! <addr>
+ *! \begin{stack} \\ \tok{.} <length> \end{stack}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Displays a portion of guest's storage.
+ *!! OPERANDS
+ *! \cbstart
+ *! \item[addr] is the guest storage address.
+ *! \item[length] is the number of bytes to display.  If not specified, 4 is
+ *! assumed.
+ *! \cbend
+ *!! SDNAREPO
+ *!! OPTIONS
+ *! \cbstart
+ *! \item[N] display guest storage in numeric format.
+ *! \item[I] display guest storage in instruction format.
+ *! \cbend
+ *!! SNOITPO
+ *!! NOTES
+ *! \cbstart
+ *! \item Currently, the instruction display does not support page-boundary
+ *! crossing.
+ *! \cbend
+ *!! SETON
+ *!! EXAMPLES
+ *! D STO 200\\
+ *! D STO N200.10\\
+ *! D STO I1234.200
+ */
+static int cmd_display_storage(struct virt_sys *sys, char *cmd, int len)
+{
+	u64 guest_addr;
+	u64 mlen = 0;
+	enum display_fmt fmt;
+
+	switch (cmd[0]) {
+		case 'N': case 'n':
+			/* numeric */
+			cmd++;
+			fmt = FMT_NUMERIC;
+			break;
+		case 'I': case 'i':
+			/* instruction */
+			cmd++;
+			fmt = FMT_INSTRUCT;
+			break;
+		default:
+			/* numeric */
+			fmt = FMT_NUMERIC;
+			break;
+	}
+
+	cmd = parse_addrspec(&guest_addr, &mlen, cmd);
+	if (IS_ERR(cmd)) {
+		con_printf(sys->con, "DISPLAY: Invalid addr-spec\n");
+		return 0;
+	}
+
+	if (fmt == FMT_INSTRUCT)
+		__display_storage_instruct(sys, guest_addr, mlen);
+	else
+		__display_storage_numeric(sys, guest_addr, mlen);
+
+	return 0;
+}
+
+/*
+ *!!! DISPLAY SIECB
+ *!! SYNTAX
+ *! \tok{\sc Display} \tok{\sc SIECB}
+ *!! XATNYS
+ *!! AUTH E
+ *!! PURPOSE
+ *! Displays hexdump of the guest's SIE control block.
+ */
+static int cmd_display_siecb(struct virt_sys *sys, char *cmd, int len)
+{
+	u32 *val;
+	int i;
+
+	SHELL_CMD_AUTH(sys, 'E');
+
+	val = (u32*) &sys->task->cpu->sie_cb;
+
+	con_printf(sys->con, "SIECB FOR %s AT %p\n",
+		   sys->directory->userid, val);
+	for(i=0; i<(sizeof(struct sie_cb)/sizeof(u32)); i+=4)
+		con_printf(sys->con, "%03lX  %08X %08X %08X %08X\n",
+			   i*sizeof(u32), val[i], val[i+1], val[i+2],
+			   val[i+3]);
+
+	return 0;
+}
+
+/*
+ *!!! DISPLAY GPR
+ *!! SYNTAX
+ *! \tok{\sc Display} \tok{\sc Gpr}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Displays the guest's general purpose registers
+ */
+static int cmd_display_gpr(struct virt_sys *sys, char *cmd, int len)
+{
+	con_printf(sys->con, "GR  0 = %016llX %016llX\n",
+		   sys->task->cpu->regs.gpr[0],
+		   sys->task->cpu->regs.gpr[1]);
+	con_printf(sys->con, "GR  2 = %016llX %016llX\n",
+		   sys->task->cpu->regs.gpr[2],
+		   sys->task->cpu->regs.gpr[3]);
+	con_printf(sys->con, "GR  4 = %016llX %016llX\n",
+		   sys->task->cpu->regs.gpr[4],
+		   sys->task->cpu->regs.gpr[5]);
+	con_printf(sys->con, "GR  6 = %016llX %016llX\n",
+		   sys->task->cpu->regs.gpr[6],
+		   sys->task->cpu->regs.gpr[7]);
+	con_printf(sys->con, "GR  8 = %016llX %016llX\n",
+		   sys->task->cpu->regs.gpr[8],
+		   sys->task->cpu->regs.gpr[9]);
+	con_printf(sys->con, "GR 10 = %016llX %016llX\n",
+		   sys->task->cpu->regs.gpr[10],
+		   sys->task->cpu->regs.gpr[11]);
+	con_printf(sys->con, "GR 12 = %016llX %016llX\n",
+		   sys->task->cpu->regs.gpr[12],
+		   sys->task->cpu->regs.gpr[13]);
+	con_printf(sys->con, "GR 14 = %016llX %016llX\n",
+		   sys->task->cpu->regs.gpr[14],
+		   sys->task->cpu->regs.gpr[15]);
+	return 0;
+}
+
+/*
+ *!!! DISPLAY FPCR
+ *!! SYNTAX
+ *! \tok{\sc Display} \tok{\sc FPCR}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Displays the guest's floating point control register
+ */
+static int cmd_display_fpcr(struct virt_sys *sys, char *cmd, int len)
+{
+	con_printf(sys->con, "FPCR  = %08X\n", sys->task->cpu->regs.fpcr);
+	return 0;
+}
+
+/*
+ *!!! DISPLAY FPR
+ *!! SYNTAX
+ *! \tok{\sc Display} \tok{\sc Fpr}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Displays the guest's floating point registers
+ */
+static int cmd_display_fpr(struct virt_sys *sys, char *cmd, int len)
+{
+	con_printf(sys->con, "FR  0 = %016llX %016llX\n",
+		   sys->task->cpu->regs.fpr[0],
+		   sys->task->cpu->regs.fpr[1]);
+	con_printf(sys->con, "FR  2 = %016llX %016llX\n",
+		   sys->task->cpu->regs.fpr[2],
+		   sys->task->cpu->regs.fpr[3]);
+	con_printf(sys->con, "FR  4 = %016llX %016llX\n",
+		   sys->task->cpu->regs.fpr[4],
+		   sys->task->cpu->regs.fpr[5]);
+	con_printf(sys->con, "FR  6 = %016llX %016llX\n",
+		   sys->task->cpu->regs.fpr[6],
+		   sys->task->cpu->regs.fpr[7]);
+	con_printf(sys->con, "FR  8 = %016llX %016llX\n",
+		   sys->task->cpu->regs.fpr[8],
+		   sys->task->cpu->regs.fpr[9]);
+	con_printf(sys->con, "FR 10 = %016llX %016llX\n",
+		   sys->task->cpu->regs.fpr[10],
+		   sys->task->cpu->regs.fpr[11]);
+	con_printf(sys->con, "FR 12 = %016llX %016llX\n",
+		   sys->task->cpu->regs.fpr[12],
+		   sys->task->cpu->regs.fpr[13]);
+	con_printf(sys->con, "FR 14 = %016llX %016llX\n",
+		   sys->task->cpu->regs.fpr[14],
+		   sys->task->cpu->regs.fpr[15]);
+	return 0;
+}
+
+/*
+ *!!! DISPLAY CR
+ *!! SYNTAX
+ *! \tok{\sc Display} \tok{\sc Cr}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Displays the guest's control registers
+ */
+static int cmd_display_cr(struct virt_sys *sys, char *cmd, int len)
+{
+	con_printf(sys->con, "CR  0 = %016llX %016llX\n",
+		   sys->task->cpu->sie_cb.gcr[0],
+		   sys->task->cpu->sie_cb.gcr[1]);
+	con_printf(sys->con, "CR  2 = %016llX %016llX\n",
+		   sys->task->cpu->sie_cb.gcr[2],
+		   sys->task->cpu->sie_cb.gcr[3]);
+	con_printf(sys->con, "CR  4 = %016llX %016llX\n",
+		   sys->task->cpu->sie_cb.gcr[4],
+		   sys->task->cpu->sie_cb.gcr[5]);
+	con_printf(sys->con, "CR  6 = %016llX %016llX\n",
+		   sys->task->cpu->sie_cb.gcr[6],
+		   sys->task->cpu->sie_cb.gcr[7]);
+	con_printf(sys->con, "CR  8 = %016llX %016llX\n",
+		   sys->task->cpu->sie_cb.gcr[8],
+		   sys->task->cpu->sie_cb.gcr[9]);
+	con_printf(sys->con, "CR 10 = %016llX %016llX\n",
+		   sys->task->cpu->sie_cb.gcr[10],
+		   sys->task->cpu->sie_cb.gcr[11]);
+	con_printf(sys->con, "CR 12 = %016llX %016llX\n",
+		   sys->task->cpu->sie_cb.gcr[12],
+		   sys->task->cpu->sie_cb.gcr[13]);
+	con_printf(sys->con, "CR 14 = %016llX %016llX\n",
+		   sys->task->cpu->sie_cb.gcr[14],
+		   sys->task->cpu->sie_cb.gcr[15]);
+	return 0;
+}
+
+/*
+ *!!! DISPLAY AR
+ *!! SYNTAX
+ *! \tok{\sc Display} \tok{\sc Ar}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Displays the guest's access registers
+ */
+static int cmd_display_ar(struct virt_sys *sys, char *cmd, int len)
+{
+	con_printf(sys->con, "AR  0 = %08X %08X\n",
+		   sys->task->cpu->regs.ar[0],
+		   sys->task->cpu->regs.ar[1]);
+	con_printf(sys->con, "AR  2 = %08X %08X\n",
+		   sys->task->cpu->regs.ar[2],
+		   sys->task->cpu->regs.ar[3]);
+	con_printf(sys->con, "AR  4 = %08X %08X\n",
+		   sys->task->cpu->regs.ar[4],
+		   sys->task->cpu->regs.ar[5]);
+	con_printf(sys->con, "AR  6 = %08X %08X\n",
+		   sys->task->cpu->regs.ar[6],
+		   sys->task->cpu->regs.ar[7]);
+	con_printf(sys->con, "AR  8 = %08X %08X\n",
+		   sys->task->cpu->regs.ar[8],
+		   sys->task->cpu->regs.ar[9]);
+	con_printf(sys->con, "AR 10 = %08X %08X\n",
+		   sys->task->cpu->regs.ar[10],
+		   sys->task->cpu->regs.ar[11]);
+	con_printf(sys->con, "AR 12 = %08X %08X\n",
+		   sys->task->cpu->regs.ar[12],
+		   sys->task->cpu->regs.ar[13]);
+	con_printf(sys->con, "AR 14 = %08X %08X\n",
+		   sys->task->cpu->regs.ar[14],
+		   sys->task->cpu->regs.ar[15]);
+	return 0;
+}
+
+/*
+ *!!! DISPLAY PSW
+ *!! SYNTAX
+ *! \tok{\sc Display} \tok{\sc PSW}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Displays the guest's PSW.
+ *!
+ *! \cbstart
+ *! If the guest is in ESA/390 mode, the 8-byte PSW is displayed.
+ *!
+ *! If the guest is in z/Architecture mode, the 16-byte PSW is displayed.
+ *! \cbend
+ */
+static int cmd_display_psw(struct virt_sys *sys, char *cmd, int len)
+{
+	u32 *ptr = (u32*) &sys->task->cpu->sie_cb.gpsw;
+
+	if (VCPU_ZARCH(sys->task->cpu))
+		con_printf(sys->con, "PSW = %08X %08X %08X %08X\n",
+			   ptr[0], ptr[1], ptr[2], ptr[3]);
+	else
+		con_printf(sys->con, "PSW = %08X %08X\n",
+			   ptr[0], ptr[1]);
+
+	return 0;
+}
+
+static void __do_display_schib(struct console *con, struct virt_device *vdev)
+{
+	con_printf(con, "%05X %04X %08X   %d  %02X %02X  %02X  %02X %02X "
+		        "---- %02X %02X %02X%02X%02X%02X %02X%02X%02X%02X\n",
+		   vdev->sch, vdev->pmcw.dev_num, vdev->pmcw.interrupt_param,
+		   vdev->pmcw.isc, ((vdev->pmcw.e  << 7) |
+				    (vdev->pmcw.lm << 5) |
+				    (vdev->pmcw.mm << 3) |
+				    (vdev->pmcw.d  << 2) |
+				    (vdev->pmcw.t  << 1) |
+				    (vdev->pmcw.v)),
+		   vdev->pmcw.lpm, vdev->pmcw.pnom, vdev->pmcw.lpum,
+		   vdev->pmcw.pim,
+		   /* MBI */
+		   vdev->pmcw.pom, vdev->pmcw.pam,
+		   vdev->pmcw.chpid[0], vdev->pmcw.chpid[1],
+		   vdev->pmcw.chpid[2], vdev->pmcw.chpid[3],
+		   vdev->pmcw.chpid[4], vdev->pmcw.chpid[5],
+		   vdev->pmcw.chpid[6], vdev->pmcw.chpid[7]);
+}
+
+/*
+ *!!! DISPLAY SCHIB
+ *!! SYNTAX
+ *! \tok{\sc Display} \tok{\sc SCHIB}
+ *! \begin{stack} \tok{ALL} \\ <schib> \end{stack}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Displays the guest's subchannel control block information
+ */
+static int cmd_display_schib(struct virt_sys *sys, char *cmd, int len)
+{
+	struct virt_device *vdev;
+	u64 sch;
+	int all;
+
+	if (strcasecmp(cmd, "ALL")) {
+		cmd = __extract_hex(cmd, &sch);
+		if (IS_ERR(cmd))
+			return PTR_ERR(cmd);
+
+		/* sch number must be: X'0001____' */
+		if ((sch & 0xffff0000) != 0x00010000)
+			return -EINVAL;
+
+		all = 0;
+	} else
+		all = 1;
+
+	/* find the virtual device */
+
+	list_for_each_entry(vdev, &sys->virt_devs, devices) {
+		if ((vdev->sch == (u32) sch) || all) {
+			if (!all || all == 1) {
+				con_printf(sys->con, "SCHIB DEV  INT-PARM ISC FLG LP "
+					   "PNO LPU PI MBI  PO PA CHPID0-3 CHPID4-7\n");
+				all = (all ? 2 : 0);
+			}
+
+			__do_display_schib(sys->con, vdev);
+
+			if (!all)
+				break;
+		}
+	}
+
+	return 0;
+}
+
+static struct cpcmd cmd_tbl_display[] = {
+	{"AR",		cmd_display_ar,		NULL},
+	{"A",		cmd_display_ar,		NULL},
+
+	{"CR",		cmd_display_cr,		NULL},
+	{"C",		cmd_display_cr,		NULL},
+
+	{"FPCR",	cmd_display_fpcr,	NULL},
+
+	{"FPR",		cmd_display_fpr,	NULL},
+	{"FP",		cmd_display_fpr,	NULL},
+	{"F",		cmd_display_fpr,	NULL},
+
+	{"GPR",		cmd_display_gpr,	NULL},
+	{"GP",		cmd_display_gpr,	NULL},
+	{"G",		cmd_display_gpr,	NULL},
+
+	{"PSW",		cmd_display_psw,	NULL},
+
+	{"SCHIB",	cmd_display_schib,	NULL},
+
+	{"SIECB",	cmd_display_siecb,	NULL},
+
+	{"STORAGE",	cmd_display_storage,	NULL},
+	{"STORAG",	cmd_display_storage,	NULL},
+	{"STORA",	cmd_display_storage,	NULL},
+	{"STOR",	cmd_display_storage,	NULL},
+	{"STO",		cmd_display_storage,	NULL},
+	{"",		NULL,			NULL},
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/cmd_enable.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,62 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+/*
+ *!!! ENABLE
+ *!! SYNTAX
+ *! \tok{\sc ENAble}
+ *! \begin{stack} \tok{ALL} \\ <rdev> \end{stack}
+ *!! XATNYS
+ *!! AUTH A
+ *!! PURPOSE
+ *! Enables a real device.
+ */
+static int cmd_enable(struct virt_sys *sys, char *cmd, int len)
+{
+	u64 devnum;
+	struct device *dev;
+	struct console *con;
+
+	if (!strcasecmp(cmd, "ALL")) {
+		con_printf(sys->con, "ENABLE ALL not yet implemented!\n");
+		return 0;
+	}
+
+	cmd = __extract_hex(cmd, &devnum);
+	if (IS_ERR(cmd))
+		return PTR_ERR(cmd);
+
+	/* device number must be 16-bit */
+	if (devnum & ~0xffffUL)
+		return -EINVAL;
+
+	dev = find_device_by_ccuu(devnum);
+	if (IS_ERR(dev)) {
+		con_printf(sys->con, "Device %04llX not found in configuration\n", devnum);
+		return 0;
+	}
+
+	if (atomic_read(&dev->in_use)) {
+		con_printf(sys->con, "Device %04llX is already in use\n", devnum);
+		dev_put(dev);
+		return 0;
+	}
+
+	if (!dev->dev->enable) {
+		con_printf(sys->con, "Device type %-4s cannot be enabled\n",
+			   type2name(dev->type));
+		return 0;
+	}
+
+	con = dev->dev->enable(dev);
+	if (IS_ERR(con)) {
+		con_printf(sys->con, "Failed to enable %04llX\n", devnum);
+		return PTR_ERR(con);
+	}
+
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/cmd_helpers.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,84 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+static char* __extract_dec(char *str, u64 *val)
+{
+	u64 res;
+	u64 tmp;
+	int len;
+
+	if (!str || !val)
+		return ERR_PTR(-EINVAL);
+
+	res = 0;
+	len = -1;
+
+	for (; str && *str != '\0'; str++, len++) {
+		if (*str >= '0' && *str <= '9')
+			tmp = *str - '0';
+		else if (*str == ' ' || *str == '\t')
+			break;
+		else
+			return ERR_PTR(-EINVAL);
+
+		res = (res * 10) + tmp;
+	}
+
+	if (len == -1)
+		return ERR_PTR(-EINVAL);
+
+	*val = res;
+
+	return str;
+}
+
+static char* __extract_hex(char *str, u64 *val)
+{
+	u64 res;
+	u64 tmp;
+	int len;
+
+	if (!str || !val)
+		return ERR_PTR(-EINVAL);
+
+	res = 0;
+	len = -1;
+
+	for (; str && *str != '\0'; str++, len++) {
+		if (*str >= '0' && *str <= '9')
+			tmp = *str - '0';
+		else if (*str >= 'A' && *str <= 'F')
+			tmp = *str - 'A' + 10;
+		else if (*str >= 'a' && *str <= 'f')
+			tmp = *str - 'a' + 10;
+		else if (*str == ' ' || *str == '\t')
+			break;
+		else
+			return ERR_PTR(-EINVAL);
+
+		res = (res << 4) | tmp;
+	}
+
+	if (len == -1)
+		return ERR_PTR(-EINVAL);
+
+	*val = res;
+
+	return str;
+}
+
+static char* __consume_ws(char *str)
+{
+	if (!str)
+		return str;
+
+	/* consume any extra whitespace */
+	while(*str == ' ' || *str == '\t')
+		str++;
+
+	return str;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/cmd_logon.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,39 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+/*
+ *!!! LOGON
+ *!! SYNTAX
+ *! \tok{\sc LOGON} <userid>
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Log on to a virtual machine.
+ */
+static int cmd_logon(struct virt_sys *data, char *cmd, int len)
+{
+	struct console *con = (struct console*) data; /* BEWARE */
+	struct user *u;
+
+	u = find_user_by_id(cmd);
+	if (IS_ERR(u)) {
+		con_printf(con, "INVALID USERID\n");
+		return 0;
+	}
+
+	spawn_user_shell(con, u);
+	con_printf(oper_con, "%s %04X LOGON AS %-8s\n",
+		   type2name(con->dev->type), con->dev->ccuu, u->userid);
+
+	return 0;
+}
+
+static int cmd_logon_fail(struct virt_sys *sys, char *cmd, int len)
+{
+	con_printf(sys->con, "ALREADY LOGGED ON\n");
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/cmd_query.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,350 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+static char *__guest_state_to_str(enum virt_cpustate st)
+{
+	switch (st) {
+		case GUEST_STOPPED:	return "STOPPED";
+		case GUEST_OPERATING:	return "RUNNING";
+		case GUEST_LOAD:	return "LOADING";
+		case GUEST_CHECKSTOP:	return "CHECK-STOP";
+	}
+
+	return "???";
+}
+
+static void display_rdev(struct console *con, struct device *dev)
+{
+	char buf[40];
+
+	buf[0] = '\0';
+
+	if (dev->dev && dev->dev->snprintf)
+		dev->dev->snprintf(dev, buf, 40);
+
+	con_printf(con, "%-4s %04X %04X %s%sSCH = %05X\n",
+		   type2name(dev->type), dev->ccuu, dev->type, buf,
+		   atomic_read(&dev->in_use) ? "" : "FREE ",
+		   dev->sch);
+}
+
+static void display_vdev(struct console *con, struct virt_device *vdev)
+{
+	switch (vdev->vtype) {
+		case VDEV_CONS:
+			con_printf(con, "CONS %04X 3215 ON %s %04X %s SCH = %05X\n",
+				   vdev->pmcw.dev_num,
+				   type2name(con->dev->type), // FIXME?
+				   con->dev->ccuu,
+				   con->sys->print_ts ? "TS" : "NOTS",
+				   vdev->sch);
+			break;
+		case VDEV_DED:
+			con_printf(con, "%-4s %04X %04X ON DEV %04X SCH = %05X\n",
+				   type2name(vdev->type),
+				   vdev->pmcw.dev_num,
+				   vdev->type,
+				   vdev->u.dedicate.rdev->ccuu,
+				   vdev->sch);
+			break;
+		case VDEV_SPOOL:
+			con_printf(con, "%-4s %04X %04X SCH = %05X\n",
+				   type2name(vdev->type),
+				   vdev->pmcw.dev_num, vdev->type,
+				   vdev->sch);
+			break;
+		case VDEV_MDISK:
+			con_printf(con, "DASD %04X 3390 %6d CYL ON DASD %04X SCH = %05X\n",
+				   vdev->pmcw.dev_num,
+				   0, /* FIXME: cyl count */
+				   0, /* FIXME: rdev */
+				   vdev->sch);
+			break;
+		case VDEV_LINK:
+			con_printf(con, "LINK %04X TO %s %04X SCH = %05X\n",
+				   vdev->pmcw.dev_num,
+				   "????", /* FIXME: userid */
+				   0xffff, /* FIXME: user's vdev # */
+				   vdev->sch);
+			break;
+		default:
+			con_printf(con, "???? unknown device type (%04X, %05X)\n",
+				   vdev->pmcw.dev_num, vdev->sch);
+			break;
+	}
+}
+
+static void display_task(struct console *con, struct task *task)
+{
+	char state;
+
+	switch(task->state) {
+		case TASK_RUNNING:  state = 'R'; break;
+		case TASK_SLEEPING: state = 'S'; break;
+		case TASK_LOCKED:   state = 'L'; break;
+		default:            state = '?'; break;
+	}
+
+	con_printf(con, "%*s %p %c %016llX\n", -TASK_NAME_LEN, task->name,
+		   task, state, task->regs.psw.ptr);
+}
+
+/*
+ *!!! QUERY TIME
+ *!! SYNTAX
+ *! \tok{\sc Query} \tok{\sc TIME}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Displays the current time
+ */
+static int cmd_query_cplevel(struct virt_sys *sys, char *cmd, int len)
+{
+	con_printf(sys->con, "HVF version " VERSION "\n");
+	con_printf(sys->con, "IPL at %02d:%02d:%02d UTC %04d-%02d-%02d\n",
+		   ipltime.th, ipltime.tm, ipltime.ts, ipltime.dy,
+		   ipltime.dm, ipltime.dd);
+
+	return 0;
+}
+
+/*
+ *!!! QUERY CPLEVEL
+ *!! SYNTAX
+ *! \tok{\sc Query} \tok{\sc CPLEVEL}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Displays the HVF version and time of IPL
+ */
+static int cmd_query_time(struct virt_sys *sys, char *cmd, int len)
+{
+	struct datetime dt;
+
+	get_parsed_tod(&dt);
+
+	con_printf(sys->con, "TIME IS %02d:%02d:%02d UTC %04d-%02d-%02d\n",
+		   dt.th, dt.tm, dt.ts, dt.dy, dt.dm, dt.dd);
+
+	return 0;
+}
+
+/*
+ *!!! QUERY ARCHMODE
+ *!! SYNTAX
+ *! \tok{\sc Query} \tok{\sc ARCHMODE}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Displays the virtual machine's current architecture mode.
+ */
+static int cmd_query_archmode(struct virt_sys *sys, char *cmd, int len)
+{
+	char *mode = (VCPU_ZARCH(sys->task->cpu)) ? "z/Arch" : "ESA390";
+
+	con_printf(sys->con, "ARCHMODE = %s\n", mode);
+
+	return 0;
+}
+
+/*
+ *!!! QUERY VIRTUAL
+ *!! SYNTAX
+ *! \tok{\sc Query} \tok{\sc Virtual}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Lists all of the guest's virtual devices
+ */
+static int cmd_query_virtual(struct virt_sys *sys, char *cmd, int len)
+{
+	struct virt_device *vdev;
+
+	con_printf(sys->con, "CPU 00  ID  %016llX %s\n",
+		   sys->task->cpu->cpuid,
+		   __guest_state_to_str(sys->task->cpu->state));
+	con_printf(sys->con, "STORAGE = %lluM\n", sys->directory->storage_size >> 20);
+
+	list_for_each_entry(vdev, &sys->virt_devs, devices)
+		display_vdev(sys->con, vdev);
+
+	return 0;
+}
+
+static void __cmd_query_real_cpus(struct virt_sys *sys)
+{
+	con_printf(sys->con, "CPU %02d  ID  %016llX RUNNING\n",
+		   getcpuaddr(),
+		   getcpuid());
+}
+
+static void __cmd_query_real_stor(struct virt_sys *sys)
+{
+	con_printf(sys->con, "STORAGE = %lluM\n", memsize >> 20);
+}
+
+enum {
+	QUERY_CPUS    = 1 << 0,
+	QUERY_STOR    = 1 << 1,
+	QUERY_DEVS    = 1 << 2,
+	QUERY_DEVNUM  = 1 << 3,
+};
+
+/*
+ *!!! QUERY REAL
+ *!! SYNTAX
+ *! \tok{\sc Query} \tok{\sc Real}
+ *! \begin{stack}
+ *!   \\
+ *!   \tok{\sc\bf ALL} \\
+ *!   \tok{\sc CPUS} \\
+ *!   \tok{\sc STORage} \\
+ *!   <rdev>
+ *! \end{stack}
+ *!! XATNYS
+ *!! AUTH A
+ *!! PURPOSE
+ *! \cbstart
+ *! Lists the host's real devices, CPUs, and storage
+ *! \cbend
+ *!! NOTES
+ *! \cbstart
+ *! \item Specifying real device numbers is not supported at the moment.
+ *! Instead, use QUERY REAL ALL to display all devices attached to the
+ *! system.
+ *! \cbend
+ *!! SETON
+ */
+static int cmd_query_real(struct virt_sys *sys, char *cmd, int len)
+{
+	int what = 0;
+	u64 devnum;
+
+	SHELL_CMD_AUTH(sys, 'A');
+
+	if (strnlen(cmd, len) == 0) {
+		what = QUERY_CPUS | QUERY_STOR | QUERY_DEVS;
+	} else if (!strcasecmp(cmd, "ALL")) {
+		what = QUERY_CPUS | QUERY_STOR | QUERY_DEVS;
+	} else if (!strcasecmp(cmd, "CPUS")) {
+		what = QUERY_CPUS;
+	} else if (!strcasecmp(cmd, "STOR") ||
+		   !strcasecmp(cmd, "STORA") ||
+		   !strcasecmp(cmd, "STORAG") ||
+		   !strcasecmp(cmd, "STORAGE")) {
+		what = QUERY_STOR;
+	} else {
+		cmd = __extract_hex(cmd, &devnum);
+		if (IS_ERR(cmd))
+			return PTR_ERR(cmd);
+
+		/* sch number must be: X'0000____' */
+		if (devnum & ~0xffffull)
+			return -EINVAL;
+
+		what = QUERY_DEVNUM;
+	}
+
+	if (what & QUERY_CPUS)
+		__cmd_query_real_cpus(sys);
+
+	if (what & QUERY_STOR)
+		__cmd_query_real_stor(sys);
+
+	if (what & QUERY_DEVS)
+		list_devices(sys->con, display_rdev);
+	if (what & QUERY_DEVNUM)
+		con_printf(sys->con, "not implemented\n");
+
+	return 0;
+}
+
+/*
+ *!!! QUERY TASK
+ *!! SYNTAX
+ *! \tok{\sc Query} \tok{\sc Task}
+ *!! XATNYS
+ *!! AUTH A
+ *!! PURPOSE
+ *! Lists all of the tasks running on the host. This includes guest virtual
+ *! cpu tasks, as well as system helper tasks.
+ */
+static int cmd_query_task(struct virt_sys *sys, char *cmd, int len)
+{
+	SHELL_CMD_AUTH(sys, 'A');
+
+	list_tasks(sys->con, display_task);
+
+	return 0;
+}
+
+static void display_names(struct console *con, struct virt_sys *sys)
+{
+	con_printf(con, "%s %04X %-8s\n", type2name(sys->con->dev->type),
+		   sys->con->dev->ccuu, sys->directory->userid);
+}
+
+/*
+ *!!! QUERY NAMES
+ *!! SYNTAX
+ *! \tok{\sc Query} \tok{\sc NAMes}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Lists all of the logged in users.
+ */
+static int cmd_query_names(struct virt_sys *sys, char *cmd, int len)
+{
+	list_users(sys->con, display_names);
+
+	return 0;
+}
+
+/*
+ *!!! QUERY USERID
+ *!! SYNTAX
+ *! \tok{\sc Query} \tok{\sc USERID}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Displays the current user id.
+ */
+static int cmd_query_userid(struct virt_sys *sys, char *cmd, int len)
+{
+	con_printf(sys->con, "%s\n", sys->directory->userid);
+	return 0;
+}
+
+static struct cpcmd cmd_tbl_query[] = {
+	{"ARCHMODE",	cmd_query_archmode,	NULL},
+
+	{"CPLEVEL",	cmd_query_cplevel,	NULL},
+
+	{"TIME",	cmd_query_time,		NULL},
+
+	{"VIRTUAL",	cmd_query_virtual,	NULL},
+	{"VIRTUA",	cmd_query_virtual,	NULL},
+	{"VIRTU",	cmd_query_virtual,	NULL},
+	{"VIRT",	cmd_query_virtual,	NULL},
+	{"VIR",		cmd_query_virtual,	NULL},
+	{"VI",		cmd_query_virtual,	NULL},
+	{"V",		cmd_query_virtual,	NULL},
+
+	{"REAL",	cmd_query_real,		NULL},
+	{"REA",		cmd_query_real,		NULL},
+	{"RE",		cmd_query_real,		NULL},
+	{"R",		cmd_query_real,		NULL},
+
+	{"NAMES",	cmd_query_names,	NULL},
+	{"NAME",	cmd_query_names,	NULL},
+	{"NAM",		cmd_query_names,	NULL},
+
+	{"TASK",	cmd_query_task,		NULL},
+
+	{"USERID",	cmd_query_userid,	NULL},
+	{"",		NULL,			NULL},
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/cmd_set.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,42 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+/*
+ *!!! SET NOTS
+ *!! SYNTAX
+ *! \tok{\sc SET} \tok{\sc NOTS}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Disable the console timestamp printing
+ */
+static int cmd_set_nots(struct virt_sys *sys, char *cmd, int len)
+{
+	sys->print_ts = 0;
+	return 0;
+}
+
+/*
+ *!!! SET TS
+ *!! SYNTAX
+ *! \tok{\sc SET} \tok{\sc TS}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Enable the console timestamp printing
+ */
+static int cmd_set_ts(struct virt_sys *sys, char *cmd, int len)
+{
+	sys->print_ts = 1;
+	return 0;
+}
+
+static struct cpcmd cmd_tbl_set[] = {
+	{"NOTS",	cmd_set_nots,		NULL},
+	{"TS",		cmd_set_ts,		NULL},
+	{"",		NULL,			NULL},
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/cmd_store.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,355 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+/*
+ *!!! STORE STORAGE
+ *!! SYNTAX
+ *! \cbstart
+ *! \tok{\sc STOre} \tok{\sc STOrage} <address> <value>
+ *! \cbend
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Sets a word in guest's storage at address to value
+ */
+static int cmd_store_storage(struct virt_sys *sys, char *cmd, int len)
+{
+	int ret;
+	u64 guest_addr, host_addr;
+	u64 val = 0;
+
+	cmd = parse_addrspec(&guest_addr, NULL, cmd);
+	if (IS_ERR(cmd)) {
+		con_printf(sys->con, "STORE: Invalid addr-spec\n");
+		return PTR_ERR(cmd);
+	}
+
+	/* consume any extra whitespace */
+	cmd = __consume_ws(cmd);
+
+	/* get the value */
+	cmd = __extract_hex(cmd, &val);
+	if (IS_ERR(cmd))
+		return PTR_ERR(cmd);
+
+	/*
+	 * round down to the nearest word
+	 */
+	guest_addr &= ~((u64) 3ULL);
+
+	/* walk the page tables to find the real page frame */
+	ret = virt2phy_current(guest_addr, &host_addr);
+	if (ret) {
+		con_printf(sys->con, "STORE: Specified address is not part of "
+			   "guest configuration\n");
+		return ret;
+	}
+
+	*((u32*) host_addr) = (u32) val;
+
+	con_printf(sys->con, "Store complete.\n");
+
+	return 0;
+}
+
+/*
+ *!!! STORE GPR
+ *!! SYNTAX
+ *! \tok{\sc STOre} \tok{\sc Gpr} <gpr> <value>
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Sets a guest's general purpose register to the specified value
+ */
+static int cmd_store_gpr(struct virt_sys *sys, char *cmd, int len)
+{
+	u64 *ptr = (u64*) &sys->task->cpu->regs.gpr;
+	u64 val, gpr;
+
+	cmd = __extract_dec(cmd, &gpr);
+	if (IS_ERR(cmd))
+		return PTR_ERR(cmd);
+	if (gpr > 15)
+		return -EINVAL;
+
+	cmd = __consume_ws(cmd);
+
+	cmd = __extract_hex(cmd, &val);
+	if (IS_ERR(cmd))
+		return PTR_ERR(cmd);
+
+	ptr[gpr] = val;
+
+	con_printf(sys->con, "Store complete.\n");
+
+	return 0;
+}
+
+/*
+ *!!! STORE FPR
+ *!! SYNTAX
+ *! \tok{\sc STOre} \tok{\sc Fpr} <fpr> <value>
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Sets a guest's floating point register to the specified value
+ */
+static int cmd_store_fpr(struct virt_sys *sys, char *cmd, int len)
+{
+	u64 *ptr = (u64*) &sys->task->cpu->regs.fpr;
+	u64 val, fpr;
+
+	cmd = __extract_dec(cmd, &fpr);
+	if (IS_ERR(cmd))
+		return PTR_ERR(cmd);
+	if (fpr > 15)
+		return -EINVAL;
+
+	cmd = __consume_ws(cmd);
+
+	cmd = __extract_hex(cmd, &val);
+	if (IS_ERR(cmd))
+		return PTR_ERR(cmd);
+
+	ptr[fpr] = val;
+
+	con_printf(sys->con, "Store complete.\n");
+
+	return 0;
+}
+
+/*
+ *!!! STORE FPCR
+ *!! SYNTAX
+ *! \tok{\sc STOre} \tok{\sc FPCR} <value>
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Sets a guest's floating point control register to the specified value
+ */
+static int cmd_store_fpcr(struct virt_sys *sys, char *cmd, int len)
+{
+	u64 val;
+
+	cmd = __extract_hex(cmd, &val);
+	if (IS_ERR(cmd))
+		return PTR_ERR(cmd);
+	if (val > 0xffffffffULL)
+		return -EINVAL;
+
+	sys->task->cpu->regs.fpcr = (u32) val;
+
+	con_printf(sys->con, "Store complete.\n");
+
+	return 0;
+}
+
+/*
+ *!!! STORE CR
+ *!! SYNTAX
+ *! \tok{\sc STOre} \tok{\sc Cr} <cr> <value>
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Sets a guest's control register to the specified value
+ */
+static int cmd_store_cr(struct virt_sys *sys, char *cmd, int len)
+{
+	u64 *ptr = (u64*) &sys->task->cpu->sie_cb.gcr;
+	u64 val, cr;
+
+	cmd = __extract_dec(cmd, &cr);
+	if (IS_ERR(cmd))
+		return PTR_ERR(cmd);
+	if (cr > 15)
+		return -EINVAL;
+
+	cmd = __consume_ws(cmd);
+
+	cmd = __extract_hex(cmd, &val);
+	if (IS_ERR(cmd))
+		return PTR_ERR(cmd);
+
+	ptr[cr] = val;
+
+	con_printf(sys->con, "Store complete.\n");
+
+	return 0;
+}
+
+/*
+ *!!! STORE AR
+ *!! SYNTAX
+ *! \tok{\sc STOre} \tok{\sc Ar} <ar> <value>
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Sets a guest's access register to the specified value
+ */
+static int cmd_store_ar(struct virt_sys *sys, char *cmd, int len)
+{
+	u32 *ptr = (u32*) &sys->task->cpu->regs.ar;
+	u64 val, ar;
+
+	cmd = __extract_dec(cmd, &ar);
+	if (IS_ERR(cmd))
+		return PTR_ERR(cmd);
+	if (ar > 15)
+		return -EINVAL;
+
+	cmd = __consume_ws(cmd);
+
+	cmd = __extract_hex(cmd, &val);
+	if (IS_ERR(cmd))
+		return PTR_ERR(cmd);
+	if (val > 0xffffffffULL)
+		return -EINVAL;
+
+	ptr[ar] = val;
+
+	con_printf(sys->con, "Store complete.\n");
+
+	return 0;
+}
+
+/*
+ *!!! STORE PSW
+ *!! SYNTAX
+ *! \cbstart
+ *! \tok{\sc STOre} \tok{\sc PSW}
+ *!     \begin{stack} \\
+ *!       \begin{stack} \\
+ *!         \begin{stack} \\ <hexword1>
+ *!         \end{stack} <hexword2>
+ *!       \end{stack} <hexword3>
+ *!     \end{stack}
+ *! <hexword4>
+ *! \cbend
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! \cbstart
+ *! Alters all or a part of the PSW.
+ *! \cbend
+ *!! OPERANDS
+ *! \cbstart
+ *! \item[hexword...]
+ *!   \textbf{For an ESA/390 guest:}
+ *!
+ *!   Alters all or part of the PSW with the data specified in hexword3
+ *!   and hexword4.  If only hexword4 is specified, it is stored to PSW bits
+ *!   32-63.  If hexword3 and hexword4 are specified, hexword3 is stored to
+ *!   PSW bits 0-31, and hexword4 to PSW bits 32-63.
+ *!
+ *!   If more than two values are specified, the PSW remains unchanged and an
+ *!   message indicating an error is printed.
+ *!
+ *!   \textbf{For a z/Architecture guest:}
+ *!
+ *!   If only one hexword4 is specified, PSW bits 96-127 are set to it.
+ *!
+ *!   If hexword3 and hexword4 are specified, PSW bits 64-95 are set to
+ *!   hexword3, and bits 96-127 are set to hexword4.
+ *!
+ *!   If hexword2, hexword3, and hexword4 are specified, PSW bits 32-63 are
+ *!   set to hexword2, bits 64-95 are set to hexword3, and bits 96-127 are
+ *!   set to hexword4.
+ *!
+ *!   If hexword1, hexword2, hexword3, and hexword4 are specified, PSW bits
+ *!   0-31 are set to hexword1, bits 32-63 are set to hexword2, bits 64-95
+ *!   are set to hexword3, and bits 96-127 are set to hexword4.
+ *! \cbend
+ *!! SDNAREPO
+ */
+static int cmd_store_psw(struct virt_sys *sys, char *cmd, int len)
+{
+	u32 *ptr = (u32*) &sys->task->cpu->sie_cb.gpsw;
+
+	u64 new_words[4] = {0, 0, 0, 0};
+	int cnt;
+
+	for (cnt=0; cnt<4; cnt++) {
+		cmd = __extract_hex(cmd, &new_words[cnt]);
+		if (IS_ERR(cmd))
+			break;
+
+		cmd = __consume_ws(cmd);
+	}
+
+	if (!cnt)
+		return -EINVAL;
+
+	if (!VCPU_ZARCH(sys->task->cpu)) {
+		/* ESA/390 mode */
+		if (cnt > 2) {
+			con_printf(sys->con, "STORE: ERROR ESA/390 PSW USES ONLY TWO WORDS\n");
+			return -EINVAL;
+		}
+
+		/*
+		 * This is a simple "hack" to make the stores go into the
+		 * right place.  If he had a single word, we want it to go
+		 * the the second word of the 16-byte PSW, not the 4th.
+		 * Similarly, if we had two words, we want them to go into
+		 * the first and second words of the 16-byte PSW.
+		 */
+		cnt += 2;
+	}
+
+	switch(cnt) {
+		case 4:
+			ptr[0] = (u32) new_words[0];
+			ptr[1] = (u32) new_words[1];
+			ptr[2] = (u32) new_words[2];
+			ptr[3] = (u32) new_words[3];
+			break;
+		case 3:
+			ptr[1] = (u32) new_words[0];
+			ptr[2] = (u32) new_words[1];
+			ptr[3] = (u32) new_words[2];
+			break;
+		case 2:
+			ptr[2] = (u32) new_words[0];
+			ptr[3] = (u32) new_words[1];
+			break;
+		case 1:
+			ptr[3] = (u32) new_words[0];
+			break;
+		case 0:
+			return -EINVAL;
+	}
+
+	con_printf(sys->con, "Store complete.\n");
+	return 0;
+}
+
+static struct cpcmd cmd_tbl_store[] = {
+	{"AR",		cmd_store_ar,		NULL},
+	{"A",		cmd_store_ar,		NULL},
+
+	{"CR",		cmd_store_cr,		NULL},
+	{"C",		cmd_store_cr,		NULL},
+
+	{"FPCR",	cmd_store_fpcr,		NULL},
+
+	{"FPR",		cmd_store_fpr,		NULL},
+	{"FP",		cmd_store_fpr,		NULL},
+	{"F",		cmd_store_fpr,		NULL},
+
+	{"GPR",		cmd_store_gpr,		NULL},
+	{"GP",		cmd_store_gpr,		NULL},
+	{"G",		cmd_store_gpr,		NULL},
+
+	{"PSW",		cmd_store_psw,		NULL},
+
+	{"STORAGE",	cmd_store_storage,	NULL},
+	{"STORAG",	cmd_store_storage,	NULL},
+	{"STORA",	cmd_store_storage,	NULL},
+	{"STOR",	cmd_store_storage,	NULL},
+	{"STO",		cmd_store_storage,	NULL},
+	{"",		NULL,			NULL},
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/cmd_system.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,156 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+extern u32 GUEST_IPL_CODE[];
+extern u32 GUEST_IPL_REGSAVE[];
+
+/*
+ *!!! IPL
+ *!! SYNTAX
+ *! \tok{\sc IPL} <vdev>
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Perform a ...
+ *!! NOTES
+ *! \item Not yet implemented.
+ *!! SETON
+ */
+static int cmd_ipl(struct virt_sys *sys, char *cmd, int len)
+{
+	struct virt_device *vdev;
+	u64 vdevnum = 0;
+	u64 host_addr;
+	int bytes;
+	int ret;
+	int i;
+
+	/* get IPL vdev # */
+	cmd = __extract_hex(cmd, &vdevnum);
+	if (IS_ERR(cmd))
+		return PTR_ERR(cmd);
+
+	/* device numbers are 16-bits */
+	if (vdevnum & ~0xffff)
+		return -EINVAL;
+
+	/* find the virtual device */
+
+	list_for_each_entry(vdev, &sys->virt_devs, devices)
+		if (vdev->pmcw.dev_num == (u16) vdevnum)
+			goto found;
+
+	return -EINVAL; /* device not found */
+
+found:
+	/*
+	 * alright, we got the device... now set up IPL helper
+	 */
+
+	bytes = sizeof(u32)*(GUEST_IPL_REGSAVE-GUEST_IPL_CODE);
+
+	con_printf(sys->con, "WARNING: IPL command is work-in-progress\n");
+
+	/*
+	 * FIXME: this should be conditional based whether or not we were
+	 * told to clear
+	 */
+	guest_load_normal(sys);
+
+	sys->task->cpu->state = GUEST_LOAD;
+
+	ret = virt2phy_current(GUEST_IPL_BASE, &host_addr);
+	if (ret)
+		goto fail;
+
+	/* we can't go over a page! */
+	BUG_ON((bytes+(16*32)) > PAGE_SIZE);
+
+	/* copy the helper into the guest storage */
+	memcpy((void*) host_addr, GUEST_IPL_CODE, bytes);
+
+	/* save the current guest regs */
+	for (i=0; i<16; i++) {
+		u32 *ptr = (u32*) ((u8*) host_addr + bytes);
+
+		ptr[i] = (u32) sys->task->cpu->regs.gpr[i];
+	}
+
+	sys->task->cpu->regs.gpr[1]  = vdev->sch;
+	sys->task->cpu->regs.gpr[2]  = vdev->pmcw.dev_num;
+	sys->task->cpu->regs.gpr[12] = GUEST_IPL_BASE;
+
+	*((u64*) &sys->task->cpu->sie_cb.gpsw) = 0x0008000080000000ULL |
+						 GUEST_IPL_BASE;
+
+	sys->task->cpu->state = GUEST_STOPPED;
+
+	con_printf(sys->con, "GUEST IPL HELPER LOADED; ENTERED STOPPED STATE\n");
+
+	return 0;
+
+fail:
+	sys->task->cpu->state = GUEST_STOPPED;
+	return ret;
+}
+
+/*!!! SYSTEM CLEAR
+ *!! SYNTAX
+ *! \tok{\sc SYStem} \tok{\sc CLEAR}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Identical to reset-clear button on a real mainframe.
+ *
+ *!!! SYSTEM RESET
+ *!p >>--SYSTEM--RESET-------------------------------------------------------------><
+ *!! SYNTAX
+ *! \tok{\sc SYStem} \tok{\sc RESET}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Identical to reset-normal button on a real mainframe.
+ *
+ *!!! SYSTEM RESTART
+ *!! SYNTAX
+ *! \tok{\sc SYStem} \tok{\sc RESTART}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Perform a restart operation.
+ *!! NOTES
+ *! \item Not yet implemented.
+ *!! SETON
+ *
+ *!!! SYSTEM STORE
+ *!! SYNTAX
+ *! \tok{\sc SYStem} \tok{\sc STORE}
+ *!! XATNYS
+ *!! AUTH G
+ *!! PURPOSE
+ *! Perform a ...
+ *!! NOTES
+ *! \item Not yet implemented.
+ *!! SETON
+ */
+static int cmd_system(struct virt_sys *sys, char *cmd, int len)
+{
+	if (!strcasecmp(cmd, "CLEAR")) {
+		guest_system_reset_clear(sys);
+		con_printf(sys->con, "STORAGE CLEARED - SYSTEM RESET\n");
+	} else if (!strcasecmp(cmd, "RESET")) {
+		guest_system_reset_normal(sys);
+		con_printf(sys->con, "SYSTEM RESET\n");
+	} else if (!strcasecmp(cmd, "RESTART")) {
+		con_printf(sys->con, "SYSTEM RESTART is not yet supported\n");
+	} else if (!strcasecmp(cmd, "STORE")) {
+		con_printf(sys->con, "SYSTEM STORE is not yet supported\n");
+	} else
+		con_printf(sys->con, "SYSTEM: Unknown variable '%s'\n", cmd);
+
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/cmds.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,177 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <directory.h>
+#include <vdevice.h>
+#include <dat.h>
+#include <mm.h>
+#include <sched.h>
+#include <disassm.h>
+#include <cpu.h>
+#include <vsprintf.h>
+#include <shell.h>
+
+struct cpcmd {
+	const char name[SHELL_CMD_MAX_LEN];
+
+	/* handle function pointer */
+	int (*fnx)(struct virt_sys *sys, char *cmd, int len);
+
+	/* sub-command handler table */
+	struct cpcmd *sub;
+};
+
+/*
+ * Map a device type to a nice to display name
+ */
+static char* type2name(u16 type)
+{
+	switch (type) {
+		case 0x1403:	return "PRT";
+		case 0x1732:	return "OSA";
+		case 0x3088:	return "CTCA";
+		case 0x3215:	return "CONS";
+		case 0x3278:	return "GRAF";
+		case 0x3505:	return "RDR";
+		case 0x3525:	return "PUN";
+
+		/* various dasds */
+		case 0x3390:
+		case 0x9336:	return "DASD";
+
+		/* various tape drives */
+		case 0x3480:
+		case 0x3490:
+		case 0x3590:	return "TAPE";
+
+		default:	return "????";
+	}
+}
+
+/*
+ * We use includes here to avoid namespace polution with all the sub-command
+ * handler functions
+ */
+#include "cmd_helpers.c"
+#include "cmd_beginstop.c"
+#include "cmd_display.c"
+#include "cmd_enable.c"
+#include "cmd_system.c"
+#include "cmd_query.c"
+#include "cmd_store.c"
+#include "cmd_logon.c"
+#include "cmd_set.c"
+
+static struct cpcmd commands[] = {
+	{"BEGIN",	cmd_begin,		NULL},
+	{"BEGI",	cmd_begin,		NULL},
+	{"BEG",		cmd_begin,		NULL},
+	{"BE",		cmd_begin,		NULL},
+
+	{"DISPLAY",	NULL,			cmd_tbl_display},
+	{"DISPLA",	NULL,			cmd_tbl_display},
+	{"DISPL",	NULL,			cmd_tbl_display},
+	{"DISP",	NULL,			cmd_tbl_display},
+	{"DIS",		NULL,			cmd_tbl_display},
+	{"DI",		NULL,			cmd_tbl_display},
+	{"D",		NULL,			cmd_tbl_display},
+
+	{"ENABLE",	cmd_enable,		NULL},
+	{"ENABL",	cmd_enable,		NULL},
+	{"ENAB",	cmd_enable,		NULL},
+	{"ENA",		cmd_enable,		NULL},
+
+	{"IPL",		cmd_ipl,		NULL},
+	{"IP",		cmd_ipl,		NULL},
+	{"I",		cmd_ipl,		NULL},
+
+	{"LOGON",	cmd_logon_fail,		NULL},
+	{"LOGO",	cmd_logon_fail,		NULL},
+	{"LOG",		cmd_logon_fail,		NULL},
+	{"LO",		cmd_logon_fail,		NULL},
+	{"L",		cmd_logon_fail,		NULL},
+
+	{"QUERY",	NULL,			cmd_tbl_query},
+	{"QUER",	NULL,			cmd_tbl_query},
+	{"QUE",		NULL,			cmd_tbl_query},
+	{"QU",		NULL,			cmd_tbl_query},
+	{"Q",		NULL,			cmd_tbl_query},
+
+	{"SET",		NULL,			cmd_tbl_set},
+
+	{"STOP",	cmd_stop,		NULL},
+
+	{"STORE",	NULL,			cmd_tbl_store},
+	{"STOR",	NULL,			cmd_tbl_store},
+	{"STO",		NULL,			cmd_tbl_store},
+
+	{"SYSTEM",	cmd_system,		NULL},
+	{"SYSTE",	cmd_system,		NULL},
+	{"SYST",	cmd_system,		NULL},
+	{"SYS",		cmd_system,		NULL},
+	{"",		NULL,			NULL},
+};
+
+static struct cpcmd logon_commands[] = {
+	{"LOGON",	cmd_logon,		NULL},
+	{"LOGO",	cmd_logon,		NULL},
+	{"LOG",		cmd_logon,		NULL},
+	{"LO",		cmd_logon,		NULL},
+	{"L",		cmd_logon,		NULL},
+	{"",		NULL,			NULL},
+};
+
+static int __invoke_shell_cmd(struct cpcmd *t, struct virt_sys *sys, char *cmd, int len)
+{
+	int i, ret;
+
+	for(i=0; t[i].name[0]; i++) {
+		const char *inp = cmd, *exp = t[i].name;
+		int match_len = 0;
+
+		while(*inp && *exp && (match_len < len) && (toupper(*inp) == *exp)) {
+			match_len++;
+			inp++;
+			exp++;
+		}
+
+		/* doesn't match */
+		if ((match_len != strnlen(t[i].name, SHELL_CMD_MAX_LEN)) ||
+		    (!isspace(*inp) && *inp))
+			continue;
+
+		/*
+		 * the next char in the input is...
+		 */
+		while((cmd[match_len] == ' ' || cmd[match_len] == '\t') &&
+		      (match_len < len))
+			/*
+			 * command was given arguments - skip over the
+			 * delimiting space
+			 */
+			match_len++;
+
+		if (t[i].sub) {
+			ret = __invoke_shell_cmd(t[i].sub, sys, cmd + match_len, len - match_len);
+			return (ret == -ENOENT) ? -ESUBENOENT : ret;
+		}
+
+		return t[i].fnx(sys, cmd + match_len, len - match_len);
+	}
+
+	return -ENOENT;
+}
+
+int invoke_shell_cmd(struct virt_sys *sys, char *cmd, int len)
+{
+	return __invoke_shell_cmd(commands, sys, cmd, len);
+}
+
+int invoke_shell_logon(struct console *con, char *cmd, int len)
+{
+	return __invoke_shell_cmd(logon_commands, (struct virt_sys*) con, cmd, len);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/directory.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,27 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <errno.h>
+#include <directory.h>
+
+#include "directory_structs.c"
+
+struct user *find_user_by_id(char *userid)
+{
+	struct user *u;
+
+	if (!userid)
+		return ERR_PTR(-ENOENT);
+
+	u = directory;
+
+	for (; u->userid; u++)
+		if (!strcasecmp(u->userid, userid))
+			return u;
+
+	return ERR_PTR(-ENOENT);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/disassm.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,1098 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <disassm.h>
+#include <vsprintf.h>
+
+static struct disassm_instruction l2_01[256] = {	/* 01xx */
+	DA_INST		(0x01, E, PR),
+	DA_INST		(0x02, E, UPT),
+	DA_INST		(0x04, E, PTFF),
+	DA_INST		(0x07, E, SCKPF),
+	DA_INST		(0x0A, E, PFPO),
+	DA_INST		(0x0B, E, TAM),
+	DA_INST		(0x0C, E, SAM24),
+	DA_INST		(0x0D, E, SAM31),
+	DA_INST		(0x0E, E, SAM64),
+	DA_INST		(0xFF, E, TRAP2),
+};
+
+static struct disassm_instruction l2_a5[16] = {		/* A5x */
+	DA_INST		(0x0,  RI1, IIHH),
+	DA_INST		(0x1,  RI1, IIHL),
+	DA_INST		(0x2,  RI1, IILH),
+	DA_INST		(0x3,  RI1, IILL),
+	DA_INST		(0x4,  RI1, NIHH),
+	DA_INST		(0x5,  RI1, NIHL),
+	DA_INST		(0x6,  RI1, NILH),
+	DA_INST		(0x7,  RI1, NILL),
+	DA_INST		(0x8,  RI1, OIHH),
+	DA_INST		(0x9,  RI1, OIHL),
+	DA_INST		(0xA,  RI1, OILH),
+	DA_INST		(0xB,  RI1, OILL),
+	DA_INST		(0xC,  RI1, LLIHH),
+	DA_INST		(0xD,  RI1, LLIHL),
+	DA_INST		(0xE,  RI1, LLILH),
+	DA_INST		(0xF,  RI1, LLILL),
+};
+
+static struct disassm_instruction l2_a7[16] = {		/* A7x */
+	DA_INST		(0x0,  RI1, TMLH),
+	DA_INST		(0x1,  RI1, TMLL),
+	DA_INST		(0x2,  RI1, TMHH),
+	DA_INST		(0x3,  RI1, TMHL),
+	DA_INST		(0x4,  RI2, BRC),
+	DA_INST		(0x5,  RI1, BRAS),
+	DA_INST		(0x6,  RI1, BRCT),
+	DA_INST		(0x7,  RI1, BRCTG),
+	DA_INST		(0x8,  RI1, LHI),
+	DA_INST		(0x9,  RI1, LGHI),
+	DA_INST		(0xA,  RI1, AHI),
+	DA_INST		(0xB,  RI1, AGHI),
+	DA_INST		(0xC,  RI1, MHI),
+	DA_INST		(0xD,  RI1, MGHI),
+	DA_INST		(0xE,  RI1, CHI),
+	DA_INST		(0xF,  RI1, CGHI),
+};
+
+static struct disassm_instruction l2_b2[256] = {	/* B2xx */
+	DA_INST		(0x02, S, STIDP),
+	DA_INST		(0x04, S, SCK),
+	DA_INST		(0x05, S, STCK),
+	DA_INST		(0x06, S, SCKC),
+	DA_INST		(0x07, S, STCKC),
+	DA_INST		(0x08, S, SPT),
+	DA_INST		(0x09, S, STPT),
+	DA_INST		(0x0A, S, SPKA),
+	DA_INST		(0x0B, S, IPK),
+	DA_INST		(0x0D, S, PTLB),
+	DA_INST		(0x10, S, SPX),
+	DA_INST		(0x11, S, STPX),
+	DA_INST		(0x12, S, STAP),
+	DA_INST		(0x14, S, SIE),
+	DA_INST		(0x18, S, PC),
+	DA_INST		(0x19, S, SAC),
+	DA_INST		(0x1A, S, CFC),
+	DA_INST		(0x21, RRE, IPTE),
+	DA_INST		(0x22, RRE, IPM),
+	DA_INST		(0x23, RRE, IVSK),
+	DA_INST		(0x24, RRE, IAC),
+	DA_INST		(0x25, RRE, SSAR),
+	DA_INST		(0x26, RRE, EPAR),
+	DA_INST		(0x27, RRE, ESAR),
+	DA_INST		(0x28, RRE, PT),
+	DA_INST		(0x29, RRE, ISKE),
+	DA_INST		(0x2A, RRE, RRBE),
+	DA_INST		(0x2B, RRF2, SSKE),
+	DA_INST		(0x2C, RRE, TB),
+	DA_INST		(0x2D, RRE, DXR),
+	DA_INST		(0x2E, RRE, PGIN),
+	DA_INST		(0x2F, RRE, PGOUT),
+	DA_INST		(0x30, S, CSCH),
+	DA_INST		(0x31, S, HSCH),
+	DA_INST		(0x32, S, MSCH),
+	DA_INST		(0x33, S, SSCH),
+	DA_INST		(0x34, S, STSCH),
+	DA_INST		(0x35, S, TSCH),
+	DA_INST		(0x36, S, TPI),
+	DA_INST		(0x37, S, SAL),
+	DA_INST		(0x38, S, RSCH),
+	DA_INST		(0x39, S, STCRW),
+	DA_INST		(0x3A, S, STCPS),
+	DA_INST		(0x3B, S, RCHP),
+	DA_INST		(0x3D, S, SCHM),
+	DA_INST		(0x40, RRE, BAKR),
+	DA_INST		(0x41, RRE, CKSM),
+	DA_INST		(0x44, RRE, SQDR),
+	DA_INST		(0x45, RRE, SQER),
+	DA_INST		(0x46, RRE, STURA),
+	DA_INST		(0x47, RRE, MSTA),
+	DA_INST		(0x48, RRE, PALB),
+	DA_INST		(0x49, RRE, EREG),
+	DA_INST		(0x4A, RRE, ESTA),
+	DA_INST		(0x4B, RRE, LURA),
+	DA_INST		(0x4C, RRE, TAR),
+	DA_INST		(0x4D, RRE, CPYA),
+	DA_INST		(0x4E, RRE, SAR),
+	DA_INST		(0x4F, RRE, EAR),
+	DA_INST		(0x50, RRE, CSP),
+	DA_INST		(0x52, RRE, MSR),
+	DA_INST		(0x54, RRE, MVPG),
+	DA_INST		(0x55, RRE, MVST),
+	DA_INST		(0x57, RRE, CUSE),
+	DA_INST		(0x58, RRE, BSG),
+	DA_INST		(0x5A, RRE, BSA),
+	DA_INST		(0x5D, RRE, CLST),
+	DA_INST		(0x5E, RRE, SRST),
+	DA_INST		(0x63, RRE, CMPSC),
+	DA_INST		(0x76, S, XSCH),
+	DA_INST		(0x77, S, RP),
+	DA_INST		(0x78, S, STCKE),
+	DA_INST		(0x79, S, SACF),
+	DA_INST		(0x7C, S, STCKF),
+	DA_INST		(0x7D, S, STSI),
+	DA_INST		(0x99, S, SRNM),
+	DA_INST		(0x9C, S, STFPC),
+	DA_INST		(0x9D, S, LFPC),
+	DA_INST		(0xA5, RRE, TRE),
+	DA_INST		(0xA6, RRF2, CUUTF),
+	DA_INST		(0xA7, RRF2, CUTFU),
+	DA_INST		(0xB0, S, STFLE),
+	DA_INST		(0xB1, S, STFL),
+	DA_INST		(0xB2, S, LPSWE),
+	DA_INST		(0xB9, S, SRNMT),
+	DA_INST		(0xBD, S, LFAS),
+	DA_INST		(0xFF, S, TRAP4),
+};
+
+static struct disassm_instruction l2_b3[256] = {	/* B3xx */
+	DA_INST		(0x00, RRE, LPEBR),
+	DA_INST		(0x01, RRE, LNEBR),
+	DA_INST		(0x02, RRE, LTEBR),
+	DA_INST		(0x03, RRE, LCEBR),
+	DA_INST		(0x04, RRE, LDEBR),
+	DA_INST		(0x05, RRE, LXDBR),
+	DA_INST		(0x06, RRE, LXEBR),
+	DA_INST		(0x07, RRE, MXDBR),
+	DA_INST		(0x08, RRE, KEBR),
+	DA_INST		(0x09, RRE, CEBR),
+	DA_INST		(0x0A, RRE, AEBR),
+	DA_INST		(0x0B, RRE, SEBR),
+	DA_INST		(0x0C, RRE, MDEBR),
+	DA_INST		(0x0D, RRE, DEBR),
+	DA_INST		(0x0E, RRF1, MAEBR),
+	DA_INST		(0x0F, RRF1, MSEBR),
+	DA_INST		(0x10, RRE, LPDBR),
+	DA_INST		(0x11, RRE, LNDBR),
+	DA_INST		(0x12, RRE, LTDBR),
+	DA_INST		(0x13, RRE, LCDBR),
+	DA_INST		(0x14, RRE, SQEBR),
+	DA_INST		(0x15, RRE, SQDBR),
+	DA_INST		(0x16, RRE, SQXBR),
+	DA_INST		(0x17, RRE, MEEBR),
+	DA_INST		(0x18, RRE, KDBR),
+	DA_INST		(0x19, RRE, CDBR),
+	DA_INST		(0x1A, RRE, ADBR),
+	DA_INST		(0x1B, RRE, SDBR),
+	DA_INST		(0x1C, RRE, MDBR),
+	DA_INST		(0x1D, RRE, DDBR),
+	DA_INST		(0x1E, RRF1, MADBR),
+	DA_INST		(0x1F, RRF1, MSDBR),
+	DA_INST		(0x24, RRE, LDER),
+	DA_INST		(0x25, RRE, LXDR),
+	DA_INST		(0x26, RRE, LXER),
+	DA_INST		(0x2E, RRF1, MAER),
+	DA_INST		(0x2F, RRF1, MSER),
+	DA_INST		(0x36, RRE, SQXR),
+	DA_INST		(0x37, RRE, MEER),
+	DA_INST		(0x38, RRF1, MAYLR),
+	DA_INST		(0x39, RRF1, MYLR),
+	DA_INST		(0x3A, RRF1, MAYR),
+	DA_INST		(0x3B, RRF1, MYR),
+	DA_INST		(0x3C, RRF1, MAYHR),
+	DA_INST		(0x3D, RRF1, MYHR),
+	DA_INST		(0x3E, RRF1, MADR),
+	DA_INST		(0x3F, RRF1, MSDR),
+	DA_INST		(0x40, RRE, LPXBR),
+	DA_INST		(0x41, RRE, LNXBR),
+	DA_INST		(0x42, RRE, LTXBR),
+	DA_INST		(0x43, RRE, LCXBR),
+	DA_INST		(0x44, RRE, LEDBR),
+	DA_INST		(0x45, RRE, LDXBR),
+	DA_INST		(0x46, RRE, LEXBR),
+	DA_INST		(0x47, RRF2, FIXBR),
+	DA_INST		(0x48, RRE, KXBR),
+	DA_INST		(0x49, RRE, CXBR),
+	DA_INST		(0x4A, RRE, AXBR),
+	DA_INST		(0x4B, RRE, SXBR),
+	DA_INST		(0x4C, RRE, MXBR),
+	DA_INST		(0x4D, RRE, DXBR),
+	DA_INST		(0x50, RRF2, TBEDR),
+	DA_INST		(0x51, RRF2, TBDR),
+	DA_INST		(0x53, RRF3, DIEBR),
+	DA_INST		(0x57, RRF2, FIEBR),
+	DA_INST		(0x58, RRE, THDER),
+	DA_INST		(0x59, RRE, THDR),
+	DA_INST		(0x5B, RRF3, DIDBR),
+	DA_INST		(0x5F, RRF2, FIDBR),
+	DA_INST		(0x60, RRE, LPXR),
+	DA_INST		(0x61, RRE, LNXR),
+	DA_INST		(0x62, RRE, LTXR),
+	DA_INST		(0x63, RRE, LCXR),
+	DA_INST		(0x65, RRE, LXR),
+	DA_INST		(0x66, RRE, LEXR),
+	DA_INST		(0x67, RRE, FIXR),
+	DA_INST		(0x69, RRE, CXR),
+	DA_INST		(0x70, RRE, LPDFR),
+	DA_INST		(0x71, RRE, LNDFR),
+	DA_INST		(0x72, RRF1, CPSDR),
+	DA_INST		(0x73, RRE, LCDFR),
+	DA_INST		(0x74, RRE, LZER),
+	DA_INST		(0x75, RRE, LZDR),
+	DA_INST		(0x76, RRE, LZXR),
+	DA_INST		(0x77, RRE, FIER),
+	DA_INST		(0x7F, RRE, FIDR),
+	DA_INST		(0x84, RRE, SFPC),
+	DA_INST		(0x85, RRE, SFASR),
+	DA_INST		(0x8C, RRE, EFPC),
+	DA_INST		(0x94, RRE, CEFBR),
+	DA_INST		(0x95, RRE, CDFBR),
+	DA_INST		(0x96, RRE, CXFBR),
+	DA_INST		(0x98, RRF2, CFEBR),
+	DA_INST		(0x99, RRF2, CFDBR),
+	DA_INST		(0x9A, RRF2, CFXBR),
+	DA_INST		(0xA4, RRE, CEGBR),
+	DA_INST		(0xA5, RRE, CDGBR),
+	DA_INST		(0xA6, RRE, CXGBR),
+	DA_INST		(0xA8, RRF2, CGEBR),
+	DA_INST		(0xA9, RRF2, CGDBR),
+	DA_INST		(0xAA, RRF2, CGXBR),
+	DA_INST		(0xB4, RRE, CEFR),
+	DA_INST		(0xB5, RRE, CDFR),
+	DA_INST		(0xB6, RRE, CXFR),
+	DA_INST		(0xB8, RRF2, CFER),
+	DA_INST		(0xB9, RRF2, CFDR),
+	DA_INST		(0xBA, RRF2, CFXR),
+	DA_INST		(0xC1, RRE, LDGR),
+	DA_INST		(0xC4, RRE, CEGR),
+	DA_INST		(0xC5, RRE, CDGR),
+	DA_INST		(0xC6, RRE, CXGR),
+	DA_INST		(0xC8, RRF2, CGER),
+	DA_INST		(0xC9, RRF2, CGDR),
+	DA_INST		(0xCA, RRF2, CGXR),
+	DA_INST		(0xCD, RRE, LGDR),
+	DA_INST		(0xD0, RRR, MDTR),
+	DA_INST		(0xD1, RRR, DDTR),
+	DA_INST		(0xD2, RRR, ADTR),
+	DA_INST		(0xD3, RRR, SDTR),
+	DA_INST		(0xD4, RRF3, LDETR),
+	DA_INST		(0xD5, RRF3, LEDTR),
+	DA_INST		(0xD6, RRE, LTDTR),
+	DA_INST		(0xD7, RRF3, FIDTR),
+	DA_INST		(0xD8, RRR, MXTR),
+	DA_INST		(0xD9, RRR, DXTR),
+	DA_INST		(0xDA, RRR, AXTR),
+	DA_INST		(0xDB, RRR, SXTR),
+	DA_INST		(0xDC, RRF3, LXDTR),
+	DA_INST		(0xDD, RRF3, LDXTR),
+	DA_INST		(0xDE, RRE, LTXTR),
+	DA_INST		(0xDF, RRF3, FIXTR),
+	DA_INST		(0xE0, RRE, KDTR),
+	DA_INST		(0xE1, RRF2, CGDTR),
+	DA_INST		(0xE2, RRE, CUDTR),
+	DA_INST		(0xE3, RRF3, CSDTR),
+	DA_INST		(0xE4, RRE, CDTR),
+	DA_INST		(0xE5, RRE, EEDTR),
+	DA_INST		(0xE7, RRE, ESDTR),
+	DA_INST		(0xE8, RRE, KXTR),
+	DA_INST		(0xE9, RRF2, CGXTR),
+	DA_INST		(0xEA, RRE, CUXTR),
+	DA_INST		(0xEB, RRF3, CSXTR),
+	DA_INST		(0xEC, RRE, CXTR),
+	DA_INST		(0xED, RRE, EEXTR),
+	DA_INST		(0xEF, RRE, ESXTR),
+	DA_INST		(0xF1, RRE, CDGTR),
+	DA_INST		(0xF2, RRE, CDUTR),
+	DA_INST		(0xF3, RRE, CDSTR),
+	DA_INST		(0xF4, RRE, CEDTR),
+	DA_INST		(0xF5, RRF3, QADTR),
+	DA_INST		(0xF6, RRF3, IEDTR),
+	DA_INST		(0xF7, RRF3, RRDTR),
+	DA_INST		(0xF9, RRE, CXGTR),
+	DA_INST		(0xFA, RRE, CXUTR),
+	DA_INST		(0xFB, RRE, CXSTR),
+	DA_INST		(0xFC, RRE, CEXTR),
+	DA_INST		(0xFD, RRF3, QAXTR),
+	DA_INST		(0xFE, RRF3, IEXTR),
+	DA_INST		(0xFF, RRF3, RRXTR),
+};
+
+static struct disassm_instruction l2_b9[256] = {	/* B9xx */
+	DA_INST		(0x00, RRE, LPGR),
+	DA_INST		(0x01, RRE, LNGR),
+	DA_INST		(0x02, RRE, LTGR),
+	DA_INST		(0x03, RRE, LCGR),
+	DA_INST		(0x04, RRE, LGR),
+	DA_INST		(0x05, RRE, LURAG),
+	DA_INST		(0x06, RRE, LGBR),
+	DA_INST		(0x07, RRE, LGHR),
+	DA_INST		(0x08, RRE, AGR),
+	DA_INST		(0x09, RRE, SGR),
+	DA_INST		(0x0A, RRE, ALGR),
+	DA_INST		(0x0B, RRE, SLGR),
+	DA_INST		(0x0C, RRE, MSGR),
+	DA_INST		(0x0D, RRE, DSGR),
+	DA_INST		(0x0E, RRE, EREGG),
+	DA_INST		(0x0F, RRE, LRVGR),
+	DA_INST		(0x10, RRE, LPGFR),
+	DA_INST		(0x11, RRE, LNGFR),
+	DA_INST		(0x12, RRE, LTGFR),
+	DA_INST		(0x13, RRE, LCGFR),
+	DA_INST		(0x14, RRE, LGFR),
+	DA_INST		(0x16, RRE, LLGFR),
+	DA_INST		(0x17, RRE, LLGTR),
+	DA_INST		(0x18, RRE, AGFR),
+	DA_INST		(0x19, RRE, SGFR),
+	DA_INST		(0x1A, RRE, ALGFR),
+	DA_INST		(0x1B, RRE, SLGFR),
+	DA_INST		(0x1C, RRE, MSGFR),
+	DA_INST		(0x1D, RRE, DSGFR),
+	DA_INST		(0x1E, RRE, KMAC),
+	DA_INST		(0x1F, RRE, LRVR),
+	DA_INST		(0x20, RRE, CGR),
+	DA_INST		(0x21, RRE, CLGR),
+	DA_INST		(0x25, RRE, STURG),
+	DA_INST		(0x26, RRE, LBR),
+	DA_INST		(0x27, RRE, LHR),
+	DA_INST		(0x2E, RRE, KM),
+	DA_INST		(0x2F, RRE, KMC),
+	DA_INST		(0x30, RRE, CGFR),
+	DA_INST		(0x31, RRE, CLGFR),
+	DA_INST		(0x3E, RRE, KIMD),
+	DA_INST		(0x3F, RRE, KLMD),
+	DA_INST		(0x46, RRE, BCTGR),
+	DA_INST		(0x60, RRF2, CGRT),
+	DA_INST		(0x61, RRF2, CLGRT),
+	DA_INST		(0x72, RRF2, CRT),
+	DA_INST		(0x73, RRF2, CLRT),
+	DA_INST		(0x80, RRE, NGR),
+	DA_INST		(0x81, RRE, OGR),
+	DA_INST		(0x82, RRE, XGR),
+	DA_INST		(0x83, RRE, FLOGR),
+	DA_INST		(0x84, RRE, LLGCR),
+	DA_INST		(0x85, RRE, LLGHR),
+	DA_INST		(0x86, RRE, MLGR),
+	DA_INST		(0x87, RRE, DLGR),
+	DA_INST		(0x88, RRE, ALCGR),
+	DA_INST		(0x89, RRE, SLBGR),
+	DA_INST		(0x8A, RRE, CSPG),
+	DA_INST		(0x8D, RRE, EPSW),
+	DA_INST		(0x8E, RRF3, IDTE),
+	DA_INST		(0x90, RRF2, TRTT),
+	DA_INST		(0x91, RRF2, TRTO),
+	DA_INST		(0x92, RRF2, TROT),
+	DA_INST		(0x93, RRF2, TROO),
+	DA_INST		(0x94, RRE, LLCR),
+	DA_INST		(0x95, RRE, LLHR),
+	DA_INST		(0x96, RRE, MLR),
+	DA_INST		(0x97, RRE, DLR),
+	DA_INST		(0x98, RRE, ALCR),
+	DA_INST		(0x99, RRE, SLBR),
+	DA_INST		(0x9A, RRE, EPAIR),
+	DA_INST		(0x9B, RRE, ESAIR),
+	DA_INST		(0x9D, RRE, ESEA),
+	DA_INST		(0x9E, RRE, PTI),
+	DA_INST		(0x9F, RRE, SSAIR),
+	DA_INST		(0xA2, RRE, PTF),
+	DA_INST		(0xAA, RRF3, LPTEA),
+	DA_INST		(0xAF, RRE, PFMF),
+	DA_INST		(0xB0, RRF2, CU14),
+	DA_INST		(0xB1, RRF2, CU24),
+	DA_INST		(0xB2, RRE, CU41),
+	DA_INST		(0xB3, RRE, CU42),
+	DA_INST		(0xBD, RRF2, TRTRE),
+	DA_INST		(0xBE, RRE, SRSTU),
+	DA_INST		(0xBF, RRF2, TRTE),
+};
+
+static struct disassm_instruction l2_c0[16] = {		/* C0x */
+	DA_INST		(0x0,  RIL1, LARL),
+	DA_INST		(0x1,  RIL1, LGFI),
+	DA_INST		(0x4,  RIL2, BRCL),
+	DA_INST		(0x5,  RIL1, BRASL),
+	DA_INST		(0x6,  RIL1, XIHF),
+	DA_INST		(0x7,  RIL1, XILF),
+	DA_INST		(0x8,  RIL1, IIHF),
+	DA_INST		(0x9,  RIL1, IILF),
+	DA_INST		(0xA,  RIL1, NIHF),
+	DA_INST		(0xB,  RIL1, NILF),
+	DA_INST		(0xC,  RIL1, OIHF),
+	DA_INST		(0xD,  RIL1, OILF),
+	DA_INST		(0xE,  RIL1, LLIHF),
+	DA_INST		(0xF,  RIL1, LLILF),
+};
+
+static struct disassm_instruction l2_c2[16] = {		/* C2x */
+	DA_INST		(0x0,  RIL1, MSGFI),
+	DA_INST		(0x1,  RIL1, MSFI),
+	DA_INST		(0x4,  RIL1, SLGFI),
+	DA_INST		(0x5,  RIL1, SLFI),
+	DA_INST		(0x8,  RIL1, AGFI),
+	DA_INST		(0x9,  RIL1, AFI),
+	DA_INST		(0xA,  RIL1, ALGFI),
+	DA_INST		(0xB,  RIL1, ALFI),
+	DA_INST		(0xC,  RIL1, CGFI),
+	DA_INST		(0xD,  RIL1, CFI),
+	DA_INST		(0xE,  RIL1, CLGFI),
+	DA_INST		(0xF,  RIL1, CLFI),
+};
+
+static struct disassm_instruction l2_c4[16] = {		/* C4x */
+	DA_INST		(0x2,  RIL1, LLHRL),
+	DA_INST		(0x4,  RIL1, LGHRL),
+	DA_INST		(0x5,  RIL1, LHRL),
+	DA_INST		(0x6,  RIL1, LLGHRL),
+	DA_INST		(0x7,  RIL1, STHRL),
+	DA_INST		(0x8,  RIL1, LGRL),
+	DA_INST		(0xB,  RIL1, STGRL),
+	DA_INST		(0xC,  RIL1, LGFRL),
+	DA_INST		(0xD,  RIL1, LRL),
+	DA_INST		(0xE,  RIL1, LLGFRL),
+	DA_INST		(0xF,  RIL1, STRL),
+};
+
+static struct disassm_instruction l2_c6[16] = {		/* C6x */
+	DA_INST		(0x0,  RIL1, EXRL),
+	DA_INST		(0x2,  RIL2, PFDRL),
+	DA_INST		(0x4,  RIL1, CGHRL),
+	DA_INST		(0x5,  RIL1, CHRL),
+	DA_INST		(0x6,  RIL1, CLGHRL),
+	DA_INST		(0x7,  RIL1, CLHRL),
+	DA_INST		(0x8,  RIL1, CGRL),
+	DA_INST		(0xA,  RIL1, CLGRL),
+	DA_INST		(0xC,  RIL1, CGFRL),
+	DA_INST		(0xD,  RIL1, CRL),
+	DA_INST		(0xE,  RIL1, CLGFRL),
+	DA_INST		(0xF,  RIL1, CLRL),
+};
+
+static struct disassm_instruction l2_c8[16] = {		/* C8x */
+	DA_INST		(0x0,  SSF, MVCOS),
+	DA_INST		(0x1,  SSF, ECTG),
+	DA_INST		(0x2,  SSF, CSST),
+};
+
+static struct disassm_instruction l2_e3[256] = {	/* E3xx */
+	DA_INST		(0x02, RXY, LTG),
+	DA_INST		(0x03, RXY, LRAG),
+	DA_INST		(0x04, RXY, LG),
+	DA_INST		(0x06, RXY, CVBY),
+	DA_INST		(0x08, RXY, AG),
+	DA_INST		(0x09, RXY, SG),
+	DA_INST		(0x0A, RXY, ALG),
+	DA_INST		(0x0B, RXY, SLG),
+	DA_INST		(0x0C, RXY, MSG),
+	DA_INST		(0x0D, RXY, DSG),
+	DA_INST		(0x0E, RXY, CVBG),
+	DA_INST		(0x0F, RXY, LRVG),
+	DA_INST		(0x12, RXY, LT),
+	DA_INST		(0x13, RXY, LRAY),
+	DA_INST		(0x14, RXY, LGF),
+	DA_INST		(0x15, RXY, LGH),
+	DA_INST		(0x16, RXY, LLGF),
+	DA_INST		(0x17, RXY, LLGT),
+	DA_INST		(0x18, RXY, AGF),
+	DA_INST		(0x19, RXY, SGF),
+	DA_INST		(0x1A, RXY, ALGF),
+	DA_INST		(0x1B, RXY, SLGF),
+	DA_INST		(0x1C, RXY, MSGF),
+	DA_INST		(0x1D, RXY, DSGF),
+	DA_INST		(0x1E, RXY, LRV),
+	DA_INST		(0x1F, RXY, LRVH),
+	DA_INST		(0x20, RXY, CG),
+	DA_INST		(0x21, RXY, CLG),
+	DA_INST		(0x24, RXY, STG),
+	DA_INST		(0x26, RXY, CVDY),
+	DA_INST		(0x2E, RXY, CVDG),
+	DA_INST		(0x2F, RXY, STRVG),
+	DA_INST		(0x30, RXY, CGF),
+	DA_INST		(0x31, RXY, CLGF),
+	DA_INST		(0x32, RXY, LTGF),
+	DA_INST		(0x34, RXY, CGH),
+	DA_INST		(0x36, RXY, PFD),
+	DA_INST		(0x3E, RXY, STRV),
+	DA_INST		(0x3F, RXY, STRVH),
+	DA_INST		(0x46, RXY, BCTG),
+	DA_INST		(0x50, RXY, STY),
+	DA_INST		(0x51, RXY, MSY),
+	DA_INST		(0x54, RXY, NY),
+	DA_INST		(0x55, RXY, CLY),
+	DA_INST		(0x56, RXY, OY),
+	DA_INST		(0x57, RXY, XY),
+	DA_INST		(0x58, RXY, LY),
+	DA_INST		(0x59, RXY, CY),
+	DA_INST		(0x5A, RXY, AY),
+	DA_INST		(0x5B, RXY, SY),
+	DA_INST		(0x5C, RXY, MFY),
+	DA_INST		(0x5E, RXY, ALY),
+	DA_INST		(0x5F, RXY, SLY),
+	DA_INST		(0x70, RXY, STHY),
+	DA_INST		(0x71, RXY, LAY),
+	DA_INST		(0x72, RXY, STCY),
+	DA_INST		(0x73, RXY, ICY),
+	DA_INST		(0x75, RXY, LAEY),
+	DA_INST		(0x76, RXY, LB),
+	DA_INST		(0x77, RXY, LGB),
+	DA_INST		(0x78, RXY, LHY),
+	DA_INST		(0x79, RXY, CHY),
+	DA_INST		(0x7A, RXY, AHY),
+	DA_INST		(0x7B, RXY, SHY),
+	DA_INST		(0x7C, RXY, MHY),
+	DA_INST		(0x80, RXY, NG),
+	DA_INST		(0x81, RXY, OG),
+	DA_INST		(0x82, RXY, XG),
+	DA_INST		(0x86, RXY, MLG),
+	DA_INST		(0x87, RXY, DLG),
+	DA_INST		(0x88, RXY, ALCG),
+	DA_INST		(0x89, RXY, SLBG),
+	DA_INST		(0x8E, RXY, STPQ),
+	DA_INST		(0x8F, RXY, LPQ),
+	DA_INST		(0x90, RXY, LLGC),
+	DA_INST		(0x91, RXY, LLGH),
+	DA_INST		(0x94, RXY, LLC),
+	DA_INST		(0x95, RXY, LLH),
+	DA_INST		(0x96, RXY, ML),
+	DA_INST		(0x97, RXY, DL),
+	DA_INST		(0x98, RXY, ALC),
+	DA_INST		(0x99, RXY, SLB),
+};
+
+static struct disassm_instruction l2_e5[256] = {	/* E5xx */
+	DA_INST		(0x00, SSE, LASP),
+	DA_INST		(0x01, SSE, TPROT),
+	DA_INST		(0x02, SSE, STRAG),
+	DA_INST		(0x0E, SSE, MVCSK),
+	DA_INST		(0x0F, SSE, MVCDK),
+	DA_INST		(0x44, SIL, MVHHI),
+	DA_INST		(0x48, SIL, MVGHI),
+	DA_INST		(0x4C, SIL, MVHI),
+	DA_INST		(0x54, SIL, CHHSI),
+	DA_INST		(0x55, SIL, CLHHSI),
+	DA_INST		(0x58, SIL, CGHSI),
+	DA_INST		(0x59, SIL, CLGHSI),
+	DA_INST		(0x5C, SIL, CHSI),
+	DA_INST		(0x5D, SIL, CLFHSI),
+};
+
+static struct disassm_instruction l2_eb[256] = {	/* EBxx */
+	DA_INST		(0x04, RSY1, LMG),
+	DA_INST		(0x0A, RSY1, SRAG),
+	DA_INST		(0x0B, RSY1, SLAG),
+	DA_INST		(0x0C, RSY1, SRLG),
+	DA_INST		(0x0D, RSY1, SLLG),
+	DA_INST		(0x0F, RSY1, TRACG),
+	DA_INST		(0x14, RSY1, CSY),
+	DA_INST		(0x1C, RSY1, RLLG),
+	DA_INST		(0x1D, RSY1, RLL),
+	DA_INST		(0x20, RSY2, CLMH),
+	DA_INST		(0x21, RSY2, CLMY),
+	DA_INST		(0x24, RSY1, STMG),
+	DA_INST		(0x25, RSY1, STCTG),
+	DA_INST		(0x26, RSY1, STMH),
+	DA_INST		(0x2C, RSY2, STCMH),
+	DA_INST		(0x2D, RSY2, STCMY),
+	DA_INST		(0x2F, RSY1, LCTLG),
+	DA_INST		(0x30, RSY1, CSG),
+	DA_INST		(0x31, RSY1, CDSY),
+	DA_INST		(0x3E, RSY1, CDSG),
+	DA_INST		(0x44, RSY1, BXHG),
+	DA_INST		(0x45, RSY1, BXLEG),
+	DA_INST		(0x4C, RSY1, ECAG),
+	DA_INST		(0x51, SIY, TMY),
+	DA_INST		(0x52, SIY, MVIY),
+	DA_INST		(0x54, SIY, NIY),
+	DA_INST		(0x55, SIY, CLIY),
+	DA_INST		(0x56, SIY, OIY),
+	DA_INST		(0x57, SIY, XIY),
+	DA_INST		(0x6A, SIY, ASI),
+	DA_INST		(0x6E, SIY, ALSI),
+	DA_INST		(0x80, RSY2, ICMH),
+	DA_INST		(0x81, RSY2, ICMY),
+	DA_INST		(0x8E, RSY1, MVCLU),
+	DA_INST		(0x8F, RSY1, CLCLU),
+	DA_INST		(0x90, RSY1, STMY),
+	DA_INST		(0x96, RSY1, LMH),
+	DA_INST		(0x98, RSY1, LMY),
+	DA_INST		(0x9A, RSY1, LAMY),
+	DA_INST		(0x9B, RSY1, STAMY),
+	DA_INST		(0xC0, RSL, TP),
+};
+
+static struct disassm_instruction l2_ec[256] = {	/* ECxx */
+	DA_INST		(0x44, RIE, BRXHG),
+	DA_INST		(0x45, RIE, BRXLG),
+	DA_INST		(0x54, RIE, RNSBG),
+	DA_INST		(0x55, RIE, RISBG),
+	DA_INST		(0x56, RIE, ROSBG),
+	DA_INST		(0x57, RIE, RXSBG),
+	DA_INST		(0x64, RIE, CGRJ),
+	DA_INST		(0x65, RIE, CLGRJ),
+	DA_INST		(0x70, RIE, CGIT),
+	DA_INST		(0x71, RIE, CLGIT),
+	DA_INST		(0x72, RIE, CIT),
+	DA_INST		(0x73, RIE, CLFIT),
+	DA_INST		(0x76, RIE, CRJ),
+	DA_INST		(0x77, RIE, CLRJ),
+	DA_INST		(0x7C, RIE, CGIJ),
+	DA_INST		(0x7D, RIE, CLGIJ),
+	DA_INST		(0x7E, RIE, CIJ),
+	DA_INST		(0x7F, RIE, CLIJ),
+	DA_INST		(0xE4, RRS, CGRB),
+	DA_INST		(0xE5, RRS, CLGRB),
+	DA_INST		(0xF6, RRS, CRB),
+	DA_INST		(0xF7, RRS, CLRB),
+	DA_INST		(0xFC, RIS, CGIB),
+	DA_INST		(0xFD, RIS, CLGIB),
+};
+
+static struct disassm_instruction l2_ed[256] = {	/* EDxx */
+	DA_INST		(0x04, RXE, LDEB),
+	DA_INST		(0x05, RXE, LXDB),
+	DA_INST		(0x06, RXE, LXEB),
+	DA_INST		(0x07, RXE, MXDB),
+	DA_INST		(0x08, RXE, KEB),
+	DA_INST		(0x09, RXE, CEB),
+	DA_INST		(0x0A, RXE, AEB),
+	DA_INST		(0x0B, RXE, SEB),
+	DA_INST		(0x0C, RXE, MDEB),
+	DA_INST		(0x0D, RXE, DEB),
+	DA_INST		(0x0E, RXE, MAEB),
+	DA_INST		(0x0F, RXE, MSEB),
+	DA_INST		(0x10, RXE, TCEB),
+	DA_INST		(0x11, RXE, TCDB),
+	DA_INST		(0x12, RXE, TCXB),
+	DA_INST		(0x14, RXE, SQEB),
+	DA_INST		(0x15, RXE, SQDB),
+	DA_INST		(0x17, RXE, MEEB),
+	DA_INST		(0x18, RXE, KDB),
+	DA_INST		(0x19, RXE, CDB),
+	DA_INST		(0x1A, RXE, ADB),
+	DA_INST		(0x1B, RXE, SDB),
+	DA_INST		(0x1C, RXE, MDB),
+	DA_INST		(0x1D, RXE, DDB),
+	DA_INST		(0x1E, RXF, MADB),
+	DA_INST		(0x1F, RXF, MSDB),
+	DA_INST		(0x24, RXE, LDE),
+	DA_INST		(0x25, RXE, LXD),
+	DA_INST		(0x26, RXE, LXE),
+	DA_INST		(0x2E, RXF, MAE),
+	DA_INST		(0x2F, RXF, MSE),
+	DA_INST		(0x34, RXE, SQE),
+	DA_INST		(0x35, RXE, SQD),
+	DA_INST		(0x37, RXE, MEE),
+	DA_INST		(0x38, RXF, MAYL),
+	DA_INST		(0x39, RXF, MYL),
+	DA_INST		(0x3A, RXF, MAY),
+	DA_INST		(0x3B, RXF, MY),
+	DA_INST		(0x3C, RXF, MAYH),
+	DA_INST		(0x3D, RXF, MYH),
+	DA_INST		(0x3E, RXF, MAD),
+	DA_INST		(0x3F, RXF, MSD),
+	DA_INST		(0x40, RXF, SLDT),
+	DA_INST		(0x41, RXF, SRDT),
+	DA_INST		(0x48, RXF, SLXT),
+	DA_INST		(0x49, RXF, SRXT),
+	DA_INST		(0x50, RXE, TDCET),
+	DA_INST		(0x51, RXE, TDGET),
+	DA_INST		(0x54, RXE, TDCDT),
+	DA_INST		(0x55, RXE, TDGDT),
+	DA_INST		(0x58, RXE, TDCXT),
+	DA_INST		(0x59, RXE, TDGXT),
+	DA_INST		(0x64, RXY, LEY),
+	DA_INST		(0x65, RXY, LDY),
+	DA_INST		(0x66, RXY, STEY),
+	DA_INST		(0x67, RXY, STDY),
+};
+
+static struct disassm_instruction l1[256] = {		/* xx */
+	DA_INST_TBL	(0x01, l2_01, 8, 8),
+	DA_INST		(0x04, RR, SPM),
+	DA_INST		(0x05, RR, BALR),
+	DA_INST		(0x06, RR, BCTR),
+	DA_INST		(0x07, RR_MASK, BCR),
+	DA_INST		(0x0A, I, SVC),
+	DA_INST		(0x0B, RR, BSM),
+	DA_INST		(0x0C, RR, BASSM),
+	DA_INST		(0x0D, RR, BASR),
+	DA_INST		(0x0E, RR, MVCL),
+	DA_INST		(0x0F, RR, CLCL),
+	DA_INST		(0x10, RR, LPR),
+	DA_INST		(0x11, RR, LNR),
+	DA_INST		(0x12, RR, LTR),
+	DA_INST		(0x13, RR, LCR),
+	DA_INST		(0x14, RR, NR),
+	DA_INST		(0x15, RR, CLR),
+	DA_INST		(0x16, RR, OR),
+	DA_INST		(0x17, RR, XR),
+	DA_INST		(0x18, RR, LR),
+	DA_INST		(0x19, RR, CR),
+	DA_INST		(0x1A, RR, AR),
+	DA_INST		(0x1B, RR, SR),
+	DA_INST		(0x1C, RR, MR),
+	DA_INST		(0x1D, RR, DR),
+	DA_INST		(0x1E, RR, ALR),
+	DA_INST		(0x1F, RR, SLR),
+	DA_INST		(0x20, RR, LPDR),
+	DA_INST		(0x21, RR, LNDR),
+	DA_INST		(0x22, RR, LTDR),
+	DA_INST		(0x23, RR, LCDR),
+	DA_INST		(0x24, RR, HDR),
+	DA_INST		(0x25, RR, LDXR),
+	DA_INST		(0x26, RR, MXR),
+	DA_INST		(0x27, RR, MXDR),
+	DA_INST		(0x28, RR, LDR),
+	DA_INST		(0x29, RR, CDR),
+	DA_INST		(0x2A, RR, ADR),
+	DA_INST		(0x2B, RR, SDR),
+	DA_INST		(0x2C, RR, MDR),
+	DA_INST		(0x2D, RR, DDR),
+	DA_INST		(0x2E, RR, AWR),
+	DA_INST		(0x2F, RR, SWR),
+	DA_INST		(0x30, RR, LPER),
+	DA_INST		(0x31, RR, LNER),
+	DA_INST		(0x32, RR, LTER),
+	DA_INST		(0x33, RR, LCER),
+	DA_INST		(0x34, RR, HER),
+	DA_INST		(0x35, RR, LEDR),
+	DA_INST		(0x36, RR, AXR),
+	DA_INST		(0x37, RR, SXR),
+	DA_INST		(0x38, RR, LER),
+	DA_INST		(0x39, RR, CER),
+	DA_INST		(0x3A, RR, AER),
+	DA_INST		(0x3B, RR, SER),
+	DA_INST		(0x3C, RR, MDER),
+	DA_INST		(0x3D, RR, DER),
+	DA_INST		(0x3E, RR, AUR),
+	DA_INST		(0x3F, RR, SUR),
+	DA_INST		(0x40, RX, STH),
+	DA_INST		(0x41, RX, LA),
+	DA_INST		(0x42, RX, STC),
+	DA_INST		(0x43, RX, IC),
+	DA_INST		(0x44, RX, EX),
+	DA_INST		(0x45, RX, BAL),
+	DA_INST		(0x46, RX, BCT),
+	DA_INST		(0x47, RX_MASK, BC),
+	DA_INST		(0x48, RX, LH),
+	DA_INST		(0x49, RX, CH),
+	DA_INST		(0x4A, RX, AH),
+	DA_INST		(0x4B, RX, SH),
+	DA_INST		(0x4C, RX, MH),
+	DA_INST		(0x4D, RX, BAS),
+	DA_INST		(0x4E, RX, CVD),
+	DA_INST		(0x4F, RX, CVB),
+	DA_INST		(0x50, RX, ST),
+	DA_INST		(0x51, RX, LAE),
+	DA_INST		(0x54, RX, N),
+	DA_INST		(0x55, RX, CL),
+	DA_INST		(0x56, RX, O),
+	DA_INST		(0x57, RX, X),
+	DA_INST		(0x58, RX, L),
+	DA_INST		(0x59, RX, C),
+	DA_INST		(0x5A, RX, A),
+	DA_INST		(0x5B, RX, S),
+	DA_INST		(0x5C, RX, M),
+	DA_INST		(0x5D, RX, D),
+	DA_INST		(0x5E, RX, AL),
+	DA_INST		(0x5F, RX, SL),
+	DA_INST		(0x60, RX, STD),
+	DA_INST		(0x67, RX, MXD),
+	DA_INST		(0x68, RX, LD),
+	DA_INST		(0x69, RX, CD),
+	DA_INST		(0x6A, RX, AD),
+	DA_INST		(0x6B, RX, SD),
+	DA_INST		(0x6C, RX, MD),
+	DA_INST		(0x6D, RX, DD),
+	DA_INST		(0x6E, RX, AW),
+	DA_INST		(0x6F, RX, SW),
+	DA_INST		(0x70, RX, STE),
+	DA_INST		(0x71, RX, MS),
+	DA_INST		(0x78, RX, LE),
+	DA_INST		(0x79, RX, CE),
+	DA_INST		(0x7A, RX, AE),
+	DA_INST		(0x7B, RX, SE),
+	DA_INST		(0x7C, RX, MDE),
+	DA_INST		(0x7D, RX, DE),
+	DA_INST		(0x7E, RX, AU),
+	DA_INST		(0x7F, RX, SU),
+	DA_INST		(0x80, S, SSM),
+	DA_INST		(0x82, S, LPSW),
+	DA_INST		(0x83, DIAG, DIAG),
+	DA_INST		(0x84, RSI, BRXH),
+	DA_INST		(0x85, RSI, BRXLE),
+	DA_INST		(0x86, RS1, BXH),
+	DA_INST		(0x87, RS1, BXLE),
+	DA_INST		(0x88, RS1, SRL),
+	DA_INST		(0x89, RS1, SLL),
+	DA_INST		(0x8A, RS1, SRA),
+	DA_INST		(0x8B, RS1, SLA),
+	DA_INST		(0x8C, RS1, SRDL),
+	DA_INST		(0x8D, RS1, SLDL),
+	DA_INST		(0x8E, RS1, SRDA),
+	DA_INST		(0x8F, RS1, SLDA),
+	DA_INST		(0x90, RS1, STM),
+	DA_INST		(0x91, SI, TM),
+	DA_INST		(0x92, SI, MVI),
+	DA_INST		(0x93, S, TS),
+	DA_INST		(0x94, SI, NI),
+	DA_INST		(0x95, SI, CLI),
+	DA_INST		(0x96, SI, OI),
+	DA_INST		(0x97, SI, XI),
+	DA_INST		(0x98, RS1, LM),
+	DA_INST		(0x99, RS1, TRACE),
+	DA_INST		(0x9A, RS1, LAM),
+	DA_INST		(0x9B, RS1, STAM),
+	DA_INST_TBL	(0xA5, l2_a5, 4, 12),
+	DA_INST_TBL	(0xA7, l2_a7, 4, 12),
+	DA_INST		(0xA8, RS1, MVCLE),
+	DA_INST		(0xA9, RS1, CLCLE),
+	DA_INST		(0xAC, SI, STNSM),
+	DA_INST		(0xAD, SI, STOSM),
+	DA_INST		(0xAE, RS1, SIGP),
+	DA_INST		(0xAF, SI, MC),
+	DA_INST		(0xB1, RX, LRA),
+	DA_INST_TBL	(0xB2, l2_b2, 8, 8),
+	DA_INST_TBL	(0xB3, l2_b3, 8, 8),
+	DA_INST		(0xB6, RS1, STCTL),
+	DA_INST		(0xB7, RS1, LCTL),
+	DA_INST_TBL	(0xB9, l2_b9, 8, 8),
+	DA_INST		(0xBA, RS1, CS),
+	DA_INST		(0xBB, RS1, CDS),
+	DA_INST		(0xBD, RS2, CLM),
+	DA_INST		(0xBE, RS2, STCM),
+	DA_INST		(0xBF, RS2, ICM),
+	DA_INST_TBL	(0xC0, l2_c0, 4, 12),
+	DA_INST_TBL	(0xC2, l2_c2, 4, 12),
+	DA_INST_TBL	(0xC4, l2_c4, 4, 12),
+	DA_INST_TBL	(0xC6, l2_c6, 4, 12),
+	DA_INST_TBL	(0xC8, l2_c8, 4, 12),
+	DA_INST		(0xD0, SS1, TRTR),
+	DA_INST		(0xD1, SS1, MVN),
+	DA_INST		(0xD2, SS1, MVC),
+	DA_INST		(0xD3, SS1, MVZ),
+	DA_INST		(0xD4, SS1, NC),
+	DA_INST		(0xD5, SS1, CLC),
+	DA_INST		(0xD6, SS1, OC),
+	DA_INST		(0xD7, SS1, XC),
+	DA_INST		(0xD9, SS4, MVCK),
+	DA_INST		(0xDA, SS4, MVCP),
+	DA_INST		(0xDB, SS4, MVCS),
+	DA_INST		(0xDC, SS1, TR),
+	DA_INST		(0xDD, SS1, TRT),
+	DA_INST		(0xDE, SS1, ED),
+	DA_INST		(0xDF, SS1, EDMK),
+	DA_INST		(0xE1, SS1, PKU),
+	DA_INST		(0xE2, SS1, UNPKU),
+	DA_INST_TBL	(0xE3, l2_e3, 8, 40),
+	DA_INST_TBL	(0xE5, l2_e5, 8, 8),
+	DA_INST		(0xE8, SS1, MVCIN),
+	DA_INST		(0xE9, SS1, PKA),
+	DA_INST		(0xEA, SS1, UNPKA),
+	DA_INST_TBL	(0xEB, l2_eb, 8, 40),
+	DA_INST_TBL	(0xEC, l2_ec, 8, 40),
+	DA_INST_TBL	(0xED, l2_ed, 8, 40),
+	DA_INST		(0xEE, SS5, PLO),
+	DA_INST		(0xEF, SS5, LMD),
+	DA_INST		(0xF0, SS3, SRP),
+	DA_INST		(0xF1, SS2, MVO),
+	DA_INST		(0xF2, SS2, PACK),
+	DA_INST		(0xF3, SS2, UNPK),
+	DA_INST		(0xF8, SS2, ZAP),
+	DA_INST		(0xF9, SS2, CP),
+	DA_INST		(0xFA, SS2, AP),
+	DA_INST		(0xFB, SS2, SP),
+	DA_INST		(0xFC, SS2, MP),
+	DA_INST		(0xFD, SS2, DP),
+};
+
+static int da_snprintf(u8 *bytes, char *buf, int buflen, u8 opcode, struct
+		       disassm_instruction *table)
+{
+#define IPFX "%-6s "
+
+	int ilc = opcode >> 6;
+	struct disassm_instruction *inst = &table[opcode];
+
+	switch (inst->fmt) {
+		case IF_INV:
+			snprintf(buf, buflen, "??");
+			break;
+		case IF_VAR:
+			{
+				unsigned char subop; /* sub op-code */
+
+				/* get the right byte */
+				subop = *(bytes+(inst->loc/8));
+
+				/* shift the needed portion right */
+				subop >>= 8 - inst->len - (inst->loc%8);
+
+				/* mask out any unneeded high bits */
+				subop &= (1 << inst->len) - 1;
+
+				snprintf(buf, buflen, "??? (many, X'%02X'+  "
+					 "X'%02X', table = %p)", opcode, subop,
+					 inst->u.ptr);
+				if (inst->u.ptr)
+					da_snprintf(bytes, buf, buflen, subop, inst->u.ptr);
+				break;
+			}
+		case IF_DIAG:
+			snprintf(buf, buflen, IPFX "X'%06X'",
+				 inst->u.name,
+				 *((u32*)(bytes)) & 0xffffff);		/* I  */
+			break;
+		case IF_E:
+			snprintf(buf, buflen, IPFX,
+				 inst->u.name);
+			break;
+		case IF_I:
+			snprintf(buf, buflen, IPFX "X'%02X'",
+				 inst->u.name,
+				 *(bytes+1));				/* I  */
+			break;
+		case IF_RI1:
+		case IF_RI2:
+			snprintf(buf, buflen, IPFX "%s%d,%d",
+				 inst->u.name,
+				 (inst->fmt == IF_RI1 ? "R" : ""),	/* reg/mask */
+				 bytes[1] >> 4,				/* R1/M1 */
+				 *((u16*)(bytes+2)));			/* I2 */
+			break;
+		case IF_RIL1:
+		case IF_RIL2:
+			snprintf(buf, buflen, IPFX "%s%d,%d",
+				 inst->u.name,
+				 (inst->fmt == IF_RIL1 ? "R" : ""),	/* reg/mask */
+				 bytes[1] >> 4,				/* R1/M1 */
+				 *((u32*)(bytes+2)));			/* I2 */
+			break;
+		case IF_RR:
+		case IF_RR_MASK:
+			snprintf(buf, buflen, IPFX "%s%d,R%d",
+				 inst->u.name,
+				 inst->fmt == IF_RR_MASK ? "" : "R",
+				 bytes[1] >> 4,				/* R1 */
+				 bytes[1] & 0xf);			/* R2 */
+			break;
+		case IF_RRE:
+			snprintf(buf, buflen, IPFX "R%d,R%d",
+				 inst->u.name,
+				 bytes[3] >> 4,				/* R1 */
+				 bytes[3] & 0xf);			/* R2 */
+			break;
+		case IF_RS1:
+		case IF_RS2:
+			snprintf(buf, buflen, IPFX "R%d,%s%d,%d(R%d)",
+				 inst->u.name,
+				 bytes[1] >> 4,				/* R1 */
+				 (inst->fmt == IF_RS1 ? "R" : ""),	/* reg/mask */
+				 bytes[1] & 0xf,			/* R3/M3 */
+				 *((u16*)(bytes+2)) & 0x0fff,		/* D2 */
+				 bytes[2] >> 4);			/* B2 */
+			break;
+		case IF_RSI:
+			snprintf(buf, buflen, IPFX "R%d,R%d,%d",
+				 inst->u.name,
+				 bytes[1] >> 4,				/* R1 */
+				 bytes[1] & 0xf,			/* R3 */
+				 *((u16*)(bytes+2)));			/* I2 */
+			break;
+		case IF_RSY1:
+		case IF_RSY2:
+			snprintf(buf, buflen, IPFX "R%d,%s%d,%d(R%d)",
+				 inst->u.name,
+				 bytes[1] >> 4,				/* R1 */
+				 (inst->fmt == IF_RSY1 ? "R" : ""),	/* reg/mask */
+				 bytes[1] & 0xf,			/* R3/M3 */
+				 ((u32)*((u16*)(bytes+2)) & 0x0fff) +
+				 (((u32)*(bytes+4)) << 12),		/* D2 */
+				 bytes[2] >> 4);			/* B2 */
+			break;
+		case IF_RX:
+		case IF_RX_MASK:
+			snprintf(buf, buflen, IPFX "%s%d,%d(R%d,R%d)",
+				 inst->u.name,
+				 inst->fmt == IF_RX_MASK ? "" : "R",
+				 bytes[1] >> 4,				/* R1 */
+				 *((u16*)(bytes+2)) & 0x0fff,		/* D2 */
+				 bytes[1] & 0xf,			/* X2 */
+				 bytes[2] >> 4);			/* B2 */
+			break;
+		case IF_RXY:
+			snprintf(buf, buflen, IPFX "R%d,%d(R%d,R%d)",
+				 inst->u.name,
+				 bytes[1] >> 4,				/* R1 */
+				 ((u32)*((u16*)(bytes+2)) & 0x0fff) +
+				 (((u32)*(bytes+4)) << 12),		/* D2 */
+				 bytes[1] & 0xf,			/* X2 */
+				 bytes[2] >> 4);			/* B2 */
+			break;
+		case IF_S:
+			snprintf(buf, buflen, IPFX "%d(R%d)",
+				 inst->u.name,
+				 *((u16*)(bytes+2)) & 0x0fff,		/* D2 */
+				 bytes[2] >> 4);			/* B2 */
+			break;
+		case IF_SI:
+			snprintf(buf, buflen, IPFX "%d(R%d),%d",
+				 inst->u.name,
+				 *((u16*)(bytes+2)) & 0x0fff,		/* D1 */
+				 bytes[2] >> 4,				/* B1 */
+				 bytes[1]);				/* I2 */
+			break;
+		case IF_SS1:
+			snprintf(buf, buflen, IPFX "%d(%d,R%d),%d(R%d)",
+				 inst->u.name,
+				 *((u16*)(bytes+2)) & 0x0fff,		/* D1 */
+				 bytes[1]+1,				/* L  */
+				 bytes[2] >> 4,				/* B1 */
+				 *((u16*)(bytes+4)) & 0x0fff,		/* D2 */
+				 bytes[4] >> 4);			/* B2 */
+			break;
+		case IF_SS2:
+			snprintf(buf, buflen, IPFX "%d(%d,R%d),%d(%d,R%d)",
+				 inst->u.name,
+				 *((u16*)(bytes+2)) & 0x0fff,		/* D1 */
+				 (bytes[1] >> 4) + 1,			/* L1 */
+				 bytes[2] >> 4,				/* B1 */
+				 *((u16*)(bytes+4)) & 0x0fff,		/* D2 */
+				 (bytes[1] & 0xf) + 1,			/* L2 */
+				 bytes[4] >> 4);			/* B2 */
+			break;
+		case IF_SS3:
+			snprintf(buf, buflen, IPFX "%d(%d,R%d),%d(R%d),%d",
+				 inst->u.name,
+				 *((u16*)(bytes+2)) & 0x0fff,		/* D1 */
+				 (bytes[1] >> 4) + 1,			/* L1 */
+				 bytes[2] >> 4,				/* B1 */
+				 *((u16*)(bytes+4)) & 0x0fff,		/* D2 */
+				 bytes[4] >> 4,				/* B2 */
+				 bytes[1] & 0xf);			/* I3 */
+			break;
+		case IF_SS4:
+			snprintf(buf, buflen, IPFX "%d(%d,R%d),%d(R%d),R%d",
+				 inst->u.name,
+				 *((u16*)(bytes+2)) & 0x0fff,		/* D1 */
+				 (bytes[1] >> 4) + 1,			/* L1 */
+				 bytes[2] >> 4,				/* B1 */
+				 *((u16*)(bytes+4)) & 0x0fff,		/* D2 */
+				 bytes[4] >> 4,				/* B2 */
+				 bytes[1] & 0xf);			/* R3 */
+			break;
+		case IF_SS5:
+			snprintf(buf, buflen, IPFX "R%d,R%d,%d(R%d),%d(R%d)",
+				 inst->u.name,
+				 bytes[1] >> 4,				/* R1 */
+				 bytes[1] & 0xf,			/* R3 */
+				 *((u16*)(bytes+2)) & 0x0fff,		/* D2 */
+				 bytes[2] >> 4,				/* B2 */
+				 *((u16*)(bytes+4)) & 0x0fff,		/* D4 */
+				 bytes[4] >> 4);			/* B4 */
+			break;
+		default:
+			snprintf(buf, buflen, "%s ???", inst->u.name);
+			break;
+	}
+
+	/* return instruction length in bytes */
+	return 2 * (ilc >= 2 ? ilc : ilc + 1);
+}
+
+int disassm(u8 *bytes, char *buf, int buflen)
+{
+	return da_snprintf(bytes, buf, buflen, *bytes, l1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/exception.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,16 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <sched.h>
+#include <vcpu.h>
+
+void queue_prog_exception(struct virt_sys *sys, enum PROG_EXCEPTION type, u64 param)
+{
+	con_printf(sys->con, "FIXME: supposed to inject a %d program exception\n", type);
+	sys->task->cpu->state = GUEST_STOPPED;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/guest.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,65 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <directory.h>
+#include <sched.h>
+#include <dat.h>
+#include <shell.h>
+
+/*
+ * FIXME:
+ * - issue any pending interruptions
+ */
+void run_guest(struct virt_sys *sys)
+{
+	u64 save_gpr[16];
+
+	/*
+	 * FIXME: need to ->icptcode = 0;
+	 */
+
+	/*
+	 * FIXME: load FPRs & FPCR
+	 */
+
+	/*
+	 * IMPORTANT: We MUST keep a valid stack address in R15. This way,
+	 * if SIE gets interrupted via an interrupt in the host, the
+	 * scheduler can still get to the struct task pointer on the stack
+	 */
+	asm volatile(
+		/* save current regs */
+		"	stmg	0,15,%0\n"
+		/* load the address of the guest state save area */
+		"	lr	14,%1\n"
+		/* load the address of the reg save area */
+		"	la	15,%0\n"
+		/* load guest's R0-R13 */
+		"	lmg	0,13,%2(14)\n"
+		/* SIE */
+		"	sie	%3(14)\n"
+		/* save guest's R0-R13 */
+		"	stmg	0,13,%2(14)\n"
+		/* restore all regs */
+		"	lmg	0,15,0(15)\n"
+
+	: /* output */
+	  "+m" (save_gpr)
+	: /* input */
+	  "a" (sys->task->cpu),
+	  "J" (offsetof(struct virt_cpu, regs.gpr)),
+	  "J" (offsetof(struct virt_cpu, sie_cb))
+	: /* clobbered */
+	  "memory"
+	);
+
+	/*
+	 * FIXME: store FPRs & FPCR
+	 */
+
+	handle_interception(sys);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/guest_ipl.S	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,121 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+	#
+	# We are guaranteed the following:
+	#
+	# 1) we are located above 16M
+	# 2) we are located below 2G
+	# 3) we are running in ESA/390
+	# 4) we are in 31-bit addressing mode
+	# 5) the guest registers are saved at GUEST_IPL_REGSAVE
+	# 6) R1 contains the subchannel #
+	# 7) R2 contains the device #
+	# 8) R12 contains the base address
+	#
+	# Register usage:
+	#
+	#   R1  = subchannel number
+	#   R2  = device number
+	#   R3  = temp
+	#   R12 = base for this code
+	#
+
+	# Nice register names
+.equ	r0,0
+.equ	r1,1
+.equ	r2,2
+.equ	r3,3
+.equ	r12,12
+.equ	r15,15
+
+	# new IO interruption PSW address
+.equ	PSANEWIO,120
+
+###############################################################################
+# Code begins here                                                            #
+###############################################################################
+
+.globl GUEST_IPL_CODE
+	.type	GUEST_IPL_CODE, @function
+GUEST_IPL_CODE:
+	STSCH	SCHIB(r12)			# get the SCHIB
+	BNZ	ERROR(r12)
+
+	OI	SCHIB+5(r12),0x80		# enable the subchannel
+
+	MSCH	SCHIB(r12)			# load up the SCHIB
+	BNZ	ERROR(r12)
+
+	# got a functioning subchannel, let's set up the new IO psw
+
+	MVC	PSANEWIO(8,r0),IOPSW(r12)
+
+	L	r3,PSANEWIO+4(r0,r0)
+	LA	r3,IO(r3,r12)			# calculate the address of
+	ST	r3,PSANEWIO+4(r0,r0)		# the IO handler
+
+	# let's set up a CCW + an ORB, start the IO, and wait
+
+	MVC	0(8,r0),INITCCW(r12)		# set up the initial CCW
+	OI	ORB+6(r12),0xff			# set the LPM in the ORB
+
+	SSCH	ORB(r12)			# start the IO
+	BNZ	ERROR(r12)
+
+	LPSW	ENABLEDWAIT(r12)		# wait for IO interruptions
+
+.equ	IO,(.-GUEST_IPL_CODE)
+	# this is the IO interrupt handler
+
+	B	DONE(r12)
+
+.equ	ERROR,(.-GUEST_IPL_CODE)
+	# an error occured, return an error
+
+	LM	r0,r15,REGSAVE(r12)
+	DIAG	r0,r0,1				# return to hypervisor
+
+.equ	DONE,(.-GUEST_IPL_CODE)
+	# we were successful!
+
+	LM	r0,r15,REGSAVE(r12)
+	DIAG	r0,r0,0				# return to hypervisor
+
+###############################################################################
+# Data begins here                                                            #
+###############################################################################
+
+.equ	DISABLEDWAIT,(.-GUEST_IPL_CODE)
+	.long	0x000c0000
+	.long	0x80000000			# disabled wait PSW; signal
+						# return to hypervisor
+.equ	ENABLEDWAIT,(.-GUEST_IPL_CODE)
+	.long	0x020c0000
+	.long	0x80000000			# enabled wait PSW; wait for IO
+
+.equ	IOPSW,(.-GUEST_IPL_CODE)
+	.long	0x00080000
+	.long	0x80000000			# new IO psw
+
+.equ	INITCCW,(.-GUEST_IPL_CODE)
+	.long	0x02000000
+	.long	0x60000018			# fmt0, read 24 bytes to addr 0
+
+	.align 4
+.equ	ORB,(.-GUEST_IPL_CODE)
+	.skip	(8*4),0				# the ORB is BIG
+
+	.align 4
+.equ	SCHIB,(.-GUEST_IPL_CODE)
+	.skip	(13*4),0			# the SCHIB is BIG
+
+	.align 4
+.globl GUEST_IPL_REGSAVE
+	.type	GUEST_IPL_REGSAVE, @function
+GUEST_IPL_REGSAVE:
+.equ	REGSAVE,(.-GUEST_IPL_CODE)		# register save area
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/init.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,327 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <directory.h>
+#include <sched.h>
+#include <errno.h>
+#include <page.h>
+#include <buddy.h>
+#include <slab.h>
+#include <dat.h>
+#include <clock.h>
+#include <ebcdic.h>
+#include <vdevice.h>
+#include <cpu.h>
+#include <mutex.h>
+#include <vsprintf.h>
+#include <shell.h>
+
+/* This is used to con_printf to the operator about various async events -
+ * e.g., user logon
+ */
+struct console *oper_con;
+
+static LIST_HEAD(online_users);
+static UNLOCKED_MUTEX(online_users_lock);
+
+static int __alloc_guest_devices(struct virt_sys *sys)
+{
+	int i;
+
+	INIT_LIST_HEAD(&sys->virt_devs);
+
+	for(i=0; sys->directory->devices[i].type != VDEV_INVAL; i++) {
+		if (alloc_virt_dev(sys, &sys->directory->devices[i],
+				   0x10000 + i))
+			con_printf(sys->con, "Failed to allocate vdev %04X, SCH = %05X\n",
+				   sys->directory->devices[i].vdev,
+				   0x10000 + i);
+	}
+
+	return 0;
+}
+
+static int __alloc_guest_storage(struct virt_sys *sys)
+{
+	u64 pages = sys->directory->storage_size >> PAGE_SHIFT;
+	struct page *p;
+
+	INIT_LIST_HEAD(&sys->guest_pages);
+
+	while (pages) {
+		p = alloc_pages(0, ZONE_NORMAL);
+		if (!p)
+			continue; /* FIXME: sleep? */
+
+		list_add(&p->guest, &sys->guest_pages);
+
+		pages--;
+
+		dat_insert_page(&sys->as, (u64) page_to_addr(p),
+				pages << PAGE_SHIFT);
+	}
+
+	return 0;
+}
+
+static void process_logon_cmd(struct console *con)
+{
+	u8 cmd[128];
+	int ret;
+
+	ret = con_read(con, cmd, 128);
+
+	if (ret == -1)
+		return; /* no lines to read */
+
+	if (!ret)
+		return; /* empty line */
+
+	ebcdic2ascii(cmd, ret);
+
+	/*
+	 * we got a command to process!
+	 */
+
+	ret = invoke_shell_logon(con, (char*) cmd, ret);
+	if (!ret)
+		return;
+
+	con_printf(con, "NOT LOGGED ON\n");
+}
+
+static void process_cmd(struct virt_sys *sys)
+{
+	u8 cmd[128];
+	int ret;
+
+	ret = con_read(sys->con, cmd, 128);
+
+	if (ret == -1)
+		return; /* no lines to read */
+
+	if (!ret) {
+		con_printf(sys->con, "CP\n");
+		return; /* empty line */
+	}
+
+	ebcdic2ascii(cmd, ret);
+
+	/*
+	 * we got a command to process!
+	 */
+	ret = invoke_shell_cmd(sys, (char*) cmd, ret);
+	switch (ret) {
+		case 0:
+			/* all fine */
+			break;
+		case -ENOENT:
+			con_printf(sys->con, "Invalid CP command: %s\n", cmd);
+			break;
+		case -ESUBENOENT:
+			con_printf(sys->con, "Invalid CP sub-command: %s\n", cmd);
+			break;
+		case -EINVAL:
+			con_printf(sys->con, "Operand missing or invalid\n");
+			break;
+		case -EPERM:
+			con_printf(sys->con, "Not authorized\n");
+			break;
+		default:
+			con_printf(sys->con, "RC=%d\n", ret);
+			break;
+	}
+}
+
+static int shell_init(void *data)
+{
+	struct virt_sys *sys = data;
+	struct virt_cpu *cpu;
+	struct datetime dt;
+	struct page *page;
+
+	page = alloc_pages(0, ZONE_NORMAL);
+	BUG_ON(!page);
+
+	cpu = page_to_addr(page);
+	sys->task->cpu = cpu;
+
+	memset(cpu, 0, PAGE_SIZE);
+
+	__alloc_guest_storage(sys);
+	__alloc_guest_devices(sys);
+
+	/*
+	 * load guest's address space into the host's PASCE
+	 */
+	load_as(&sys->as);
+
+	cpu->cpuid = getcpuid() | 0xFF00000000000000ULL;
+
+	memset(&cpu->sie_cb, 0, sizeof(struct sie_cb));
+	cpu->sie_cb.gmsor = 0;
+	cpu->sie_cb.gmslm = sys->directory->storage_size;
+	cpu->sie_cb.gbea = 1;
+	cpu->sie_cb.ecb  = 2;
+	cpu->sie_cb.eca  = 0xC1002001U;
+	/*
+	 * TODO: What about ->scaoh and ->scaol?
+	 */
+
+	guest_power_on_reset(sys);
+
+	get_parsed_tod(&dt);
+	con_printf(sys->con, "LOGON FOR %s AT %02d:%02d:%02d UTC %04d-%02d-%02d\n",
+		   sys->directory->userid, dt.th, dt.tm, dt.ts, dt.dy, dt.dm, dt.dd);
+
+	for (;;) {
+		/*
+		 *   - process any console input
+		 *   - if the guest is running
+		 *     - issue any pending interruptions
+		 *     - continue executing it
+		 *     - process any intercepts from SIE
+		 *   - else, schedule()
+		 */
+
+		process_cmd(sys);
+
+		if (cpu->state == GUEST_OPERATING)
+			run_guest(sys);
+		else
+			schedule();
+	}
+
+	return 0;
+}
+
+static void __con_attn(struct console *con)
+{
+	if (con->sys) {
+		/* There's already a user on this console */
+
+		if (!con->sys->task->cpu ||
+		    con->sys->task->cpu->state == GUEST_STOPPED)
+			return;
+
+		if (!con_read_pending(con))
+			return;
+
+		/*
+		 * There's a read pending. Generate an interception.
+		 */
+		atomic_set_mask(CPUSTAT_STOP_INT, &con->sys->task->cpu->sie_cb.cpuflags);
+	} else {
+		if (!con_read_pending(con))
+			return;
+
+		/*
+		 * There's a read pending. MUST be a command
+		 */
+		process_logon_cmd(con);
+	}
+}
+
+static int shell_con_attn(void *data)
+{
+	for(;;) {
+		schedule();
+
+		for_each_console(__con_attn);
+	}
+
+	return 0;
+}
+
+void spawn_oper_shell(struct console *con)
+{
+	struct virt_sys *sys;
+
+	oper_con = con;
+
+	sys = malloc(sizeof(struct virt_sys), ZONE_NORMAL);
+	BUG_ON(!sys);
+
+	sys->con = con;
+	con->sys = sys;
+
+	sys->directory = find_user_by_id("operator");
+	BUG_ON(IS_ERR(sys->directory));
+
+	sys->print_ts = 1; /* print timestamps */
+
+	sys->task = create_task("OPERATOR-vcpu0", shell_init, sys);
+	BUG_ON(IS_ERR(sys->task));
+
+	BUG_ON(IS_ERR(create_task("console-attn", shell_con_attn, NULL)));
+
+	mutex_lock(&online_users_lock);
+	list_add_tail(&sys->online_users, &online_users);
+	mutex_unlock(&online_users_lock);
+}
+
+void spawn_user_shell(struct console *con, struct user *u)
+{
+	char tname[TASK_NAME_LEN+1];
+	struct virt_sys *sys;
+	int already_online = 0;
+
+	mutex_lock(&online_users_lock);
+	list_for_each_entry(sys, &online_users, online_users) {
+		if (sys->directory == u) {
+			already_online = 1;
+			break;
+		}
+	}
+	mutex_unlock(&online_users_lock);
+
+	if (already_online) {
+		con_printf(con, "ALREADY LOGGED ON\n");
+		return;
+	}
+
+	sys = malloc(sizeof(struct virt_sys), ZONE_NORMAL);
+	if (!sys)
+		goto err;
+
+	sys->con = con;
+	con->sys = sys;
+
+	sys->directory = u;
+
+	sys->print_ts = 1; /* print timestamps */
+
+	snprintf(tname, TASK_NAME_LEN, "%s-vcpu0", u->userid);
+	sys->task = create_task(tname, shell_init, sys);
+	if (IS_ERR(sys->task))
+		goto err_free;
+
+	mutex_lock(&online_users_lock);
+	list_add_tail(&sys->online_users, &online_users);
+	mutex_unlock(&online_users_lock);
+	return;
+
+err_free:
+	free(sys);
+	con->sys = NULL;
+err:
+	con_printf(con, "INTERNAL ERROR DURING LOGON\n");
+}
+
+void list_users(struct console *con, void (*f)(struct console *con,
+					       struct virt_sys *sys))
+{
+	struct virt_sys *sys;
+
+	if (!f)
+		return;
+
+	mutex_lock(&online_users_lock);
+	list_for_each_entry(sys, &online_users, online_users)
+		f(con, sys);
+	mutex_unlock(&online_users_lock);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/instruction.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,30 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <sched.h>
+#include <shell.h>
+
+static const intercept_handler_t instruction_funcs[256] = {
+	[0xb2] = handle_instruction_priv,	/* assorted priv. insts */
+};
+
+int handle_instruction(struct virt_sys *sys)
+{
+	struct virt_cpu *cpu = sys->task->cpu;
+	intercept_handler_t h;
+	int err = -EINVAL;
+
+	con_printf(sys->con, "INTRCPT: INST (%04x %08x)\n",
+		   cpu->sie_cb.ipa,
+		   cpu->sie_cb.ipb);
+
+	h = instruction_funcs[cpu->sie_cb.ipa >> 8];
+	if (h)
+		err = h(sys);
+
+	return err;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/instruction_priv.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,224 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <list.h>
+#include <sched.h>
+#include <vdevice.h>
+#include <vcpu.h>
+#include <shell.h>
+
+static int handle_msch(struct virt_sys *sys)
+{
+	struct virt_cpu *cpu = sys->task->cpu;
+
+	u64 r1 = __guest_gpr(cpu, 1);
+	u64 addr = RAW_S_1(cpu);
+
+	struct schib *gschib;
+	struct virt_device *vdev, *vdev_cur;
+	int ret = 0;
+
+	if ((PAGE_SIZE-(addr & PAGE_MASK)) < sizeof(struct schib)) {
+		con_printf(sys->con, "The SCHIB crosses page boundary (%016llx; %lu)! CPU stopped\n",
+			   addr, sizeof(struct schib));
+		cpu->state = GUEST_STOPPED;
+		goto out;
+	}
+
+	/* sch number must be: X'0001____' */
+	if ((r1 & 0xffff0000) != 0x00010000) {
+		queue_prog_exception(sys, PROG_OPERAND, r1);
+		goto out;
+	}
+
+	/* schib must be word-aligned */
+	if (addr & 0x3) {
+		queue_prog_exception(sys, PROG_SPEC, addr);
+		goto out;
+	}
+
+	/* find the virtual device */
+	vdev = NULL;
+	list_for_each_entry(vdev_cur, &sys->virt_devs, devices) {
+		if (vdev_cur->sch == (u32) r1) {
+			vdev = vdev_cur;
+			break;
+		}
+	}
+
+	/* There's no virtual device with this sch number; CC=3 */
+	if (!vdev) {
+		cpu->sie_cb.gpsw.cc = 3;
+		goto out;
+	}
+
+	/* translate guest address to host address */
+	ret = virt2phy_current(addr, &addr);
+	if (ret) {
+		if (ret != -EFAULT)
+			goto out;
+
+		ret = 0;
+		queue_prog_exception(sys, PROG_ADDR, addr);
+		goto out;
+	}
+
+	gschib = (struct schib*) addr;
+
+	/*
+	 * Condition code 1 is set, and no other action is taken, when the
+	 *   subchannel is status pending. (See “Status Control (SC)” on
+	 *   page 16-16.)
+	 */
+	if (vdev->scsw.sc & SC_STATUS) {
+		cpu->sie_cb.gpsw.cc = 1;
+		goto out;
+	}
+
+	/*
+	 * Condition code 2 is set, and no other action is taken, when a
+	 *   clear, halt, or start function is in progress at the
+	 *   subchannel.  (See “Function Control (FC)” on page 16-12.)
+	 */
+	if (vdev->scsw.fc & (FC_START | FC_HALT | FC_CLEAR)) {
+		cpu->sie_cb.gpsw.cc = 2;
+		goto out;
+	}
+
+	/*
+	 * The channel-subsystem operations that may be influenced due to
+	 * placement of SCHIB information in the subchannel are:
+	 *
+	 * • I/O processing (E field)
+	 * • Interruption processing (interruption parameter and ISC field)
+	 * • Path management (D, LPM, and POM fields)
+	 * • Monitoring and address-limit checking (measurement-block index,
+	 *   LM, and MM fields)
+	 * • Measurement-block-format control (F field)
+	 * • Extended-measurement-word-mode enable (X field)
+	 * • Concurrent-sense facility (S field)
+	 * • Measurement-block address (MBA)
+	*/
+
+	if (!gschib->pmcw.v)
+		goto out_cc0;
+
+	vdev->pmcw.interrupt_param = gschib->pmcw.interrupt_param;
+	vdev->pmcw.e   = gschib->pmcw.e;
+	vdev->pmcw.isc = gschib->pmcw.isc;
+	vdev->pmcw.d   = gschib->pmcw.d;
+	vdev->pmcw.lpm = gschib->pmcw.lpm;
+	vdev->pmcw.pom = gschib->pmcw.pom;
+	vdev->pmcw.lm  = gschib->pmcw.lm;
+	vdev->pmcw.mm  = gschib->pmcw.mm;
+	vdev->pmcw.f   = gschib->pmcw.f;
+	vdev->pmcw.x   = gschib->pmcw.x;
+	vdev->pmcw.s   = gschib->pmcw.s;
+	vdev->pmcw.mbi = gschib->pmcw.mbi;
+	/* FIXME: save measurement-block address */
+
+out_cc0:
+	cpu->sie_cb.gpsw.cc = 0;
+
+out:
+	return ret;
+}
+
+static int handle_ssch(struct virt_sys *sys)
+{
+	con_printf(sys->con, "SSCH handler\n");
+	return -ENOMEM;
+}
+
+static int handle_stsch(struct virt_sys *sys)
+{
+	struct virt_cpu *cpu = sys->task->cpu;
+
+	u64 r1   = __guest_gpr(cpu, 1);
+	u64 addr = RAW_S_1(cpu);
+
+	struct schib *gschib;
+	struct virt_device *vdev, *vdev_cur;
+	int ret = 0;
+
+	if ((PAGE_SIZE-(addr & PAGE_MASK)) < sizeof(struct schib)) {
+		con_printf(sys->con, "The SCHIB crosses page boundary (%016llx; %lu)! CPU stopped\n",
+			   addr, sizeof(struct schib));
+		cpu->state = GUEST_STOPPED;
+		goto out;
+	}
+
+	/* sch number must be: X'0001____' */
+	if ((r1 & 0xffff0000) != 0x00010000) {
+		queue_prog_exception(sys, PROG_OPERAND, r1);
+		goto out;
+	}
+
+	/* schib must be word-aligned */
+	if (addr & 0x3) {
+		queue_prog_exception(sys, PROG_SPEC, addr);
+		goto out;
+	}
+
+	/* find the virtual device */
+	vdev = NULL;
+	list_for_each_entry(vdev_cur, &sys->virt_devs, devices) {
+		if (vdev_cur->sch == (u32) r1) {
+			vdev = vdev_cur;
+			break;
+		}
+	}
+
+	/* There's no virtual device with this sch number; CC=3 */
+	if (!vdev) {
+		cpu->sie_cb.gpsw.cc = 3;
+		goto out;
+	}
+
+	/* translate guest address to host address */
+	ret = virt2phy_current(addr, &addr);
+	if (ret) {
+		if (ret == -EFAULT) {
+			ret = 0;
+			queue_prog_exception(sys, PROG_ADDR, addr);
+		}
+
+		goto out;
+	}
+
+	gschib = (struct schib*) addr;
+
+	/* copy! */
+	memcpy(&gschib->pmcw, &vdev->pmcw, sizeof(struct pmcw));
+	memcpy(&gschib->scsw, &vdev->scsw, sizeof(struct scsw));
+
+	/* CC: 0 */
+	cpu->sie_cb.gpsw.cc = 0;
+
+out:
+	return ret;
+}
+
+static const intercept_handler_t instruction_priv_funcs[256] = {
+	[0x32] = handle_msch,
+	[0x33] = handle_ssch,
+	[0x34] = handle_stsch,
+};
+
+int handle_instruction_priv(struct virt_sys *sys)
+{
+	struct virt_cpu *cpu = sys->task->cpu;
+	intercept_handler_t h;
+	int err = -EINVAL;
+
+	h = instruction_priv_funcs[cpu->sie_cb.ipa & 0xff];
+	if (h)
+		err = h(sys);
+
+	return err;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/intercept.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,125 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <directory.h>
+#include <sched.h>
+#include <dat.h>
+#include <shell.h>
+
+static int handle_noop(struct virt_sys *sys)
+{
+	return 0;
+}
+
+static int handle_program(struct virt_sys *sys)
+{
+	con_printf(sys->con, "INTRCPT: PROG\n");
+	sys->task->cpu->state = GUEST_STOPPED;
+	return 0;
+}
+
+static int handle_instruction_and_program(struct virt_sys *sys)
+{
+	con_printf(sys->con, "INTRCPT: INST+PROG\n");
+	sys->task->cpu->state = GUEST_STOPPED;
+	return 0;
+}
+
+static int handle_ext_req(struct virt_sys *sys)
+{
+	con_printf(sys->con, "INTRCPT: EXT REQ\n");
+	sys->task->cpu->state = GUEST_STOPPED;
+	return 0;
+}
+
+static int handle_ext_int(struct virt_sys *sys)
+{
+	con_printf(sys->con, "INTRCPT: EXT INT\n");
+	sys->task->cpu->state = GUEST_STOPPED;
+	return 0;
+}
+
+static int handle_io_req(struct virt_sys *sys)
+{
+	con_printf(sys->con, "INTRCPT: IO REQ\n");
+	sys->task->cpu->state = GUEST_STOPPED;
+	return 0;
+}
+
+static int handle_wait(struct virt_sys *sys)
+{
+	con_printf(sys->con, "INTRCPT: WAIT\n");
+	sys->task->cpu->state = GUEST_STOPPED;
+	return 0;
+}
+
+static int handle_validity(struct virt_sys *sys)
+{
+	con_printf(sys->con, "INTRCPT: VALIDITY\n");
+	sys->task->cpu->state = GUEST_STOPPED;
+	return 0;
+}
+
+static int handle_stop(struct virt_sys *sys)
+{
+	atomic_clear_mask(CPUSTAT_STOP_INT, &sys->task->cpu->sie_cb.cpuflags);
+	return 0;
+}
+
+static int handle_oper_except(struct virt_sys *sys)
+{
+	con_printf(sys->con, "INTRCPT: OPER EXCEPT\n");
+	sys->task->cpu->state = GUEST_STOPPED;
+	return 0;
+}
+
+static int handle_exp_run(struct virt_sys *sys)
+{
+	con_printf(sys->con, "INTRCPT: EXP RUN\n");
+	sys->task->cpu->state = GUEST_STOPPED;
+	return 0;
+}
+
+static int handle_exp_timer(struct virt_sys *sys)
+{
+	con_printf(sys->con, "INTRCPT: EXP TIMER\n");
+	sys->task->cpu->state = GUEST_STOPPED;
+	return 0;
+}
+
+static const intercept_handler_t intercept_funcs[0x4c >> 2] = {
+	[0x00 >> 2] = handle_noop,
+	[0x04 >> 2] = handle_instruction,
+	[0x08 >> 2] = handle_program,
+	[0x0c >> 2] = handle_instruction_and_program,
+	[0x10 >> 2] = handle_ext_req,
+	[0x14 >> 2] = handle_ext_int,
+	[0x18 >> 2] = handle_io_req,
+	[0x1c >> 2] = handle_wait,
+	[0x20 >> 2] = handle_validity,
+	[0x28 >> 2] = handle_stop,
+	[0x2c >> 2] = handle_oper_except,
+	[0x44 >> 2] = handle_exp_run,
+	[0x48 >> 2] = handle_exp_timer,
+};
+
+void handle_interception(struct virt_sys *sys)
+{
+	struct virt_cpu *cpu = sys->task->cpu;
+	intercept_handler_t h;
+	int err = -EINVAL;
+
+	h = intercept_funcs[cpu->sie_cb.icptcode >> 2];
+	if (h)
+		err = h(sys);
+
+	if (err) {
+		cpu->state = GUEST_STOPPED;
+		con_printf(sys->con, "Unknown/mis-handled intercept code %02x, err = %d\n",
+			   cpu->sie_cb.icptcode, err);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/reset.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,225 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <directory.h>
+#include <sched.h>
+#include <dat.h>
+#include <shell.h>
+
+#define RESET_CPU			0x000001
+#define SET_ESA390			0x000002
+#define RESET_PSW			0x000004
+#define RESET_PREFIX			0x000008
+#define RESET_CPU_TIMER			0x000010
+#define RESET_CLK_COMP			0x000020
+#define RESET_TOD_PROG_REG		0x000040
+#define RESET_CR			0x000080
+#define RESET_BREAK_EV_ADDR		0x000100
+#define RESET_FPCR			0x000200
+#define RESET_AR			0x000400
+#define RESET_GPR			0x000800
+#define RESET_FPR			0x001000
+#define RESET_STORAGE_KEYS		0x002000
+#define RESET_STORAGE			0x004000
+#define RESET_NONVOL_STORAGE		0x008000
+#define RESET_EXPANDED_STORAGE		0x010000
+#define RESET_TOD			0x020000
+#define RESET_TOD_STEER			0x040000
+#define RESET_FLOATING_INTERRUPTIONS	0x080000
+#define RESET_IO			0x100000
+#define RESET_PLO_LOCKS			0x200000
+#define __RESET_PLO_LOCKS_PRESERVE	0x400000
+#define RESET_PLO_LOCKS_PRESERVE	(RESET_PLO_LOCKS | \
+					 __RESET_PLO_LOCKS_PRESERVE)
+
+/*
+ * These define all the different ways of reseting the system...to save us
+ * typing later on :)
+ */
+#define SUBSYSTEM_RESET_FLAGS	(RESET_FLOATING_INTERRUPTIONS | RESET_IO)
+#define CPU_RESET_FLAGS		(RESET_CPU)
+#define INIT_CPU_RESET_FLAGS	(RESET_CPU | SET_ESA390 | RESET_PSW | \
+				 RESET_PREFIX | RESET_CPU_TIMER | \
+				 RESET_CLK_COMP | RESET_TOD_PROG_REG | \
+				 RESET_CR | RESET_BREAK_EV_ADDR | \
+				 RESET_FPCR)
+#define CLEAR_RESET_FLAGS	(RESET_CPU | SET_ESA390 | RESET_PSW | \
+				 RESET_PREFIX | RESET_CPU_TIMER | \
+				 RESET_CLK_COMP | RESET_TOD_PROG_REG | \
+				 RESET_CR | RESET_BREAK_EV_ADDR | RESET_FPCR | \
+				 RESET_AR | RESET_GPR | RESET_FPR | \
+				 RESET_STORAGE_KEYS | RESET_STORAGE | \
+				 RESET_NONVOL_STORAGE | RESET_PLO_LOCKS | \
+				 RESET_FLOATING_INTERRUPTIONS | RESET_IO)
+#define POWER_ON_RESET_FLAGS	(RESET_CPU | SET_ESA390 | RESET_PSW | \
+				 RESET_PREFIX | RESET_CPU_TIMER | \
+				 RESET_CLK_COMP | RESET_TOD_PROG_REG | \
+				 RESET_CR | RESET_BREAK_EV_ADDR | RESET_FPCR | \
+				 RESET_AR | RESET_GPR | RESET_FPR | \
+				 RESET_STORAGE_KEYS | RESET_STORAGE | \
+				 RESET_EXPANDED_STORAGE | RESET_TOD | \
+				 RESET_TOD_STEER | RESET_PLO_LOCKS_PRESERVE | \
+				 RESET_FLOATING_INTERRUPTIONS | RESET_IO)
+
+/*
+ * Reset TODO:
+ *  - handle Captured-z/Architecture-PSW register
+ */
+static void __perform_cpu_reset(struct virt_sys *sys, int flags)
+{
+	struct virt_cpu *cpu = sys->task->cpu;
+
+	if (flags & RESET_CPU) {
+		if (flags & SET_ESA390) {
+			/* FIXME: set the arch mode to ESA/390 */
+		}
+
+		/*
+		 * FIXME: clear interruptions:
+		 *  - PROG
+		 *  - SVC
+		 *  - local EXT (floating EXT are NOT cleared)
+		 *  - MCHECK (floating are NOT cleared)
+		 */
+
+		cpu->state = GUEST_STOPPED;
+	}
+
+	if (flags & RESET_PSW)
+		memset(&cpu->sie_cb.gpsw, 0, sizeof(struct psw));
+
+	if (flags & RESET_PREFIX)
+		cpu->sie_cb.prefix = 0;
+
+	if (flags & RESET_CPU_TIMER) {
+		/* FIXME */
+	}
+
+	if (flags & RESET_CLK_COMP) {
+		/* FIXME */
+	}
+
+	if (flags & RESET_TOD_PROG_REG) {
+		/* FIXME */
+	}
+
+	if (flags & RESET_CR) {
+		memset(cpu->sie_cb.gcr, 0, 16*sizeof(u64));
+		cpu->sie_cb.gcr[0]  = 0xE0UL;
+		cpu->sie_cb.gcr[14] = 0xC2000000UL;
+	}
+
+	if (flags & RESET_BREAK_EV_ADDR) {
+		/* FIXME: initialize to 0x1 */
+	}
+
+	if (flags & RESET_FPCR)
+		cpu->regs.fpcr = 0;
+
+	if (flags & RESET_AR)
+		memset(cpu->regs.ar, 0, 16*sizeof(u32));
+
+	if (flags & RESET_GPR)
+		memset(cpu->regs.gpr, 0, 16*sizeof(u64));
+
+	if (flags & RESET_FPR)
+		memset(cpu->regs.fpr, 0, 16*sizeof(u64));
+
+	if (flags & RESET_STORAGE_KEYS) {
+	}
+
+	if (flags & RESET_STORAGE) {
+		struct page *p;
+
+		list_for_each_entry(p, &sys->guest_pages, guest)
+			memset(page_to_addr(p), 0, PAGE_SIZE);
+	}
+
+	if (flags & RESET_NONVOL_STORAGE) {
+	}
+
+	if (flags & RESET_EXPANDED_STORAGE) {
+	}
+
+	if (flags & RESET_TOD) {
+	}
+
+	if (flags & RESET_TOD_STEER) {
+	}
+
+	if (flags & RESET_PLO_LOCKS) {
+		/*
+		 * TODO: if RESET_PLO_LOCKS_PRESERVE is set, don't reset
+		 * locks held by powered on CPUS
+		 */
+	}
+}
+
+static void __perform_noncpu_reset(struct virt_sys *sys, int flags)
+{
+	if (flags & RESET_FLOATING_INTERRUPTIONS) {
+	}
+
+	if (flags & RESET_IO) {
+	}
+}
+
+/**************/
+
+void guest_power_on_reset(struct virt_sys *sys)
+{
+	__perform_cpu_reset(sys, POWER_ON_RESET_FLAGS);
+	__perform_noncpu_reset(sys, POWER_ON_RESET_FLAGS);
+}
+
+void guest_system_reset_normal(struct virt_sys *sys)
+{
+	__perform_cpu_reset(sys, CPU_RESET_FLAGS);
+
+	/*
+	 * TODO: once we have SMP guests, all other cpus should get a
+	 * CPU_RESET_FLAGS as well.
+	 */
+
+	__perform_noncpu_reset(sys, SUBSYSTEM_RESET_FLAGS);
+}
+
+void guest_system_reset_clear(struct virt_sys *sys)
+{
+	__perform_cpu_reset(sys, CLEAR_RESET_FLAGS);
+
+	/*
+	 * TODO: once we have SMP guests, all other cpus should get a
+	 * CLEAR_RESET_FLAGS as well.
+	 */
+
+	__perform_noncpu_reset(sys, CLEAR_RESET_FLAGS);
+}
+
+void guest_load_normal(struct virt_sys *sys)
+{
+	__perform_cpu_reset(sys, INIT_CPU_RESET_FLAGS);
+
+	/*
+	 * TODO: once we have SMP guests, all other cpus should get a
+	 * CPU_RESET_FLAGS.
+	 */
+
+	__perform_noncpu_reset(sys, SUBSYSTEM_RESET_FLAGS);
+}
+
+void guest_load_clear(struct virt_sys *sys)
+{
+	__perform_cpu_reset(sys, CLEAR_RESET_FLAGS);
+
+	/*
+	 * TODO: once we have SMP guests, all other cpus should get a
+	 * CLEAR_RESET_FLAGS as well.
+	 */
+
+	__perform_noncpu_reset(sys, CLEAR_RESET_FLAGS);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cp/shell/splash.c	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,25 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
+#include <splash.h>
+
+char *splash[] = {
+	"                    HH        HH  VV        VV  FFFFFFFFFFFF\n",
+	"                    HH        HH  VV        VV  FFFFFFFFFFFF\n",
+	"                    HH        HH  VV        VV  FF\n",
+	"                    HH        HH  VV        VV  FF\n",
+	"                    HH        HH  VV        VV  FF\n",
+	"                    HHHHHHHHHHHH  VV        VV  FFFFFFF\n",
+	"                    HHHHHHHHHHHH  VV        VV  FFFFFFF\n",
+	"                    HH        HH   VV      VV   FF\n",
+	"                    HH        HH    VV    VV    FF\n",
+	"                    HH        HH     VV  VV     FF\n",
+	"                    HH        HH      VVVV      FF\n",
+	"                    HH        HH       VV       FF\n",
+	"\n",
+	NULL,
+};
--- a/doc/manual/cp-directory.tex	Tue Dec 29 20:04:16 2009 -0500
+++ b/doc/manual/cp-directory.tex	Fri Jun 18 20:41:48 2010 -0400
@@ -94,7 +94,7 @@
 
 \begin{figure*}[htb]
 \small
-\lstinputlisting{../../sys/hvf.directory}
+\lstinputlisting{../../cp/hvf.directory}
 \captionfont
 \caption{\capfont Example directory defining three users.}
 \label{fig:directory-sample}
--- a/doc/manual/gen-docs.sh	Tue Dec 29 20:04:16 2009 -0500
+++ b/doc/manual/gen-docs.sh	Fri Jun 18 20:41:48 2010 -0400
@@ -115,7 +115,7 @@
 rm -f cp-cmd-list.tex
 mkdir -p tex/
 
-for srcf in ../../sys/cp/cmd_*.c ; do
+for srcf in ../../cp/shell/cmd_*.c ; do
 	echo "Inspecting $srcf..."
 	write_docs $srcf tex
 	#write_docs $srcf txt
--- a/hercules/hvf.cnf	Tue Dec 29 20:04:16 2009 -0500
+++ b/hercules/hvf.cnf	Fri Jun 18 20:41:48 2010 -0400
@@ -31,7 +31,7 @@
 #---    ----    --------------------
 
 # Card Reader
-000C    3505    ../sys/loader_rdr.bin ../sys/hvf ebcdic multifile
+000C    3505    ../cp/loader_rdr.bin ../cp/hvf ebcdic multifile
 
 # Card Punch
 000D    3525    punch00d.txt ascii
--- a/hercules/tape-hvf.tdf	Tue Dec 29 20:04:16 2009 -0500
+++ b/hercules/tape-hvf.tdf	Fri Jun 18 20:41:48 2010 -0400
@@ -1,4 +1,4 @@
 @TDF
-/home/jeffpc/hvf/sys/loader_tape.bin      FIXED RECSIZE 1024
-/home/jeffpc/hvf/sys/hvf                  FIXED RECSIZE 4096
+/home/jeffpc/hvf/cp/loader_tape.bin      FIXED RECSIZE 1024
+/home/jeffpc/hvf/cp/hvf                  FIXED RECSIZE 4096
 EOT
--- a/include/binfmt_elf.h	Tue Dec 29 20:04:16 2009 -0500
+++ b/include/binfmt_elf.h	Fri Jun 18 20:41:48 2010 -0400
@@ -1,3 +1,10 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
 #ifndef __BINFMT_ELF_H
 #define __BINFMT_ELF_H
 
--- a/include/clock.h	Tue Dec 29 20:04:16 2009 -0500
+++ b/include/clock.h	Fri Jun 18 20:41:48 2010 -0400
@@ -1,3 +1,10 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
 #ifndef __CLOCK_H
 #define __CLOCK_H
 
--- a/include/digest.h	Tue Dec 29 20:04:16 2009 -0500
+++ b/include/digest.h	Fri Jun 18 20:41:48 2010 -0400
@@ -1,3 +1,10 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
 #ifndef __DIGEST_H
 #define __DIGEST_H
 
--- a/include/errno.h	Tue Dec 29 20:04:16 2009 -0500
+++ b/include/errno.h	Fri Jun 18 20:41:48 2010 -0400
@@ -1,3 +1,10 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
 #ifndef __ERRNO_H
 #define __ERRNO_H
 
--- a/include/string.h	Tue Dec 29 20:04:16 2009 -0500
+++ b/include/string.h	Fri Jun 18 20:41:48 2010 -0400
@@ -1,3 +1,10 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
 #ifndef __STRING_H
 #define __STRING_H
 
--- a/include/types.h	Tue Dec 29 20:04:16 2009 -0500
+++ b/include/types.h	Fri Jun 18 20:41:48 2010 -0400
@@ -1,3 +1,10 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
 #ifndef __TYPES_H
 #define __TYPES_H
 
--- a/lib/Makefile	Tue Dec 29 20:04:16 2009 -0500
+++ b/lib/Makefile	Fri Jun 18 20:41:48 2010 -0400
@@ -7,7 +7,7 @@
      digest.a		\
      string.a
 
-include ../sys/scripts/Makefile.commands
+include ../cp/scripts/Makefile.commands
 
 all: $(LIBS)
 
--- a/lib/clock.c	Tue Dec 29 20:04:16 2009 -0500
+++ b/lib/clock.c	Fri Jun 18 20:41:48 2010 -0400
@@ -1,3 +1,10 @@
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
+
 #include <clock.h>
 
 #define LS_NONE			0x00	/* non-leap second entry */
--- a/lib/string.c	Tue Dec 29 20:04:16 2009 -0500
+++ b/lib/string.c	Fri Jun 18 20:41:48 2010 -0400
@@ -1,5 +1,10 @@
 /*
- * Copyright (c) 2007,2008 Josef 'Jeff' Sipek
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ *
+ * Some of these functions are based on Linux's lib/string.c.
  */
 
 #include <string.h>
--- a/lib/vsprintf.c	Tue Dec 29 20:04:16 2009 -0500
+++ b/lib/vsprintf.c	Fri Jun 18 20:41:48 2010 -0400
@@ -1,4 +1,9 @@
 /*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ *
  * A number of things found in this file were borrowed from the Linux Kernel
  */
 
--- a/loader/Makefile	Tue Dec 29 20:04:16 2009 -0500
+++ b/loader/Makefile	Fri Jun 18 20:41:48 2010 -0400
@@ -5,7 +5,7 @@
 CFLAGS=-g -fno-strict-aliasing -fno-builtin -nostdlib -Wall -m64 -I ../include/ -O2 -include ../include/types.h
 NUCLEUSCFLAGS=
 
-include ../sys/scripts/Makefile.commands
+include ../cp/scripts/Makefile.commands
 
 all: eckd.rto loader.rto
 
--- a/nss/8ball/8ball.S	Tue Dec 29 20:04:16 2009 -0500
+++ b/nss/8ball/8ball.S	Fri Jun 18 20:41:48 2010 -0400
@@ -1,6 +1,9 @@
-#
-# Copyright (c) 2009 Josef 'Jeff' Sipek
-#
+/*
+ * (C) Copyright 2007-2010  Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ *
+ * This file is released under the GPLv2.  See the COPYING file for more
+ * details.
+ */
 
 #
 # At this point, the machine is running in ESA390 mode.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/gen-announce-email.sh	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+USAGE="$0 <rev> <prev_rev>"
+
+rev="$1"
+prev_rev="$2"
+
+if [ -z "$rev" -o -z "$prev_rev" ]; then
+	echo $USAGE >&2
+	exit 1
+fi
+
+(cat << DONE
+HVF <<REV>> is available for download.
+
+HVF is a hypervisor OS for z/Architecture systems.
+
+Tarballs:
+http://www.josefsipek.net/projects/hvf/src/
+
+Git repo:
+git://repo.or.cz/hvf.git
+
+
+<<SUMMARY>>
+
+As always, patches, and other feedback is welcome.
+
+Josef "Jeff" Sipek.
+
+------------
+Changes since <<PREV_REV>>:
+
+DONE
+) | sed -e "s/<<REV>>/$rev/g" -e "s/<<PREV_REV>>/$prev_rev/g"
+
+git-log --no-merges $prev_rev..$rev | git-shortlog
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/release_version.sh	Fri Jun 18 20:41:48 2010 -0400
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+if [ $# -ne 1 ]; then
+	echo "Usage: $0 <tagname>"
+	exit 1
+fi
+
+case "$1" in
+	v*)
+		tag="$1"
+		;;
+	[0-9]*)
+		tag="v$1"
+		;;
+esac
+
+ver=`echo $tag | sed -e 's/^v//'`
+
+echo "About start release process of '`git rev-parse HEAD`' as '$tag'..."
+echo "Press enter to continue."
+read n
+
+echo "1) Edit VERSION in 'Makefile'"
+read n
+vim Makefile
+git update-index Makefile
+git commit -s -m "HVF $ver"
+
+echo "2) Tag the commit with '$tag'"
+read n
+git tag -u C7958FFE -m "HVF $tag" "$tag"
+
+echo "3) Generate hvf-$ver.tar.{gz,bz2}"
+read n
+git archive --format=tar --prefix=hvf-$ver/ HEAD | gzip -9 > hvf-$ver.tar.gz
+git archive --format=tar --prefix=hvf-$ver/ HEAD | bzip2 -9 > hvf-$ver.tar.bz2
+
+echo "4) Profit"
+
+echo "We're all done, have a nice day."
--- a/sys/.gitignore	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-*.o
-*.rto
-ipl/ipl_rdr_ccws.S
-ipl/ipl_tape.S
-cp/directory_structs.c
-hvf
-loader_rdr.bin
-loader_tape.bin
-cscope.out
--- a/sys/Makefile	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-#
-# HVF: Hobbyist Virtualization Facility
-#
-
-VERSION=0.16-rc2
-
-AS=$(CROSS_COMPILE)as
-CC=$(CROSS_COMPILE)gcc
-LD=$(CROSS_COMPILE)ld
-OBJCOPY=$(CROSS_COMPILE)objcopy
-
-# By default, be terse
-V=0
-
-DISPLAYVERSION=$(shell ./scripts/extract-version.sh)
-
-MAKEFLAGS += -rR --no-print-directory
-CFLAGS=-DVERSION=\"$(DISPLAYVERSION)\" -g -fno-strict-aliasing -fno-builtin -nostdlib -Wall -m64 -I include/ -I ../include/ -O2 -include ../include/types.h
-NUCLEUSCFLAGS=-include include/nucleus.h
-LDFLAGS=-m elf64_s390
-
-LIBS=clock digest string
-
-export AS CC LD OBJCOPY
-export MAKEFLAGS CFLAGS NUCLEUSCFLAGS LDFLAGS
-
-TOP_DIRS=nucleus/ mm/ fs/ drivers/ cp/
-
-.PHONY: all build clean mrproper cleanup hvfclean tags
-.PHONY: $(TOP_DIRS)
-
-include scripts/Makefile.commands
-
-all: build hvf
-	@echo "Image is `stat -c %s hvf` bytes"
-
-hvf: $(patsubst %/,%/built-in.o,$(TOP_DIRS))
-	$(call link-hvf,$^ $(patsubst %,../lib/%.a,$(LIBS)),$@)
-
-docs:
-	./scripts/gen-docs.sh
-
-clean:
-	@$(MAKE) DIR=nucleus/ cleanup V=$V
-	@$(MAKE) DIR=mm/ cleanup V=$V
-	@$(MAKE) DIR=fs/ cleanup V=$V
-	@$(MAKE) DIR=drivers/ cleanup V=$V
-	@$(MAKE) DIR=cp/ cleanup V=$V
-	$(call clean,hvf)
-	$(call clean,cp/directory_structs.c)
-	$(call rclean,doc/commands)
-
-mrproper: clean
-	$(call clean,cscope.out ctags)
-
-cleanup:
-	$(call clean,$(DIR)*.o)
-
-build: $(TOP_DIRS)
-
-$(TOP_DIRS): %/:
-	@$(MAKE) -f scripts/Makefile.build DIR=$@ V=$V
-
-tags:
-	$(call cscope)
-
-#
-# Include Makefiles from all the top level directories
-#
-include $(patsubst %/,%/Makefile,$(TOP_DIRS))
--- a/sys/cp/Makefile	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-objs-cp := init.o directory.o cmds.o disassm.o guest.o reset.o intercept.o \
-	guest_ipl.o exception.o instruction.o instruction_priv.o splash.o
--- a/sys/cp/cmd_beginstop.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- *!!! BEGIN
- *!! SYNTAX
- *! \tok{\sc BEgin}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Starts/resumes virtual machine execution.
- */
-static int cmd_begin(struct virt_sys *sys, char *cmd, int len)
-{
-	sys->task->cpu->state = GUEST_OPERATING;
-	return 0;
-}
-
-/*
- *!!! STOP
- *!! SYNTAX
- *! \tok{\sc STOP}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Stops virtual machine execution.
- */
-static int cmd_stop(struct virt_sys *sys, char *cmd, int len)
-{
-	sys->task->cpu->state = GUEST_STOPPED;
-	return 0;
-}
--- a/sys/cp/cmd_display.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,549 +0,0 @@
-static char* parse_addrspec(u64 *val, u64 *len, char *s)
-{
-	u64 tmp;
-	int parsed = 0;
-
-	tmp = 0;
-	while(!(*s == '\0' ||
-		*s == ' ' ||
-		*s == '\t')) {
-		if (*s >= '0' && *s <= '9')
-			tmp = 16*tmp + (*s - '0');
-		else if ((*s >= 'A' && *s <= 'F') ||
-			 (*s >= 'a' && *s <= 'f'))
-			tmp = 16*tmp + 10 + ((*s & ~0x20) - 'A');
-		else if (*s == '.' && parsed)
-			break;
-		else
-			return ERR_PTR(-EINVAL);
-
-		s++;
-		parsed = 1;
-	}
-
-	if (len) {
-		*len = 0;
-		if (*s == '.') {
-			s = __extract_hex(s+1, len);
-			if (IS_ERR(s))
-				parsed = 0;
-		}
-	}
-
-	*val = tmp;
-
-	return (parsed == 1 ? s : ERR_PTR(-EINVAL));
-}
-
-enum display_fmt {
-	FMT_NUMERIC = 0,
-	FMT_INSTRUCT,
-};
-
-static void __display_storage_instruct(struct virt_sys *sys, u64 guest_addr,
-				       u64 mlen)
-{
-	int ret;
-	char buf[64];
-	int ilen;
-	u64 val;
-	u64 host_addr;
-
-	u64 end_addr;
-
-	/* walk the page tables to find the real page frame */
-	ret = virt2phy_current(guest_addr, &host_addr);
-	if (ret) {
-		con_printf(sys->con, "DISPLAY: Specified address is not part of "
-			   "guest configuration (RC=%d,%d)\n", -EFAULT, ret);
-		return;
-	}
-
-	if (!mlen)
-		mlen = 1;
-
-	end_addr = guest_addr + mlen;
-
-	while(guest_addr < end_addr) {
-		/*
-		 * FIXME: make sure crossing page-boundary doesn't break
-		 * give us garbage
-		 */
-		ilen = disassm((unsigned char*) host_addr, buf, 64);
-
-		if ((host_addr & PAGE_MASK) >= (PAGE_SIZE-ilen)) {
-			con_printf(sys->con, "DISPLAY: Instruction spans page "
-				   "boundary - not supported\n");
-			break;
-		}
-
-		/* load the dword at the address, and shift it to the LSB part */
-		val = *((u64*)host_addr) >> 8*(sizeof(u64) - ilen);
-
-		con_printf(sys->con, "R%016llX  %0*llX%*s  %s\n", guest_addr,
-			   2*ilen, val,			/* inst hex dump */
-			   12-2*ilen, "",		/* spacer */
-			   buf);
-
-		host_addr += ilen;
-		guest_addr += ilen;
-	}
-}
-
-static void __display_storage_numeric(struct virt_sys *sys, u64 guest_addr,
-				      u64 mlen)
-{
-	char buf[80];
-	char *bp;
-
-	u64 host_addr;
-	int this_len;
-
-	int ret;
-
-	/* round down */
-	guest_addr &= ~((u64) 0x3);
-
-	/* walk the page tables to find the real page frame */
-	ret = virt2phy_current(guest_addr, &host_addr);
-	if (ret)
-		goto fault;
-
-	if (mlen > 4)
-		mlen = (mlen >> 2) + !!(mlen & 0x3);
-	else
-		mlen = 1;
-
-	while(mlen && !ret) {
-		this_len = (mlen > 4) ? 4 : mlen;
-
-		mlen -= this_len;
-
-		bp = buf;
-		bp += snprintf(bp, 80, "R%016llX  ", guest_addr);
-
-		while(this_len) {
-			bp += snprintf(bp, 80 - (bp - buf), "%08X ",
-				       *(u32*)host_addr);
-
-			guest_addr += 4;
-			host_addr += 4;
-			this_len--;
-
-			/* loop if we're not crossing a page, or if we're done */
-			if (((guest_addr & PAGE_MASK) != 0) || !mlen)
-				continue;
-
-			/*
-			 * We will attempt to walk further along guest
-			 * storage, and are about to cross a page boundary,
-			 * walk the page tables to find the real page frame
-			 */
-			ret = virt2phy_current(guest_addr, &host_addr);
-			if (ret)
-				break;
-		}
-
-		con_printf(sys->con, "%s\n", buf);
-	}
-
-fault:
-	if (ret)
-		con_printf(sys->con, "DISPLAY: The address %016llX is not part of "
-			   "guest configuration (RC=%d,%d)\n", guest_addr, -EFAULT, ret);
-}
-
-/*
- *!!! DISPLAY STORAGE
- *!! SYNTAX
- *! \tok{\sc Display} \tok{\sc STOrage}
- *! \begin{stack} \\ \deftok{N} \\ \tok{I} \end{stack}
- *! <addr>
- *! \begin{stack} \\ \tok{.} <length> \end{stack}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Displays a portion of guest's storage.
- *!! OPERANDS
- *! \cbstart
- *! \item[addr] is the guest storage address.
- *! \item[length] is the number of bytes to display.  If not specified, 4 is
- *! assumed.
- *! \cbend
- *!! SDNAREPO
- *!! OPTIONS
- *! \cbstart
- *! \item[N] display guest storage in numeric format.
- *! \item[I] display guest storage in instruction format.
- *! \cbend
- *!! SNOITPO
- *!! NOTES
- *! \cbstart
- *! \item Currently, the instruction display does not support page-boundary
- *! crossing.
- *! \cbend
- *!! SETON
- *!! EXAMPLES
- *! D STO 200\\
- *! D STO N200.10\\
- *! D STO I1234.200
- */
-static int cmd_display_storage(struct virt_sys *sys, char *cmd, int len)
-{
-	u64 guest_addr;
-	u64 mlen = 0;
-	enum display_fmt fmt;
-
-	switch (cmd[0]) {
-		case 'N': case 'n':
-			/* numeric */
-			cmd++;
-			fmt = FMT_NUMERIC;
-			break;
-		case 'I': case 'i':
-			/* instruction */
-			cmd++;
-			fmt = FMT_INSTRUCT;
-			break;
-		default:
-			/* numeric */
-			fmt = FMT_NUMERIC;
-			break;
-	}
-
-	cmd = parse_addrspec(&guest_addr, &mlen, cmd);
-	if (IS_ERR(cmd)) {
-		con_printf(sys->con, "DISPLAY: Invalid addr-spec\n");
-		return 0;
-	}
-
-	if (fmt == FMT_INSTRUCT)
-		__display_storage_instruct(sys, guest_addr, mlen);
-	else
-		__display_storage_numeric(sys, guest_addr, mlen);
-
-	return 0;
-}
-
-/*
- *!!! DISPLAY SIECB
- *!! SYNTAX
- *! \tok{\sc Display} \tok{\sc SIECB}
- *!! XATNYS
- *!! AUTH E
- *!! PURPOSE
- *! Displays hexdump of the guest's SIE control block.
- */
-static int cmd_display_siecb(struct virt_sys *sys, char *cmd, int len)
-{
-	u32 *val;
-	int i;
-
-	CP_CMD_AUTH(sys, 'E');
-
-	val = (u32*) &sys->task->cpu->sie_cb;
-
-	for(i=0; i<(sizeof(struct sie_cb)/sizeof(u32)); i+=4)
-		con_printf(sys->con, "%03lX  %08X %08X %08X %08X\n",
-			   i*sizeof(u32), val[i], val[i+1], val[i+2],
-			   val[i+3]);
-
-	return 0;
-}
-
-/*
- *!!! DISPLAY GPR
- *!! SYNTAX
- *! \tok{\sc Display} \tok{\sc Gpr}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Displays the guest's general purpose registers
- */
-static int cmd_display_gpr(struct virt_sys *sys, char *cmd, int len)
-{
-	con_printf(sys->con, "GR  0 = %016llX %016llX\n",
-		   sys->task->cpu->regs.gpr[0],
-		   sys->task->cpu->regs.gpr[1]);
-	con_printf(sys->con, "GR  2 = %016llX %016llX\n",
-		   sys->task->cpu->regs.gpr[2],
-		   sys->task->cpu->regs.gpr[3]);
-	con_printf(sys->con, "GR  4 = %016llX %016llX\n",
-		   sys->task->cpu->regs.gpr[4],
-		   sys->task->cpu->regs.gpr[5]);
-	con_printf(sys->con, "GR  6 = %016llX %016llX\n",
-		   sys->task->cpu->regs.gpr[6],
-		   sys->task->cpu->regs.gpr[7]);
-	con_printf(sys->con, "GR  8 = %016llX %016llX\n",
-		   sys->task->cpu->regs.gpr[8],
-		   sys->task->cpu->regs.gpr[9]);
-	con_printf(sys->con, "GR 10 = %016llX %016llX\n",
-		   sys->task->cpu->regs.gpr[10],
-		   sys->task->cpu->regs.gpr[11]);
-	con_printf(sys->con, "GR 12 = %016llX %016llX\n",
-		   sys->task->cpu->regs.gpr[12],
-		   sys->task->cpu->regs.gpr[13]);
-	con_printf(sys->con, "GR 14 = %016llX %016llX\n",
-		   sys->task->cpu->regs.gpr[14],
-		   sys->task->cpu->regs.gpr[15]);
-	return 0;
-}
-
-/*
- *!!! DISPLAY FPCR
- *!! SYNTAX
- *! \tok{\sc Display} \tok{\sc FPCR}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Displays the guest's floating point control register
- */
-static int cmd_display_fpcr(struct virt_sys *sys, char *cmd, int len)
-{
-	con_printf(sys->con, "FPCR  = %08X\n", sys->task->cpu->regs.fpcr);
-	return 0;
-}
-
-/*
- *!!! DISPLAY FPR
- *!! SYNTAX
- *! \tok{\sc Display} \tok{\sc Fpr}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Displays the guest's floating point registers
- */
-static int cmd_display_fpr(struct virt_sys *sys, char *cmd, int len)
-{
-	con_printf(sys->con, "FR  0 = %016llX %016llX\n",
-		   sys->task->cpu->regs.fpr[0],
-		   sys->task->cpu->regs.fpr[1]);
-	con_printf(sys->con, "FR  2 = %016llX %016llX\n",
-		   sys->task->cpu->regs.fpr[2],
-		   sys->task->cpu->regs.fpr[3]);
-	con_printf(sys->con, "FR  4 = %016llX %016llX\n",
-		   sys->task->cpu->regs.fpr[4],
-		   sys->task->cpu->regs.fpr[5]);
-	con_printf(sys->con, "FR  6 = %016llX %016llX\n",
-		   sys->task->cpu->regs.fpr[6],
-		   sys->task->cpu->regs.fpr[7]);
-	con_printf(sys->con, "FR  8 = %016llX %016llX\n",
-		   sys->task->cpu->regs.fpr[8],
-		   sys->task->cpu->regs.fpr[9]);
-	con_printf(sys->con, "FR 10 = %016llX %016llX\n",
-		   sys->task->cpu->regs.fpr[10],
-		   sys->task->cpu->regs.fpr[11]);
-	con_printf(sys->con, "FR 12 = %016llX %016llX\n",
-		   sys->task->cpu->regs.fpr[12],
-		   sys->task->cpu->regs.fpr[13]);
-	con_printf(sys->con, "FR 14 = %016llX %016llX\n",
-		   sys->task->cpu->regs.fpr[14],
-		   sys->task->cpu->regs.fpr[15]);
-	return 0;
-}
-
-/*
- *!!! DISPLAY CR
- *!! SYNTAX
- *! \tok{\sc Display} \tok{\sc Cr}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Displays the guest's control registers
- */
-static int cmd_display_cr(struct virt_sys *sys, char *cmd, int len)
-{
-	con_printf(sys->con, "CR  0 = %016llX %016llX\n",
-		   sys->task->cpu->sie_cb.gcr[0],
-		   sys->task->cpu->sie_cb.gcr[1]);
-	con_printf(sys->con, "CR  2 = %016llX %016llX\n",
-		   sys->task->cpu->sie_cb.gcr[2],
-		   sys->task->cpu->sie_cb.gcr[3]);
-	con_printf(sys->con, "CR  4 = %016llX %016llX\n",
-		   sys->task->cpu->sie_cb.gcr[4],
-		   sys->task->cpu->sie_cb.gcr[5]);
-	con_printf(sys->con, "CR  6 = %016llX %016llX\n",
-		   sys->task->cpu->sie_cb.gcr[6],
-		   sys->task->cpu->sie_cb.gcr[7]);
-	con_printf(sys->con, "CR  8 = %016llX %016llX\n",
-		   sys->task->cpu->sie_cb.gcr[8],
-		   sys->task->cpu->sie_cb.gcr[9]);
-	con_printf(sys->con, "CR 10 = %016llX %016llX\n",
-		   sys->task->cpu->sie_cb.gcr[10],
-		   sys->task->cpu->sie_cb.gcr[11]);
-	con_printf(sys->con, "CR 12 = %016llX %016llX\n",
-		   sys->task->cpu->sie_cb.gcr[12],
-		   sys->task->cpu->sie_cb.gcr[13]);
-	con_printf(sys->con, "CR 14 = %016llX %016llX\n",
-		   sys->task->cpu->sie_cb.gcr[14],
-		   sys->task->cpu->sie_cb.gcr[15]);
-	return 0;
-}
-
-/*
- *!!! DISPLAY AR
- *!! SYNTAX
- *! \tok{\sc Display} \tok{\sc Ar}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Displays the guest's access registers
- */
-static int cmd_display_ar(struct virt_sys *sys, char *cmd, int len)
-{
-	con_printf(sys->con, "AR  0 = %08X %08X\n",
-		   sys->task->cpu->regs.ar[0],
-		   sys->task->cpu->regs.ar[1]);
-	con_printf(sys->con, "AR  2 = %08X %08X\n",
-		   sys->task->cpu->regs.ar[2],
-		   sys->task->cpu->regs.ar[3]);
-	con_printf(sys->con, "AR  4 = %08X %08X\n",
-		   sys->task->cpu->regs.ar[4],
-		   sys->task->cpu->regs.ar[5]);
-	con_printf(sys->con, "AR  6 = %08X %08X\n",
-		   sys->task->cpu->regs.ar[6],
-		   sys->task->cpu->regs.ar[7]);
-	con_printf(sys->con, "AR  8 = %08X %08X\n",
-		   sys->task->cpu->regs.ar[8],
-		   sys->task->cpu->regs.ar[9]);
-	con_printf(sys->con, "AR 10 = %08X %08X\n",
-		   sys->task->cpu->regs.ar[10],
-		   sys->task->cpu->regs.ar[11]);
-	con_printf(sys->con, "AR 12 = %08X %08X\n",
-		   sys->task->cpu->regs.ar[12],
-		   sys->task->cpu->regs.ar[13]);
-	con_printf(sys->con, "AR 14 = %08X %08X\n",
-		   sys->task->cpu->regs.ar[14],
-		   sys->task->cpu->regs.ar[15]);
-	return 0;
-}
-
-/*
- *!!! DISPLAY PSW
- *!! SYNTAX
- *! \tok{\sc Display} \tok{\sc PSW}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Displays the guest's PSW.
- *!
- *! \cbstart
- *! If the guest is in ESA/390 mode, the 8-byte PSW is displayed.
- *!
- *! If the guest is in z/Architecture mode, the 16-byte PSW is displayed.
- *! \cbend
- */
-static int cmd_display_psw(struct virt_sys *sys, char *cmd, int len)
-{
-	u32 *ptr = (u32*) &sys->task->cpu->sie_cb.gpsw;
-
-	if (VCPU_ZARCH(sys->task->cpu))
-		con_printf(sys->con, "PSW = %08X %08X %08X %08X\n",
-			   ptr[0], ptr[1], ptr[2], ptr[3]);
-	else
-		con_printf(sys->con, "PSW = %08X %08X\n",
-			   ptr[0], ptr[1]);
-
-	return 0;
-}
-
-static void __do_display_schib(struct console *con, struct virt_device *vdev)
-{
-	con_printf(con, "%05X %04X %08X   %d  %02X %02X  %02X  %02X %02X "
-		        "---- %02X %02X %02X%02X%02X%02X %02X%02X%02X%02X\n",
-		   vdev->sch, vdev->pmcw.dev_num, vdev->pmcw.interrupt_param,
-		   vdev->pmcw.isc, ((vdev->pmcw.e  << 7) |
-				    (vdev->pmcw.lm << 5) |
-				    (vdev->pmcw.mm << 3) |
-				    (vdev->pmcw.d  << 2) |
-				    (vdev->pmcw.t  << 1) |
-				    (vdev->pmcw.v)),
-		   vdev->pmcw.lpm, vdev->pmcw.pnom, vdev->pmcw.lpum,
-		   vdev->pmcw.pim,
-		   /* MBI */
-		   vdev->pmcw.pom, vdev->pmcw.pam,
-		   vdev->pmcw.chpid[0], vdev->pmcw.chpid[1],
-		   vdev->pmcw.chpid[2], vdev->pmcw.chpid[3],
-		   vdev->pmcw.chpid[4], vdev->pmcw.chpid[5],
-		   vdev->pmcw.chpid[6], vdev->pmcw.chpid[7]);
-}
-
-/*
- *!!! DISPLAY SCHIB
- *!! SYNTAX
- *! \tok{\sc Display} \tok{\sc SCHIB}
- *! \begin{stack} \tok{ALL} \\ <schib> \end{stack}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Displays the guest's subchannel control block information
- */
-static int cmd_display_schib(struct virt_sys *sys, char *cmd, int len)
-{
-	struct virt_device *vdev;
-	u64 sch;
-	int all;
-
-	if (strcasecmp(cmd, "ALL")) {
-		cmd = __extract_hex(cmd, &sch);
-		if (IS_ERR(cmd))
-			return PTR_ERR(cmd);
-
-		/* sch number must be: X'0001____' */
-		if ((sch & 0xffff0000) != 0x00010000)
-			return -EINVAL;
-
-		all = 0;
-	} else
-		all = 1;
-
-	/* find the virtual device */
-
-	list_for_each_entry(vdev, &sys->virt_devs, devices) {
-		if ((vdev->sch == (u32) sch) || all) {
-			if (!all || all == 1) {
-				con_printf(sys->con, "SCHIB DEV  INT-PARM ISC FLG LP "
-					   "PNO LPU PI MBI  PO PA CHPID0-3 CHPID4-7\n");
-				all = (all ? 2 : 0);
-			}
-
-			__do_display_schib(sys->con, vdev);
-
-			if (!all)
-				break;
-		}
-	}
-
-	return 0;
-}
-
-static struct cpcmd cmd_tbl_display[] = {
-	{"AR",		cmd_display_ar,		NULL},
-	{"A",		cmd_display_ar,		NULL},
-
-	{"CR",		cmd_display_cr,		NULL},
-	{"C",		cmd_display_cr,		NULL},
-
-	{"FPCR",	cmd_display_fpcr,	NULL},
-
-	{"FPR",		cmd_display_fpr,	NULL},
-	{"FP",		cmd_display_fpr,	NULL},
-	{"F",		cmd_display_fpr,	NULL},
-
-	{"GPR",		cmd_display_gpr,	NULL},
-	{"GP",		cmd_display_gpr,	NULL},
-	{"G",		cmd_display_gpr,	NULL},
-
-	{"PSW",		cmd_display_psw,	NULL},
-
-	{"SCHIB",	cmd_display_schib,	NULL},
-
-	{"SIECB",	cmd_display_siecb,	NULL},
-
-	{"STORAGE",	cmd_display_storage,	NULL},
-	{"STORAG",	cmd_display_storage,	NULL},
-	{"STORA",	cmd_display_storage,	NULL},
-	{"STOR",	cmd_display_storage,	NULL},
-	{"STO",		cmd_display_storage,	NULL},
-	{"",		NULL,			NULL},
-};
--- a/sys/cp/cmd_enable.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- *!!! ENABLE
- *!! SYNTAX
- *! \tok{\sc ENAble}
- *! \begin{stack} \tok{ALL} \\ <rdev> \end{stack}
- *!! XATNYS
- *!! AUTH A
- *!! PURPOSE
- *! Enables a real device.
- */
-static int cmd_enable(struct virt_sys *sys, char *cmd, int len)
-{
-	u64 devnum;
-	struct device *dev;
-	struct console *con;
-
-	if (!strcasecmp(cmd, "ALL")) {
-		con_printf(sys->con, "ENABLE ALL not yet implemented!\n");
-		return 0;
-	}
-
-	cmd = __extract_hex(cmd, &devnum);
-	if (IS_ERR(cmd))
-		return PTR_ERR(cmd);
-
-	/* device number must be 16-bit */
-	if (devnum & ~0xffffUL)
-		return -EINVAL;
-
-	dev = find_device_by_ccuu(devnum);
-	if (IS_ERR(dev)) {
-		con_printf(sys->con, "Device %04llX not found in configuration\n", devnum);
-		return 0;
-	}
-
-	if (atomic_read(&dev->in_use)) {
-		con_printf(sys->con, "Device %04llX is already in use\n", devnum);
-		dev_put(dev);
-		return 0;
-	}
-
-	if (!dev->dev->enable) {
-		con_printf(sys->con, "Device type %-4s cannot be enabled\n",
-			   type2name(dev->type));
-		return 0;
-	}
-
-	con = dev->dev->enable(dev);
-	if (IS_ERR(con)) {
-		con_printf(sys->con, "Failed to enable %04llX\n", devnum);
-		return PTR_ERR(con);
-	}
-
-	return 0;
-}
--- a/sys/cp/cmd_helpers.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-static char* __extract_dec(char *str, u64 *val)
-{
-	u64 res;
-	u64 tmp;
-	int len;
-
-	if (!str || !val)
-		return ERR_PTR(-EINVAL);
-
-	res = 0;
-	len = -1;
-
-	for (; str && *str != '\0'; str++, len++) {
-		if (*str >= '0' && *str <= '9')
-			tmp = *str - '0';
-		else if (*str == ' ' || *str == '\t')
-			break;
-		else
-			return ERR_PTR(-EINVAL);
-
-		res = (res * 10) + tmp;
-	}
-
-	if (len == -1)
-		return ERR_PTR(-EINVAL);
-
-	*val = res;
-
-	return str;
-}
-
-static char* __extract_hex(char *str, u64 *val)
-{
-	u64 res;
-	u64 tmp;
-	int len;
-
-	if (!str || !val)
-		return ERR_PTR(-EINVAL);
-
-	res = 0;
-	len = -1;
-
-	for (; str && *str != '\0'; str++, len++) {
-		if (*str >= '0' && *str <= '9')
-			tmp = *str - '0';
-		else if (*str >= 'A' && *str <= 'F')
-			tmp = *str - 'A' + 10;
-		else if (*str >= 'a' && *str <= 'f')
-			tmp = *str - 'a' + 10;
-		else if (*str == ' ' || *str == '\t')
-			break;
-		else
-			return ERR_PTR(-EINVAL);
-
-		res = (res << 4) | tmp;
-	}
-
-	if (len == -1)
-		return ERR_PTR(-EINVAL);
-
-	*val = res;
-
-	return str;
-}
-
-static char* __consume_ws(char *str)
-{
-	if (!str)
-		return str;
-
-	/* consume any extra whitespace */
-	while(*str == ' ' || *str == '\t')
-		str++;
-
-	return str;
-}
--- a/sys/cp/cmd_logon.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- *!!! LOGON
- *!! SYNTAX
- *! \tok{\sc LOGON} <userid>
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Log on to a virtual machine.
- */
-static int cmd_logon(struct virt_sys *data, char *cmd, int len)
-{
-	struct console *con = (struct console*) data; /* BEWARE */
-	struct user *u;
-
-	u = find_user_by_id(cmd);
-	if (IS_ERR(u)) {
-		con_printf(con, "INVALID USERID\n");
-		return 0;
-	}
-
-	spawn_user_cp(con, u);
-	con_printf(oper_con, "%s %04X LOGON AS %-8s\n",
-		   type2name(con->dev->type), con->dev->ccuu, u->userid);
-
-	return 0;
-}
-
-static int cmd_logon_fail(struct virt_sys *sys, char *cmd, int len)
-{
-	con_printf(sys->con, "ALREADY LOGGED ON\n");
-	return 0;
-}
--- a/sys/cp/cmd_query.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,261 +0,0 @@
-static char *__guest_state_to_str(enum virt_cpustate st)
-{
-	switch (st) {
-		case GUEST_STOPPED:	return "STOPPED";
-		case GUEST_OPERATING:	return "RUNNING";
-		case GUEST_LOAD:	return "LOADING";
-		case GUEST_CHECKSTOP:	return "CHECK-STOP";
-	}
-
-	return "???";
-}
-
-static void display_rdev(struct console *con, struct device *dev)
-{
-	char buf[40];
-
-	buf[0] = '\0';
-
-	if (dev->dev && dev->dev->snprintf)
-		dev->dev->snprintf(dev, buf, 40);
-
-	con_printf(con, "%-4s %04X %04X %s%sSCH = %05X\n",
-		   type2name(dev->type), dev->ccuu, dev->type, buf,
-		   atomic_read(&dev->in_use) ? "" : "FREE ",
-		   dev->sch);
-}
-
-static void display_vdev(struct console *con, struct virt_device *vdev)
-{
-	switch (vdev->vtype) {
-		case VDEV_CONS:
-			con_printf(con, "CONS %04X 3215 ON %s %04X %s SCH = %05X\n",
-				   vdev->pmcw.dev_num,
-				   type2name(con->dev->type), // FIXME?
-				   con->dev->ccuu,
-				   con->sys->print_ts ? "TS" : "NOTS",
-				   vdev->sch);
-			break;
-		case VDEV_DED:
-			con_printf(con, "%-4s %04X %04X ON DEV %04X SCH = %05X\n",
-				   type2name(vdev->type),
-				   vdev->pmcw.dev_num,
-				   vdev->type,
-				   vdev->u.dedicate.rdev->ccuu,
-				   vdev->sch);
-			break;
-		case VDEV_SPOOL:
-			con_printf(con, "%-4s %04X %04X SCH = %05X\n",
-				   type2name(vdev->type),
-				   vdev->pmcw.dev_num, vdev->type,
-				   vdev->sch);
-			break;
-		case VDEV_MDISK:
-			con_printf(con, "DASD %04X 3390 %6d CYL ON DASD %04X SCH = %05X\n",
-				   vdev->pmcw.dev_num,
-				   0, /* FIXME: cyl count */
-				   0, /* FIXME: rdev */
-				   vdev->sch);
-			break;
-		case VDEV_LINK:
-			con_printf(con, "LINK %04X TO %s %04X SCH = %05X\n",
-				   vdev->pmcw.dev_num,
-				   "????", /* FIXME: userid */
-				   0xffff, /* FIXME: user's vdev # */
-				   vdev->sch);
-			break;
-		default:
-			con_printf(con, "???? unknown device type (%04X, %05X)\n",
-				   vdev->pmcw.dev_num, vdev->sch);
-			break;
-	}
-}
-
-static void display_task(struct console *con, struct task *task)
-{
-	char state;
-
-	switch(task->state) {
-		case TASK_RUNNING:  state = 'R'; break;
-		case TASK_SLEEPING: state = 'S'; break;
-		case TASK_LOCKED:   state = 'L'; break;
-		default:            state = '?'; break;
-	}
-
-	con_printf(con, "%*s %p %c %016llX\n", -TASK_NAME_LEN, task->name,
-		   task, state, task->regs.psw.ptr);
-}
-
-/*
- *!!! QUERY TIME
- *!! SYNTAX
- *! \tok{\sc Query} \tok{\sc TIME}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Displays the current time
- */
-static int cmd_query_cplevel(struct virt_sys *sys, char *cmd, int len)
-{
-	con_printf(sys->con, "HVF version " VERSION "\n");
-	con_printf(sys->con, "IPL at %02d:%02d:%02d UTC %04d-%02d-%02d\n",
-		   ipltime.th, ipltime.tm, ipltime.ts, ipltime.dy,
-		   ipltime.dm, ipltime.dd);
-
-	return 0;
-}
-
-/*
- *!!! QUERY CPLEVEL
- *!! SYNTAX
- *! \tok{\sc Query} \tok{\sc CPLEVEL}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Displays the HVF version and time of IPL
- */
-static int cmd_query_time(struct virt_sys *sys, char *cmd, int len)
-{
-	struct datetime dt;
-
-	get_parsed_tod(&dt);
-
-	con_printf(sys->con, "TIME IS %02d:%02d:%02d UTC %04d-%02d-%02d\n",
-		   dt.th, dt.tm, dt.ts, dt.dy, dt.dm, dt.dd);
-
-	return 0;
-}
-
-/*
- *!!! QUERY ARCHMODE
- *!! SYNTAX
- *! \tok{\sc Query} \tok{\sc ARCHMODE}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Displays the virtual machine's current architecture mode.
- */
-static int cmd_query_archmode(struct virt_sys *sys, char *cmd, int len)
-{
-	char *mode = (VCPU_ZARCH(sys->task->cpu)) ? "z/Arch" : "ESA390";
-
-	con_printf(sys->con, "ARCHMODE = %s\n", mode);
-
-	return 0;
-}
-
-/*
- *!!! QUERY VIRTUAL
- *!! SYNTAX
- *! \tok{\sc Query} \tok{\sc Virtual}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Lists all of the guest's virtual devices
- */
-static int cmd_query_virtual(struct virt_sys *sys, char *cmd, int len)
-{
-	struct virt_device *vdev;
-
-	con_printf(sys->con, "CPU 00  ID  %016llX %s\n",
-		   sys->task->cpu->cpuid,
-		   __guest_state_to_str(sys->task->cpu->state));
-	con_printf(sys->con, "STORAGE = %lluM\n", sys->directory->storage_size >> 20);
-
-	list_for_each_entry(vdev, &sys->virt_devs, devices)
-		display_vdev(sys->con, vdev);
-
-	return 0;
-}
-
-/*
- *!!! QUERY REAL
- *!! SYNTAX
- *! \tok{\sc Query} \tok{\sc Real}
- *!! XATNYS
- *!! AUTH A
- *!! PURPOSE
- *! Lists all of the host's real devices
- */
-static int cmd_query_real(struct virt_sys *sys, char *cmd, int len)
-{
-	CP_CMD_AUTH(sys, 'A');
-
-	con_printf(sys->con, "CPU %02d  ID  %016llX RUNNING\n",
-		   getcpuaddr(),
-		   getcpuid());
-	con_printf(sys->con, "STORAGE = %lluM\n", memsize >> 20);
-
-	list_devices(sys->con, display_rdev);
-
-	return 0;
-}
-
-/*
- *!!! QUERY TASK
- *!! SYNTAX
- *! \tok{\sc Query} \tok{\sc Task}
- *!! XATNYS
- *!! AUTH A
- *!! PURPOSE
- *! Lists all of the tasks running on the host. This includes guest virtual
- *! cpu tasks, as well as system helper tasks.
- */
-static int cmd_query_task(struct virt_sys *sys, char *cmd, int len)
-{
-	CP_CMD_AUTH(sys, 'A');
-
-	list_tasks(sys->con, display_task);
-
-	return 0;
-}
-
-static void display_names(struct console *con, struct virt_sys *sys)
-{
-	con_printf(con, "%s %04X %-8s\n", type2name(sys->con->dev->type),
-		   sys->con->dev->ccuu, sys->directory->userid);
-}
-
-/*
- *!!! QUERY NAMES
- *!! SYNTAX
- *! \tok{\sc Query} \tok{\sc NAMes}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Lists all of the logged in users.
- */
-static int cmd_query_names(struct virt_sys *sys, char *cmd, int len)
-{
-	list_users(sys->con, display_names);
-
-	return 0;
-}
-
-static struct cpcmd cmd_tbl_query[] = {
-	{"ARCHMODE",	cmd_query_archmode,	NULL},
-
-	{"CPLEVEL",	cmd_query_cplevel,	NULL},
-
-	{"TIME",	cmd_query_time,		NULL},
-
-	{"VIRTUAL",	cmd_query_virtual,	NULL},
-	{"VIRTUA",	cmd_query_virtual,	NULL},
-	{"VIRTU",	cmd_query_virtual,	NULL},
-	{"VIRT",	cmd_query_virtual,	NULL},
-	{"VIR",		cmd_query_virtual,	NULL},
-	{"VI",		cmd_query_virtual,	NULL},
-	{"V",		cmd_query_virtual,	NULL},
-
-	{"REAL",	cmd_query_real,		NULL},
-	{"REA",		cmd_query_real,		NULL},
-	{"RE",		cmd_query_real,		NULL},
-	{"R",		cmd_query_real,		NULL},
-
-	{"NAMES",	cmd_query_names,	NULL},
-	{"NAME",	cmd_query_names,	NULL},
-	{"NAM",		cmd_query_names,	NULL},
-
-	{"TASK",	cmd_query_task,		NULL},
-	{"",		NULL,			NULL},
-};
--- a/sys/cp/cmd_set.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- *!!! SET NOTS
- *!! SYNTAX
- *! \tok{\sc SET} \tok{\sc NOTS}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Disable the console timestamp printing
- */
-static int cmd_set_nots(struct virt_sys *sys, char *cmd, int len)
-{
-	sys->print_ts = 0;
-	return 0;
-}
-
-/*
- *!!! SET TS
- *!! SYNTAX
- *! \tok{\sc SET} \tok{\sc TS}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Enable the console timestamp printing
- */
-static int cmd_set_ts(struct virt_sys *sys, char *cmd, int len)
-{
-	sys->print_ts = 1;
-	return 0;
-}
-
-static struct cpcmd cmd_tbl_set[] = {
-	{"NOTS",	cmd_set_nots,		NULL},
-	{"TS",		cmd_set_ts,		NULL},
-	{"",		NULL,			NULL},
-};
--- a/sys/cp/cmd_store.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,348 +0,0 @@
-/*
- *!!! STORE STORAGE
- *!! SYNTAX
- *! \cbstart
- *! \tok{\sc STOre} \tok{\sc STOrage} <address> <value>
- *! \cbend
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Sets a word in guest's storage at address to value
- */
-static int cmd_store_storage(struct virt_sys *sys, char *cmd, int len)
-{
-	int ret;
-	u64 guest_addr, host_addr;
-	u64 val = 0;
-
-	cmd = parse_addrspec(&guest_addr, NULL, cmd);
-	if (IS_ERR(cmd)) {
-		con_printf(sys->con, "STORE: Invalid addr-spec\n");
-		return PTR_ERR(cmd);
-	}
-
-	/* consume any extra whitespace */
-	cmd = __consume_ws(cmd);
-
-	/* get the value */
-	cmd = __extract_hex(cmd, &val);
-	if (IS_ERR(cmd))
-		return PTR_ERR(cmd);
-
-	/*
-	 * round down to the nearest word
-	 */
-	guest_addr &= ~((u64) 3ULL);
-
-	/* walk the page tables to find the real page frame */
-	ret = virt2phy_current(guest_addr, &host_addr);
-	if (ret) {
-		con_printf(sys->con, "STORE: Specified address is not part of "
-			   "guest configuration\n");
-		return ret;
-	}
-
-	*((u32*) host_addr) = (u32) val;
-
-	con_printf(sys->con, "Store complete.\n");
-
-	return 0;
-}
-
-/*
- *!!! STORE GPR
- *!! SYNTAX
- *! \tok{\sc STOre} \tok{\sc Gpr} <gpr> <value>
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Sets a guest's general purpose register to the specified value
- */
-static int cmd_store_gpr(struct virt_sys *sys, char *cmd, int len)
-{
-	u64 *ptr = (u64*) &sys->task->cpu->regs.gpr;
-	u64 val, gpr;
-
-	cmd = __extract_dec(cmd, &gpr);
-	if (IS_ERR(cmd))
-		return PTR_ERR(cmd);
-	if (gpr > 15)
-		return -EINVAL;
-
-	cmd = __consume_ws(cmd);
-
-	cmd = __extract_hex(cmd, &val);
-	if (IS_ERR(cmd))
-		return PTR_ERR(cmd);
-
-	ptr[gpr] = val;
-
-	con_printf(sys->con, "Store complete.\n");
-
-	return 0;
-}
-
-/*
- *!!! STORE FPR
- *!! SYNTAX
- *! \tok{\sc STOre} \tok{\sc Fpr} <fpr> <value>
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Sets a guest's floating point register to the specified value
- */
-static int cmd_store_fpr(struct virt_sys *sys, char *cmd, int len)
-{
-	u64 *ptr = (u64*) &sys->task->cpu->regs.fpr;
-	u64 val, fpr;
-
-	cmd = __extract_dec(cmd, &fpr);
-	if (IS_ERR(cmd))
-		return PTR_ERR(cmd);
-	if (fpr > 15)
-		return -EINVAL;
-
-	cmd = __consume_ws(cmd);
-
-	cmd = __extract_hex(cmd, &val);
-	if (IS_ERR(cmd))
-		return PTR_ERR(cmd);
-
-	ptr[fpr] = val;
-
-	con_printf(sys->con, "Store complete.\n");
-
-	return 0;
-}
-
-/*
- *!!! STORE FPCR
- *!! SYNTAX
- *! \tok{\sc STOre} \tok{\sc FPCR} <value>
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Sets a guest's floating point control register to the specified value
- */
-static int cmd_store_fpcr(struct virt_sys *sys, char *cmd, int len)
-{
-	u64 val;
-
-	cmd = __extract_hex(cmd, &val);
-	if (IS_ERR(cmd))
-		return PTR_ERR(cmd);
-	if (val > 0xffffffffULL)
-		return -EINVAL;
-
-	sys->task->cpu->regs.fpcr = (u32) val;
-
-	con_printf(sys->con, "Store complete.\n");
-
-	return 0;
-}
-
-/*
- *!!! STORE CR
- *!! SYNTAX
- *! \tok{\sc STOre} \tok{\sc Cr} <cr> <value>
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Sets a guest's control register to the specified value
- */
-static int cmd_store_cr(struct virt_sys *sys, char *cmd, int len)
-{
-	u64 *ptr = (u64*) &sys->task->cpu->sie_cb.gcr;
-	u64 val, cr;
-
-	cmd = __extract_dec(cmd, &cr);
-	if (IS_ERR(cmd))
-		return PTR_ERR(cmd);
-	if (cr > 15)
-		return -EINVAL;
-
-	cmd = __consume_ws(cmd);
-
-	cmd = __extract_hex(cmd, &val);
-	if (IS_ERR(cmd))
-		return PTR_ERR(cmd);
-
-	ptr[cr] = val;
-
-	con_printf(sys->con, "Store complete.\n");
-
-	return 0;
-}
-
-/*
- *!!! STORE AR
- *!! SYNTAX
- *! \tok{\sc STOre} \tok{\sc Ar} <ar> <value>
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Sets a guest's access register to the specified value
- */
-static int cmd_store_ar(struct virt_sys *sys, char *cmd, int len)
-{
-	u32 *ptr = (u32*) &sys->task->cpu->regs.ar;
-	u64 val, ar;
-
-	cmd = __extract_dec(cmd, &ar);
-	if (IS_ERR(cmd))
-		return PTR_ERR(cmd);
-	if (ar > 15)
-		return -EINVAL;
-
-	cmd = __consume_ws(cmd);
-
-	cmd = __extract_hex(cmd, &val);
-	if (IS_ERR(cmd))
-		return PTR_ERR(cmd);
-	if (val > 0xffffffffULL)
-		return -EINVAL;
-
-	ptr[ar] = val;
-
-	con_printf(sys->con, "Store complete.\n");
-
-	return 0;
-}
-
-/*
- *!!! STORE PSW
- *!! SYNTAX
- *! \cbstart
- *! \tok{\sc STOre} \tok{\sc PSW}
- *!     \begin{stack} \\
- *!       \begin{stack} \\
- *!         \begin{stack} \\ <hexword1>
- *!         \end{stack} <hexword2>
- *!       \end{stack} <hexword3>
- *!     \end{stack}
- *! <hexword4>
- *! \cbend
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! \cbstart
- *! Alters all or a part of the PSW.
- *! \cbend
- *!! OPERANDS
- *! \cbstart
- *! \item[hexword...]
- *!   \textbf{For an ESA/390 guest:}
- *!
- *!   Alters all or part of the PSW with the data specified in hexword1
- *!   and hexword2.  If only hexword2 is specified, it is stored to PSW bits
- *!   32-63.  If hexword3 and hexword4 are specified, hexword3 is stored to
- *!   PSW bits 0-31, and hexword4 to PSW bits 32-63.
- *!
- *!   If more than two values are specified, the PSW remains unchanged and an
- *!   message indicating an error is printed.
- *!
- *!   \textbf{For a z/Architecture guest:}
- *!
- *!   If only one hexword4 is specified, PSW bits 96-127 are set to it.
- *!
- *!   If hexword3 and hexword4 are specified, PSW bits 64-95 are set to
- *!   hexword3, and bits 96-127 are set to hexword4.
- *!
- *!   If hexword2, hexword3, and hexword4 are specified, PSW bits 32-63 are
- *!   set to hexword2, bits 64-95 are set to hexword3, and bits 96-127 are
- *!   set to hexword4.
- *!
- *!   If hexword1, hexword2, hexword3, and hexword4 are specified, PSW bits
- *!   0-31 are set to hexword1, bits 32-63 are set to hexword2, bits 64-95
- *!   are set to hexword3, and bits 96-127 are set to hexword4.
- *! \cbend
- *!! SDNAREPO
- */
-static int cmd_store_psw(struct virt_sys *sys, char *cmd, int len)
-{
-	u32 *ptr = (u32*) &sys->task->cpu->sie_cb.gpsw;
-
-	u64 new_words[4] = {0, 0, 0, 0};
-	int cnt;
-
-	for (cnt=0; cnt<4; cnt++) {
-		cmd = __extract_hex(cmd, &new_words[cnt]);
-		if (IS_ERR(cmd))
-			break;
-
-		cmd = __consume_ws(cmd);
-	}
-
-	if (!cnt)
-		return -EINVAL;
-
-	if (!VCPU_ZARCH(sys->task->cpu)) {
-		/* ESA/390 mode */
-		if (cnt > 2) {
-			con_printf(sys->con, "STORE: ERROR ESA/390 PSW USES ONLY TWO WORDS\n");
-			return -EINVAL;
-		}
-
-		/*
-		 * This is a simple "hack" to make the stores go into the
-		 * right place.  If he had a single word, we want it to go
-		 * the the second word of the 16-byte PSW, not the 4th.
-		 * Similarly, if we had two words, we want them to go into
-		 * the first and second words of the 16-byte PSW.
-		 */
-		cnt += 2;
-	}
-
-	switch(cnt) {
-		case 4:
-			ptr[0] = (u32) new_words[0];
-			ptr[1] = (u32) new_words[1];
-			ptr[2] = (u32) new_words[2];
-			ptr[3] = (u32) new_words[3];
-			break;
-		case 3:
-			ptr[1] = (u32) new_words[0];
-			ptr[2] = (u32) new_words[1];
-			ptr[3] = (u32) new_words[2];
-			break;
-		case 2:
-			ptr[2] = (u32) new_words[0];
-			ptr[3] = (u32) new_words[1];
-			break;
-		case 1:
-			ptr[3] = (u32) new_words[0];
-			break;
-		case 0:
-			return -EINVAL;
-	}
-
-	con_printf(sys->con, "Store complete.\n");
-	return 0;
-}
-
-static struct cpcmd cmd_tbl_store[] = {
-	{"AR",		cmd_store_ar,		NULL},
-	{"A",		cmd_store_ar,		NULL},
-
-	{"CR",		cmd_store_cr,		NULL},
-	{"C",		cmd_store_cr,		NULL},
-
-	{"FPCR",	cmd_store_fpcr,		NULL},
-
-	{"FPR",		cmd_store_fpr,		NULL},
-	{"FP",		cmd_store_fpr,		NULL},
-	{"F",		cmd_store_fpr,		NULL},
-
-	{"GPR",		cmd_store_gpr,		NULL},
-	{"GP",		cmd_store_gpr,		NULL},
-	{"G",		cmd_store_gpr,		NULL},
-
-	{"PSW",		cmd_store_psw,		NULL},
-
-	{"STORAGE",	cmd_store_storage,	NULL},
-	{"STORAG",	cmd_store_storage,	NULL},
-	{"STORA",	cmd_store_storage,	NULL},
-	{"STOR",	cmd_store_storage,	NULL},
-	{"STO",		cmd_store_storage,	NULL},
-	{"",		NULL,			NULL},
-};
--- a/sys/cp/cmd_system.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-extern u32 GUEST_IPL_CODE[];
-extern u32 GUEST_IPL_REGSAVE[];
-
-/*
- *!!! IPL
- *!! SYNTAX
- *! \tok{\sc IPL} <vdev>
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Perform a ...
- *!! NOTES
- *! \item Not yet implemented.
- *!! SETON
- */
-static int cmd_ipl(struct virt_sys *sys, char *cmd, int len)
-{
-	struct virt_device *vdev;
-	u64 vdevnum = 0;
-	u64 host_addr;
-	int bytes;
-	int ret;
-	int i;
-
-	/* get IPL vdev # */
-	cmd = __extract_hex(cmd, &vdevnum);
-	if (IS_ERR(cmd))
-		return PTR_ERR(cmd);
-
-	/* device numbers are 16-bits */
-	if (vdevnum & ~0xffff)
-		return -EINVAL;
-
-	/* find the virtual device */
-
-	list_for_each_entry(vdev, &sys->virt_devs, devices)
-		if (vdev->pmcw.dev_num == (u16) vdevnum)
-			goto found;
-
-	return -EINVAL; /* device not found */
-
-found:
-	/*
-	 * alright, we got the device... now set up IPL helper
-	 */
-
-	bytes = sizeof(u32)*(GUEST_IPL_REGSAVE-GUEST_IPL_CODE);
-
-	con_printf(sys->con, "WARNING: IPL command is work-in-progress\n");
-
-	/*
-	 * FIXME: this should be conditional based whether or not we were
-	 * told to clear
-	 */
-	guest_load_normal(sys);
-
-	sys->task->cpu->state = GUEST_LOAD;
-
-	ret = virt2phy_current(GUEST_IPL_BASE, &host_addr);
-	if (ret)
-		goto fail;
-
-	/* we can't go over a page! */
-	BUG_ON((bytes+(16*32)) > PAGE_SIZE);
-
-	/* copy the helper into the guest storage */
-	memcpy((void*) host_addr, GUEST_IPL_CODE, bytes);
-
-	/* save the current guest regs */
-	for (i=0; i<16; i++) {
-		u32 *ptr = (u32*) ((u8*) host_addr + bytes);
-
-		ptr[i] = (u32) sys->task->cpu->regs.gpr[i];
-	}
-
-	sys->task->cpu->regs.gpr[1]  = vdev->sch;
-	sys->task->cpu->regs.gpr[2]  = vdev->pmcw.dev_num;
-	sys->task->cpu->regs.gpr[12] = GUEST_IPL_BASE;
-
-	*((u64*) &sys->task->cpu->sie_cb.gpsw) = 0x0008000080000000ULL |
-						 GUEST_IPL_BASE;
-
-	sys->task->cpu->state = GUEST_STOPPED;
-
-	con_printf(sys->con, "GUEST IPL HELPER LOADED; ENTERED STOPPED STATE\n");
-
-	return 0;
-
-fail:
-	sys->task->cpu->state = GUEST_STOPPED;
-	return ret;
-}
-
-/*!!! SYSTEM CLEAR
- *!! SYNTAX
- *! \tok{\sc SYStem} \tok{\sc CLEAR}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Identical to reset-clear button on a real mainframe.
- *
- *!!! SYSTEM RESET
- *!p >>--SYSTEM--RESET-------------------------------------------------------------><
- *!! SYNTAX
- *! \tok{\sc SYStem} \tok{\sc RESET}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Identical to reset-normal button on a real mainframe.
- *
- *!!! SYSTEM RESTART
- *!! SYNTAX
- *! \tok{\sc SYStem} \tok{\sc RESTART}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Perform a restart operation.
- *!! NOTES
- *! \item Not yet implemented.
- *!! SETON
- *
- *!!! SYSTEM STORE
- *!! SYNTAX
- *! \tok{\sc SYStem} \tok{\sc STORE}
- *!! XATNYS
- *!! AUTH G
- *!! PURPOSE
- *! Perform a ...
- *!! NOTES
- *! \item Not yet implemented.
- *!! SETON
- */
-static int cmd_system(struct virt_sys *sys, char *cmd, int len)
-{
-	if (!strcasecmp(cmd, "CLEAR")) {
-		guest_system_reset_clear(sys);
-		con_printf(sys->con, "STORAGE CLEARED - SYSTEM RESET\n");
-	} else if (!strcasecmp(cmd, "RESET")) {
-		guest_system_reset_normal(sys);
-		con_printf(sys->con, "SYSTEM RESET\n");
-	} else if (!strcasecmp(cmd, "RESTART")) {
-		con_printf(sys->con, "SYSTEM RESTART is not yet supported\n");
-	} else if (!strcasecmp(cmd, "STORE")) {
-		con_printf(sys->con, "SYSTEM STORE is not yet supported\n");
-	} else
-		con_printf(sys->con, "SYSTEM: Unknown variable '%s'\n", cmd);
-
-	return 0;
-}
--- a/sys/cp/cmds.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,170 +0,0 @@
-#include <directory.h>
-#include <vdevice.h>
-#include <dat.h>
-#include <mm.h>
-#include <sched.h>
-#include <disassm.h>
-#include <cp.h>
-#include <cpu.h>
-#include <vsprintf.h>
-
-struct cpcmd {
-	const char name[CP_CMD_MAX_LEN];
-
-	/* handle function pointer */
-	int (*fnx)(struct virt_sys *sys, char *cmd, int len);
-
-	/* sub-command handler table */
-	struct cpcmd *sub;
-};
-
-/*
- * Map a device type to a nice to display name
- */
-static char* type2name(u16 type)
-{
-	switch (type) {
-		case 0x1403:	return "PRT";
-		case 0x1732:	return "OSA";
-		case 0x3088:	return "CTCA";
-		case 0x3215:	return "CONS";
-		case 0x3278:	return "GRAF";
-		case 0x3505:	return "RDR";
-		case 0x3525:	return "PUN";
-
-		/* various dasds */
-		case 0x3390:
-		case 0x9336:	return "DASD";
-
-		/* various tape drives */
-		case 0x3480:
-		case 0x3490:
-		case 0x3590:	return "TAPE";
-
-		default:	return "????";
-	}
-}
-
-/*
- * We use includes here to avoid namespace polution with all the sub-command
- * handler functions
- */
-#include "cmd_helpers.c"
-#include "cmd_beginstop.c"
-#include "cmd_display.c"
-#include "cmd_enable.c"
-#include "cmd_system.c"
-#include "cmd_query.c"
-#include "cmd_store.c"
-#include "cmd_logon.c"
-#include "cmd_set.c"
-
-static struct cpcmd commands[] = {
-	{"BEGIN",	cmd_begin,		NULL},
-	{"BEGI",	cmd_begin,		NULL},
-	{"BEG",		cmd_begin,		NULL},
-	{"BE",		cmd_begin,		NULL},
-
-	{"DISPLAY",	NULL,			cmd_tbl_display},
-	{"DISPLA",	NULL,			cmd_tbl_display},
-	{"DISPL",	NULL,			cmd_tbl_display},
-	{"DISP",	NULL,			cmd_tbl_display},
-	{"DIS",		NULL,			cmd_tbl_display},
-	{"DI",		NULL,			cmd_tbl_display},
-	{"D",		NULL,			cmd_tbl_display},
-
-	{"ENABLE",	cmd_enable,		NULL},
-	{"ENABL",	cmd_enable,		NULL},
-	{"ENAB",	cmd_enable,		NULL},
-	{"ENA",		cmd_enable,		NULL},
-
-	{"IPL",		cmd_ipl,		NULL},
-	{"IP",		cmd_ipl,		NULL},
-	{"I",		cmd_ipl,		NULL},
-
-	{"LOGON",	cmd_logon_fail,		NULL},
-	{"LOGO",	cmd_logon_fail,		NULL},
-	{"LOG",		cmd_logon_fail,		NULL},
-	{"LO",		cmd_logon_fail,		NULL},
-	{"L",		cmd_logon_fail,		NULL},
-
-	{"QUERY",	NULL,			cmd_tbl_query},
-	{"QUER",	NULL,			cmd_tbl_query},
-	{"QUE",		NULL,			cmd_tbl_query},
-	{"QU",		NULL,			cmd_tbl_query},
-	{"Q",		NULL,			cmd_tbl_query},
-
-	{"SET",		NULL,			cmd_tbl_set},
-
-	{"STOP",	cmd_stop,		NULL},
-
-	{"STORE",	NULL,			cmd_tbl_store},
-	{"STOR",	NULL,			cmd_tbl_store},
-	{"STO",		NULL,			cmd_tbl_store},
-
-	{"SYSTEM",	cmd_system,		NULL},
-	{"SYSTE",	cmd_system,		NULL},
-	{"SYST",	cmd_system,		NULL},
-	{"SYS",		cmd_system,		NULL},
-	{"",		NULL,			NULL},
-};
-
-static struct cpcmd logon_commands[] = {
-	{"LOGON",	cmd_logon,		NULL},
-	{"LOGO",	cmd_logon,		NULL},
-	{"LOG",		cmd_logon,		NULL},
-	{"LO",		cmd_logon,		NULL},
-	{"L",		cmd_logon,		NULL},
-	{"",		NULL,			NULL},
-};
-
-static int __invoke_cp_cmd(struct cpcmd *t, struct virt_sys *sys, char *cmd, int len)
-{
-	int i, ret;
-
-	for(i=0; t[i].name[0]; i++) {
-		const char *inp = cmd, *exp = t[i].name;
-		int match_len = 0;
-
-		while(*inp && *exp && (match_len < len) && (toupper(*inp) == *exp)) {
-			match_len++;
-			inp++;
-			exp++;
-		}
-
-		/* doesn't match */
-		if ((match_len != strnlen(t[i].name, CP_CMD_MAX_LEN)) ||
-		    (!isspace(*inp) && *inp))
-			continue;
-
-		/*
-		 * the next char in the input is...
-		 */
-		while((cmd[match_len] == ' ' || cmd[match_len] == '\t') &&
-		      (match_len < len))
-			/*
-			 * command was given arguments - skip over the
-			 * delimiting space
-			 */
-			match_len++;
-
-		if (t[i].sub) {
-			ret = __invoke_cp_cmd(t[i].sub, sys, cmd + match_len, len - match_len);
-			return (ret == -ENOENT) ? -ESUBENOENT : ret;
-		}
-
-		return t[i].fnx(sys, cmd + match_len, len - match_len);
-	}
-
-	return -ENOENT;
-}
-
-int invoke_cp_cmd(struct virt_sys *sys, char *cmd, int len)
-{
-	return __invoke_cp_cmd(commands, sys, cmd, len);
-}
-
-int invoke_cp_logon(struct console *con, char *cmd, int len)
-{
-	return __invoke_cp_cmd(logon_commands, (struct virt_sys*) con, cmd, len);
-}
--- a/sys/cp/directory.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-#include <errno.h>
-#include <directory.h>
-
-#include "directory_structs.c"
-
-struct user *find_user_by_id(char *userid)
-{
-	struct user *u;
-
-	if (!userid)
-		return ERR_PTR(-ENOENT);
-
-	u = directory;
-
-	for (; u->userid; u++)
-		if (!strcasecmp(u->userid, userid))
-			return u;
-
-	return ERR_PTR(-ENOENT);
-}
--- a/sys/cp/disassm.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1091 +0,0 @@
-#include <disassm.h>
-#include <vsprintf.h>
-
-static struct disassm_instruction l2_01[256] = {	/* 01xx */
-	DA_INST		(0x01, E, PR),
-	DA_INST		(0x02, E, UPT),
-	DA_INST		(0x04, E, PTFF),
-	DA_INST		(0x07, E, SCKPF),
-	DA_INST		(0x0A, E, PFPO),
-	DA_INST		(0x0B, E, TAM),
-	DA_INST		(0x0C, E, SAM24),
-	DA_INST		(0x0D, E, SAM31),
-	DA_INST		(0x0E, E, SAM64),
-	DA_INST		(0xFF, E, TRAP2),
-};
-
-static struct disassm_instruction l2_a5[16] = {		/* A5x */
-	DA_INST		(0x0,  RI1, IIHH),
-	DA_INST		(0x1,  RI1, IIHL),
-	DA_INST		(0x2,  RI1, IILH),
-	DA_INST		(0x3,  RI1, IILL),
-	DA_INST		(0x4,  RI1, NIHH),
-	DA_INST		(0x5,  RI1, NIHL),
-	DA_INST		(0x6,  RI1, NILH),
-	DA_INST		(0x7,  RI1, NILL),
-	DA_INST		(0x8,  RI1, OIHH),
-	DA_INST		(0x9,  RI1, OIHL),
-	DA_INST		(0xA,  RI1, OILH),
-	DA_INST		(0xB,  RI1, OILL),
-	DA_INST		(0xC,  RI1, LLIHH),
-	DA_INST		(0xD,  RI1, LLIHL),
-	DA_INST		(0xE,  RI1, LLILH),
-	DA_INST		(0xF,  RI1, LLILL),
-};
-
-static struct disassm_instruction l2_a7[16] = {		/* A7x */
-	DA_INST		(0x0,  RI1, TMLH),
-	DA_INST		(0x1,  RI1, TMLL),
-	DA_INST		(0x2,  RI1, TMHH),
-	DA_INST		(0x3,  RI1, TMHL),
-	DA_INST		(0x4,  RI2, BRC),
-	DA_INST		(0x5,  RI1, BRAS),
-	DA_INST		(0x6,  RI1, BRCT),
-	DA_INST		(0x7,  RI1, BRCTG),
-	DA_INST		(0x8,  RI1, LHI),
-	DA_INST		(0x9,  RI1, LGHI),
-	DA_INST		(0xA,  RI1, AHI),
-	DA_INST		(0xB,  RI1, AGHI),
-	DA_INST		(0xC,  RI1, MHI),
-	DA_INST		(0xD,  RI1, MGHI),
-	DA_INST		(0xE,  RI1, CHI),
-	DA_INST		(0xF,  RI1, CGHI),
-};
-
-static struct disassm_instruction l2_b2[256] = {	/* B2xx */
-	DA_INST		(0x02, S, STIDP),
-	DA_INST		(0x04, S, SCK),
-	DA_INST		(0x05, S, STCK),
-	DA_INST		(0x06, S, SCKC),
-	DA_INST		(0x07, S, STCKC),
-	DA_INST		(0x08, S, SPT),
-	DA_INST		(0x09, S, STPT),
-	DA_INST		(0x0A, S, SPKA),
-	DA_INST		(0x0B, S, IPK),
-	DA_INST		(0x0D, S, PTLB),
-	DA_INST		(0x10, S, SPX),
-	DA_INST		(0x11, S, STPX),
-	DA_INST		(0x12, S, STAP),
-	DA_INST		(0x14, S, SIE),
-	DA_INST		(0x18, S, PC),
-	DA_INST		(0x19, S, SAC),
-	DA_INST		(0x1A, S, CFC),
-	DA_INST		(0x21, RRE, IPTE),
-	DA_INST		(0x22, RRE, IPM),
-	DA_INST		(0x23, RRE, IVSK),
-	DA_INST		(0x24, RRE, IAC),
-	DA_INST		(0x25, RRE, SSAR),
-	DA_INST		(0x26, RRE, EPAR),
-	DA_INST		(0x27, RRE, ESAR),
-	DA_INST		(0x28, RRE, PT),
-	DA_INST		(0x29, RRE, ISKE),
-	DA_INST		(0x2A, RRE, RRBE),
-	DA_INST		(0x2B, RRF2, SSKE),
-	DA_INST		(0x2C, RRE, TB),
-	DA_INST		(0x2D, RRE, DXR),
-	DA_INST		(0x2E, RRE, PGIN),
-	DA_INST		(0x2F, RRE, PGOUT),
-	DA_INST		(0x30, S, CSCH),
-	DA_INST		(0x31, S, HSCH),
-	DA_INST		(0x32, S, MSCH),
-	DA_INST		(0x33, S, SSCH),
-	DA_INST		(0x34, S, STSCH),
-	DA_INST		(0x35, S, TSCH),
-	DA_INST		(0x36, S, TPI),
-	DA_INST		(0x37, S, SAL),
-	DA_INST		(0x38, S, RSCH),
-	DA_INST		(0x39, S, STCRW),
-	DA_INST		(0x3A, S, STCPS),
-	DA_INST		(0x3B, S, RCHP),
-	DA_INST		(0x3D, S, SCHM),
-	DA_INST		(0x40, RRE, BAKR),
-	DA_INST		(0x41, RRE, CKSM),
-	DA_INST		(0x44, RRE, SQDR),
-	DA_INST		(0x45, RRE, SQER),
-	DA_INST		(0x46, RRE, STURA),
-	DA_INST		(0x47, RRE, MSTA),
-	DA_INST		(0x48, RRE, PALB),
-	DA_INST		(0x49, RRE, EREG),
-	DA_INST		(0x4A, RRE, ESTA),
-	DA_INST		(0x4B, RRE, LURA),
-	DA_INST		(0x4C, RRE, TAR),
-	DA_INST		(0x4D, RRE, CPYA),
-	DA_INST		(0x4E, RRE, SAR),
-	DA_INST		(0x4F, RRE, EAR),
-	DA_INST		(0x50, RRE, CSP),
-	DA_INST		(0x52, RRE, MSR),
-	DA_INST		(0x54, RRE, MVPG),
-	DA_INST		(0x55, RRE, MVST),
-	DA_INST		(0x57, RRE, CUSE),
-	DA_INST		(0x58, RRE, BSG),
-	DA_INST		(0x5A, RRE, BSA),
-	DA_INST		(0x5D, RRE, CLST),
-	DA_INST		(0x5E, RRE, SRST),
-	DA_INST		(0x63, RRE, CMPSC),
-	DA_INST		(0x76, S, XSCH),
-	DA_INST		(0x77, S, RP),
-	DA_INST		(0x78, S, STCKE),
-	DA_INST		(0x79, S, SACF),
-	DA_INST		(0x7C, S, STCKF),
-	DA_INST		(0x7D, S, STSI),
-	DA_INST		(0x99, S, SRNM),
-	DA_INST		(0x9C, S, STFPC),
-	DA_INST		(0x9D, S, LFPC),
-	DA_INST		(0xA5, RRE, TRE),
-	DA_INST		(0xA6, RRF2, CUUTF),
-	DA_INST		(0xA7, RRF2, CUTFU),
-	DA_INST		(0xB0, S, STFLE),
-	DA_INST		(0xB1, S, STFL),
-	DA_INST		(0xB2, S, LPSWE),
-	DA_INST		(0xB9, S, SRNMT),
-	DA_INST		(0xBD, S, LFAS),
-	DA_INST		(0xFF, S, TRAP4),
-};
-
-static struct disassm_instruction l2_b3[256] = {	/* B3xx */
-	DA_INST		(0x00, RRE, LPEBR),
-	DA_INST		(0x01, RRE, LNEBR),
-	DA_INST		(0x02, RRE, LTEBR),
-	DA_INST		(0x03, RRE, LCEBR),
-	DA_INST		(0x04, RRE, LDEBR),
-	DA_INST		(0x05, RRE, LXDBR),
-	DA_INST		(0x06, RRE, LXEBR),
-	DA_INST		(0x07, RRE, MXDBR),
-	DA_INST		(0x08, RRE, KEBR),
-	DA_INST		(0x09, RRE, CEBR),
-	DA_INST		(0x0A, RRE, AEBR),
-	DA_INST		(0x0B, RRE, SEBR),
-	DA_INST		(0x0C, RRE, MDEBR),
-	DA_INST		(0x0D, RRE, DEBR),
-	DA_INST		(0x0E, RRF1, MAEBR),
-	DA_INST		(0x0F, RRF1, MSEBR),
-	DA_INST		(0x10, RRE, LPDBR),
-	DA_INST		(0x11, RRE, LNDBR),
-	DA_INST		(0x12, RRE, LTDBR),
-	DA_INST		(0x13, RRE, LCDBR),
-	DA_INST		(0x14, RRE, SQEBR),
-	DA_INST		(0x15, RRE, SQDBR),
-	DA_INST		(0x16, RRE, SQXBR),
-	DA_INST		(0x17, RRE, MEEBR),
-	DA_INST		(0x18, RRE, KDBR),
-	DA_INST		(0x19, RRE, CDBR),
-	DA_INST		(0x1A, RRE, ADBR),
-	DA_INST		(0x1B, RRE, SDBR),
-	DA_INST		(0x1C, RRE, MDBR),
-	DA_INST		(0x1D, RRE, DDBR),
-	DA_INST		(0x1E, RRF1, MADBR),
-	DA_INST		(0x1F, RRF1, MSDBR),
-	DA_INST		(0x24, RRE, LDER),
-	DA_INST		(0x25, RRE, LXDR),
-	DA_INST		(0x26, RRE, LXER),
-	DA_INST		(0x2E, RRF1, MAER),
-	DA_INST		(0x2F, RRF1, MSER),
-	DA_INST		(0x36, RRE, SQXR),
-	DA_INST		(0x37, RRE, MEER),
-	DA_INST		(0x38, RRF1, MAYLR),
-	DA_INST		(0x39, RRF1, MYLR),
-	DA_INST		(0x3A, RRF1, MAYR),
-	DA_INST		(0x3B, RRF1, MYR),
-	DA_INST		(0x3C, RRF1, MAYHR),
-	DA_INST		(0x3D, RRF1, MYHR),
-	DA_INST		(0x3E, RRF1, MADR),
-	DA_INST		(0x3F, RRF1, MSDR),
-	DA_INST		(0x40, RRE, LPXBR),
-	DA_INST		(0x41, RRE, LNXBR),
-	DA_INST		(0x42, RRE, LTXBR),
-	DA_INST		(0x43, RRE, LCXBR),
-	DA_INST		(0x44, RRE, LEDBR),
-	DA_INST		(0x45, RRE, LDXBR),
-	DA_INST		(0x46, RRE, LEXBR),
-	DA_INST		(0x47, RRF2, FIXBR),
-	DA_INST		(0x48, RRE, KXBR),
-	DA_INST		(0x49, RRE, CXBR),
-	DA_INST		(0x4A, RRE, AXBR),
-	DA_INST		(0x4B, RRE, SXBR),
-	DA_INST		(0x4C, RRE, MXBR),
-	DA_INST		(0x4D, RRE, DXBR),
-	DA_INST		(0x50, RRF2, TBEDR),
-	DA_INST		(0x51, RRF2, TBDR),
-	DA_INST		(0x53, RRF3, DIEBR),
-	DA_INST		(0x57, RRF2, FIEBR),
-	DA_INST		(0x58, RRE, THDER),
-	DA_INST		(0x59, RRE, THDR),
-	DA_INST		(0x5B, RRF3, DIDBR),
-	DA_INST		(0x5F, RRF2, FIDBR),
-	DA_INST		(0x60, RRE, LPXR),
-	DA_INST		(0x61, RRE, LNXR),
-	DA_INST		(0x62, RRE, LTXR),
-	DA_INST		(0x63, RRE, LCXR),
-	DA_INST		(0x65, RRE, LXR),
-	DA_INST		(0x66, RRE, LEXR),
-	DA_INST		(0x67, RRE, FIXR),
-	DA_INST		(0x69, RRE, CXR),
-	DA_INST		(0x70, RRE, LPDFR),
-	DA_INST		(0x71, RRE, LNDFR),
-	DA_INST		(0x72, RRF1, CPSDR),
-	DA_INST		(0x73, RRE, LCDFR),
-	DA_INST		(0x74, RRE, LZER),
-	DA_INST		(0x75, RRE, LZDR),
-	DA_INST		(0x76, RRE, LZXR),
-	DA_INST		(0x77, RRE, FIER),
-	DA_INST		(0x7F, RRE, FIDR),
-	DA_INST		(0x84, RRE, SFPC),
-	DA_INST		(0x85, RRE, SFASR),
-	DA_INST		(0x8C, RRE, EFPC),
-	DA_INST		(0x94, RRE, CEFBR),
-	DA_INST		(0x95, RRE, CDFBR),
-	DA_INST		(0x96, RRE, CXFBR),
-	DA_INST		(0x98, RRF2, CFEBR),
-	DA_INST		(0x99, RRF2, CFDBR),
-	DA_INST		(0x9A, RRF2, CFXBR),
-	DA_INST		(0xA4, RRE, CEGBR),
-	DA_INST		(0xA5, RRE, CDGBR),
-	DA_INST		(0xA6, RRE, CXGBR),
-	DA_INST		(0xA8, RRF2, CGEBR),
-	DA_INST		(0xA9, RRF2, CGDBR),
-	DA_INST		(0xAA, RRF2, CGXBR),
-	DA_INST		(0xB4, RRE, CEFR),
-	DA_INST		(0xB5, RRE, CDFR),
-	DA_INST		(0xB6, RRE, CXFR),
-	DA_INST		(0xB8, RRF2, CFER),
-	DA_INST		(0xB9, RRF2, CFDR),
-	DA_INST		(0xBA, RRF2, CFXR),
-	DA_INST		(0xC1, RRE, LDGR),
-	DA_INST		(0xC4, RRE, CEGR),
-	DA_INST		(0xC5, RRE, CDGR),
-	DA_INST		(0xC6, RRE, CXGR),
-	DA_INST		(0xC8, RRF2, CGER),
-	DA_INST		(0xC9, RRF2, CGDR),
-	DA_INST		(0xCA, RRF2, CGXR),
-	DA_INST		(0xCD, RRE, LGDR),
-	DA_INST		(0xD0, RRR, MDTR),
-	DA_INST		(0xD1, RRR, DDTR),
-	DA_INST		(0xD2, RRR, ADTR),
-	DA_INST		(0xD3, RRR, SDTR),
-	DA_INST		(0xD4, RRF3, LDETR),
-	DA_INST		(0xD5, RRF3, LEDTR),
-	DA_INST		(0xD6, RRE, LTDTR),
-	DA_INST		(0xD7, RRF3, FIDTR),
-	DA_INST		(0xD8, RRR, MXTR),
-	DA_INST		(0xD9, RRR, DXTR),
-	DA_INST		(0xDA, RRR, AXTR),
-	DA_INST		(0xDB, RRR, SXTR),
-	DA_INST		(0xDC, RRF3, LXDTR),
-	DA_INST		(0xDD, RRF3, LDXTR),
-	DA_INST		(0xDE, RRE, LTXTR),
-	DA_INST		(0xDF, RRF3, FIXTR),
-	DA_INST		(0xE0, RRE, KDTR),
-	DA_INST		(0xE1, RRF2, CGDTR),
-	DA_INST		(0xE2, RRE, CUDTR),
-	DA_INST		(0xE3, RRF3, CSDTR),
-	DA_INST		(0xE4, RRE, CDTR),
-	DA_INST		(0xE5, RRE, EEDTR),
-	DA_INST		(0xE7, RRE, ESDTR),
-	DA_INST		(0xE8, RRE, KXTR),
-	DA_INST		(0xE9, RRF2, CGXTR),
-	DA_INST		(0xEA, RRE, CUXTR),
-	DA_INST		(0xEB, RRF3, CSXTR),
-	DA_INST		(0xEC, RRE, CXTR),
-	DA_INST		(0xED, RRE, EEXTR),
-	DA_INST		(0xEF, RRE, ESXTR),
-	DA_INST		(0xF1, RRE, CDGTR),
-	DA_INST		(0xF2, RRE, CDUTR),
-	DA_INST		(0xF3, RRE, CDSTR),
-	DA_INST		(0xF4, RRE, CEDTR),
-	DA_INST		(0xF5, RRF3, QADTR),
-	DA_INST		(0xF6, RRF3, IEDTR),
-	DA_INST		(0xF7, RRF3, RRDTR),
-	DA_INST		(0xF9, RRE, CXGTR),
-	DA_INST		(0xFA, RRE, CXUTR),
-	DA_INST		(0xFB, RRE, CXSTR),
-	DA_INST		(0xFC, RRE, CEXTR),
-	DA_INST		(0xFD, RRF3, QAXTR),
-	DA_INST		(0xFE, RRF3, IEXTR),
-	DA_INST		(0xFF, RRF3, RRXTR),
-};
-
-static struct disassm_instruction l2_b9[256] = {	/* B9xx */
-	DA_INST		(0x00, RRE, LPGR),
-	DA_INST		(0x01, RRE, LNGR),
-	DA_INST		(0x02, RRE, LTGR),
-	DA_INST		(0x03, RRE, LCGR),
-	DA_INST		(0x04, RRE, LGR),
-	DA_INST		(0x05, RRE, LURAG),
-	DA_INST		(0x06, RRE, LGBR),
-	DA_INST		(0x07, RRE, LGHR),
-	DA_INST		(0x08, RRE, AGR),
-	DA_INST		(0x09, RRE, SGR),
-	DA_INST		(0x0A, RRE, ALGR),
-	DA_INST		(0x0B, RRE, SLGR),
-	DA_INST		(0x0C, RRE, MSGR),
-	DA_INST		(0x0D, RRE, DSGR),
-	DA_INST		(0x0E, RRE, EREGG),
-	DA_INST		(0x0F, RRE, LRVGR),
-	DA_INST		(0x10, RRE, LPGFR),
-	DA_INST		(0x11, RRE, LNGFR),
-	DA_INST		(0x12, RRE, LTGFR),
-	DA_INST		(0x13, RRE, LCGFR),
-	DA_INST		(0x14, RRE, LGFR),
-	DA_INST		(0x16, RRE, LLGFR),
-	DA_INST		(0x17, RRE, LLGTR),
-	DA_INST		(0x18, RRE, AGFR),
-	DA_INST		(0x19, RRE, SGFR),
-	DA_INST		(0x1A, RRE, ALGFR),
-	DA_INST		(0x1B, RRE, SLGFR),
-	DA_INST		(0x1C, RRE, MSGFR),
-	DA_INST		(0x1D, RRE, DSGFR),
-	DA_INST		(0x1E, RRE, KMAC),
-	DA_INST		(0x1F, RRE, LRVR),
-	DA_INST		(0x20, RRE, CGR),
-	DA_INST		(0x21, RRE, CLGR),
-	DA_INST		(0x25, RRE, STURG),
-	DA_INST		(0x26, RRE, LBR),
-	DA_INST		(0x27, RRE, LHR),
-	DA_INST		(0x2E, RRE, KM),
-	DA_INST		(0x2F, RRE, KMC),
-	DA_INST		(0x30, RRE, CGFR),
-	DA_INST		(0x31, RRE, CLGFR),
-	DA_INST		(0x3E, RRE, KIMD),
-	DA_INST		(0x3F, RRE, KLMD),
-	DA_INST		(0x46, RRE, BCTGR),
-	DA_INST		(0x60, RRF2, CGRT),
-	DA_INST		(0x61, RRF2, CLGRT),
-	DA_INST		(0x72, RRF2, CRT),
-	DA_INST		(0x73, RRF2, CLRT),
-	DA_INST		(0x80, RRE, NGR),
-	DA_INST		(0x81, RRE, OGR),
-	DA_INST		(0x82, RRE, XGR),
-	DA_INST		(0x83, RRE, FLOGR),
-	DA_INST		(0x84, RRE, LLGCR),
-	DA_INST		(0x85, RRE, LLGHR),
-	DA_INST		(0x86, RRE, MLGR),
-	DA_INST		(0x87, RRE, DLGR),
-	DA_INST		(0x88, RRE, ALCGR),
-	DA_INST		(0x89, RRE, SLBGR),
-	DA_INST		(0x8A, RRE, CSPG),
-	DA_INST		(0x8D, RRE, EPSW),
-	DA_INST		(0x8E, RRF3, IDTE),
-	DA_INST		(0x90, RRF2, TRTT),
-	DA_INST		(0x91, RRF2, TRTO),
-	DA_INST		(0x92, RRF2, TROT),
-	DA_INST		(0x93, RRF2, TROO),
-	DA_INST		(0x94, RRE, LLCR),
-	DA_INST		(0x95, RRE, LLHR),
-	DA_INST		(0x96, RRE, MLR),
-	DA_INST		(0x97, RRE, DLR),
-	DA_INST		(0x98, RRE, ALCR),
-	DA_INST		(0x99, RRE, SLBR),
-	DA_INST		(0x9A, RRE, EPAIR),
-	DA_INST		(0x9B, RRE, ESAIR),
-	DA_INST		(0x9D, RRE, ESEA),
-	DA_INST		(0x9E, RRE, PTI),
-	DA_INST		(0x9F, RRE, SSAIR),
-	DA_INST		(0xA2, RRE, PTF),
-	DA_INST		(0xAA, RRF3, LPTEA),
-	DA_INST		(0xAF, RRE, PFMF),
-	DA_INST		(0xB0, RRF2, CU14),
-	DA_INST		(0xB1, RRF2, CU24),
-	DA_INST		(0xB2, RRE, CU41),
-	DA_INST		(0xB3, RRE, CU42),
-	DA_INST		(0xBD, RRF2, TRTRE),
-	DA_INST		(0xBE, RRE, SRSTU),
-	DA_INST		(0xBF, RRF2, TRTE),
-};
-
-static struct disassm_instruction l2_c0[16] = {		/* C0x */
-	DA_INST		(0x0,  RIL1, LARL),
-	DA_INST		(0x1,  RIL1, LGFI),
-	DA_INST		(0x4,  RIL2, BRCL),
-	DA_INST		(0x5,  RIL1, BRASL),
-	DA_INST		(0x6,  RIL1, XIHF),
-	DA_INST		(0x7,  RIL1, XILF),
-	DA_INST		(0x8,  RIL1, IIHF),
-	DA_INST		(0x9,  RIL1, IILF),
-	DA_INST		(0xA,  RIL1, NIHF),
-	DA_INST		(0xB,  RIL1, NILF),
-	DA_INST		(0xC,  RIL1, OIHF),
-	DA_INST		(0xD,  RIL1, OILF),
-	DA_INST		(0xE,  RIL1, LLIHF),
-	DA_INST		(0xF,  RIL1, LLILF),
-};
-
-static struct disassm_instruction l2_c2[16] = {		/* C2x */
-	DA_INST		(0x0,  RIL1, MSGFI),
-	DA_INST		(0x1,  RIL1, MSFI),
-	DA_INST		(0x4,  RIL1, SLGFI),
-	DA_INST		(0x5,  RIL1, SLFI),
-	DA_INST		(0x8,  RIL1, AGFI),
-	DA_INST		(0x9,  RIL1, AFI),
-	DA_INST		(0xA,  RIL1, ALGFI),
-	DA_INST		(0xB,  RIL1, ALFI),
-	DA_INST		(0xC,  RIL1, CGFI),
-	DA_INST		(0xD,  RIL1, CFI),
-	DA_INST		(0xE,  RIL1, CLGFI),
-	DA_INST		(0xF,  RIL1, CLFI),
-};
-
-static struct disassm_instruction l2_c4[16] = {		/* C4x */
-	DA_INST		(0x2,  RIL1, LLHRL),
-	DA_INST		(0x4,  RIL1, LGHRL),
-	DA_INST		(0x5,  RIL1, LHRL),
-	DA_INST		(0x6,  RIL1, LLGHRL),
-	DA_INST		(0x7,  RIL1, STHRL),
-	DA_INST		(0x8,  RIL1, LGRL),
-	DA_INST		(0xB,  RIL1, STGRL),
-	DA_INST		(0xC,  RIL1, LGFRL),
-	DA_INST		(0xD,  RIL1, LRL),
-	DA_INST		(0xE,  RIL1, LLGFRL),
-	DA_INST		(0xF,  RIL1, STRL),
-};
-
-static struct disassm_instruction l2_c6[16] = {		/* C6x */
-	DA_INST		(0x0,  RIL1, EXRL),
-	DA_INST		(0x2,  RIL2, PFDRL),
-	DA_INST		(0x4,  RIL1, CGHRL),
-	DA_INST		(0x5,  RIL1, CHRL),
-	DA_INST		(0x6,  RIL1, CLGHRL),
-	DA_INST		(0x7,  RIL1, CLHRL),
-	DA_INST		(0x8,  RIL1, CGRL),
-	DA_INST		(0xA,  RIL1, CLGRL),
-	DA_INST		(0xC,  RIL1, CGFRL),
-	DA_INST		(0xD,  RIL1, CRL),
-	DA_INST		(0xE,  RIL1, CLGFRL),
-	DA_INST		(0xF,  RIL1, CLRL),
-};
-
-static struct disassm_instruction l2_c8[16] = {		/* C8x */
-	DA_INST		(0x0,  SSF, MVCOS),
-	DA_INST		(0x1,  SSF, ECTG),
-	DA_INST		(0x2,  SSF, CSST),
-};
-
-static struct disassm_instruction l2_e3[256] = {	/* E3xx */
-	DA_INST		(0x02, RXY, LTG),
-	DA_INST		(0x03, RXY, LRAG),
-	DA_INST		(0x04, RXY, LG),
-	DA_INST		(0x06, RXY, CVBY),
-	DA_INST		(0x08, RXY, AG),
-	DA_INST		(0x09, RXY, SG),
-	DA_INST		(0x0A, RXY, ALG),
-	DA_INST		(0x0B, RXY, SLG),
-	DA_INST		(0x0C, RXY, MSG),
-	DA_INST		(0x0D, RXY, DSG),
-	DA_INST		(0x0E, RXY, CVBG),
-	DA_INST		(0x0F, RXY, LRVG),
-	DA_INST		(0x12, RXY, LT),
-	DA_INST		(0x13, RXY, LRAY),
-	DA_INST		(0x14, RXY, LGF),
-	DA_INST		(0x15, RXY, LGH),
-	DA_INST		(0x16, RXY, LLGF),
-	DA_INST		(0x17, RXY, LLGT),
-	DA_INST		(0x18, RXY, AGF),
-	DA_INST		(0x19, RXY, SGF),
-	DA_INST		(0x1A, RXY, ALGF),
-	DA_INST		(0x1B, RXY, SLGF),
-	DA_INST		(0x1C, RXY, MSGF),
-	DA_INST		(0x1D, RXY, DSGF),
-	DA_INST		(0x1E, RXY, LRV),
-	DA_INST		(0x1F, RXY, LRVH),
-	DA_INST		(0x20, RXY, CG),
-	DA_INST		(0x21, RXY, CLG),
-	DA_INST		(0x24, RXY, STG),
-	DA_INST		(0x26, RXY, CVDY),
-	DA_INST		(0x2E, RXY, CVDG),
-	DA_INST		(0x2F, RXY, STRVG),
-	DA_INST		(0x30, RXY, CGF),
-	DA_INST		(0x31, RXY, CLGF),
-	DA_INST		(0x32, RXY, LTGF),
-	DA_INST		(0x34, RXY, CGH),
-	DA_INST		(0x36, RXY, PFD),
-	DA_INST		(0x3E, RXY, STRV),
-	DA_INST		(0x3F, RXY, STRVH),
-	DA_INST		(0x46, RXY, BCTG),
-	DA_INST		(0x50, RXY, STY),
-	DA_INST		(0x51, RXY, MSY),
-	DA_INST		(0x54, RXY, NY),
-	DA_INST		(0x55, RXY, CLY),
-	DA_INST		(0x56, RXY, OY),
-	DA_INST		(0x57, RXY, XY),
-	DA_INST		(0x58, RXY, LY),
-	DA_INST		(0x59, RXY, CY),
-	DA_INST		(0x5A, RXY, AY),
-	DA_INST		(0x5B, RXY, SY),
-	DA_INST		(0x5C, RXY, MFY),
-	DA_INST		(0x5E, RXY, ALY),
-	DA_INST		(0x5F, RXY, SLY),
-	DA_INST		(0x70, RXY, STHY),
-	DA_INST		(0x71, RXY, LAY),
-	DA_INST		(0x72, RXY, STCY),
-	DA_INST		(0x73, RXY, ICY),
-	DA_INST		(0x75, RXY, LAEY),
-	DA_INST		(0x76, RXY, LB),
-	DA_INST		(0x77, RXY, LGB),
-	DA_INST		(0x78, RXY, LHY),
-	DA_INST		(0x79, RXY, CHY),
-	DA_INST		(0x7A, RXY, AHY),
-	DA_INST		(0x7B, RXY, SHY),
-	DA_INST		(0x7C, RXY, MHY),
-	DA_INST		(0x80, RXY, NG),
-	DA_INST		(0x81, RXY, OG),
-	DA_INST		(0x82, RXY, XG),
-	DA_INST		(0x86, RXY, MLG),
-	DA_INST		(0x87, RXY, DLG),
-	DA_INST		(0x88, RXY, ALCG),
-	DA_INST		(0x89, RXY, SLBG),
-	DA_INST		(0x8E, RXY, STPQ),
-	DA_INST		(0x8F, RXY, LPQ),
-	DA_INST		(0x90, RXY, LLGC),
-	DA_INST		(0x91, RXY, LLGH),
-	DA_INST		(0x94, RXY, LLC),
-	DA_INST		(0x95, RXY, LLH),
-	DA_INST		(0x96, RXY, ML),
-	DA_INST		(0x97, RXY, DL),
-	DA_INST		(0x98, RXY, ALC),
-	DA_INST		(0x99, RXY, SLB),
-};
-
-static struct disassm_instruction l2_e5[256] = {	/* E5xx */
-	DA_INST		(0x00, SSE, LASP),
-	DA_INST		(0x01, SSE, TPROT),
-	DA_INST		(0x02, SSE, STRAG),
-	DA_INST		(0x0E, SSE, MVCSK),
-	DA_INST		(0x0F, SSE, MVCDK),
-	DA_INST		(0x44, SIL, MVHHI),
-	DA_INST		(0x48, SIL, MVGHI),
-	DA_INST		(0x4C, SIL, MVHI),
-	DA_INST		(0x54, SIL, CHHSI),
-	DA_INST		(0x55, SIL, CLHHSI),
-	DA_INST		(0x58, SIL, CGHSI),
-	DA_INST		(0x59, SIL, CLGHSI),
-	DA_INST		(0x5C, SIL, CHSI),
-	DA_INST		(0x5D, SIL, CLFHSI),
-};
-
-static struct disassm_instruction l2_eb[256] = {	/* EBxx */
-	DA_INST		(0x04, RSY1, LMG),
-	DA_INST		(0x0A, RSY1, SRAG),
-	DA_INST		(0x0B, RSY1, SLAG),
-	DA_INST		(0x0C, RSY1, SRLG),
-	DA_INST		(0x0D, RSY1, SLLG),
-	DA_INST		(0x0F, RSY1, TRACG),
-	DA_INST		(0x14, RSY1, CSY),
-	DA_INST		(0x1C, RSY1, RLLG),
-	DA_INST		(0x1D, RSY1, RLL),
-	DA_INST		(0x20, RSY2, CLMH),
-	DA_INST		(0x21, RSY2, CLMY),
-	DA_INST		(0x24, RSY1, STMG),
-	DA_INST		(0x25, RSY1, STCTG),
-	DA_INST		(0x26, RSY1, STMH),
-	DA_INST		(0x2C, RSY2, STCMH),
-	DA_INST		(0x2D, RSY2, STCMY),
-	DA_INST		(0x2F, RSY1, LCTLG),
-	DA_INST		(0x30, RSY1, CSG),
-	DA_INST		(0x31, RSY1, CDSY),
-	DA_INST		(0x3E, RSY1, CDSG),
-	DA_INST		(0x44, RSY1, BXHG),
-	DA_INST		(0x45, RSY1, BXLEG),
-	DA_INST		(0x4C, RSY1, ECAG),
-	DA_INST		(0x51, SIY, TMY),
-	DA_INST		(0x52, SIY, MVIY),
-	DA_INST		(0x54, SIY, NIY),
-	DA_INST		(0x55, SIY, CLIY),
-	DA_INST		(0x56, SIY, OIY),
-	DA_INST		(0x57, SIY, XIY),
-	DA_INST		(0x6A, SIY, ASI),
-	DA_INST		(0x6E, SIY, ALSI),
-	DA_INST		(0x80, RSY2, ICMH),
-	DA_INST		(0x81, RSY2, ICMY),
-	DA_INST		(0x8E, RSY1, MVCLU),
-	DA_INST		(0x8F, RSY1, CLCLU),
-	DA_INST		(0x90, RSY1, STMY),
-	DA_INST		(0x96, RSY1, LMH),
-	DA_INST		(0x98, RSY1, LMY),
-	DA_INST		(0x9A, RSY1, LAMY),
-	DA_INST		(0x9B, RSY1, STAMY),
-	DA_INST		(0xC0, RSL, TP),
-};
-
-static struct disassm_instruction l2_ec[256] = {	/* ECxx */
-	DA_INST		(0x44, RIE, BRXHG),
-	DA_INST		(0x45, RIE, BRXLG),
-	DA_INST		(0x54, RIE, RNSBG),
-	DA_INST		(0x55, RIE, RISBG),
-	DA_INST		(0x56, RIE, ROSBG),
-	DA_INST		(0x57, RIE, RXSBG),
-	DA_INST		(0x64, RIE, CGRJ),
-	DA_INST		(0x65, RIE, CLGRJ),
-	DA_INST		(0x70, RIE, CGIT),
-	DA_INST		(0x71, RIE, CLGIT),
-	DA_INST		(0x72, RIE, CIT),
-	DA_INST		(0x73, RIE, CLFIT),
-	DA_INST		(0x76, RIE, CRJ),
-	DA_INST		(0x77, RIE, CLRJ),
-	DA_INST		(0x7C, RIE, CGIJ),
-	DA_INST		(0x7D, RIE, CLGIJ),
-	DA_INST		(0x7E, RIE, CIJ),
-	DA_INST		(0x7F, RIE, CLIJ),
-	DA_INST		(0xE4, RRS, CGRB),
-	DA_INST		(0xE5, RRS, CLGRB),
-	DA_INST		(0xF6, RRS, CRB),
-	DA_INST		(0xF7, RRS, CLRB),
-	DA_INST		(0xFC, RIS, CGIB),
-	DA_INST		(0xFD, RIS, CLGIB),
-};
-
-static struct disassm_instruction l2_ed[256] = {	/* EDxx */
-	DA_INST		(0x04, RXE, LDEB),
-	DA_INST		(0x05, RXE, LXDB),
-	DA_INST		(0x06, RXE, LXEB),
-	DA_INST		(0x07, RXE, MXDB),
-	DA_INST		(0x08, RXE, KEB),
-	DA_INST		(0x09, RXE, CEB),
-	DA_INST		(0x0A, RXE, AEB),
-	DA_INST		(0x0B, RXE, SEB),
-	DA_INST		(0x0C, RXE, MDEB),
-	DA_INST		(0x0D, RXE, DEB),
-	DA_INST		(0x0E, RXE, MAEB),
-	DA_INST		(0x0F, RXE, MSEB),
-	DA_INST		(0x10, RXE, TCEB),
-	DA_INST		(0x11, RXE, TCDB),
-	DA_INST		(0x12, RXE, TCXB),
-	DA_INST		(0x14, RXE, SQEB),
-	DA_INST		(0x15, RXE, SQDB),
-	DA_INST		(0x17, RXE, MEEB),
-	DA_INST		(0x18, RXE, KDB),
-	DA_INST		(0x19, RXE, CDB),
-	DA_INST		(0x1A, RXE, ADB),
-	DA_INST		(0x1B, RXE, SDB),
-	DA_INST		(0x1C, RXE, MDB),
-	DA_INST		(0x1D, RXE, DDB),
-	DA_INST		(0x1E, RXF, MADB),
-	DA_INST		(0x1F, RXF, MSDB),
-	DA_INST		(0x24, RXE, LDE),
-	DA_INST		(0x25, RXE, LXD),
-	DA_INST		(0x26, RXE, LXE),
-	DA_INST		(0x2E, RXF, MAE),
-	DA_INST		(0x2F, RXF, MSE),
-	DA_INST		(0x34, RXE, SQE),
-	DA_INST		(0x35, RXE, SQD),
-	DA_INST		(0x37, RXE, MEE),
-	DA_INST		(0x38, RXF, MAYL),
-	DA_INST		(0x39, RXF, MYL),
-	DA_INST		(0x3A, RXF, MAY),
-	DA_INST		(0x3B, RXF, MY),
-	DA_INST		(0x3C, RXF, MAYH),
-	DA_INST		(0x3D, RXF, MYH),
-	DA_INST		(0x3E, RXF, MAD),
-	DA_INST		(0x3F, RXF, MSD),
-	DA_INST		(0x40, RXF, SLDT),
-	DA_INST		(0x41, RXF, SRDT),
-	DA_INST		(0x48, RXF, SLXT),
-	DA_INST		(0x49, RXF, SRXT),
-	DA_INST		(0x50, RXE, TDCET),
-	DA_INST		(0x51, RXE, TDGET),
-	DA_INST		(0x54, RXE, TDCDT),
-	DA_INST		(0x55, RXE, TDGDT),
-	DA_INST		(0x58, RXE, TDCXT),
-	DA_INST		(0x59, RXE, TDGXT),
-	DA_INST		(0x64, RXY, LEY),
-	DA_INST		(0x65, RXY, LDY),
-	DA_INST		(0x66, RXY, STEY),
-	DA_INST		(0x67, RXY, STDY),
-};
-
-static struct disassm_instruction l1[256] = {		/* xx */
-	DA_INST_TBL	(0x01, l2_01, 8, 8),
-	DA_INST		(0x04, RR, SPM),
-	DA_INST		(0x05, RR, BALR),
-	DA_INST		(0x06, RR, BCTR),
-	DA_INST		(0x07, RR_MASK, BCR),
-	DA_INST		(0x0A, I, SVC),
-	DA_INST		(0x0B, RR, BSM),
-	DA_INST		(0x0C, RR, BASSM),
-	DA_INST		(0x0D, RR, BASR),
-	DA_INST		(0x0E, RR, MVCL),
-	DA_INST		(0x0F, RR, CLCL),
-	DA_INST		(0x10, RR, LPR),
-	DA_INST		(0x11, RR, LNR),
-	DA_INST		(0x12, RR, LTR),
-	DA_INST		(0x13, RR, LCR),
-	DA_INST		(0x14, RR, NR),
-	DA_INST		(0x15, RR, CLR),
-	DA_INST		(0x16, RR, OR),
-	DA_INST		(0x17, RR, XR),
-	DA_INST		(0x18, RR, LR),
-	DA_INST		(0x19, RR, CR),
-	DA_INST		(0x1A, RR, AR),
-	DA_INST		(0x1B, RR, SR),
-	DA_INST		(0x1C, RR, MR),
-	DA_INST		(0x1D, RR, DR),
-	DA_INST		(0x1E, RR, ALR),
-	DA_INST		(0x1F, RR, SLR),
-	DA_INST		(0x20, RR, LPDR),
-	DA_INST		(0x21, RR, LNDR),
-	DA_INST		(0x22, RR, LTDR),
-	DA_INST		(0x23, RR, LCDR),
-	DA_INST		(0x24, RR, HDR),
-	DA_INST		(0x25, RR, LDXR),
-	DA_INST		(0x26, RR, MXR),
-	DA_INST		(0x27, RR, MXDR),
-	DA_INST		(0x28, RR, LDR),
-	DA_INST		(0x29, RR, CDR),
-	DA_INST		(0x2A, RR, ADR),
-	DA_INST		(0x2B, RR, SDR),
-	DA_INST		(0x2C, RR, MDR),
-	DA_INST		(0x2D, RR, DDR),
-	DA_INST		(0x2E, RR, AWR),
-	DA_INST		(0x2F, RR, SWR),
-	DA_INST		(0x30, RR, LPER),
-	DA_INST		(0x31, RR, LNER),
-	DA_INST		(0x32, RR, LTER),
-	DA_INST		(0x33, RR, LCER),
-	DA_INST		(0x34, RR, HER),
-	DA_INST		(0x35, RR, LEDR),
-	DA_INST		(0x36, RR, AXR),
-	DA_INST		(0x37, RR, SXR),
-	DA_INST		(0x38, RR, LER),
-	DA_INST		(0x39, RR, CER),
-	DA_INST		(0x3A, RR, AER),
-	DA_INST		(0x3B, RR, SER),
-	DA_INST		(0x3C, RR, MDER),
-	DA_INST		(0x3D, RR, DER),
-	DA_INST		(0x3E, RR, AUR),
-	DA_INST		(0x3F, RR, SUR),
-	DA_INST		(0x40, RX, STH),
-	DA_INST		(0x41, RX, LA),
-	DA_INST		(0x42, RX, STC),
-	DA_INST		(0x43, RX, IC),
-	DA_INST		(0x44, RX, EX),
-	DA_INST		(0x45, RX, BAL),
-	DA_INST		(0x46, RX, BCT),
-	DA_INST		(0x47, RX_MASK, BC),
-	DA_INST		(0x48, RX, LH),
-	DA_INST		(0x49, RX, CH),
-	DA_INST		(0x4A, RX, AH),
-	DA_INST		(0x4B, RX, SH),
-	DA_INST		(0x4C, RX, MH),
-	DA_INST		(0x4D, RX, BAS),
-	DA_INST		(0x4E, RX, CVD),
-	DA_INST		(0x4F, RX, CVB),
-	DA_INST		(0x50, RX, ST),
-	DA_INST		(0x51, RX, LAE),
-	DA_INST		(0x54, RX, N),
-	DA_INST		(0x55, RX, CL),
-	DA_INST		(0x56, RX, O),
-	DA_INST		(0x57, RX, X),
-	DA_INST		(0x58, RX, L),
-	DA_INST		(0x59, RX, C),
-	DA_INST		(0x5A, RX, A),
-	DA_INST		(0x5B, RX, S),
-	DA_INST		(0x5C, RX, M),
-	DA_INST		(0x5D, RX, D),
-	DA_INST		(0x5E, RX, AL),
-	DA_INST		(0x5F, RX, SL),
-	DA_INST		(0x60, RX, STD),
-	DA_INST		(0x67, RX, MXD),
-	DA_INST		(0x68, RX, LD),
-	DA_INST		(0x69, RX, CD),
-	DA_INST		(0x6A, RX, AD),
-	DA_INST		(0x6B, RX, SD),
-	DA_INST		(0x6C, RX, MD),
-	DA_INST		(0x6D, RX, DD),
-	DA_INST		(0x6E, RX, AW),
-	DA_INST		(0x6F, RX, SW),
-	DA_INST		(0x70, RX, STE),
-	DA_INST		(0x71, RX, MS),
-	DA_INST		(0x78, RX, LE),
-	DA_INST		(0x79, RX, CE),
-	DA_INST		(0x7A, RX, AE),
-	DA_INST		(0x7B, RX, SE),
-	DA_INST		(0x7C, RX, MDE),
-	DA_INST		(0x7D, RX, DE),
-	DA_INST		(0x7E, RX, AU),
-	DA_INST		(0x7F, RX, SU),
-	DA_INST		(0x80, S, SSM),
-	DA_INST		(0x82, S, LPSW),
-	DA_INST		(0x83, DIAG, DIAG),
-	DA_INST		(0x84, RSI, BRXH),
-	DA_INST		(0x85, RSI, BRXLE),
-	DA_INST		(0x86, RS1, BXH),
-	DA_INST		(0x87, RS1, BXLE),
-	DA_INST		(0x88, RS1, SRL),
-	DA_INST		(0x89, RS1, SLL),
-	DA_INST		(0x8A, RS1, SRA),
-	DA_INST		(0x8B, RS1, SLA),
-	DA_INST		(0x8C, RS1, SRDL),
-	DA_INST		(0x8D, RS1, SLDL),
-	DA_INST		(0x8E, RS1, SRDA),
-	DA_INST		(0x8F, RS1, SLDA),
-	DA_INST		(0x90, RS1, STM),
-	DA_INST		(0x91, SI, TM),
-	DA_INST		(0x92, SI, MVI),
-	DA_INST		(0x93, S, TS),
-	DA_INST		(0x94, SI, NI),
-	DA_INST		(0x95, SI, CLI),
-	DA_INST		(0x96, SI, OI),
-	DA_INST		(0x97, SI, XI),
-	DA_INST		(0x98, RS1, LM),
-	DA_INST		(0x99, RS1, TRACE),
-	DA_INST		(0x9A, RS1, LAM),
-	DA_INST		(0x9B, RS1, STAM),
-	DA_INST_TBL	(0xA5, l2_a5, 4, 12),
-	DA_INST_TBL	(0xA7, l2_a7, 4, 12),
-	DA_INST		(0xA8, RS1, MVCLE),
-	DA_INST		(0xA9, RS1, CLCLE),
-	DA_INST		(0xAC, SI, STNSM),
-	DA_INST		(0xAD, SI, STOSM),
-	DA_INST		(0xAE, RS1, SIGP),
-	DA_INST		(0xAF, SI, MC),
-	DA_INST		(0xB1, RX, LRA),
-	DA_INST_TBL	(0xB2, l2_b2, 8, 8),
-	DA_INST_TBL	(0xB3, l2_b3, 8, 8),
-	DA_INST		(0xB6, RS1, STCTL),
-	DA_INST		(0xB7, RS1, LCTL),
-	DA_INST_TBL	(0xB9, l2_b9, 8, 8),
-	DA_INST		(0xBA, RS1, CS),
-	DA_INST		(0xBB, RS1, CDS),
-	DA_INST		(0xBD, RS2, CLM),
-	DA_INST		(0xBE, RS2, STCM),
-	DA_INST		(0xBF, RS2, ICM),
-	DA_INST_TBL	(0xC0, l2_c0, 4, 12),
-	DA_INST_TBL	(0xC2, l2_c2, 4, 12),
-	DA_INST_TBL	(0xC4, l2_c4, 4, 12),
-	DA_INST_TBL	(0xC6, l2_c6, 4, 12),
-	DA_INST_TBL	(0xC8, l2_c8, 4, 12),
-	DA_INST		(0xD0, SS1, TRTR),
-	DA_INST		(0xD1, SS1, MVN),
-	DA_INST		(0xD2, SS1, MVC),
-	DA_INST		(0xD3, SS1, MVZ),
-	DA_INST		(0xD4, SS1, NC),
-	DA_INST		(0xD5, SS1, CLC),
-	DA_INST		(0xD6, SS1, OC),
-	DA_INST		(0xD7, SS1, XC),
-	DA_INST		(0xD9, SS4, MVCK),
-	DA_INST		(0xDA, SS4, MVCP),
-	DA_INST		(0xDB, SS4, MVCS),
-	DA_INST		(0xDC, SS1, TR),
-	DA_INST		(0xDD, SS1, TRT),
-	DA_INST		(0xDE, SS1, ED),
-	DA_INST		(0xDF, SS1, EDMK),
-	DA_INST		(0xE1, SS1, PKU),
-	DA_INST		(0xE2, SS1, UNPKU),
-	DA_INST_TBL	(0xE3, l2_e3, 8, 40),
-	DA_INST_TBL	(0xE5, l2_e5, 8, 8),
-	DA_INST		(0xE8, SS1, MVCIN),
-	DA_INST		(0xE9, SS1, PKA),
-	DA_INST		(0xEA, SS1, UNPKA),
-	DA_INST_TBL	(0xEB, l2_eb, 8, 40),
-	DA_INST_TBL	(0xEC, l2_ec, 8, 40),
-	DA_INST_TBL	(0xED, l2_ed, 8, 40),
-	DA_INST		(0xEE, SS5, PLO),
-	DA_INST		(0xEF, SS5, LMD),
-	DA_INST		(0xF0, SS3, SRP),
-	DA_INST		(0xF1, SS2, MVO),
-	DA_INST		(0xF2, SS2, PACK),
-	DA_INST		(0xF3, SS2, UNPK),
-	DA_INST		(0xF8, SS2, ZAP),
-	DA_INST		(0xF9, SS2, CP),
-	DA_INST		(0xFA, SS2, AP),
-	DA_INST		(0xFB, SS2, SP),
-	DA_INST		(0xFC, SS2, MP),
-	DA_INST		(0xFD, SS2, DP),
-};
-
-static int da_snprintf(u8 *bytes, char *buf, int buflen, u8 opcode, struct
-		       disassm_instruction *table)
-{
-#define IPFX "%-6s "
-
-	int ilc = opcode >> 6;
-	struct disassm_instruction *inst = &table[opcode];
-
-	switch (inst->fmt) {
-		case IF_INV:
-			snprintf(buf, buflen, "??");
-			break;
-		case IF_VAR:
-			{
-				unsigned char subop; /* sub op-code */
-
-				/* get the right byte */
-				subop = *(bytes+(inst->loc/8));
-
-				/* shift the needed portion right */
-				subop >>= 8 - inst->len - (inst->loc%8);
-
-				/* mask out any unneeded high bits */
-				subop &= (1 << inst->len) - 1;
-
-				snprintf(buf, buflen, "??? (many, X'%02X'+  "
-					 "X'%02X', table = %p)", opcode, subop,
-					 inst->u.ptr);
-				if (inst->u.ptr)
-					da_snprintf(bytes, buf, buflen, subop, inst->u.ptr);
-				break;
-			}
-		case IF_DIAG:
-			snprintf(buf, buflen, IPFX "X'%06X'",
-				 inst->u.name,
-				 *((u32*)(bytes)) & 0xffffff);		/* I  */
-			break;
-		case IF_E:
-			snprintf(buf, buflen, IPFX,
-				 inst->u.name);
-			break;
-		case IF_I:
-			snprintf(buf, buflen, IPFX "X'%02X'",
-				 inst->u.name,
-				 *(bytes+1));				/* I  */
-			break;
-		case IF_RI1:
-		case IF_RI2:
-			snprintf(buf, buflen, IPFX "%s%d,%d",
-				 inst->u.name,
-				 (inst->fmt == IF_RI1 ? "R" : ""),	/* reg/mask */
-				 bytes[1] >> 4,				/* R1/M1 */
-				 *((u16*)(bytes+2)));			/* I2 */
-			break;
-		case IF_RIL1:
-		case IF_RIL2:
-			snprintf(buf, buflen, IPFX "%s%d,%d",
-				 inst->u.name,
-				 (inst->fmt == IF_RIL1 ? "R" : ""),	/* reg/mask */
-				 bytes[1] >> 4,				/* R1/M1 */
-				 *((u32*)(bytes+2)));			/* I2 */
-			break;
-		case IF_RR:
-		case IF_RR_MASK:
-			snprintf(buf, buflen, IPFX "%s%d,R%d",
-				 inst->u.name,
-				 inst->fmt == IF_RR_MASK ? "" : "R",
-				 bytes[1] >> 4,				/* R1 */
-				 bytes[1] & 0xf);			/* R2 */
-			break;
-		case IF_RRE:
-			snprintf(buf, buflen, IPFX "R%d,R%d",
-				 inst->u.name,
-				 bytes[3] >> 4,				/* R1 */
-				 bytes[3] & 0xf);			/* R2 */
-			break;
-		case IF_RS1:
-		case IF_RS2:
-			snprintf(buf, buflen, IPFX "R%d,%s%d,%d(R%d)",
-				 inst->u.name,
-				 bytes[1] >> 4,				/* R1 */
-				 (inst->fmt == IF_RS1 ? "R" : ""),	/* reg/mask */
-				 bytes[1] & 0xf,			/* R3/M3 */
-				 *((u16*)(bytes+2)) & 0x0fff,		/* D2 */
-				 bytes[2] >> 4);			/* B2 */
-			break;
-		case IF_RSI:
-			snprintf(buf, buflen, IPFX "R%d,R%d,%d",
-				 inst->u.name,
-				 bytes[1] >> 4,				/* R1 */
-				 bytes[1] & 0xf,			/* R3 */
-				 *((u16*)(bytes+2)));			/* I2 */
-			break;
-		case IF_RSY1:
-		case IF_RSY2:
-			snprintf(buf, buflen, IPFX "R%d,%s%d,%d(R%d)",
-				 inst->u.name,
-				 bytes[1] >> 4,				/* R1 */
-				 (inst->fmt == IF_RSY1 ? "R" : ""),	/* reg/mask */
-				 bytes[1] & 0xf,			/* R3/M3 */
-				 ((u32)*((u16*)(bytes+2)) & 0x0fff) +
-				 (((u32)*(bytes+4)) << 12),		/* D2 */
-				 bytes[2] >> 4);			/* B2 */
-			break;
-		case IF_RX:
-		case IF_RX_MASK:
-			snprintf(buf, buflen, IPFX "%s%d,%d(R%d,R%d)",
-				 inst->u.name,
-				 inst->fmt == IF_RX_MASK ? "" : "R",
-				 bytes[1] >> 4,				/* R1 */
-				 *((u16*)(bytes+2)) & 0x0fff,		/* D2 */
-				 bytes[1] & 0xf,			/* X2 */
-				 bytes[2] >> 4);			/* B2 */
-			break;
-		case IF_RXY:
-			snprintf(buf, buflen, IPFX "R%d,%d(R%d,R%d)",
-				 inst->u.name,
-				 bytes[1] >> 4,				/* R1 */
-				 ((u32)*((u16*)(bytes+2)) & 0x0fff) +
-				 (((u32)*(bytes+4)) << 12),		/* D2 */
-				 bytes[1] & 0xf,			/* X2 */
-				 bytes[2] >> 4);			/* B2 */
-			break;
-		case IF_S:
-			snprintf(buf, buflen, IPFX "%d(R%d)",
-				 inst->u.name,
-				 *((u16*)(bytes+2)) & 0x0fff,		/* D2 */
-				 bytes[2] >> 4);			/* B2 */
-			break;
-		case IF_SI:
-			snprintf(buf, buflen, IPFX "%d(R%d),%d",
-				 inst->u.name,
-				 *((u16*)(bytes+2)) & 0x0fff,		/* D1 */
-				 bytes[2] >> 4,				/* B1 */
-				 bytes[1]);				/* I2 */
-			break;
-		case IF_SS1:
-			snprintf(buf, buflen, IPFX "%d(%d,R%d),%d(R%d)",
-				 inst->u.name,
-				 *((u16*)(bytes+2)) & 0x0fff,		/* D1 */
-				 bytes[1]+1,				/* L  */
-				 bytes[2] >> 4,				/* B1 */
-				 *((u16*)(bytes+4)) & 0x0fff,		/* D2 */
-				 bytes[4] >> 4);			/* B2 */
-			break;
-		case IF_SS2:
-			snprintf(buf, buflen, IPFX "%d(%d,R%d),%d(%d,R%d)",
-				 inst->u.name,
-				 *((u16*)(bytes+2)) & 0x0fff,		/* D1 */
-				 (bytes[1] >> 4) + 1,			/* L1 */
-				 bytes[2] >> 4,				/* B1 */
-				 *((u16*)(bytes+4)) & 0x0fff,		/* D2 */
-				 (bytes[1] & 0xf) + 1,			/* L2 */
-				 bytes[4] >> 4);			/* B2 */
-			break;
-		case IF_SS3:
-			snprintf(buf, buflen, IPFX "%d(%d,R%d),%d(R%d),%d",
-				 inst->u.name,
-				 *((u16*)(bytes+2)) & 0x0fff,		/* D1 */
-				 (bytes[1] >> 4) + 1,			/* L1 */
-				 bytes[2] >> 4,				/* B1 */
-				 *((u16*)(bytes+4)) & 0x0fff,		/* D2 */
-				 bytes[4] >> 4,				/* B2 */
-				 bytes[1] & 0xf);			/* I3 */
-			break;
-		case IF_SS4:
-			snprintf(buf, buflen, IPFX "%d(%d,R%d),%d(R%d),R%d",
-				 inst->u.name,
-				 *((u16*)(bytes+2)) & 0x0fff,		/* D1 */
-				 (bytes[1] >> 4) + 1,			/* L1 */
-				 bytes[2] >> 4,				/* B1 */
-				 *((u16*)(bytes+4)) & 0x0fff,		/* D2 */
-				 bytes[4] >> 4,				/* B2 */
-				 bytes[1] & 0xf);			/* R3 */
-			break;
-		case IF_SS5:
-			snprintf(buf, buflen, IPFX "R%d,R%d,%d(R%d),%d(R%d)",
-				 inst->u.name,
-				 bytes[1] >> 4,				/* R1 */
-				 bytes[1] & 0xf,			/* R3 */
-				 *((u16*)(bytes+2)) & 0x0fff,		/* D2 */
-				 bytes[2] >> 4,				/* B2 */
-				 *((u16*)(bytes+4)) & 0x0fff,		/* D4 */
-				 bytes[4] >> 4);			/* B4 */
-			break;
-		default:
-			snprintf(buf, buflen, "%s ???", inst->u.name);
-			break;
-	}
-
-	/* return instruction length in bytes */
-	return 2 * (ilc >= 2 ? ilc : ilc + 1);
-}
-
-int disassm(u8 *bytes, char *buf, int buflen)
-{
-	return da_snprintf(bytes, buf, buflen, *bytes, l1);
-}
--- a/sys/cp/exception.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-#include <sched.h>
-#include <vcpu.h>
-
-void queue_prog_exception(struct virt_sys *sys, enum PROG_EXCEPTION type, u64 param)
-{
-	con_printf(sys->con, "FIXME: supposed to inject a %d program exception\n", type);
-	sys->task->cpu->state = GUEST_STOPPED;
-}
-
--- a/sys/cp/guest.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-#include <directory.h>
-#include <sched.h>
-#include <dat.h>
-#include <cp.h>
-
-/*
- * FIXME:
- * - issue any pending interruptions
- */
-void run_guest(struct virt_sys *sys)
-{
-	u64 save_gpr[16];
-
-	/*
-	 * FIXME: need to ->icptcode = 0;
-	 */
-
-	/*
-	 * FIXME: load FPRs & FPCR
-	 */
-
-	/*
-	 * IMPORTANT: We MUST keep a valid stack address in R15. This way,
-	 * if SIE gets interrupted via an interrupt in the host, the
-	 * scheduler can still get to the struct task pointer on the stack
-	 */
-	asm volatile(
-		/* save current regs */
-		"	stmg	0,15,%0\n"
-		/* load the address of the guest state save area */
-		"	lr	14,%1\n"
-		/* load the address of the reg save area */
-		"	la	15,%0\n"
-		/* load guest's R0-R13 */
-		"	lmg	0,13,%2(14)\n"
-		/* SIE */
-		"	sie	%3(14)\n"
-		/* save guest's R0-R13 */
-		"	stmg	0,13,%2(14)\n"
-		/* restore all regs */
-		"	lmg	0,15,0(15)\n"
-
-	: /* output */
-	  "+m" (save_gpr)
-	: /* input */
-	  "a" (sys->task->cpu),
-	  "J" (offsetof(struct virt_cpu, regs.gpr)),
-	  "J" (offsetof(struct virt_cpu, sie_cb))
-	: /* clobbered */
-	  "memory"
-	);
-
-	/*
-	 * FIXME: store FPRs & FPCR
-	 */
-
-	handle_interception(sys);
-}
--- a/sys/cp/guest_ipl.S	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-	#
-	# We are guaranteed the following:
-	#
-	# 1) we are located above 16M
-	# 2) we are located below 2G
-	# 3) we are running in ESA/390
-	# 4) we are in 31-bit addressing mode
-	# 5) the guest registers are saved at GUEST_IPL_REGSAVE
-	# 6) R1 contains the subchannel #
-	# 7) R2 contains the device #
-	# 8) R12 contains the base address
-	#
-	# Register usage:
-	#
-	#   R1  = subchannel number
-	#   R2  = device number
-	#   R3  = temp
-	#   R12 = base for this code
-	#
-
-	# Nice register names
-.equ	r0,0
-.equ	r1,1
-.equ	r2,2
-.equ	r3,3
-.equ	r12,12
-.equ	r15,15
-
-	# new IO interruption PSW address
-.equ	PSANEWIO,120
-
-###############################################################################
-# Code begins here                                                            #
-###############################################################################
-
-.globl GUEST_IPL_CODE
-	.type	GUEST_IPL_CODE, @function
-GUEST_IPL_CODE:
-	STSCH	SCHIB(r12)			# get the SCHIB
-	BNZ	ERROR(r12)
-
-	OI	SCHIB+5(r12),0x80		# enable the subchannel
-
-	MSCH	SCHIB(r12)			# load up the SCHIB
-	BNZ	ERROR(r12)
-
-	# got a functioning subchannel, let's set up the new IO psw
-
-	MVC	PSANEWIO(8,r0),IOPSW(r12)
-
-	L	r3,PSANEWIO+4(r0,r0)
-	LA	r3,IO(r3,r12)			# calculate the address of
-	ST	r3,PSANEWIO+4(r0,r0)		# the IO handler
-
-	# let's set up a CCW + an ORB, start the IO, and wait
-
-	MVC	0(8,r0),INITCCW(r12)		# set up the initial CCW
-	OI	ORB+6(r12),0xff			# set the LPM in the ORB
-
-	SSCH	ORB(r12)			# start the IO
-	BNZ	ERROR(r12)
-
-	LPSW	ENABLEDWAIT(r12)		# wait for IO interruptions
-
-.equ	IO,(.-GUEST_IPL_CODE)
-	# this is the IO interrupt handler
-
-	B	DONE(r12)
-
-.equ	ERROR,(.-GUEST_IPL_CODE)
-	# an error occured, return an error
-
-	LM	r0,r15,REGSAVE(r12)
-	DIAG	r0,r0,1				# return to hypervisor
-
-.equ	DONE,(.-GUEST_IPL_CODE)
-	# we were successful!
-
-	LM	r0,r15,REGSAVE(r12)
-	DIAG	r0,r0,0				# return to hypervisor
-
-###############################################################################
-# Data begins here                                                            #
-###############################################################################
-
-.equ	DISABLEDWAIT,(.-GUEST_IPL_CODE)
-	.long	0x000c0000
-	.long	0x80000000			# disabled wait PSW; signal
-						# return to hypervisor
-.equ	ENABLEDWAIT,(.-GUEST_IPL_CODE)
-	.long	0x020c0000
-	.long	0x80000000			# enabled wait PSW; wait for IO
-
-.equ	IOPSW,(.-GUEST_IPL_CODE)
-	.long	0x00080000
-	.long	0x80000000			# new IO psw
-
-.equ	INITCCW,(.-GUEST_IPL_CODE)
-	.long	0x02000000
-	.long	0x60000018			# fmt0, read 24 bytes to addr 0
-
-	.align 4
-.equ	ORB,(.-GUEST_IPL_CODE)
-	.skip	(8*4),0				# the ORB is BIG
-
-	.align 4
-.equ	SCHIB,(.-GUEST_IPL_CODE)
-	.skip	(13*4),0			# the SCHIB is BIG
-
-	.align 4
-.globl GUEST_IPL_REGSAVE
-	.type	GUEST_IPL_REGSAVE, @function
-GUEST_IPL_REGSAVE:
-.equ	REGSAVE,(.-GUEST_IPL_CODE)		# register save area
--- a/sys/cp/init.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,320 +0,0 @@
-#include <directory.h>
-#include <sched.h>
-#include <errno.h>
-#include <page.h>
-#include <buddy.h>
-#include <slab.h>
-#include <dat.h>
-#include <cp.h>
-#include <clock.h>
-#include <ebcdic.h>
-#include <vdevice.h>
-#include <cpu.h>
-#include <mutex.h>
-#include <vsprintf.h>
-
-/* This is used to con_printf to the operator about various async events -
- * e.g., user logon
- */
-struct console *oper_con;
-
-static LIST_HEAD(online_users);
-static UNLOCKED_MUTEX(online_users_lock);
-
-static int __alloc_guest_devices(struct virt_sys *sys)
-{
-	int i;
-
-	INIT_LIST_HEAD(&sys->virt_devs);
-
-	for(i=0; sys->directory->devices[i].type != VDEV_INVAL; i++) {
-		if (alloc_virt_dev(sys, &sys->directory->devices[i],
-				   0x10000 + i))
-			con_printf(sys->con, "Failed to allocate vdev %04X, SCH = %05X\n",
-				   sys->directory->devices[i].vdev,
-				   0x10000 + i);
-	}
-
-	return 0;
-}
-
-static int __alloc_guest_storage(struct virt_sys *sys)
-{
-	u64 pages = sys->directory->storage_size >> PAGE_SHIFT;
-	struct page *p;
-
-	INIT_LIST_HEAD(&sys->guest_pages);
-
-	while (pages) {
-		p = alloc_pages(0, ZONE_NORMAL);
-		if (!p)
-			continue; /* FIXME: sleep? */
-
-		list_add(&p->guest, &sys->guest_pages);
-
-		pages--;
-
-		dat_insert_page(&sys->as, (u64) page_to_addr(p),
-				pages << PAGE_SHIFT);
-	}
-
-	return 0;
-}
-
-static void process_logon_cmd(struct console *con)
-{
-	u8 cmd[128];
-	int ret;
-
-	ret = con_read(con, cmd, 128);
-
-	if (ret == -1)
-		return; /* no lines to read */
-
-	if (!ret)
-		return; /* empty line */
-
-	ebcdic2ascii(cmd, ret);
-
-	/*
-	 * we got a command to process!
-	 */
-
-	ret = invoke_cp_logon(con, (char*) cmd, ret);
-	if (!ret)
-		return;
-
-	con_printf(con, "NOT LOGGED ON\n");
-}
-
-static void process_cmd(struct virt_sys *sys)
-{
-	u8 cmd[128];
-	int ret;
-
-	ret = con_read(sys->con, cmd, 128);
-
-	if (ret == -1)
-		return; /* no lines to read */
-
-	if (!ret) {
-		con_printf(sys->con, "CP\n");
-		return; /* empty line */
-	}
-
-	ebcdic2ascii(cmd, ret);
-
-	/*
-	 * we got a command to process!
-	 */
-	ret = invoke_cp_cmd(sys, (char*) cmd, ret);
-	switch (ret) {
-		case 0:
-			/* all fine */
-			break;
-		case -ENOENT:
-			con_printf(sys->con, "Invalid CP command: %s\n", cmd);
-			break;
-		case -ESUBENOENT:
-			con_printf(sys->con, "Invalid CP sub-command: %s\n", cmd);
-			break;
-		case -EINVAL:
-			con_printf(sys->con, "Operand missing or invalid\n");
-			break;
-		case -EPERM:
-			con_printf(sys->con, "Not authorized\n");
-			break;
-		default:
-			con_printf(sys->con, "RC=%d\n", ret);
-			break;
-	}
-}
-
-static int cp_init(void *data)
-{
-	struct virt_sys *sys = data;
-	struct virt_cpu *cpu;
-	struct datetime dt;
-	struct page *page;
-
-	page = alloc_pages(0, ZONE_NORMAL);
-	BUG_ON(!page);
-
-	cpu = page_to_addr(page);
-	sys->task->cpu = cpu;
-
-	memset(cpu, 0, PAGE_SIZE);
-
-	__alloc_guest_storage(sys);
-	__alloc_guest_devices(sys);
-
-	/*
-	 * load guest's address space into the host's PASCE
-	 */
-	load_as(&sys->as);
-
-	cpu->cpuid = getcpuid() | 0xFF00000000000000ULL;
-
-	memset(&cpu->sie_cb, 0, sizeof(struct sie_cb));
-	cpu->sie_cb.gmsor = 0;
-	cpu->sie_cb.gmslm = sys->directory->storage_size;
-	cpu->sie_cb.gbea = 1;
-	cpu->sie_cb.ecb  = 2;
-	cpu->sie_cb.eca  = 0xC1002001U;
-	/*
-	 * TODO: What about ->scaoh and ->scaol?
-	 */
-
-	guest_power_on_reset(sys);
-
-	get_parsed_tod(&dt);
-	con_printf(sys->con, "LOGON FOR %s AT %02d:%02d:%02d UTC %04d-%02d-%02d\n",
-		   sys->directory->userid, dt.th, dt.tm, dt.ts, dt.dy, dt.dm, dt.dd);
-
-	for (;;) {
-		/*
-		 *   - process any console input
-		 *   - if the guest is running
-		 *     - issue any pending interruptions
-		 *     - continue executing it
-		 *     - process any intercepts from SIE
-		 *   - else, schedule()
-		 */
-
-		process_cmd(sys);
-
-		if (cpu->state == GUEST_OPERATING)
-			run_guest(sys);
-		else
-			schedule();
-	}
-
-	return 0;
-}
-
-static void __con_attn(struct console *con)
-{
-	if (con->sys) {
-		/* There's already a user on this console */
-
-		if (!con->sys->task->cpu ||
-		    con->sys->task->cpu->state == GUEST_STOPPED)
-			return;
-
-		if (!con_read_pending(con))
-			return;
-
-		/*
-		 * There's a read pending. Generate an interception.
-		 */
-		atomic_set_mask(CPUSTAT_STOP_INT, &con->sys->task->cpu->sie_cb.cpuflags);
-	} else {
-		if (!con_read_pending(con))
-			return;
-
-		/*
-		 * There's a read pending. MUST be a command
-		 */
-		process_logon_cmd(con);
-	}
-}
-
-static int cp_con_attn(void *data)
-{
-	for(;;) {
-		schedule();
-
-		for_each_console(__con_attn);
-	}
-
-	return 0;
-}
-
-void spawn_oper_cp(struct console *con)
-{
-	struct virt_sys *sys;
-
-	oper_con = con;
-
-	sys = malloc(sizeof(struct virt_sys), ZONE_NORMAL);
-	BUG_ON(!sys);
-
-	sys->con = con;
-	con->sys = sys;
-
-	sys->directory = find_user_by_id("operator");
-	BUG_ON(IS_ERR(sys->directory));
-
-	sys->print_ts = 1; /* print timestamps */
-
-	sys->task = create_task("OPERATOR-vcpu0", cp_init, sys);
-	BUG_ON(IS_ERR(sys->task));
-
-	BUG_ON(IS_ERR(create_task("console-attn", cp_con_attn, NULL)));
-
-	mutex_lock(&online_users_lock);
-	list_add_tail(&sys->online_users, &online_users);
-	mutex_unlock(&online_users_lock);
-}
-
-void spawn_user_cp(struct console *con, struct user *u)
-{
-	char tname[TASK_NAME_LEN+1];
-	struct virt_sys *sys;
-	int already_online = 0;
-
-	mutex_lock(&online_users_lock);
-	list_for_each_entry(sys, &online_users, online_users) {
-		if (sys->directory == u) {
-			already_online = 1;
-			break;
-		}
-	}
-	mutex_unlock(&online_users_lock);
-
-	if (already_online) {
-		con_printf(con, "ALREADY LOGGED ON\n");
-		return;
-	}
-
-	sys = malloc(sizeof(struct virt_sys), ZONE_NORMAL);
-	if (!sys)
-		goto err;
-
-	sys->con = con;
-	con->sys = sys;
-
-	sys->directory = u;
-
-	sys->print_ts = 1; /* print timestamps */
-
-	snprintf(tname, TASK_NAME_LEN, "%s-vcpu0", u->userid);
-	sys->task = create_task(tname, cp_init, sys);
-	if (IS_ERR(sys->task))
-		goto err_free;
-
-	mutex_lock(&online_users_lock);
-	list_add_tail(&sys->online_users, &online_users);
-	mutex_unlock(&online_users_lock);
-	return;
-
-err_free:
-	free(sys);
-	con->sys = NULL;
-err:
-	con_printf(con, "INTERNAL ERROR DURING LOGON\n");
-}
-
-void list_users(struct console *con, void (*f)(struct console *con,
-					       struct virt_sys *sys))
-{
-	struct virt_sys *sys;
-
-	if (!f)
-		return;
-
-	mutex_lock(&online_users_lock);
-	list_for_each_entry(sys, &online_users, online_users)
-		f(con, sys);
-	mutex_unlock(&online_users_lock);
-}
--- a/sys/cp/instruction.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#include <sched.h>
-#include <cp.h>
-
-static const intercept_handler_t instruction_funcs[256] = {
-	[0xb2] = handle_instruction_priv,	/* assorted priv. insts */
-};
-
-int handle_instruction(struct virt_sys *sys)
-{
-	struct virt_cpu *cpu = sys->task->cpu;
-	intercept_handler_t h;
-	int err = -EINVAL;
-
-	con_printf(sys->con, "INTRCPT: INST (%04x %08x)\n",
-		   cpu->sie_cb.ipa,
-		   cpu->sie_cb.ipb);
-
-	h = instruction_funcs[cpu->sie_cb.ipa >> 8];
-	if (h)
-		err = h(sys);
-
-	return err;
-}
--- a/sys/cp/instruction_priv.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,217 +0,0 @@
-#include <list.h>
-#include <sched.h>
-#include <cp.h>
-#include <vdevice.h>
-#include <vcpu.h>
-
-static int handle_msch(struct virt_sys *sys)
-{
-	struct virt_cpu *cpu = sys->task->cpu;
-
-	u64 r1 = __guest_gpr(cpu, 1);
-	u64 addr = RAW_S_1(cpu);
-
-	struct schib *gschib;
-	struct virt_device *vdev, *vdev_cur;
-	int ret = 0;
-
-	if ((PAGE_SIZE-(addr & PAGE_MASK)) < sizeof(struct schib)) {
-		con_printf(sys->con, "The SCHIB crosses page boundary (%016llx; %lu)! CPU stopped\n",
-			   addr, sizeof(struct schib));
-		cpu->state = GUEST_STOPPED;
-		goto out;
-	}
-
-	/* sch number must be: X'0001____' */
-	if ((r1 & 0xffff0000) != 0x00010000) {
-		queue_prog_exception(sys, PROG_OPERAND, r1);
-		goto out;
-	}
-
-	/* schib must be word-aligned */
-	if (addr & 0x3) {
-		queue_prog_exception(sys, PROG_SPEC, addr);
-		goto out;
-	}
-
-	/* find the virtual device */
-	vdev = NULL;
-	list_for_each_entry(vdev_cur, &sys->virt_devs, devices) {
-		if (vdev_cur->sch == (u32) r1) {
-			vdev = vdev_cur;
-			break;
-		}
-	}
-
-	/* There's no virtual device with this sch number; CC=3 */
-	if (!vdev) {
-		cpu->sie_cb.gpsw.cc = 3;
-		goto out;
-	}
-
-	/* translate guest address to host address */
-	ret = virt2phy_current(addr, &addr);
-	if (ret) {
-		if (ret != -EFAULT)
-			goto out;
-
-		ret = 0;
-		queue_prog_exception(sys, PROG_ADDR, addr);
-		goto out;
-	}
-
-	gschib = (struct schib*) addr;
-
-	/*
-	 * Condition code 1 is set, and no other action is taken, when the
-	 *   subchannel is status pending. (See “Status Control (SC)” on
-	 *   page 16-16.)
-	 */
-	if (vdev->scsw.sc & SC_STATUS) {
-		cpu->sie_cb.gpsw.cc = 1;
-		goto out;
-	}
-
-	/*
-	 * Condition code 2 is set, and no other action is taken, when a
-	 *   clear, halt, or start function is in progress at the
-	 *   subchannel.  (See “Function Control (FC)” on page 16-12.)
-	 */
-	if (vdev->scsw.fc & (FC_START | FC_HALT | FC_CLEAR)) {
-		cpu->sie_cb.gpsw.cc = 2;
-		goto out;
-	}
-
-	/*
-	 * The channel-subsystem operations that may be influenced due to
-	 * placement of SCHIB information in the subchannel are:
-	 *
-	 * • I/O processing (E field)
-	 * • Interruption processing (interruption parameter and ISC field)
-	 * • Path management (D, LPM, and POM fields)
-	 * • Monitoring and address-limit checking (measurement-block index,
-	 *   LM, and MM fields)
-	 * • Measurement-block-format control (F field)
-	 * • Extended-measurement-word-mode enable (X field)
-	 * • Concurrent-sense facility (S field)
-	 * • Measurement-block address (MBA)
-	*/
-
-	if (!gschib->pmcw.v)
-		goto out_cc0;
-
-	vdev->pmcw.interrupt_param = gschib->pmcw.interrupt_param;
-	vdev->pmcw.e   = gschib->pmcw.e;
-	vdev->pmcw.isc = gschib->pmcw.isc;
-	vdev->pmcw.d   = gschib->pmcw.d;
-	vdev->pmcw.lpm = gschib->pmcw.lpm;
-	vdev->pmcw.pom = gschib->pmcw.pom;
-	vdev->pmcw.lm  = gschib->pmcw.lm;
-	vdev->pmcw.mm  = gschib->pmcw.mm;
-	vdev->pmcw.f   = gschib->pmcw.f;
-	vdev->pmcw.x   = gschib->pmcw.x;
-	vdev->pmcw.s   = gschib->pmcw.s;
-	vdev->pmcw.mbi = gschib->pmcw.mbi;
-	/* FIXME: save measurement-block address */
-
-out_cc0:
-	cpu->sie_cb.gpsw.cc = 0;
-
-out:
-	return ret;
-}
-
-static int handle_ssch(struct virt_sys *sys)
-{
-	con_printf(sys->con, "SSCH handler\n");
-	return -ENOMEM;
-}
-
-static int handle_stsch(struct virt_sys *sys)
-{
-	struct virt_cpu *cpu = sys->task->cpu;
-
-	u64 r1   = __guest_gpr(cpu, 1);
-	u64 addr = RAW_S_1(cpu);
-
-	struct schib *gschib;
-	struct virt_device *vdev, *vdev_cur;
-	int ret = 0;
-
-	if ((PAGE_SIZE-(addr & PAGE_MASK)) < sizeof(struct schib)) {
-		con_printf(sys->con, "The SCHIB crosses page boundary (%016llx; %lu)! CPU stopped\n",
-			   addr, sizeof(struct schib));
-		cpu->state = GUEST_STOPPED;
-		goto out;
-	}
-
-	/* sch number must be: X'0001____' */
-	if ((r1 & 0xffff0000) != 0x00010000) {
-		queue_prog_exception(sys, PROG_OPERAND, r1);
-		goto out;
-	}
-
-	/* schib must be word-aligned */
-	if (addr & 0x3) {
-		queue_prog_exception(sys, PROG_SPEC, addr);
-		goto out;
-	}
-
-	/* find the virtual device */
-	vdev = NULL;
-	list_for_each_entry(vdev_cur, &sys->virt_devs, devices) {
-		if (vdev_cur->sch == (u32) r1) {
-			vdev = vdev_cur;
-			break;
-		}
-	}
-
-	/* There's no virtual device with this sch number; CC=3 */
-	if (!vdev) {
-		cpu->sie_cb.gpsw.cc = 3;
-		goto out;
-	}
-
-	/* translate guest address to host address */
-	ret = virt2phy_current(addr, &addr);
-	if (ret) {
-		if (ret == -EFAULT) {
-			ret = 0;
-			queue_prog_exception(sys, PROG_ADDR, addr);
-		}
-
-		goto out;
-	}
-
-	gschib = (struct schib*) addr;
-
-	/* copy! */
-	memcpy(&gschib->pmcw, &vdev->pmcw, sizeof(struct pmcw));
-	memcpy(&gschib->scsw, &vdev->scsw, sizeof(struct scsw));
-
-	/* CC: 0 */
-	cpu->sie_cb.gpsw.cc = 0;
-
-out:
-	return ret;
-}
-
-static const intercept_handler_t instruction_priv_funcs[256] = {
-	[0x32] = handle_msch,
-	[0x33] = handle_ssch,
-	[0x34] = handle_stsch,
-};
-
-int handle_instruction_priv(struct virt_sys *sys)
-{
-	struct virt_cpu *cpu = sys->task->cpu;
-	intercept_handler_t h;
-	int err = -EINVAL;
-
-	h = instruction_priv_funcs[cpu->sie_cb.ipa & 0xff];
-	if (h)
-		err = h(sys);
-
-	return err;
-}
-
--- a/sys/cp/intercept.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-#include <directory.h>
-#include <sched.h>
-#include <dat.h>
-#include <cp.h>
-
-static int handle_noop(struct virt_sys *sys)
-{
-	return 0;
-}
-
-static int handle_program(struct virt_sys *sys)
-{
-	con_printf(sys->con, "INTRCPT: PROG\n");
-	sys->task->cpu->state = GUEST_STOPPED;
-	return 0;
-}
-
-static int handle_instruction_and_program(struct virt_sys *sys)
-{
-	con_printf(sys->con, "INTRCPT: INST+PROG\n");
-	sys->task->cpu->state = GUEST_STOPPED;
-	return 0;
-}
-
-static int handle_ext_req(struct virt_sys *sys)
-{
-	con_printf(sys->con, "INTRCPT: EXT REQ\n");
-	sys->task->cpu->state = GUEST_STOPPED;
-	return 0;
-}
-
-static int handle_ext_int(struct virt_sys *sys)
-{
-	con_printf(sys->con, "INTRCPT: EXT INT\n");
-	sys->task->cpu->state = GUEST_STOPPED;
-	return 0;
-}
-
-static int handle_io_req(struct virt_sys *sys)
-{
-	con_printf(sys->con, "INTRCPT: IO REQ\n");
-	sys->task->cpu->state = GUEST_STOPPED;
-	return 0;
-}
-
-static int handle_wait(struct virt_sys *sys)
-{
-	con_printf(sys->con, "INTRCPT: WAIT\n");
-	sys->task->cpu->state = GUEST_STOPPED;
-	return 0;
-}
-
-static int handle_validity(struct virt_sys *sys)
-{
-	con_printf(sys->con, "INTRCPT: VALIDITY\n");
-	sys->task->cpu->state = GUEST_STOPPED;
-	return 0;
-}
-
-static int handle_stop(struct virt_sys *sys)
-{
-	atomic_clear_mask(CPUSTAT_STOP_INT, &sys->task->cpu->sie_cb.cpuflags);
-	return 0;
-}
-
-static int handle_oper_except(struct virt_sys *sys)
-{
-	con_printf(sys->con, "INTRCPT: OPER EXCEPT\n");
-	sys->task->cpu->state = GUEST_STOPPED;
-	return 0;
-}
-
-static int handle_exp_run(struct virt_sys *sys)
-{
-	con_printf(sys->con, "INTRCPT: EXP RUN\n");
-	sys->task->cpu->state = GUEST_STOPPED;
-	return 0;
-}
-
-static int handle_exp_timer(struct virt_sys *sys)
-{
-	con_printf(sys->con, "INTRCPT: EXP TIMER\n");
-	sys->task->cpu->state = GUEST_STOPPED;
-	return 0;
-}
-
-static const intercept_handler_t intercept_funcs[0x4c >> 2] = {
-	[0x00 >> 2] = handle_noop,
-	[0x04 >> 2] = handle_instruction,
-	[0x08 >> 2] = handle_program,
-	[0x0c >> 2] = handle_instruction_and_program,
-	[0x10 >> 2] = handle_ext_req,
-	[0x14 >> 2] = handle_ext_int,
-	[0x18 >> 2] = handle_io_req,
-	[0x1c >> 2] = handle_wait,
-	[0x20 >> 2] = handle_validity,
-	[0x28 >> 2] = handle_stop,
-	[0x2c >> 2] = handle_oper_except,
-	[0x44 >> 2] = handle_exp_run,
-	[0x48 >> 2] = handle_exp_timer,
-};
-
-void handle_interception(struct virt_sys *sys)
-{
-	struct virt_cpu *cpu = sys->task->cpu;
-	intercept_handler_t h;
-	int err = -EINVAL;
-
-	h = intercept_funcs[cpu->sie_cb.icptcode >> 2];
-	if (h)
-		err = h(sys);
-
-	if (err) {
-		cpu->state = GUEST_STOPPED;
-		con_printf(sys->con, "Unknown/mis-handled intercept code %02x, err = %d\n",
-			   cpu->sie_cb.icptcode, err);
-	}
-}
--- a/sys/cp/reset.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-#include <directory.h>
-#include <sched.h>
-#include <dat.h>
-#include <cp.h>
-
-#define RESET_CPU			0x000001
-#define SET_ESA390			0x000002
-#define RESET_PSW			0x000004
-#define RESET_PREFIX			0x000008
-#define RESET_CPU_TIMER			0x000010
-#define RESET_CLK_COMP			0x000020
-#define RESET_TOD_PROG_REG		0x000040
-#define RESET_CR			0x000080
-#define RESET_BREAK_EV_ADDR		0x000100
-#define RESET_FPCR			0x000200
-#define RESET_AR			0x000400
-#define RESET_GPR			0x000800
-#define RESET_FPR			0x001000
-#define RESET_STORAGE_KEYS		0x002000
-#define RESET_STORAGE			0x004000
-#define RESET_NONVOL_STORAGE		0x008000
-#define RESET_EXPANDED_STORAGE		0x010000
-#define RESET_TOD			0x020000
-#define RESET_TOD_STEER			0x040000
-#define RESET_FLOATING_INTERRUPTIONS	0x080000
-#define RESET_IO			0x100000
-#define RESET_PLO_LOCKS			0x200000
-#define __RESET_PLO_LOCKS_PRESERVE	0x400000
-#define RESET_PLO_LOCKS_PRESERVE	(RESET_PLO_LOCKS | \
-					 __RESET_PLO_LOCKS_PRESERVE)
-
-/*
- * These define all the different ways of reseting the system...to save us
- * typing later on :)
- */
-#define SUBSYSTEM_RESET_FLAGS	(RESET_FLOATING_INTERRUPTIONS | RESET_IO)
-#define CPU_RESET_FLAGS		(RESET_CPU)
-#define INIT_CPU_RESET_FLAGS	(RESET_CPU | SET_ESA390 | RESET_PSW | \
-				 RESET_PREFIX | RESET_CPU_TIMER | \
-				 RESET_CLK_COMP | RESET_TOD_PROG_REG | \
-				 RESET_CR | RESET_BREAK_EV_ADDR | \
-				 RESET_FPCR)
-#define CLEAR_RESET_FLAGS	(RESET_CPU | SET_ESA390 | RESET_PSW | \
-				 RESET_PREFIX | RESET_CPU_TIMER | \
-				 RESET_CLK_COMP | RESET_TOD_PROG_REG | \
-				 RESET_CR | RESET_BREAK_EV_ADDR | RESET_FPCR | \
-				 RESET_AR | RESET_GPR | RESET_FPR | \
-				 RESET_STORAGE_KEYS | RESET_STORAGE | \
-				 RESET_NONVOL_STORAGE | RESET_PLO_LOCKS | \
-				 RESET_FLOATING_INTERRUPTIONS | RESET_IO)
-#define POWER_ON_RESET_FLAGS	(RESET_CPU | SET_ESA390 | RESET_PSW | \
-				 RESET_PREFIX | RESET_CPU_TIMER | \
-				 RESET_CLK_COMP | RESET_TOD_PROG_REG | \
-				 RESET_CR | RESET_BREAK_EV_ADDR | RESET_FPCR | \
-				 RESET_AR | RESET_GPR | RESET_FPR | \
-				 RESET_STORAGE_KEYS | RESET_STORAGE | \
-				 RESET_EXPANDED_STORAGE | RESET_TOD | \
-				 RESET_TOD_STEER | RESET_PLO_LOCKS_PRESERVE | \
-				 RESET_FLOATING_INTERRUPTIONS | RESET_IO)
-
-/*
- * Reset TODO:
- *  - handle Captured-z/Architecture-PSW register
- */
-static void __perform_cpu_reset(struct virt_sys *sys, int flags)
-{
-	struct virt_cpu *cpu = sys->task->cpu;
-
-	if (flags & RESET_CPU) {
-		if (flags & SET_ESA390) {
-			/* FIXME: set the arch mode to ESA/390 */
-		}
-
-		/*
-		 * FIXME: clear interruptions:
-		 *  - PROG
-		 *  - SVC
-		 *  - local EXT (floating EXT are NOT cleared)
-		 *  - MCHECK (floating are NOT cleared)
-		 */
-
-		cpu->state = GUEST_STOPPED;
-	}
-
-	if (flags & RESET_PSW)
-		memset(&cpu->sie_cb.gpsw, 0, sizeof(struct psw));
-
-	if (flags & RESET_PREFIX)
-		cpu->sie_cb.prefix = 0;
-
-	if (flags & RESET_CPU_TIMER) {
-		/* FIXME */
-	}
-
-	if (flags & RESET_CLK_COMP) {
-		/* FIXME */
-	}
-
-	if (flags & RESET_TOD_PROG_REG) {
-		/* FIXME */
-	}
-
-	if (flags & RESET_CR) {
-		memset(cpu->sie_cb.gcr, 0, 16*sizeof(u64));
-		cpu->sie_cb.gcr[0]  = 0xE0UL;
-		cpu->sie_cb.gcr[14] = 0xC2000000UL;
-	}
-
-	if (flags & RESET_BREAK_EV_ADDR) {
-		/* FIXME: initialize to 0x1 */
-	}
-
-	if (flags & RESET_FPCR)
-		cpu->regs.fpcr = 0;
-
-	if (flags & RESET_AR)
-		memset(cpu->regs.ar, 0, 16*sizeof(u32));
-
-	if (flags & RESET_GPR)
-		memset(cpu->regs.gpr, 0, 16*sizeof(u64));
-
-	if (flags & RESET_FPR)
-		memset(cpu->regs.fpr, 0, 16*sizeof(u64));
-
-	if (flags & RESET_STORAGE_KEYS) {
-	}
-
-	if (flags & RESET_STORAGE) {
-		struct page *p;
-
-		list_for_each_entry(p, &sys->guest_pages, guest)
-			memset(page_to_addr(p), 0, PAGE_SIZE);
-	}
-
-	if (flags & RESET_NONVOL_STORAGE) {
-	}
-
-	if (flags & RESET_EXPANDED_STORAGE) {
-	}
-
-	if (flags & RESET_TOD) {
-	}
-
-	if (flags & RESET_TOD_STEER) {
-	}
-
-	if (flags & RESET_PLO_LOCKS) {
-		/*
-		 * TODO: if RESET_PLO_LOCKS_PRESERVE is set, don't reset
-		 * locks held by powered on CPUS
-		 */
-	}
-}
-
-static void __perform_noncpu_reset(struct virt_sys *sys, int flags)
-{
-	if (flags & RESET_FLOATING_INTERRUPTIONS) {
-	}
-
-	if (flags & RESET_IO) {
-	}
-}
-
-/**************/
-
-void guest_power_on_reset(struct virt_sys *sys)
-{
-	__perform_cpu_reset(sys, POWER_ON_RESET_FLAGS);
-	__perform_noncpu_reset(sys, POWER_ON_RESET_FLAGS);
-}
-
-void guest_system_reset_normal(struct virt_sys *sys)
-{
-	__perform_cpu_reset(sys, CPU_RESET_FLAGS);
-
-	/*
-	 * TODO: once we have SMP guests, all other cpus should get a
-	 * CPU_RESET_FLAGS as well.
-	 */
-
-	__perform_noncpu_reset(sys, SUBSYSTEM_RESET_FLAGS);
-}
-
-void guest_system_reset_clear(struct virt_sys *sys)
-{
-	__perform_cpu_reset(sys, CLEAR_RESET_FLAGS);
-
-	/*
-	 * TODO: once we have SMP guests, all other cpus should get a
-	 * CLEAR_RESET_FLAGS as well.
-	 */
-
-	__perform_noncpu_reset(sys, CLEAR_RESET_FLAGS);
-}
-
-void guest_load_normal(struct virt_sys *sys)
-{
-	__perform_cpu_reset(sys, INIT_CPU_RESET_FLAGS);
-
-	/*
-	 * TODO: once we have SMP guests, all other cpus should get a
-	 * CPU_RESET_FLAGS.
-	 */
-
-	__perform_noncpu_reset(sys, SUBSYSTEM_RESET_FLAGS);
-}
-
-void guest_load_clear(struct virt_sys *sys)
-{
-	__perform_cpu_reset(sys, CLEAR_RESET_FLAGS);
-
-	/*
-	 * TODO: once we have SMP guests, all other cpus should get a
-	 * CLEAR_RESET_FLAGS as well.
-	 */
-
-	__perform_noncpu_reset(sys, CLEAR_RESET_FLAGS);
-}
--- a/sys/cp/splash.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#include <splash.h>
-
-char *splash[] = {
-	"                    HH        HH  VV        VV  FFFFFFFFFFFF\n",
-	"                    HH        HH  VV        VV  FFFFFFFFFFFF\n",
-	"                    HH        HH  VV        VV  FF\n",
-	"                    HH        HH  VV        VV  FF\n",
-	"                    HH        HH  VV        VV  FF\n",
-	"                    HHHHHHHHHHHH  VV        VV  FFFFFFF\n",
-	"                    HHHHHHHHHHHH  VV        VV  FFFFFFF\n",
-	"                    HH        HH   VV      VV   FF\n",
-	"                    HH        HH    VV    VV    FF\n",
-	"                    HH        HH     VV  VV     FF\n",
-	"                    HH        HH      VVVV      FF\n",
-	"                    HH        HH       VV       FF\n",
-	"\n",
-	NULL,
-};
--- a/sys/doc/.gitignore	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-commands
--- a/sys/doc/PSA.txt	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-Aside from the architecture defined storage locations in the PSA, HVF uses
-the following addresses for special reasons:
-
-hex	dec	length	reason
-
- 200	 512	128	interrupt handler GPR storage
- 280	 640	16	PSW temporary storage
- 290	 656	8	current pointer
--- a/sys/doc/ipl.txt	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-This file attempts to describe what happens during IPL.
-
-NOTE: At the time, only IPL from tape and card reader is supported.
-
-1) system reads 24 bytes from the device 
-
-   a) bytes   0-7: new PSW, no interrupts, start address 0x800000 (8MB)
-
-   IPL from tape:
-
-      b) bytes  8-15: CCW to rewind the tape to previous TM
-
-      c) bytes 16-23: CCW to read the entire loader to 0x800000 (8 MB)
-
-   IPL from card reader:
-
-      b) bytes  8-15: CCW to read 80 bytes (containing up to 10 CCWs) to
-         0x18
-
-      c) bytes 16-23: CCW to read 24 bytes (containing up to 3 CCWs) to 0x68
-
-      Command chaining starts reading CCWs from addres 0x18 on. These read
-      the loader to 0x800000 (8 MB)
-
-2) arch mode is changed to z/Arch (see ipl/setmode.S)
-
-3) temporary stack is set up (R15 being the pointer) (see ipl/setmode.S)
-
-4) loader begins to execute: function load_nucleus (see ipl/loader.c)
-
-   NOTE: loader.c use static inlines extensively, and thefore stack usage is
-   minimal
-
-   a) If the IPL was from a tape, a CCW is issues to seek to the next TM
-
-   b) nucleus is read from tape to 0x400000 (4 MB)
-
-      NOTE: the data at 4MB just read is a 64-bit s390 ELF binary with Linux
-      ABI bits
-
-      i)   addition CCW address is set in the ORB
-
-      ii)  __readnucleus() is called; this function is implemented in
-           assembly (see ipl/loader_asm.S)
-
-      iii) IO interrupt handler is set up (implemented in asm, see
-           ipl/loader_asm.S)
-
-      iv)  ORB is sent to the subchannel
-
-      v)   interrupts are enabled
-
-      vi)  a new PSW with wait state bit set is loaded
-
-      vii) on IO interrupt
-
-           1) TSCH is issued to fill in a IRB
-
-           2) magic value (ORB int param) is checked
-
-	   3) Device End flag is checked in the IRB
-
-	      NOTE: more checks should be performed here
-
-	   4) If the device end flag is set, return to code that set up the
-              interrupt handler
-
-	   5) otherwise, load up the old IO PSW (the one with the wait
-              state)
-
-      viii)return to caller (back to ipl/loader.c)
-
-   c) verify ELF header magic number, machine, type, etc. values
-
-   d) traverse the section headers & copy data to final destination
-
-      i)   if the section type is PROGBITS (data stored in the ELF), copy
-           the data from it's temporary location to the desired location
-	   (destination, offset within file, and length are all stored in
-	   the section header) - this takes care of .text, .data, and
-	   .rodata sections
-
-      ii)  if the section type is NOBITS (uninitialized storage, e.g.,
-           .bss), do nothing, just assume that the location is a valid
-	   location in memory
-
-      iii) skip any other section types
-
-      NOTE: SYMTAB and STRTAB section types should be copied to a useful
-      location to allow for symbols to be looked up during nucleus execution
-
-   e) jump to the entry point as indicated by the ELF header
-
-At this point, the nucleus is executing.
--- a/sys/doc/memory.txt	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-Physical locations:
-
--------------------  (2^64)-1  --
-|                 |              \
-|                 |               |
-         .                        |
-         .                        \
-         .                         >    Generic pages
-         .                        /
-         .                        |
-|                 |               |
-|                 |              /
-|-----------------|  f(memsize)--
-|                 |              \
-|                 |               |
-         .                        \
-         .                         >    struct page array (see below)
-         .                        /
-|                 |               |
-|                 |              /
-|-----------------|  4M        --
-|                 |              \
-|                 |               |
-         .                        \
-         .                         >    OS .text, .data, .rodata, .bss
-         .                        /
-|                 |               |
-|                 |              /
-|-----------------|  1M        --
-|                 |              \
-|                 |               |
-         .                        |
-         .                        |
-         .                        \
-|                 |                >    PSA for each CPU
-|                 |               /
-|-----------------|  8k           |
-|                 |               |
-|       PSA       |               |
-|                 |              /
--------------------  0         --
-
-
-0 - 1MB:
-	Divided into up to 128 8KB chunks; nth chunk is nth CPU's PSA
-	(mapping done via the prefix register).
-
-1MB - 4MB:
-	OS .text
-	OS .data
-	OS .rodata
-	OS .bss
-
-4MB - (4MB + roundup((memsize >> PAGE_SIZE) * sizeof(struct page))):
-	This is an array of struct page entries for each page in the system.
-	The size varies based on the amount of memory installed.
-
-?? - (2^64)-1:
-	Generic pages; used for nucleus & process data
-
-	These pages are managed by the buddy allocator.
-
--- a/sys/drivers/3215.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-#include <device.h>
-#include <console.h>
-#include <list.h>
-#include <sched.h>
-#include <directory.h>
-
-static struct device_type d3215 = {
-	.types		= LIST_HEAD_INIT(d3215.types),
-	.reg		= NULL,
-	.interrupt	= NULL,
-	.enable		= console_enable,
-	.snprintf	= NULL,
-	.type		= 0x3215,
-	.model		= 0,
-};
-
-int register_driver_3215(void)
-{
-	return register_device_type(&d3215);
-}
-
--- a/sys/drivers/Makefile	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-objs-drivers := device.o console.o 3215.o dasd.o vdevice.o
--- a/sys/drivers/console.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,387 +0,0 @@
-#include <console.h>
-#include <slab.h>
-#include <sched.h>
-#include <directory.h>
-#include <splash.h>
-#include <vsprintf.h>
-
-/*
- * List of all consoles on the system
- */
-static LIST_HEAD(consoles);
-static spinlock_t consoles_lock = SPIN_LOCK_UNLOCKED;
-
-static int read_io_int_handler(struct device *dev, struct io_op *ioop, struct irb *irb)
-{
-	struct console_line *cline;
-	struct ccw *ccw;
-	void *ptr;
-
-	/* Device End is set, we're done */
-	if (!(irb->scsw.dev_status & 0x04)) {
-		ioop->err = -EAGAIN;
-		return 0;
-	}
-
-	ccw = (struct ccw*) (u64) ioop->orb.addr;
-	ptr = (void*) (u64) ccw->addr;
-	cline = container_of(ptr, struct console_line, buf);
-
-	cline->len = strnlen((char*) cline->buf, CON_MAX_LINE_LEN-1);
-	cline->state = CON_STATE_IO;
-
-	ioop->err = 0;
-	return 0;
-}
-
-static void do_issue_read(struct console *con, struct io_op *ioop, struct ccw *ccws)
-{
-	struct console_line *cline;
-	int found;
-
-	found = 0;
-
-	atomic_dec(&con->dev->attention);
-
-	spin_lock(&con->lock);
-	list_for_each_entry(cline, &con->read_lines, lines) {
-		if (cline->state != CON_STATE_FREE)
-			continue;
-
-		cline->state = CON_STATE_PENDING;
-		found = 1;
-		break;
-	}
-
-	if (!found) {
-		/*
-		 * No unused console lines, time to allocate a new one
-		 */
-		cline = malloc(CON_LINE_ALLOC_SIZE, ZONE_NORMAL);
-		BUG_ON(!cline);
-
-		cline->state = CON_STATE_PENDING;
-		list_add_tail(&cline->lines, &con->read_lines);
-	}
-	spin_unlock(&con->lock);
-
-	/* clear the buffer to allow strlen on the result */
-	memset(cline->buf, 0, CON_MAX_LINE_LEN);
-
-	memset(ccws, 0, sizeof(struct ccw));
-
-	ccws[0].addr  = ADDR31(cline->buf);
-	ccws[0].count = CON_MAX_LINE_LEN - 1;
-	ccws[0].cmd   = 0x0a;
-	ccws[0].flags = CCW_FLAG_SLI;
-
-	memset(&ioop->orb, 0, sizeof(struct orb));
-	ioop->orb.lpm  = 0xff;
-	ioop->orb.addr = ADDR31(ccws);
-	ioop->orb.f    = 1;
-
-	ioop->handler = read_io_int_handler;
-	ioop->dtor = NULL;
-
-	submit_io(con->dev, ioop, CAN_SLEEP);
-}
-
-/**
- * console_flusher - iterates over a console's buffers and initiates the IO
- */
-static int console_flusher(void *data)
-{
-	struct console *con = data;
-	struct console_line *cline;
-	int free_count;
-	int ccw_count;
-
-	/* needed for the IO */
-	struct io_op ioop;
-	struct ccw ccws[CON_MAX_FLUSH_LINES];
-
-	for(;;) {
-		if (atomic_read(&con->dev->attention))
-			do_issue_read(con, &ioop, ccws);
-
-		spin_lock(&con->lock);
-
-		/*
-		 * free all the lines we just finished the IO for
-		 */
-		free_count = 0;
-		list_for_each_entry(cline, &con->write_lines, lines) {
-			if (cline->state != CON_STATE_IO)
-				continue;
-
-			cline->state = CON_STATE_FREE;
-			free_count++;
-
-			if (free_count > CON_MAX_FREE_LINES) {
-				list_del(&cline->lines);
-				free(cline);
-			}
-		}
-
-		/*
-		 * find at most CON_MAX_FLUSH_LINES of CON_STATE_PENDING
-		 * lines and shove necessary information into the right
-		 * CCW
-		 */
-		ccw_count = 0;
-		list_for_each_entry(cline, &con->write_lines, lines) {
-			if (ccw_count >= CON_MAX_FLUSH_LINES)
-				break;
-
-			if (cline->state != CON_STATE_PENDING)
-				continue;
-
-			cline->state = CON_STATE_IO;
-
-			ccws[ccw_count].addr = ADDR31(cline->buf);
-			ccws[ccw_count].count = cline->len;
-			ccws[ccw_count].cmd   = 0x01; /* write */
-			ccws[ccw_count].flags = CCW_FLAG_CC | CCW_FLAG_SLI;
-
-			ccw_count++;
-		}
-
-		/*
-		 * We don't need the lock anymore
-		 */
-		spin_unlock(&con->lock);
-
-		/*
-		 * Anything to do?
-		 */
-		if (!ccw_count) {
-			schedule();
-			continue;
-		}
-
-		/*
-		 * Clear Command-Chaining on the last CCW
-		 */
-		ccws[ccw_count-1].flags &= ~CCW_FLAG_CC;
-
-		/*
-		 * Now, set up the ORB and CCW
-		 */
-		memset(&ioop.orb, 0, sizeof(struct orb));
-		ioop.orb.lpm = 0xff;
-		ioop.orb.addr = ADDR31(ccws);
-		ioop.orb.f = 1;		/* format 1 CCW */
-
-		/*
-		 * Set up the operation handler pointers, and start the IO
-		 */
-		ioop.handler = NULL;
-		ioop.dtor = NULL;
-
-		submit_io(con->dev, &ioop, CAN_SLEEP);
-	}
-
-	return 0;
-}
-
-/**
- * register_console - generic device registration callback
- * @dev:	console device to register
- */
-static int register_console(struct device *dev)
-{
-	struct console *con;
-	struct console_line *cline;
-
-	dev_get(dev);
-
-	con = malloc(sizeof(struct console), ZONE_NORMAL);
-	BUG_ON(!con);
-
-	con->sys    = NULL;
-	con->dev    = dev;
-	con->lock   = SPIN_LOCK_UNLOCKED;
-	INIT_LIST_HEAD(&con->write_lines);
-	INIT_LIST_HEAD(&con->read_lines);
-
-	/*
-	 * alloc one read-line
-	 */
-	cline = malloc(CON_LINE_ALLOC_SIZE, ZONE_NORMAL);
-	BUG_ON(!cline);
-	cline->state = CON_STATE_FREE;
-	list_add(&cline->lines, &con->read_lines);
-
-	spin_lock(&consoles_lock);
-	list_add_tail(&con->consoles, &consoles);
-	spin_unlock(&consoles_lock);
-
-	return 0;
-}
-
-static void print_splash(struct console *con)
-{
-	int i;
-
-	for(i = 0; splash[i]; i++)
-		con_printf(con, splash[i]);
-
-	con_printf(con, "HVF VERSION " VERSION "\n\n");
-}
-
-struct console* start_oper_console(void)
-{
-	struct device *dev;
-
-	/*
-	 * We only start the operator console
-	 */
-
-	dev = find_device_by_ccuu(OPER_CONSOLE_CCUU);
-	BUG_ON(IS_ERR(dev));
-
-	return console_enable(dev);
-}
-
-void* console_enable(struct device *dev)
-{
-	char name[TASK_NAME_LEN+1];
-	struct console *con;
-
-	con = find_console(dev);
-	if (!IS_ERR(con))
-		return con;
-
-	if (register_console(dev))
-		return ERR_PTR(-ENOMEM);
-
-	/* try again, this time, we should always find it! */
-	con = find_console(dev);
-	if (IS_ERR(con))
-		return con;
-
-	atomic_inc(&con->dev->in_use);
-
-	snprintf(name, TASK_NAME_LEN, "%05X-conflsh", con->dev->sch);
-
-	create_task(name, console_flusher, con);
-
-	print_splash(con);
-
-	return con;
-}
-
-int con_read_pending(struct console *con)
-{
-	struct console_line *cline;
-	int ret = 0;
-
-	spin_lock(&con->lock);
-
-	list_for_each_entry(cline, &con->read_lines, lines) {
-		if (cline->state == CON_STATE_IO) {
-			ret = 1;
-			break;
-		}
-	}
-
-	spin_unlock(&con->lock);
-
-	return ret;
-}
-
-int con_read(struct console *con, u8 *buf, int size)
-{
-	struct console_line *cline;
-	int len;
-
-	spin_lock(&con->lock);
-
-	list_for_each_entry(cline, &con->read_lines, lines) {
-		if (cline->state == CON_STATE_IO)
-			goto found;
-	}
-
-	spin_unlock(&con->lock);
-
-	return -1;
-
-found:
-	len = (size-1 < cline->len) ? size-1 : cline->len;
-
-	memcpy(buf, cline->buf, len);
-	buf[len] = '\0';
-
-	cline->state = CON_STATE_FREE;
-
-	spin_unlock(&con->lock);
-
-	return len;
-}
-
-int con_write(struct console *con, u8 *buf, int len)
-{
-	int bytes = 0;
-	struct console_line *cline;
-
-	spin_lock(&con->lock);
-
-	list_for_each_entry(cline, &con->write_lines, lines) {
-		if (cline->state == CON_STATE_FREE)
-			goto found;
-	}
-
-	/* None found, can we allocate a new one? */
-	cline = malloc(CON_LINE_ALLOC_SIZE, ZONE_NORMAL);
-	if (!cline)
-		goto abort;
-
-	list_add_tail(&cline->lines, &con->write_lines);
-
-found:
-	cline->state = CON_STATE_PENDING;
-
-	cline->len = (len < CON_MAX_LINE_LEN) ?  len : CON_MAX_LINE_LEN;
-	memcpy(cline->buf, buf, cline->len);
-
-	/*
-	 * All done here. The async thread will pick up the line of text,
-	 * and issue the IO.
-	 */
-
-abort:
-	spin_unlock(&con->lock);
-
-	return bytes;
-}
-
-void for_each_console(void (*f)(struct console *con))
-{
-	struct console *con;
-
-	if (!f)
-		return;
-
-	spin_lock(&consoles_lock);
-	list_for_each_entry(con, &consoles, consoles)
-		f(con);
-	spin_unlock(&consoles_lock);
-}
-
-struct console* find_console(struct device *dev)
-{
-	struct console *con;
-
-	if (!dev)
-		return ERR_PTR(-ENOENT);
-
-	spin_lock(&consoles_lock);
-	list_for_each_entry(con, &consoles, consoles) {
-		if (con->dev == dev)
-			goto found;
-	}
-	con = ERR_PTR(-ENOENT);
-found:
-	spin_unlock(&consoles_lock);
-	return con;
-}
--- a/sys/drivers/dasd.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,276 +0,0 @@
-#include <device.h>
-#include <console.h>
-#include <list.h>
-#include <io.h>
-#include <sched.h>
-#include <vsprintf.h>
-
-static int d3390_snprintf(struct device *dev, char* buf, int len)
-{
-	return snprintf(buf, len, "%10d CYL ", dev->eckd.cyls);
-}
-
-static inline unsigned int ceil_quot(unsigned int d1, unsigned int d2)
-{
-        return (d1 + (d2 - 1)) / d2;
-}
-
-static inline int d3390_recs_per_track(int kl, int dl)
-{
-	int dn, kn;
-
-	dn = ceil_quot(dl + 6, 232) + 1;
-	if (kl) {
-		kn = ceil_quot(kl + 6, 232) + 1;
-		return 1729 / (10 + 9 + ceil_quot(kl + 6 * kn, 34) +
-			       9 + ceil_quot(dl + 6 * dn, 34));
-	} else
-		return 1729 / (10 + 9 + ceil_quot(dl + 6 * dn, 34));
-}
-
-static int d3390_reg(struct device *dev)
-{
-	struct io_op ioop;
-	struct ccw ccw;
-	int ret;
-	u8 buf[64];
-
-	switch(dev->model) {
-		case 0x02: /* 3390, 3390-1 */
-		case 0x06: /* 3390-2 */
-		case 0x0a: /* 3390-3 */
-		case 0x0c: /* 3390-9, 3390-27, 3390-J, 3390-54, 3390-JJ */
-			break;
-		default:
-			return -ENOENT;
-	}
-
-	/*
-	 * Set up IO op for Read Device Characteristics
-	 */
-	ioop.handler = NULL;
-	ioop.dtor = NULL;
-
-	memset(&ioop.orb, 0, sizeof(struct orb));
-	ioop.orb.lpm = 0xff;
-	ioop.orb.addr = ADDR31(&ccw);
-	ioop.orb.f = 1;
-
-	memset(&ccw, 0, sizeof(struct ccw));
-	ccw.cmd = 0x64; /* RDC */
-	ccw.flags = CCW_FLAG_SLI;
-	ccw.count = 64;
-	ccw.addr = ADDR31(buf);
-
-	/*
-	 * issue RDC
-	 */
-	ret = submit_io(dev, &ioop, CAN_LOOP);
-	if (ret)
-		return ret;
-
-	dev->eckd.cyls    = (buf[12] << 8) |
-		buf[13];
-	dev->eckd.tracks  = (buf[14] << 8) |
-		buf[15];
-	dev->eckd.recs    = d3390_recs_per_track(0, 4096);
-	dev->eckd.sectors = buf[16];
-	dev->eckd.len     = (buf[18] << 8) |
-		buf[19];
-
-	dev->eckd.formula = buf[22];
-	if (dev->eckd.formula == 1) {
-		dev->eckd.f1 = buf[23];
-		dev->eckd.f2 = (buf[24] << 8) |
-			buf[25];
-		dev->eckd.f3 = (buf[26] << 8) |
-			buf[27];
-		dev->eckd.f4 = 0;
-		dev->eckd.f5 = 0;
-	} else if (dev->eckd.formula == 2) {
-		dev->eckd.f1 = buf[23];
-		dev->eckd.f2 = buf[24];
-		dev->eckd.f3 = buf[25];
-		dev->eckd.f4 = buf[26];
-		dev->eckd.f5 = buf[27];
-	} else
-		return -EINVAL;
-
-	return 0;
-}
-
-static int d3390_read(struct device *dev, u8 *buf, int lba)
-{
-	struct io_op ioop;
-	struct ccw ccw[4];
-	u8 seek_data[6];
-	u8 search_data[5];
-	int ret;
-
-	u16 cc, hh, r;
-	int rpt = dev->eckd.recs;
-	int rpc = dev->eckd.tracks * rpt;
-
-	if (lba < 1)
-		return -EINVAL;
-
-	lba--;
-	cc = lba / rpc;
-	hh = (lba % rpc) / rpt;
-	r = (lba % rpc) % rpt;
-	r++;
-
-	/*
-	 * Set up IO op
-	 */
-	ioop.handler = NULL;
-	ioop.dtor = NULL;
-
-	memset(&ioop.orb, 0, sizeof(struct orb));
-	ioop.orb.lpm = 0xff;
-	ioop.orb.addr = ADDR31(ccw);
-	ioop.orb.f = 1;
-
-	memset(ccw, 0, sizeof(ccw));
-
-	/* SEEK */
-	ccw[0].cmd = 0x07;
-	ccw[0].flags = CCW_FLAG_CC | CCW_FLAG_SLI;
-	ccw[0].count = 6;
-	ccw[0].addr = ADDR31(seek_data);
-
-	seek_data[0] = 0;		/* zero */
-	seek_data[1] = 0;		/* zero */
-	seek_data[2] = cc >> 8;		/* Cc */
-	seek_data[3] = cc & 0xff;	/* cC */
-	seek_data[4] = hh >> 8;		/* Hh */
-	seek_data[5] = hh & 0xff;	/* hH */
-
-	/* SEARCH */
-	ccw[1].cmd = 0x31;
-	ccw[1].flags = CCW_FLAG_CC | CCW_FLAG_SLI;
-	ccw[1].count = 5;
-	ccw[1].addr = ADDR31(search_data);
-
-	search_data[0] = cc >> 8;
-	search_data[1] = cc & 0xff;
-	search_data[2] = hh >> 8;
-	search_data[3] = hh & 0xff;
-	search_data[4] = r;
-
-	/* TIC */
-	ccw[2].cmd = 0x08;
-	ccw[2].flags = 0;
-	ccw[2].count = 0;
-	ccw[2].addr = ADDR31(&ccw[1]);
-
-	/* READ DATA */
-	ccw[3].cmd = 0x86;
-	ccw[3].flags = 0;
-	ccw[3].count = 4096;
-	ccw[3].addr = ADDR31(buf);
-
-	/*
-	 * issue IO
-	 */
-	ret = submit_io(dev, &ioop, CAN_SLEEP);
-	return ret;
-}
-
-static struct device_type d3390 = {
-	.types		= LIST_HEAD_INIT(d3390.types),
-	.reg		= d3390_reg,
-	.interrupt	= NULL,
-	.enable		= NULL,
-	.snprintf	= d3390_snprintf,
-
-	.read		= d3390_read,
-
-	.type		= 0x3390,
-	.all_models	= 1,
-};
-
-/******************************************************************************/
-
-static int d9336_snprintf(struct device *dev, char* buf, int len)
-{
-	return snprintf(buf, len, "%10d BLK ", dev->fba.blks);
-}
-
-static int d9336_reg(struct device *dev)
-{
-	struct io_op ioop;
-	struct ccw ccw;
-	int ret;
-	u8 buf[64];
-
-	switch(dev->model) {
-		case 0x00: /* 9336-10 */
-		case 0x10: /* 9336-20 */
-			break;
-		default:
-			return -ENOENT;
-	}
-
-	/*
-	 * Set up IO op for Read Device Characteristics
-	 */
-	ioop.handler = NULL;
-	ioop.dtor = NULL;
-
-	memset(&ioop.orb, 0, sizeof(struct orb));
-	ioop.orb.lpm = 0xff;
-	ioop.orb.addr = ADDR31(&ccw);
-	ioop.orb.f = 1;
-
-	memset(&ccw, 0, sizeof(struct ccw));
-	ccw.cmd = 0x64; /* RDC */
-	ccw.flags = CCW_FLAG_SLI;
-	ccw.count = 64;
-	ccw.addr = ADDR31(buf);
-
-	/*
-	 * issue RDC
-	 */
-	ret = submit_io(dev, &ioop, CAN_LOOP);
-	if (ret)
-		return ret;
-
-	dev->fba.blk_size = (buf[4] << 8) | buf[5];
-	dev->fba.bpg = (buf[6] << 24)  |
-		(buf[7] << 16)  |
-		(buf[8] << 8)   |
-		buf[9];
-	dev->fba.bpp = (buf[10] << 24) |
-		(buf[11] << 16) |
-		(buf[12] << 8)  |
-		buf[13];
-	dev->fba.blks= (buf[14] << 24) |
-		(buf[15] << 16) |
-		(buf[16] << 8)  |
-		buf[17];
-
-	return 0;
-}
-
-static struct device_type d9336 = {
-	.types		= LIST_HEAD_INIT(d9336.types),
-	.reg		= d9336_reg,
-	.interrupt	= NULL,
-	.enable		= NULL,
-	.snprintf	= d9336_snprintf,
-	.type		= 0x9336,
-	.all_models	= 1,
-};
-
-int register_driver_dasd(void)
-{
-	int ret;
-
-	ret = register_device_type(&d3390);
-	if (ret)
-		return ret;
-
-	return register_device_type(&d9336);
-}
-
--- a/sys/drivers/device.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,365 +0,0 @@
-#include <list.h>
-#include <channel.h>
-#include <io.h>
-#include <slab.h>
-#include <device.h>
-#include <spinlock.h>
-#include <sched.h>
-
-struct senseid_struct {
-	u8 __reserved;
-	u16 cu_type;
-	u8 cu_model;
-	u16 dev_type;
-	u8 dev_model;
-} __attribute__((packed));
-
-struct static_device {
-	u16 dev_num;
-	struct senseid_struct sense;
-};
-
-#define END_OF_STATIC_DEV_LIST	0xffff
-
-/*
- * This defines staticly-configured devices - ugly but necessary for devices
- * that fail to identify themseleves via Sense-ID
- */
-static struct static_device static_device_list[] = {
-	{ .dev_num = 0x0009, .sense = { .dev_type = 0x3215, .dev_model = 0 } },
-	{ .dev_num = END_OF_STATIC_DEV_LIST },
-};
-
-/*
- * We need this device temporarily because submit_io & friends assume that
- * the device that's doing IO is on the device list. Unfortunately, that
- * isn't the case during IO device scanning. We register this device type,
- * and each device temporarily during the scan to make submit_io & friends
- * happy. When we're done scanning, we unregister this type.
- */
-static struct device_type __fake_dev_type = {
-	.types		= LIST_HEAD_INIT(__fake_dev_type.types),
-	.reg		= NULL,
-	.interrupt	= NULL,
-	.snprintf	= NULL,
-	.type		= 0,
-	.model		= 0,
-};
-
-static LIST_HEAD(device_types);
-static spinlock_t dev_types_lock;
-
-static LIST_HEAD(devices);
-static spinlock_t devs_lock;
-
-static void unregister_device_type(struct device_type *type)
-{
-	spin_lock(&dev_types_lock);
-	list_del(&type->types);
-	spin_unlock(&dev_types_lock);
-}
-
-/**
- * register_device_type - register a new device type/model
- * @dev:	device type to register
- */
-int register_device_type(struct device_type *dev)
-{
-	struct device_type *entry;
-
-	spin_lock(&dev_types_lock);
-
-	list_for_each_entry(entry, &device_types, types) {
-		if (dev == entry ||
-		    (dev->type == entry->type && dev->model == entry->model)) {
-			spin_unlock(&dev_types_lock);
-			return -EEXIST;
-		}
-	}
-
-	list_add_tail(&dev->types, &device_types);
-
-	spin_unlock(&dev_types_lock);
-
-	return 0;
-}
-
-/**
- * find_device_by_ccuu - find device struct by ccuu
- * @ccuu:	device ccuu to find
- */
-struct device *find_device_by_ccuu(u16 ccuu)
-{
-	struct device *dev;
-
-	spin_lock(&devs_lock);
-
-	list_for_each_entry(dev, &devices, devices) {
-		if (dev->ccuu == ccuu) {
-			dev_get(dev);
-			spin_unlock(&devs_lock);
-			return dev;
-		}
-	}
-
-	spin_unlock(&devs_lock);
-
-	return ERR_PTR(-ENOENT);
-}
-
-/**
- * find_device_by_sch - find device struct by subchannel number
- * @sch:	device subchannel
- */
-struct device *find_device_by_sch(u32 sch)
-{
-	struct device *dev;
-
-	spin_lock(&devs_lock);
-
-	list_for_each_entry(dev, &devices, devices) {
-		if (dev->sch == sch) {
-			dev_get(dev);
-			spin_unlock(&devs_lock);
-			return dev;
-		}
-	}
-
-	spin_unlock(&devs_lock);
-
-	return ERR_PTR(-ENOENT);
-}
-
-/**
- * find_device_by_type - find device struct by type/model
- * @type:	device type to find
- * @model:	device model to find
- */
-struct device *find_device_by_type(u16 type, u8 model)
-{
-	struct device *dev;
-
-	spin_lock(&devs_lock);
-
-	list_for_each_entry(dev, &devices, devices) {
-		if (dev->type == type &&
-		    dev->model == model) {
-			dev_get(dev);
-			spin_unlock(&devs_lock);
-			return dev;
-		}
-	}
-
-	spin_unlock(&devs_lock);
-
-	return ERR_PTR(-ENOENT);
-}
-
-/**
- * __register_device - helper to register a device
- * @dev:	device to register
- * @remove:	remove the device from the list first
- */
-static int __register_device(struct device *dev, int remove)
-{
-	struct device_type *type;
-	int err = 0;
-
-	spin_double_lock(&devs_lock, &dev_types_lock);
-
-	list_for_each_entry(type, &device_types, types) {
-		if (type->type == dev->type &&
-		    (type->all_models ||
-		     type->model == dev->model))
-			goto found;
-	}
-
-	err = -ENOENT;
-	type = NULL;
-
-found:
-	spin_double_unlock(&devs_lock, &dev_types_lock);
-
-	atomic_set(&dev->refcnt, 1);
-	atomic_set(&dev->in_use, 0);
-
-	dev->dev = type;
-
-	if (type && type->reg) {
-		err = type->reg(dev);
-
-		if (err)
-			dev->dev = NULL;
-	}
-
-	spin_double_lock(&devs_lock, &dev_types_lock);
-	if (remove)
-		list_del(&dev->devices);
-	list_add_tail(&dev->devices, &devices);
-	spin_double_unlock(&devs_lock, &dev_types_lock);
-
-	return err;
-}
-
-static int do_sense_id(struct device *dev, u16 dev_num, struct senseid_struct *buf)
-{
-	struct io_op ioop;
-	struct ccw ccw;
-	int ret;
-	int idx;
-	struct static_device *sdev;
-
-	/*
-	 * Check static configuration; if device is found (by device
-	 * number), use that information instead of issuing sense-id
-	 */
-	for(idx = 0; sdev = &static_device_list[idx],
-	    sdev->dev_num != END_OF_STATIC_DEV_LIST; idx++) {
-		if (sdev->dev_num == dev_num) {
-			memcpy(buf, &sdev->sense, sizeof(struct senseid_struct));
-			return 0;
-		}
-	}
-
-	/*
-	 * Set up IO op for Sense-ID
-	 */
-	ioop.handler = NULL;
-	ioop.dtor = NULL;
-
-	memset(&ioop.orb, 0, sizeof(struct orb));
-	ioop.orb.lpm = 0xff;
-	ioop.orb.addr = ADDR31(&ccw);
-	ioop.orb.f = 1;
-
-	memset(&ccw, 0, sizeof(struct ccw));
-	ccw.cmd = 0xe4; /* Sense-ID */
-	ccw.flags = CCW_FLAG_SLI;
-	ccw.count = sizeof(struct senseid_struct);
-	ccw.addr = ADDR31(buf);
-
-	/*
-	 * issue SENSE-ID
-	 */
-	ret = submit_io(dev, &ioop, CAN_LOOP);
-	BUG_ON(ret);
-
-	return ioop.err;
-}
-
-/*
- * Scan all subchannel ids, and register each device
- */
-void scan_devices(void)
-{
-	struct schib schib;
-	struct device *dev = NULL;
-	struct senseid_struct buf;
-	u32 sch;
-	int ret;
-
-	BUG_ON(register_device_type(&__fake_dev_type));
-
-	memset(&schib, 0, sizeof(struct schib));
-
-	/*
-	 * For each possible subchannel id...
-	 */
-	for(sch = 0x10000; sch <= 0x1ffff; sch++) {
-		/*
-		 * ...call store subchannel, to find out whether or not
-		 * there is a device
-		 */
-		if (store_sch(sch, &schib))
-			continue;
-
-		if (!schib.pmcw.v)
-			continue;
-
-		/*
-		 * The following code tries to take the following steps:
-		 *   - alloc device struct
-		 *   - enable the subchannel
-		 *   - MSCH
-		 *   - issue SENSE-ID IO op & wait for completion
-		 *   - register device with apropriate subsystem
-		 */
-
-		if (!dev) {
-			dev = malloc(sizeof(struct device), ZONE_NORMAL);
-
-			/*
-			 * if we failed to allocate memory, there's not much we can
-			 * do
-			 */
-			BUG_ON(!dev);
-
-			atomic_set(&dev->attention, 0);
-			INIT_LIST_HEAD(&dev->q_out);
-			dev->dev = &__fake_dev_type;
-		}
-
-		schib.pmcw.e = 1;
-
-		if (modify_sch(sch, &schib))
-			continue;
-
-		dev->sch   = sch;
-		BUG_ON(__register_device(dev, 0));
-		BUG_ON(dev->dev != &__fake_dev_type);
-
-		/*
-		 * Find out what the device is - whichever way is necessary
-		 */
-		ret = do_sense_id(dev, schib.pmcw.dev_num, &buf);
-
-		if (ret)
-			continue;
-
-		dev->type  = buf.dev_type;
-		dev->model = buf.dev_model;
-		dev->ccuu  = schib.pmcw.dev_num;
-
-		/* __register_device will remove the fake entry! */
-		if (__register_device(dev, 1)) {
-			/*
-			 * error registering ... the device struct MUST NOT
-			 * be freed as it has been added onto the devices
-			 * list. All that needs to be done is to reset the
-			 * enabled bit.
-			 */
-			schib.pmcw.e = 0;
-
-			/* msch could fail, but it shouldn't be fatal */
-			modify_sch(sch, &schib);
-		}
-
-		/* to prevent a valid device struct from being free'd */
-		dev = NULL;
-	}
-
-	unregister_device_type(&__fake_dev_type);
-
-	free(dev);
-}
-
-void list_devices(struct console *con, void (*f)(struct console*, struct device*))
-{
-	struct device *dev;
-
-	spin_lock(&devs_lock);
-
-	list_for_each_entry(dev, &devices, devices) {
-		dev_get(dev);
-		f(con, dev);
-		dev_put(dev);
-	}
-
-	spin_unlock(&devs_lock);
-}
-
-void register_drivers(void)
-{
-	register_driver_3215();
-	register_driver_dasd();
-}
--- a/sys/drivers/vdevice.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-#include <slab.h>
-#include <list.h>
-#include <vdevice.h>
-
-static int __setup_vdev_ded(struct virt_sys *sys,
-			    struct directory_vdev *dirdev,
-			    struct virt_device *vdev)
-{
-	struct device *rdev;
-
-	rdev = find_device_by_ccuu(dirdev->u.dedicate.rdev);
-	if (IS_ERR(rdev))
-		return PTR_ERR(rdev);
-
-	atomic_inc(&rdev->in_use);
-
-	vdev->u.dedicate.rdev = rdev;
-	vdev->type = rdev->type;
-	vdev->model = rdev->model;
-
-	return 0;
-}
-
-int alloc_virt_dev(struct virt_sys *sys, struct directory_vdev *dirdev,
-		   u32 sch)
-{
-	struct virt_device *vdev;
-	int ret = 0;
-
-	vdev = malloc(sizeof(struct virt_device), ZONE_NORMAL);
-	if (!vdev)
-		return -ENOMEM;
-
-	vdev->vtype = dirdev->type;
-	vdev->sch = sch;
-	vdev->pmcw.v = 1;
-	vdev->pmcw.dev_num = dirdev->vdev;
-	vdev->pmcw.lpm = 0x80;
-	vdev->pmcw.pim = 0x80;
-	vdev->pmcw.pom = 0xff;
-	vdev->pmcw.pam = 0x80;
-
-	switch(dirdev->type) {
-		case VDEV_CONS:
-			vdev->type = 0x3215;
-			vdev->model = 0;
-			break;
-		case VDEV_DED:
-			ret = __setup_vdev_ded(sys, dirdev, vdev);
-			break;
-		case VDEV_SPOOL:
-			vdev->type = dirdev->u.spool.type;
-			vdev->model = dirdev->u.spool.model;
-			// FIXME: hook it up to the spooler
-			break;
-		case VDEV_MDISK:
-			vdev->type = 0x3390;
-			vdev->model = 3;
-			// FIXME: hook it up to mdisk driver
-			break;
-		case VDEV_LINK:
-			goto free;
-		case VDEV_INVAL:
-			goto out;
-	}
-
-	list_add_tail(&vdev->devices, &sys->virt_devs);
-
-	return ret;
-
-free:
-	free(vdev);
-	return 0;
-
-out:
-	free(vdev);
-	return -EINVAL;
-}
--- a/sys/fs/Makefile	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-objs-fs := bdev.o edf.o
--- a/sys/fs/bdev.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-#include <device.h>
-#include <bdev.h>
-
-int bdev_read_block(struct device *dev, void *buf, int lba)
-{
-	if (!dev->dev->read)
-		return -EINVAL;
-
-	return dev->dev->read(dev, buf, lba);
-}
--- a/sys/fs/edf.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,171 +0,0 @@
-#include <mutex.h>
-#include <buddy.h>
-#include <slab.h>
-#include <device.h>
-#include <bdev.h>
-#include <ebcdic.h>
-#include <edf.h>
-
-struct fs *edf_mount(struct device *dev)
-{
-	struct page *page;
-	void *tmp;
-	struct fs *fs;
-	long ret;
-
-	page = alloc_pages(0, ZONE_NORMAL);
-	if (!page)
-		return ERR_PTR(-ENOMEM);
-	tmp = page_to_addr(page);
-
-	ret = -ENOMEM;
-	fs = malloc(sizeof(struct fs), ZONE_NORMAL);
-	if (!fs)
-		goto out_free;
-
-	/* First, read & verify the label */
-	ret = bdev_read_block(dev, tmp, EDF_LABEL_BLOCK_NO);
-	if (ret)
-		goto out_free;
-
-	mutex_init(&fs->lock);
-	INIT_LIST_HEAD(&fs->files);
-	fs->dev = dev;
-	fs->tmp_buf = tmp;
-
-	memcpy(&fs->ADT, tmp, sizeof(struct ADT));
-
-	ret = -EINVAL;
-	if ((fs->ADT.ADTIDENT != __ADTIDENT) ||
-	    (fs->ADT.ADTDBSIZ != EDF_SUPPORTED_BLOCK_SIZE) ||
-	    (fs->ADT.ADTOFFST != 0) ||
-	    (fs->ADT.ADTFSTSZ != sizeof(struct FST)))
-		goto out_free;
-
-	return fs;
-
-out_free:
-	free(fs);
-	free_pages(tmp, 0);
-	return ERR_PTR(ret);
-}
-
-extern struct console *oper_con;
-struct file *edf_lookup(struct fs *fs, char *fn, char *ft)
-{
-	char __fn[8];
-	char __ft[8];
-	struct page *page;
-	struct file *file;
-	struct file *tmpf;
-	struct FST *fst;
-	long ret;
-	int found;
-	int i;
-
-	file = malloc(sizeof(struct file), ZONE_NORMAL);
-	if (!file)
-		return ERR_PTR(-ENOMEM);
-
-	file->fs = fs;
-	file->buf = NULL;
-
-	memcpy(__fn, fn, 8);
-	memcpy(__ft, ft, 8);
-	ascii2ebcdic((u8 *) __fn, 8);
-	ascii2ebcdic((u8 *) __ft, 8);
-
-	mutex_lock(&fs->lock);
-
-	/* first, check the cache */
-	list_for_each_entry(tmpf, &fs->files, files) {
-		if (!memcmp((char*) tmpf->FST.FSTFNAME, __fn, 8) &&
-		    !memcmp((char*) tmpf->FST.FSTFTYPE, __ft, 8)) {
-			mutex_unlock(&fs->lock);
-			free(file);
-			return tmpf;
-		}
-	}
-
-	page = alloc_pages(0, ZONE_NORMAL);
-	if (!page) {
-		ret = -ENOMEM;
-		goto out_unlock;
-	}
-	file->buf = page_to_addr(page);
-
-	/* oh well, must do it the hard way ... read from disk */
-	ret = bdev_read_block(fs->dev, fs->tmp_buf, fs->ADT.ADTDOP);
-	if (ret)
-		goto out_unlock;
-
-	fst = fs->tmp_buf;
-
-	for(i=0,found=0; i<fs->ADT.ADTNFST; i++) {
-		if ((!memcmp(fst[i].FSTFNAME, __fn, 8)) &&
-		    (!memcmp(fst[i].FSTFTYPE, __ft, 8))) {
-			memcpy(&file->FST, &fst[i], sizeof(struct FST));
-			found = 1;
-			break;
-		}
-	}
-
-	if (!found) {
-		ret = -ENOENT;
-		goto out_unlock;
-	}
-
-	mutex_init(&file->lock);
-	list_add_tail(&file->files, &fs->files);
-
-	mutex_unlock(&fs->lock);
-
-	return file;
-
-out_unlock:
-	if (file && file->buf)
-		free_pages(file->buf, 0);
-	mutex_unlock(&fs->lock);
-	free(file);
-	return ERR_PTR(ret);
-}
-
-int edf_read_rec(struct file *file, char *buf, u32 recno)
-{
-	struct fs *fs = file->fs;
-	u32 fop, lrecl;
-	int ret;
-
-	if (file->FST.FSTNLVL != 0 ||
-	    file->FST.FSTPTRSZ != 4 ||
-	    file->FST.FSTLRECL > fs->ADT.ADTDBSIZ ||
-	    file->FST.FSTRECFM != FSTDFIX)
-		return -EINVAL;
-
-	mutex_lock(&file->lock);
-
-	fop = file->FST.FSTFOP;
-	lrecl = file->FST.FSTLRECL;
-
-	ret = bdev_read_block(fs->dev, file->buf, fop);
-	if (ret)
-		goto out;
-
-	memcpy(buf, file->buf + (recno * lrecl), lrecl);
-
-out:
-	mutex_unlock(&file->lock);
-
-	return ret;
-}
-
-void edf_file_free(struct file *file)
-{
-	struct fs *fs = file->fs;
-
-	mutex_lock(&fs->lock);
-	list_del(&file->files);
-	mutex_unlock(&fs->lock);
-
-	free(file);
-}
--- a/sys/hvf.directory	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-USER OPERATOR A
-    MACHINE ESA 1
-    STORAGE 17M
-    CONSOLE 0009 3215
-    SPOOL 000C 3505 READER
-    SPOOL 000D 3525 PUNCH
-    SPOOL 000E 1403 PRINT
-    MDISK 0191 3390 15 100 0192
-
-USER JEFFPC A
-    MACHINE ESA 1
-    STORAGE 64M
-    CONSOLE 0009 3215
-    SPOOL 000C 3505 READER
-    SPOOL 000D 3525 PUNCH
-    SPOOL 000E 1403 PRINT
-    MDISK 0190 3390 15 100 0192
-
-USER OBIWAN G
-    MACHINE ESA 1
-    STORAGE 2M
-    CONSOLE 0009 3215
-    SPOOL 000C 3505 READER
-    SPOOL 000D 3525 PUNCH
-    SPOOL 000E 1403 PRINT
-    MDISK 0193 3390 15 100 0192
--- a/sys/include/atomic.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/*
- * Based on atomic.h from Linux Kernel
- */
-
-#ifndef __ARCH_S390_ATOMIC__
-#define __ARCH_S390_ATOMIC__
-
-/*
- *  include/asm-s390/atomic.h
- *
- *  S390 version
- *    Copyright (C) 1999-2005 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
- *               Denis Joseph Barrow,
- *		 Arnd Bergmann (arndb@de.ibm.com)
- *
- *  Derived from "include/asm-i386/bitops.h"
- *    Copyright (C) 1992, Linus Torvalds
- *
- */
-
-/*
- * Atomic operations that C can't guarantee us.  Useful for
- * resource counting etc..
- * S390 uses 'Compare And Swap' for atomicity in SMP enviroment
- */
-
-typedef struct {
-	volatile int counter;
-} __attribute__ ((aligned (4))) atomic_t;
-#define ATOMIC_INIT(i)  { (i) }
-
-#define __CS_LOOP(ptr, op_val, op_string) ({				\
-	typeof(ptr->counter) old_val, new_val;				\
-	asm volatile(							\
-		"	l	%0,%2\n"				\
-		"0:	lr	%1,%0\n"				\
-		op_string "	%1,%3\n"				\
-		"	cs	%0,%1,%2\n"				\
-		"	jl	0b"					\
-		: "=&d" (old_val), "=&d" (new_val),			\
-		  "=Q" (((atomic_t *)(ptr))->counter)			\
-		: "d" (op_val),	 "Q" (((atomic_t *)(ptr))->counter)	\
-		: "cc", "memory");					\
-	new_val;							\
-})
-
-#define atomic_read(v)          ((v)->counter)
-#define atomic_set(v,i)         (((v)->counter) = (i))
-
-static __inline__ int atomic_add_return(int i, atomic_t * v)
-{
-	return __CS_LOOP(v, i, "ar");
-}
-#define atomic_add(_i, _v)		atomic_add_return(_i, _v)
-#define atomic_add_negative(_i, _v)	(atomic_add_return(_i, _v) < 0)
-#define atomic_inc(_v)			atomic_add_return(1, _v)
-#define atomic_inc_return(_v)		atomic_add_return(1, _v)
-#define atomic_inc_and_test(_v)		(atomic_add_return(1, _v) == 0)
-
-static __inline__ int atomic_sub_return(int i, atomic_t * v)
-{
-	return __CS_LOOP(v, i, "sr");
-}
-#define atomic_sub(_i, _v)		atomic_sub_return(_i, _v)
-#define atomic_sub_and_test(_i, _v)	(atomic_sub_return(_i, _v) == 0)
-#define atomic_dec(_v)			atomic_sub_return(1, _v)
-#define atomic_dec_return(_v)		atomic_sub_return(1, _v)
-#define atomic_dec_and_test(_v)		(atomic_sub_return(1, _v) == 0)
-
-static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t * v)
-{
-	       __CS_LOOP(v, ~mask, "nr");
-}
-
-static __inline__ void atomic_set_mask(unsigned long mask, atomic_t * v)
-{
-	       __CS_LOOP(v, mask, "or");
-}
-
-#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
-
-static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new)
-{
-	asm volatile(
-		"	cs	%0,%2,%1"
-		: "+d" (old), "=Q" (v->counter)
-		: "d" (new), "Q" (v->counter)
-		: "cc", "memory");
-	return old;
-}
-
-static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
-{
-	int c, old;
-	c = atomic_read(v);
-	for (;;) {
-		if (unlikely(c == u))
-			break;
-		old = atomic_cmpxchg(v, c, c + a);
-		if (likely(old == c))
-			break;
-		c = old;
-	}
-	return c != u;
-}
-
-#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
-
-#undef __CS_LOOP
-
-typedef struct {
-	volatile long long counter;
-} __attribute__ ((aligned (8))) atomic64_t;
-#define ATOMIC64_INIT(i)  { (i) }
-
-#define __CSG_LOOP(ptr, op_val, op_string) ({				\
-	typeof(ptr->counter) old_val, new_val;				\
-	asm volatile(							\
-		"	lg	%0,%2\n"				\
-		"0:	lgr	%1,%0\n"				\
-		op_string "	%1,%3\n"				\
-		"	csg	%0,%1,%2\n"				\
-		"	jl	0b"					\
-		: "=&d" (old_val), "=&d" (new_val),			\
-		  "=Q" (((atomic_t *)(ptr))->counter)			\
-		: "d" (op_val),	"Q" (((atomic_t *)(ptr))->counter)	\
-		: "cc", "memory" );					\
-	new_val;							\
-})
-
-#define atomic64_read(v)          ((v)->counter)
-#define atomic64_set(v,i)         (((v)->counter) = (i))
-
-static __inline__ long long atomic64_add_return(long long i, atomic64_t * v)
-{
-	return __CSG_LOOP(v, i, "agr");
-}
-#define atomic64_add(_i, _v)		atomic64_add_return(_i, _v)
-#define atomic64_add_negative(_i, _v)	(atomic64_add_return(_i, _v) < 0)
-#define atomic64_inc(_v)		atomic64_add_return(1, _v)
-#define atomic64_inc_return(_v)		atomic64_add_return(1, _v)
-#define atomic64_inc_and_test(_v)	(atomic64_add_return(1, _v) == 0)
-
-static __inline__ long long atomic64_sub_return(long long i, atomic64_t * v)
-{
-	return __CSG_LOOP(v, i, "sgr");
-}
-#define atomic64_sub(_i, _v)		atomic64_sub_return(_i, _v)
-#define atomic64_sub_and_test(_i, _v)	(atomic64_sub_return(_i, _v) == 0)
-#define atomic64_dec(_v)		atomic64_sub_return(1, _v)
-#define atomic64_dec_return(_v)		atomic64_sub_return(1, _v)
-#define atomic64_dec_and_test(_v)	(atomic64_sub_return(1, _v) == 0)
-
-static __inline__ void atomic64_clear_mask(unsigned long mask, atomic64_t * v)
-{
-	       __CSG_LOOP(v, ~mask, "ngr");
-}
-
-static __inline__ void atomic64_set_mask(unsigned long mask, atomic64_t * v)
-{
-	       __CSG_LOOP(v, mask, "ogr");
-}
-
-#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
-
-static __inline__ long long atomic64_cmpxchg(atomic64_t *v,
-					     long long old, long long new)
-{
-	asm volatile(
-		"	csg	%0,%2,%1"
-		: "+d" (old), "=Q" (v->counter)
-		: "d" (new), "Q" (v->counter)
-		: "cc", "memory");
-	return old;
-}
-
-static __inline__ int atomic64_add_unless(atomic64_t *v,
-					  long long a, long long u)
-{
-	long long c, old;
-	c = atomic64_read(v);
-	for (;;) {
-		if (unlikely(c == u))
-			break;
-		old = atomic64_cmpxchg(v, c, c + a);
-		if (likely(old == c))
-			break;
-		c = old;
-	}
-	return c != u;
-}
-
-#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
-
-#undef __CSG_LOOP
-
-#define smp_mb__before_atomic_dec()	smp_mb()
-#define smp_mb__after_atomic_dec()	smp_mb()
-#define smp_mb__before_atomic_inc()	smp_mb()
-#define smp_mb__after_atomic_inc()	smp_mb()
-
-#endif /* __ARCH_S390_ATOMIC__  */
--- a/sys/include/bdev.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-#ifndef __BDEV_H
-#define __BDEV_H
-
-extern int bdev_read_block(struct device *dev, void *buf, int lba);
-
-#endif
--- a/sys/include/buddy.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-#ifndef __BUDDY_H
-#define __BUDDY_H
-
-#include <page.h>
-
-extern void init_buddy_alloc(u64 start);
-extern struct page *alloc_pages(int order, int type);
-extern void free_pages(void *ptr, int order);
-
-#endif
--- a/sys/include/channel.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,302 +0,0 @@
-#ifndef __CHANNEL_H
-#define __CHANNEL_H
-
-/*
- * We only care about format-1 CCWs
- */
-struct ccw {
-	u8 cmd;			/* Command code */
-	u8 flags;		/* Flags */
-	u16 count;		/* Count */
-	u32 addr;		/* Data Address */
-} __attribute__((packed,aligned(8)));
-
-struct ccw0 {
-	u8 cmd;			/* Command code */
-	u8 addr_hi;		/* Data Address (bits 8-15) */
-	u16 addr_lo;		/* Data Address (bits 16-31) */
-	u8 flags;		/* Flags */
-	u8 _res0;
-	u16 count;		/* Count */
-} __attribute__((packed,aligned(8)));
-
-#define CCW_CMD_IPL_READ	0x02
-#define CCW_CMD_NOP		0x03
-#define CCW_CMD_BASIC_SENSE	0x04
-#define CCW_CMD_SENSE_ID	0xe4
-#define CCW_CMD_TIC		0x08
-
-#define CCW_FLAG_CD		0x80	/* Chain-Data */
-#define CCW_FLAG_CC		0x40	/* Chain-Command */
-#define CCW_FLAG_SLI		0x20	/* Suppress-Length-Indication */
-#define CCW_FLAG_SKP		0x10	/* Skip */
-#define CCW_FLAG_PCI		0x08	/* Program-Controlled-Interruption */
-#define CCW_FLAG_IDA		0x04	/* Indirect-Data-Address */
-#define CCW_FLAG_S		0x02	/* Suspend */
-#define CCW_FLAG_MIDA		0x01	/* Modified-Indirect-Data-Address */
-
-/*
- * ORB
- */
-struct orb {
-	/* word 0 */
-	u32 param;		/* Interruption Parameter */
-
-	/* word 1 */
-	u8 key:4,		/* Subchannel Key */
-	   s:1,			/* Suspend */
-	   c:1,			/* Streaming-Mode Control */
-	   m:1,			/* Modification Control */
-	   y:1;			/* Synchronization Control */
-	u8 f:1,			/* Format Control */
-	   p:1,			/* Prefetch Control */
-	   i:1,			/* Initial-Status-Interruption Control */
-	   a:1,			/* Address-Limit-Checking control */
-	   u:1,			/* Suppress-Suspend-Interruption Control */
-	   __zero1:1,
-	   h:1,			/* Format-2-IDAW Control */
-	   t:1;			/* 2K-IDAW Control */
-	u8 lpm;			/* Logical-Path Mask */
-	u8 l:1,			/* Incorrect-Length-Suppression Mode */
-	   d:1,			/* Modified-CCW-Indirect-Data-Addressing Control */
-	   __zero2:5,
-	   x:1;			/* ORB-Extension Control */
-
-	/* word 2 */
-	u32 addr;		/* Channel-Program Address */
-
-	/* word 3 */
-	u8 css_prio;		/* Channel-Subsystem Priority */
-	u8 __reserved1;
-	u8 cu_prio;		/* Control-Unit Priority */
-	u8 __reserved2;
-
-	/* word 4 - 7 */
-	u32 __reserved3;
-	u32 __reserved4;
-	u32 __reserved5;
-	u32 __reserved6;
-} __attribute__((packed,aligned(4)));
-
-enum SCSW_FC {
-	FC_CLEAR	= 0x10,
-	FC_HALT		= 0x20,
-	FC_START	= 0x40,
-};
-
-enum SCSW_SC {
-	SC_STATUS	= 0x01,
-	SC_SECONDARY	= 0x02,
-	SC_PRIMARY	= 0x04,
-	SC_INTERMED	= 0x08,
-	SC_ALERT	= 0x10,
-};
-
-struct scsw {
-	/* word 0 */
-	u16 key:4,		/* Subchannel key */
-	    s:1,		/* Suspend control */
-	    l:1,		/* ESW format */
-	    cc:2,		/* Deferred condition code */
-	    f:1,		/* Format */
-	    p:1,		/* Prefetch */
-	    i:1,		/* Initial-status interruption control */
-	    a:1,		/* Address-limit-checking control */
-	    u:1,		/* Supress-suspended interruption */
-	    z:1,		/* Zero condition code */
-	    e:1,		/* Extended control */
-	    n:1;		/* Path no operational */
-	u16 __zero:1,
-	    fc:3,		/* Function control */
-	    ac:8,		/* Activity control */
-	    sc:4;		/* Status control */
-
-	/* word 1 */
-	u32 addr;		/* CCW Address */
-
-	/* word 2 */
-	u8 dev_status;		/* Device status */
-	u8 sch_status;		/* Subchannel status */
-	u16 count;		/* Count */
-} __attribute__((packed));
-
-/* needed by IRB */
-struct irb_ext_status {
-	/* TODO: not implemented */
-	u32 w0, w1, w2, w3, w4;
-} __attribute__((packed));
-
-/* needed by IRB */
-struct irb_ext_control {
-	/* TODO: not implemented */
-	u32 w0, w1, w2, w3, w4, w5, w6, w7;
-} __attribute__((packed));
-
-/* needed by IRB */
-struct irb_ext_measurement {
-	/* TODO: not implemented */
-	u32 w0, w1, w2, w3, w4, w5, w6, w7;
-} __attribute__((packed));
-
-struct irb {
-	struct scsw scsw;			/* Subchannel-Status */
-	struct irb_ext_status ext_status;	/* Extended-Status */
-	struct irb_ext_control ext_control;	/* Extended-Control */
-	struct irb_ext_measurement ext_measure;	/* Extended-Measurement */
-} __attribute__((packed,aligned(4)));
-
-/* Path Management Control Word */
-struct pmcw {
-	/* word 0 */
-	u32 interrupt_param;	/* Interruption Parameter */
-
-	/* word 1*/
-	u8 __zero1:2,
-	   isc:3,		/* I/O-Interruption-Subclass Code */
-	   __zero2:3;
-	u8 e:1,			/* Enabled */
-	   lm:2,		/* Limit Mode */
-	   mm:2,		/* Measurement-Mode Enable */
-	   d:1,			/* Multipath Mode */
-	   t:1,			/* Timing Facility */
-	   v:1;			/* Device Number Valid */
-	u16 dev_num;		/* Device Number */
-
-	/* word 2 */
-	u8 lpm;			/* Logical-Path Mask */
-	u8 pnom;		/* Path-Not-Operational Mask */
-	u8 lpum;		/* Last-Path-Used Mask */
-	u8 pim;			/* Path-Installed Mask */
-
-	/* word 3 */
-	u16 mbi;		/* Measurement-Block Index */
-	u8 pom;			/* Path-Operational Mask */
-	u8 pam;			/* Path-Available Mask */
-
-	/* word 4 & 5 */
-	u8 chpid[8];		/* Channel-Path Identifiers */
-
-	/* word 6 */
-	u16 __zero3;
-	u16 __zero4:13,
-	    f:1,		/* Measurement Block Format Control */
-	    x:1,		/* Extended Measurement Word Mode Enable */
-	    s:1;		/* Concurrent Sense */
-};
-
-/* needed by schib */
-struct schib_measurement_block {
-	/* TODO: not implemented */
-	u32 w0, w1;
-};
-
-struct schib {
-	struct pmcw pmcw;		/* Path Management Control Word */
-	struct scsw scsw;		/* Subchannel Status Word */
-	union {
-		struct schib_measurement_block measure_block;
-	};
-	u32 model_dep_area;
-} __attribute__((packed,aligned(4)));
-
-static inline int store_sch(u32 sch, struct schib *schib)
-{
-	int cc;
-
-	asm volatile(
-		"lr	%%r1,%2\n"
-		"stsch	%1\n"
-		"ipm	%0\n"
-		"srl	%0,28\n"
-		: /* output */
-		  "=d" (cc),
-		  "=Q" (*schib)
-		: /* input */
-		  "d" (sch)
-		: /* clobbered */
-		  "cc", "r1", "memory"
-	);
-
-	if (cc == 3)
-		return -EINVAL;
-	return 0;
-}
-
-static inline int modify_sch(u32 sch, struct schib *schib)
-{
-	int cc;
-
-	asm volatile(
-		"lr	%%r1,%1\n"
-		"msch	0(%2)\n"
-		"ipm	%0\n"
-		"srl	%0,28\n"
-		: /* output */
-		  "=d" (cc)
-		: /* input */
-		  "d" (sch),
-		  "a" (schib)
-		: /* clobbered */
-		  "cc", "r1"
-	);
-
-	if (cc == 1 || cc == 2)
-		return -EBUSY;
-	if (cc == 3)
-		return -EINVAL;
-	return 0;
-}
-
-static inline int start_sch(u32 sch, struct orb *orb)
-{
-	int cc;
-
-	asm volatile(
-		"	lr	%%r1,%1\n"
-		"	ssch	0(%2)\n"
-		"	ipm	%0\n"
-		"	srl	%0,28\n"
-		: /* output */
-		  "=d" (cc)
-		: /* input */
-		  "d" (sch),
-		  "a" (orb)
-		: /* clobbered */
-		  "cc", "r1"
-	);
-
-	if (cc == 1 || cc == 2)
-		return -EBUSY;
-	if (cc == 3)
-		return -EINVAL;
-
-	return 0;
-}
-
-static inline int test_sch(u32 sch, struct irb *irb)
-{
-	int cc;
-
-	asm volatile(
-		"	lr	%%r1,%1\n"
-		"	tsch	0(%2)\n"
-		"	ipm	%0\n"
-		"	srl	%0,28\n"
-	: /* output */
-	  "=d" (cc)
-	: /* input */
-	  "d" (sch),
-	  "a" (irb)
-	: /* clobbered */
-	  "cc", "r1"
-	);
-
-	if (cc == 3)
-		return -EINVAL;
-
-	return 0;
-}
-
-extern void scan_devices(void);
-
-#endif
--- a/sys/include/compiler.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-#ifndef __COMPILER_H
-#define __COMPILER_H
-
-/*
- * For compatibility with some Linux kernel code
- */
-#define likely(x) (x)
-#define unlikely(x) (x)
-
-#endif
--- a/sys/include/config.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-/*
- * Base address within a guest's address space; used as the base address for
- * the IPL helper code.
- *
- * NOTE: It must be >= 16M, but <2G
- */
-#define GUEST_IPL_BASE		(16ULL * 1024ULL * 1024ULL)
-
-#define OPER_CONSOLE_CCUU	0x0009
-
-#endif
--- a/sys/include/console.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-#ifndef __CONSOLE_H
-#define __CONSOLE_H
-
-#include <device.h>
-#include <io.h>
-#include <spinlock.h>
-
-/* line allocation size */
-#define CON_LINE_ALLOC_SIZE	256
-
-/* maximum line length */
-#define CON_MAX_LINE_LEN	(CON_LINE_ALLOC_SIZE - sizeof(struct console_line))
-
-/* maximum number of free lines to keep around */
-#define CON_MAX_FREE_LINES	32
-
-/* number of lines of console text to flush at a time */
-#define CON_MAX_FLUSH_LINES	32
-
-/* line state */
-#define CON_STATE_FREE		0
-#define CON_STATE_PENDING	1
-#define CON_STATE_IO		2
-
-struct console_line {
-	struct list_head lines;
-	u16 len;
-	u16 state;
-	u8 buf[0];
-};
-
-struct console {
-	struct list_head consoles;
-	struct virt_sys *sys;
-	struct device *dev;
-	spinlock_t lock;
-	struct list_head write_lines;
-	struct list_head read_lines;
-};
-
-extern int console_interrupt(struct device *dev, struct irb *irb);
-extern struct console* start_oper_console(void);
-extern void* console_enable(struct device *dev);
-extern int con_read_pending(struct console *con);
-extern int con_read(struct console *con, u8 *buf, int size);
-extern int con_write(struct console *con, u8 *buf, int len);
-extern void for_each_console(void (*f)(struct console *con));
-extern struct console* find_console(struct device *dev);
-
-#endif
--- a/sys/include/cp.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-#ifndef __CP_H
-#define __CP_H
-
-#include <directory.h>
-
-#define CP_CMD_MAX_LEN	8
-
-/*
- * This file should contain only externally (from CP's point of view)
- * visible interfaces.
- */
-extern struct console *oper_con;
-
-extern void spawn_oper_cp(struct console *con);
-extern void spawn_user_cp(struct console *con, struct user *u);
-extern int invoke_cp_cmd(struct virt_sys *sys, char *cmd, int len);
-extern int invoke_cp_logon(struct console *con, char *cmd, int len);
-
-extern void list_users(struct console *con, void (*f)(struct console *con,
-						      struct virt_sys *sys));
-
-/* All the different ways to reset the system */
-extern void guest_power_on_reset(struct virt_sys *sys);
-extern void guest_system_reset_normal(struct virt_sys *sys);
-extern void guest_system_reset_clear(struct virt_sys *sys);
-extern void guest_load_normal(struct virt_sys *sys);
-extern void guest_load_clear(struct virt_sys *sys);
-
-extern void run_guest(struct virt_sys *sys);
-extern void handle_interception(struct virt_sys *sys);
-
-extern int handle_instruction(struct virt_sys *sys);
-extern int handle_instruction_priv(struct virt_sys *sys);
-
-typedef int (*intercept_handler_t)(struct virt_sys *sys);
-
-#define CP_CMD_AUTH(s,a)	do { \
-					if ((s)->directory->auth > (a)) \
-						return -EPERM; \
-				} while(0)
-
-#endif
--- a/sys/include/cpu.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-#ifndef __CPU_H
-#define __CPU_H
-
-static inline u64 getcpuid()
-{
-	u64 cpuid = ~0;
-
-	asm("stidp	0(%1)\n"
-	: /* output */
-	  "=m" (cpuid)
-	: /* input */
-	  "a" (&cpuid)
-	);
-
-	return cpuid;
-}
-
-static inline u16 getcpuaddr()
-{
-	u16 cpuaddr = ~0;
-
-	asm("stap	0(%1)\n"
-	: /* output */
-	  "=m" (cpuaddr)
-	: /* input */
-	  "a" (&cpuaddr)
-	);
-
-	return cpuaddr;
-}
-
-#endif
--- a/sys/include/dat.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,136 +0,0 @@
-#ifndef __DAT_H
-#define __DAT_H
-
-struct address_space {
-	struct dat_rte *region_table;
-	struct dat_ste *segment_table;
-};
-
-/* region/segment-table destination */
-struct dat_td {
-	u64 origin:52,		/* region/segment table origin */
-	    __reserved0:2,
-	    g:1,		/* subspace-group control */
-	    p:1,		/* private-space control */
-	    s:1,		/* storage-alteration-event ctl */
-	    x:1,		/* space-switch-event control */
-	    r:1,		/* real-space control */
-	    __reserved1:1,
-	    dt:2,		/* designation-type control */
-	    tl:2;		/* table length */
-} __attribute__((packed));
-
-#define DAT_TD_DT_RFT		3	/* region-first */
-#define DAT_TD_DT_RST		2	/* region-second */
-#define DAT_TD_DT_RTT		1	/* region-third */
-#define DAT_TD_DT_ST		0	/* segment */
-
-/* region-table entries (first, second, and third) */
-struct dat_rte {
-	u64 origin:52,		/* next-level-table origin */
-	    __reserved0:4,
-	    tf:2,		/* table offset (next lower tbl) */
-	    i:1,		/* region invalid */
-	    __reserved1:1,
-	    tt:2,		/* table-type bits (current tbl) */
-	    tl:2;		/* table length (next lower tbl) */
-} __attribute__((packed));
-
-/*
- * Constants for struct rte
- */
-#define DAT_RTE_TT_RFT		3	/* region-first */
-#define DAT_RTE_TT_RST		2	/* region-second */
-#define DAT_RTE_TT_RTT		1	/* region-third */
-
-#define ADDR_TO_RTE_ORIGIN(a)	((a) >> 12)
-#define RTE_ORIGIN_TO_ADDR(o)	((void*)(((u64)(o)) << 12))
-
-/* segment-table entries */
-struct dat_ste {
-	u64 origin:53,		/* page-table origin */
-	    __reserved0:1,
-	    p:1,		/* page-protection bit */
-	    __reserved1:3,
-	    i:1,		/* segment-invalid bit */
-	    c:1,		/* common-segment bit */
-	    tt:2,		/* table-type bits */
-	    __reserved2:2;
-} __attribute__((packed));
-
-#define DAT_STE_TT_ST		0	/* segment-table */
-
-#define ADDR_TO_STE_ORIGIN(a)	((a) >> 11)
-#define STE_ORIGIN_TO_ADDR(o)	((void*)(((u64)(o)) << 11))
-
-/* page-table entries */
-struct dat_pte {
-	u64 pfra:52,		/* page-frame real address */
-	    __zero0:1,
-	    i:1,		/* page-invalid bit */
-	    p:1,		/* page-protection bit */
-	    __zero1:1,
-	    __reserved:8;
-} __attribute__((packed));
-
-#define DAT_RX(addr)	(((u64)(addr)) >> 31)
-#define DAT_SX(addr)	((((u64)(addr)) >> 20) & 0x7ff)
-#define DAT_PX(addr)	((((u64)(addr)) >> 12) & 0xff)
-#define DAT_BX(addr)	(((u64)(addr))& 0xfff)
-
-extern int dat_insert_page(struct address_space *as, u64 phy, u64 virt);
-extern void setup_dat(void);
-extern void load_as(struct address_space *as);
-
-extern int virt2phy(struct address_space *as, u64 virt, u64 *phy);
-
-static inline void store_pasce(u64 *pasce)
-{
-	asm volatile(
-		"	stctg	1,1,0(%0)\n"
-	: /* output */
-	: /* input */
-	  "a" (pasce)
-	);
-}
-
-static inline void load_pasce(u64 pasce)
-{
-	if (!pasce)
-		return;
-
-	asm volatile(
-		"	lctlg	1,1,%0\n"
-	: /* output */
-	: /* input */
-	  "m" (pasce)
-	);
-}
-
-/* get host real address from guest real, using the currently loaded ASCE */
-static inline int virt2phy_current(u64 virt, u64 *phy)
-{
-	u64 result;
-	int cc;
-
-	asm volatile(
-		"	lrag	%0,0(%%r0,%2)\n"
-		"	ipm	%1\n"
-		"	srl	%1,28\n"
-	: /* output */
-	  "=d" (result),
-	  "=d" (cc)
-	: /* input */
-	  "a" (virt)
-	: /* clobber */
-	  "cc"
-	);
-
-	if (cc != 0)
-		return -EFAULT;
-
-	*phy = result;
-	return 0;
-}
-
-#endif
--- a/sys/include/device.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-#ifndef __DEVICE_H
-#define __DEVICE_H
-
-#include <atomic.h>
-#include <spinlock.h>
-#include <list.h>
-
-struct device;
-struct irb;
-
-struct device_type {
-	struct list_head types;
-	int (*reg)(struct device *dev);
-	int (*interrupt)(struct device *dev, struct irb *irb);
-	void* (*enable)(struct device *dev);
-	int (*snprintf)(struct device *dev, char *buf, int len);
-
-	/* the following ops are for the bdev wrapper layer */
-	int (*read)(struct device *dev, u8 *buf, int len);
-
-	u16 type;
-	u8 model;
-	u8 all_models;
-};
-
-struct device {
-	struct list_head devices;
-	u32 sch;			/* subchannel id */
-	u16 type;			/* 3330, 3215, ... */
-	u8 model;
-	u16 ccuu;			/* device number */
-	struct device_type *dev;
-
-	spinlock_t q_lock;
-	struct io_op *q_cur;
-	struct list_head q_out;
-	atomic_t attention;
-
-	atomic_t in_use;		/* is the device in use by someone? */
-
-	atomic_t refcnt;		/* internal reference counter */
-
-	union {
-		struct {
-			u16 cyls;	/* cylinders */
-			u16 tracks;	/* tracks per cylinder */
-			u16 len;	/* track length */
-			u16 recs;	/* number of records */
-			u8  sectors;	/* # sectors per track */
-			u8  formula;	/* capacity formula */
-			u16 f1,		/* factor f1 */
-			    f2,		/* factor f2 */
-			    f3,		/* factor f3 */
-			    f4,		/* factor f4 */
-			    f5;		/* factor f5 */
-		} eckd;
-		struct {
-			u16 blk_size;	/* block size */
-			u32 bpg;	/* blocks per cyclical group */
-			u32 bpp;	/* blocks per access possition */
-			u32 blks;	/* blocks */
-		} fba;
-	};
-};
-
-extern struct device *find_device_by_type(u16 type, u8 model);
-extern struct device *find_device_by_ccuu(u16 ccuu);
-extern struct device *find_device_by_sch(u32 sch);
-extern int register_device_type(struct device_type *dev);
-extern void scan_devices(void);
-extern void list_devices(struct console *con,
-			 void (*f)(struct console*, struct device*));
-extern void register_drivers(void);
-
-static inline void dev_get(struct device *dev)
-{
-	BUG_ON(atomic_read(&dev->refcnt) < 1);
-	atomic_inc(&dev->refcnt);
-}
-
-static inline void dev_put(struct device *dev)
-{
-	atomic_dec(&dev->refcnt);
-	BUG_ON(atomic_read(&dev->refcnt) < 1);
-}
-
-/* device specific register functions */
-extern int register_driver_3215(void);
-extern int register_driver_dasd(void);
-
-#endif
--- a/sys/include/directory.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-#ifndef __DIRECTORY_H
-#define __DIRECTORY_H
-
-#include <console.h>
-
-enum directory_vdevtype {
-	VDEV_INVAL = 0,			/* invalid */
-	VDEV_CONS,			/* a console */
-	VDEV_DED,			/* dedicated real device */
-	VDEV_SPOOL,			/* backed by the spool */
-	VDEV_MDISK,			/* a minidisk */
-	VDEV_LINK,			/* a link to another user's device */
-};
-
-struct directory_vdev {
-	enum directory_vdevtype type;	/* device type */
-	u16 vdev;			/* virtual dev # */
-
-	union {
-		/* VDEV_CONS */
-		struct {
-		} console;
-
-		/* VDEV_DED */
-		struct {
-			u16 rdev;	/* real device # */
-		} dedicate;
-
-		/* VDEV_SPOOL */
-		struct {
-			u16 type;
-			u8 model;
-		} spool;
-
-		/* VDEV_MDISK */
-		struct {
-			u16 cyloff;	/* first cylinder # */
-			u16 cylcnt;	/* cylinder count */
-			u16 rdev;	/* real DASD containing the mdisk */
-		} mdisk;
-
-		/* VDEV_LINK */
-		struct {
-		} link;
-	} u;
-};
-
-struct user {
-	char *userid;
-	struct task *task;
-
-	/* VM configuration */
-	u64 storage_size;
-
-	struct directory_vdev *devices;
-
-	u8 auth;
-};
-
-extern struct user *find_user_by_id(char *userid);
-
-#endif
--- a/sys/include/disassm.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-#ifndef __DISASSM_H
-#define __DISASSM_H
-
-enum inst_fmt {
-	IF_INV = 0,
-	IF_VAR,
-	IF_E,
-	IF_I,
-	IF_RI1,
-	IF_RI2,
-	IF_RIE,
-	IF_RIL1,
-	IF_RIL2,
-	IF_RIS,
-	IF_RR,
-	IF_RR_MASK,
-	IF_RRE,
-	IF_RRF1,
-	IF_RRF2,
-	IF_RRF3,
-	IF_RRR,
-	IF_RRS,
-	IF_RS1,
-	IF_RS2,
-	IF_RSI,
-	IF_RSL,
-	IF_RSY1,
-	IF_RSY2,
-	IF_RX,
-	IF_RX_MASK,
-	IF_RXE,
-	IF_RXF,
-	IF_RXY,
-	IF_S,
-	IF_SI,
-	IF_SIL,
-	IF_SIY,
-	IF_SS1,
-	IF_SS2,
-	IF_SS3,
-	IF_SS4,
-	IF_SS5,
-	IF_SSE,
-	IF_SSF,
-	IF_DIAG,
-};
-
-struct disassm_instruction {
-	union {
-		char *name;	/* instruction name; inst only */
-
-		void *ptr;	/* next level table; table only */
-	} u;
-
-	/* all */
-	char fmt;		/* instruction format */
-
-	/* table only */
-	char len;		/* table len */
-	char loc;		/* sub-opcode location offset in bits */
-};
-
-#define DA_INST(idx,ifmt,iname)		[idx] = { .fmt = IF_##ifmt,	.u.name = #iname, }
-#define DA_INST_TBL(idx,itbl,ilen,iloc)	[idx] = { .fmt = IF_VAR,	.u.ptr = (itbl), \
-						  .len = (ilen),	.loc = (iloc), }
-
-extern int disassm(u8 *bytes, char *buf, int buflen);
-
-#endif
--- a/sys/include/ebcdic.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-#ifndef __EBCDIC_H
-#define __EBCDIC_H
-
-extern u8 ascii2ebcdic_table[256];
-extern u8 ebcdic2ascii_table[256];
-
-/*
- * Generic translate buffer function.
- */
-static inline void __translate(u8 *buf, int len, const u8 *table)
-{
-	asm volatile(
-		"	sgr	%%r0,%%r0\n"		/* test byte = 0 */
-		"	la	%%r2,0(%0)\n"		/* buffer */
-		"	lgr	%%r3,%2\n"		/* length */
-		"	la	%%r4,0(%1)\n"		/* table */
-		"0:	tre	%%r2,%%r4\n"
-		"	brc	1,0b\n"
-		: /* output */
-		: /* input */
-		  "a" (buf),
-		  "a" (table),
-		  "d" (len)
-		: /* clobbered */
-		  "cc", "r0", "r2", "r3", "r4"
-	);
-}
-
-#define ascii2ebcdic(buf, len)	\
-			__translate((buf), (len), ascii2ebcdic_table)
-#define ebcdic2ascii(buf, len)  \
-			__translate((buf), (len), ebcdic2ascii_table)
-
-#endif
--- a/sys/include/edf.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-#ifndef __EDF_H
-#define __EDF_H
-
-#include <mutex.h>
-#include <device.h>
-
-struct ADT {
-	u32     ADTIDENT;       /* VOL START / LABEL IDENTIFIER */
-#define __ADTIDENT 0xC3D4E2F1   /* 'CMS1' in EBCDIC */
-	u8      ADTID[6];       /* VOL START / VOL IDENTIFIER */
-	u8      ADTVER[2];      /* VERSION LEVEL */
-	u32     ADTDBSIZ;       /* DISK BLOCK SIZE */
-	u32     ADTDOP;         /* DISK ORIGIN POINTER */
-	u32     ADTCYL;         /* NUM OF FORMATTED CYL ON DISK */
-	u32     ADTMCYL;        /* MAX NUM FORMATTED CYL ON DISK */
-	u32     ADTNUM;         /* Number of Blocks on disk */
-	u32     ADTUSED;        /* Number of Blocks used */
-	u32     ADTFSTSZ;       /* SIZE OF FST */
-	u32     ADTNFST;        /* NUMBER OF FST'S PER BLOCK */
-	u8      ADTDCRED[6];    /* DISK CREATION DATE (YYMMDDHHMMSS) */
-	u8      ADTFLGL;        /* LABEL FLAG BYTE (ADTFLGL) */
-#define ADTCNTRY        0x01    /* Century for disk creation date (0=19, 1=20),
-	                         * corresponds to ADTDCRED. */
-	u8      reserved[1];
-	u32     ADTOFFST;       /* DISK OFFSET WHEN RESERVED */
-	u32     ADTAMNB;        /* ALLOC MAP BLOCK WITH NEXT HOLE */
-	u32     ADTAMND;        /* DISP INTO HBLK DATA OF NEXT HOLE */
-	u32     ADTAMUP;        /* DISP INTO USER PART OF ALLOC MAP */
-	u32     ADTOFCNT;       /* Count of SFS open files for this ADT */
-	u8      ADTSFNAM[8];    /* NAME OF SHARED SEGMENT */
-};
-
-struct FST {
-	u8    FSTFNAME[8];       /* filename */
-	u8    FSTFTYPE[8];       /* filetype */
-	u8    FSTDATEW[2];       /* DATE LAST WRITTEN - MMDD */
-	u8    FSTTIMEW[2];       /* TIME LAST WRITTEN - HHMM */
-	u16   FSTWRPNT;          /* WRITE POINTER - ITEM NUMBER */
-	u16   FSTRDPNT;          /* READ POINTER - ITEM NUMBER */
-	u8    FSTFMODE[2];       /* FILE MODE - LETTER AND NUMBER */
-	u16   FSTRECCT;          /* NUMBER OF LOGICAL RECORDS */
-	u16   FSTFCLPT;          /* FIRST CHAIN LINK POINTER */
-	u8    FSTRECFM;          /* F*1 - RECORD FORMAT - F OR V */
-#define FSTDFIX        0xC6 /* Fixed record format (EBCDIC 'F') */
-#define FSTDVAR        0xE5 /* Variable record format (EBCDIC 'V') */
-	u8    FSTFLAGS;          /* F*2 - FST FLAG BYTE */
-#define FSTRWDSK       0x80 /* READ/WRITE DISK */
-#define FSTRODSK       0x00 /* READ/ONLY DISK */
-#define FSTDSFS        0x10 /* Shared File FST */
-#define FSTXRDSK       0x40 /* EXTENSION OF R/O DISK */
-#define FSTXWDSK       0xC0 /* EXTENSION OF R/W DISK */
-#define FSTEPL         0x20 /* EXTENDED PLIST */
-#define FSTDIA         0x40 /* ITEM AVAILABLE */
-#define FSTDRA         0x01 /* PREVIOUS RECORD NULL */
-#define FSTCNTRY       0x08 /* Century for date last written (0=19, 1=20),\\
-			       corresponds to FSTYEARW, FSTADATI. */
-#define FSTACTRD       0x04 /* ACTIVE FOR READING */
-#define FSTACTWR       0x02 /* ACTIVE FOR WRITING */
-#define FSTACTPT       0x01 /* ACTIVE FROM A POINT */
-#define FSTFILEA       0x07 /* THE FILE IS ACTIVE */
-	u32   FSTLRECL;          /* LOGICAL RECORD LENGTH */
-	u16   FSTBLKCT;          /* NUMBER OF 800 BYTE BLOCKS */
-	u16   FSTYEARW;          /* YEAR LAST WRITTEN */
-	u32   FSTFOP;            /* ALT. FILE ORIGIN POINTER */
-	u32   FSTADBC;           /* ALT. NUMBER OF DATA BLOCKS */
-	u32   FSTAIC;            /* ALT. ITEM COUNT */
-	u8    FSTNLVL;           /* NUMBER OF POINTER BLOCK LEVELS */
-	u8    FSTPTRSZ;          /* LENGTH OF A POINTER ELEMENT */
-	u8    FSTADATI[6];       /* ALT. DATE/TIME(YY MM DD HH MM SS) */
-	u8    FSTREALM;          /* Real filemode */
-	u8    FSTFLAG2;          /* F*3 - FST FLAG BYTE 2 FSTFLAG2 */
-#define FSTPIPEU       0x10 /* Reserved for CMS PIPELINES usage */
-	u8    reserved[2];
-};
-
-#define EDF_LABEL_BLOCK_NO		3
-
-#define EDF_SUPPORTED_BLOCK_SIZE	4096
-
-struct fs {
-	struct ADT ADT;
-	struct list_head files;
-	mutex_t lock;
-	struct device *dev;
-	void *tmp_buf;
-};
-
-struct file {
-	struct FST FST;
-	struct list_head files;
-	mutex_t lock;
-	struct fs *fs;
-	char *buf;
-};
-
-extern struct fs *edf_mount(struct device *dev);
-extern struct file *edf_lookup(struct fs *fs, char *fn, char *ft);
-extern int edf_read_rec(struct file *file, char *buf, u32 recno);
-
-#endif
--- a/sys/include/interrupt.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-#ifndef __INTERRUPT_H
-#define __INTERRUPT_H
-
-/*
- * I/O interruptions specific constants & structures
- */
-struct io_int_code {
-	u32 ssid;
-	u32 param;
-} __attribute__((packed));
-
-#define PSA_INT_GPR	((u64*) 0x200)
-#define PSA_TMP_PSW	((struct psw*) 0x280)
-
-#define IO_INT_OLD_PSW	((void*) 0x170)
-#define IO_INT_NEW_PSW	((void*) 0x1f0)
-#define IO_INT_CODE	((struct io_int_code*) 0xb8)
-
-#define EXT_INT_OLD_PSW	((void*) 0x130)
-#define EXT_INT_NEW_PSW	((void*) 0x1b0)
-#define EXT_INT_CODE	((u16*) 0x86)
-
-#define SVC_INT_OLD_PSW ((void*) 0x140)
-#define SVC_INT_NEW_PSW ((void*) 0x1c0)
-#define SVC_INT_CODE	((u16*) 0x8a)
-
-#define PGM_INT_OLD_PSW	((void*) 0x150)
-#define PGM_INT_NEW_PSW ((void*) 0x1d0)
-#define PGM_INT_ILC	((u8*) 0x8d)
-#define PGM_INT_CODE	((u16*) 0x8e)
-
-/*
- * Assembly stubs to call the C-handlers
- */
-extern void IO_INT(void);
-extern void EXT_INT(void);
-extern void SVC_INT(void);
-extern void PGM_INT(void);
-
-/**
- * local_int_disable - disable interruptions & return old mask
- */
-#define local_int_disable() ({ \
-	unsigned long __flags; \
-	__asm__ __volatile__ ( \
-		"stnsm 0(%1),0xfc" : "=m" (__flags) : "a" (&__flags) ); \
-	__flags; \
-	})
-
-/**
- * local_int_restore - restore interrupt mask
- * x:	mask to restore
- */
-#define local_int_restore(x) \
-	__asm__ __volatile__("ssm   0(%0)" : : "a" (&x), "m" (x) : "memory")
-
-/**
- * local_int_restore - restore interrupt mask
- * x:	mask to restore
- */
-static inline int interruptable()
-{
-	u8 x;
-
-	__asm__ __volatile__(
-		"stosm   0(%0),0x00"
-		: /* out */
-		: /* in */
-		 "a" (&x),
-		 "m" (x)
-		: /* clobber */
-		 "memory"
-	);
-
-	return (x & 0x43) != 0;
-}
-
-extern void set_timer(void);
-
-/*
- * The Supervisor-Service call table
- */
-#define SVC_SCHEDULE		0
-#define SVC_SCHEDULE_BLOCKED	1
-#define NR_SVC			2
-extern u64 svc_table[NR_SVC];
-
-/* Interrupt handlers */
-extern void __pgm_int_handler(void);
-extern void __ext_int_handler(void);
-extern void __io_int_handler(void);
-
-/* Interrupt handler stack pointer */
-extern u8 *int_stack_ptr;
-
-#endif
--- a/sys/include/io.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-#ifndef __IO_H
-#define __IO_H
-
-#include <channel.h>
-#include <atomic.h>
-#include <list.h>
-
-struct device;
-
-/*
- * Defines an I/O operation
- *
- * This structure contains any and all state one should need to service any
- * I/O interruption.
- */
-struct io_op {
-	struct orb orb;		/* Operation Request Block */
-
-	struct list_head list;	/* list of in-flight operations */
-
-	int (*handler)(struct device *dev, struct io_op *ioop, struct irb *irb);
-				/* I/O specific callback */
-	void (*dtor)(struct device *dev, struct io_op *ioop);
-				/* I/O specific destructor */
-
-	int err;		/* return code */
-	atomic_t done;		/* has the operation completed */
-};
-
-extern void init_io(void);
-extern int submit_io(struct device *dev, struct io_op *oop, int flags);
-
-#endif
--- a/sys/include/list.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,421 +0,0 @@
-/*
- * Based on list.h from Linux Kernel
- */
-
-#ifndef _LINUX_LIST_H
-#define _LINUX_LIST_H
-
-#define LIST_POISON1	((void*) 0x8585858585858585ULL)
-#define LIST_POISON2	((void*) 0x8686868686868686ULL)
-
-/*
- * Simple doubly linked list implementation.
- *
- * Some of the internal functions ("__xxx") are useful when
- * manipulating whole lists rather than single entries, as
- * sometimes we already know the next/prev entries and we can
- * generate better code by using them directly rather than
- * using the generic single-entry routines.
- */
-
-struct list_head {
-	struct list_head *next, *prev;
-};
-
-#define LIST_HEAD_INIT(name) { &(name), &(name) }
-
-#define LIST_HEAD(name) \
-	struct list_head name = LIST_HEAD_INIT(name)
-
-static inline void INIT_LIST_HEAD(struct list_head *list)
-{
-	list->next = list;
-	list->prev = list;
-}
-
-/*
- * Insert a new entry between two known consecutive entries.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_add(struct list_head *new,
-			      struct list_head *prev,
-			      struct list_head *next)
-{
-	next->prev = new;
-	new->next = next;
-	new->prev = prev;
-	prev->next = new;
-}
-
-/**
- * list_add - add a new entry
- * @new: new entry to be added
- * @head: list head to add it after
- *
- * Insert a new entry after the specified head.
- * This is good for implementing stacks.
- */
-static inline void list_add(struct list_head *new, struct list_head *head)
-{
-	__list_add(new, head, head->next);
-}
-
-
-/**
- * list_add_tail - add a new entry
- * @new: new entry to be added
- * @head: list head to add it before
- *
- * Insert a new entry before the specified head.
- * This is useful for implementing queues.
- */
-static inline void list_add_tail(struct list_head *new, struct list_head *head)
-{
-	__list_add(new, head->prev, head);
-}
-
-/*
- * Delete a list entry by making the prev/next entries
- * point to each other.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
- */
-static inline void __list_del(struct list_head * prev, struct list_head * next)
-{
-	next->prev = prev;
-	prev->next = next;
-}
-
-/**
- * list_del - deletes entry from list.
- * @entry: the element to delete from the list.
- * Note: list_empty() on entry does not return true after this, the entry is
- * in an undefined state.
- */
-static inline void list_del(struct list_head *entry)
-{
-	__list_del(entry->prev, entry->next);
-	entry->next = LIST_POISON1;
-	entry->prev = LIST_POISON2;
-}
-
-/**
- * list_replace - replace old entry by new one
- * @old : the element to be replaced
- * @new : the new element to insert
- *
- * If @old was empty, it will be overwritten.
- */
-static inline void list_replace(struct list_head *old,
-				struct list_head *new)
-{
-	new->next = old->next;
-	new->next->prev = new;
-	new->prev = old->prev;
-	new->prev->next = new;
-}
-
-static inline void list_replace_init(struct list_head *old,
-					struct list_head *new)
-{
-	list_replace(old, new);
-	INIT_LIST_HEAD(old);
-}
-
-/**
- * list_del_init - deletes entry from list and reinitialize it.
- * @entry: the element to delete from the list.
- */
-static inline void list_del_init(struct list_head *entry)
-{
-	__list_del(entry->prev, entry->next);
-	INIT_LIST_HEAD(entry);
-}
-
-/**
- * list_move - delete from one list and add as another's head
- * @list: the entry to move
- * @head: the head that will precede our entry
- */
-static inline void list_move(struct list_head *list, struct list_head *head)
-{
-	__list_del(list->prev, list->next);
-	list_add(list, head);
-}
-
-/**
- * list_move_tail - delete from one list and add as another's tail
- * @list: the entry to move
- * @head: the head that will follow our entry
- */
-static inline void list_move_tail(struct list_head *list,
-				  struct list_head *head)
-{
-	__list_del(list->prev, list->next);
-	list_add_tail(list, head);
-}
-
-/**
- * list_is_last - tests whether @list is the last entry in list @head
- * @list: the entry to test
- * @head: the head of the list
- */
-static inline int list_is_last(const struct list_head *list,
-				const struct list_head *head)
-{
-	return list->next == head;
-}
-
-/**
- * list_empty - tests whether a list is empty
- * @head: the list to test.
- */
-static inline int list_empty(const struct list_head *head)
-{
-	return head->next == head;
-}
-
-/**
- * list_empty_careful - tests whether a list is empty and not being modified
- * @head: the list to test
- *
- * Description:
- * tests whether a list is empty _and_ checks that no other CPU might be
- * in the process of modifying either member (next or prev)
- *
- * NOTE: using list_empty_careful() without synchronization
- * can only be safe if the only activity that can happen
- * to the list entry is list_del_init(). Eg. it cannot be used
- * if another CPU could re-list_add() it.
- */
-static inline int list_empty_careful(const struct list_head *head)
-{
-	struct list_head *next = head->next;
-	return (next == head) && (next == head->prev);
-}
-
-static inline void __list_splice(struct list_head *list,
-				 struct list_head *head)
-{
-	struct list_head *first = list->next;
-	struct list_head *last = list->prev;
-	struct list_head *at = head->next;
-
-	first->prev = head;
-	head->next = first;
-
-	last->next = at;
-	at->prev = last;
-}
-
-/**
- * list_splice - join two lists
- * @list: the new list to add.
- * @head: the place to add it in the first list.
- */
-static inline void list_splice(struct list_head *list, struct list_head *head)
-{
-	if (!list_empty(list))
-		__list_splice(list, head);
-}
-
-/**
- * list_splice_init - join two lists and reinitialise the emptied list.
- * @list: the new list to add.
- * @head: the place to add it in the first list.
- *
- * The list at @list is reinitialised
- */
-static inline void list_splice_init(struct list_head *list,
-				    struct list_head *head)
-{
-	if (!list_empty(list)) {
-		__list_splice(list, head);
-		INIT_LIST_HEAD(list);
-	}
-}
-
-/**
- * list_entry - get the struct for this entry
- * @ptr:	the &struct list_head pointer.
- * @type:	the type of the struct this is embedded in.
- * @member:	the name of the list_struct within the struct.
- */
-#define list_entry(ptr, type, member) \
-	container_of(ptr, type, member)
-
-/**
- * list_first_entry - get the first element from a list
- * @ptr:	the list head to take the element from.
- * @type:	the type of the struct this is embedded in.
- * @member:	the name of the list_struct within the struct.
- *
- * Note, that list is expected to be not empty.
- */
-#define list_first_entry(ptr, type, member) \
-	list_entry((ptr)->next, type, member)
-
-/**
- * list_for_each	-	iterate over a list
- * @pos:	the &struct list_head to use as a loop cursor.
- * @head:	the head for your list.
- */
-#define list_for_each(pos, head) \
-	for (pos = (head)->next; prefetch(pos->next), pos != (head); \
-		pos = pos->next)
-
-/**
- * __list_for_each	-	iterate over a list
- * @pos:	the &struct list_head to use as a loop cursor.
- * @head:	the head for your list.
- *
- * This variant differs from list_for_each() in that it's the
- * simplest possible list iteration code, no prefetching is done.
- * Use this for code that knows the list to be very short (empty
- * or 1 entry) most of the time.
- */
-#define __list_for_each(pos, head) \
-	for (pos = (head)->next; pos != (head); pos = pos->next)
-
-/**
- * list_for_each_prev	-	iterate over a list backwards
- * @pos:	the &struct list_head to use as a loop cursor.
- * @head:	the head for your list.
- */
-#define list_for_each_prev(pos, head) \
-	for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
-		pos = pos->prev)
-
-/**
- * list_for_each_safe - iterate over a list safe against removal of list entry
- * @pos:	the &struct list_head to use as a loop cursor.
- * @n:		another &struct list_head to use as temporary storage
- * @head:	the head for your list.
- */
-#define list_for_each_safe(pos, n, head) \
-	for (pos = (head)->next, n = pos->next; pos != (head); \
-		pos = n, n = pos->next)
-
-/**
- * list_for_each_entry	-	iterate over list of given type
- * @pos:	the type * to use as a loop cursor.
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- */
-#define list_for_each_entry(pos, head, member)				\
-	for (pos = list_entry((head)->next, typeof(*pos), member);	\
-	     &pos->member != (head);					\
-	     pos = list_entry(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_entry_reverse - iterate backwards over list of given type.
- * @pos:	the type * to use as a loop cursor.
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- */
-#define list_for_each_entry_reverse(pos, head, member)			\
-	for (pos = list_entry((head)->prev, typeof(*pos), member);	\
-	     prefetch(pos->member.prev), &pos->member != (head);	\
-	     pos = list_entry(pos->member.prev, typeof(*pos), member))
-
-/**
- * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
- * @pos:	the type * to use as a start point
- * @head:	the head of the list
- * @member:	the name of the list_struct within the struct.
- *
- * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
- */
-#define list_prepare_entry(pos, head, member) \
-	((pos) ? : list_entry(head, typeof(*pos), member))
-
-/**
- * list_for_each_entry_continue - continue iteration over list of given type
- * @pos:	the type * to use as a loop cursor.
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- *
- * Continue to iterate over list of given type, continuing after
- * the current position.
- */
-#define list_for_each_entry_continue(pos, head, member)			\
-	for (pos = list_entry(pos->member.next, typeof(*pos), member);	\
-	     prefetch(pos->member.next), &pos->member != (head);	\
-	     pos = list_entry(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_entry_from - iterate over list of given type from the current point
- * @pos:	the type * to use as a loop cursor.
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- *
- * Iterate over list of given type, continuing from current position.
- */
-#define list_for_each_entry_from(pos, head, member)			\
-	for (; prefetch(pos->member.next), &pos->member != (head);	\
-	     pos = list_entry(pos->member.next, typeof(*pos), member))
-
-/**
- * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
- * @pos:	the type * to use as a loop cursor.
- * @n:		another type * to use as temporary storage
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- */
-#define list_for_each_entry_safe(pos, n, head, member)			\
-	for (pos = list_entry((head)->next, typeof(*pos), member),	\
-		n = list_entry(pos->member.next, typeof(*pos), member);	\
-	     &pos->member != (head);					\
-	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
-
-/**
- * list_for_each_entry_safe_continue
- * @pos:	the type * to use as a loop cursor.
- * @n:		another type * to use as temporary storage
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- *
- * Iterate over list of given type, continuing after current point,
- * safe against removal of list entry.
- */
-#define list_for_each_entry_safe_continue(pos, n, head, member)			\
-	for (pos = list_entry(pos->member.next, typeof(*pos), member),		\
-		n = list_entry(pos->member.next, typeof(*pos), member);		\
-	     &pos->member != (head);						\
-	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
-
-/**
- * list_for_each_entry_safe_from
- * @pos:	the type * to use as a loop cursor.
- * @n:		another type * to use as temporary storage
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- *
- * Iterate over list of given type from current point, safe against
- * removal of list entry.
- */
-#define list_for_each_entry_safe_from(pos, n, head, member)			\
-	for (n = list_entry(pos->member.next, typeof(*pos), member);		\
-	     &pos->member != (head);						\
-	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
-
-/**
- * list_for_each_entry_safe_reverse
- * @pos:	the type * to use as a loop cursor.
- * @n:		another type * to use as temporary storage
- * @head:	the head for your list.
- * @member:	the name of the list_struct within the struct.
- *
- * Iterate backwards over list of given type, safe against removal
- * of list entry.
- */
-#define list_for_each_entry_safe_reverse(pos, n, head, member)		\
-	for (pos = list_entry((head)->prev, typeof(*pos), member),	\
-		n = list_entry(pos->member.prev, typeof(*pos), member);	\
-	     &pos->member != (head);					\
-	     pos = n, n = list_entry(n->member.prev, typeof(*n), member))
-
-#endif
--- a/sys/include/magic.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-#ifndef __MAGIC_H
-#define __MAGIC_H
-
-#define MAGIC_PSW_IDLE_CODE		0x1D1E
-
-#define SLAB_MAGIC			0xe2d3c1c2
-#define SLAB_CONT_MAGIC			0xe2d3c1c3
-
-#endif
--- a/sys/include/mm.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-#ifndef __MM_H
-#define __MM_H
-
-extern u64 memsize;
-
-/* Turn Low-address protection on */
-static inline void lap_on(void)
-{
-	u64 cr0;
-
-	asm volatile(
-		"stctg	0,0,%0\n"	/* get cr0 */
-		"oi	%1,0x10\n"	/* enable */
-		"lctlg	0,0,%0\n"	/* reload cr0 */
-	: /* output */
-	: /* input */
-	  "m" (cr0),
-	  "m" (*(u64*) (((u8*)&cr0) + 4))
-	);
-}
-
-#endif
--- a/sys/include/mutex.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-#ifndef __MUTEX_H
-#define __MUTEX_H
-
-#include <list.h>
-#include <atomic.h>
-#include <spinlock.h>
-#include <sched.h>
-#include <interrupt.h>
-
-typedef struct {
-	atomic_t state;
-	spinlock_t queue_lock;
-	struct list_head queue;
-} mutex_t;
-
-#define UNLOCKED_MUTEX(name)	mutex_t name = { \
-			.state = ATOMIC_INIT(1), \
-			.queue = LIST_HEAD_INIT(name.queue), \
-			.queue_lock = SPIN_LOCK_UNLOCKED, \
-		}
-
-static inline void mutex_init(mutex_t *lock)
-{
-	atomic_set(&lock->state, 1);
-	INIT_LIST_HEAD(&lock->queue);
-	lock->queue_lock = SPIN_LOCK_UNLOCKED;
-}
-
-extern void __mutex_lock(mutex_t *lock);
-
-static inline void mutex_lock(mutex_t *lock)
-{
-	/*
-	 * if we are not interruptable, we shouldn't call any functions that
-	 * may sleep - e.g., mutex_lock
-	 */
-	BUG_ON(!interruptable());
-
-	if (unlikely(atomic_add_unless(&lock->state, -1, 0) == 0))
-		__mutex_lock(lock); /* the slow-path */
-}
-
-static inline void mutex_unlock(mutex_t *lock)
-{
-	struct task *task;
-
-	spin_lock(&lock->queue_lock);
-
-	if (likely(list_empty(&lock->queue))) {
-		/* no one is waiting on the queue */
-		atomic_inc(&lock->state);
-		spin_unlock(&lock->queue_lock);
-		return;
-	}
-
-	/*
-	 * someone is waiting on the queue, let's dequeue them & make them
-	 * runnable again
-	 */
-	task = list_first_entry(&lock->queue, struct task, blocked_list);
-	list_del(&task->blocked_list);
-	spin_unlock(&lock->queue_lock);
-
-	make_runnable(task);
-}
-
-#endif
--- a/sys/include/nucleus.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-#ifndef __NUCLEUS_H
-#define __NUCLEUS_H
-
-#include <config.h>
-#include <compiler.h>
-#include <errno.h>
-#include <string.h>
-
-extern volatile u64 ticks;
-
-extern struct datetime ipltime;
-
-/* The beginning of it all... */
-extern void start(u64 __memsize, u32 __iplsch);
-
-/* borrowed from Linux */
-#define container_of(ptr, type, member) ({                      \
-         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
-         (type *)( (char *)__mptr - offsetof(type,member) );})
-
-/* borrowed from Linux */
-#define offsetof(type, member) __builtin_offsetof(type,member)
-
-static inline void lpswe(void *psw)
-{
-	asm volatile(
-		"	lpswe	0(%0)\n"
-	: /* output */
-	: /* input */
-	  "a" (psw)
-	: /* clobbered */
-	  "cc"
-	);
-}
-
-#define BUG()		do { \
-				asm volatile(".byte 0x00,0x00" : : : "memory"); \
-			} while(0)
-#define BUG_ON(cond)	do { \
-				if (unlikely(cond)) \
-					BUG(); \
-			} while(0)
-
-/*
- * This should be as simple as a cast, but unfortunately, the BUG_ON check
- * is there to make sure we never submit a truncated address to the channels
- *
- * In the future, the io code should check if IDA is necessary, and in that
- * case allocate an IDAL & set the IDA ccw flag. Other parts of the system
- * that require 31-bit address should do whatever their equivalent action
- * is.
- */
-static inline u32 ADDR31(void *ptr)
-{
-	u64 ip = (u64) ptr;
-
-	BUG_ON(ip & ~0x7fffffffull);
-
-	return (u32) ip;
-}
-
-/*
- * stdio.h equivalents
- */
-struct console;
-
-extern int vprintf(struct console *con, const char *fmt, va_list args)
-        __attribute__ ((format (printf, 2, 0)));
-extern int con_printf(struct console *con, const char *fmt, ...)
-        __attribute__ ((format (printf, 2, 3)));
-
-/*
- * stdarg.h equivalents
- */
-
-#endif
--- a/sys/include/page.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-#ifndef __PAGE_H
-#define __PAGE_H
-
-#include <list.h>
-
-#define PAGE_SHIFT	12
-#define PAGE_SIZE	(1<<PAGE_SHIFT)
-#define PAGE_MASK	(PAGE_SIZE-1)
-
-#define PAGE_INFO_BASE	((struct page*) 0x400000)
-
-#define ZONE_NORMAL	0
-#define ZONE_LOW	1
-
-#define ZONE_NORMAL_MAX_ORDER	(64-PAGE_SHIFT)
-#define ZONE_LOW_MAX_ORDER	(31-PAGE_SHIFT)
-
-/*
- * This structure describes a page of memory
- */
-struct page {
-	union {
-		struct list_head buddy;	/* buddy allocator list */
-		struct list_head guest;	/* guest storage list */
-	};
-};
-
-/*
- * Externs
- */
-extern void init_pages(void);
-
-/*
- * Static inlines
- */
-static inline struct page *page_num_to_ptr(u64 pnum)
-{
-	struct page *base = PAGE_INFO_BASE;
-
-	return &base[pnum];
-}
-
-static inline void *page_to_addr(struct page *page)
-{
-	u64 pagenum = (((u64) page) - ((u64) PAGE_INFO_BASE)) / sizeof(struct page);
-
-	return (void*) (pagenum << PAGE_SHIFT);
-}
-
-static inline struct page *addr_to_page(void *addr)
-{
-	struct page *base = PAGE_INFO_BASE;
-
-	return &base[((u64) addr) >> PAGE_SHIFT];
-}
-
-static inline int IS_LOW_ZONE(struct page *page)
-{
-	return ((u64) page_to_addr(page)) < (2UL*1024*1024*1024);
-}
-
-static inline int ZONE_TYPE(struct page *page)
-{
-	return IS_LOW_ZONE(page) ? ZONE_LOW : ZONE_NORMAL;
-}
-
-#endif
--- a/sys/include/sched.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-#ifndef __SCHED_H
-#define __SCHED_H
-
-#include <list.h>
-#include <page.h>
-#include <dat.h>
-#include <clock.h>
-#include <interrupt.h>
-
-#define CAN_SLEEP		1	/* safe to sleep */
-#define CAN_LOOP		2	/* safe to busy-wait */
-
-#define TASK_RUNNING		0
-#define TASK_SLEEPING		1
-#define TASK_LOCKED		2
-
-#define STACK_FRAME_SIZE	160
-
-#define SCHED_SLICE_MS		30	/* 30ms scheduler slice */
-#define SCHED_TICKS_PER_SLICE	(HZ / SCHED_SLICE_MS)
-
-#define HZ			100	/* number of ticks per second */
-
-struct psw {
-	u8 _zero0:1,
-	   r:1,			/* PER Mask (R)			*/
-	   _zero1:3,
-	   t:1,			/* DAT Mode (T)			*/
-	   io:1,		/* I/O Mask (IO)		*/
-	   ex:1;		/* External Mask (EX)		*/
-
-	u8 key:4,		/* Key				*/
-	   _zero2:1,
-	   m:1,			/* Machine-Check Mask (M)	*/
-	   w:1,			/* Wait State (W)		*/
-	   p:1;			/* Problem State (P)		*/
-
-	u8 as:2,		/* Address-Space Control (AS)	*/
-	   cc:2,		/* Condition Code (CC)		*/
-	   prog_mask:4;		/* Program Mask			*/
-
-	u8 _zero3:7,
-	   ea:1;		/* Extended Addressing (EA)	*/
-
-	u32 ba:1,		/* Basic Addressing (BA)	*/
-	    _zero4:31;
-
-	u64 ptr;
-};
-
-/*
- * saved registers for guests
- *
- * NOTE: some registers are saved in the SIE control block!
- */
-struct guest_regs {
-	u64 gpr[16];
-	u32 ar[16];
-	u64 fpr[64];
-	u32 fpcr;
-};
-
-/* saved registers for CP tasks */
-struct regs {
-	struct psw psw;
-	u64 gpr[16];
-	u64 cr1;
-};
-
-/*
- * These states mirror those described in chapter 4 of SA22-7832-06
- */
-enum virt_cpustate {
-	GUEST_STOPPED = 0,
-	GUEST_OPERATING,
-	GUEST_LOAD,
-	GUEST_CHECKSTOP,
-};
-
-#include <sie.h>
-
-struct virt_cpu {
-	/* the SIE control block is picky about alignment */
-	struct sie_cb sie_cb;
-
-	struct guest_regs regs;
-	u64 cpuid;
-
-	enum virt_cpustate state;
-};
-
-#define TASK_NAME_LEN		16
-
-/*
- * This structure describes a running process.
- */
-struct task {
-	struct regs regs;		/* saved registers */
-
-	struct list_head run_queue;	/* runnable list */
-	struct list_head proc_list;	/* processes list */
-	struct list_head blocked_list;	/* blocked on mutex/etc. list */
-
-	u64 slice_end_time;		/* end of slice time (ticks) */
-
-	struct virt_cpu *cpu;		/* guest cpu */
-
-	int state;			/* state */
-
-	char name[TASK_NAME_LEN+1];	/* task name */
-};
-
-struct virt_sys {
-	struct task *task;		/* the virtual CPU task */
-	struct user *directory;		/* the directory information */
-
-	struct console *con;		/* the login console */
-	int print_ts;			/* print timestamps */
-
-	struct list_head guest_pages;	/* list of guest pages */
-	struct list_head virt_devs;	/* list of guest virtual devs */
-	struct list_head online_users;	/* list of online users */
-
-	struct address_space as;	/* the guest storage */
-};
-
-extern void init_sched(void);		/* initialize the scheduler */
-extern struct task* create_task(char *name, int (*f)(void*), void*);
-					/* create a new task */
-extern void __schedule(struct psw *,
-		       int newstate);	/* scheduler helper - use with caution */
-extern void __schedule_svc(void);
-extern void __schedule_blocked_svc(void);
-
-extern void make_runnable(struct task *task);
-
-extern void list_tasks(struct console *con,
-		       void (*f)(struct console *, struct task*));
-
-/**
- * current - the current task's task struct
- */
-#define current		extract_task()
-
-#define PSA_CURRENT	((struct task**) 0x290)
-
-/**
- * extract_task - return the current task struct
- */
-static inline struct task *extract_task(void)
-{
-	return *PSA_CURRENT;
-}
-
-/**
- * set_task_ptr - set the stack's task struct pointer
- * @task:	task struct pointer to be made current
- */
-static inline void set_task_ptr(struct task *task)
-{
-	*PSA_CURRENT = task;
-}
-
-/**
- * schedule - used to explicitly yield the cpu
- */
-static inline void schedule(void)
-{
-	/*
-	 * if we are not interruptable, we shouldn't call any functions that
-	 * may sleep - schedule() is guaranteed to sleep :)
-	 */
-	BUG_ON(!interruptable());
-
-	asm volatile(
-		"	svc	%0\n"
-	: /* output */
-	: /* input */
-	  "i" (SVC_SCHEDULE)
-	);
-}
-
-/**
- * schedule_blocked - used to explicitly yield the cpu without readding the
- * task to the runnable queue
- */
-static inline void schedule_blocked(void)
-{
-	/*
-	 * if we are not interruptable, we shouldn't call any functions that
-	 * may sleep - schedule() is guaranteed to sleep :)
-	 */
-	BUG_ON(!interruptable());
-
-	asm volatile(
-		"	svc	%0\n"
-	: /* output */
-	: /* input */
-	  "i" (SVC_SCHEDULE_BLOCKED)
-	);
-}
-
-#endif
--- a/sys/include/sie.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-#ifndef __SIE_H
-#define __SIE_H
-
-/*
- * Taken from linux/arch/s390/include/asm/kvm_host.h
- */
-
-#include <atomic.h>
-
-/*
- * Constants for sie_cb->cpuflags
- */
-#define CPUSTAT_HOST		0x80000000
-#define CPUSTAT_WAIT		0x10000000
-#define CPUSTAT_ECALL_PEND	0x08000000
-#define CPUSTAT_STOP_INT	0x04000000
-#define CPUSTAT_IO_INT		0x02000000
-#define CPUSTAT_EXT_INT		0x01000000
-#define CPUSTAT_RUNNING		0x00800000
-#define CPUSTAT_RETAINED	0x00400000
-#define CPUSTAT_TIMING_SUB	0x00020000
-#define CPUSTAT_SIE_SUB		0x00010000
-#define CPUSTAT_RRF		0x00008000
-#define CPUSTAT_SLSV		0x00004000
-#define CPUSTAT_SLSR		0x00002000
-#define CPUSTAT_ZARCH		0x00000800
-#define CPUSTAT_MCDS		0x00000100
-#define CPUSTAT_SM		0x00000080
-#define CPUSTAT_G		0x00000008
-#define CPUSTAT_J		0x00000002
-#define CPUSTAT_P		0x00000001
-
-struct sie_cb {
-	atomic_t	cpuflags;		/* 0x0000 */
-	u32		prefix;			/* 0x0004 */
-	u8		reserved8[32];		/* 0x0008 */
-	u64		cputm;			/* 0x0028 */
-	u64		ckc;			/* 0x0030 */
-	u64		epoch;			/* 0x0038 */
-	u8		reserved40[4];		/* 0x0040 */
-#define LCTL_CR0 0x8000
-	u16		lctl;			/* 0x0044 */
-	s16		icpua;			/* 0x0046 */
-	u32		ictl;			/* 0x0048 */
-	u32		eca;			/* 0x004c */
-	u8		icptcode;		/* 0x0050 */
-	u8		reserved51;		/* 0x0051 */
-	u16		ihcpu;			/* 0x0052 */
-	u8		reserved54[2];		/* 0x0054 */
-	u16		ipa;			/* 0x0056 */
-	u32		ipb;			/* 0x0058 */
-	u32		scaoh;			/* 0x005c */
-	u8		reserved60;		/* 0x0060 */
-	u8		ecb;			/* 0x0061 */
-	u8		reserved62[2];		/* 0x0062 */
-	u32		scaol;			/* 0x0064 */
-	u8		reserved68[4];		/* 0x0068 */
-	u32		todpr;			/* 0x006c */
-	u8		reserved70[16];		/* 0x0070 */
-	u64		gmsor;			/* 0x0080 */
-	u64		gmslm;			/* 0x0088 */
-	struct psw	gpsw;			/* 0x0090 */
-	u64		gg14;			/* 0x00a0 */
-	u64		gg15;			/* 0x00a8 */
-	u8		reservedb0[30];		/* 0x00b0 */
-	u16		iprcc;			/* 0x00ce */
-	u8		reservedd0[48];		/* 0x00d0 */
-	u64		gcr[16];		/* 0x0100 */
-	u64		gbea;			/* 0x0180 */
-	u8		reserved188[120];	/* 0x0188 */
-} __attribute__((aligned(256),packed));
-
-#define VCPU_ZARCH(vcpu)	(atomic_read(&((vcpu)->sie_cb.cpuflags)) & CPUSTAT_ZARCH)
-
-#endif
--- a/sys/include/slab.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-#ifndef __SLAB_H
-#define __SLAB_H
-
-#include <list.h>
-#include <spinlock.h>
-#include <page.h>
-
-struct slab {
-	u32 magic;			/* magic */
-	spinlock_t lock;		/* lock to protect entire slab */
-	struct list_head slab_pages;	/* list of pages */
-	struct slab *first;		/* pointer to first slab page */
-	u16 objsize;			/* effective object size */
-	u16 startoff;			/* first object offset */
-	u16 count;			/* number of objects in this page */
-	u16 used;			/* number of used objects */
-	u8 bitmap[0];			/* allocation bitmap */
-} __attribute__((packed));
-
-extern int init_slab(void);
-
-extern struct slab *create_slab(u16 objsize, u8 align);
-extern void free_slab(struct slab *slab);
-
-extern void *malloc(int size, int type);
-extern void free(void *ptr);
-
-#endif
--- a/sys/include/spinlock.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-#ifndef __SPINLOCK_H
-#define __SPINLOCK_H
-
-/*
- * Heavily based on Linux's spinlock implementation
- */
-
-typedef struct {
-	volatile unsigned int lock;
-} spinlock_t;
-
-#define SPIN_LOCK_UNLOCKED	(spinlock_t) { 0 }
-
-static inline int __compare_and_swap(volatile unsigned int *lock,
-		unsigned int old, unsigned int new)
-{
-	asm volatile(
-		"	cs	%0,%3,%1"
-		: "=d" (old), "=Q" (*lock)
-		: "0" (old), "d" (new), "Q" (*lock)
-		: "cc", "memory" );
-	return old;
-}
-
-#define spin_is_locked(x) ((x)->lock != 0)
-
-#define SPIN_RETRY 1000
-
-extern void __spin_lock_wait(spinlock_t *lp, unsigned int pc);
-extern int __spin_trylock_retry(spinlock_t *lp, unsigned int pc);
-
-/**
- * spin_lock - lock a spinlock
- * @lock:	lock to lock
- */
-static inline void spin_lock(spinlock_t *lock)
-{
-	unsigned long pc = 1 | (unsigned long) __builtin_return_address(0);
-
-	if (unlikely(__compare_and_swap(&lock->lock, 0, pc) != 0))
-		__spin_lock_wait(lock, pc);
-}
-
-/**
- * spin_trylock - attempt to try to acquire a lock, but do not spin if
- * acquisition would fail
- * @lock:	lock to lock
- */
-static inline int spin_trylock(spinlock_t *lock)
-{
-	unsigned long pc = 1 | (unsigned long) __builtin_return_address(0);
-
-	if (likely(__compare_and_swap(&lock->lock, 0, pc) == 0))
-		return 1;
-	return __spin_trylock_retry(lock, pc);
-}
-
-/**
- * spin_unlock - unlock a lock
- * @lock:	lock to unlock
- */
-static inline void spin_unlock(spinlock_t *lock)
-{
-	__compare_and_swap(&lock->lock, lock->lock, 0);
-}
-
-extern void spin_lock_intsave(spinlock_t *lock, unsigned long *mask);
-extern void spin_unlock_intrestore(spinlock_t *lock, unsigned long mask);
-
-static inline void spin_double_lock(spinlock_t *l1, spinlock_t *l2)
-{
-	if (l1 < l2) {
-		spin_lock(l1);
-		spin_lock(l2);
-	} else {
-		spin_lock(l2);
-		spin_lock(l1);
-	}
-}
-
-static inline void spin_double_unlock(spinlock_t *l1, spinlock_t *l2)
-{
-	if (l1 < l2) {
-		spin_unlock(l2);
-		spin_unlock(l1);
-	} else {
-		spin_unlock(l1);
-		spin_unlock(l2);
-	}
-}
-
-#endif
--- a/sys/include/splash.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-#ifndef __SPLASH_H
-#define __SPLASH_H
-
-extern char *splash[];
-
-#endif
--- a/sys/include/vcpu.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-#ifndef __VCPU_H
-#define __VCPU_H
-
-#include <sched.h>
-
-/*****************************************************************************/
-/* Guest exception queuing                                                   */
-
-enum PROG_EXCEPTION {
-	PROG_OPERAND		= 0x0001,
-	PROG_PRIV		= 0x0002,
-	PROG_EXEC		= 0x0003,
-	PROG_PROT		= 0x0004,
-	PROG_ADDR		= 0x0005,
-	PROG_SPEC		= 0x0006,
-	PROG_DATA		= 0x0007,
-};
-
-extern void queue_prog_exception(struct virt_sys *sys, enum PROG_EXCEPTION type, u64 param);
-
-/*****************************************************************************/
-/* Guest register reading & address calculation                              */
-
-static inline u64 __guest_gpr(struct virt_cpu *cpu, int gpr)
-{
-	u64 ret = cpu->regs.gpr[gpr];
-
-	if (!(atomic_read(&cpu->sie_cb.cpuflags) & CPUSTAT_ZARCH))
-		ret &= 0xffffffffULL;
-
-	return ret;
-}
-
-static inline u64 __guest_addr(struct virt_cpu *cpu, u64 disp, int x, int b)
-{
-	u64 mask;
-
-	if (cpu->sie_cb.gpsw.ea && cpu->sie_cb.gpsw.ba)
-		mask = ~0;
-	else if (!cpu->sie_cb.gpsw.ea && cpu->sie_cb.gpsw.ba)
-		mask = 0x7fffffff;
-	else if (!cpu->sie_cb.gpsw.ea && !cpu->sie_cb.gpsw.ba)
-		mask = 0x00ffffff;
-	else
-		BUG();
-
-	return (disp +
-		(x ? __guest_gpr(cpu, x) : 0) +
-		(b ? __guest_gpr(cpu, b) : 0)) & mask;
-}
-
-/*****************************************************************************/
-/* SIE Interception Param parsing & instruction decode                       */
-
-#define IP_TO_RAW(sie)		((((u64)(sie).ipa) << 32) | ((u64)(sie).ipb))
-
-static inline u64 RAW_S_1(struct virt_cpu *cpu)
-{
-	u64 raw = IP_TO_RAW(cpu->sie_cb);
-
-	return __guest_addr(cpu,
-			    (raw >> 16) & 0xfff,
-			    (raw) >> 28 & 0xf,
-			    0);
-}
-
-#endif
--- a/sys/include/vdevice.h	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-#ifndef __VDEVICE_H
-#define __VDEVICE_H
-
-#include <list.h>
-#include <directory.h>
-#include <sched.h>
-
-struct virt_device {
-	struct list_head devices;
-	enum directory_vdevtype vtype;	/* VDEV_CONS, VDEV_DED, ... */
-	u32 sch;			/* subchannel id */
-	u16 type;			/* 3330, 3215, ... */
-	u8 model;
-
-	union {
-		struct {
-			struct device *rdev;
-					/* real device */
-		} dedicate;
-	} u;
-
-	struct pmcw pmcw;		/* path info */
-	struct scsw scsw;		/* subchannel-status */
-};
-
-extern int alloc_virt_dev(struct virt_sys *sys,
-		struct directory_vdev *dirdev, u32 sch);
-
-#endif
--- a/sys/mm/Makefile	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-objs-mm := buddy.o page.o slab.o dat.o
--- a/sys/mm/buddy.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,209 +0,0 @@
-/*
- * Copyright (c) 2007 Josef 'Jeff' Sipek
- */
-
-#include <list.h>
-#include <page.h>
-#include <mm.h>
-#include <buddy.h>
-#include <spinlock.h>
-
-/*
- * Lists of free page ranges
- */
-static struct list_head orders_normal[64-PAGE_SHIFT];
-static struct list_head orders_low[31-PAGE_SHIFT];
-
-static spinlock_t orders_lock = SPIN_LOCK_UNLOCKED;
-
-static void __init_buddy_alloc(u64 base, int pages, int max_order,
-			       struct list_head *orders)
-{
-	int order;
-	struct page *p;
-
-	for(order=0; order < max_order; order++) {
-		INIT_LIST_HEAD(&orders[order]);
-
-		if (pages & (1 << order)) {
-			p = page_num_to_ptr(base >> PAGE_SHIFT);
-
-			list_add(&p->buddy, &orders[order]);
-
-			base += (PAGE_SIZE << order);
-		}
-	}
-}
-
-/*
- * Initialize the buddy allocator. This is rather simple, and the only
- * complication is that we must keep track of storage below 2GB separately
- * since some IO related structures can address only the first 2GB. *sigh*
- */
-void init_buddy_alloc(u64 start)
-{
-	u64 normal_pages;
-	u64 low_pages;
-
-	if (memsize > 2UL*1024*1024*1024) {
-		/* There are more than 2GB of storage */
-		low_pages = (2UL*1024*1024*1024 - start) >> PAGE_SHIFT;
-		normal_pages = (memsize - start) >> PAGE_SHIFT;
-		normal_pages -= low_pages;
-	} else {
-		/* All the storage is under the 2GB mark */
-		low_pages = (memsize - start) >> PAGE_SHIFT;
-		normal_pages = 0;
-	}
-
-	/* let's add all the free low storage to the lists */
-	__init_buddy_alloc(start, low_pages, ZONE_LOW_MAX_ORDER, orders_low);
-
-	/* now, let's add all the free storage above 2GB */
-	__init_buddy_alloc(2UL*1024*1024*1024, normal_pages, ZONE_NORMAL_MAX_ORDER,
-			   orders_normal);
-}
-
-static struct page *__do_alloc_pages(int order, struct list_head *orders)
-{
-	struct page *page;
-
-	if (!list_empty(&orders[order])) {
-		page = list_first_entry(&orders[order], struct page, buddy);
-
-		list_del(&page->buddy);
-
-		return page;
-	}
-
-	return NULL;
-}
-
-static struct page *__alloc_pages(int order, int type)
-{
-	struct page *p;
-
-	/* Do we have to use ZONE_LOW? */
-	if (type == ZONE_LOW)
-		goto zone_low;
-
-	p = __do_alloc_pages(order, orders_normal);
-	if (p)
-		return p;
-
-	/* If there was no ZONE_NORMAL page, let's try ZONE_LOW */
-
-zone_low:
-	return __do_alloc_pages(order, orders_low);
-}
-
-/*
- * Split a given (actual) order allocation into an allocation of wanted
- * order, and return the rest of pages to the unused lists
- *
- * E.g.,
- *
- * pages (base):
- *
- * +---+---+---+---+---+---+---+---+
- * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
- * +---+---+---+---+---+---+---+---+
- *
- * actual = 3
- * wanted = 1
- *
- * return order 2 range back to free pool:
- *
- *                 +---+---+---+---+
- *                 | 4 | 5 | 6 | 7 |
- *                 +---+---+---+---+
- *
- * return order 1 range back to free pool:
- *
- *         +---+---+
- *         | 2 | 3 |
- *         +---+---+
- *
- * The End. Now, pages 2-7 are back in the free pool, and pages 0&1 are an
- * order 1 allocation.
- *
- */
-static void __chip_pages(struct page *base, int actual, int wanted)
-{
-	struct page *p;
-	struct list_head *orders;
-
-	orders = (IS_LOW_ZONE(base) ? orders_low : orders_normal);
-
-	for(; actual > wanted; actual--) {
-		p = &base[1 << (actual-1)];
-		list_add(&p->buddy, &orders[actual-1]);
-	}
-}
-
-/**
- * alloc_pages - allocate a series of consecutive pages
- * @order:	allocate 2^order consecutive pages
- * @type:	type of pages (<2GB, or anywhere)
- */
-struct page *alloc_pages(int order, int type)
-{
-	struct page *page;
-	int gord;
-	unsigned long mask;
-	int max_order;
-
-	spin_lock_intsave(&orders_lock, &mask);
-
-	/* easy way */
-	page = __alloc_pages(order, type);
-	if (page)
-		goto out;
-
-	/*
-	 * There is no page-range of the given order, let's try to find the
-	 * smallest one larger and split it
-	 */
-
-	max_order = (type == ZONE_LOW ?
-			ZONE_LOW_MAX_ORDER : ZONE_NORMAL_MAX_ORDER);
-
-	for(gord=order+1; gord < max_order; gord++) {
-		if (gord >= max_order)
-			break;
-
-		page = __alloc_pages(gord, type);
-		if (!page)
-			continue;
-
-		__chip_pages(page, gord, order);
-
-		goto out;
-	}
-
-	/* alright, totally out of memory */
-	page = NULL;
-
-out:
-	spin_unlock_intrestore(&orders_lock, mask);
-
-	return page;
-}
-
-void free_pages(void *ptr, int order)
-{
-	struct page *base = addr_to_page(ptr);
-	unsigned long mask;
-	struct list_head *orders;
-
-	orders = IS_LOW_ZONE(base) ? orders_low : orders_normal;
-
-	spin_lock_intsave(&orders_lock, &mask);
-	list_add(&base->buddy, &orders[order]);
-	spin_unlock_intrestore(&orders_lock, mask);
-
-	/*
-	 * TODO: a more complex thing we could try is to coallesce adjecent
-	 * page ranges into one higher order one (defrag)
-	 */
-}
--- a/sys/mm/dat.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-#include <page.h>
-#include <buddy.h>
-#include <dat.h>
-#include <mm.h>
-
-static void *alloc_table(int order)
-{
-	struct page *p;
-
-	p = alloc_pages(order, ZONE_NORMAL);
-	BUG_ON(!p);
-	memset(page_to_addr(p), 0xff, PAGE_SIZE << order);
-
-	return page_to_addr(p);
-}
-
-/**
- * dat_insert_page - insert a virt->phy mapping into an address space
- * @as:		address space to add the mapping to
- * @phy:	physical address to add
- * @virt:	virtual address to add
- */
-int dat_insert_page(struct address_space *as, u64 phy, u64 virt)
-{
-	struct dat_rte *region;
-	struct dat_ste *segment;
-	struct dat_pte *page;
-	void *ptr;
-
-	region = as->region_table;
-
-	if (!region) {
-		if (!as->segment_table)
-			/*
-			 * Need to allocate the segment table
-			 *
-			 * max of 2048 * 8-byte entries = 16 kbytes
-			 */
-			as->segment_table = alloc_table(2);
-
-		segment = as->segment_table;
-
-		goto walk_segment;
-	}
-
-	BUG_ON(DAT_RX(virt)); // FIXME: we don't support storage >2GB
-
-	if (region->origin == 0xfffffffffffffUL) {
-		/*
-		 * Need to allocate the segment table
-		 *
-		 * max of 2048 * 8-byte entries = 16 kbytes
-		 */
-		ptr = alloc_table(2);
-
-		region->origin = ADDR_TO_RTE_ORIGIN((u64) ptr);
-
-		region->tf = 0; /* FIXME: is this right? */
-		region->i = 0;
-		region->tt = DAT_RTE_TT_RTT;
-		region->tl = 3; /* FIXME: is this right? */
-		region->__reserved0 = 0;
-		region->__reserved1 = 0;
-	}
-
-	segment = RTE_ORIGIN_TO_ADDR(region->origin);
-
-walk_segment:
-	segment += DAT_SX(virt);
-
-	if (segment->origin == 0x1fffffffffffffUL) {
-		/*
-		 * Need to allocate the page table
-		 *
-		 * max of 256 * 8-byte entries = 2048 bytes
-		 */
-		ptr = alloc_table(0);
-
-		segment->origin = ADDR_TO_STE_ORIGIN((u64) ptr);
-		segment->p = 0;
-		segment->i = 0;
-		segment->c = 0;
-		segment->tt = DAT_STE_TT_ST;
-		segment->__reserved0 = 0;
-		segment->__reserved1 = 0;
-		segment->__reserved2 = 0;
-	}
-
-	page = STE_ORIGIN_TO_ADDR(segment->origin);
-	page += DAT_PX(virt);
-
-	page->pfra = phy >> PAGE_SHIFT;
-	page->i = 0;
-	page->p = 0;
-	page->__zero0 = 0;
-	page->__zero1 = 0;
-	page->__reserved = 0;
-
-	return 0;
-}
-
-void setup_dat(void)
-{
-	/* nothing to do! */
-}
-
-void load_as(struct address_space *as)
-{
-	struct dat_td cr1;
-
-	BUG_ON(!as->segment_table);
-
-	/*
-	 * Load up the PASCE (cr1)
-	 */
-	memset(&cr1, 0, sizeof(struct dat_td));
-	cr1.origin = ((u64)as->segment_table) >> 12;
-	cr1.dt = DAT_TD_DT_ST;
-	cr1.tl = 3;
-
-	asm volatile(
-		"	lctlg	1,1,%0\n"
-	: /* output */
-	: /* input */
-	  "m" (cr1)
-	);
-}
--- a/sys/mm/page.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2007 Josef 'Jeff' Sipek
- */
-
-#include <list.h>
-#include <page.h>
-#include <mm.h>
-
-/*
- * Main storage size
- */
-u64 memsize;
-
-/*
- * Initialize fields in a struct page
- */
-static void __init_page(struct page *page)
-{
-	INIT_LIST_HEAD(&page->buddy);
-}
-
-/*
- * Initialize struct page for each available page
- */
-void init_pages(void)
-{
-	u64 pnum;
-
-	for(pnum=0; pnum < (memsize>>PAGE_SHIFT); pnum++)
-		__init_page(page_num_to_ptr(pnum));
-}
-
--- a/sys/mm/slab.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,283 +0,0 @@
-/*
- * Copyright (c) 2007 Josef 'Jeff' Sipek
- */
-
-#include <magic.h>
-#include <buddy.h>
-#include <slab.h>
-#include <page.h>
-
-static struct slab *generic[7];
-
-/*
- * Create slab caches for 16, 32, 64, 128, and 256 byte allocations
- */
-int init_slab(void)
-{
-	generic[0] = create_slab(16, 4);
-	if (!generic[0])
-		goto out_err;
-
-	generic[1] = create_slab(32, 4);
-	if (!generic[1])
-		goto out_err;
-
-	generic[2] = create_slab(64, 4);
-	if (!generic[2])
-		goto out_err;
-
-	generic[3] = create_slab(128, 4);
-	if (!generic[3])
-		goto out_err;
-
-	generic[4] = create_slab(256, 8);
-	if (!generic[4])
-		goto out_err;
-
-	generic[5] = create_slab(512, 8);
-	if (!generic[5])
-		goto out_err;
-
-	generic[6] = create_slab(1024, 8);
-	if (!generic[6])
-		goto out_err;
-
-	return 0;
-
-out_err:
-	free_slab(generic[0]);
-	free_slab(generic[1]);
-	free_slab(generic[2]);
-	free_slab(generic[3]);
-	free_slab(generic[4]);
-	free_slab(generic[5]);
-	free_slab(generic[6]);
-
-	return -ENOMEM;
-}
-
-/**
- * create_slab - Create a new slab
- * @objsize:	object size in bytes
- * @align:	object alignment in bytes (must be a power of two)
- */
-struct slab *create_slab(u16 objsize, u8 align)
-{
-	struct page *page;
-	struct slab *slab;
-
-	if (!objsize || !align)
-		return NULL;
-
-	page = alloc_pages(0, ZONE_NORMAL);
-	if (!page)
-		return NULL;
-
-	slab = page_to_addr(page);
-	memset(slab, 0, PAGE_SIZE);
-
-	slab->magic = SLAB_MAGIC;
-	slab->lock = SPIN_LOCK_UNLOCKED;
-	INIT_LIST_HEAD(&slab->slab_pages);
-	slab->first = slab;
-
-	align--; /* turn into a mask */
-
-	/* actual object size */
-	if (objsize & align)
-		objsize += align + 1 - (objsize & align);
-	slab->objsize = objsize;
-
-	/* number of objects in a page */
-	slab->count = 8 * (PAGE_SIZE - sizeof(struct slab)) / (8 * objsize + 1);
-
-	/* offset of the first object */
-	slab->startoff = sizeof(struct slab) + (slab->count + 4) / 8;
-	if (slab->startoff & align) {
-		u16 tmp;
-
-		slab->startoff += align + 1 - (slab->startoff & align);
-
-		/*
-		 * TODO: there's got to be a better way to ensure that we
-		 * fit into a single page
-		 */
-		tmp = slab->startoff + slab->count * slab->objsize;
-		if (tmp > PAGE_SIZE)
-			slab->count--;
-	}
-
-	slab->used = 0;
-
-	return slab;
-}
-
-void free_slab(struct slab *passed_slab)
-{
-	struct slab *slab;
-
-	if (!passed_slab)
-		return;
-
-	BUG_ON(passed_slab->magic != SLAB_MAGIC);
-	BUG_ON(passed_slab->used != 0);
-
-	list_for_each_entry(slab, &passed_slab->slab_pages, slab_pages) {
-		BUG_ON(slab->magic != SLAB_CONT_MAGIC);
-		BUG_ON(slab->used != 0);
-
-		/*
-		 * Theoretically, we should remove the page from the list,
-		 * but no one _really_ cares
-		 */
-
-		free_pages(slab, 0);
-	}
-
-	free_pages(passed_slab, 0);
-}
-
-static inline void *__alloc_slab_obj_newpage(struct slab *slab, int type)
-{
-	struct page *page;
-	struct slab *new;
-
-	page = alloc_pages(0, type);
-	if (!page)
-		return ERR_PTR(-ENOMEM);
-
-	new = page_to_addr(page);
-
-	memset(new, 0, PAGE_SIZE);
-	new->magic = SLAB_CONT_MAGIC;
-	new->first = slab;
-	new->objsize = slab->objsize;
-	new->startoff = slab->startoff;
-	new->count = slab->count;
-
-	/* add it to the current slab */
-	list_add_tail(&new->slab_pages, &slab->slab_pages);
-
-	return new;
-}
-
-static void *alloc_slab_obj(struct slab *passed_slab, int type)
-{
-	struct slab *slab = passed_slab;
-	void *obj = NULL;
-	int objidx;
-	u8 *bits;
-	u8 mask;
-	unsigned long int_mask;
-
-	if (!slab)
-		return NULL;
-
-	BUG_ON(passed_slab->magic != SLAB_MAGIC);
-
-	spin_lock_intsave(&passed_slab->lock, &int_mask);
-
-	/*
-	 * Does the first slab page have an unused object _AND_ is in the
-	 * right zone?
-	 */
-	if (slab->used < slab->count && ZONE_TYPE(addr_to_page(slab)) == type)
-		goto alloc;
-
-	/*
-	 * No. Find the first slab page that has unused objects
-	 */
-	list_for_each_entry(slab, &passed_slab->slab_pages, slab_pages)
-		if (slab->used < slab->count &&
-		    ZONE_TYPE(addr_to_page(slab)) == type)
-			goto alloc;
-
-	/*
-	 * None of the pages have an unused object. Let's allocate another
-	 * page
-	 */
-
-	slab = __alloc_slab_obj_newpage(passed_slab, type);
-	if (IS_ERR(slab))
-		/*
-		 * FIXME: if we tried to get a ZONE_NORMAL and failed,
-		 * shouldn't we retry with ZONE_LOW?
-		 */
-		goto out;
-
-
-alloc:
-	/* found a page */
-	for (objidx = 0; objidx < slab->count; objidx++) {
-		bits = slab->bitmap + (objidx/8);
-
-		mask = 1 << (7 - (objidx % 8));
-
-		if (*bits & mask)
-			continue;
-
-		slab->used++;
-		*bits |= mask;
-
-		obj = ((u8*) slab) + slab->startoff + slab->objsize * objidx;
-		break;
-	}
-
-out:
-	spin_unlock_intrestore(&passed_slab->lock, int_mask);
-
-	return obj;
-}
-
-static void free_slab_obj(void *ptr)
-{
-	struct slab *slab;
-	int objidx;
-	u8 *bits;
-	unsigned long int_mask;
-
-	/* get the slab object ptr */
-	slab = (struct slab *) (((u64) ptr) & ~0xfff);
-
-	spin_lock_intsave(&slab->first->lock, &int_mask);
-
-	/* calculate the object number */
-	objidx = (((u64) ptr) - ((u64) slab) - slab->startoff) / slab->objsize;
-
-	/* update the bitmap */
-	bits = slab->bitmap + (objidx/8);
-	*bits &= ~(1 << (7 - (objidx % 8)));
-
-	if (--slab->used) {
-		/* FIXME: free the page? */
-	}
-
-	spin_unlock_intrestore(&slab->first->lock, int_mask);
-}
-
-void *malloc(int size, int type)
-{
-	if (!size)
-		return NULL;
-	if (size <= 16)
-		return alloc_slab_obj(generic[0], type);
-	if (size <= 32)
-		return alloc_slab_obj(generic[1], type);
-	if (size <= 64)
-		return alloc_slab_obj(generic[2], type);
-	if (size <= 128)
-		return alloc_slab_obj(generic[3], type);
-	if (size <= 256)
-		return alloc_slab_obj(generic[4], type);
-	if (size <= 512)
-		return alloc_slab_obj(generic[5], type);
-	if (size <= 1024)
-		return alloc_slab_obj(generic[6], type);
-	return NULL;
-}
-
-void free(void *ptr)
-{
-	if (ptr)
-		free_slab_obj(ptr);
-}
--- a/sys/nucleus/Makefile	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-objs-nucleus := init.o io.o printf.o ebcdic.o int.o ext.o svc.o pgm.o \
-	spinlock.o mutex.o sched.o
--- a/sys/nucleus/ebcdic.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +0,0 @@
-#include <ebcdic.h>
-
-/*
- * Tables taken from Linux's arch/s390/kernel/ebcdic.c
- */
-
-/*
- * ASCII (IBM PC 437)  -> EBCDIC 037
- */
-u8 ascii2ebcdic_table[256] =
-{
- /*00 NUL   SOH   STX   ETX   EOT   ENQ   ACK   BEL */
-     0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
- /*08  BS    HT    LF    VT    FF    CR    SO    SI */
- /*              ->NL                               */
-     0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /*10 DLE   DC1   DC2   DC3   DC4   NAK   SYN   ETB */
-     0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
- /*18 CAN    EM   SUB   ESC    FS    GS    RS    US */
- /*                               ->IGS ->IRS ->IUS */
-     0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F,
- /*20  SP     !     "     #     $     %     &     ' */
-     0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
- /*28   (     )     *     +     ,     -    .      / */
-     0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
- /*30   0     1     2     3     4     5     6     7 */
-     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
- /*38   8     9     :     ;     <     =     >     ? */
-     0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
- /*40   @     A     B     C     D     E     F     G */
-     0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
- /*48   H     I     J     K     L     M     N     O */
-     0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
- /*50   P     Q     R     S     T     U     V     W */
-     0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
- /*58   X     Y     Z     [     \     ]     ^     _ */
-     0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D,
- /*60   `     a     b     c     d     e     f     g */
-     0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- /*68   h     i     j     k     l     m     n     o */
-     0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
- /*70   p     q     r     s     t     u     v     w */
-     0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
- /*78   x     y     z     {     |     }     ~    DL */
-     0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
- /*80*/
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- /*88*/
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- /*90*/
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- /*98*/
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- /*A0*/
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- /*A8*/
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- /*B0*/
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- /*B8*/
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- /*C0*/
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- /*C8*/
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- /*D0*/
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- /*D8*/
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- /*E0        sz						*/
-     0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- /*E8*/
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- /*F0*/
-     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
- /*F8*/
-     0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF
-};
-
-/*
- * EBCDIC 037 -> ASCII (IBM PC 437)
- */
-u8 ebcdic2ascii_table[256] =
-{
- /* 0x00   NUL   SOH   STX   ETX  *SEL    HT  *RNL   DEL */
-          0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F,
- /* 0x08   -GE  -SPS  -RPT    VT    FF    CR    SO    SI */
-          0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- /* 0x10   DLE   DC1   DC2   DC3  -RES   -NL    BS  -POC
-                                  -ENP  ->LF             */
-          0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07,
- /* 0x18   CAN    EM  -UBS  -CU1  -IFS  -IGS  -IRS  -ITB
-                                                    -IUS */
-          0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x20   -DS  -SOS    FS  -WUS  -BYP    LF   ETB   ESC
-                                  -INP                   */
-          0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B,
- /* 0x28   -SA  -SFE   -SM  -CSP  -MFA   ENQ   ACK   BEL
-                       -SW                               */
-          0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07,
- /* 0x30  ----  ----   SYN   -IR   -PP  -TRN  -NBS   EOT */
-          0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04,
- /* 0x38  -SBS   -IT  -RFF  -CU3   DC4   NAK  ----   SUB */
-          0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A,
- /* 0x40    SP   RSP           ä              ----       */
-          0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86,
- /* 0x48                       .     <     (     +     | */
-          0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
- /* 0x50     &                                      ---- */
-          0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07,
- /* 0x58           ß     !     $     *     )     ;       */
-          0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA,
- /* 0x60     -     /  ----     Ä  ----  ----  ----       */
-          0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F,
- /* 0x68              ----     ,     %     _     >     ? */
-          0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
- /* 0x70  ----        ----  ----  ----  ----  ----  ---- */
-          0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- /* 0x78     *     `     :     #     @     '     =     " */
-          0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
- /* 0x80     *     a     b     c     d     e     f     g */
-          0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
- /* 0x88     h     i              ----  ----  ----       */
-          0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1,
- /* 0x90     °     j     k     l     m     n     o     p */
-          0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
- /* 0x98     q     r                    ----        ---- */
-          0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07,
- /* 0xA0           ~     s     t     u     v     w     x */
-          0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- /* 0xA8     y     z              ----  ----  ----  ---- */
-          0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07,
- /* 0xB0     ^                    ----     §  ----       */
-          0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC,
- /* 0xB8        ----     [     ]  ----  ----  ----  ---- */
-          0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07,
- /* 0xC0     {     A     B     C     D     E     F     G */
-          0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
- /* 0xC8     H     I  ----           ö              ---- */
-          0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07,
- /* 0xD0     }     J     K     L     M     N     O     P */
-          0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
- /* 0xD8     Q     R  ----           ü                   */
-          0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98,
- /* 0xE0     \           S     T     U     V     W     X */
-          0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- /* 0xE8     Y     Z        ----     Ö  ----  ----  ---- */
-          0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07,
- /* 0xF0     0     1     2     3     4     5     6     7 */
-          0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- /* 0xF8     8     9  ----  ----     Ü  ----  ----  ---- */
-          0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07
-};
-
--- a/sys/nucleus/ext.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-#include <interrupt.h>
-#include <sched.h>
-
-/*
- * This is the tick counter, it starts at 0 when we initialize the nucleus
- */
-volatile u64 ticks;
-
-void set_timer(void)
-{
-	u64 time = 1000 * 1000 * CLK_MICROSEC / HZ;
-
-	asm volatile(
-		"spt	%0\n"		/* set timer value */
-	: /* output */
-	: /* input */
-	  "m" (time)
-	);
-}
-
-void __ext_int_handler(void)
-{
-	if (*EXT_INT_CODE == 0x1005) {
-		/*
-		 * This is the timer, let's call the scheduler.
-		 */
-
-		ticks++;
-
-		set_timer();
-
-		/*
-		 * No need to save the registers, the assembly stub that
-		 * called this function already saved them at PSA_INT_GPR
-		 */
-		if (!(ticks % SCHED_TICKS_PER_SLICE)) {
-			__schedule(EXT_INT_OLD_PSW, TASK_SLEEPING);
-
-			/* unreachable */
-			BUG();
-		}
-	}
-}
-
--- a/sys/nucleus/init.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,204 +0,0 @@
-/*
- * Copyright (c) 2007 Josef 'Jeff' Sipek
- */
-
-#include <mm.h>
-#include <dat.h>
-#include <slab.h>
-#include <page.h>
-#include <buddy.h>
-#include <io.h>
-#include <sched.h>
-#include <device.h>
-#include <console.h>
-#include <interrupt.h>
-#include <magic.h>
-#include <cp.h>
-
-static struct psw new_io_psw = {
-	.ea	= 1,
-	.ba	= 1,
-
-	.ptr  = (u64) &IO_INT,
-};
-
-static struct psw new_ext_psw = {
-	.ea	= 1,
-	.ba	= 1,
-
-	.ptr	= (u64) &EXT_INT,
-};
-
-static struct psw new_svc_psw = {
-	.ea	= 1,
-	.ba	= 1,
-
-	.ptr	= (u64) &SVC_INT,
-};
-
-static struct psw new_pgm_psw = {
-	.ea	= 1,
-	.ba	= 1,
-
-	.ptr	= (u64) &PGM_INT,
-};
-
-u8 *int_stack_ptr;
-
-/* the time HVF got IPLd */
-struct datetime ipltime;
-
-static void init_int_stack(void)
-{
-	struct page *page;
-
-	page = alloc_pages(0, ZONE_NORMAL);
-	BUG_ON(!page);
-
-	int_stack_ptr = PAGE_SIZE + (u8*)page_to_addr(page);
-}
-
-static void idle_task_body(void)
-{
-	/*
-	 * Warning: hack alert! The following overrides what __init_task
-	 * set, this allows us to skip the usual start_task wrapper.
-	 */
-	current->regs.psw.w   = 1;
-	current->regs.psw.ptr = MAGIC_PSW_IDLE_CODE;
-
-	/*
-	 * Load the new PSW that'll wait with special magic code set
-	 */
-	lpswe(&current->regs.psw);
-
-	BUG();
-}
-
-/*
- * This is where everything starts
- */
-void start(u64 __memsize, u32 __iplsch)
-{
-	u64 first_free_page;
-	u64 struct_page_bytes;
-	struct psw psw;
-	struct console *opcon; /* operator's console */
-
-	/*
-	 * ticks starts at 0
-	 */
-	ticks = 0;
-
-	/*
-	 * save total system memory size
-	 */
-	memsize = __memsize;
-
-	/*
-	 * Initialize struct page entries
-	 */
-	init_pages();
-
-	/*
-	 * Calculate address of the first free page (we may have to round
-	 * up)
-	 */
-	struct_page_bytes = (memsize >> PAGE_SHIFT) * sizeof(struct page);
-
-	first_free_page = (u64) PAGE_INFO_BASE + struct_page_bytes;
-	if (struct_page_bytes & (PAGE_SIZE-1))
-		first_free_page += PAGE_SIZE - (struct_page_bytes & (PAGE_SIZE-1));
-
-	/*
-	 * Initialize the buddy allocator
-	 */
-	init_buddy_alloc(first_free_page);
-
-	/*
-	 * Initialize slab allocator default caches
-	 */
-	init_slab();
-
-	/*
-	 * Set up interrupt PSWs
-	 */
-	memcpy(IO_INT_NEW_PSW, &new_io_psw, sizeof(struct psw));
-	memcpy(EXT_INT_NEW_PSW, &new_ext_psw, sizeof(struct psw));
-	memcpy(SVC_INT_NEW_PSW, &new_svc_psw, sizeof(struct psw));
-	memcpy(PGM_INT_NEW_PSW, &new_pgm_psw, sizeof(struct psw));
-
-	/* Turn on Low-address Protection */
-	lap_on();
-
-	/*
-	 * Set up page table entries for the nucleus
-	 */
-	setup_dat();
-
-	/*
-	 * Allocate & initialize the interrupt stack
-	 */
-	init_int_stack();
-
-	/*
-	 * Initialize the io subsystem
-	 */
-	init_io();
-
-	/*
-	 * Register all the device drivers
-	 */
-	register_drivers();
-
-	/*
-	 * Time to enable interrupts => load new psw
-	 */
-	memset(&psw, 0, sizeof(struct psw));
-	psw.io	= 1;
-	psw.ea	= 1;
-	psw.ba	= 1;
-
-	asm volatile(
-		"	larl	%%r1,0f\n"
-		"	stg	%%r1,%0\n"
-		"	lpswe	%1\n"
-		"0:\n"
-	: /* output */
-	  "=m" (psw.ptr)
-	: /* input */
-	  "m" (psw)
-	: /* clobbered */
-	  "r1"
-	);
-
-	/*
-	 * Let's discover all the devices attached
-	 */
-	scan_devices();
-
-	/*
-	 * Initialize the process scheduler
-	 */
-	init_sched();
-
-	/*
-	 * IPL is more or less done
-	 */
-	get_parsed_tod(&ipltime);
-
-	opcon = start_oper_console();
-
-	con_printf(opcon, "NOW %02d:%02d:%02d UTC %04d-%02d-%02d\n\n",
-		   ipltime.th, ipltime.tm, ipltime.ts, ipltime.dy,
-		   ipltime.dm, ipltime.dd);
-
-	spawn_oper_cp(opcon);
-
-	/*
-	 * THIS IS WHERE THE IDLE TASK BEGINS
-	 */
-
-	idle_task_body();
-}
-
--- a/sys/nucleus/int.S	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-.text
-
-#include <interrupt.h>
-
-#
-# IO Interrupt
-#
-	.align	4
-.globl IO_INT
-	.type	IO_INT, @function
-IO_INT:
-	# save regs
-	STMG	%r0,%r15,0x200(%r0)
-
-	# set up stack
-	LARL	%r15, int_stack_ptr
-	LG	%r15, 0(%r15)
-	AGHI	%r15,-160
-
-	LARL	%r14, __io_int_handler
-	BALR	%r14, %r14		# call the real handler
-
-	# restore regs
-	LMG	%r0,%r15,0x200(%r0)
-
-	LPSWE	0x170			# go back to what we interrupted
-
-
-#
-# External Interrupt
-#
-	.align 4
-.globl EXT_INT
-	.type	EXT_INT, @function
-EXT_INT:
-	# save regs
-	STMG	%r0,%r15,0x200(%r0)
-
-	# set up stack
-	LARL	%r15, int_stack_ptr
-	LG	%r15, 0(%r15)
-	AGHI	%r15,-160
-
-	LARL	%r14, __ext_int_handler
-	BALR	%r14, %r14		# call the real handler
-
-	#
-	# NOTE: we may never return from the C-interrupt handler if the
-	# interrupt was caused by the timer clock, in which case the
-	# scheduler kicks in, and gives control to someone else
-	#
-
-	# restore regs
-	LMG	%r0,%r15,0x200(%r0)
-
-	LPSWE	0x130			# go back to what we interrupted
-
-
-#
-# Supervisor-Call Interrupt
-#
-	.align 4
-.globl SVC_INT
-	.type	SVC_INT, @function
-SVC_INT:
-	# save regs
-	STMG	%r0,%r15,0x200(%r0)
-
-	# set up stack
-	LARL	%r15, int_stack_ptr
-	LG	%r15, 0(%r15)
-	AGHI	%r15,-160
-
-	# find the right handler
-	LARL	%r14, svc_table		# table address
-	LGH	%r2, 0x8a		# interruption code
-	SLL	%r2, 3
-					# byte offset into table
-	LG	%r14, 0(%r2,%r14)	# load value from table
-
-	BALR	%r14, %r14		# call the real handler
-
-	# restore regs
-	LMG	%r0,%r15,0x200(%r0)
-
-	LPSWE	0x140			# go back to what we interrupted
-
-
-#
-# Program Interrupt
-#
-	.align 4
-.globl PGM_INT
-	.type	PGM_INT, @function
-PGM_INT:
-	# save regs
-	STMG	%r0,%r15,0x200(%r0)
-
-	# set up stack
-	LARL	%r15, int_stack_ptr
-	LG	%r15, 0(%r15)
-	AGHI	%r15,-160
-
-	LARL	%r14, __pgm_int_handler
-	BALR	%r14, %r14		# call the real handler
-
-	#
-	# NOTE: we may never return from the C-interrupt handler
-	#
-
-	# restore regs
-	LMG	%r0,%r15,0x200(%r0)
-
-	LPSWE	0x150			# go back to what we interrupted
--- a/sys/nucleus/io.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-/*
- * Copyright (c) 2007 Josef 'Jeff' Sipek
- */
-
-#include <channel.h>
-#include <io.h>
-#include <interrupt.h>
-#include <device.h>
-#include <sched.h>
-#include <atomic.h>
-#include <spinlock.h>
-#include <buddy.h>
-#include <sched.h>
-
-/*
- * Helper function to make sure the io_op has everything set right
- */
-static int __verify_io_op(struct io_op *ioop)
-{
-	// FIXME: check everything that makes sense to check
-	return 0;
-}
-
-static void __reset_reserved_fields(struct io_op *ioop)
-{
-	ioop->orb.__zero1 = 0;
-	ioop->orb.__zero2 = 0;
-
-	ioop->orb.__reserved1 = 0;
-	ioop->orb.__reserved2 = 0;
-	ioop->orb.__reserved3 = 0;
-	ioop->orb.__reserved4 = 0;
-	ioop->orb.__reserved5 = 0;
-	ioop->orb.__reserved6 = 0;
-}
-
-/* NOTE: assumes dev->q_lock is held */
-static void __submit_io(struct device *dev)
-{
-	struct io_op *ioop;
-	int err;
-
-	if (dev->q_cur)
-		return;
-
-	if (list_empty(&dev->q_out))
-		return;
-
-	ioop = list_entry(dev->q_out.next, struct io_op, list);
-
-	err = start_sch(dev->sch, &ioop->orb);
-	if (!err) {
-		list_del(&ioop->list);
-		dev->q_cur = ioop;
-	} else
-		ioop->err = err;
-}
-
-/*
- * Submit an I/O request to a subchannel, and set up everything needed to
- * handle the operation
- */
-int submit_io(struct device *dev, struct io_op *ioop, int flags)
-{
-	static atomic_t op_id_counter;
-	unsigned long intmask;
-	int err = -EBUSY;
-
-	err = __verify_io_op(ioop);
-	if (err)
-		return 0;
-
-	/* make sure all reserved fields have the right values */
-	__reset_reserved_fields(ioop);
-
-	ioop->err = 0;
-	ioop->orb.param = atomic_inc_return(&op_id_counter);
-	atomic_set(&ioop->done, 0);
-
-	/* add it to the list of ops */
-	spin_lock_intsave(&dev->q_lock, &intmask);
-	list_add_tail(&ioop->list, &dev->q_out);
-
-	__submit_io(dev); /* try to submit an IO right now */
-	spin_unlock_intrestore(&dev->q_lock, intmask);
-
-	if (flags & CAN_LOOP) {
-		while(!atomic_read(&ioop->done))
-			;
-	} else if (flags & CAN_SLEEP) {
-		while(!atomic_read(&ioop->done))
-			schedule();
-	}
-
-	return 0;
-}
-
-/*
- * Initialize the channel I/O subsystem
- */
-void init_io(void)
-{
-	u64 cr6;
-
-	/* enable all I/O interrupt classes */
-	asm volatile(
-		"stctg	6,6,%0\n"	/* get cr6 */
-		"oi	%1,0xff\n"	/* enable all */
-		"lctlg	6,6,%0\n"	/* reload cr6 */
-	: /* output */
-	: /* input */
-	  "m" (cr6),
-	  "m" (*(u64*) (((u8*)&cr6) + 4))
-	);
-}
-
-static int default_io_handler(struct device *dev, struct io_op *ioop, struct irb *irb)
-{
-	ioop->err = -EAGAIN;
-
-	/* Unit check? */
-	if (irb->scsw.dev_status & 0x02)
-		ioop->err = -EUCHECK; /* FIXME: we should bail */
-
-	/* Device End is set, we're done */
-	if (irb->scsw.dev_status & 0x04)
-		ioop->err = 0;
-
-	return 0;
-}
-
-static void __cpu_initiated_io(struct device *dev, struct io_op *ioop, struct irb *irb)
-{
-	unsigned long intmask;
-
-	ioop->err = test_sch(dev->sch, irb);
-
-	if (!ioop->err && ioop->handler)
-		ioop->handler(dev, ioop, irb);
-	else if (!ioop->err)
-		default_io_handler(dev, ioop, irb);
-
-	/*
-	 * We can do this, because the test_sch function sets ->err, and
-	 * therefore regardless of ->handler being defined, ->err will have
-	 * a reasonable value
-	 */
-	if (ioop->err == -EAGAIN)
-		return; /* leave handler registered */
-
-	/* ...and remove it form the list */
-	spin_lock_intsave(&dev->q_lock, &intmask);
-	dev->q_cur = NULL;
-
-	__submit_io(dev); /* try to submit another IO */
-	spin_unlock_intrestore(&dev->q_lock, intmask);
-
-	/* flag io_op as done... */
-	atomic_set(&ioop->done, 1);
-
-	/* call the destructor if there is one */
-	if (ioop->dtor)
-		ioop->dtor(dev, ioop);
-}
-
-static void __dev_initiated_io(struct device *dev, struct irb *irb)
-{
-}
-
-/*
- * I/O Interrupt handler (C portion)
- */
-void __io_int_handler(void)
-{
-	unsigned long intmask;
-	struct io_op *ioop;
-	struct device *dev;
-	struct irb irb;
-
-	dev = find_device_by_sch(IO_INT_CODE->ssid);
-	BUG_ON(IS_ERR(dev));
-
-	spin_lock_intsave(&dev->q_lock, &intmask);
-	ioop = dev->q_cur;
-	spin_unlock_intrestore(&dev->q_lock, intmask);
-
-	if (ioop && ioop->orb.param == IO_INT_CODE->param &&
-	    dev->sch == IO_INT_CODE->ssid) {
-		/*
-		 * CPU-initiated operation
-		 */
-
-		__cpu_initiated_io(dev, ioop, &irb);
-		dev_put(dev);
-		return;
-	}
-
-	/*
-	 * device-initiated operation
-	 */
-	BUG_ON(test_sch(dev->sch, &irb));
-
-	atomic_inc(&dev->attention);
-
-	if (dev->dev->interrupt)
-		dev->dev->interrupt(dev, &irb);
-	else
-		__dev_initiated_io(dev, &irb);
-	dev_put(dev);
-}
--- a/sys/nucleus/mutex.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#include <mutex.h>
-
-/* slow-path mutex locking */
-void __mutex_lock(mutex_t *lock)
-{
-	spin_lock(&lock->queue_lock);
-
-	if (unlikely(atomic_add_unless(&lock->state, -1, 0))) {
-		spin_unlock(&lock->queue_lock);
-		return; /* aha! someone released it & it's ours now! */
-	}
-
-	list_add_tail(&current->blocked_list, &lock->queue);
-
-	spin_unlock(&lock->queue_lock);
-
-	schedule_blocked();
-}
--- a/sys/nucleus/pgm.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-#include <interrupt.h>
-#include <ebcdic.h>
-#include <vsprintf.h>
-
-static char abend_msg_buf[1024];
-
-/*
- * All is lost! All hands abandon ship!
- *
- * Try to write out a message to a special buffer to help debugging, and
- * then stop the CPU.
- */
-static void abend(void)
-{
-	int ret;
-
-	ret = snprintf(abend_msg_buf, 1024,
-		"ABEND       %04x"
-		"PSW        ILC %d"
-		"%016llx%016llx"
-		"GPR             "
-		"%016llx%016llx%016llx%016llx"
-		"%016llx%016llx%016llx%016llx"
-		"%016llx%016llx%016llx%016llx"
-		"%016llx%016llx%016llx%016llx",
-		*PGM_INT_CODE, (*PGM_INT_ILC) >> 1,
-		*((u64*) PGM_INT_OLD_PSW), *(((u64*) PGM_INT_OLD_PSW)+1),
-		PSA_INT_GPR[0],  PSA_INT_GPR[1],  PSA_INT_GPR[2],  PSA_INT_GPR[3],
-		PSA_INT_GPR[4],  PSA_INT_GPR[5],  PSA_INT_GPR[6],  PSA_INT_GPR[7],
-		PSA_INT_GPR[8],  PSA_INT_GPR[9],  PSA_INT_GPR[10], PSA_INT_GPR[11],
-		PSA_INT_GPR[12], PSA_INT_GPR[13], PSA_INT_GPR[14], PSA_INT_GPR[15]
-	);
-
-	if (ret)
-		ascii2ebcdic((u8 *) abend_msg_buf, ret);
-
-	/*
-	 * halt the cpu
-	 *
-	 * NOTE: we don't care about not clobbering registers as when this
-	 * code executes, the CPU will be stopped.
-	 */
-	asm volatile(
-		"LR	%%r15, %0		# buffer pointer\n"
-		"SR	%%r1, %%r1		# not used, but should be zero\n"
-		"SR	%%r3, %%r3 		# CPU Address\n"
-		"SIGP	%%r1, %%r3, 0x05	# Signal, order 0x05\n"
-	: /* out */
-	: /* in */
-	  "a" (abend_msg_buf)
-	);
-
-	/*
-	 * If SIGP failed, loop forever
-	 */
-	for(;;);
-}
-
-void __pgm_int_handler(void)
-{
-	abend();
-}
--- a/sys/nucleus/printf.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2007 Josef 'Jeff' Sipek
- */
-
-#include <channel.h>
-#include <console.h>
-#include <directory.h>
-#include <ebcdic.h>
-#include <slab.h>
-#include <clock.h>
-#include <sched.h>
-#include <vsprintf.h>
-#include <stdarg.h>
-
-int vprintf(struct console *con, const char *fmt, va_list args)
-{
-	struct datetime dt;
-	char buf[128];
-	int off = 0;
-	int ret;
-
-	if (!con->sys || (con->sys && con->sys->print_ts)) {
-		memset(&dt, 0, sizeof(dt));
-		ret = get_parsed_tod(&dt);
-		off = snprintf(buf, 128, "%02d:%02d:%02d ", dt.th, dt.tm,
-			       dt.ts);
-	}
-
-	ret = vsnprintf(buf+off, 128-off, fmt, args);
-	if (ret) {
-		ascii2ebcdic((u8 *) buf, off+ret);
-		con_write(con, (u8 *) buf, off+ret);
-	}
-
-	return ret;
-}
-
-int con_printf(struct console *con, const char *fmt, ...)
-{
-	va_list args;
-	int r;
-
-	va_start(args, fmt);
-	r = vprintf(con, fmt, args);
-	va_end(args);
-
-	return r;
-}
--- a/sys/nucleus/sched.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,292 +0,0 @@
-#include <sched.h>
-#include <page.h>
-#include <buddy.h>
-#include <slab.h>
-#include <magic.h>
-
-/* list of all runnable processes */
-static struct list_head runnable;
-
-/* list of all processes in the system */
-static struct list_head processes;
-
-/* idle task */
-static struct task idle_task;
-
-/**
- * start_task - helper used to start the task's code
- * @f:	function to execute
- */
-static void start_task(int (*f)(void*), void *data)
-{
-	/*
-	 * Start executing the code
-	 */
-	if (f)
-		(*f)(data);
-
-	/*
-	 * Done, now, it's time to cleanup
-	 *
-	 * FIXME:
-	 *  - delete from processes list
-	 *  - free stack page
-	 *  - free struct
-	 *  - schedule
-	 */
-	BUG();
-}
-
-/**
- * __init_task - helper to initialize the task structure
- * @task:	task struct to initialize
- * @f:		pointer to function to execute
- * @stack:	pointer to the page for stack
- */
-static void __init_task(struct task *task, void *f, void *data, void *stack)
-{
-	memset(task, 0, sizeof(struct task));
-
-	task->regs.psw.io	= 1;
-	task->regs.psw.ex	= 1;
-	task->regs.psw.ea	= 1;
-	task->regs.psw.ba	= 1;
-
-	/* code to execute */
-	task->regs.psw.ptr = (u64) start_task;
-
-	task->regs.gpr[2]  = (u64) f;
-	task->regs.gpr[3]  = (u64) data;
-	task->regs.gpr[15] = ((u64) stack) + PAGE_SIZE - STACK_FRAME_SIZE;
-
-	task->state = TASK_SLEEPING;
-}
-
-/**
- * init_idle_task - initialize the idle task
- *
- * Since the initial thread of execution already has a stack, and the task
- * struct is a global variable, all that is left for us to do is to
- * associate the current stack with idle_task.
- */
-static void init_idle_task(void)
-{
-	u64 stack;
-
-	stack = ((u64) &stack) & ~(PAGE_SIZE-1);
-
-	__init_task(&idle_task, NULL, NULL, (void*) stack);
-	set_task_ptr(&idle_task);
-
-	/*
-	 * NOTE: The idle task is _not_ supposed to be on either of the
-	 * two process lists.
-	 */
-}
-
-/**
- * create_task - create a new task
- * @name:	name for the task
- * @f:		function pointer to where thread of execution should begin
- * @data:	arbitrary data to pass to the task
- */
-struct task* create_task(char *name, int (*f)(void *), void *data)
-{
-	struct page *page;
-	struct task *task;
-
-	/*
-	 * Allocate a page for stack, and struct task itself
-	 */
-	page = alloc_pages(0, ZONE_NORMAL);
-	task = malloc(sizeof(struct task), ZONE_NORMAL);
-	if (!page || !task)
-		goto out;
-
-	/*
-	 * Set up task's state
-	 */
-	__init_task(task, f, data, page_to_addr(page));
-
-	strncpy(task->name, name, TASK_NAME_LEN);
-
-	/*
-	 * Add the task to the scheduler lists
-	 */
-	list_add_tail(&task->proc_list, &processes);
-	list_add_tail(&task->run_queue, &runnable);
-
-	return task;
-
-out:
-	free(task);
-	free_pages(page_to_addr(page), 0);
-
-	return ERR_PTR(-ENOMEM);
-}
-
-/**
- * __sched - core of the scheduler code. This decides which task to run
- * next, and switches over to it
- */
-static void __sched(int force_idle)
-{
-	struct task *next;
-
-	/*
-	 * If there are no runnable tasks, let's use the idle thread
-	 */
-	if (force_idle || list_empty(&runnable)) {
-		next = &idle_task;
-		goto run;
-	}
-
-	next = list_first_entry(&runnable, struct task, run_queue);
-	BUG_ON(!next);
-
-	/*
-	 * Remove the new task from the run queue & mark it as running
-	 */
-	list_del(&next->run_queue);
-	next->state = TASK_RUNNING;
-
-run:
-	next->slice_end_time = (force_idle) ? force_idle : ticks + SCHED_TICKS_PER_SLICE;
-
-	/*
-	 * NOTE: Because we need to load the registers _BEFORE_ we issue
-	 * lpswe, we have to place the new psw into PSA and use register 0
-	 */
-	memcpy(PSA_TMP_PSW, &next->regs.psw, sizeof(struct psw));
-	set_task_ptr(next);
-
-	load_pasce(next->regs.cr1);
-
-	/*
-	 * Load the next task
-	 *
-	 * FIXME: fp? ar? cr?
-	 */
-	asm volatile(
-		"lmg	%%r0,%%r15,%0\n"	/* load gpr */
-		"lpswe	%1\n"			/* load new psw */
-	: /* output */
-	: /* input */
-	  "m" (next->regs.gpr[0]),
-	  "m" (*PSA_TMP_PSW)
-	);
-
-	/* unreachable */
-	BUG();
-}
-
-/**
- * schedule_preempted - called to switch tasks
- */
-void __schedule(struct psw *old_psw, int newstate)
-{
-	struct task *prev;
-	int force_idle = 0;
-
-	/*
-	 * Save last process's state
-	 */
-
-	prev = current;
-	BUG_ON(!prev);
-
-	/*
-	 * Save the registers (gpr, psw, ...)
-	 *
-	 * FIXME: fp? ar? cr?
-	 */
-	memcpy(prev->regs.gpr, PSA_INT_GPR, sizeof(u64)*16);
-	memcpy(&prev->regs.psw, old_psw, sizeof(struct psw));
-
-	/*
-	 * Idle task doesn't get added back to the queue
-	 */
-	if (prev == &idle_task)
-		goto go;
-
-	store_pasce(&prev->regs.cr1);
-
-	/*
-	 * Add back on the queue
-	 */
-	prev->state = newstate;
-	if (newstate != TASK_LOCKED)
-		list_add_tail(&prev->run_queue, &runnable);
-
-	/*
-	 * If the previous task didn't use it's full slice, force idle_task
-	 * to take over.
-	 */
-	if (prev->slice_end_time >= (ticks + SCHED_TICKS_PER_SLICE))
-		force_idle = prev->slice_end_time;
-
-go:
-	/*
-	 * Run the rest of the scheduler that selects the next task and
-	 * context switches
-	 */
-	__sched(force_idle);
-}
-
-/**
- * __schedule_svc - wrapper for the supervisor-service call handler
- */
-void __schedule_svc(void)
-{
-	__schedule(SVC_INT_OLD_PSW, TASK_SLEEPING);
-}
-
-/**
- * __schedule_blocked__svc - wrapper for the supervisor-service call handler
- */
-void __schedule_blocked_svc(void)
-{
-	__schedule(SVC_INT_OLD_PSW, TASK_LOCKED);
-}
-
-/*
- * Initialize the schduler, and all associated structures
- */
-void init_sched(void)
-{
-	u64 cr0;
-
-	INIT_LIST_HEAD(&runnable);
-	INIT_LIST_HEAD(&processes);
-
-	init_idle_task();
-
-	/* enable cpu timer interrupt subclass */
-	asm volatile(
-		"stctg	0,0,%0\n"	/* get cr0 */
-		"oi	%1,0x04\n"	/* enable cpu timer subclass */
-		"ni	%1,0x7f\n"	/* disable clock comp */
-		"lctlg	0,0,%0\n"	/* reload cr0 */
-	: /* output */
-	: /* input */
-	  "m" (cr0),
-	  "m" (*(((u8*)&cr0) + 6))
-	);
-
-	set_timer();
-}
-
-void list_tasks(struct console *con,
-		void (*f)(struct console *, struct task*))
-{
-	struct task *t;
-
-	list_for_each_entry(t, &processes, proc_list)
-		f(con, t);
-}
-
-void make_runnable(struct task *task)
-{
-	task->state = TASK_SLEEPING;
-	list_add_tail(&task->run_queue, &runnable);
-}
--- a/sys/nucleus/spinlock.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-#include <interrupt.h>
-#include <spinlock.h>
-
-void __spin_lock_wait(spinlock_t *lp, unsigned int pc)
-{
-	while (1) {
-		if (__compare_and_swap(&lp->lock, 0, pc) == 0)
-			return;
-	}
-}
-
-int __spin_trylock_retry(spinlock_t *lp, unsigned int pc)
-{
-	int count = SPIN_RETRY;
-
-	while (count-- > 0)
-		if (__compare_and_swap(&lp->lock, 0, pc) == 0)
-			return 1;
-	return 0;
-}
-
-/**
- * spin_lock_intsave - disable interrupts and lock
- * @lock:	lock to lock
- * @mask:	pointer to where interrupt mask will be stored
- */
-void spin_lock_intsave(spinlock_t *lock, unsigned long *mask)
-{
-	*mask = local_int_disable();
-	spin_lock(lock);
-}
-
-/**
- * spin_unlock_intrestore - unlock and restore interrupt flags flags
- * @lock:	lock to unlock
- * @mask:	mask to restore
- */
-void spin_unlock_intrestore(spinlock_t *lock, unsigned long mask)
-{
-        spin_unlock(lock);
-        local_int_restore(mask);
-}
-
--- a/sys/nucleus/svc.c	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-#include <sched.h>
-#include <interrupt.h>
-
-u64 svc_table[NR_SVC] = {
-	(u64) __schedule_svc,
-	(u64) __schedule_blocked_svc,
-};
-
--- a/sys/scripts/Makefile.build	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-#
-# Build a single directory (built-in.o)
-#
-
-.PHONY: all
-
-.PRECIOUS: %.o
-
-include scripts/Makefile.commands
-
-override DIR := $(patsubst %/,%,$(DIR))
-include $(DIR)/Makefile
-
-OBJS := $(foreach obj,$(objs-$(DIR)),$(patsubst %,$(DIR)/%,$(obj)))
-
-all: $(DIR)/built-in.o
-	@echo -n
-
-%/built-in.o: $(OBJS)
-	$(call o-to-builtin,$(OBJS),$@)
-
-%.o: %.S
-	$(call s-to-o,$<,$@)
-
-%.s: %.c
-	$(call c-to-s,$<,$@)
-
-%.o: %.c
-	$(call c-to-o,$<,$@)
-
-cp/directory.c: cp/directory_structs.c
-
-cp/directory_structs.c: hvf.directory
-	$(call gendir,$<,$@)
--- a/sys/scripts/Makefile.commands	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-cmd-ar=$(AR) rc $(1) $(2)
-cmd-c-to-o=$(CC) $(CFLAGS) $(NUCLEUSCFLAGS) -c -o $(2) $(1)
-cmd-c-to-s=$(CC) $(CFLAGS) $(NUCLEUSCFLAGS) -S -o $(2) $(1)
-cmd-s-to-o=$(AS) -m64 -o $(2) $(1)
-cmd-o-to-builtin=$(LD) $(LDFLAGS) -r -o $(2) $(1)
-cmd-link-hvf=$(LD) $(LDFLAGS) -T scripts/linker.script -o $(2) $(1)
-cmd-link-ipl=$(LD) -melf64_s390 -T linker.script -o $(2) $(1)
-cmd-objcopy-t=$(OBJCOPY) -O binary -j .text $(1) $(2)
-cmd-objcopy-tdr=$(OBJCOPY) -O binary -j .text -j .data -j .rodata -j .rodata.str1.2 $(1) $(2)
-cmd-genipl-rdr=bash scripts/gen_rdr_ccws.sh $(1)
-cmd-genipl-tape=bash scripts/gen_tape_ipl_s.sh $(1) $(2)
-cmd-concat=cat $(1) > $(2)
-cmd-pad=bash scripts/pad.sh $(1) $(2)
-cmd-clean=rm -f $(1)
-cmd-rclean=rm -rf $(1)
-cmd-cscope=cscope -R -b
-cmd-gendir=bash scripts/gen-dir.sh $(1) $(2)
-
-ifeq ($V,1)
-ar=$(cmd-ar)
-c-to-o=$(cmd-c-to-o)
-c-to-s=$(cmd-c-to-s)
-c-to-o-ipl=$(cmd-c-to-o-ipl)
-s-to-o=$(cmd-s-to-o)
-o-to-builtin=$(cmd-o-to-builtin)
-link-hvf=$(cmd-link-hvf)
-link-ipl=$(cmd-link-ipl)
-objcopy-t=$(cmd-objcopy-t)
-objcopy-tdr=$(cmd-objcopy-tdr)
-genipl-rdr=$(cmd-genipl-rdr)
-genipl-tape=$(cmd-genipl-tape)
-concat=$(cmd-concat)
-pad=$(cmd-pad)
-clean=$(cmd-clean)
-rclean=$(cmd-rclean)
-cscope=$(cmd-cscope)
-gendir=$(cmd-gendir)
-else
-ar=@echo "  [AR]      $(1)"; $(cmd-ar)
-c-to-o=@echo "  [CC]      $(2)"; $(cmd-c-to-o)
-c-to-s=@echo "  [CC]      $(2)"; $(cmd-c-to-s)
-c-to-o-ipl=@echo "  [CC]      $(2)"; $(cmd-c-to-o-ipl)
-s-to-o=@echo "  [AS]      $(2)"; $(cmd-s-to-o)
-o-to-builtin=@echo "  [LD]      $(2)"; $(cmd-o-to-builtin)
-link-hvf=@echo "  [LD]      hvf"; $(cmd-link-hvf)
-link-ipl=@echo "  [LD]      $2"; $(cmd-link-ipl)
-objcopy-t=@echo "  [OBJCOPY] $2"; $(cmd-objcopy-t)
-objcopy-tdr=@echo "  [OBJCOPY] $2"; $(cmd-objcopy-tdr)
-genipl-rdr=@echo "  [GENRDR]  $1"; $(cmd-genipl-rdr)
-genipl-tape=@echo "  [GENTAPE] $2"; $(cmd-genipl-tape)
-concat=@echo "  [CONCAT]  $2"; $(cmd-concat)
-pad=@echo "  [PAD]     $1 (multiple of $2 bytes)"; $(cmd-pad)
-clean=@echo "  [CLEAN]   $1"; $(cmd-clean)
-rclean=@echo "  [CLEAN]   $1"; $(cmd-rclean)
-cscope=@echo "  [CSCOPE]  cscope.out"; $(cmd-cscope)
-gendir=@echo "  [DIRECT]  $1 -> $2"; $(cmd-gendir)
-endif
-
--- a/sys/scripts/extract-version.sh	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-#!/bin/sh
-
-v=`git describe 2> /dev/null`
-
-case "$v" in
-	"")
-		awk '/^VERSION=/ { print substr($0,9); exit; }' < Makefile
-		;;
-	*)
-		echo "$v"
-		;;
-esac
--- a/sys/scripts/gen-dir.sh	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-#!/bin/sh
-
-if [ $# -ne 2 ]; then
-	echo "Usage: $0 <directory> <outfile>" >&2
-	exit 1
-fi
-
-userid=""
-
-close_devlist()
-{
-cat >> directory.devlist <<DONE
-	{ /* END   */ .type = VDEV_INVAL, },
-};
-DONE
-echo "	}," >> directory.userlist
-}
-
-parse_line()
-{
-	case "$1" in
-		USER)
-			[ ! -z "$userid" ] && close_devlist
-
-			echo "static struct directory_vdev __directory_$2[] = {" >> directory.devlist
-			echo "	{" >> directory.userlist
-			echo "		.userid = \"$2\"," >> directory.userlist
-			echo "		.auth = '$3'," >> directory.userlist
-			echo "		.devices = __directory_$2," >> directory.userlist
-
-			userid="$2"
-			;;
-		MACHINE)
-			;;
-		STORAGE)
-			tmp=`echo $2 | sed -e 's/[KMG]//g'`
-			case "$2" in
-				*K) size="${tmp}ULL * 1024ULL" ;;
-				*M) size="${tmp}ULL * 1024ULL * 1024ULL" ;;
-				*G) size="${tmp}ULL * 1024ULL * 1024ULL * 1024ULL" ;;
-				*)  size="$2ULL" ;;
-			esac
-			echo "		.storage_size = $size," >> directory.userlist
-			;;
-		CONSOLE)
-			echo "	{ /* CON   */ .type = VDEV_CONS,  .vdev = 0x$2, }," >> directory.devlist
-			;;
-		SPOOL)
-			case "$4" in
-				READER)
-					echo "	{ /* RDR   */ .type = VDEV_SPOOL, .vdev = 0x$2, .u.spool = { .type = 0x$3, .model = 1 }, }," >> directory.devlist
-					;;
-				PUNCH)
-					echo "	{ /* PUN   */ .type = VDEV_SPOOL, .vdev = 0x$2, .u.spool = { .type = 0x$3, .model = 1 }, }," >> directory.devlist
-					;;
-				PRINT)
-					echo "	{ /* PRT   */ .type = VDEV_SPOOL, .vdev = 0x$2, .u.spool = { .type = 0x$3, .model = 1 }, }," >> directory.devlist
-					;;
-			esac
-			;;
-		MDISK)
-			echo "	{ /* MDISK */ .type = VDEV_MDISK, .vdev = 0x$2, .u.mdisk = { .rdev = 0x$6, .cyloff = $4, .cylcnt = $5, }, }," >> directory.devlist
-			;;
-		DEDICATE)
-			echo "	{ /* DED   */ .type = VDEV_DED,   .vdev = 0x$2, .u.dedicate = { .rdev = 0x$3, }, }," >> directory.devlist
-			;;
-		*)
-			echo "Error near:" "$@" >&2
-			exit 2
-			;;
-	esac
-}
-
-open_userlist()
-{
-	echo "static struct user directory[] = {" > directory.userlist
-}
-
-close_userlist()
-{
-cat >> directory.userlist <<DONE
-	{ /* END */ .userid = NULL, },
-};
-DONE
-}
-
-rm -f directory.devlist
-open_userlist
-cat "$1" | while read line ; do
-	[ -z "$line" ] && continue
-
-	parse_line $line
-done
-close_devlist
-close_userlist
-
-cat directory.devlist directory.userlist > $2
-
-rm -f directory.devlist directory.userlist
--- a/sys/scripts/gen-docs.sh	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-write_docs()
-{
-cat "$1" | awk -v fmt="$2" '
-BEGIN{
-	docdir = "doc/commands";
-
-	if (fmt == "txt") {
-		cmd_title_open = "";
-		cmd_title_close = "";
-		sec_hdr_open = "";
-		sec_hdr_close = "";
-		par_open = "";
-		par_close = "";
-		pre_open = "";
-		pre_close = "";
-	} else if (fmt == "html") {
-		cmd_title_open = "<h1>";
-		cmd_title_close = "</h1>";
-		sec_hdr_open = "<h2>";
-		sec_hdr_close = "</h2>";
-		par_open = "<p>";
-		par_close = "</p>";
-		pre_open = "<pre>";
-		pre_close = "</pre>";
-	} else {
-		printf "ERROR: unknown format \"%s\"\n", fmt;
-		exit;
-	}
-
-	fname = "";
-}
-
-/^[/ ]\*!!! / {
-	# begin a new command
-	if (fname != "")
-		close(fname);
-
-	name="";
-	fname="";
-	for(i=2; i<=NF; i+=1) {
-		name = name $i " ";
-		fname = fname $i "_";
-	}
-	name = substr(name, 1, length(name)-1);
-	fname = docdir "/" fmt "/" substr(fname, 1, length(fname)-1) "." fmt;
-
-	print "Writing out ", fname;
-
-	print cmd_title_open > fname;
-	print name >> fname;
-	print cmd_title_close >> fname;
-}
-
-/^[/ ]\*!! AUTH / {
-	# output an authorization block
-	print sec_hdr_open >> fname;
-	print "Authorization" >> fname;
-	print sec_hdr_close par_open >> fname;
-	print $3 >> fname;
-	printf par_close >> fname;
-}
-
-/^[/ ]\*!! PURPOSE$/ {
-	# output purpose section header
-	print sec_hdr_open >> fname;
-	print "Purpose" >> fname;
-	print sec_hdr_close >> fname;
-}
-
-/^[/ ]\*!! NOTES$/ {
-	# output notes section header
-	print sec_hdr_open >> fname;
-	print "Usage Notes" >> fname;
-	print sec_hdr_close >> fname;
-}
-
-/^[/ ]\*!p / {
-	# preformated verbatim line
-	print pre_open substr($0, 6) pre_close >> fname;
-}
-
-/^[/ ]\*! / {
-	# verbatim line
-	print substr($0, 5) >> fname;
-}
-
-/^[/ ]\*!$/ {
-	# just make a new paragraph
-	print substr($0, 5) >> fname;
-}
-'
-}
-
-mkdir -p doc/commands/txt
-mkdir -p doc/commands/html
-
-for srcf in cp/cmd_*.c ; do
-	echo "Inspecting $srcf..."
-	write_docs $srcf txt
-	write_docs $srcf html
-done
--- a/sys/scripts/linker.script	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-SECTIONS
-{
-  ENTRY(start)
-  . = 0x100000;
-  .text : { *(.text) }
-  .data : { *(.data) }
-  .bss : { *(.bss) }
-}
--- a/sys/scripts/pad.sh	Tue Dec 29 20:04:16 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-# pad <fname> <multiple>
-
-len=`stat -c %s "$1"`
-dif=`expr $len % "$2"`
-
-if [ $dif -ne 0 ]; then
-	dif=`expr "$2" - $dif`
-	dd if=/dev/zero bs=1 count=$dif 2> /dev/null >> "$1"
-fi