view arch/channel.h @ 14:c75be274ce23

Now functioning arch code
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Thu, 07 Apr 2011 23:29:10 -0400
parents 40af39d064fa
children 3d69c66b2610
line wrap: on
line source

#ifndef __CHANNEL_H
#define __CHANNEL_H

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 */
};

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:7,		/* Activity control */
	    sc:5;		/* 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));

struct schib {
	struct pmcw pmcw;               /* Path Management Control Word */
	struct scsw scsw;               /* Subchannel Status Word */
	u32 measure_block_1;
	u32 measure_block_2;
	u32 model_dep_area;
} __attribute__((packed,aligned(4)));

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)));

struct ccw {
	u8 cmd;			/* Command code */
	u8 flags;		/* Flags */
	u16 count;		/* Count */
	u32 addr;		/* Data Address */
} __attribute__((packed,aligned(8)));

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;
};

struct irb {
	struct scsw scsw;			/* Subchannel-Status */
	u32 w0a, w1a, w2a, w3a, w4a;
	u32 w0b, w1b, w2b, w3b, w4b, w5b, w6b, w7b;
	u32 w0c, w1c, w2c, w3c, w4c, w5c, w6c, w7c;
} __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"
	);

	return cc;
}

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"
	);

	return cc;
}

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"
	);

	return cc;
}

static inline void wait_for_io_int()
{
	struct psw psw;

        __builtin_memset(&psw, 0, sizeof(struct psw));
        psw.io  = 1;
        psw.ea  = 1;
        psw.ba  = 1;
	psw.w   = 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", "r2"
        );
}

#endif