示例#1
0
static void pt_release_pml4(pte_t *pml4, virt_t from, virt_t to)
{
	virt_t vaddr = from;

	for (int i = pml4_i(from); vaddr != to; ++i) {
		const pte_t pte = pml4[i];
		const virt_t bytes =
			MINU(PML3_SIZE - (vaddr & PML3_MASK), to - vaddr);
		const pfn_t pages = bytes >> PAGE_BITS;

		if (pte_present(pte)) {
			const phys_t paddr = pte_phys(pte);
			const pfn_t pfn = paddr >> PAGE_BITS;
			struct page *pt = pfn2page(pfn);

			pt_release_pml3(va(paddr), vaddr, vaddr + bytes);
			pt->u.refcount -= pages;

			if (pt->u.refcount == 0) {
				pml4[i] = 0;
				free_page_table(pt);
			}
		}
		vaddr += bytes;	
	}
}
示例#2
0
static int pt_populate_pml2(pte_t *pml2, virt_t from, virt_t to, pte_t flags)
{
	virt_t vaddr = from;

	for (int i = pml2_i(from); vaddr != to; ++i) {
		const virt_t bytes =
			MINU(PML1_SIZE - (vaddr & PML1_MASK), to - vaddr);
		const pfn_t pages = bytes >> PAGE_BITS;

		if (!pte_present(pml2[i]) && !pte_large(flags)) {
			struct page *pt = alloc_page_table(flags);

			if (!pt) {
				pt_release_pml2(pml2, from, vaddr);
				return -ENOMEM;
			}

			pt->u.refcount += pages;
			pml2[i] = page_paddr(pt) | flags;
		} else if (pte_present(pml2[i]) && !pte_large(pml2[i])) {
			const pfn_t pfn = pte_phys(pml2[i]) >> PAGE_BITS;
			struct page *pt = pfn2page(pfn);

			pt->u.refcount += pages;
		}
		vaddr += bytes;
	}

	return 0;
}
示例#3
0
size_t cbuffer_advance(struct cbuffer *buffer, size_t size)
{
	const size_t to_advance = MINU(size, buffer->len);

	buffer->read += to_advance;
	if (buffer->read >= buffer->size)
		buffer->read -= buffer->size;
	buffer->len -= to_advance;
	return to_advance;
}
示例#4
0
static void vsinkprintf_buffer_write(struct vsinkprintf_sink *sink,
			const char *data, size_t size)
{
	struct vsinkprintf_buffer_sink *buf =
		(struct vsinkprintf_buffer_sink *)sink;

	const int remain = MAX(buf->size - 1 - buf->pos, 0);

	if (remain)
		memcpy(buf->data + buf->pos, data, MINU(remain, size));
	buf->pos += size;
}
示例#5
0
ssize_t cbuffer_fill(struct cbuffer *buffer, int fd)
{
	const size_t write = buffer->read + buffer->len;
	const size_t to_end = buffer->size - write;
	const size_t to_read = MINU(buffer->size - buffer->len, to_end);

	ssize_t ret = read(fd, buffer->buf + write, to_read);

	if (ret > 0)
		buffer->len += ret;
	return ret;
}
示例#6
0
static int pt_populate_pml4(pte_t *pml4, virt_t from, virt_t to, pte_t flags)
{
	virt_t vaddr = from;

	for (int i = pml4_i(from); vaddr < to; ++i) {
		struct page *pt;
		phys_t paddr;
		const virt_t bytes =
			MINU(PML3_SIZE - (vaddr & PML3_MASK), to - vaddr);
		const pfn_t pages = bytes >> PAGE_BITS;

		if (!pte_present(pml4[i])) {
			pt = alloc_page_table(flags);

			if (!pt) {
				pt_release_pml4(pml4, from, vaddr);
				return -ENOMEM;
			}

			paddr = page_paddr(pt);
			pml4[i] = paddr | (flags & ~PTE_LARGE);
		} else {
			const pte_t pte = pml4[i];

			paddr = pte_phys(pte);
			pt = pfn2page(paddr >> PAGE_BITS);
		}
		pt->u.refcount += pages;

		const int rc = pt_populate_pml3(va(paddr), vaddr, vaddr + bytes,
					flags);

		if (rc) {
			pt_release_pml4(pml4, from, vaddr);
			pt->u.refcount -= pages;

			if (pt->u.refcount == 0) {
				pml4[i] = 0;
				free_page_table(pt);
			}

			return rc;
		}

		vaddr += bytes;
	}

	return 0;
}
示例#7
0
static bool readdir_next_entry(struct dir_iter_ctx *ctx, const char *name,
			size_t len)
{
	struct readdir_ctx *rdctx = (struct readdir_ctx *)ctx;
	struct dirent *entries = rdctx->entries;
	size_t count = rdctx->count;
	size_t pos = rdctx->pos;

	if (pos != count) {
		memset(entries[pos].name, 0, MAX_PATH_LEN);
		strncpy(entries[pos].name, name, MINU(MAX_PATH_LEN - 1, len));
		++rdctx->pos;
		return true;
	}
	return false;
}
示例#8
0
void memory_free_region(unsigned long long addr, unsigned long long size)
{
	const unsigned long long begin = ALIGN(addr, PAGE_SIZE);
	const unsigned long long end = MINU(ALIGN_DOWN(addr + size, PAGE_SIZE),
				MAX_PHYS_SIZE);

	if (begin >= end)
		return;

	if (begin < LOWMEM_SIZE && end > LOWMEM_SIZE) {
		__memory_free_region(begin, LOWMEM_SIZE);
		__memory_free_region(LOWMEM_SIZE, end);
	} else {
		__memory_free_region(begin, end);
	}
}
示例#9
0
size_t cbuffer_read(struct cbuffer *buffer, void *d, size_t size)
{
	const size_t to_read = MINU(size, buffer->len);
	const size_t to_end = buffer->size - buffer->read;
	char *dst = d;

	if (!to_read)
		return 0;

	if (to_end >= to_read) {
		memcpy(dst, buffer->buf + buffer->read, to_read);
	} else {
		memcpy(dst, buffer->buf + buffer->read, to_end);
		memcpy(dst + to_end, buffer->buf, to_read - to_end);
	}
	return to_read;
}
示例#10
0
static void memory_node_add(unsigned long long addr, unsigned long long size)
{
	const unsigned long long begin = ALIGN(addr, PAGE_SIZE);
	const unsigned long long end = MINU(ALIGN_DOWN(addr + size, PAGE_SIZE),
				MAX_PHYS_SIZE);

	if (begin >= end)
		return;

	if (begin < LOWMEM_SIZE && end > LOWMEM_SIZE) {
		__memory_node_add(NT_LOW, begin, LOWMEM_SIZE);
		__memory_node_add(NT_HIGH, LOWMEM_SIZE, end);
	} else {
		const enum node_type type = (end <= LOWMEM_SIZE)
					? NT_LOW : NT_HIGH;

		__memory_node_add(type, begin, end);
	}
}
示例#11
0
size_t cbuffer_write(struct cbuffer *buffer, const void *s, size_t size)
{
	const size_t to_write = MINU(buffer->size - buffer->len, size);
	size_t write = buffer->read + buffer->len;
	const char *src = s;

	if (write >= buffer->size)
		write -= buffer->size;

	const size_t to_end = buffer->size - write;

	if (!to_write)
		return 0;

	if (to_end >= to_write) {
		memcpy(buffer->buf + write, src, to_write);
	} else {
		memcpy(buffer->buf + write, src, to_end);
		memcpy(buffer->buf, src + to_end, to_write - to_end);
	}
	buffer->len += to_write;
	return to_write;
}
示例#12
0
/* Process 3OP Integer instructions */
bool eval_3OP_Int(struct lilith* vm, struct Instruction* c)
{
	#ifdef DEBUG
	char Name[20] = "ILLEGAL_3OP";
	#endif

	switch(c->raw_XOP)
	{
		case 0x000: /* ADD */
		{
			#ifdef DEBUG
			strncpy(Name, "ADD", 19);
			#elif TRACE
			record_trace("ADD");
			#endif

			ADD(vm, c);
			break;
		}
		case 0x001: /* ADDU */
		{
			#ifdef DEBUG
			strncpy(Name, "ADDU", 19);
			#elif TRACE
			record_trace("ADDU");
			#endif

			ADDU(vm, c);
			break;
		}
		case 0x002: /* SUB */
		{
			#ifdef DEBUG
			strncpy(Name, "SUB", 19);
			#elif TRACE
			record_trace("SUB");
			#endif

			SUB(vm, c);
			break;
		}
		case 0x003: /* SUBU */
		{
			#ifdef DEBUG
			strncpy(Name, "SUBU", 19);
			#elif TRACE
			record_trace("SUBU");
			#endif

			SUBU(vm, c);
			break;
		}
		case 0x004: /* CMP */
		{
			#ifdef DEBUG
			strncpy(Name, "CMP", 19);
			#elif TRACE
			record_trace("CMP");
			#endif

			CMP(vm, c);
			break;
		}
		case 0x005: /* CMPU */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPU", 19);
			#elif TRACE
			record_trace("CMPU");
			#endif

			CMPU(vm, c);
			break;
		}
		case 0x006: /* MUL */
		{
			#ifdef DEBUG
			strncpy(Name, "MUL", 19);
			#elif TRACE
			record_trace("MUL");
			#endif

			MUL(vm, c);
			break;
		}
		case 0x007: /* MULH */
		{
			#ifdef DEBUG
			strncpy(Name, "MULH", 19);
			#elif TRACE
			record_trace("MULH");
			#endif

			MULH(vm, c);
			break;
		}
		case 0x008: /* MULU */
		{
			#ifdef DEBUG
			strncpy(Name, "MULU", 19);
			#elif TRACE
			record_trace("MULU");
			#endif

			MULU(vm, c);
			break;
		}
		case 0x009: /* MULUH */
		{
			#ifdef DEBUG
			strncpy(Name, "MULUH", 19);
			#elif TRACE
			record_trace("MULUH");
			#endif

			MULUH(vm, c);
			break;
		}
		case 0x00A: /* DIV */
		{
			#ifdef DEBUG
			strncpy(Name, "DIV", 19);
			#elif TRACE
			record_trace("DIV");
			#endif

			DIV(vm, c);
			break;
		}
		case 0x00B: /* MOD */
		{
			#ifdef DEBUG
			strncpy(Name, "MOD", 19);
			#elif TRACE
			record_trace("MOD");
			#endif

			MOD(vm, c);
			break;
		}
		case 0x00C: /* DIVU */
		{
			#ifdef DEBUG
			strncpy(Name, "DIVU", 19);
			#elif TRACE
			record_trace("DIVU");
			#endif

			DIVU(vm, c);
			break;
		}
		case 0x00D: /* MODU */
		{
			#ifdef DEBUG
			strncpy(Name, "MODU", 19);
			#elif TRACE
			record_trace("MODU");
			#endif

			MODU(vm, c);
			break;
		}
		case 0x010: /* MAX */
		{
			#ifdef DEBUG
			strncpy(Name, "MAX", 19);
			#elif TRACE
			record_trace("MAX");
			#endif

			MAX(vm, c);
			break;
		}
		case 0x011: /* MAXU */
		{
			#ifdef DEBUG
			strncpy(Name, "MAXU", 19);
			#elif TRACE
			record_trace("MAXU");
			#endif

			MAXU(vm, c);
			break;
		}
		case 0x012: /* MIN */
		{
			#ifdef DEBUG
			strncpy(Name, "MIN", 19);
			#elif TRACE
			record_trace("MIN");
			#endif

			MIN(vm, c);
			break;
		}
		case 0x013: /* MINU */
		{
			#ifdef DEBUG
			strncpy(Name, "MINU", 19);
			#elif TRACE
			record_trace("MINU");
			#endif

			MINU(vm, c);
			break;
		}
		case 0x014: /* PACK */
		case 0x015: /* UNPACK */
		case 0x016: /* PACK8.CO */
		case 0x017: /* PACK8U.CO */
		case 0x018: /* PACK16.CO */
		case 0x019: /* PACK16U.CO */
		case 0x01A: /* PACK32.CO */
		case 0x01B: /* PACK32U.CO */
		{
			illegal_instruction(vm, c);
			break;
		}
		case 0x020: /* AND */
		{
			#ifdef DEBUG
			strncpy(Name, "AND", 19);
			#elif TRACE
			record_trace("AND");
			#endif

			AND(vm, c);
			break;
		}
		case 0x021: /* OR */
		{
			#ifdef DEBUG
			strncpy(Name, "OR", 19);
			#elif TRACE
			record_trace("OR");
			#endif

			OR(vm, c);
			break;
		}
		case 0x022: /* XOR */
		{
			#ifdef DEBUG
			strncpy(Name, "XOR", 19);
			#elif TRACE
			record_trace("XOR");
			#endif

			XOR(vm, c);
			break;
		}
		case 0x023: /* NAND */
		{
			#ifdef DEBUG
			strncpy(Name, "NAND", 19);
			#elif TRACE
			record_trace("NAND");
			#endif

			NAND(vm, c);
			break;
		}
		case 0x024: /* NOR */
		{
			#ifdef DEBUG
			strncpy(Name, "NOR", 19);
			#elif TRACE
			record_trace("NOR");
			#endif

			NOR(vm, c);
			break;
		}
		case 0x025: /* XNOR */
		{
			#ifdef DEBUG
			strncpy(Name, "XNOR", 19);
			#elif TRACE
			record_trace("XNOR");
			#endif

			XNOR(vm, c);
			break;
		}
		case 0x026: /* MPQ */
		{
			#ifdef DEBUG
			strncpy(Name, "MPQ", 19);
			#elif TRACE
			record_trace("MPQ");
			#endif

			MPQ(vm, c);
			break;
		}
		case 0x027: /* LPQ */
		{
			#ifdef DEBUG
			strncpy(Name, "LPQ", 19);
			#elif TRACE
			record_trace("LPQ");
			#endif

			LPQ(vm, c);
			break;
		}
		case 0x028: /* CPQ */
		{
			#ifdef DEBUG
			strncpy(Name, "CPQ", 19);
			#elif TRACE
			record_trace("CPQ");
			#endif

			CPQ(vm, c);
			break;
		}
		case 0x029: /* BPQ */
		{
			#ifdef DEBUG
			strncpy(Name, "BPQ", 19);
			#elif TRACE
			record_trace("BPQ");
			#endif

			BPQ(vm, c);
			break;
		}
		case 0x030: /* SAL */
		{
			#ifdef DEBUG
			strncpy(Name, "SAL", 19);
			#elif TRACE
			record_trace("SAL");
			#endif

			SAL(vm, c);
			break;
		}
		case 0x031: /* SAR */
		{
			#ifdef DEBUG
			strncpy(Name, "SAR", 19);
			#elif TRACE
			record_trace("SAR");
			#endif

			SAR(vm, c);
			break;
		}
		case 0x032: /* SL0 */
		{
			#ifdef DEBUG
			strncpy(Name, "SL0", 19);
			#elif TRACE
			record_trace("SL0");
			#endif

			SL0(vm, c);
			break;
		}
		case 0x033: /* SR0 */
		{
			#ifdef DEBUG
			strncpy(Name, "SR0", 19);
			#elif TRACE
			record_trace("SR0");
			#endif

			SR0(vm, c);
			break;
		}
		case 0x034: /* SL1 */
		{
			#ifdef DEBUG
			strncpy(Name, "SL1", 19);
			#elif TRACE
			record_trace("SL1");
			#endif

			SL1(vm, c);
			break;
		}
		case 0x035: /* SR1 */
		{
			#ifdef DEBUG
			strncpy(Name, "SR1", 19);
			#elif TRACE
			record_trace("SR1");
			#endif

			SR1(vm, c);
			break;
		}
		case 0x036: /* ROL */
		{
			#ifdef DEBUG
			strncpy(Name, "ROL", 19);
			#elif TRACE
			record_trace("ROL");
			#endif

			ROL(vm, c);
			break;
		}
		case 0x037: /* ROR */
		{
			#ifdef DEBUG
			strncpy(Name, "ROR", 19);
			#elif TRACE
			record_trace("ROR");
			#endif

			ROR(vm, c);
			break;
		}
		case 0x038: /* LOADX */
		{
			#ifdef DEBUG
			strncpy(Name, "LOADX", 19);
			#elif TRACE
			record_trace("LOADX");
			#endif

			LOADX(vm, c);
			break;
		}
		case 0x039: /* LOADX8 */
		{
			#ifdef DEBUG
			strncpy(Name, "LOADX8", 19);
			#elif TRACE
			record_trace("LOADX8");
			#endif

			LOADX8(vm, c);
			break;
		}
		case 0x03A: /* LOADXU8 */
		{
			#ifdef DEBUG
			strncpy(Name, "LOADXU8", 19);
			#elif TRACE
			record_trace("LOADXU8");
			#endif

			LOADXU8(vm, c);
			break;
		}
		case 0x03B: /* LOADX16 */
		{
			#ifdef DEBUG
			strncpy(Name, "LOADX16", 19);
			#elif TRACE
			record_trace("LOADX16");
			#endif

			LOADX16(vm, c);
			break;
		}
		case 0x03C: /* LOADXU16 */
		{
			#ifdef DEBUG
			strncpy(Name, "LOADXU16", 19);
			#elif TRACE
			record_trace("LOADXU16");
			#endif

			LOADXU16(vm, c);
			break;
		}
		case 0x03D: /* LOADX32 */
		{
			#ifdef DEBUG
			strncpy(Name, "LOADX32", 19);
			#elif TRACE
			record_trace("LOADX32");
			#endif

			LOADX32(vm, c);
			break;
		}
		case 0x03E: /* LOADXU32 */
		{
			#ifdef DEBUG
			strncpy(Name, "LOADXU32", 19);
			#elif TRACE
			record_trace("LOADXU32");
			#endif

			LOADXU32(vm, c);
			break;
		}
		case 0x048: /* STOREX */
		{
			#ifdef DEBUG
			strncpy(Name, "STOREX", 19);
			#elif TRACE
			record_trace("STOREX");
			#endif

			STOREX(vm, c);
			break;
		}
		case 0x049: /* STOREX8 */
		{
			#ifdef DEBUG
			strncpy(Name, "STOREX8", 19);
			#elif TRACE
			record_trace("STOREX8");
			#endif

			STOREX8(vm, c);
			break;
		}
		case 0x04A: /* STOREX16 */
		{
			#ifdef DEBUG
			strncpy(Name, "STOREX16", 19);
			#elif TRACE
			record_trace("STOREX16");
			#endif

			STOREX16(vm, c);
			break;
		}
		case 0x04B: /* STOREX32 */
		{
			#ifdef DEBUG
			strncpy(Name, "STOREX32", 19);
			#elif TRACE
			record_trace("STOREX32");
			#endif

			STOREX32(vm, c);
			break;
		}
		case 0x050: /* CMPJUMP.G */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMP.G", 19);
			#elif TRACE
			record_trace("CMPJUMP.G");
			#endif

			CMPJUMP_G(vm, c);
			break;
		}
		case 0x051: /* CMPJUMP.GE */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMP.GE", 19);
			#elif TRACE
			record_trace("CMPJUMP.GE");
			#endif

			CMPJUMP_GE(vm, c);
			break;
		}
		case 0x052: /* CMPJUMP.E */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMP.E", 19);
			#elif TRACE
			record_trace("CMPJUMP.E");
			#endif

			CMPJUMP_E(vm, c);
			break;
		}
		case 0x053: /* CMPJUMP.NE */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMP.NE", 19);
			#elif TRACE
			record_trace("CMPJUMP.NE");
			#endif

			CMPJUMP_NE(vm, c);
			break;
		}
		case 0x054: /* CMPJUMP.LE */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMP.LE", 19);
			#elif TRACE
			record_trace("CMPJUMP.LE");
			#endif

			CMPJUMP_LE(vm, c);
			break;
		}
		case 0x055: /* CMPJUMP.L */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMP.L", 19);
			#elif TRACE
			record_trace("CMPJUMP.L");
			#endif

			CMPJUMP_L(vm, c);
			break;
		}
		case 0x060: /* CMPJUMPU.G */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMPU.G", 19);
			#elif TRACE
			record_trace("CMPJUMPU.G");
			#endif

			CMPJUMPU_G(vm, c);
			break;
		}
		case 0x061: /* CMPJUMPU.GE */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMPU.GE", 19);
			#elif TRACE
			record_trace("CMPJUMPU.GE");
			#endif

			CMPJUMPU_GE(vm, c);
			break;
		}
		case 0x064: /* CMPJUMPU.LE */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMPU.LE", 19);
			#elif TRACE
			record_trace("CMPJUMPU.LE");
			#endif

			CMPJUMPU_LE(vm, c);
			break;
		}
		case 0x065: /* CMPJUMPU.L */
		{
			#ifdef DEBUG
			strncpy(Name, "CMPJUMPU.L", 19);
			#elif TRACE
			record_trace("CMPJUMPU.L");
			#endif

			CMPJUMPU_L(vm, c);
			break;
		}
		default:
		{
			illegal_instruction(vm, c);
			break;
		}
	}
	#ifdef DEBUG
	fprintf(stdout, "# %s reg%u reg%u reg%u\n", Name, c->reg0, c->reg1, c->reg2);
	#endif
	return false;
}