Esempio n. 1
0
Stack *_get_stack( void ) {
    Stack *stack;

    if( _deque(&g_free_stacks,(void **)&stack) != ERR_NONE ) {
        return( 0 );
    }

    _memclr( (void *) stack, sizeof(Stack) );

    return( stack );

}
Esempio n. 2
0
void _init_stacks( void ) {
    int i;

    // first, put all stacks into the free pool
    //
    // NOTE:  queues must have been initialized first!

    for( i = 0; i < N_PROCESSES; ++i ) {
        if( _free_stack(&g_stacks[i]) != ERR_NONE ) {
            _kpanic( "init stacks:  enqueue failed" );
        }
    }

    // set up the system stack

    _memclr( (void *)&g_system_stack, sizeof(Stack) );

    g_system_esp = ((unsigned int *)(&g_system_stack + 1)) - 2;

    // announce that we have initialized the stack module

    c_puts( " stacks" );

}
Esempio n. 3
0
context_t *_setup_stack( stack_t *stack, uint32_t entry ) {
	uint32_t *tmp;
	context_t *context;

	/*
	** Set up the initial stack contents for a (new) user process.
	**
	** We reserve two longwords at the bottom of the stack as
	** scratch space.  Above that, we simulate a call to exit() by
	** inserting an exit status value and a dummy return address; we
	** then simulate a call from exit() to the user main routine by
	** pushing the address of exit() as a "return address".  Finally,
	** above that we place an context_t area that is initialized with
	** the standard initial register contents.
	**
	** The low end of the stack will contain these values:
	**
	**	esp ->	?	<- context save area
	**		...	<- context save area
	**		?	<- context save area
	**		exit	<- return address for main()
	**		0	<- dummy return address
	**		status	<- code for exit() call
	**		filler
	**		filler  <- last word in stack
	**
	** When this process is dispatched, the context restore
	** code will pop all the saved context information off
	** the stack, leaving the 
	*/

	/*
	** First, compute a pointer to the 3rd-to-last longword
	** (where the exit code will go).
	*/

	tmp = (uint32_t *)(stack + 1) - 3;

	// Next, fill in the dummy return information

	*tmp-- = X_SUCCESS;		// exit() parameter
	*tmp-- = 0;			// dummy return address
	*tmp   = (uint32_t) exit;	// "return" into exit()

	/*
	** Now, fill in the "saved" context information.  Begin
	** by computing a pointer to the context save area.
	*/

	context = (context_t *)tmp - 1;

	/*
	** Clear the context area to ensure that the "saved"
	** general registers all contain 0.
	*/

	_memclr( (void *) context, sizeof(context_t) );

	/*
	** Initialize all the registers that should be non-zero.
	** First, the segment registers.
	*/

	context->cs  = GDT_CODE;
	context->ss  = GDT_STACK;
	context->ds  = GDT_DATA;
	context->es  = GDT_DATA;
	context->fs  = GDT_DATA;
	context->gs  = GDT_DATA;

	/*
	** EIP must contain the entry point of the user routine;
	** in essence, we're pretending that this is where we
	** were executing when the interrupt arrived.
	*/

	context->eip = entry;

	// EFLAGS must be properly initialized

	context->eflags = DEFAULT_EFLAGS;

	// return the pointer to the new context

	return( context );

}
Esempio n. 4
0
Context *_setup_stack( Stack *stack, unsigned int entry ) {
    Context *context;
    unsigned int *ptr;

    // start by clearing the stack

    _memclr( (void *)stack, sizeof(Stack) );

    //
    // We need to set up the initial stack contents for a (new)
    // user process.
    //
    // We reserve a longword at the bottom of the stack for
    // some scratch space.  Above this, we'll place a dummy
    // "return address" so that if the process ever returns
    // from its main routine it will "return" to the exit()
    // system call.  Finally, above that we'll initialize a
    // context for the process to use when dispatched.
    //

    // find the location immediately after the stack

    ptr = (unsigned int *)(stack + 1);

    // back up two longwords' distance

    ptr -= 2;

    // assign the dummy return address

    *ptr = (unsigned int) exit;

    // figure out where the process context area should be

    context = ((Context *)ptr) - 1;

    // initialize all the register fields in the context
    // area that should contain something other than zero
    //
    // first, the segment register save areas

    // This function is used for two processes that run within the kernel,
    // so they use the kernel stack. But since they are processes, they still
    // need an LDT.

    context->ss = LDT_DSEG;
    context->ds = LDT_DSEG;
    context->es = LDT_DSEG;
    context->fs = LDT_DSEG;
    context->gs = LDT_DSEG;

    context->cs = LDT_CSEG;

    // next, the entry point for the process

    context->eip = (unsigned int) entry;

    // the initial EFLAGS settings

    context->eflags = DEFAULT_EFLAGS;

    // finally, the context pointer goes into the PCB
    // so that the context can be "restored" when this
    // process is eventually dispatched

    context->esp = (unsigned int) ptr;

    // return the context pointer

    return( context );

}
Esempio n. 5
0
/*
** _init_sio
**
** Initialize the UART chip.
*/
void _init_sio( void ) {

	//
	// Initialize SIO variables.
	//

	_memclr( (void *) g_inbuffer, sizeof(g_inbuffer) );
	g_inlast = g_innext = g_inbuffer;
	g_incount = 0;

	_memclr( (void *) g_outbuffer, sizeof(g_outbuffer) );
	g_outlast = g_outnext = g_outbuffer;
	g_outcount = 0;
	g_sending = 0;

	//
	// Next, initialize the UART.
	//

	// Initialize the FIFOs
	//
	// this is a bizarre little sequence of operations

	__outb( UA4_FCR, 0x20 );
	__outb( UA4_FCR, 0x00 );		// reset
	__outb( UA4_FCR, UA5_FCR_FIFO_EN );	// 0x01
	__outb( UA4_FCR, UA5_FCR_FIFO_EN |
			 UA5_FCR_RXSR );	// 0x03
	__outb( UA4_FCR, UA5_FCR_FIFO_EN |
			 UA5_FCR_RXSR |
			 UA5_FCR_TXSR );	// 0x07

	// disable interrupts

	__outb( UA4_IER, 0 );

	// select bank 1 and set the data rate

	__outb( UA4_LCR, UA4_LCR_BANK1 );
	__outb( UA4_LBGD_L, BAUD_LOW_BYTE( BAUD_9600 ) );
	__outb( UA4_LBGD_H, BAUD_HIGH_BYTE( BAUD_9600 ) );

	// Select bank 0, and at the same time set the LCR for our
	// data characteristics.

	__outb( UA4_LCR, UA4_LCR_BANK0 |
			 UA4_LCR_BITS_8 |
			 UA4_LCR_1_STOP_BIT |
			 UA4_LCR_NO_PARITY );
	
	// Set the ISEN bit to enable the interrupt request signal.

	__outb( UA4_MCR, UA4_MCR_ISEN | UA4_MCR_DTR | UA4_MCR_RTS );

	// Install our ISR

	__install_isr( INT_VEC_SERIAL_PORT_1, _isr_sio );

	// Enable device interrupts.

	__outb( UA4_IER, UA4_IER_TX_INT_ENABLE | UA4_IER_RX_INT_ENABLE );

	// Report that we're done.

	c_puts( " sio" );

}