Ejemplo n.º 1
0
/* malloc() called by:
 *   RCCE_shmalloc_init()
 *   RCCE_shmalloc()
 *   RCCE_malloc_init()
 *   RCCE_malloc()
 *   RCCE_flag_alloc() */
void *malloc(size_t nbytes)
{
    irqmask im; 
    struct memblock *prev, *curr, *leftover;

    /* we don't allocate 0 bytes. */
    if (0 == nbytes)
    {   
        return NULL;
    }   

    /* round request to size of memblock */
    nbytes = (uint)roundmb(nbytes);

    /* make room for accounting information */
    nbytes += sizeof(struct memblock);

    im = disable();

    prev = &memlist;
    curr = memlist.next;
    while (curr != NULL)
    {   
        if (curr->length == nbytes)
        {   
			/* perfect size */
            prev->next = curr->next;
            memlist.length -= nbytes;

            break;
        }
        else if (curr->length > nbytes)
        {
            /* split block into two */
            leftover = (struct memblock *)((ulong)curr + nbytes);
            prev->next = leftover;
            leftover->next = curr->next;
            leftover->length = curr->length - nbytes;
            memlist.length -= nbytes;

            break;
        }
        prev = curr;
        curr = curr->next;
    }

	if (curr == NULL)
	{
		restore(im);
		return NULL;
	}

	curr->next = curr;
	curr->length = nbytes;

	restore(im);
	return (void *)(curr + 1); /* +1 to skip accounting info */
}
Ejemplo n.º 2
0
/*------------------------------------------------------------------------
 *  freemem  --  free a memory block, returning it to memlist
 *------------------------------------------------------------------------
 */
SYSCALL freemem(struct mblock *block, unsigned size) {
    STATWORD ps;    
    struct  mblock  *p, *q;
    unsigned top;

    if (size==0 || (unsigned)block>(unsigned)maxaddr
        || ((unsigned)block)<((unsigned) &end))
        return(SYSERR);
    size = (unsigned)roundmb(size);
    disable(ps);

    // Iterate through the list until we get to the end or 
    // the next block (p) is greater than the block we are 
    // freeing. Basically this is so we can insert our block
    // back into the list in sorted order.
    for( p=memlist.mnext,q= &memlist;
         p != (struct mblock *) NULL && p < block ;
         q=p,p=p->mnext )
        ;

    
    // Check for errors
    //     - Is the block already a part of a free block?
    //         - Does q include part of it?
    //         - Does p include part of it?
    if (((top=q->mlen+(unsigned)q)>(unsigned)block && q!= &memlist) ||
        (p!=NULL && (size+(unsigned)block) > (unsigned)p )) {
        restore(ps);
        return(SYSERR);
    }

    // Is the top of the current block equal to the start of the
    // block that is being freed? If so then just make the current
    // free block bigger (adjust mlen).
    if ( q!= &memlist && top == (unsigned)block ) {
            q->mlen += size;

    // If not then create a new block and add it to the list.
    } else {
        block->mlen = size;
        block->mnext = p;
        q->mnext = block;
        q = block;
    }


    // We may now be able to merge this block with the next block
    // if they are now right next to one another. 
    if ( (unsigned)( q->mlen + (unsigned)q ) == (unsigned)p) {
        q->mlen += p->mlen;
        q->mnext = p->mnext;
    }

    restore(ps);
    return(OK);
}
Ejemplo n.º 3
0
/**
 * @ingroup memory_mgmt
 *
 * Allocate stack memory.
 *
 * @param nbytes
 *      Number of bytes requested.
 *
 * @return
 *      ::SYSERR if @p nbytes was 0 or there is no memory to satisfy the
 *      request; otherwise returns a pointer to the <b>topmost word</b> of the
 *      allocated memory region.  The intention is that this is the base of a
 *      stack growing down.  Free the stack with stkfree() when done with it.
 */
void *stkget(uint nbytes)
{
    irqmask im;
    struct memblock *prev, *next, *fits, *fitsprev;

    if (0 == nbytes)
    {
        return (void *)SYSERR;
    }

    /* round to multiple of memblock size   */
    nbytes = (uint)roundmb(nbytes);

    im = disable();

    prev = &memlist;
    next = memlist.next;
    fits = NULL;
    fitsprev = NULL;

    /* scan list for highest block that fits */
    while (next != NULL)
    {
        if (next->length >= nbytes)
        {
            fits = next;
            fitsprev = prev;
        }
        prev = next;
        next = next->next;
    }

    if (NULL == fits)
    {
        /* no block big enough */
        restore(im);
        return (void *)SYSERR;
    }

    if (nbytes == fits->length)
    {
        fitsprev->next = fits->next;
    }
    else
    {
        /* take top portion */
        fits->length -= nbytes;
        fits = (struct memblock *)((ulong)fits + fits->length);
    }

    memlist.length -= nbytes;
    restore(im);
    return (void *)((ulong)fits + nbytes - sizeof(int));
}
Ejemplo n.º 4
0
/**
 * Intializes all XINU data structures and devices.
 * @return OK if everything is initialized successfully
 */
local sysinit(void)
{
	int     i = 0;
	pcb     *ppcb = NULL;               /* process control block pointer */
	semblk  *psem = NULL;               /* semaphore block pointer       */
	memblk  *pmem = NULL;               /* memory block pointer          */

	/* Initialize system variables */
	/* Count this NULLPROC as the first process in the system. */
	numproc   = 1;

    /* Initialize free memory list */
	freelist.next   = pmem = (memblk *) roundmb(minheap);
	freelist.length = (ulong)truncew((ulong)platform.maxaddr - (ulong)minheap);
	pmem->next      = NULL;
	pmem->length    = freelist.length;

	/* Initialize process table */
	for (i = 0; i < NPROC; i++)
		{ proctab[i].state = PRFREE; }

	/* initialize null process entry */
	ppcb = &proctab[NULLPROC];
	ppcb->state        = PRCURR;
	strncpy(ppcb->name, "prnull", 7);
	ppcb->stkbase      = (void *)&end;
	ppcb->stkptr       = NULL;
	ppcb->stklen       = (ulong)minheap - (ulong)&end;
	ppcb->priority     = 0;
	currpid            = NULLPROC;

	/* Initialize semaphores */
	for (i = 0; i < NSEM; i++)
	{
		psem = &semtab[i];
		psem->state = SFREE;
		psem->count = 0;
		psem->queue = newqueue();
	}

	/* initialize bounded-waiting mutex subsystems */
	mutexInit();

	/* initialize process ready list */
	readylist = newqueue();

#if RTCLOCK
	/* initialize real time clock */
	clockinit();
#endif

	return OK;
}
Ejemplo n.º 5
0
void init_heap()
{
	struct memblock *heap;

	/* round memheap up to memblock alignment */
	heap = (struct memblock *)roundmb(memheap);

	memlist.next = heap;
	memlist.length = (ulong)_start - (ulong)memheap;
	heap->next = NULL;
	heap->length = memlist.length;
}
Ejemplo n.º 6
0
/**
 * Free a memory block, returning it to free list.
 * @param pmem pointer to memory block
 * @param nbytes size of memory block
 * @return OK on success, SYSERR on failure
 *
 */
syscall	freemem(void *pmem, ulong nbytes)
{
	ulong im = disable();

	// Insert back into free list, and compact with adjacent blocks.
	if ((0 >= nbytes) || (pmem == NULL))
	{
		restore(im);
		return SYSERR;
	}
	
	memblk *newblock = (memblk *)pmem;
	if (((void *)newblock < minheap) || ((void *)newblock > platform.maxaddr) || ((void *)(newblock + nbytes/8) > platform.maxaddr))
	{
		restore(im);
		return SYSERR;
	}
	
	nbytes = (ulong)roundmb(nbytes);

	memblk *curr = freelist.next;
	memblk *prev = NULL;

	while((curr != NULL) && (curr < newblock))
	{
		prev = curr;
		curr = curr->next;
	}

	newblock->length = nbytes;
	newblock->next = curr;
	if (NULL == prev)
		freelist.next = newblock;
	else
		prev->next = newblock;
	
	if ((newblock + newblock->length/8) == newblock->next)
	{
		newblock->next = curr->next;
		newblock->length += curr->length;
	}
	if (NULL != prev)
	{
		if ((prev + prev->length/8) == newblock)
		{
			prev->next = newblock->next;
			prev->length += newblock->length;
		}
	}
	freelist.length += nbytes;
	restore(im);
	return OK;
}
Ejemplo n.º 7
0
/*------------------------------------------------------------------------
 *  getstk  -  Allocate stack memory, returning highest word address
 *------------------------------------------------------------------------
 */
char  	*getstk(
	  uint32	nbytes		/* Size of memory requested	*/
	)
{
	intmask	mask;			/* Saved interrupt mask		*/
	struct	memblk	*prev, *curr;	/* Walk through memory list	*/
	struct	memblk	*fits, *fitsprev; /* Record block that fits	*/
    uint32 read = 0;        /* jteague6 - for best-fit finding */

	mask = disable();
	if (nbytes == 0) {
		restore(mask);
		return (char *)SYSERR;
	}

	nbytes = (uint32) roundmb(nbytes);	/* Use mblock multiples	*/

	prev = &memlist;
	curr = memlist.mnext;
	fits = NULL;
	fitsprev = NULL;  /* Just to avoid a compiler warning */

	while (curr != NULL) {			/* Scan entire list	*/
		/* jteague6 - for best fit, we want to not only make sure the block
         * fitst, but we want to also make sure it is the first fitting block
         * that has been found, or that it is smaller than the current
         * fitting block. */
        if (curr->mlength >= nbytes &&
                ( read == 0 ||
                  curr->mlength < fits->mlength )) {	/* Record block address	*/
			fits = curr;		/*   when request fits	*/
			fitsprev = prev;
            read = 1;           /* To prevent erroneous positives */
		}
		prev = curr;
		curr = curr->mnext;
	}

	if (fits == NULL) {			/* No block was found	*/
		restore(mask);
		return (char *)SYSERR;
	}
	if (nbytes == fits->mlength) {		/* Block is exact match	*/
		fitsprev->mnext = fits->mnext;
	} else {				/* Remove top section	*/
		fits->mlength -= nbytes;
		fits = (struct memblk *)((uint32)fits + fits->mlength);
	}
	memlist.mlength -= nbytes;
	restore(mask);
	return (char *)((uint32) fits + nbytes - 2 * sizeof(uint32));
}
Ejemplo n.º 8
0
void	nulluser(void)
{
	sysinit();

	kprintf("\n\r%s\n\n\r", VERSION);

	/* Output Xinu memory layout */

	kprintf("%10d bytes physical memory.\n",
		(uint32)maxheap - (uint32)0);
	kprintf("           [0x%08X to 0x%08X]\r\n",
		(uint32)0, (uint32)maxheap - 1);
	kprintf("%10d bytes of Xinu code.\n",
		(uint32)&etext - (uint32)0);
	kprintf("           [0x%08X to 0x%08X]\n",
		(uint32)0, (uint32)&etext - 1);
	kprintf("%10d bytes of data.\n",
		(uint32)&end - (uint32)&etext);
	kprintf("           [0x%08X to 0x%08X]\n",
		(uint32)&etext, (uint32)&end - 1);
	if ( (char *)minheap < HOLESTART) {
	    kprintf("%10d bytes of heap space below 640K.\n",
		(uint32)HOLESTART - (uint32)roundmb(minheap));
	}
	if ( (char *)maxheap > HOLEEND ) {
	    kprintf("%10d bytes of heap space above 1M.\n",
		(uint32)maxheap - (uint32)HOLEEND);
	    kprintf("           [0x%08X to 0x%08X]\n",
		(uint32)HOLEEND, (uint32)truncmb(maxheap) - 1);
	}

	/* Enable interrupts */
	
	enable();

	/* Start the network */
	
	resume(create((void *)netin, NETSTK, NETPRIO, "netin", 0));

	/* Create a process to execute function main() */

	resume (
	   create((void *)main, INITSTK, INITPRIO, "Main process", 2, 0, NULL));

	/* Become the Null process (i.e., guarantee that the CPU has	*/
	/*  something to run when no other process is ready to execute)	*/

	while (TRUE) {
		;		/* do nothing */
	}
}
Ejemplo n.º 9
0
/**
 * Allocate heap storage, returning lowest word address
 * @param nbytes  bytes requested
 * @return pointer to region on success, SYSERR on failure
 */
void *memget(uint nbytes)
{
    register struct memblock *prev, *curr, *leftover;
    irqmask im;

    if (0 == nbytes)
    {
        return (void *)SYSERR;
    }

    /* round to multiple of memblock size   */
    nbytes = (ulong)roundmb(nbytes);

    im = disable();

    prev = &memlist;
    curr = memlist.next;
    while (curr != NULL)
    {
        if (curr->length == nbytes)
        {
            prev->next = curr->next;
            memlist.length -= nbytes;

            restore(im);
            return (void *)(curr);
        }
        else if (curr->length > nbytes)
        {
            /* split block into two */
            leftover = (struct memblock *)((ulong)curr + nbytes);
            prev->next = leftover;
            leftover->next = curr->next;
            leftover->length = curr->length - nbytes;
            memlist.length -= nbytes;

            restore(im);
            return (void *)(curr);
        }
        prev = curr;
        curr = curr->next;
    }
    restore(im);
    return (void *)SYSERR;
}
/*------------------------------------------------------------------------
 *  getstk  -  Allocate stack memory, returning highest word address
 *------------------------------------------------------------------------
 */
char  	*newgetstk(
    uint32	nbytes		/* Size of memory requested	*/
)
{
    intmask	mask;			/* Saved interrupt mask		*/
    struct	memblk	*prev, *curr;	/* Walk through memory list	*/
    struct	memblk	*fits, *fitsprev; /* Record block that fits	*/

    mask = disable();
    if (nbytes == 0) {
        restore(mask);
        return (char *)SYSERR;
    }

    nbytes = (uint32) roundmb(nbytes);	/* Use mblock multiples	*/

    prev = &memlist;
    curr = memlist.mnext;
    fits = NULL;
    fitsprev = NULL;  /* Just to avoid a compiler warning */

    while (curr != NULL) {			/* Scan entire list	*/
        if (curr->mlength >= nbytes) {	/* Record block address	*/
            fits = curr;		/*   when request fits	*/
            fitsprev = prev;
            break; //
        }
        prev = curr;
        curr = curr->mnext;
    }

    if (fits == NULL) {			/* No block was found	*/
        restore(mask);
        return (char *)SYSERR;
    }
    if (nbytes == fits->mlength) {	//	Block is exact match
        fitsprev->mnext = fits->mnext;
    } else {				 //Remove top section
        fits->mlength -= nbytes;
        fits = (struct memblk *)((uint32)fits + fits->mlength);
    }
    memlist.mlength -= nbytes;
    restore(mask);
    return (char *)((uint32) fits + nbytes - sizeof(uint32));
}
Ejemplo n.º 11
0
/*------------------------------------------------------------------------
 *  getmem  -  Allocate heap storage, returning lowest word address
 *------------------------------------------------------------------------
 */
char  	*getmem(
	  uint32	nbytes		/* Size of memory requested	*/
	)
{
	intmask	mask;			/* Saved interrupt mask		*/
	struct	memblk	*prev, *curr, *leftover;

	mask = disable();
	if (nbytes == 0) {
		restore(mask);
		return (char *)SYSERR;
	}

	nbytes = (uint32) roundmb(nbytes);	/* Use memblk multiples	*/

	prev = &memlist;
	curr = memlist.mnext;
	while (curr != NULL) {			/* Search free list	*/

		if (curr->mlength == nbytes) {	/* Block is exact match	*/
			prev->mnext = curr->mnext;
			memlist.mlength -= nbytes;
			OS_sendevent(getpid(), PROCESS_GETMEM_EVENT);
			restore(mask);
			return (char *)(curr);

		} else if (curr->mlength > nbytes) { /* Split big block	*/
			leftover = (struct memblk *)((uint32) curr +
					nbytes);
			prev->mnext = leftover;
			leftover->mnext = curr->mnext;
			leftover->mlength = curr->mlength - nbytes;
			memlist.mlength -= nbytes;
			OS_sendevent(getpid(), PROCESS_GETMEM_EVENT);
			restore(mask);
			return (char *)(curr);
		} else {			/* Move to next block	*/
			prev = curr;
			curr = curr->mnext;
		}
	}
	restore(mask);
	return (char *)SYSERR;
}
Ejemplo n.º 12
0
/*------------------------------------------------------------------------
 *  freemem  --  free a memory block, returning it to memlist
 *------------------------------------------------------------------------
 */
SYSCALL	freemem(struct mblock *block, unsigned size)
{
	
	int start;
	if(activated == 1)
		start = ctr1000;
	STATWORD ps;    
	struct	mblock	*p, *q;
	unsigned top;

	if (size==0 || (unsigned)block>(unsigned)maxaddr
	    || ((unsigned)block)<((unsigned) &end))
		return(SYSERR);
	size = (unsigned)roundmb(size);
	disable(ps);
	for( p=memlist.mnext,q= &memlist;
	     p != (struct mblock *) NULL && p < block ;
	     q=p,p=p->mnext )
		;
	if (((top=q->mlen+(unsigned)q)>(unsigned)block && q!= &memlist) ||
	    (p!=NULL && (size+(unsigned)block) > (unsigned)p )) {
		restore(ps);
		return(SYSERR);
	}
	if ( q!= &memlist && top == (unsigned)block )
			q->mlen += size;
	else {
		block->mlen = size;
		block->mnext = p;
		q->mnext = block;
		q = block;
	}
	if ( (unsigned)( q->mlen + (unsigned)q ) == (unsigned)p) {
		q->mlen += p->mlen;
		q->mnext = p->mnext;
	}
	restore(ps);
	if(activated == 1)
	{
		Info[currpid][FREEMEM].freq++;
		Info[currpid][FREEMEM].time += (ctr1000 - start);
	}	
	return(OK);
}
Ejemplo n.º 13
0
/*------------------------------------------------------------------------
 *  getstk  -  Allocate stack memory, returning highest word address
 *------------------------------------------------------------------------
 */
char  	*getstk(
	  uint32	nbytes		/* size of memory requested	*/
	)
{
	intmask	mask;			/* saved interrupt mask		*/
	struct	memblk	*prev, *curr;	/* walk through memory list	*/
	struct	memblk	*fits, *fitsprev; /* record block that fits	*/

	mask = disable();
	if (nbytes == 0) {
		restore(mask);
		return (char *)SYSERR;
	}

	nbytes = (uint32) roundmb(nbytes);	/* use mblock multiples	*/

	prev = &memlist;
	curr = memlist.mnext;
	fits = NULL;

	while (curr != NULL) {			/* scan entire list	*/
		if (curr->mlength >= nbytes) {	/* record block address	*/
			fits = curr;		/*   when request fits	*/
			fitsprev = prev;
		}
		prev = curr;
		curr = curr->mnext;
	}

	if (fits == NULL) {			/* no block was found	*/
		restore(mask);
		return (char *)SYSERR;
	}
	if (nbytes == fits->mlength) {		/* block is exact match	*/
		fitsprev->mnext = fits->mnext;
	} else {				/* remove top section	*/
		fits->mlength -= nbytes;
		fits = (struct memblk *)((uint32)fits + fits->mlength);
	}
	memlist.mlength -= nbytes;
	restore(mask);
	return (char *)((uint32) fits + nbytes - sizeof(uint32));
}
Ejemplo n.º 14
0
/*------------------------------------------------------------------------
 *  freemem  --  free a memory block, returning it to memlist
 *------------------------------------------------------------------------
 */
SYSCALL
freemem(void *block0, unsigned size)
{
	struct mblock *block = (struct mblock *)block0;
	STATWORD ps;    
	struct	mblock	*p, *q;
	unsigned top;

	if (size==0 || (unsigned)block>(unsigned)maxaddr
	    || ((unsigned)block)<((unsigned) &end))
		return(SYSERR);
	size = (unsigned)roundmb(size);
	disable(ps);
	for( p=memlist.mnext,q= &memlist;
	     p != (struct mblock *) NULL && p < block ;
	     q=p,p=p->mnext )
		;
	if ((top=q->mlen+(unsigned)q)>(unsigned)block && q!= &memlist ||
	    p!=NULL && (size+(unsigned)block) > (unsigned)p ) {
		restore(ps);
		return(SYSERR);
	}
	if ( q!= &memlist && top == (unsigned)block )
			q->mlen += size;
	else {
		block->mlen = size;
		block->mnext = p;
		q->mnext = block;
		q = block;
	}
	if ( (unsigned)( q->mlen + (unsigned)q ) == (unsigned)p) {
		q->mlen += p->mlen;
		q->mnext = p->mnext;
	}
	restore(ps);
	return(OK);
}
Ejemplo n.º 15
0
//////////////////////////////////////////////////////////////////////////
//  vheap_test
//////////////////////////////////////////////////////////////////////////
void vheaptask() {
    int i,x;
    char * str;
    char * pass = "******";
    char * fail = "FAIL";

    // Values for proc structure
    char pstate = 'Z';
    int pprio   = 100;
    int pesp    = 45;


    // Values for bs_map_t structure
    int pid    = 99;
    int npages = 32;
    int vpno   = 4200;

    // Values for frame_t structure
    int status = 75;
    int type   = 1;
    int refcnt = 7200;

    // Create a proc structure.. populate some print it out
    kprintf("Allocating pentry structure\n\n");
    struct pentry * pptr;
    pptr = vgetmem(sizeof(struct pentry));
    if (pptr == SYSERR) {
        kprintf("Could not allocate mem for pentry");
        return;
    }
    kprintf("Mem for pentry structure: 0x%08x\n", pptr);
    pptr->pstate = pstate;
    pptr->pprio  = pprio;
    pptr->pesp   = pesp;

    str = (pptr->pstate == pstate) ? pass : fail;
    kprintf("task1: UT1 pptr->pstate: \t%s\n", str);

    str = (pptr->pprio == pprio) ? pass : fail;
    kprintf("task1: UT2 pptr->pprio: \t%s\n", str);

    str = (pptr->pesp == pesp) ? pass : fail;
    kprintf("task1: UT3 pptr->pesp: \t%s\n", str);

    kprintf("\n\n");




    // Create a bs_map_t structure.. populate some print it out
    kprintf("Allocating bs_map_t structure\n\n");
    bs_map_t * bsmptr;
    bsmptr = vgetmem(sizeof(bs_map_t));
    if (bsmptr == SYSERR) {
        kprintf("Could not allocate mem for bs_map_t");
        return;
    }
    kprintf("Mem for bs_map_t structure: 0x%08x\n", bsmptr);
    bsmptr->pid    = pid;
    bsmptr->npages = npages;
    bsmptr->vpno   = vpno;

    str = (bsmptr->pid == pid) ? pass : fail;
    kprintf("task1: UT4 bsmptr->pid: \t%s\n", str);

    str = (bsmptr->npages == npages) ? pass : fail;
    kprintf("task1: UT5 bsmptr->npages: \t%s\n", str);

    str = (bsmptr->pid == pid) ? pass : fail;
    kprintf("task1: UT6 bsmptr->vpno: \t%s\n", str);

    kprintf("\n\n");



    // Free the proc structure
    kprintf("Freeing pentry structure\n\n");
    vfreemem((struct mblock *)pptr, sizeof(struct pentry));
    kprintf("\n\n");




    // Create a frame_t structure
    kprintf("Allocating frame_t structure\n\n");
    frame_t * frame;
    frame = vgetmem(sizeof(frame_t));
    if (frame == SYSERR) {
        kprintf("Could not allocate mem for frame_t");
        return;
    }
    kprintf("Mem for frame_t structure: 0x%08x\n", frame);
    frame->status = status;
    frame->type   = type;
    frame->refcnt = refcnt;

    str = (frame->status == status) ? pass : fail;
    kprintf("task1: UT7 frame->status: \t%s\n", str);

    str = (frame->type == type) ? pass : fail;
    kprintf("task1: UT8 frame->type: \t%s\n", str);

    str = (frame->refcnt == refcnt) ? pass : fail;
    kprintf("task1: UT9 frame->refcnt: \t%s\n", str);

    kprintf("\n\n");




    // Test the bs_map_t structure
    str = (bsmptr->pid == pid) ? pass : fail;
    kprintf("task1: UT10 bsmptr->pid: \t%s\n", str);

    str = (bsmptr->npages == npages) ? pass : fail;
    kprintf("task1: UT11 bsmptr->npages: \t%s\n", str);

    str = (bsmptr->pid == pid) ? pass : fail;
    kprintf("task1: UT12 bsmptr->vpno: \t%s\n", str);

    kprintf("\n\n");


    // Create a proc structure.. populate some print it out
    kprintf("Allocating pentry structure\n\n");
    struct pentry * pptr2;
    pptr2 = vgetmem(sizeof(struct pentry));
    if (pptr2 == SYSERR) {
        kprintf("Could not allocate mem for pentry");
        return;
    }
    kprintf("Mem for pentry structure: 0x%08x\n", pptr2);
    pptr2->pstate = pstate;
    pptr2->pprio  = pprio;
    pptr2->pesp   = pesp;

    str = (pptr2->pstate == pstate) ? pass : fail;
    kprintf("task1: UT13 pptr2->pstate: \t%s\n", str);

    str = (pptr2->pprio == pprio) ? pass : fail;
    kprintf("task1: UT14 pptr2->pprio: \t%s\n", str);

    str = (pptr2->pesp == pesp) ? pass : fail;
    kprintf("task1: UT15 pptr2->pesp: \t%s\n", str);

    kprintf("\n\n");



    // Free the bsmptr structure
    kprintf("Freeing bsmptr structure\n\n");
    vfreemem((struct mblock *)pptr, sizeof(bs_map_t));
    kprintf("\n\n");



    // Create a proc structure.. populate some print it out
    kprintf("Allocating pentry structure\n\n");
    struct pentry * pptr3;
    pptr3 = vgetmem(sizeof(struct pentry));
    if (pptr3 == SYSERR) {
        kprintf("Could not allocate mem for pentry");
        return;
    }
    kprintf("Mem for pentry structure: 0x%08x\n", pptr3);
    pptr3->pstate = pstate;
    pptr3->pprio  = pprio;
    pptr3->pesp   = pesp;

    str = (pptr3->pstate == pstate) ? pass : fail;
    kprintf("task1: UT16 pptr3->pstate: \t%s\n", str);

    str = (pptr3->pprio == pprio) ? pass : fail;
    kprintf("task1: UT17 pptr3->pprio: \t%s\n", str);

    str = (pptr3->pesp == pesp) ? pass : fail;
    kprintf("task1: UT18 pptr3->pesp: \t%s\n", str);

    kprintf("\n\n");





    // Final Tests.. So here is what we had:
    //  1. pptr =  vgetmem(sizeof(struct pentry *)
    //      -> Gets the first address (4096*NBPG)
    //  2. bsmptr = vgetmem(sizeof(bs_map_t)
    //      -> Gets addr immediately following
    //  3. vfreemem(pptr)
    //  4. frame = vgetmem(sizeof(frame_t)
    //      -> Since smaller -> Gets slot that pptr occupied
    //  5. pptr2 =  vgetmem(sizeof(struct pentry *)
    //      -> Gets address after frame
    //  6. vfreemem(bsmptr)
    //  5. pptr3 =  vgetmem(sizeof(struct pentry *)
    //      -> Since larger than bsmptr cannot occupy that space
    //      -> Gets address at end.
    //
    str = (pptr == 4096*NBPG) ? pass : fail;
    kprintf("task1: UT19 pptr mem: \t%s\n", str);

    x  = 4096*NBPG; 
    x += (int)roundmb(sizeof(struct pentry)); 
    x += (int)roundmb(sizeof(bs_map_t));
    str = (pptr2 == x) ? pass : fail;
    kprintf("task1: UT20 pptr2 mem: \t%s\n", str);

    x  = 4096*NBPG; 
    x += 2*(int)roundmb(sizeof(struct pentry)); 
    x += (int)roundmb(sizeof(bs_map_t));
    str = (pptr3 == x) ? pass : fail;
    kprintf("task1: UT21 pptr3 mem: \t%s\n", str);

    x = 4096*NBPG + sizeof(struct pentry);
    str = (bsmptr == x) ? pass : fail;
    kprintf("task1: UT22 bsmptr mem: \t%s\n", str);

    str = (frame == 4096*NBPG) ? pass : fail;
    kprintf("task1: UT23 frame mem: \t%s\n", str);


}
Ejemplo n.º 16
0
/*------------------------------------------------------------------------
 *  freemem  -  Free a memory block, returning the block to the free list
 *------------------------------------------------------------------------
 */
syscall	freestk(
	  char		*blkaddr,	/* Pointer to memory block	*/
	  uint32	nbytes		/* Size of block in bytes	*/
	)
{
	intmask	mask;			/* Saved interrupt mask		*/
	struct	memblk	*next, *prev, *block;
	uint32	top;

	mask = disable();
	
    /* jteague6 - modify arguments so they are set to the same values they
     * would be if the macro was still in use. */
    blkaddr = (char *)((uint32)blkaddr - ((uint32)roundmb(nbytes))
                    + (uint32)sizeof(uint32));
    nbytes = (uint32)roundmb(nbytes);

    /* jteague6 - from here, we search from the front to free. This is slow,
     * but it allows a massive amount of code reuse, and frankly I had issues
     * getting it to work searching from the rear. */

    if ((nbytes == 0) || ((uint32) blkaddr < (uint32) minheap)
			  || ((uint32) blkaddr > (uint32) maxheap)) {
		restore(mask);
		return SYSERR;
	}

	nbytes = (uint32) roundmb(nbytes);	/* Use memblk multiples	*/
	block = (struct memblk *)blkaddr;

	prev = &memlist;			/* Walk along free list	*/
	next = memlist.mnext;
	while ((next != NULL) && (next < block)) {
		prev = next;
		next = next->mnext;
	}

	if (prev == &memlist) {		/* Compute top of previous block*/
		top = (uint32) NULL;
	} else {
		top = (uint32) prev + prev->mlength;
	}

	/* Ensure new block does not overlap previous or next blocks	*/

	if (((prev != &memlist) && (uint32) block < top)
	    || ((next != NULL)	&& (uint32) block+nbytes>(uint32)next)) {
		restore(mask);
		return SYSERR;
	}

	memlist.mlength += nbytes;

	/* Either coalesce with previous block or add to free list */

	if (top == (uint32) block) { 	/* Coalesce with previous block	*/
		prev->mlength += nbytes;
		block = prev;
	} else {			/* Link into list as new node	*/
		block->mnext = next;
		block->mlength = nbytes;
		prev->mnext = block;
        /* jteague6 - support for rear list searching - modify mprev
         * links and reset memtail->mprev if needed */
        if( prev == &memlist ) {
            block->mprev = NULL;
        }
        else {
            block->mprev = prev;
        }
        if( block->mnext == NULL ) {
            memtail.mprev = block;
        }
        else {
            block->mnext->mprev = block;
        }
	}

	/* Coalesce with next block if adjacent */

	if (((uint32) block + block->mlength) == (uint32) next) {
		block->mlength += next->mlength;
		block->mnext = next->mnext;
        /* jteague6 - support for rear list searching - modify mprev
         * links and reset memtail->mprev if needed */
        if( block->mnext == NULL ) {
            memtail.mprev = block;
        }
        else {
            block->mnext->mprev = block;
        }
	}
	restore(mask);
	return OK;
}
Ejemplo n.º 17
0
/*------------------------------------------------------------------------
 *  sysinit  --  initialize all Xinu data structeres and devices
 *------------------------------------------------------------------------
 */
LOCAL
sysinit()
{
	static	long	currsp;
	int	i,j, avail;
	struct	pentry	*pptr;
	struct	sentry	*sptr;
	struct	mblock	*mptr;
	SYSCALL pfintr();

	/*********************/
	set_evec(14, pfintr);

	pptr = &proctab[NULLPROC]; /* initialize null process entry */
	/*********************/
	

	numproc = 0;			/* initialize system variables */
	nextproc = NPROC-1;
	nextsem = NSEM-1;
	nextqueue = NPROC;		/* q[0..NPROC-1] are processes */

	/* initialize free memory list */
	/* PC version has to pre-allocate 640K-1024K "hole" */
	if (maxaddr+1 > HOLESTART) {
		memlist.mnext = mptr = (struct mblock *) roundmb(&end);
		mptr->mnext = (struct mblock *)HOLEEND;
		mptr->mlen = (int) truncew(((unsigned) HOLESTART -
	     		 (unsigned)&end));
        mptr->mlen -= 4;

		mptr = (struct mblock *) HOLEEND;
		mptr->mnext = 0;
		mptr->mlen = (int) truncew((unsigned)maxaddr - HOLEEND -
	      		NULLSTK);
/*
		mptr->mlen = (int) truncew((unsigned)maxaddr - (4096 - 1024 ) *  4096 - HOLEEND - NULLSTK);
*/
	} else {
		/* initialize free memory list */
		memlist.mnext = mptr = (struct mblock *) roundmb(&end);
		mptr->mnext = 0;
		mptr->mlen = (int) truncew((unsigned)maxaddr - (int)&end -
			NULLSTK);
	}
	

	for (i=0 ; i<NPROC ; i++)	/* initialize process table */
		proctab[i].pstate = PRFREE;


#ifdef	MEMMARK
	_mkinit();			/* initialize memory marking */
#endif

#ifdef	RTCLOCK
	clkinit();			/* initialize r.t.clock	*/
#endif

	mon_init();     /* init monitor */

#ifdef NDEVS
	for (i=0 ; i<NDEVS ; i++ ) {	    
	    init_dev(i);
	}
#endif

	pptr = &proctab[NULLPROC];	/* initialize null process entry */
	pptr->pstate = PRCURR;
	for (j=0; j<7; j++)
		pptr->pname[j] = "prnull"[j];
	pptr->plimit = (WORD)(maxaddr + 1) - NULLSTK;
	pptr->pbase = (WORD) maxaddr - 3;
/*
	pptr->plimit = (WORD)(maxaddr + 1) - NULLSTK - (4096 - 1024 )*4096;
	pptr->pbase = (WORD) maxaddr - 3 - (4096-1024)*4096;
*/
	pptr->pesp = pptr->pbase-4;	/* for stkchk; rewritten before used */
	*( (int *)pptr->pbase ) = MAGIC;
	pptr->paddr = (WORD) nulluser;
	pptr->pargs = 0;
	pptr->pprio = 0;
	currpid = NULLPROC;
	
	
	for (i=0 ; i<NSEM ; i++) {	/* initialize semaphores */
		(sptr = &semaph[i])->sstate = SFREE;
		sptr->sqtail = 1 + (sptr->sqhead = newqueue());
	}

	rdytail = 1 + (rdyhead=newqueue());/* initialize ready list */

	init_bsm();
	init_frm();

	kprintf("initialize page tables for null process\n");
	init_glb_pgs(glb_pg_tbl_frm_mapping);
	// init pg dir for proc 0
	frame_t *pg_dir = get_free_frame();
	init_pg_dir(pg_dir, NULLPROC);
	pptr->pdbr = pg_dir->frm_num;
	pptr->pd = pg_dir;
	return(OK);
}
Ejemplo n.º 18
0
/**
 * Intializes all Xinu data structures and devices.
 * @return OK if everything is initialized successfully
 */
static int sysinit(void)
{
    int i;
    void *userheap;             /* pointer to user memory heap   */
    struct thrent *thrptr;      /* thread control block pointer  */
    device *devptr;             /* device entry pointer          */
    struct sement *semptr;      /* semaphore entry pointer       */
    struct memblock *pmblock;   /* memory block pointer          */
    struct bfpentry *bfpptr;

    /* Initialize system variables */
    /* Count this NULLTHREAD as the first thread in the system. */
    thrcount = 1;

    kprintf("variable i in this function is at 0x%x\r\n", &i);
    kprintf("this function sysinit is at 0x%x\r\n", &sysinit);
    kprintf("_start is at 0x%x\r\n", _start);
    kprintf("_end is at (the end) at 0x%x\r\n", &_end);
    kprintf("readylist is at 0x%x\r\n", &readylist);
    kprintf("kputc is at 0x%x\r\n", &kputc);
    kprintf("NTHREAD is %d\r\n", NTHREAD);

    kprintf("memheap is 0x%x\r\n", memheap);

    /* Initialize free memory list */
    memheap = roundmb(memheap);
    platform.maxaddr = truncmb(platform.maxaddr);
    kprintf("platform.maxaddr is 0x%x\r\n", platform.maxaddr);
    memlist.next = pmblock = (struct memblock *)memheap;
    memlist.length = (uint)(platform.maxaddr - memheap);
    pmblock->next = NULL;
    pmblock->length = (uint)(platform.maxaddr - memheap);

    /* Initialize thread table */
    for (i = 0; i < NTHREAD; i++)
    {
        thrtab[i].state = THRFREE;
    }
    kprintf("thrtab is at 0x%x, size %d\r\n", thrtab, sizeof(thrtab));

    /* initialize null thread entry */
    thrptr = &thrtab[NULLTHREAD];
    thrptr->state = THRCURR;
    thrptr->prio = 0;
    strncpy(thrptr->name, "prnull", 7);
    thrptr->stkbase = (void *)&_end;
    thrptr->stklen = (ulong)memheap - (ulong)&_end;
    thrptr->stkptr = 0;
    thrptr->memlist.next = NULL;
    thrptr->memlist.length = 0;
    thrcurrent = NULLTHREAD;

    kprintf("&_end is 0x%x\n", &_end);

    /* Initialize semaphores */
    for (i = 0; i < NSEM; i++)
    {
        semptr = &semtab[i];
        semptr->state = SFREE;
        semptr->count = 0;
        semptr->queue = queinit();
    }

    kprintf("NPOOL is %d\n", NPOOL);

    /* Initialize buffer pools */
    for (i = 0; i < NPOOL; i++)
    {
        bfpptr = &bfptab[i];
        bfpptr->state = BFPFREE;
    }
    kprintf("calling queinit() for readylist\r\n");

    /* initialize thread ready list */
    readylist = queinit();

#if SB_BUS
    backplaneInit(NULL);
#endif                          /* SB_BUS */

#if RTCLOCK
    /* initialize real time clock */
    kprintf("Clock being initialized.\r\n" );
    clkinit();
#endif                          /* RTCLOCK */

#ifdef UHEAP_SIZE
    /* Initialize user memory manager */
    userheap = stkget(UHEAP_SIZE);
    if (SYSERR != (int)userheap)
    {
        userheap = (void *)((uint)userheap - UHEAP_SIZE + sizeof(int));
        memRegionInit(userheap, UHEAP_SIZE);

        /* initialize memory protection */
        safeInit();

        /* initialize kernel page mappings */
        safeKmapInit();
    }
#else
    userheap = NULL;
#endif                          /* UHEAP_SIZE */

#if USE_TLB
    /* initialize TLB */
    tlbInit();
    /* register system call handler */
    exceptionVector[EXC_SYS] = syscall_entry;
#endif                          /* USE_TLB */

#if NMAILBOX
    /* intialize mailboxes */
    mailboxInit();
#endif

#if NDEVS
    for (i = 0; i < NDEVS; i++)
    {
        if (!isbaddev(i))
        {
            devptr = (device *)&devtab[i];
            (devptr->init) (devptr);
        }
    }
#endif
#if 0
#if NVRAM
    nvramInit();
#endif
    kprintf("SO MUCH MORE NOT done with sysinit()\r\n");
#if NNETIF
    netInit();
#endif
    kprintf("NOT done with sysinit()\r\n");
#if GPIO
    gpioLEDOn(GPIO_LED_CISCOWHT);
#endif
#endif
    kprintf("done with sysinit()\r\n");

    return OK;
}
Ejemplo n.º 19
0
static	void	sysinit(void)
{
	int32	i;
	struct	procent	*prptr;		/* ptr to process table entry	*/
	struct	dentry	*devptr;	/* ptr to device table entry	*/
	struct	sentry	*semptr;	/* prr to semaphore table entry	*/
	struct	memblk	*memptr;	/* ptr to memory block		*/

	/* Initialize the interrupt vectors */

	initevec();

	/* Initialize system variables */

	/* Count the Null process as the first process in the system */

	prcount = 1;

	/* Scheduling is not currently blocked */

	Defer.ndefers = 0;

	/* Initialize the free memory list */

	/* Note: PC version has to pre-allocate 640K-1024K "hole" */

	maxheap = (void *)MAXADDR;
	minheap = &end;

	memptr = memlist.mnext = (struct memblk *)roundmb(minheap);
	if ((char *)(maxheap+1) > HOLESTART) {
		/* create two blocks that straddle the hole */
		memptr->mnext = (struct memblk *)HOLEEND;
		memptr->mlength = (int) truncmb((unsigned) HOLESTART -
	     		 (unsigned)&end - 4);
		memptr = (struct memblk *) HOLEEND;
		memptr->mnext = (struct memblk *) NULL;
		memptr->mlength = (int) truncmb( (uint32)maxheap - 
				(uint32)HOLEEND - NULLSTK);
	} else {
		/* initialize free memory list to one block */
		memlist.mnext = memptr = (struct memblk *) roundmb(&end);
		memptr->mnext = (struct memblk *) NULL;
		memptr->mlength = (uint32) truncmb((uint32)maxheap -
				(uint32)&end - NULLSTK);
	}

	/* Initialize process table entries free */

	for (i = 0; i < NPROC; i++) {
		prptr = &proctab[i];
		prptr->prstate = PR_FREE;
		prptr->prname[0] = NULLCH;
		prptr->prstkbase = NULL;
		prptr->prprio = 0;
	}

	/* Initialize the Null process entry */

	prptr = &proctab[NULLPROC];
	prptr->prstate = PR_CURR;
	prptr->prprio = 0;
	strncpy(prptr->prname, "prnull", 7);
	prptr->prstkbase = getstk(NULLSTK);
	prptr->prstklen = NULLSTK;
	prptr->prstkptr = 0;
	currpid = NULLPROC;

	/* Initialize semaphores */

	for (i = 0; i < NSEM; i++) {
		semptr = &semtab[i];
		semptr->sstate = S_FREE;
		semptr->scount = 0;
		semptr->squeue = newqueue();
	}

	/* Initialize buffer pools */

	bufinit();
	/* Create a ready list for processes */

	readylist = newqueue();

	/* Initialize the PCI bus */

	pci_init();

	/* Initialize the real time clock */

	clkinit();

	for (i = 0; i < NDEVS; i++) {
		if (! isbaddev(i)) {
			devptr = (struct dentry *) &devtab[i];
			(devptr->dvinit) (devptr);
		}
	}
	return;
}
Ejemplo n.º 20
0
SYSCALL create(int (*procaddr)(), int ssize, int priority, char *name, int nargs, ...)
{
	STATWORD ps;    
	int pid;				/* stores new process id	*/
	struct pentry *pptr;	/* pointer to proc. table entry */
	int i;
	unsigned char *saddr;			/* stack address		*/
	int INITRET();
	va_list ap;

	disable(ps);
	ssize = (int) roundmb(ssize);
	if ( (saddr = (unsigned char *)getstk(ssize)) == (unsigned char *)SYSERR ) {
	    restore(ps);
	    return (SYSERR);
	}
	if ( ssize < MINSTK || (pid=newpid()) == SYSERR || priority < 1 ) {
	    freestk((unsigned)saddr, (unsigned)ssize);
	    restore(ps);
	    return(SYSERR);
	}
	numproc++;
	pptr = &proctab[pid];
	
	/* stderr set to &kprint_out (see kprintf.c and initialize.c) */
	pptr->fildes[0] = fdopen(CONSOLE, "r");	/* stdin set to console */
	pptr->fildes[1] = fdopen(CONSOLE, "w");	/* stdout set to console */
	pptr->fildes[2] = &kprint_out;			/* stderr set to &kprint_out */

	for (i=2; i < _NFILE; i++)			/* others set to unused */
		pptr->fildes[i] = (FILE *)FDFREE;

	pptr->pstate = PRSUSP;
	for (i=0 ; i<PNMLEN && (int)(pptr->pname[i]=name[i])!=0 ; i++)
		;
	pptr->pprio = priority;
	pptr->pbase = saddr;
	pptr->pstklen = ssize;
	pptr->psem = 0;
	pptr->phasmsg = FALSE;
	pptr->plimit = pptr->pbase - ssize + sizeof (WORD);	
	*saddr-- = (char)MAGIC;		/* Bottom of stack */
	pptr->pargs = nargs;
	for (i=0 ; i<PNREGS ; i++)
		pptr->pregs[i] = INITREG;	
	pptr->paddr = (int *)procaddr;
	pptr->pregs[SPC_L] = lobyte((unsigned) procaddr);
	pptr->pregs[SPC_H] = hibyte((unsigned) procaddr);
	pptr->pregs[SSREG] = INITPS;
	pptr->pnxtkin = BADPID;
	pptr->pdevs[0] = pptr->pdevs[1] = BADDEV;
	
	va_start(ap,nargs);
	for (i=0 ; i < nargs; i++)
		{
	    pptr->parg[i] = va_arg(ap, unsigned int);
		}
	va_end(ap);
	pptr->parg[nargs] = 0;
	
	/* machine/compiler dependent pass arguments to created process */
	pptr->pregs[24] = lobyte((unsigned)pptr->pargs);	/*r24*/
	pptr->pregs[25] = hibyte((unsigned)pptr->pargs);
	pptr->pregs[22] = lobyte((unsigned)&pptr->parg[0]);	/*r22*/
	pptr->pregs[23] = hibyte((unsigned)&pptr->parg[0]);

	*saddr-- = lobyte((unsigned)INITRET);	/* push on initial return address*/
	*saddr-- = hibyte((unsigned)INITRET);
//	*saddr-- = 0;	/* 256Kb memory device */ /*TODO make conditional*/
	*saddr-- = lobyte((unsigned)procaddr);	/* push on procedure address	*/
	*saddr-- = hibyte((unsigned)procaddr);
//	*saddr-- = 0;	/* 256Kb memory device */ /*TODO make conditional*/
	pptr->pregs[SSP_L] = lobyte((unsigned) saddr);
	pptr->pregs[SSP_H] = hibyte((unsigned) saddr);

	restore(ps);
	return(pid);
}
Ejemplo n.º 21
0
/*------------------------------------------------------------------------
 * meminit - initialize memory bounds and the free memory list
 *------------------------------------------------------------------------
 */
void	meminit(void) {

	struct	memblk	*memptr;	/* Ptr to memory block		*/
	struct	mbmregion	*mmap_addr;	/* Ptr to mmap entries		*/
	struct	mbmregion	*mmap_addrend;	/* Ptr to end of mmap region	*/
	struct	memblk	*next_memptr;	/* Ptr to next memory block	*/
	uint32	next_block_length;	/* Size of next memory block	*/
	
	mmap_addr = (struct mbmregion*)NULL;
	mmap_addrend = (struct mbmregion*)NULL;

	/* Initialize the free list */
	memptr = &memlist;
	memptr->mnext = (struct memblk *)NULL;
	memptr->mlength = 0;
	
	/* Initialize the memory counters */
	/*    Heap starts at the end of Xinu image */
	minheap = (void*)&end;
	maxheap = minheap;
	
	/* Check if Xinu was loaded using the multiboot specification	*/
	/*   and a memory map was included				*/
	if(bootsign != MULTIBOOT_SIGNATURE) {
		panic("could not find multiboot signature");
	}
	if(!(bootinfo->flags & MULTIBOOT_BOOTINFO_MMAP)) {
		panic("no mmap found in boot info");
	}
	
	/* Get base address of mmap region (passed by GRUB) */
	mmap_addr = (struct mbmregion*)bootinfo->mmap_addr;
		
	/* Calculate address that follows the mmap block */
	mmap_addrend = (struct mbmregion*)((uint8*)mmap_addr + bootinfo->mmap_length);

	/* Read mmap blocks and initialize the Xinu free memory list	*/
	while(mmap_addr < mmap_addrend) {

		/* If block is not usable, skip to next block */
		if(mmap_addr->type != MULTIBOOT_MMAP_TYPE_USABLE) {
			mmap_addr = (struct mbmregion*)((uint8*)mmap_addr + mmap_addr->size + 4);
			continue;
		}
			
		if((uint32)maxheap < ((uint32)mmap_addr->base_addr + (uint32)mmap_addr->length)) {
			maxheap = (void*)((uint32)mmap_addr->base_addr + (uint32)mmap_addr->length);
		}

		/* Ignore memory blocks within the Xinu image */
		if((mmap_addr->base_addr + mmap_addr->length) < ((uint32)minheap)) {
			mmap_addr = (struct mbmregion*)((uint8*)mmap_addr + mmap_addr->size + 4);
			continue;
		}
		
		/* The block is usable, so add it to Xinu's memory list */

		/* This block straddles the end of the Xinu image */
		if((mmap_addr->base_addr <= (uint32)minheap) &&
		  ((mmap_addr->base_addr + mmap_addr->length) >
		  (uint32)minheap)) {

			/* This is the first free block, base address is the minheap */
			next_memptr = (struct memblk *)roundmb(minheap);

			/* Subtract Xinu image from length of block */
			next_block_length = (uint32)truncmb(mmap_addr->base_addr + mmap_addr->length - (uint32)minheap);
		} else {

			/* Handle a free memory block other than the first one */
			next_memptr = (struct memblk *)roundmb(mmap_addr->base_addr);

			/* Initialize the length of the block */
			next_block_length = (uint32)truncmb(mmap_addr->length);
		}
		
		/* Add then new block to the free list */
		memptr->mnext = next_memptr;
		memptr = memptr->mnext;
		memptr->mlength = next_block_length;
		memlist.mlength += next_block_length;

		/* Move to the next mmap block */
		mmap_addr = (struct mbmregion*)((uint8*)mmap_addr + mmap_addr->size + 4);
	}

	/* End of all mmap blocks, and so end of Xinu free list */
	if(memptr) {
		memptr->mnext = (struct memblk *)NULL;
	}
}
Ejemplo n.º 22
0
/**
 * Intializes all Xinu data structures and devices.
 * @return OK if everything is initialized successfully
 */
static int sysinit(void)
{
    int i;
    struct thrent *thrptr;      /* thread control block pointer  */
    struct memblock *pmblock;   /* memory block pointer          */

    /* Initialize system variables */
    /* Count this NULLTHREAD as the first thread in the system. */
    thrcount = 1;

    /* Initialize free memory list */
    memheap = roundmb(memheap);
    platform.maxaddr = truncmb(platform.maxaddr);
    memlist.next = pmblock = (struct memblock *)memheap;
    memlist.length = (uint)(platform.maxaddr - memheap);
    pmblock->next = NULL;
    pmblock->length = (uint)(platform.maxaddr - memheap);

    /* Initialize thread table */
    for (i = 0; i < NTHREAD; i++)
    {
        thrtab[i].state = THRFREE;
    }

    /* initialize null thread entry */
    thrptr = &thrtab[NULLTHREAD];
    thrptr->state = THRCURR;
    thrptr->prio = 0;
    strlcpy(thrptr->name, "prnull", TNMLEN);
    thrptr->stkbase = (void *)&_end;
    thrptr->stklen = (ulong)memheap - (ulong)&_end;
    thrptr->stkptr = 0;
    thrptr->memlist.next = NULL;
    thrptr->memlist.length = 0;
    thrcurrent = NULLTHREAD;

    /* Initialize semaphores */
    for (i = 0; i < NSEM; i++)
    {
        semtab[i].state = SFREE;
        semtab[i].queue = queinit();
    }

    /* Initialize monitors */
    for (i = 0; i < NMON; i++)
    {
        montab[i].state = MFREE;
    }

    /* Initialize buffer pools */
    for (i = 0; i < NPOOL; i++)
    {
        bfptab[i].state = BFPFREE;
    }

    /* initialize thread ready list */
    readylist = queinit();

#if SB_BUS
    backplaneInit(NULL);
#endif                          /* SB_BUS */

#if RTCLOCK
    /* initialize real time clock */
    clkinit();
#endif                          /* RTCLOCK */

#ifdef UHEAP_SIZE
    /* Initialize user memory manager */
    {
        void *userheap;             /* pointer to user memory heap   */
        userheap = stkget(UHEAP_SIZE);
        if (SYSERR != (int)userheap)
        {
            userheap = (void *)((uint)userheap - UHEAP_SIZE + sizeof(int));
            memRegionInit(userheap, UHEAP_SIZE);

            /* initialize memory protection */
            safeInit();

            /* initialize kernel page mappings */
            safeKmapInit();
        }
    }
#endif

#if USE_TLB
    /* initialize TLB */
    tlbInit();
    /* register system call handler */
    exceptionVector[EXC_SYS] = syscall_entry;
#endif                          /* USE_TLB */

#if NMAILBOX
    /* intialize mailboxes */
    mailboxInit();
#endif

#if NDEVS
    for (i = 0; i < NDEVS; i++)
    {
        devtab[i].init((device*)&devtab[i]);
    }
#endif

#ifdef WITH_USB
    usbinit();
#endif

#if NVRAM
    nvramInit();
#endif

#if NNETIF
    netInit();
#endif

#if GPIO
    gpioLEDOn(GPIO_LED_CISCOWHT);
#endif
    return OK;
}
Ejemplo n.º 23
0
/*------------------------------------------------------------------------
 *  create  -  Create a process to start running a function on x86
 *------------------------------------------------------------------------
 */
pid32	create(
	  void		*funcaddr,	/* Address of the function	*/
	  uint32	ssize,		/* Stack size in bytes		*/
	  pri16		priority,	/* Process priority > 0		*/
	  char		*name,		/* Name (for debugging)		*/
	  uint32	nargs,		/* Number of args that follow	*/
	  ...
	)
{
	uint32		savsp, *pushsp;
	intmask 	mask;    	/* Interrupt mask		*/
	pid32		pid;		/* Stores new process id	*/
	struct	procent	*prptr;		/* Pointer to proc. table entry */
	int32		i;
	uint32		*a;		/* Points to list of args	*/
	uint32		*saddr;		/* Stack address		*/

	mask = disable();
	if (ssize < MINSTK)
		ssize = MINSTK;
	ssize = (uint32) roundmb(ssize);
	if ( (priority < 1) || ((pid=newpid()) == SYSERR) ||
	     ((saddr = (uint32 *)getstk(ssize)) == (uint32 *)SYSERR) ) {
		restore(mask);
		return SYSERR;
	}

	prcount++;
	prptr = &proctab[pid];

	/* Initialize process table entry for new process */
	prptr->prstate = PR_SUSP;	/* Initial state is suspended	*/
	prptr->prprio = priority;
	prptr->prstkbase = (char *)saddr;
	prptr->prstklen = ssize;
	prptr->prname[PNMLEN-1] = NULLCH;
	for (i=0 ; i<PNMLEN-1 && (prptr->prname[i]=name[i])!=NULLCH; i++)
		;
	prptr->prsem = -1;
	prptr->prparent = (pid32)getpid();
	prptr->prhasmsg = FALSE;

	// message queue for mysend<n> and myreceive<n>
	initMsgBuffer(&(prptr->mBuff));
	prptr->prnmsgwait = 0; // initially waiting for 0 messages from mysendn

	/* Set up stdin, stdout, and stderr descriptors for the shell	*/
	prptr->prdesc[0] = CONSOLE;
	prptr->prdesc[1] = CONSOLE;
	prptr->prdesc[2] = CONSOLE;

	/* Initialize stack as if the process was called		*/

	*saddr = STACKMAGIC;
	savsp = (uint32)saddr;

	/* Push arguments */
	a = (uint32 *)(&nargs + 1);	/* Start of args		*/
	a += nargs -1;			/* Last argument		*/
	for ( ; nargs > 0 ; nargs--)	/* Machine dependent; copy args	*/
		*--saddr = *a--;	/* onto created process's stack	*/
	*--saddr = (long)INITRET;	/* Push on return address	*/

	/* The following entries on the stack must match what ctxsw	*/
	/*   expects a saved process state to contain: ret address,	*/
	/*   ebp, interrupt mask, flags, registers, and an old SP	*/

	*--saddr = (long)funcaddr;	/* Make the stack look like it's*/
					/*   half-way through a call to	*/
					/*   ctxsw that "returns" to the*/
					/*   new process		*/
	*--saddr = savsp;		/* This will be register ebp	*/
					/*   for process exit		*/
	savsp = (uint32) saddr;		/* Start of frame for ctxsw	*/
	*--saddr = 0x00000200;		/* New process runs with	*/
					/*   interrupts enabled		*/

	/* Basically, the following emulates an x86 "pushal" instruction*/

	*--saddr = 0;			/* %eax */
	*--saddr = 0;			/* %ecx */
	*--saddr = 0;			/* %edx */
	*--saddr = 0;			/* %ebx */
	*--saddr = 0;			/* %esp; value filled in below	*/
	pushsp = saddr;			/* Remember this location	*/
	*--saddr = savsp;		/* %ebp (while finishing ctxsw)	*/
	*--saddr = 0;			/* %esi */
	*--saddr = 0;			/* %edi */
	*pushsp = (unsigned long) (prptr->prstkptr = (char *)saddr);
	restore(mask);
	return pid;
}
Ejemplo n.º 24
0
/*------------------------------------------------------------------------
 *  sysinit  --  initialize all Xinu data structeres and devices
 *------------------------------------------------------------------------
 */
LOCAL	sysinit()
{

	int i,j,len;
	struct pentry *pptr;	 /* null process entry */
	struct sentry *sptr;
	struct mblock *volatile mptr;

	numproc = 0;			/* initialize system variables */
	nextproc = NPROC-1;
	nextsem = NSEM-1;
	nextqueue = NPROC;		/* q[0..NPROC-1] are processes */

	memlist.mnext = mptr =		/* initialize free memory list */
	    (struct mblock *volatile) roundmb(__malloc_heap_start);
	mptr->mnext = (struct mblock *)NULL;
	mptr->mlen = len = (int) truncmb(RAMEND - NULLSTK - (unsigned)&__bss_end);
	__malloc_heap_start = (char *)mptr;
	__malloc_heap_end = __malloc_heap_start + len;
	kprintf_P(PSTR("Heap: %p of length %d\n"), mptr, len);
	
	for (i=0 ; i<NPROC ; i++)	/* initialize process table */
		proctab[i].pstate = PRFREE;

	/* initialize null process entry */
	pptr = &proctab[NULLPROC];
	pptr->pstate = PRCURR;
	for (j=0; j<6; j++)
		pptr->pname[j] = "nullp"[j];

	pptr->plimit = (unsigned char *)(RAMEND + 1) - NULLSTK;
	pptr->pbase = (unsigned char *) RAMEND;
	*pptr->pbase = (unsigned char)MAGIC; 	/* clobbers return, but proc 0 doesn't return */
	pptr->paddr = (int *) main;
	pptr->pargs = 0;
	pptr->pprio = 0;
	pptr->pregs[SSP_L] = lobyte((unsigned int)pptr->plimit);	/* for error checking */
	pptr->pregs[SSP_H] = hibyte((unsigned int)pptr->plimit);	/* for error checking */
	currpid = NULLPROC;

	for (i=0 ; i<NSEM ; i++) {	/* initialize semaphores */
		(sptr = &semaph[i])->sstate = SFREE;
		sptr->sqtail = 1 + (sptr->sqhead = newqueue());
	}

	rdytail = 1 + (rdyhead=newqueue());	/* initialize ready list */

	
#ifdef	MEMMARK
	kprintf("Memory marking\n");
	_mkinit();			/* initialize memory marking */
#else
	kprintf("Pool init\n");
	poolinit();			/* explicitly */
	pinit(MAXMSGS);
#endif

#ifdef	RTCLOCK
	kprintf("init RTC\n");
	clkinit();			/* initialize r.t.clock	*/
#endif

#ifdef NDEVS
	for ( i=0 ; i<NDEVS ; i++ ) {
		if (i>0) kprintf("init dev %d\n", i);
	    init(i);
	}
#endif

#ifdef	NNETS
//	kprintf("net init\n");
	netinit();
#endif

	return (OK);
}
/*------------------------------------------------------------------------
 *  sysinit  --  initialize all Xinu data structeres and devices
 *------------------------------------------------------------------------
 */
LOCAL int sysinit()
{
	int	i,j;
	struct	pentry	*pptr;
	struct	sentry	*sptr;
	struct	mblock	*mptr;

	numproc = 0;			/* initialize system variables */
	nextproc = NPROC-1;
	nextsem = NSEM-1;
	nextqueue = NPROC;		/* q[0..NPROC-1] are processes */

	/* initialize free memory list */
	/* PC version has to pre-allocate 640K-1024K "hole" */
	if (maxaddr+1 > (char *)HOLESTART) {
		memlist.mnext = mptr = (struct mblock *) roundmb(&end);
		mptr->mnext = (struct mblock *)HOLEEND;
		mptr->mlen = (int) truncew(((unsigned) HOLESTART -
	     		 (unsigned)&end));
        mptr->mlen -= 4;

		mptr = (struct mblock *) HOLEEND;
		mptr->mnext = 0;
		mptr->mlen = (int) truncew((unsigned)maxaddr - HOLEEND -
	      		NULLSTK);
	} else {
		/* initialize free memory list */
		memlist.mnext = mptr = (struct mblock *) roundmb(&end);
		mptr->mnext = 0;
		mptr->mlen = (int) truncew((unsigned)maxaddr - (int)&end -
			NULLSTK);
	}
	

	for (i=0 ; i<NPROC ; i++)	/* initialize process table */
		proctab[i].pstate = PRFREE;

	pptr = &proctab[NULLPROC];	/* initialize null process entry */
	pptr->pstate = PRCURR;
	for (j=0; j<7; j++)
		pptr->pname[j] = "prnull"[j];
	pptr->plimit = (WORD)(maxaddr + 1) - NULLSTK;
	pptr->pbase = (WORD) maxaddr - 3;
	pptr->pesp = pptr->pbase-4;	/* for stkchk; rewritten before used */
	*( (int *)pptr->pbase ) = MAGIC;
	pptr->paddr = (WORD) nulluser;
	pptr->pargs = 0;
	pptr->pprio = 0;
	currpid = NULLPROC;

	for (i=0 ; i<NSEM ; i++) {	/* initialize semaphores */
		(sptr = &semaph[i])->sstate = SFREE;
		sptr->sqtail = 1 + (sptr->sqhead = newqueue());
	}

	rdytail = 1 + (rdyhead=newqueue());/* initialize ready list */

#ifdef	MEMMARK
	_mkinit();			/* initialize memory marking */
#endif

#ifdef	RTCLOCK
	clkinit();			/* initialize r.t.clock	*/
#endif

	pci_init();	/* PCI */

	mon_init();	/* init monitor */
//	ripinit();

#ifdef NDEVS
	for (i=0 ; i<NDEVS ; i++ ) {	    
	    init_dev(i);
	}
#endif
	buf_init();
	return(OK);
}
Ejemplo n.º 26
0
/*------------------------------------------------------------------------
 *  getmem  -  Allocate heap storage, returning lowest word address
 *------------------------------------------------------------------------
 */
char  	*getmem(
	  uint32	nbytes		/* Size of memory requested	*/
	)
{
	intmask	mask;			/* Saved interrupt mask		*/
	struct	memblk	*prev, *curr, *leftover;

	mask = disable();
	if (nbytes == 0) {
		restore(mask);
		return (char *)SYSERR;
	}

	nbytes = (uint32) roundmb(nbytes);	/* Use memblk multiples	*/

	prev = &memlist;
	curr = memlist.mnext;
	while (curr != NULL) {			/* Search free list	*/

		if (curr->mlength == nbytes) {	/* Block is exact match	*/
			prev->mnext = curr->mnext;
            /* jteague6 - allow prev node re-linking to support
             * from-the-back node searching */
            if( curr == memtail.mprev ) {
                memtail.mprev = prev;
            }
            else {
                curr->mnext->mprev = prev;
            }

			memlist.mlength -= nbytes;
			restore(mask);
			return (char *)(curr);

		} else if (curr->mlength > nbytes) { /* Split big block	*/
			leftover = (struct memblk *)((uint32) curr +
					nbytes);
			prev->mnext = leftover;
			leftover->mnext = curr->mnext;
			leftover->mlength = curr->mlength - nbytes;
			memlist.mlength -= nbytes;

            /* jteague6 - support prev node re-linking to allow
             * from-the-back memory searching */
            leftover->mprev = curr->mprev;
            if( curr == memtail.mprev ) {
                memtail.mprev = leftover;
            }
            else {
                curr->mnext->mprev = leftover;
            }
			restore(mask);
			return (char *)(curr);
		} else {			/* Move to next block	*/
			prev = curr;
			curr = curr->mnext;
		}
	}
	restore(mask);
	return (char *)SYSERR;
}
Ejemplo n.º 27
0
/*------------------------------------------------------------------------
 *  freemem  -  Free a memory block, returning the block to the free list
 *------------------------------------------------------------------------
 */
syscall	freemem(
	  char		*blkaddr,	/* Pointer to memory block	*/
	  uint32	nbytes		/* Size of block in bytes	*/
	)
{
	intmask	mask;			/* Saved interrupt mask		*/
	struct	memblk	*next, *prev, *block;
	uint32	top;

	mask = disable();
	if ((nbytes == 0) || ((uint32) blkaddr < (uint32) minheap)
			  || ((uint32) blkaddr > (uint32) maxheap)) {
		restore(mask);
		return SYSERR;
	}

	nbytes = (uint32) roundmb(nbytes);	/* Use memblk multiples	*/
	block = (struct memblk *)blkaddr;

	prev = &memlist;			/* Walk along free list	*/
	next = memlist.mnext;
	while ((next != NULL) && (next < block)) {
		prev = next;
		next = next->mnext;
	}

	if (prev == &memlist) {		/* Compute top of previous block*/
		top = (uint32) NULL;
	} else {
		top = (uint32) prev + prev->mlength;
	}

	/* Ensure new block does not overlap previous or next blocks	*/

	if (((prev != &memlist) && (uint32) block < top)
	    || ((next != NULL)	&& (uint32) block+nbytes>(uint32)next)) {
		restore(mask);
		return SYSERR;
	}

	memlist.mlength += nbytes;

	/* Either coalesce with previous block or add to free list */

	if (top == (uint32) block) { 	/* Coalesce with previous block	*/
		prev->mlength += nbytes;
		block = prev;
	} else {			/* Link into list as new node	*/
		block->mnext = next;
		block->mlength = nbytes;
		prev->mnext = block;
	}

	/* Coalesce with next block if adjacent */

	if (((uint32) block + block->mlength) == (uint32) next) {
		block->mlength += next->mlength;
		block->mnext = next->mnext;
	}
	restore(mask);
	return OK;
}
Ejemplo n.º 28
0
/*
 *  vfreemem - free a virtual memory block, returning it to vmemlist
 *
 */
SYSCALL vfreemem(struct mblock* block, unsigned int size) {
    STATWORD ps;    
    struct mblock * curr;
    struct mblock * next;
    struct pentry * pptr;
    unsigned top;

    
    // Make sure they passed us a valid value for size
    if (size==0)
        return SYSERR;

    // Make sure they passed us a valid value for block
    if ((unsigned) block < (unsigned)(NBPG*4096))
        return SYSERR;

    // Get pointer to proctab entry for this proc
    pptr = &proctab[currpid];


    // Round up to a multiple of the size of a memory block
    size = (unsigned)roundmb(size);

    // Disable interrupts
    disable(ps);

    // Iterate through the list until we get to the end or 
    // the next block (p) is greater than the block we are 
    // freeing. Basically this is so we can insert our block
    // back into the list in sorted order.
    curr = &(pptr->vmemlist);
    next = curr->mnext;
    while((next != (struct mblock *) NULL) && (next < block)) { 
         curr=next;
         next=next->mnext;
    }


    // Check for errors
    //     - Is the block already a part of a free block?
    //         - Does curr include part of it?
    //         - Does next include part of it?


    // Check for errors.. See if the block is already a member of the 
    // current block (make sure the current block isn't the head of
    // the list). 
    top = curr->mlen + (unsigned)curr; // The top of the current block
    if ((curr != &(pptr->vmemlist)) && (top > (unsigned)block)) {
        restore(ps);
        return SYSERR;
    }

    // Check for errors.. See if the block is a member of the next
    // block
    if ((next != NULL) && ((size + (unsigned)block) > (unsigned)next)) {
        restore(ps);
        return(SYSERR);
    }

    // Is the top of the current block equal to the start of the
    // block that is being freed? If so then just make the current
    // free block bigger (adjust mlen).
    if ((curr != &(pptr->vmemlist)) && (top == (unsigned)block)) {
            curr->mlen += size;

    // If not then create a new block and add it to the list.
    } else {
        block->mlen = size;
        block->mnext = next;
        curr->mnext = block;
        curr = block;
    }


    // We may now be able to merge this block with the next block
    // if they are now right next to one another. 
    if ((unsigned)(curr->mlen + (unsigned)curr) == (unsigned)next) {
        curr->mlen += next->mlen;
        curr->mnext = next->mnext;
    }

    restore(ps);
    return(OK);
}
Ejemplo n.º 29
0
/*------------------------------------------------------------------------
 *  sysinit  --  initialize all Xinu data structeres and devices
 *------------------------------------------------------------------------
 */
LOCAL
sysinit()
{
	static	long	currsp;
	int	i,j;
	struct	pentry	*pptr;
	struct	sentry	*sptr;
	struct	mblock	*mptr;

	numproc = 0;			/* initialize system variables */
	nextproc = NPROC-1;
	nextsem = NSEM-1;
	nextqueue = NPROC;		/* q[0..NPROC-1] are processes */

#ifdef X__COM32__
	puts_com32("sysinit()\n");
#endif
	
#ifdef __COM32__
	/* initialize free memory list */
	kprintf("com32topmem %d\n", (unsigned long) com32topmem);
	com32topmem = com32topmem - 1024*64; /* !!! we need some space fort this code */
	maxaddr =  (char*) com32topmem;
	kprintf("maxaddr     %d\n", (unsigned long) maxaddr);
	memlist.mnext = mptr = (struct mblock *) roundmb(&end);
	mptr->mnext = 0;
	mptr->mlen = (int) truncew((unsigned)maxaddr - (int)&end -
			NULLSTK);
#else
	/* initialize free memory list */
	/* PC version has to pre-allocate 640K-1024K "hole" */
	if (maxaddr+1 > HOLESTART) {
		memlist.mnext = mptr = (struct mblock *) roundmb(&end);
		mptr->mnext = (struct mblock *)HOLEEND;
		mptr->mlen = (int) truncew((unsigned) HOLESTART -
	     		 (unsigned)&end - 4);

		mptr = (struct mblock *) HOLEEND;
		mptr->mnext = 0;
		mptr->mlen = (int) truncew(maxaddr - HOLEEND - NULLSTK);
	} else {
		/* initialize free memory list */
		memlist.mnext = mptr = (struct mblock *) roundmb(&end);
		mptr->mnext = 0;
		mptr->mlen = (int) truncew((unsigned)maxaddr - (int)&end -
			NULLSTK);
	}
#endif
	
#ifdef X__COM32__
	puts_com32("sysinit() free memory list done\n");
#endif
	
	for (i=0 ; i<NPROC ; i++)	/* initialize process table */
		proctab[i].pstate = PRFREE;

#ifdef X__COM32__
	puts_com32("sysinit() proctab done\n");
#endif
	
	pptr = &proctab[NULLPROC];	/* initialize null process entry */
	pptr->pstate = PRCURR;
	for (j=0; j<7; j++)
		pptr->pname[j] = "prnull"[j];
	pptr->plimit = (WORD)(maxaddr + 1) - NULLSTK;
	pptr->pbase = (WORD) maxaddr - 3;
	pptr->pesp = pptr->pbase-4;	/* for stkchk; rewritten before used */
	*( (int *)pptr->pbase ) = MAGIC;
	pptr->paddr = (WORD) nulluser;
	pptr->pargs = 0;
	pptr->pprio = 0;
	currpid = NULLPROC;

	for (i=0 ; i<NSEM ; i++) {	/* initialize semaphores */
		(sptr = &semaph[i])->sstate = SFREE;
		sptr->sqtail = 1 + (sptr->sqhead = newqueue());
	}

	rdytail = 1 + (rdyhead=newqueue());/* initialize ready list */

#ifdef X__COM32__
	puts_com32("sysinit() semaphores done\n");
#endif
	
#ifdef	MEMMARK
	_mkinit();			/* initialize memory marking */
#ifdef __COM32__
	puts_com32("sysinit()  memory marking done\n");
#endif
#endif

#ifdef	RTCLOCK
	clkinit();			/* initialize r.t.clock	*/
#ifdef __COM32__
	puts_com32("sysinit() rtc done\n");
#endif
#endif

#ifdef NDEVS
	for ( i=0 ; i<NDEVS ; i++ ) {
	    init(i);
	}
#ifdef __COM32__
	puts_com32("sysinit() devs done\n");
#endif	
#endif

#ifdef	NNETS
	netinit();
#ifdef __COM32__
	puts_com32("sysinit() netinit() done\n");
#endif
#endif

	return(OK);
}
Ejemplo n.º 30
-1
/*------------------------------------------------------------------------
 * getmem  --  allocate heap storage, returning lowest WORD address
 *------------------------------------------------------------------------
 */
WORD *vgetmem(unsigned nbytes)
{
	STATWORD ps;    
	struct	mblock	*p, *q, *leftover;

	disable(ps);
	if (nbytes==0 || memlist.mnext== (struct mblock *) NULL) {
		restore(ps);
		return( (WORD *)SYSERR);
	}
	nbytes = (unsigned int) roundmb(nbytes);
	for (q= &memlist,p=memlist.mnext ;
	     p != (struct mblock *) NULL ;
	     q=p,p=p->mnext)
		if ( p->mlen == nbytes) {
			q->mnext = p->mnext;
			restore(ps);
			return( (WORD *)p );
		} else if ( p->mlen > nbytes ) {
			leftover = (struct mblock *)( (unsigned)p + nbytes );
			q->mnext = leftover;
			leftover->mnext = p->mnext;
			leftover->mlen = p->mlen - nbytes;
			restore(ps);
			return( (WORD *)p );
		}
	restore(ps);
	return( (WORD *)SYSERR );
}