Skip to content
This repository has been archived by the owner on Nov 24, 2021. It is now read-only.

Commit

Permalink
add basic gdb support for aarch64 (#94)
Browse files Browse the repository at this point in the history
following kernel features are required:
- first page table (pl0) is located at a fix address
- unhandled page faults are forwarded to the hypervisor
  • Loading branch information
stlankes committed Jul 21, 2018
1 parent 2319afd commit 748744c
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 26 deletions.
5 changes: 4 additions & 1 deletion arch/aarch64/include/asm/page.h
Expand Up @@ -179,12 +179,15 @@ int page_unmap(size_t viraddr, size_t npages);
int page_set_flags(size_t viraddr, uint32_t npages, int flags);

/** @brief Handler to map on demand pages for the heap
*
* * @param viraddr Virtual address, which triggers the page fault
* * @param pc Instruction pointer, where the handler is triggered
*
* @return
* - 0 on success
* - -EINVAL (-22) on failure.
*/
int page_fault_handler(size_t viraddr);
int page_fault_handler(size_t viraddr, size_t pc);

/** @brief Flush Translation Lookaside Buffer
*/
Expand Down
35 changes: 17 additions & 18 deletions arch/aarch64/kernel/entry.S
Expand Up @@ -127,6 +127,23 @@ host_logical_addr: .quad 0
.global uart_mmio
uart_mmio: .dword 0

.global l0_pgtable
.align 12
l0_pgtable:
.quad l1_pgtable + PT_PT
.space 510*8, 0
.quad l0_pgtable + PT_PT + PT_SELF
l1_pgtable:
.quad l2_pgtable + PT_PT
.space 511*8, 0
l2_pgtable:
.quad l3_pgtable + PT_PT
.space 511*8, 0
l3_pgtable:
.quad 0x00000000 + PT_MEM_CD // map II ports
.quad 0x09000000 + PT_MEM_CD // map QEMU's uart port
.space 510*8, 0

start64:
//mrs x0, s3_1_c15_c3_0 // Read EL1 Configuration Base Address Register

Expand Down Expand Up @@ -572,21 +589,3 @@ END(vector_table)
boot_stack: .skip KERNEL_STACK_SIZE
.global boot_ist
boot_ist: .skip KERNEL_STACK_SIZE


.global l0_pgtable
.align 12
l0_pgtable:
.quad l1_pgtable + PT_PT
.space 510*8, 0
.quad l0_pgtable + PT_PT + PT_SELF
l1_pgtable:
.quad l2_pgtable + PT_PT
.space 511*8, 0
l2_pgtable:
.quad l3_pgtable + PT_PT
.space 511*8, 0
l3_pgtable:
.quad 0x00000000 + PT_MEM_CD // map II ports
.quad 0x09000000 + PT_MEM_CD // map QEMU's uart port
.space 510*8, 0
12 changes: 7 additions & 5 deletions arch/aarch64/kernel/irq.c
Expand Up @@ -274,6 +274,7 @@ void do_sync(void *regs)
uint32_t esr = read_esr();
uint32_t ec = esr >> 26;
uint32_t iss = esr & 0xFFFFFF;
uint64_t pc = get_elr();

/* data abort from lower or current level */
if ((ec == 0b100100) || (ec == 0b100101)) {
Expand All @@ -282,7 +283,7 @@ void do_sync(void *regs)
/* read far_el1 register, which holds the faulting virtual address */
uint64_t far = read_far();

if (page_fault_handler(far) == 0)
if (page_fault_handler(far, pc) == 0)
return;

LOG_ERROR("Unable to handle page fault at 0x%llx\n", far);
Expand All @@ -298,13 +299,14 @@ void do_sync(void *regs)
} else {
LOG_ERROR("Unknown exception\n");
}
} else if (ec == 0x3c) {
LOG_ERROR("Trap to debugger, PC=0x%x\n", pc);
} else {
LOG_ERROR("Unsupported exception class\n");
LOG_ERROR("Unsupported exception class: 0x%x, PC=0x%x\n", ec, pc);
}

while (1) {
HALT;
}
sys_exit(-EFAULT);

}

size_t** do_fiq(void *regs)
Expand Down
17 changes: 16 additions & 1 deletion arch/aarch64/mm/page.c
Expand Up @@ -44,6 +44,13 @@

#include <asm/irq.h>
#include <asm/page.h>
#include <asm/uhyve.h>

typedef struct {
uint64_t rip;
uint64_t addr;
int success;
} __attribute__ ((packed)) uhyve_pfault_t;

/* Note that linker symbols are not variables, they have no memory
* allocated for maintaining a value, rather their address is their value. */
Expand Down Expand Up @@ -192,7 +199,7 @@ int page_unmap(size_t viraddr, size_t npages)
return 0;
}

int page_fault_handler(size_t viraddr)
int page_fault_handler(size_t viraddr, size_t pc)
{
task_t* task = per_core(current_task);

Expand Down Expand Up @@ -258,6 +265,14 @@ int page_fault_handler(size_t viraddr)
default_handler:
spinlock_irqsave_unlock(&page_lock);

/* indicate unrecoverable page fault to the hypervisor */
uhyve_pfault_t arg = {pc, viraddr, -1};
/*
* In principle, uhyve_send is a function call to the hypervisor.
* => It is safe to pass data, which are stored on the stack.
*/
uhyve_send(UHYVE_PORT_PFAULT, (unsigned)virt_to_phys((size_t)&arg));

return -EINVAL;
}

Expand Down
2 changes: 1 addition & 1 deletion caves
Submodule caves updated from 155b31 to f19613
2 changes: 2 additions & 0 deletions include/hermit/stddef.h
Expand Up @@ -66,6 +66,8 @@ extern size_t image_size;
#define UHYVE_PORT_EXIT 0x540
#define UHYVE_PORT_LSEEK 0x580

#define UHYVE_PORT_PFAULT 0x511

// Networkports
#define UHYVE_PORT_NETINFO 0x600
#define UHYVE_PORT_NETWRITE 0x640
Expand Down

0 comments on commit 748744c

Please sign in to comment.