📄 portkern.c
字号:
//
// Module description:
// This file contains subroutines that are kernel specific.
// See also portkern.h
//
#include <pcdisk.h>
// ********************************************************************
// ENABLE/DISABLE INTERRUPTS
// ********************************************************************
/* enable interrupts inside an interrupt service routine */
void ks_enable(void) /*__fn__*/
{
}
void ks_disable(void)
{
}
/* Declare semaphores */
#if (defined(PLUS))
NU_SEMAPHORE fs_drivesem[NDRIVES];
NU_SEMAPHORE fs_iosem[NDRIVES];
NU_SEMAPHORE fs_critsem;
#elif (defined(UCOS))
OS_EVENT *fs_drivesem[NDRIVES];
OS_EVENT *fs_iosem[NDRIVES];
OS_EVENT *fs_critsem;
#elif (defined(POLLOS))
/* POLLOS DOESN'T NEED SEMAPHORES */
#endif
/* Declare signals */
#if (defined(PLUS))
NU_SEMAPHORE ide_signal[N_ATA_CONTROLLERS];
#elif (defined(UCOS))
OS_EVENT *ide_signal[N_ATA_CONTROLLERS];
#elif (defined(POLLOS))
/* POLLOS USES Simple counters for signals */
int ide_signal[N_ATA_CONTROLLERS];
#endif
/* Resource initialization routine. This is a non-reentrant routine that is
called by _pc_memory_init() which is in turn called by the check mem
macros at the entry to the API calls.
This routine creates the signals and semaphores required by the
file system and starts a timer task running to control the floppy
motor
*/
void init_user_table(void);
BOOLEAN ks_resource_init(void) /*__fn__*/
{
#if (!defined(POLLOS))
int i;
#endif
// Build RTFS Semaphores if the file system is included;
// one per drive for accessing the fat and finodes
// one per drive to keep IO single threaded.
// NOTE: Since two logical drives can share the same
// interface at run time we calculate which semaphore to
// wait on when before we access the controller.
#if (defined(PLUS))
for (i = 0; i < NDRIVES; i++)
{
if (NU_Create_Semaphore(&fs_drivesem[i], "DRVSEM", 1, NU_FIFO) != NU_SUCCESS)
return(FALSE);
if (NU_Create_Semaphore(&fs_iosem[i], "IOSEM", 1, NU_FIFO) != NU_SUCCESS)
return(FALSE);
}
// Semaphores for exclusive access to the buffer pool and other
// critical regions..
if (NU_Create_Semaphore(&fs_critsem, "CRTSEM", 1, NU_FIFO) != NU_SUCCESS)
return(FALSE);
#elif (defined(UCOS))
for (i = 0; i < NDRIVES; i++)
{
fs_drivesem[i]=OSSemCreate(1);
if (!fs_drivesem[i])
return(FALSE);
fs_iosem[i]=OSSemCreate(1);
if (!fs_iosem[i])
return(FALSE);
}
// Semaphores for exclusive access to the buffer pool and other
// critical regions..
fs_critsem=OSSemCreate(1);
if (!fs_critsem)
return(FALSE);
#elif (defined(POLLOS))
/* POLLOS DOESN'T NEED SEMAPHORES */
#else
#error Please initialize semaphores for your kernel
#endif
// Build RTFS Interrupt signals if the file system is included
#if (USE_ATA)
#if (defined(PLUS))
if (NU_Create_Semaphore(&ide_signal[0], "IDESIG", 0, NU_FIFO) != NU_SUCCESS)
return(FALSE);
if (NU_Create_Semaphore(&ide_signal[1], "IDESIG", 0, NU_FIFO) != NU_SUCCESS)
return(FALSE);
#elif (defined(UCOS))
ide_signal[0] = OSSemCreate(0);
if (!ide_signal[0])
return(FALSE);
ide_signal[1] = OSSemCreate(0);
if (!ide_signal[1])
return(FALSE);
#elif (defined(POLLOS))
/* POLLOS USES Simple counters for signals */
ide_signal[0] = 0;
ide_signal[1] = 0;
#else
#error Please initialize ide counting semaphores for your kernel
#endif
#endif
/* Initialize a user table */
init_user_table();
return(TRUE);
}
/* Claim and release semaphores. These are called by macros defied in
portkern.h
*/
void ks_claim_logdrive(int driveno)
{
#if (defined(PLUS))
NU_Obtain_Semaphore(&fs_drivesem[driveno],NU_SUSPEND);
#elif (defined(UCOS))
byte err;
OSSemPend(fs_drivesem[driveno], 0, &err);
#elif (defined(POLLOS))
/* POLLOS does not need semaphores */
#else
#error Implement semaphore claim and release for your kernel
#endif
}
void ks_release_logdrive(int driveno)
{
#if (defined(PLUS))
NU_Release_Semaphore(&fs_drivesem[driveno]);
#elif (defined(UCOS))
OSSemPost(fs_drivesem[driveno]);
#elif (defined(POLLOS))
/* POLLOS does not need semaphores */
#else
#error Implement semaphore claim and release for your kernel
#endif
}
void ks_claim_fscritical(void)
{
#if (defined(PLUS))
NU_Obtain_Semaphore(&fs_critsem,NU_SUSPEND);
#elif (defined(UCOS))
byte err;
OSSemPend(fs_critsem, 0, &err);
#elif (defined(POLLOS))
/* POLLOS does not need semaphores */
#else
#error Implement semaphore claim and release for your kernel
#endif
}
void ks_release_fscritical(void)
{
#if (defined(PLUS))
NU_Release_Semaphore(&fs_critsem);
#elif (defined(UCOS))
OSSemPost(fs_critsem);
#elif (defined(POLLOS))
/* POLLOS does not need semaphores */
#else
#error Implement semaphore claim and release for your kernel
#endif
}
void ks_claim_drive_io(int driveno)
{
#if (defined(PLUS))
NU_Obtain_Semaphore(&fs_iosem[driveno],NU_SUSPEND);
#elif (defined(UCOS))
byte err;
OSSemPend(fs_iosem[driveno], 0, &err);
#elif (defined(POLLOS))
/* POLLOS does not need semaphores */
#else
#error Implement semaphore claim and release for your kernel
#endif
}
void ks_release_drive_io(int driveno)
{
#if (defined(PLUS))
NU_Release_Semaphore(&fs_iosem[driveno]);
#elif (defined(UCOS))
OSSemPost(fs_iosem[driveno]);
#elif (defined(POLLOS))
/* POLLOS does not need semaphores */
#else
#error Implement semaphore claim and release for your kernel
#endif
}
#if (defined(POLLOS))
// Poolos signal test
// ********************************************************************
// Test for a signal
BOOLEAN pollos_test(int *psig, word timeout) /* __fn__*/
{
dword last_time, end_time, curr_time;
if (timeout)
{
last_time = end_time = 0; // keep compiler happy
curr_time = ks_get_ticks();
end_time = curr_time + (dword) timeout;
// Check for a wrap
if (end_time < curr_time)
end_time = (dword) 0xffffffffL;
last_time = curr_time;
do
{
// See if we timed out
curr_time = ks_get_ticks();
if (curr_time > end_time)
break;
// if wrap or clearing of clock then start count over
if (curr_time < last_time)
end_time = curr_time + (dword) timeout;
last_time = curr_time;
} while (*psig == 0);
}
if (*psig)
{
*psig -= 1;
return(TRUE);
}
else
{
return(FALSE);
}
}
#endif
#if (USE_ATA)
/* clear set and test routines for the ide signal */
void ks_clear_ide_signal(int controller)
{
#if (defined(PLUS))
while(NU_Obtain_Semaphore(&ide_signal[controller], 0) == NU_SUCCESS)
;
#elif (defined(UCOS))
while(ks_test_ide_signal(controller, 0))
;
#elif (defined(POLLOS))
ide_signal[controller] = 0;
#else
#error Implement counting semaphore clear for your kernel
#endif
}
void ks_set_ide_signal(int controller)
{
#if (defined(PLUS))
NU_Release_Semaphore(&ide_signal[controller]);
#elif (defined(UCOS))
OSSemPost(ide_signal[controller]);
#elif (defined(POLLOS))
ide_signal[controller] += 1;
#else
#error Implement counting semaphore increment for your kernel
#endif
}
BOOLEAN ks_test_ide_signal(int controller, word timeout)
{
#if (defined(PLUS))
return(NU_Obtain_Semaphore(&ide_signal[controller], timeout) == NU_SUCCESS);
#elif (defined(UCOS))
{
byte err;
if (timeout == 0)
{
/* For zero timeout - first check the internal counter
and fall through into the blocking routine if we know
that it won't block */
if (!ide_signal[controller]->OSEventCnt)
return(FALSE);
}
OSSemPend(ide_signal[controller], timeout, &err);
return(err == OS_NO_ERR);
}
#elif (defined(POLLOS))
return(pollos_test(&ide_signal[controller], timeout));
#else
#error Implement counting semaphore test for your kernel
#endif
}
#endif
/* Timer management functions */
// ********************************************************************
// ks_get_ticks() - get period since system startup
//
// Returns number of ticks since system startup
//
dword ks_get_ticks(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -