Ejemplo n.º 1
0
int main(void)
{
	unsigned int va;
	unsigned int stack_addr = (unsigned int) &va & ~(PAGE_SIZE - 1);

	// Map code & data
	for (va = 0; va < 0x10000; va += PAGE_SIZE)
	{
		add_itlb_mapping(va, va);
		add_dtlb_mapping(va, va | TLB_WRITABLE);
	}

	add_dtlb_mapping(stack_addr, stack_addr | TLB_WRITABLE);
	add_dtlb_mapping(IO_REGION_BASE, IO_REGION_BASE | TLB_WRITABLE);

	// Enable MMU and disable supervisor mode in flags register
	__builtin_nyuzi_write_control_reg(CR_FAULT_HANDLER, general_fault_handler);
	__builtin_nyuzi_write_control_reg(CR_TLB_MISS_HANDLER, tlb_fault_handler);
	__builtin_nyuzi_write_control_reg(CR_FLAGS, FLAG_MMU_EN);

	// This will fault because the thread is in user mode. Then the general
	// fault handler will read the address to ensure the mapping wasn't inserted.
	// That should cause a TLB fault.
	add_dtlb_mapping(data, ((unsigned int)data) | TLB_WRITABLE);
	// CHECK: general fault 10
	// CHECK: TLB fault 

	printf("FAIL: executed instruction\n");
}
Ejemplo n.º 2
0
int main(void)
{
	unsigned int va;
	unsigned int stack_addr = (unsigned int) &va & ~(PAGE_SIZE - 1);

	// Map code & data
	for (va = 0; va < 0x10000; va += PAGE_SIZE)
	{
		add_itlb_mapping(va, va);
		add_dtlb_mapping(va, va | TLB_WRITABLE);
	}

	add_dtlb_mapping(stack_addr, stack_addr | TLB_WRITABLE);
	add_dtlb_mapping(IO_REGION_BASE, IO_REGION_BASE | TLB_WRITABLE);

	// A data region. Enter a few bogus mapping first, then the proper
	// one, which should replace them.
	add_dtlb_mapping(data_addr, 0x101000 | TLB_WRITABLE);
	add_dtlb_mapping(data_addr, 0x102000 | TLB_WRITABLE);
	add_dtlb_mapping(data_addr, 0x103000 | TLB_WRITABLE);
	add_dtlb_mapping(data_addr, 0x104000 | TLB_WRITABLE);
	add_dtlb_mapping(data_addr, ((unsigned int) data_addr) | TLB_WRITABLE);

	// Enable MMU in flags register
	__builtin_nyuzi_write_control_reg(CR_TLB_MISS_HANDLER, tlb_miss_handler);
	__builtin_nyuzi_write_control_reg(CR_FLAGS, FLAG_MMU_EN | FLAG_SUPERVISOR_EN);

	*data_addr = 0x1f6818aa;
	printf("data value %08x\n", *data_addr); // CHECK: data value 1f6818aa

	return 0;
}
Ejemplo n.º 3
0
int main(void)
{
    unsigned int va;
    int asid;
    unsigned int stack_addr = (unsigned int) &va & ~(PAGE_SIZE - 1);

    // Map code & data
    for (va = 0; va < 0x10000; va += PAGE_SIZE)
    {
        add_itlb_mapping(va, va | TLB_GLOBAL | TLB_EXECUTABLE | TLB_PRESENT);
        add_dtlb_mapping(va, va | TLB_WRITABLE | TLB_GLOBAL | TLB_PRESENT);
    }

    add_dtlb_mapping(stack_addr, stack_addr | TLB_WRITABLE | TLB_GLOBAL
                     | TLB_PRESENT);
    add_dtlb_mapping(IO_REGION_BASE, IO_REGION_BASE | TLB_WRITABLE
                     | TLB_GLOBAL | TLB_PRESENT);

    // Map a private page into address space 1
    set_asid(1);
    add_dtlb_mapping(VADDR1, PADDR1 | TLB_PRESENT);
    *((unsigned int*) PADDR1) = 0xdeadbeef;

    // Map a private page into address space 2
    set_asid(2);
    add_dtlb_mapping(VADDR1, PADDR2 | TLB_PRESENT);
    *((unsigned int*) PADDR2) = 0xabcdefed;

    // Enable MMU in flags register
    __builtin_nyuzi_write_control_reg(CR_FAULT_HANDLER, fault_handler);
    __builtin_nyuzi_write_control_reg(CR_TLB_MISS_HANDLER, fault_handler);
    __builtin_nyuzi_write_control_reg(CR_FLAGS, FLAG_MMU_EN | FLAG_SUPERVISOR_EN);

    // Read value from first address space
    set_asid(1);
    printf("A1 %08x\n", *((volatile unsigned int*) VADDR1)); // CHECK: A1 deadbeef

    // Read value from the second address space
    set_asid(2);
    printf("A2 %08x\n", *((volatile unsigned int*) VADDR1)); // CHECK: A2 abcdefed

    return 0;
}
Ejemplo n.º 4
0
int main(void)
{
    unsigned int va;
    unsigned int stack_addr = (unsigned int) &va & ~(PAGE_SIZE - 1);

    // Map code & data
    for (va = 0; va < 0x10000; va += PAGE_SIZE)
    {
        add_itlb_mapping(va, va | TLB_GLOBAL);
        add_dtlb_mapping(va, va | TLB_WRITABLE | TLB_GLOBAL);
    }

    add_dtlb_mapping(stack_addr, stack_addr | TLB_WRITABLE);
    add_dtlb_mapping(data_addr, ((unsigned int)data_addr) | TLB_WRITABLE);	// Writable
    *data_addr2 = 0x12345678;
    add_dtlb_mapping(data_addr2, data_addr2); // Not writable
    add_dtlb_mapping(IO_REGION_BASE, IO_REGION_BASE | TLB_WRITABLE); // I/O

    // Enable MMU in flags register
    __builtin_nyuzi_write_control_reg(CR_FAULT_HANDLER, fault_handler);
    __builtin_nyuzi_write_control_reg(CR_TLB_MISS_HANDLER, fault_handler);
    __builtin_nyuzi_write_control_reg(CR_FLAGS, FLAG_MMU_EN | FLAG_SUPERVISOR_EN);

    // This should write successfully
    *data_addr = 0x1f6818aa;
    printf("data value %08x\n", *data_addr); // CHECK: data value 1f6818aa

    // Attempt to write to write protected page will fail.
    *data_addr2 = 0xdeadbeef;

    // Ensure two things:
    // - that a fault is raised
    // - that the value isn't actually written
    // CHECK: FAULT 7 00101000
    // CHECK: data value = 12345678

    printf("should_not_be_here\n"); // CHECKN: should_not_be_here

    return 0;
}
int main(void)
{
	unsigned int va;
	int asid;
	unsigned int stack_addr = (unsigned int) &va & ~(PAGE_SIZE - 1);

	// Map code & data
	for (va = 0; va < 0x10000; va += PAGE_SIZE)
	{
		add_itlb_mapping(va, va);
		add_dtlb_mapping(va, va | TLB_WRITABLE | TLB_GLOBAL);
	}

	add_dtlb_mapping(stack_addr, stack_addr | TLB_WRITABLE);
	add_dtlb_mapping(IO_REGION_BASE, IO_REGION_BASE | TLB_SUPERVISOR | TLB_WRITABLE);

	// Alias mapping that we will use for test (the normal mapped region is used
	// to halt the test).
	add_dtlb_mapping(0x100000, IO_REGION_BASE | TLB_SUPERVISOR | TLB_WRITABLE);
	
	__builtin_nyuzi_write_control_reg(CR_FAULT_HANDLER, fault_handler);
	__builtin_nyuzi_write_control_reg(CR_FLAGS, FLAG_MMU_EN | FLAG_SUPERVISOR_EN);

	// Can write to page in supervisor mode
	globaltmp = *((volatile unsigned int*) 0x100000);
	printf("check1\n");
	// CHECK: check1

	// Switch to user mode, but leave MMU active
	switch_to_user_mode();

	*((volatile unsigned int*) 0x100000) = 0x12;
	// CHECK: FAULT 8 00100000 current flags 06 prev flags 02
	
	// XXX no way to verify that the write wasn't sent to external bus
}