changeset 34:720e29b26c81

merge
author Jonathan Pevarnek <pevarnj@gmail.com>
date Wed, 06 Apr 2011 17:18:00 -0400
parents fc797d0cb298 (current diff) e984f53304ea (diff)
children f806eec33c45
files arch/io.c hercules/dynamic.cnf hercules/sarpn.cnf include/system.h
diffstat 5 files changed, 219 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/arch/io.c	Mon Apr 04 14:48:10 2011 -0400
+++ b/arch/io.c	Wed Apr 06 17:18:00 2011 -0400
@@ -414,9 +414,8 @@
 			for(;;); \
 		} while(0)
 
-static void enable_cons(int devnum)
+u32 find_dev(int devnum)
 {
-	struct psw psw;
 	struct schib schib;
 	u32 sch;
 
@@ -435,53 +434,64 @@
 		if (modify_sch(sch, &schib))
 			continue;
 
-		// found it
-		init_cons = 1;
-		consch = sch;
-
-		// set up the IO interrupt handler
-		psw.ea  = 1;
-		psw.ba  = 1;
-
-		asm volatile(
-			"       larl    %%r1,0f\n"
-			"       stg     %%r1,%0\n"
-			"	brc	15,1f\n"
-			/* IO handler code begins */
-			"0:\n"
-			"	l	%%r1,0xb8\n"
-			"	larl	%%r2,irb\n"
-			"	tsch	0(%%r2)\n"
-			"	l	%%r1,5(%%r2)\n"
-			"	nill	%%r1,0x04\n"
-			"	brc	8,2f\n" // done?
-			"	lg	%%r1,0x178\n" // yes.
-			"	bcr	15,%%r1\n"
-			"2:\n"
-			"	l	%%r1,5(%%r2)\n"
-			"	nill	%%r1,0x80\n"
-			"	brc	8,3f\n" // attention?
-			"	lg	%%r1,0x178\n" // yes.
-			"	bcr	15,%%r1\n"
-			"3:\n"
-			"	lpswe	0x170\n"
-			/* IO handler code ends */
-			"1:\n"
-		: /* output */
-		  "=m" (psw.ptr),
-		  "=m" (irb)
-		: /* input */
-		  "a" (&irb)
-		: /* clobbered */
-		  "r1", "r2"
-		);
-
-		__builtin_memcpy(((void*) 0x1f0), &psw, sizeof(struct psw));
-
-		return;
+		return sch;
 	}
 
-	die();
+	return 0;
+}
+
+static void enable_cons(int devnum)
+{
+	struct psw psw;
+	u32 sch;
+
+	sch = find_dev(devnum);
+
+	if (!sch)
+		die();
+
+	// found it
+	init_cons = 1;
+	consch = sch;
+
+	// set up the IO interrupt handler
+	psw.ea  = 1;
+	psw.ba  = 1;
+
+	asm volatile(
+		"       larl    %%r1,0f\n"
+		"       stg     %%r1,%0\n"
+		"	brc	15,1f\n"
+		/* IO handler code begins */
+		"0:\n"
+		"	l	%%r1,0xb8\n"
+		"	larl	%%r2,irb\n"
+		"	tsch	0(%%r2)\n"
+		"	l	%%r1,5(%%r2)\n"
+		"	nill	%%r1,0x04\n"
+		"	brc	8,2f\n" // done?
+		"	lg	%%r1,0x178\n" // yes.
+		"	bcr	15,%%r1\n"
+		"2:\n"
+		"	l	%%r1,5(%%r2)\n"
+		"	nill	%%r1,0x80\n"
+		"	brc	8,3f\n" // attention?
+		"	lg	%%r1,0x178\n" // yes.
+		"	bcr	15,%%r1\n"
+		"3:\n"
+		"	lpswe	0x170\n"
+		/* IO handler code ends */
+		"1:\n"
+	: /* output */
+	  "=m" (psw.ptr),
+	  "=m" (irb)
+	: /* input */
+	  "a" (&irb)
+	: /* clobbered */
+	  "r1", "r2"
+	);
+
+	__builtin_memcpy(((void*) 0x1f0), &psw, sizeof(struct psw));
 }
 
 static inline void wait_for_io_int()
@@ -576,3 +586,156 @@
 
 	return i;
 }
+
+#define FBA_BLK_SIZE			512
+
+#define DASD_FBA_WRITE			0x41
+#define DASD_FBA_READ			0x42
+#define DASD_FBA_LOCATE_RECORD		0x43
+#define DASD_FBA_DEFINE_EXTENT		0x63
+
+enum op_type {
+	WRITE = 0,
+	READ,
+};
+
+struct fba_DE_data {
+	u8 perm:2,              /* Permissions on this extent */
+	   __zero0:2,
+	   da:1,
+	   diag:1,              /* allow diagnose */
+	   __zero1:2;
+	u8 __zero3;
+	u16 blksize;            /* Blocksize */
+	u32 ext_loc;            /* Extent locator */
+	u32 ext_beg;            /* logical number of block 0 in extent */
+	u32 ext_end;            /* logocal number of last block in extent */
+};
+
+struct fba_LO_data {
+	u8 zero:4,
+	   cmd:4;
+	u8 aux;
+	u16 count;
+	u32 blkno;
+};
+
+/* build a Define-Extent CCW */
+static void fba_define_extent(struct ccw *ccw, struct fba_DE_data *data,
+			      enum op_type rw, u16 blksize, u32 blkno, u32 len)
+{
+	ccw->cmd   = DASD_FBA_DEFINE_EXTENT;
+	ccw->count = 0x10;
+	ccw->addr  = (u32) (u64) data;
+
+	__builtin_memset(data, 0, sizeof(struct fba_DE_data));
+	switch(rw) {
+		case WRITE:
+			data->perm = 0x00;
+			break;
+		case READ:
+			data->perm = 0x01;
+			break;
+		default:
+			die();
+			break;
+	}
+	data->blksize = blksize;
+	data->ext_loc = blkno;
+	data->ext_end = len - 1;
+}
+
+/* build a Locate-Record CCW */
+static void fba_locate_record(struct ccw *ccw, struct fba_LO_data *data,
+			      enum op_type rw, u32 blkno, u32 len)
+{
+	ccw->cmd   = DASD_FBA_LOCATE_RECORD;
+	ccw->count = 0x08;
+	ccw->addr  = (u32) (u64) data;
+
+	__builtin_memset(data, 0, sizeof(struct fba_LO_data));
+	switch(rw) {
+		case WRITE:
+			data->cmd = 0x05;
+			break;
+		case READ:
+			data->cmd = 0x06;
+			break;
+		default:
+			die();
+			break;
+	}
+	data->blkno = blkno;
+	data->count = len;
+}
+
+/* build a Read or Write CCW */
+static void fba_readwrite(struct ccw *ccw, void *ptr, enum op_type rw, u32 len)
+{
+	if(len > 0xffff)
+		die();
+
+	switch(rw) {
+		case 0:
+			ccw->cmd = DASD_FBA_WRITE;
+			break;
+		case 1:
+			ccw->cmd = DASD_FBA_READ;
+			break;
+		default:
+			die();
+			break;
+	}
+
+	ccw->count = len;
+	ccw->addr  = (u32) (u64) ptr;
+}
+
+/**
+ * fba_read_blk - read a block from an FBA device
+ * @dev:	device to read from
+ * @blkno:	block number to read
+ * @ptr:	buffer to fill
+ * @sync:	synchronous I/O
+ */
+static int __fba_readwrite_blk(u32 dev, u32 blkno, void *ptr, enum op_type dir)
+{
+	struct ccw ccw[3];
+	struct fba_DE_data defext;
+	struct fba_LO_data locate;
+
+	__builtin_memset(&orb, 0, sizeof(struct orb));
+	orb.lpm = 0xff;
+	orb.addr = (u32) (u64) ccw;
+	orb.f = 1;
+
+	__builtin_memset(ccw, 0, sizeof(ccw));
+
+	/* Define-Extent */
+	fba_define_extent(&ccw[0], &defext, dir, FBA_BLK_SIZE, blkno, 1);
+	ccw[0].flags |= 0x40;
+
+	/* Locate */
+	fba_locate_record(&ccw[1], &locate, dir, 0, 1);
+	ccw[1].flags |= 0x40;
+
+	/* Read */
+	fba_readwrite(&ccw[2], ptr, dir, FBA_BLK_SIZE);
+
+	if (start_sch(dev, &orb))
+		die();
+
+	wait_for_io_int();
+
+	return 0;
+}
+
+int fba_read_blk(u32 dev, u32 blkno, void *ptr)
+{
+	return __fba_readwrite_blk(dev, blkno, ptr, READ);
+}
+
+int fba_write_blk(u32 dev, u32 blkno, void *ptr)
+{
+	return __fba_readwrite_blk(dev, blkno, ptr, WRITE);
+}
Binary file hercules/disk.img has changed
--- a/hercules/dynamic.cnf	Mon Apr 04 14:48:10 2011 -0400
+++ b/hercules/dynamic.cnf	Wed Apr 06 17:18:00 2011 -0400
@@ -16,3 +16,5 @@
 #---    ----    --------------------
 0009	3215	
 000C    3505	../loader.bin ../dynamic ebcdic multifile eof
+
+0100	9336	disk.img
--- a/hercules/sarpn.cnf	Mon Apr 04 14:48:10 2011 -0400
+++ b/hercules/sarpn.cnf	Wed Apr 06 17:18:00 2011 -0400
@@ -16,3 +16,5 @@
 #---    ----    --------------------
 0009	3215	
 000C    3505	../loader.bin ../sarpn ebcdic multifile eof
+
+0100	9336	disk.img
--- a/include/system.h	Mon Apr 04 14:48:10 2011 -0400
+++ b/include/system.h	Wed Apr 06 17:18:00 2011 -0400
@@ -29,6 +29,11 @@
 	extern int putline(char *buf, int len);
 	extern int getline(char *buf, int len);
 
+	extern u32 find_dev(int devnum);
+
+	extern int fba_read_blk(u32 dev, u32 blkno, void *ptr);
+	extern int fba_write_blk(u32 dev, u32 blkno, void *ptr);
+
 #ifdef __cplusplus
 }
 #endif