Jump to content

SMPV211 - Appendix A: Difference between revisions

From EDM2
No edit summary
No edit summary
 
Line 1: Line 1:
{{SMPV211}}
The following is the source code for an actual PSD.
The following is the source code for an actual PSD.
==Main program==
==Main program==

Latest revision as of 19:38, 24 May 2025

Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation

OS/2 for SMP V2.11 Reference
  1. Notices
  2. Overview of OS/2 for SMP Version 2.11
  3. Platform Specific Drivers (PSDs)
  4. Understanding Spinlocks
  5. Device Drivers In OS/2 for SMP V2.11
  6. Application Considerations
  7. Avoiding Device Driver Deadlocks
  8. New Device Helper (DevHlp) Routines
  9. New Kernel Debugger Commands
  10. The Single Processor Utility Program
  11. OS/2 for SMP V2.11 Tools
  12. Appendix A
  13. Glossary

The following is the source code for an actual PSD.

Main program

#define INCL_ERROR_H

#include <os2.h>
#include <psd.h>
#include <alr.h>


extern ulong_t RMP2Available(void);


/*
 *  Global Variables
 */

P_F_2   router = 0;
char   *pParmString = 0;
int     IODelayCount = 30;
PLMA   *pPSDPLMA = 0;
ulong_t sizePLMA = 0;


/***  Disable - Disable interrupts
 *
 *    This function disables interrupts, and returns
 *    the original state of eflags
 *
 *    ENTRY   None
 *
 *    EXIT    EFLAGS
 *
 */

ulong_t Disable(void) {

   ulong_t eflags;

   _asm {
      pushfd
      pop   eax
      mov   eflags,eax
      cli
   };

   return (eflags);
}


/***  Enable - Restore the state of eflags
 *
 *    This function restores the state of eflags
 *
 *    ENTRY   eflags - state of eflags to restore
 *
 *    EXIT    None
 *
 */

void Enable(ulong_t eflags) {

   _asm {
      push  eflags
      popfd
   };

   return;
}


 /***  InByte - Read a byte from a port
  *
  *    This function reads a byte from a specified port
  *
  *    ENTRY   port - port number to read from
  *
  *    EXIT    data read
  *
  */

 ulong_t InByte(ulong_t port) {

    ulong_t data;

    _asm {
       mov   dx,port
       in    al,dx
       movzx eax,al
       mov   data,eax
    };

    return (data);
}


/***  OutByte - Writes a byte to a port
 *
 *    This function writes a byte to a specified port
 *
 *    ENTRY   port - port number to read from
 *            data - data to write
 *
 *    EXIT    None
 *
 */

void OutByte(ulong_t port, ulong_t data) {

   _asm {
      mov   dx,port
      mov   al,byte ptr data
      out   dx,al
   };

   return;
}


/***  SendEOI - Send an end of interrupt
 *
 *    This function sends an end of interrupt.
 *
 *    ENTRY   irq - irq level to end
 *
 *    EXIT    None
 *
 */

ulong_t SendEOI(ulong_t irq) {

   ulong_t flags;

   flags = Disable();

   if (irq < NUM_IRQ_PER_PIC)
      OutByte(PIC1_PORT0, OCW2_NON_SPECIFIC_EOI);
   else {
      OutByte(PIC2_PORT0, OCW2_NON_SPECIFIC_EOI);
      IODelay;
      OutByte(PIC1_PORT0, OCW2_NON_SPECIFIC_EOI);
   }

   Enable(flags);
}


/***  WHO_AM_I - Returns the current processor number
 *
 *    This function returns the current processor number
 *
 *    ENTRY   NONE
 *
 *    EXIT    Current processor number (P1 or P2)
 *
 */

ulong_t WHO_AM_I (void) {
   return(InByte(WHO_AM_I_PORT));
}


/***  IPIPresent - Detects the presence of an IPI
 *
 *    This function detects the presence of an IPI on the current
 *    processor
 *
 *    ENTRY   None
 *
 *    EXIT    NO_ERROR - IPI present
 *            -1       - IPI not present
 *
 */

ulong_t IPIPresent (void) {

   ulong_t rc = 0;
   struct control_s ctrl;
   ulong_t port;

   port = pPSDPLMA->controlport;

   ctrl.b_all = InByte(port);
   if (ctrl.b_387err)
   {
      OutByte (0xf0, 0); // The busy latch for NPX must be cleared.
                         // When we call the interrupt handler
                         // (w/ Call16bitDD int.asm), ints. are 1st enabled.
                         // If the busy latch is not cleared, then we
                         // will take this interrupt in again and will
                         // eventually nest until the interrupt stack is
                         // overrun.
      rc = -1;
   }
   return (rc);
}


/***  Install - Install PSD
 *
 *    This function checks to see if this PSD is installable on the
 *    current platform.
 *
 *    ENTRY   pinstall - pointer to an INSTALL structure
 *
 *    EXIT    NO_ERROR - PSD Installed
 *            -1       - PSD not valid for this platform
 *
 */

ulong_t Install(INSTALL *pinstall) {

   VMALLOC vmac;
   int i;
   char *p;
   ulong_t rc = 0;
   char ALR_String =  "PROVEISA";

// _asm int 3;

   /* Setup Global variables */

   router = pinstall->pPSDHlpRouter;
   pParmString = pinstall->pParmString;
   pPSDPLMA = (void *)pinstall->pPSDPLMA;
   sizePLMA = pinstall->sizePLMA;

   vmac.addr = BIOS_SEG << 4;
   vmac.cbsize = _64K;
   vmac.flags = VMALLOC_PHYS;

   /* Map BIOS area */

   if ((rc = PSDHelp(router, PSDHLP_VMALLOC, &vmac)) == NO_ERROR) {

      /* Check for ALR string */

      p = (char *)vmac.addr + ALR_STRING_OFFSET;

      for (i = 0; ALR_String i != '\0'; i++)
         if (p i  != ALR_String i) {
            rc = -1;
            break;
         }

      /* Free BIOS mapping */

      PSDHelp(router, PSDHLP_VMFREE, vmac.addr);
   }

   return (rc);
}


/***  DeInstall - DeInstall PSD
 *
 *    This function deinstalls the PSD.
 *
 *    ENTRY   None
 *
 *    EXIT    NO_ERROR
 *
 */

ulong_t DeInstall(void) {

   return (NO_ERROR);
}


/***  Init - Initialize the PSD
 *
 *    This function initializes the PSD.
 *
 *    ENTRY   None
 *
 *    EXIT    NO_ERROR - PSD initialized
 *            -1       - PSD not initialized
 *
 */

ulong_t Init(INIT *pinit) {

   struct control_s ctrl;
   SET_IRQ set_irq;


   /* Initialize P1 control port */

   ctrl.b_all = 0;
   ctrl.b_cacheon = 1;


   OutByte(P1_PROCESSOR_CONTROL_PORT, ctrl.b_all);

   /* Setup P2 interrupt vector */

   OutByte(P2_INTERRUPT_VECTOR_CONTROL_PORT, IPI_VECTOR);

   /* Setup IPI info */

   set_irq.irq = 13;
   set_irq.flags = IRQf_IPI;
   set_irq.vector = 0;
   set_irq.handler = (P_F_2)IPIPresent;

   PSDHelp(router, PSDHLP_SET_IRQ, &set_irq);

   /* Fill init structure */

   pinit->flags = INIT_EOI_IRQ13_ON_CPU0;           //76422
   pinit->version = VERSION;

   return (NO_ERROR);
}


/***  ProcInit - Processor initialization
 *
 *    This function initializes per processor items.
 *
 *    NOTE: This function is called once on each processor
 *          in the system.
 *
 *    ENTRY   None
 *
 *    EXIT    NO_ERROR - Processor initialized
 *            -1       - Processor not initialized
 *
 */

ulong_t ProcInit(void) {

   if (WHO_AM_I() == P1) {
      pPSDPLMA->procnum = 0;
      pPSDPLMA->controlport = P1_PROCESSOR_CONTROL_PORT;
   }
   else {
      pPSDPLMA->procnum = 1;
      pPSDPLMA->controlport = P2_PROCESSOR_CONTROL_PORT;
   }

   return (NO_ERROR);
}


/***  StartProcessor - Start a processor
 *
 *    This function starts a processor.
 *
 *    ENTRY   procnum - processor number to start (0-based)
 *
 *    EXIT    Return Code
 *
 */

ulong_t StartProcessor(ulong_t procnum) {

   CALL_REAL_MODE rm;
   struct control_s ctrl;
   ulong_t rc = -1;


   if (procnum == 1) {

      rm.function = (ulong_t)&RMP2Available;
      rm.pdata = 0;

      rc = PSDHelp(router, PSDHLP_CALL_REAL_MODE, &rm);

      if (rc & P2_AVAILABLE) {

         /* Dispatch P2 */

         ctrl.b_all = 0;
         ctrl.b_cacheon = 1;

         OutByte(P2_PROCESSOR_CONTROL_PORT, ctrl.b_all);
         rc = NO_ERROR;
      }
      else
         rc = -1;
   }

   return (rc);
}


/***  GetNumOfProcs - Get number of processors
 *
 *    This function gets the number of processors which exist on this
 *    platform.
 *
 *    ENTRY   None
 *
 *    EXIT    Number of processors
 *
 */

ulong_t GetNumOfProcs(void) {

   ulong_t cprocs = 2;

   return (cprocs);
}


/***  GenIPI - Generate an inter-processor interrupt
 *
 *    This function generates an IPI.
 *
 *    ENTRY   procnum - processor number to interrupt (0-based)
 *
 *    EXIT    NO_ERROR
 *
 */

ulong_t GenIPI(ulong_t procnum) {

   struct control_s ctrl;
   ulong_t port;


   if (procnum == 0)
      port = P1_PROCESSOR_CONTROL_PORT;
   else
      port = P2_PROCESSOR_CONTROL_PORT;


   ctrl.b_all = InByte(port);
   ctrl.b_pint = 1;

   OutByte(port, ctrl.b_all);

   return (NO_ERROR);
}


/***  EndIPI - End an inter-processor interrupt
 *
 *    This function ends an IPI.
 *
 *    ENTRY   procnum - processor number to end interrupt on (0-based)
 *
 *    EXIT    NO_ERROR
 *
 */

ulong_t EndIPI(ulong_t procnum) {

   struct control_s ctrl;
   ulong_t port;

   if (procnum == 0)
      port = P1_PROCESSOR_CONTROL_PORT;
   else
      port = P2_PROCESSOR_CONTROL_PORT;

   ctrl.b_all = InByte(port);
   ctrl.b_pint = 0;

   OutByte(port, ctrl.b_all);

   if (procnum == 0)
      SendEOI(IPI_IRQ);

   return (NO_ERROR);
}

Entry stub

.386

_TEXT SEGMENT

ASSUME CS:_TEXT,DS:NOTHING

      PUBLIC  _RMP2Available

_RMP2Available PROC

      mov   ah,0E2h
      mov   al,0
      int   15h
      movzx eax,ax
      retf

_RMP2Available ENDP

_TEXT ENDS

END

PSD.H

/*static char *SCCSID = "@(#)psd.h 1.0 93/18/08";*/


// XLATOFF

#ifndef ulong_t

typedef unsigned long   ulong_t;
typedef unsigned short  ushort_t;
typedef unsigned char   uchar_t;

#endif

typedef int (*P_F_1)(ulong_t arg);
typedef int (*P_F_2)(ulong_t arg1, ulong_t arg2);

#define PSDHelp(router, function, arg) \
   ((*router)((function), (ulong_t)(arg)))

// XLATON
/* ASM
P_F_1 struc
dd ?
P_F_1 ends
P_F_2 struc
dd ?
P_F_2 ends
*/


#define WARM_REBOOT_VECTOR_SEG  0x40
#define WARM_REBOOT_VECTOR_OFF  0x67


/* PSD Info structure */

typedef struct info_s {                     /* psd */
   ulong_t  flags;                          /* PSD flags */
   ulong_t  version;                        /* PSD version */
   ulong_t  hmte;                           /* MTE handle of PSD */
   uchar_t *pParmString;                    /* Pointer to ASCIIZ PSD parameter*/
   ulong_t  IRQ_IPI;                        /* IRQ for IPI */
   ulong_t  IRQ_LSI;                        /* IRQ for LSI */
   ulong_t  IRQ_SPI;                        /* IRQ for SPI */
} PSDINFO;


/* PSD flags definition */

#define PSD_ADV_INT_MODE        0x20000000  /* PSD is in adv int mode #81531 */
#define PSD_INSTALLED           0x40000000  /* PSD has been installed */
#define PSD_INITIALIZED         0x80000000  /* PSD has been initialized */

/* PSD function numbers-structures */

#define PSD_INSTALL             0x00000000  /* Install PSD */

typedef struct install_s {                  /* install */
   P_F_2   pPSDHlpRouter;                   /* Address of PSDHlpRouter */
   char   *pParmString;                     /* Pointer to parameter string */
   void   *pPSDPLMA;                        /* Pointer to PSD's PLMA */
   ulong_t sizePLMA;                        /* Size of PLMA in bytes */
} INSTALL;

#define PSD_DEINSTALL           0x00000001  /* DeInstall PSD */

#define PSD_INIT                0x00000002  /* Initialize PSD */

typedef struct init_s {                     /* init */
   ulong_t flags;                           /* Init flags */
   ulong_t version;                         /* PSD Version number */
} INIT;

#define INIT_GLOBAL_IRQ_ACCESS  0x00000001  /* Platform has global IRQ access */
#define INIT_USE_FPERR_TRAP     0x00000002  /* Use Trap 16 to report FP err's */
#define INIT_EOI_IRQ13_ON_CPU0  0x00000004  /* eoi IRQ 13 only if on cpu 0    */
#define INIT_TIMER_CPU0         0x00000008  /* system timer is on CPU 0       */

#define PSD_PROC_INIT           0x00000003  /* Initialize processor */

#define PSD_START_PROC          0x00000004  /* Start processor */

#define PSD_GET_NUM_OF_PROCS    0x00000005  /* Get number of processors */

#define PSD_GEN_IPI             0x00000006  /* Generate an IPI */

#define PSD_END_IPI             0x00000007  /* End an IPI */

#define PSD_PORT_IO             0x00000008  /* Port I/O */

typedef struct port_io_s {                  /* port_io */
   ulong_t port;                            /* Port number to access */
   ulong_t data;                            /* Data read, or data to write */
   ulong_t flags;                           /* IO Flags */
} PORT_IO;

#define IO_READ_BYTE    0x0000              /* Read a byte from the port */
#define IO_READ_WORD    0x0001              /* Read a word from the port */
#define IO_READ_DWORD   0x0002              /* Read a dword from the port */
#define IO_WRITE_BYTE   0x0003              /* Write a byte to the port */
#define IO_WRITE_WORD   0x0004              /* Write a word to the port */
#define IO_WRITE_DWORD  0x0005              /* Write a dword to the port */

#define IO_FLAGMASK     0x0007              /* Flag mask */

#define PSD_IRQ_MASK            0x00000009  /* Mask/Unmask IRQ levels */

typedef struct psd_irq_s {                  /* psd_irq */
   ulong_t flags;                           /* IRQ flags */
   ulong_t data;                            /* IRQ data */
                                            /*   depending on type of irq */
                                            /*   operation, the data field */
                                            /*   can contain any of the */
                                            /*   following info: */
                                            /*   1) Mask or UNMasking data */
                                            /*   2) IRR or ISR reg values */
                                            /*   3) IRQ # for EOI operations */
   ulong_t procnum;                         /* Processor number */
} PSD_IRQ;

#define PSD_IRQ_REG             0x0000000A  /* Access IRQ related regs */

#define PSD_IRQ_EOI             0x0000000B  /* Issue an EOI */

#define IRQ_MASK                0x00000001  /* Turn on IRQ mask bits */
#define IRQ_UNMASK              0x00000002  /* Turn off IRQ mask bits */
#define IRQ_GETMASK             0x00000004  /* Get IRQ mask bits */
#define IRQ_NEWMASK             0x00000010  /* Set and/or Reset all masks */
#define IRQ_READ_IRR            0x00000100  /* Read the IRR reg */
#define IRQ_READ_ISR            0x00000200  /* Read the ISR reg */

#define PSD_APP_COMM            0x0000000C  /* PSD/APP Communication */

#define PSD_SET_ADV_INT_MODE    0x0000000D  /* Set advanced int mode */

#define PSD_SET_PROC_STATE      0x0000000E  /* Set proc state; idle, or busy */

#define PROC_STATE_IDLE         0x00000000  /* Processor is idle */
#define PROC_STATE_BUSY         0x00000001  /* Processor is busy */

#define PSD_QUERY_SYSTEM_TIMER  0x0000000F  /* Query Value of System Timer 0 */

typedef struct psd_qrytmr_s {               /* psd_qrytmr */
   ulong_t qw_ulLo_psd;                     /* Timer count */
   ulong_t qw_ulHi_psd;                     /* Timer count */
   ulong_t pqwTmr;                          /* 16:16 ptr to qwTmr */
} PSD_QRYTMR;

#define PSD_SET_SYSTEM_TIMER    0x00000010  /* Set System Timer 0 counter    */

typedef struct psd_settmr_s {               /* psd_settmr */
   ulong_t NewRollOver;                     /* NewRollover*/
   ulong_t pqwTmrRollover;                  /* 16:16 ptr to qwTmrRollover */
} PSD_SETTMR;

/* PSD helper function numbers-structures */

#define PSDHLP_VMALLOC          0x00000000  /* Allocate memory */

typedef struct vmalloc_s {                  /* vmalloc */
   ulong_t addr;                            /* Physical address to map */
                                            /*  if VMALLOC_PHYS */
                                            /* Lin addr to alloc at */
                                            /*  if VMALLOC_LOCSPECIFIC */
                                            /* on return, addr of allocation */
   ulong_t cbsize;                          /* Size of mapping in bytes */
   ulong_t flags;                           /* Allocation flags */
} VMALLOC;

#define VMALLOC_FIXED           0x00000001  /* Allocate resident memory */
#define VMALLOC_CONTIG          0x00000002  /* Allocate contiguous memory */
#define VMALLOC_LOCSPECIFIC     0x00000004  /* Alloc at a specific lin address */
#define VMALLOC_PHYS            0x00000008  /* Map physical address */
#define VMALLOC_1M              0x00000010  /* Allocate below 1M */

#define VMALLOC_FLAGMASK        0x0000001f  /* Valid flag mask */

#define PSDHLP_VMFREE           0x00000001  /* Free memory */

#define PSDHLP_SET_IRQ          0x00000002  /* Set up an IRQ */

typedef struct set_irq_s {                  /* set_irq */
   ushort_t irq;                            /* IRQ level */
   ushort_t flags;                          /* Set IRQ flags */
   ulong_t  vector;                         /* IRQ interrupt vector */
   P_F_2    handler;                        /* IRQ handler */
} SET_IRQ;

#define IRQf_IPI  0x0020                    /* IRQ for IPI */
#define IRQf_LSI  0x0040                    /* IRQ for LSI */
#define IRQf_SPI  0x0080                    /* IRQ for SPI */

#define PSDHLP_CALL_REAL_MODE   0x00000003  /* Call a function in real mode */

typedef struct call_real_mode_s {           /* call_real_mode */
   ulong_t function;                        /* Function address */
   ulong_t pdata;                           /* Pointer to data area */
} CALL_REAL_MODE;

#define PSDHLP_VMLINTOPHYS      0x00000004  /* Convert linear addr to phys */

#define PSDHLP_ADJ_PG_RANGES    0x00000005  /* Adjust page ranges */

typedef struct _pagerange_s {               /* pagerange */
   ulong_t lastframe;                       /* Last valid page in range */
   ulong_t firstframe;                      /* First valid page in range */
};

typedef struct adj_pg_ranges_s{             /* adj_pg_ranges */
   struct _pagerange_s *pprt;               /* Pointer to page range table */
   ulong_t nranges;                         /* Num of ranges in range table */
} ADJ_PG_RANGES;

/* PSD function prototypes */

extern void PSDEnter (ulong_t function, ulong_t arg, P_F_2 altEntry);

Specific header

/*
 * Miscellaneous
 */

#define VERSION   0x00000010

#define _64K      (64 * 1024)

#define BIOS_SEG             0xF000
#define ALR_STRING_OFFSET   0xEC47

#define P2_AVAILABLE         0x00008000


/*
 * PLMA structure
 */

typedef struct plma_s {
   ulong_t procnum;       /* Current processor number (0-based) */
   ulong_t controlport;   /* Control port for current processor */
} PLMA;


/*
 * Generate delay between I/O instructions
 */

#define IODelay {int i; for(i = 0; i < IODelayCount; i++); }


/*
 * IPI info
 */

#define IPI_IRQ     0x0d      /* IRQ level for IPI */
#define IPI_VECTOR  0x75      /* Vector number for IPI */


/*
 * PIC Info
 */

#define NUM_IRQ_PER_PIC         0x08
#define OCW2_NON_SPECIFIC_EOI   0x20
#define PIC1_PORT0              0x20
#define PIC1_PORT1              0x21
#define PIC2_PORT0              0xA0
#define PIC2_PORT1              0xA1


/*
 * The contents of the WHO_AM_I port (read-only) can be used
 * by code to determine which processor we are currently on
 */

#define WHO_AM_I_PORT  0xC70
#define P1             0x00
#define P2             0xF0


/*
 * The processor control port contains the bits used to control
 * various functions of the associated processor
 */

#define P1_PROCESSOR_CONTROL_PORT  0x0C6A
#define P2_PROCESSOR_CONTROL_PORT  0xFC6A

struct _b_control_s {
   ulong_t _reset:1,      /* RESET - (Not implemented for P1) */
                          /*  1 = Resets processor */

           _387pres:1,    /* 387PRES - (Read only) */
                          /*  0 = 80387 is not installed */
                          /*  1 = 80387 is installed */

           _cacheon:1,    /* CACHEON - (Not implemented for P1) */
                          /*  0 = Disables cache */
                          /*  1 = Enables cache */

           _mbusaccess:1, /* M Bus Access (Not implemented for P1) */
                          /*  0 = Allows the processor to gain */
                          /*      control of the memory bus */
                          /*  1 = Prohibits the processor from gaining */
                          /*      access to the memory bus. The */
                          /*      processor can execute instructions */
                          /*      from its cache; however, cache read */
                          /*      misses, I/O, and writes cause the */
                          /*      processor to cease executing */
                          /*      instructions until the bit becomes */
                          /*      a "0" */

           _flush:1,      /* FLUSH */
                          /*  Writing a "1" to this bit followed by a "0" */
                          /*  causes invalidation of all cache address */
                          /*  information */

           _387err:1,     /* 387ERR */
                          /*  0 = No 80387 error */
                          /*  0 = An 80387 error has occurred. This bit */
                          /*      must be cleared by software */

           _pint:1,       /* PINT */
                          /*  A low-to-high transition of this bit causes */
                          /*  an interrupt. This bit must be cleared by  */
                          /*  software, preferably by the interrupt service */
                          /*  routine. On P2, the value stored in FC68h */
                          /*  contains the interrupt number. P1 is always */
                          /*  interrupted with IRQ13 */

           _intdis:1,     /* INTDIS */
                          /*  When set to "1", this bit disables interrupts */
                          /*  sent to the processor by way of the PINT bit. */
                          /*  The PINT bit can still be changed when */
                          /*  interrupts are disabled; however, the */
                          /*  low-to-high transition is not seen by the */
                          /*  processor until the INTDIS bit is made inactive */
           _pad:24;
};

struct _l_control_s {     /* to treat control as an unsigned long */
    unsigned long _long;
};

union _control_u {
    struct _b_control_s b_control_s;
    struct _l_control_s l_control_s;
};

struct control_s {
    union _control_u control_u;
};

#define b_reset       control_u.b_control_s._reset
#define b_387pres     control_u.b_control_s._387pres
#define b_cacheon     control_u.b_control_s._cacheon
#define b_mbusaccess  control_u.b_control_s._mbusaccess
#define b_flush       control_u.b_control_s._flush
#define b_387err      control_u.b_control_s._387err
#define b_pint        control_u.b_control_s._pint
#define b_intdis      control_u.b_control_s._intdis
#define b_all         control_u.l_control_s._long


/*
 * The interrupt vector control port contains the 8-bit interrupt
 * number that is executed when the PINT bit transitions from "0"
 * to "1". This vector is only used for P2. P1 is always interrupted
 * with IRQ 13.
 */

#define P2_INTERRUPT_VECTOR_CONTROL_PORT 0xFC68


/*
 * The following ports contain the EISA identification of the
 * system processor boards
 */

#define COMPAQ_ID1  0x0000000E
#define COMPAQ_ID2  0x00000011

#define P1_EISA_PRODUCT_ID_PORT1  0x0C80  /* Compressed COMPAQ ID - OEh */
#define P1_EISA_PRODUCT_ID_PORT2  0x0C81  /*                        11h */
#define P1_EISA_PRODUCT_ID_PORT3  0x0C82  /* Product code for the proc board */
#define P1_EISA_PRODUCT_ID_PORT4  0x0C83  /* Revision number */

#define P2_EISA_PRODUCT_ID_PORT1  0xFC80  /* Compressed COMPAQ ID - OEh */
#define P2_EISA_PRODUCT_ID_PORT2  0xFC81  /*                        11h */
#define P2_EISA_PRODUCT_ID_PORT3  0xFC82  /* Product code for the proc board */
#define P2_EISA_PRODUCT_ID_PORT4  0xFC83  /* Revision number */

/*
 * Any write to The RAM Relocation Register (memory mapped)
 * will flush the caches of both P1 and P2
 */

#define RAM_RELOCATION_REGISTER       0x80C00000


/*
 * The P1 Cache Control Register (memory mapped)
 */

#define P1_CACHE_CONTROL_REGISTER     0x80C00002

struct p1cache_s {
   ulong_t _reserved1:6,
           _p1cc:1,       /* P1 Cache Control */
                          /*  0 = Disables P1 cache */
                          /*  1 = Enables P1 cache */
           _reserved2:9;
};


/*
 * Expanision board control ports
 */

#define P1_EISA_EXPANSION_BOARD_CONTROL  0x0C84
#define P2_EISA_EXPANSION_BOARD_CONTROL  0xFC84

Makefile

# SCCSID = @(#)makefile 6.7 92/06/03

#/***********************************************************************/
#/*                                                                     */
#/* PSD Name: ALR.PSD - ALR PSD                                         */
#/*           -----------------------------------                       */
#/*                                                                     */
#/* Source File Name: MAKEFILE                                          */
#/*                                                                     */
#/* Descriptive Name: MAKEFILE for the ALR PSD                          */
#/*                                                                     */
#/* Function:                                                           */
#/*                                                                     */
#/*                                                                     */
#/*---------------------------------------------------------------------*/
#/*                                                                     */
#/* Copyright (C) 1992 IBM Corporation                                  */
#/*                                                                     */
#/* DISCLAIMER OF WARRANTIES.  The following enclosed code is           */
#/* provided to you solely for the purpose of assisting you in          */
#/* the development of your applications. The code is provided          */
#/* "AS IS", without warranty of any kind. IBM shall not be liable      */
#/* for any damages arising out of your use of this code, even if       */
#/* they have been advised of the possibility of such damages.          */
#/*                                                                     */
#/*---------------------------------------------------------------------*/
#/*                                                                     */
#/* Change Log                                                          */
#/*                                                                     */
#/* Mark    Date      Programmer  Comment                               */
#/* ----    ----      ----------  -------                               */
#/* @nnnn   mm/dd/yy  NNN                                               */
#/*                                                                     */
#/*                                                                     */
#/***********************************************************************/

# ******  NOTE  ******
#
#       If you are using a SED command with TAB characters, many editors
#       will expand tabs causing unpredictable results in other programs.
#
#       Documentation:
#
#       Using SED command with TABS. Besure to invoke set tab save option
#       on your editor. If you don't, the program 'xyz' will not work
#       correctly.
#

#****************************************************************************
#  Dot directive definition area (usually just suffixes)
#****************************************************************************

.SUFFIXES:
.SUFFIXES: .com .sys .exe .obj .mbj .asm .inc .def .lnk .lrf .crf .ref
.SUFFIXES: .lst .sym .map .c .h .lib

#****************************************************************************
#  Environment Setup for the component(s).
#****************************************************************************

#
# Conditional Setup Area and User Defined Macros
#

#
# Compiler Location w/ includes, libs and tools
#

INC    = ..\..\..\inc
H      = ..\..\..\h
LIB    = ..\..\..\lib386;..\..\..\lib
TOOLSPATH = ..\..\..\tools

#
# Because the compiler/linker and other tools use environment
# variables ( INCLUDE, LIB, etc ) in order to get the location of files,
# the following line will check the environment for the LIFE of the
# makefile and will be specific to this set of instructions. All MAKEFILES
# are requested to use this format to insure that they are using the correct
# level of files and tools.
#

!if set INCLUDE=$(INC) || \
    set LIB=$(LIB) || set PATH=$(TOOLSPATH);$(DK_TOOLS)
!endif


#
# Compiler/tools Macros
#

AS=masm
CC=cl386
IMPLIB=implib
IPF=ipfc
LIBUTIL=lib
LINK=link386
MAPSYM=mapsym
RC=rc

#
# Compiler and Linker Options
#

AFLAGS = -MX -T -Z $(ENV)
AINC   = -I. -I$(INC)
CINC   = -I$(H) -I$(MAKEDIR)
CFLAGS = /c /Zp /Gs /AS $(ENV)
LFLAGS = /map /nod /exepack

LIBS = os2386.lib
DEF = ALR.def

#****************************************************************************
# Set up Macros that will contain all the different dependencies for the
# executables and dlls etc. that are generated.
#****************************************************************************

#
#
#
OBJ1 =  entry.obj main.obj

#
#       LIST Files
#
LIST =

OBJS = $(OBJ1)

#****************************************************************************
#   Setup the inference rules for compiling and assembling source code to
#   object code.
#****************************************************************************


.asm.obj:
        $(AS) $(AFLAGS) $(AINC) $*.asm;

.asm.mbj:
        $(AS) $(AFLAGS) -DMMIOPH $(AINC) $*.asm $*.mbj;

.asm.lst:
        $(AS) -l -n $(AFLAGS) $(AINC) $*.asm;

.c.obj:
        $(CC) $(CFLAGS) $(CINC) $*.c

.c.lst:
        $(CC) $(CFLAGS) /Fc $(CINC) $*.c
        copy $*.cod $*.lst
        del $*.cod


#****************************************************************************
#   Target Information
#****************************************************************************
#
# This is a very important step. The following small amount of code MUST
# NOT be removed from the program. The following directive will do
# dependency checking every time this component is built UNLESS the
# following is performed:
#               A specific tag is used -- ie. all
#
# This allows the developer as well as the B & I group to perform incremental
# build with a degree of accuracy that has not been used before.
# There are some instances where certain types of INCLUDE files must be
# created first. This type of format will allow the developer to require
# that file to be created first. In order to achieve that, all that has to
# be done is to make the DEPEND.MAK tag have your required target. Below is
# an example:
#
#    depend.mak:   { your file(s) } dephold
#
# Please DON'T remove the following line
#

!include      "$(H)\common.mak"
!include      "$(H)\version.mak"

#
# Should be the default tag for all general processing
#

all:    ALR.psd

list: $(LIST)

clean:
        if exist *.lnk	del *.lnk
        if exist *.obj	del *.obj
        if exist *.mbj	del *.mbj
        if exist *.map	del *.map
        if exist *.old	del *.old
        if exist *.lst	del *.lst
        if exist *.lsd	del *.lsd
        if exist *.sym	del *.sym
        if exist *.sys	del *.sys




#*****************************************************************************
#   Specific Description Block Information
#*****************************************************************************

# This section would only be for specific direction as to how to create
# unique elements that are necessary to the build process. This could
# be compiling or assembling, creation of DEF files and other unique
# files.
# If all compiler and assembly rules are the same, use an inference rule to
# perform the compilation.
#

alr.psd:  $(OBJS) makefile
        Rem Create DEF file <<$(DEF)
LIBRARY ALR

EXPORTS

   PSD_INSTALL          = _Install
   PSD_DEINSTALL        = _DeInstall
   PSD_INIT             = _Init
   PSD_PROC_INIT        = _ProcInit
   PSD_START_PROC       = _StartProcessor
   PSD_GET_NUM_OF_PROCS = _GetNumOfProcs
   PSD_GEN_IPI          = _GenIPI
   PSD_END_IPI          = _EndIPI
<<keep
        $(LINK) $(LFLAGS) @<<$(@B).lnk
$(OBJ1)
$*.psd
$*.map
$(LIBS)
$(DEF)
<<keep
        $(MAPSYM) $*.map



#****************************************************************************
#  Dependency generation and Checking
#****************************************************************************

depend.mak:  dephold
        touch depchk
        includes -e -sobj -llst -I. -I$(H) -I$(DISKH) -I$(INC) -P$$(H)=$(H) *.c *.asm >$@
        -del depchk

dephold:
        touch $@

!include depend.mak