⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vm.c

📁 pebble
💻 C
字号:
/* 
 * Copyright 1999, 2000, 2001, 2002 Lucent Technologies Inc.
 * All Rights Reserved.
 * Information Sciences Research Center, Bell Labs.
 *
 * LUCENT TECHNOLOGIES DOES NOT CLAIM MERCHANTABILITY OF THIS SOFTWARE 
 * OR THE SUITABILITY OF THIS SOFTWARE FOR ANY PARTICULAR PURPOSE. The
 * software is provided "as is" without expressed or implied warranty 
 * of any kind.
 *
 * These notices must be retained in any copies of any part of this
 * software.
 *
 */

#include "unistd.h"
#include "types.h"
#include "pebble.h"
#include "machine/cpu.h"
#include "diag.h"
#include "time.h"
#include "nucleus.h"

typedef struct {
	int *base;
} mobj;

mobj *create_mobj(size_t, int);

#define	vm_map(x, client) \
		  call_portal(SYS_VM_MAP, (x), (client))
#define vm_protect(x, client, y) \
		  call_portal(SYS_VM_PROTECT, (x), (client), (y))
#define vm_allocate(x, client) \
		  call_portal(SYS_VM_ALLOCATE, (x), (client))

/*
 * Fault handlers that the VM server will install in the clients'
 * portal tables.
 *
 * pagefault: Handles TLBL, TLBS exceptions. It backs the virtual page
 *	      by a physical frame. Additionally, it write-protects the
 *	      page if it is in a range with transactional semantics.
 * protectionfault: Handles MOD exception.
 */

Time start, elapsed;
uint elapsedcount;

static void pagefault(Thread *t, int asid, int switched_stack,
       char *badvirt)
{
	/* Got page fault. Need to find out what memory object backs
	 * this vaddr, then decide how to back it up.
	 * For now, just allocate a physical page and update the pte.
	 */
	start = hrtime();
	vm_map(badvirt, asid);
	elapsed = 2 * (hrtime() - start);
	if (VM_DIAG)
		printf("map: %d cycles\n", (int)elapsed);

	/* Write-protect the page - should only be done when in
	 * transactional range XXX
	 */
	start = hrtime();
	get_thread();
	elapsed = 2 * (hrtime() - start);
	if (VM_DIAG)
		printf("null: %d cycles\n", (int)elapsed);

	start = hrtime();
	vm_protect(badvirt, asid, 1);
	elapsed = 2 * (hrtime() - start);
	if (VM_DIAG)
		printf("mprotect: %d cycles\n", (int)elapsed);

	return;
}

static void protectionfault(Thread *t, int asid, int switched_stack,
       char *badvirt) 
{
	/*
	 * Got write protection fault.
	 */
	elapsedcount = get_count();
	elapsed = hrtime();
	if (VM_DIAG)
		printf("elapsed = %u %u, elapsedcount = %d\n",
		(uint)(elapsed>>32), (uint)elapsed, elapsedcount);

	/* Write-enable the page
	 *
	 * This should be the first time a client tries to modify this
	 * page. A write lock should be acquired on the page so that
	 * no other transaction can modify it before this one commits
	 * or aborts.
	 *
	 * At this point, we should either copy the page to a shadow
	 * page, or write it to the log. In both cases, we are
	 * preparing for undo action in a possible abort (due to
	 * explicit action, or recovery after failure)
	 */
	vm_protect(badvirt, asid, 0);

	return;
}

/*
 * Triggered by a low watermark on free physical frames, it
 * can propose an alternative victim for replacement.
 *
 * If the page to be evicted is dirty after being modified by
 * an ongoing transaction, the undo log record will need to be
 * flushed to disk before the frame is written to the stable
 * database.
 */

static int pageout(char *victim)
{
	 return (int)NULL;
}

static int transmem(int asid, int size)
{
	int *mem;

	printf("Creating transactional memory segment of size %d for"
		       " domain %d\n", size, asid);

	/* In response to client request for memory segment with
	 * transactional semantics, the VM server will install fault
	 * handlers to the client portal table.
	 *
	 * Hence, when the client is causing a page or protection
	 * fault, it will be the VM server that handles it.
	 */

	/* note: register A2 is != 0 if portal code switched stacks */
	if (portal_create(EXC_MOD, "eftai", 0, (Func) protectionfault, 1) < 0)
		panic("portal_create_excpt for intr_dispatcher failed\n");

	/* note: register A2 is != 0 if portal code switched stacks */
	if (portal_create(EXC_TLBL, "eftaii", 0, (Func) pagefault, 1) < 0)
		panic("portal_create_excpt for intr_dispatcher failed\n");

	/* note: register A2 is != 0 if portal code switched stacks */
	if (portal_create(EXC_TLBS, "eftaii", 0, (Func) pagefault, 1) < 0)
		panic("portal_create_excpt for intr_dispatcher failed\n");

	printf("Portals created okay\n");

	mem = (int *)vm_allocate(size, asid);

	return (int)mem;
}

/* Need interface to physical memory, still */

int
main(int arg, char *argv[])
{
	/* verify that we are running in user mode with interrupts enabled */
	if (!check_psw(1,1)) {
		printf("idle: invalid processor status: %08lx\n", get_psw());
		task_exit(1);
	}

	printf("Transactional memory server (id %d) is active.\n",
		get_asid());

	if (portal_create(SYS_TRANSMEM, "spai", 0, (Func) transmem, 0)
	   < 0) {
		panic("portal_create failed for transactional memory\n");
	}

	if (portal_create(SYS_TRANSPAGEOUT, "spai", 0, (Func) pageout, 0)
	   < 0) {
		panic("portal_create failed for transactional memory pageout\n");
	}

	/*
	 * return to initialization code.
	 * cannot just "return", since the startup code (crt0.S) calls
	 * exit when main routine terminates.
	 */
	call_portal(SYS_RTN_RPC);
	return(1);
}

/* Things I need to do with memory objects
 *
 * a. Create a memory object of a certain size. Demand-paged, it is
 *    backed by a cache of physical pages.
 * b. Map a memory object to a virtual address range.
 *
 */

mobj *create_mobj(size_t size, int client_asid)
{
	mobj *m = (mobj *) malloc(sizeof(mobj));

	m->base = (int *) vm_allocate(size, client_asid);

	return m;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -