Beispiel #1
0
/**
 *  프로세서를 리셋(Reset)
 */
void kReboot( void )
{
    int i;
    
    // 입력 버퍼(포트 0x60)에 데이터가 비어있으면 출력 포트에 값을 쓰는 커맨드와 출력 포트 데이터 전송
    for( i = 0 ; i < 0xFFFF ; i++ )
    {
        // 입력 버퍼(포트 0x60)가 비었으면 커맨드 전송 가능
        if( kIsInputBufferFull() == FALSE )
        {
            break;
        }
    }
    
    // 커맨드 레지스터(0x64)에 출력 포트 설정 커맨드(0xD1)을 전달
    kOutPortByte( 0x64, 0xD1 );
    
    // 입력 버퍼(0x60)에 0을 전달하여 프로세서를 리셋(Reset)함
    kOutPortByte( 0x60, 0x00 );
    
    while( 1 )
    {
        ;
    }
}
Beispiel #2
0
/**
 *  키보드를 활성화 함
 */
BOOL kActivateKeyboard( void )
{
    int i, j;
    BOOL bPreviousInterrupt;
    BOOL bResult;
    
    // 인터럽트 불가
    bPreviousInterrupt = kSetInterruptFlag( FALSE );
    
    // 컨트롤 레지스터(포트 0x64)에 키보드 활성화 커맨드(0xAE)를 전달하여 키보드 디바이스 활성화
    kOutPortByte( 0x64, 0xAE );
        
    // 입력 버퍼(포트 0x60)가 빌 때까지 기다렸다가 키보드에 활성화 커맨드를 전송
    // 0xFFFF만큼 루프를 수행할 시간이면 충분히 커맨드가 전송될 수 있음
    // 0xFFFF 루프를 수행한 이후에도 입력 버퍼(포트 0x60)가 비지 않으면 무시하고 전송
    for( i = 0 ; i < 0xFFFF ; i++ )
    {
        // 입력 버퍼(포트 0x60)가 비어있으면 키보드 커맨드 전송 가능
        if( kIsInputBufferFull() == FALSE )
        {
            break;
        }
    }
    // 입력 버퍼(포트 0x60)로 키보드 활성화(0xF4) 커맨드를 전달하여 키보드로 전송
    kOutPortByte( 0x60, 0xF4 );
    
    // ACK가 올 때까지 대기함
    bResult = kWaitForACKAndPutOtherScanCode();
    
    // 이전 인터럽트 상태 복원
    kSetInterruptFlag( bPreviousInterrupt );
    return bResult;
}
Beispiel #3
0
void kEnableA20Gate( void )
{
	BYTE bOutputPortData;
	int i;

	// 키보드 컨트롤러 정보를 읽거나 쓰려면  미리 D0, D1 커맨드 신호를 보내야 한다.

	kOutPortByte( 0x64, 0xD0 ); // 키보드 컨트롤러의 출력 포트 값을 읽는 함수

	for( i = 0 ; i < 0xFFFF ; i++ )
	{
		if( kIsOutputBufferFull()) // 출력값이 있으면
		{
			break;
		}
	}

	bOutputPortData = kInPortByte(0x60); // 출력값을 읽어냄

	bOutputPortData |= 0x01; // 1인경우 A20Gate, 0인경우 리붓

	for( i = 0 ; i < 0xFFFF ; i++ )
	{
		if ( kIsInputBufferFull() == FALSE ) // 입력 버퍼에 데이터가 비어있으면
		{
			break;
		}
	}

	kOutPortByte(0x64, 0xD1); // 키보드 컨트롤러의 출력 포트 값을 보내는 커맨드
	kOutPortByte(0x60, bOutputPortData); // A20 Gate On
}
Beispiel #4
0
/**
 *  커서의 위치를 설정
 *      문자를 출력할 위치도 같이 설정
 */
void kSetCursor( int iX, int iY ) 
{
    int iLinearValue;
    int iOldX;
    int iOldY;
    int i;
    
    // 커서의 위치를 계산
    iLinearValue = iY * CONSOLE_WIDTH + iX;

    // 텍스트 모드로 시작했으면 CRT 컨트롤러로 커서 위치를 전송
    if( kIsGraphicMode() == FALSE )
    {
        // CRTC 컨트롤 어드레스 레지스터(포트 0x3D4)에 0x0E를 전송하여
        // 상위 커서 위치 레지스터를 선택
        kOutPortByte( VGA_PORT_INDEX, VGA_INDEX_UPPERCURSOR );
        // CRTC 컨트롤 데이터 레지스터(포트 0x3D5)에 커서의 상위 바이트를 출력
        kOutPortByte( VGA_PORT_DATA, iLinearValue >> 8 );
    
        // CRTC 컨트롤 어드레스 레지스터(포트 0x3D4)에 0x0F를 전송하여
        // 하위 커서 위치 레지스터를 선택
        kOutPortByte( VGA_PORT_INDEX, VGA_INDEX_LOWERCURSOR );
        // CRTC 컨트롤 데이터 레지스터(포트 0x3D5)에 커서의 하위 바이트를 출력
        kOutPortByte( VGA_PORT_DATA, iLinearValue & 0xFF );
    }
Beispiel #5
0
BOOL kActivateKeyboard(void)
{
	int i;
	int j;
	BOOL bPreviousInterrupt;
	BOOL bResult;

	// 인터럽트 막아놓고 원래의 상태를 저장
	bPreviousInterrupt = kSetInterruptFlag( FALSE );

	kOutPortByte(0x64, 0xAE); // 0x64(컨트롤(쓰기)레지스터에 0xAE 신호 발송 (키보드 디바이스 활성화) )

	for( i = 0 ; i < 0xFFFF ; i++ )
	{
		if (!kIsInputBufferFull()) // inputbuffer가 비었으면 키보드 활성화(디바이스X) 신호 보낼것
		{
			break;
		}
	}

	kOutPortByte(0x60, 0xF4); // 0x60에 0xF4 전송 (입력버퍼로 키보드 활성화 키 전송)

	// ACK가 올때까지 기다림
	bResult = kWaitForACKAndPutOtherScanCode();

	// 이전 인터럽트 상태 복원
	kSetInterruptFlag(bPreviousInterrupt);

	return bResult;

}
Beispiel #6
0
/**
 *  키보드 LED의 ON/OFF를 변경
 */
BOOL kChangeKeyboardLED( BOOL bCapsLockOn, BOOL bNumLockOn, BOOL bScrollLockOn )
{
    int i, j;
    BOOL bPreviousInterrupt;
    BOOL bResult;
    BYTE bData;
    
    // 인터럽트 불가
    bPreviousInterrupt = kSetInterruptFlag( FALSE );    
        
    // 키보드에 LED 변경 커맨드 전송하고 커맨드가 처리될 때까지 대기
    for( i = 0 ; i < 0xFFFF ; i++ )
    {
        // 출력 버퍼(포트 0x60)가 비었으면 커맨드 전송 가능
        if( kIsInputBufferFull() == FALSE )
        {
            break;
        }
    }
    
    // 출력 버퍼(포트 0x60)로 LED 상태 변경 커맨드(0xED) 전송
    kOutPortByte( 0x60, 0xED );
    for( i = 0 ; i < 0xFFFF ; i++ )
    {
        // 입력 버퍼(포트 0x60)가 비어있으면 키보드가 커맨드를 가져간 것임
        if( kIsInputBufferFull() == FALSE )
        {
            break;
        }
    }
    
    // ACK가 올때까지 대기함
    bResult = kWaitForACKAndPutOtherScanCode();

    if( bResult == FALSE )
    {
        // 이전 인터럽트 상태 복원
        kSetInterruptFlag( bPreviousInterrupt );
        return FALSE;
    }
    
    // LED 변경 값을 키보드로 전송하고 데이터가 처리가 완료될 때까지 대기
    kOutPortByte( 0x60, ( bCapsLockOn << 2 ) | ( bNumLockOn << 1 ) | bScrollLockOn );
    for( i = 0 ; i < 0xFFFF ; i++ )
    {
        // 입력 버퍼(포트 0x60)가 비어있으면 키보드가 LED 데이터를 가져간 것임
        if( kIsInputBufferFull() == FALSE )
        {
            break;
        }
    }
    
    // ACK가 올 때까지 대기함
    bResult = kWaitForACKAndPutOtherScanCode();

    // 이전 인터럽트 상태 복원
    kSetInterruptFlag( bPreviousInterrupt );
    return bResult;
}
Beispiel #7
0
BOOL kChangeKeyboardLED( BOOL bCapsLockOn, BOOL bNumLockOn, BOOL bScrollLockOn )
{
	int i, j;
	BOOL bPreviousInterrupt;
	BOOL bResult;
	BYTE bData;

	// 인터럽트 불가
	bPreviousInterrupt = kSetInterruptFlag( FALSE );

	for( i = 0 ; i < 0xFFFF ; i++ )
	{
		if( kIsInputBufferFull() == FALSE ) // 입력버퍼가 빌때까지 기다림
		{
			break;
		}
	}

	// 출력 버퍼에 LED 상태 변경 한다는 커맨드 전송(0xED)
	kOutPortByte(0x60, 0xED);
	for( i = 0 ; i < 0xFFFF ; i++ )
	{
		if(kIsInputBufferFull() == FALSE) // 입력 버퍼가 빌때까지 기다림
			break;
	}

	// ACK를 기다림
	bResult = kWaitForACKAndPutOtherScanCode();

	if( bResult == FALSE )
	{
		kSetInterruptFlag( bPreviousInterrupt );
		return FALSE;
	}
	if ( j>= 100 ) // 일정 시간 이상 ACK가 안옴
		return FALSE;


	// 2비트 , 1비트, 0비트에 따라 온을 시켜줌
	kOutPortByte( 0x60, (bCapsLockOn << 2) | (bNumLockOn << 1) | bScrollLockOn );

	for( i = 0 ; i < 0xFFFF ; i++ )
	{
		if(kIsInputBufferFull() == FALSE)
		{
			break;
		}
	}

	bResult = kWaitForACKAndPutOtherScanCode();
	kSetInterruptFlag(bPreviousInterrupt);

	return bResult;
}
Beispiel #8
0
void kReboot( void )
{
	int i;

	for(i = 0 ; i < 0xFFFF ; i++ )
	{
		if( kIsInputBufferFull() == FALSE)
			break;
	}
	kOutPortByte(0x64, 0xD1); // 키보드 버퍼에 컨트롤 입력값을 입력할것이다.

	kOutPortByte(0x60, 0x00);
	while(1)
	{
		; // 재부팅
	}
}
Beispiel #9
0
// Initialize PIT
void kInitializePIT( WORD wCount, BOOL bPeriodic )
{
	// Initiate PIT controller register(port 0x43) 
	// and stop it, then set binary counter as mode 0
	kOutPortByte( PIT_PORT_CONTROL, PIT_COUNTER0_ONCE );
	
	// If it is periodic, set mode 2
	if ( bPeriodic == TRUE )
	{
		// Set binary counter as mode 2 in PIT controller register(port 0x43)
		kOutPortByte( PIT_PORT_CONTROL, PIT_COUNTER0_PERIODIC );
	}
	
	// Set initial value from LSB to MSB in counter0(port 0x40)
	kOutPortByte( PIT_PORT_COUNTER0, wCount );
	kOutPortByte( PIT_PORT_COUNTER0, wCount >> 8 );
}
Beispiel #10
0
void kReadRTCTime( BYTE* pbHour, BYTE* pbMinute, BYTE* pbSecond )
{
	BYTE bData;
	// CMOS 메모리 어드레스 레지스터(포트 0x70)에 시간을 저장하는 레지스터 지정
	kOutPortByte( RTC_CMOSADDRESS, RTC_ADDRESS_HOUR );
	// 데이터 레지스터에서 시간 얻어옴
	bData = kInPortByte( RTC_CMOSDATA );
	*pbHour = RTC_BCDTOBINARY( bData );

	kOutPortByte( RTC_CMOSADDRESS, RTC_ADDRESS_MINUTE );
	bData = kInPortByte( RTC_CMOSDATA );
	*pbMinute = RTC_BCDTOBINARY( bData );

	kOutPortByte( RTC_CMOSADDRESS, RTC_ADDRESS_SECOND );
	bData = kInPortByte( RTC_CMOSDATA );
	*pbSecond = RTC_BCDTOBINARY( bData );

}
Beispiel #11
0
/**
 *  A20 게이트를 활성화
 */
void kEnableA20Gate( void )
{
    BYTE bOutputPortData;
    int i;
    
    // 컨트롤 레지스터(포트 0x64)에 키보드 컨트롤러의 출력 포트 값을 읽는 커맨드(0xD0) 전송
    kOutPortByte( 0x64, 0xD0 );
    
    // 출력 포트의 데이터를 기다렸다가 읽음
    for( i = 0 ; i < 0xFFFF ; i++ )
    {
        // 출력 버퍼(포트 0x60)가 차있으면 데이터를 읽을 수 있음 
        if( kIsOutputBufferFull() == TRUE )
        {
            break;
        }
    }
    // 출력 포트(포트 0x60)에 수신된 키보드 컨트롤러의 출력 포트 값을 읽음
    bOutputPortData = kInPortByte( 0x60 );
    
    // A20 게이트 비트 설정
    bOutputPortData |= 0x01;
    
    // 입력 버퍼(포트 0x60)에 데이터가 비어있으면 출력 포트에 값을 쓰는 커맨드와 출력 포트 데이터 전송
    for( i = 0 ; i < 0xFFFF ; i++ )
    {
        // 입력 버퍼(포트 0x60)가 비었으면 커맨드 전송 가능
        if( kIsInputBufferFull() == FALSE )
        {
            break;
        }
    }
    
    // 커맨드 레지스터(0x64)에 출력 포트 설정 커맨드(0xD1)을 전달
    kOutPortByte( 0x64, 0xD1 );
    
    // 입력 버퍼(0x60)에 A20 게이트 비트가 1로 설정된 값을 전달
    kOutPortByte( 0x60, bOutputPortData );
}
Beispiel #12
0
/**
 *  커서의 위치를 설정
 *      문자를 출력할 위치도 같이 설정
 */
void kSetCursor( int iX, int iY ) 
{
    int iLinearValue;

    // 커서의 위치를 계산
    iLinearValue = iY * CONSOLE_WIDTH + iX;

    // CRTC 컨트롤 어드레스 레지스터(포트 0x3D4)에 0x0E를 전송하여
    // 상위 커서 위치 레지스터를 선택
    kOutPortByte( VGA_PORT_INDEX, VGA_INDEX_UPPERCURSOR );
    // CRTC 컨트롤 데이터 레지스터(포트 0x3D5)에 커서의 상위 바이트를 출력
    kOutPortByte( VGA_PORT_DATA, iLinearValue >> 8 );

    // CRTC 컨트롤 어드레스 레지스터(포트 0x3D4)에 0x0F를 전송하여
    // 하위 커서 위치 레지스터를 선택
    kOutPortByte( VGA_PORT_INDEX, VGA_INDEX_LOWERCURSOR );
    // CRTC 컨트롤 데이터 레지스터(포트 0x3D5)에 커서의 하위 바이트를 출력
    kOutPortByte( VGA_PORT_DATA, iLinearValue & 0xFF );

    // 문자를 출력할 위치 업데이트
    gs_stConsoleManager.iCurrentPrintOffset = iLinearValue;
}
Beispiel #13
0
void kReadRTCDate( WORD* pwYear, BYTE* pbMonth, BYTE* pbDayOfMonth, BYTE* pbDayOfWeek )
{
	BYTE bData;

	kOutPortByte( RTC_CMOSADDRESS, RTC_ADDRESS_YEAR );
	bData = kInPortByte( RTC_CMOSDATA );
	*pwYear = RTC_BCDTOBINARY( bData ) + 2000;



	kOutPortByte( RTC_CMOSADDRESS, RTC_ADDRESS_MONTH );
	bData = kInPortByte( RTC_CMOSDATA );
	*pbMonth = RTC_BCDTOBINARY( bData );

	kOutPortByte( RTC_CMOSADDRESS, RTC_ADDRESS_DAYOFMONTH );
	bData = kInPortByte( RTC_CMOSDATA );
	*pbDayOfMonth = RTC_BCDTOBINARY( bData );

	kOutPortByte( RTC_CMOSADDRESS, RTC_ADDRESS_DAYOFWEEK );
	bData = kInPortByte( RTC_CMOSDATA );
	*pbDayOfWeek = RTC_BCDTOBINARY( bData );

}
Beispiel #14
0
// Return value of counter0
WORD kReadCounter0( void )
{
	BYTE bHighByte, bLowByte;
	WORD wTemp = 0;
	
	// Send latch command to PIT control register(port 0x43) to read value of counter0
	kOutPortByte( PIT_PORT_CONTROL, PIT_COUNTER0_LATCH);
	
	// Read from LSB to MSB in counter0
	bLowByte = kInPortByte( PIT_PORT_COUNTER0);
	bHighByte = kInPortByte( PIT_PORT_COUNTER0 );
	
	// Return 16 bit
	wTemp = bHighByte;
	wTemp = ( wTemp << 8 ) | bLowByte;
	return wTemp;
}
Beispiel #15
0
/**
 *  멀티코어 프로세서 또는 멀티 프로세서 모드로 전환하는 함수
 */
BOOL kChangeToMultiCoreMode( void )
{
    MPCONFIGRUATIONMANAGER* pstMPManager;
    BOOL bInterruptFlag;
    int i;

    // Application Processor 활성화
    if( kStartUpApplicationProcessor() == FALSE )
    {
        return FALSE;
    }

    //--------------------------------------------------------------------------
    // 대칭 I/O 모드로 전환
    //--------------------------------------------------------------------------
    // MP 설정 매니저를 찾아서 PIC 모드인가 확인
    pstMPManager = kGetMPConfigurationManager();
    if( pstMPManager->bUsePICMode == TRUE )
    {
        // PIC 모드이면 I/O 포트 어드레스 0x22에 0x70을 먼저 전송하고 
        // I/O 포트 어드레스 0x23에 0x01을 전송하는 방법으로 IMCR 레지스터에 접근하여
        // PIC 모드 비활성화
        kOutPortByte( 0x22, 0x70 );
        kOutPortByte( 0x23, 0x01 );
    }

    // PIC 컨트롤러의 인터럽트를 모두 마스크하여 인터럽트가 발생할 수 없도록 함
    kMaskPICInterrupt( 0xFFFF );

    // 프로세서 전체의 로컬 APIC를 활성화
    kEnableGlobalLocalAPIC();
    
    // 현재 코어의 로컬 APIC를 활성화
    kEnableSoftwareLocalAPIC();

    // 인터럽트를 불가로 설정
    bInterruptFlag = kSetInterruptFlag( FALSE );
    
    // 모든 인터럽트를 수신할 수 있도록 태스크 우선 순위 레지스터를 0으로 설정
    kSetTaskPriority( 0 );

    // 로컬 APIC의 로컬 벡터 테이블을 초기화
    kInitializeLocalVectorTable();

    // 대칭 I/O 모드로 변경되었음을 설정
    kSetSymmetricIOMode( TRUE );
    
    // I/O APIC 초기화
    kInitializeIORedirectionTable();
        
    // 이전 인터럽트 플래그를 복원
    kSetInterruptFlag( bInterruptFlag );

    // 인터럽트 부하 분산 기능 활성화
    kSetInterruptLoadBalancing( TRUE );

    // 태스크 부하 분산 기능 활성화
    for( i = 0 ; i < MAXPROCESSORCOUNT ; i++ )
    {
        kSetTaskLoadBalancing( i, TRUE );
    }
    
    return TRUE;
}