Example #1
0
void HalStartSerial()
{
        int oflags;

        // Open the term for reading and writing.
        if( (serialInFd = open(SERIAL_INPUT_DEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0 ) {
                HalPanic("failed to open input fd", errno);
        }
        if( (serialOutFd = open(SERIAL_OUTPUT_DEVICE, O_WRONLY | O_NOCTTY | O_NONBLOCK) ) < 0 ) {
                HalPanic("failed to open output fd", errno);
        }

        //Get the term settings
        tcgetattr(serialInFd, &serialSettingsOld);

        // For now, lets reuse whatever terminal settings we were started with.
        serialSettings.c_cflag = serialSettingsOld.c_cflag;
        serialSettings.c_iflag = serialSettingsOld.c_iflag;
        serialSettings.c_oflag = serialSettingsOld.c_oflag;
        serialSettings.c_lflag = serialSettingsOld.c_lflag;

        serialSettings.c_cc[VEOF] = serialSettingsOld.c_cc[VEOF];
        serialSettings.c_cc[VEOL] = serialSettingsOld.c_cc[VEOL];
        serialSettings.c_cc[VEOL2] = serialSettingsOld.c_cc[VEOL2];
        serialSettings.c_cc[VERASE] = serialSettingsOld.c_cc[VERASE];
        serialSettings.c_cc[VWERASE] = serialSettingsOld.c_cc[VWERASE];
        serialSettings.c_cc[VKILL] = serialSettingsOld.c_cc[VKILL];
        serialSettings.c_cc[VREPRINT] = serialSettingsOld.c_cc[VREPRINT];
        serialSettings.c_cc[VINTR] = serialSettingsOld.c_cc[VINTR];
        serialSettings.c_cc[VQUIT] = serialSettingsOld.c_cc[VQUIT];
        serialSettings.c_cc[VSUSP] = serialSettingsOld.c_cc[VSUSP];
        serialSettings.c_cc[VDSUSP] = serialSettingsOld.c_cc[VDSUSP];
        serialSettings.c_cc[VSTART] = serialSettingsOld.c_cc[VSTART];
        serialSettings.c_cc[VSTOP] = serialSettingsOld.c_cc[VSTOP];
        serialSettings.c_cc[VLNEXT] = serialSettingsOld.c_cc[VLNEXT];
        serialSettings.c_cc[VDISCARD] = serialSettingsOld.c_cc[VDISCARD];
        serialSettings.c_cc[VMIN] = serialSettingsOld.c_cc[VMIN];
        serialSettings.c_cc[VTIME] = serialSettingsOld.c_cc[VTIME];
        serialSettings.c_cc[VSTATUS] = serialSettingsOld.c_cc[VSTATUS];

        serialSettings.c_ispeed = serialSettingsOld.c_ispeed;
        serialSettings.c_ospeed = serialSettingsOld.c_ospeed;

        tcflush(serialInFd, TCIFLUSH);
        tcsetattr(serialInFd,TCSANOW,&serialSettings);

        fcntl(serialInFd, F_SETOWN, getpid(  ));
        oflags = fcntl(serialInFd, F_GETFL);
        fcntl(serialInFd, F_SETFL, oflags | FASYNC);

        fcntl(serialOutFd, F_SETOWN, getpid(  ));
        oflags = fcntl(serialOutFd, F_GETFL);
        fcntl(serialOutFd, F_SETFL, oflags | FASYNC);
}
Example #2
0
void HalSerialWriteChar(char data)
{
        int writelen = write(serialOutFd, &data, sizeof(char));

        if( writelen > 0 ) {

        } else if(writelen == 0) {
                HalPanic("Wrote 0 to STDOUT\n", 0);
        } else {
                HalPanic("Failed to write to STDOUT", errno);
        }
}
Example #3
0
/*
 * sigaltstack will cause this function to be called on an alternate stack.
 * This allows us to bootstrap new threads.
 */
void HalStackTrampoline( int SignalNumber )
{
        int status;
        //Save stack startup state before releaseing the tempContext.
        STACK_INIT_ROUTINE * foo = halTempContext->Foo;
        void * arg = halTempContext->Arg;

        status = _setjmp( halTempContext->Registers );

        if( status == 0 ) {
                //Because status was 0 we know that this is the creation of
                //the stack frame. We can use the locals to construct the frame.

                halTempContextProcessed = TRUE;
                halTempContext = NULL;
                return;
        } else {
                //If we get here, then someone has jumped into a newly created thread.
                //Test to make sure we are atomic
                ASSERT( HalIsIrqAtomic(IRQ_LEVEL_MAX) );

                foo(arg);

                //Returning from a function which was invoked by siglongjmp is not
                //supported. Foo should never retrun.
                HalPanic("Tried to return from trampoline!");
                return;
        }
}
Example #4
0
/*
 * All signals call this routine.
 * This routine then calls the appropriate ISR Handler.
 */
void HalIsrHandler( int SignalNumber )
{
        INDEX index;
        enum IRQ_LEVEL irq;

#ifdef DEBUG
        HalUpdateIsrDebugInfo();
#endif

        //We dont know which irq is associated with SignalNumber, so lets find it.
        for(index = 0; index < IRQ_LEVEL_COUNT; index++) {
                if( HalIrqToSignal[index] == SignalNumber ) {
                        //We found it, call the appropriate ISR.
                        irq = index;
                        HalIsrJumpTable[irq]();
#ifdef DEBUG
                        //We are about to return into an unknown frame.
                        //I can't predict what the irq will be there.
                        HalInvalidateIsrDebugInfo();
#endif
                        return;
                }
        }

        HalPanic("Signal delivered for which no Irq was registered", SignalNumber);
}
Example #5
0
/*
 * sigaltstack will cause this fuction to be called on an alternate stack.
 * This allows us to bootstrap new threads.
 */
void HalStackTrampoline( int SignalNumber )
{
        int status;
        status = _setjmp( halTempContext->Registers );

        if( status == 0 ) {
                //Because status was 0 we know that this is the creation of
                //the stack frame. We can use the locals to construct the frame.

                halTempContextProcessed = TRUE;
                halTempContext = NULL;
                return;
        } else {
                //If we get here, then someone has jumped into a newly created thread.
                //Test to make sure we are atomic
                ASSERT( HalIsIrqAtomic(IRQ_LEVEL_TIMER) );

                StackInitRoutine();

                //Returning from a function which was invoked by siglongjmp is not
                //supported. Foo should never retrun.
                HalPanic("Tried to return from StackInitRoutine!\n", 0 );
                return;
        }
}
Example #6
0
/*
 * All signals call this routine.
 * This routine then calls the appropriate ISR Handler.
 */
void HalIsrHandler( int SignalNumber )
{
        enum IRQ_LEVEL irq = HalSignalToIrq[SignalNumber];
        HAL_ISR_HANDLER * handler = HalSignalToHandler[SignalNumber];

        ASSERT (SignalNumber >= 0 && SignalNumber < NSIG);
        if (handler == NULL) {
                HalPanic("Signal delivered for which no Irq was registered");
        }
        ASSERT (handler != NULL);
        ASSERT (irq != IRQ_LEVEL_NONE);
#ifdef DEBUG
        HalUpdateIsrDebugInfo();
#endif
        handler(irq);
#ifdef DEBUG
        //We are about to return into an unknown frame.
        //I can't predict what the irq will be there.
        HalInvalidateIsrDebugInfo();
#endif
}
Example #7
0
BOOL HalSerialGetChar(char * out)
{
        int readlen = read(serialInFd, out, sizeof(char));

        if(readlen > 0) {
                return TRUE;
        } else if(readlen == 0) {
                //We are allowed to recieve zero bytes from the serial.
                return FALSE;
        } else {
                if(errno == EINTR) {
                        return FALSE; //We are allowed to be interrupted by another signal.
                } else if(errno == EAGAIN) {
                        return FALSE;
                } else if(errno == EWOULDBLOCK) {
                        return FALSE;
                } else {
                        HalPanic("Recieved error from STDIN!\n", errno );
                        return FALSE;
                }
        }
}
Example #8
0
void HalCreateStackFrame(
                struct MACHINE_CONTEXT * Context,
                void * stack,
                COUNT stackSize,
                STACK_INIT_ROUTINE foo,
                void * arg)
{
        int status;
        char * cstack = stack;
        stack_t newStack;
        sigset_t oldSet;
        sigset_t trampolineMask;
        struct sigaction switchStackAction;

        ASSUME(sigemptyset( &oldSet ), 0);
        ASSUME(sigemptyset( &trampolineMask ), 0);
        ASSUME(sigaddset( &trampolineMask, HAL_ISR_TRAMPOLINE ), 0);

        Context->Foo = foo;
        Context->Arg = arg;

        //We are about to bootstrap the new thread. Because we have to modify global
        //state here, we must make sure no interrupts occur until after we are bootstrapped.
        //We do all of this under the nose of the Isr unit.
        sigprocmask(SIG_BLOCK, &HalIrqToSigaction[IRQ_LEVEL_MAX].sa_mask, &oldSet);

        //NOTE: We use the interrupt mask here, because we want to block all operations.
        switchStackAction.sa_handler = HalStackTrampoline;
        switchStackAction.sa_mask = HalIrqToSigaction[IRQ_LEVEL_MAX].sa_mask;
        switchStackAction.sa_flags = SA_ONSTACK;
        sigaction(HAL_ISR_TRAMPOLINE, &switchStackAction, NULL );

        halTempContext = Context;
        halTempContextProcessed = FALSE;

        newStack.ss_sp = cstack;
        newStack.ss_size = stackSize;
        newStack.ss_flags = 0;
        status = sigaltstack( &newStack, NULL );
	if (status != 0) {
		HalPanicErrno("Failed to turn on sigaltstack.");
	}


        status = raise( HAL_ISR_TRAMPOLINE );
        if (status != 0) {
                HalPanicErrno("Failed raise stack bootstrap signal");
        }

        //At this point we know that we can't be interrupted.
        //The trampoline signal has been triggered.
        //All signals are blocked.
        //We will unblock the Trampoine signal so it gets delivered.
        ASSUME(sigprocmask( SIG_UNBLOCK, &trampolineMask, NULL ), 0);

        //Make sure that the signal was delivered.
        if (!halTempContextProcessed) {
                HalPanic("Failed to bootstrap new stack via signal");
        }

	//Now that trampoline has fired, we can get back to the thread with longjump.
	//Lets turn off sigaltstack.
        newStack.ss_flags = SS_DISABLE;
        status = sigaltstack( &newStack, NULL );
	if (status != 0) {
		HalPanicErrno("Failed to turn off sigaltstack.");
	}

        //Now that we have bootstrapped the new thread, lets restore the old mask.
        ASSUME(sigprocmask(SIG_SETMASK, &oldSet, NULL), 0);
}