Additions:
@@ Return to [[SMPProgrammingAddendum SMP Programming Addendum]] Page.@@
@@ Return to [[SMPProgrammingAddendum SMP Programming Addendum]] Page.@@
Additions:
====main.c====
Deletions:
main.c
Additions:
main.c
Additions:
#include // needed for NO_ERROR
mov edx, port
in al, dx
movzx eax, al
mov data, eax
mov edx,port
return(NO_ERROR);
char *ALR_String = "PROVEISA";
/* 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;
}
return ( NO_ERROR ) ;
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 );
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) ;
if (procnum == 0 )
return (NO_ERROR) ;
if ( procnum == 0 ) port = P1_PROCESSOR_CONTROL_PORT;
if (procnum == 0) SendEOI(IPI_IRQ);
return(NO_ERROR);
Deletions:
#include
mov dx,port
in al,dx
movzx eax,al
mov data,eax
mov dx,port
char ALR_String = "PROVEISA";
/* 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;
}
}
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 ) ;
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;
}
if (procnum = 0 )
}
if ( procnum = 0 ) port = P1_PROCESSOR_CONTROL_PORT;
if (procnum = 0) SendEOI(IPI_IRQ);
}
Additions:
pushfd
pop eax
mov eflags,eax
cli
push eflags
popfd
ulong_t data;
_asm {
mov dx,port
in al,dx
movzx eax,al
mov data,eax
};
return (data);
mov dx,port
mov al,byte ptr data
out dx,al
OutByte(PIC1_PORT0, OCW2_NON_SPECIFIC_EOI);
OutByte(PIC2_PORT0, OCW2_NON_SPECIFIC_EOI);
IODelay;
OutByte(PIC1_PORT0, OCW2_NON_SPECIFIC_EOI);
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;
/* 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);
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 ;
}
/*** ProcInit - Processor initialization
* This function initializes per processor items.
* NOTE : This function is called once on each processor
* in the system .
* 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;
}
}
/*** 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);
}
/*** 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);
}
Deletions:
pushfd
pop eax
mov eflags,eax
cli
push eflags
popfd
ulong_t data;
_asm {
mov dx,port
in al,dx
movzx eax,al
mov data,eax
};
return (data);
mov dx,port
mov al,byte ptr data
out dx,al
OutByte(PIC1_PORT0, OCW2_NON_SPECIFIC_EOI);
OutByte(PIC2_PORT0, OCW2_NON_SPECIFIC_EOI);
IODelay;
OutByte(PIC1_PORT0, OCW2_NON_SPECIFIC_EOI);
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;
/* 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);
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 ) ;
}
Additions:
if ( procnum = = 0 ) port = P1 _ PROCESSOR _ CONTROL _ PORT ;
else port = P2 _ PROCESSOR _ CONTROL _ PORT ;
if ( procnum = = 0 ) SendEOI ( IPI _ IRQ ) ;
return ( NO _ ERROR ) ;
}
Deletions:
SendEOI ( IPI _ IRQ ) ;