#ifndef _KACOMM_H_
#define _KACOMM_H_

/*
 * Q-bus usage (addresses are relative to Q-bus base):
 *
 *	00000000 - 0003ffff	UNIX
 *	00040000 - 0005ffff	Area for BOOT ioctl to use
 *	00060000 - 0007ffff	Unused
 *	00080000 - 00081fff	Unused
 *	00082000 - 00083fff	Arbiter -> slave 1 area
 *	00084000 - 00085fff	Arbiter -> slave 2 area
 *	00086000 - 00087fff	Arbiter -> slave 3 area
 *	00088000 - 00089fff	Slave 1 -> arbiter area
 *	0008a000 - 0008bfff	Unused
 *	0008c000 - 0008dfff	Slave 1 -> slave 2 area
 *	0008e000 - 0008ffff	Slave 1 -> slave 3 area
 *	00090000 - 00091fff	Slave 2 -> arbiter area
 *	00092000 - 00093fff	Slave 2 -> slave 1 area
 *	00094000 - 00095fff	Unused
 *	00096000 - 00097fff	Slave 2 -> slave 3 area
 *	00098000 - 00099fff	Slave 3 -> arbiter area
 *	0009a000 - 0009bfff	Slave 3 -> slave 1 area
 *	0009c000 - 0009dfff	Slave 3 -> slave 2 area
 *	0009e000 - 0009ffff	Unused
 *	000a0000 - 000a03ff	Arbiter blackboard
 *	000a0400 - 000a07ff	Slave 1 blackboard
 *	000a0800 - 000a0bff	Slave 2 blackboard
 *	000a0c00 - 000a0fff	Slave 3 blackboard
 *	000a1000 - 000fffff	Unused
 *	00100000 - 0017ffff	Memory exported by arbiter
 *	00180000 - 001fffff	Memory exported by slave 1
 *	00200000 - 0027ffff	Memory exported by slave 2
 *	00280000 - 002fffff	Memory exported by slave 3
 *	00300000 - 003fffff	Unused
 */

/* Names */
#define KA_ARBITER 0
#define KA_SLAVE(i) (i)
#define KA_SLAVE_1 KA_SLAVE(1)
#define KA_SLAVE_2 KA_SLAVE(2)
#define KA_SLAVE_3 KA_SLAVE(3)

/* Machine sizes */
#define KA_QBUSSIZE     0x00400000		/* Q-bus space */
#define KA_QBUSIOSIZE   0x00002000		/* Q-bus I/O page */
#define KA_QBUSUNIXSIZE 0x00040000		/* Q-bus space UNIX owns */

/* Communication area sizes */
/* Many places in the slave .s files assume these numbers are multiples	 */
/*  of the hardware pagesize, 512 (0x200).				 */
#define KA_BOOTSIZE     0x00020000		/* Boot area */
#define KA_MSGBUFSIZE   0x00002000		/* Each message area */
#define KA_BBOARDSIZE   0x00000400		/* Each blackboard area */
#define KA_EXPORTSIZE   0x00080000		/* Each export area */

/* Machine base addresses */
#define KA_QBUSBASE   0x30000000		/* Q-bus space */
#define KA_QBUSIOBASE 0x20000000		/* Q-bus I/O page */
#define KA_QMAPBASE   0x20088000		/* Q-bus map registers */

/* Area base addresses */
#define KA_BOOTBASE   (KA_QBUSBASE+0x00040000)	/* Boot area */
#define KA_MSGBASE    (KA_QBUSBASE+0x00080000)	/* Message areas */
#define KA_BBOARDBASE (KA_QBUSBASE+0x000a0000)	/* Blackboards */
#define KA_EXPORTBASE (KA_QBUSBASE+0x00100000)	/* Export areas */

/* The equivalent of this #define is wired into slave .s files */
#define KA_X_TO_Y(from,to) (KA_MSGBASE+(KA_MSGBUFSIZE*(((from)*4)+(to))))
#define KA_A_TO_1 KA_X_TO_Y(KA_ARBITER,KA_SLAVE_1)
#define KA_A_TO_2 KA_X_TO_Y(KA_ARBITER,KA_SLAVE_2)
#define KA_A_TO_3 KA_X_TO_Y(KA_ARBITER,KA_SLAVE_3)
#define KA_1_TO_A KA_X_TO_Y(KA_SLAVE_1,KA_ARBITER)
#define KA_1_TO_2 KA_X_TO_Y(KA_SLAVE_1,KA_SLAVE_2)
#define KA_1_TO_3 KA_X_TO_Y(KA_SLAVE_1,KA_SLAVE_3)
#define KA_2_TO_A KA_X_TO_Y(KA_SLAVE_2,KA_ARBITER)
#define KA_2_TO_1 KA_X_TO_Y(KA_SLAVE_2,KA_SLAVE_1)
#define KA_2_TO_3 KA_X_TO_Y(KA_SLAVE_2,KA_SLAVE_3)
#define KA_3_TO_A KA_X_TO_Y(KA_SLAVE_3,KA_ARBITER)
#define KA_3_TO_1 KA_X_TO_Y(KA_SLAVE_3,KA_SLAVE_1)
#define KA_3_TO_2 KA_X_TO_Y(KA_SLAVE_3,KA_SLAVE_2)

/* The equivalent of this #define is wired into slave .s files */
#define KA_BBOARD(cpu) (KA_BBOARDBASE+(KA_BBOARDSIZE*(cpu)))
#define KA_BBOARD_A KA_BBOARD(KA_ARBITER)
#define KA_BBOARD_1 KA_BBOARD(KA_SLAVE_1)
#define KA_BBOARD_2 KA_BBOARD(KA_SLAVE_2)
#define KA_BBOARD_3 KA_BBOARD(KA_SLAVE_3)

#define KA_EXPORT(cpu) (KA_EXPORTBASE+(KA_EXPORTSIZE*(cpu)))
#define KA_EXPORT_A KA_EXPORT(KA_ARBITER)
#define KA_EXPORT_1 KA_EXPORT(KA_SLAVE_1)
#define KA_EXPORT_2 KA_EXPORT(KA_SLAVE_2)
#define KA_EXPORT_3 KA_EXPORT(KA_SLAVE_3)

/* Assorted #defines */

#define KA_QMAP_V 0x80000000	/* Valid bit for a Q-bus map register */

#define KA_CANWAIT  0		/* Can afford to sleep() */
#define KA_CANTWAIT 1		/* Can't afford to sleep() */

/* I/O codes for ka_msgbufio */
#define KA_WRITE     0		/* Write */
#define KA_IREAD     1		/* Read, interrupt level */
#define KA_READ      2		/* Read, non-interrupt level */
#define KA_ISKIP     3		/* Read w/o saving, interrupt level */
#define KA_SKIP      4		/* Read w/o saving, non-interrupt level */
/* Bit masks */
#define KA_OP    0x0ff		/* Mask off just the operation */
#define KA_PEEK  0x100		/* Just move bytes, don't change pointers */

/* The 12 is the total size of the non-data area in the kamsgarea	 */
/*  struct below.  We can't play with sizeof because this define gets	 */
/*  used in assembly code.						 */
#define KA_MSGDATASIZE (KA_MSGBUFSIZE-12)
#ifndef LOCORE
/* The seen variable is for the private use of the recipient processor.	 */
/*  Change the KA_MSGDATASIZE #define whenever adding to or deleting	 */
/*  from the non-data portion of this structure.			 */
struct kamsgarea {
  int head;
  int seen;
  int tail;
  char data[KA_MSGDATASIZE];
  } ;
struct kabboard {
  int timesch;
  int time100;
  int time_rt[4];	/* modified only by the scheduler cpus */
  } ;
struct kabbblock {
  struct kabboard common;
  char scratch[KA_BBOARDSIZE-sizeof(struct kabboard)];
  } ;
#endif

#endif
