SMPV211 - Appendix A
Appearance
Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation
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