Bug fixes
Signed-off-by: Daniel Schwyn <daniel.schwyn@inf.ethz.ch>
This commit is contained in:
parent
6d444bf552
commit
a7a01f8ea1
1
.gitignore
vendored
1
.gitignore
vendored
@ -49,3 +49,4 @@ bin/
|
||||
# clang
|
||||
.clang_complete
|
||||
compile_commands.json
|
||||
test-logs
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include <barrelfish_kpi/distcaps.h> // for distcap_state_t
|
||||
#include <barrelfish_kpi/lmp.h> // invoking lmp endpoint requires flags
|
||||
#include <barrelfish_kpi/syscalls.h>
|
||||
#include <barrelfish_kpi/platform.h> // for struct platform info
|
||||
#include <aos/caddr.h>
|
||||
#include <barrelfish_kpi/paging_arch.h>
|
||||
|
||||
@ -241,4 +242,15 @@ static inline errval_t invoke_vnode_inherit(struct capref dest, capaddr_t src,
|
||||
newflags, src_mcn, dst_mcn).error;
|
||||
}
|
||||
|
||||
static inline errval_t invoke_kernel_get_platform_info(struct capref kernel_cap, struct platform_info* pi)
|
||||
{
|
||||
struct sysret sr = cap_invoke2(kernel_cap, KernelCmd_Get_platform, (lvaddr_t)pi);
|
||||
if (err_is_fail(sr.error)) {
|
||||
pi->arch = PI_ARCH_UNKNOWN;
|
||||
pi->platform = PI_PLATFORM_UNKNOWN;
|
||||
}
|
||||
|
||||
return sr.error;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include <aos/static_assert.h>
|
||||
|
||||
enum pi_arch {
|
||||
PI_ARCH_UNKNOWN,
|
||||
PI_ARCH_X86,
|
||||
PI_ARCH_ARMV7A,
|
||||
PI_ARCH_ARMV8A,
|
||||
|
||||
@ -38,6 +38,7 @@ enum debug_message {
|
||||
DEBUG_CREATE_IRQ_SRC_CAP,
|
||||
DEBUG_GET_MDB_SIZE,
|
||||
DEBUG_PRINT_MDB_COUNTERS,
|
||||
DEBUG_GET_PLATFORM_INFO,
|
||||
};
|
||||
|
||||
#endif //BARRELFISH_KPI_SYS_DEBUG_H
|
||||
|
||||
34
include/drivers/pl011.h
Normal file
34
include/drivers/pl011.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2020, ETH Zurich.
|
||||
* Copyright (c) 2022, The University of British Columbia.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is distributed under the terms in the attached LICENSE file.
|
||||
* If you do not find this file, copies can be found by writing to:
|
||||
* ETH Zurich D-INFK, CAB F.78, Universitaetstr 6, CH-8092 Zurich.
|
||||
*/
|
||||
|
||||
#ifndef PL011_H_
|
||||
#define PL011_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <aos/aos.h>
|
||||
|
||||
//#define PL011_DEBUG_ON
|
||||
#if defined(PL011_DEBUG_ON)
|
||||
#define PL011_DEBUG(x...) debug_printf("pl011:" x)
|
||||
#else
|
||||
#define PL011_DEBUG(x...) ((void)0)
|
||||
#endif
|
||||
|
||||
#define PL011_UART0_INT 1
|
||||
|
||||
struct pl011_s;
|
||||
|
||||
errval_t pl011_init(struct pl011_s** s, void *base);
|
||||
errval_t pl011_enable_interrupt(struct pl011_s * s);
|
||||
errval_t pl011_putchar(struct pl011_s* s, char c);
|
||||
errval_t pl011_getchar(struct pl011_s* s, char *c);
|
||||
|
||||
|
||||
#endif
|
||||
37
include/maps/qemu_map.h
Normal file
37
include/maps/qemu_map.h
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* \file
|
||||
* \brief Physical memory map for the QEMU Virt Platform
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2022, The University of British Columbia.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is distributed under the terms in the attached LICENSE file.
|
||||
* If you do not find this file, copies can be found by writing to:
|
||||
* ETH Zurich D-INFK, CAB F.78, Universitaetstrasse 6, CH-8092 Zurich.
|
||||
* Attn: Systems Group.
|
||||
*/
|
||||
|
||||
#ifndef QEMU_MAP_H
|
||||
#define QEMU_MAP_H
|
||||
|
||||
|
||||
#define QEMU_SPI_INTERRUPTS_START 32
|
||||
|
||||
/*
|
||||
* UART
|
||||
*/
|
||||
|
||||
#define QEMU_UART_BASE 0x09000000
|
||||
#define QEMU_UART_SIZE 0x1000
|
||||
#define QEMU_UART_INT (QEMU_SPI_INTERRUPTS_START + PL011_UART0_INT)
|
||||
/*
|
||||
* GIC Distributor
|
||||
*/
|
||||
#define QEMU_GIC_DIST_BASE 0x08000000
|
||||
#define QEMU_GIC_DIST_SIZE 0x1000
|
||||
|
||||
|
||||
|
||||
#endif // QEMU_MAP_H
|
||||
@ -88,7 +88,7 @@ long atol(const char *);
|
||||
void *bsearch(const void *, const void *, size_t,
|
||||
size_t, int (*)(const void *, const void *));
|
||||
void *calloc(size_t, size_t) __malloc_like __result_use_check
|
||||
__alloc_size(1) __alloc_size(2);
|
||||
__attribute__((__alloc_size__(1, 2)));
|
||||
div_t div(int, int) __pure2;
|
||||
_Noreturn void exit(int);
|
||||
void free(void *);
|
||||
@ -303,8 +303,8 @@ void qsort_r(void *, size_t, size_t, void *,
|
||||
int (*)(void *, const void *, const void *));
|
||||
int radixsort(const unsigned char **, int, const unsigned char *,
|
||||
unsigned);
|
||||
void *reallocarray(void *, size_t, size_t) __result_use_check __alloc_size(2)
|
||||
__alloc_size(3);
|
||||
void *reallocarray(void *, size_t, size_t) __result_use_check
|
||||
__attribute__((__alloc_size__(2, 3)));
|
||||
void *reallocf(void *, size_t) __alloc_size(2);
|
||||
int rpmatch(const char *);
|
||||
void setprogname(const char *);
|
||||
|
||||
@ -28,7 +28,8 @@ extern lpaddr_t platform_gic_distributor_base;
|
||||
// Command line arguments
|
||||
static struct cmdarg cmdargs[] = {
|
||||
{"gic", ArgType_UInt, { .uinteger = &platform_gic_cpu_interface_base }},
|
||||
{"gicdist", ArgType_UInt, { .uinteger = &platform_gic_distributor_base }}
|
||||
{"gicdist", ArgType_UInt, { .uinteger = &platform_gic_distributor_base }},
|
||||
{NULL, 0, {NULL}}
|
||||
};
|
||||
|
||||
enum IrqType {
|
||||
|
||||
@ -26,7 +26,8 @@ extern lpaddr_t platform_gic_distributor_base;
|
||||
// Command line arguments
|
||||
static struct cmdarg cmdargs[] = {
|
||||
{"gic", ArgType_ULong, { .ulonginteger = &platform_gic_cpu_interface_base }},
|
||||
{"gicdist", ArgType_ULong, { .ulonginteger = &platform_gic_distributor_base }}
|
||||
{"gicdist", ArgType_ULong, { .ulonginteger = &platform_gic_distributor_base }},
|
||||
{NULL, 0, {NULL}}
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@ -27,7 +27,8 @@ extern lpaddr_t platform_gic_redistributor_base;
|
||||
// Command line arguments
|
||||
static struct cmdarg cmdargs[] = {
|
||||
{"gicdist", ArgType_ULong, { .ulonginteger = &platform_gic_distributor_base }},
|
||||
{"gicredist", ArgType_ULong, { .ulonginteger = &platform_gic_redistributor_base }}
|
||||
{"gicredist", ArgType_ULong, { .ulonginteger = &platform_gic_redistributor_base }},
|
||||
{NULL, 0, {NULL}}
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@ -525,25 +525,26 @@ caps_map_l3(struct capability* dest,
|
||||
{
|
||||
assert(0 == (kpi_paging_flags & ~KPI_PAGING_FLAGS_MASK));
|
||||
|
||||
if (slot + pte_count >= VMSAv8_64_PTABLE_NUM_ENTRIES) {
|
||||
// Check slot is valid and mapping does not overlap leaf page table
|
||||
if (slot + pte_count > VMSAv8_64_PTABLE_NUM_ENTRIES) {
|
||||
if (slot >= VMSAv8_64_PTABLE_NUM_ENTRIES) {
|
||||
return SYS_ERR_VNODE_SLOT_INVALID;
|
||||
}
|
||||
else {
|
||||
return SYS_ERR_VM_MAP_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
if (src->type != ObjType_Frame && src->type != ObjType_DevFrame) {
|
||||
return SYS_ERR_WRONG_MAPPING;
|
||||
}
|
||||
|
||||
// check offset within frame
|
||||
if ((offset + BASE_PAGE_SIZE > get_size(src)) ||
|
||||
if ((offset + pte_count * BASE_PAGE_SIZE > get_size(src)) ||
|
||||
((offset % BASE_PAGE_SIZE) != 0)) {
|
||||
return SYS_ERR_FRAME_OFFSET_INVALID;
|
||||
}
|
||||
|
||||
// check mapping does not overlap leaf page table
|
||||
if (slot + pte_count > VMSAv8_64_PTABLE_NUM_ENTRIES ) {
|
||||
return SYS_ERR_VM_MAP_SIZE;
|
||||
}
|
||||
|
||||
// Destination
|
||||
lpaddr_t dest_lpaddr = gen_phys_to_local_phys(get_address(dest));
|
||||
lvaddr_t dest_lvaddr = local_phys_to_mem(dest_lpaddr);
|
||||
@ -770,7 +771,7 @@ bool paging_is_region_valid(lvaddr_t buffer, size_t size, uint8_t type)
|
||||
return true;
|
||||
}
|
||||
|
||||
void paging_dump_tables(struct dcb *dispatcher)
|
||||
void paging_dump_tables(struct dcb *dispatcher, lvaddr_t addr)
|
||||
{
|
||||
if (!local_phys_is_valid(dispatcher->vspace)) {
|
||||
printk(LOG_ERR, "dispatcher->vspace = 0x%"PRIxLPADDR": too high!\n" ,
|
||||
@ -779,6 +780,68 @@ void paging_dump_tables(struct dcb *dispatcher)
|
||||
}
|
||||
lvaddr_t l0 = local_phys_to_mem(dispatcher->vspace);
|
||||
|
||||
if (addr < (VMSAv8_64_PTABLE_NUM_ENTRIES * VMSAv8_64_PTABLE_NUM_ENTRIES * HUGE_PAGE_SIZE)) {
|
||||
uint32_t l0_index = VMSAv8_64_L0_INDEX(addr);
|
||||
uint32_t l1_index = VMSAv8_64_L1_INDEX(addr);
|
||||
uint32_t l2_index = VMSAv8_64_L2_INDEX(addr);
|
||||
uint32_t l3_index = VMSAv8_64_L3_INDEX(addr);
|
||||
|
||||
printf("dumping table: %lx -> %u.%u.%u.%u\n", addr, l0_index, l1_index, l2_index, l3_index);
|
||||
|
||||
union armv8_ttable_entry *l0_e = (union armv8_ttable_entry *) l0 + l0_index;
|
||||
if (!l0_e->d.valid) {
|
||||
printf("l0[% 3d] -> INVALID\n", l0_index);
|
||||
return;
|
||||
}
|
||||
|
||||
genpaddr_t l1_gp = (genpaddr_t)(l0_e->d.base) << BASE_PAGE_BITS;
|
||||
lvaddr_t l1 = local_phys_to_mem(gen_phys_to_local_phys(l1_gp));
|
||||
printf("l0[% 3d] -> l1 @ %p\n", l0_index, l1);
|
||||
|
||||
union armv8_ttable_entry *l1_e = (union armv8_ttable_entry *)l1 + l1_index;
|
||||
if (!l1_e->d.valid) {
|
||||
printf(" l1[% 3d] -> INVALID\n", l1_index);
|
||||
return;
|
||||
}
|
||||
|
||||
// super page mapping
|
||||
if (l1_e->block_l1.mb0 == 0) {
|
||||
genpaddr_t l2_gp = (genpaddr_t)(l1_e->block_l1.base) << HUGE_PAGE_BITS;
|
||||
printf(" l1[% 3d] -> HUGE_PAGE @ 0x%lx\n", l1_index, l2_gp);
|
||||
return;
|
||||
}
|
||||
|
||||
genpaddr_t l2_gp = (genpaddr_t)(l1_e->d.base) << BASE_PAGE_BITS;
|
||||
lvaddr_t l2 = local_phys_to_mem(gen_phys_to_local_phys(l2_gp));
|
||||
printf(" l1[% 3d] -> l2 @ %p\n", l1_index, l2);
|
||||
|
||||
union armv8_ttable_entry *l2_e = (union armv8_ttable_entry *)l2 + l2_index;
|
||||
if (!l2_e->d.valid) {
|
||||
printf(" l2[% 3d] -> INVALID\n", l2_index);
|
||||
return;
|
||||
}
|
||||
|
||||
if (l2_e->block_l2.mb0 == 0) {
|
||||
genpaddr_t l3_gp = (genpaddr_t)(l1_e->block_l2.base) << LARGE_PAGE_BITS;
|
||||
printf(" l2[% 3d] -> LARGE_PAGE @ 0x%lx\n", l1_index, l3_gp);
|
||||
return;
|
||||
}
|
||||
|
||||
genpaddr_t l3_gp = (genpaddr_t)(l2_e->d.base) << BASE_PAGE_BITS;
|
||||
lvaddr_t l3 = local_phys_to_mem(gen_phys_to_local_phys(l3_gp));
|
||||
printf(" l2 [% 3d] -> l3 @ %p\n", l2_index, l3);
|
||||
|
||||
union armv8_ttable_entry *l3_e = (union armv8_ttable_entry *)l3 + l3_index;
|
||||
if (!l3_e->d.valid) {
|
||||
printf(" l3[% 3d] -> INVALID\n", l3_index);
|
||||
return;
|
||||
}
|
||||
genpaddr_t paddr = (genpaddr_t)(l3_e->page.base) << BASE_PAGE_BITS;
|
||||
printf(" l3[% 3d] -> BASE_PAGE @ 0x%lx \n", l3_index, paddr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (int l0_index = 0; l0_index < VMSAv8_64_PTABLE_NUM_ENTRIES; l0_index++) {
|
||||
// get level0 table
|
||||
union armv8_ttable_entry *l0_e = (union armv8_ttable_entry *) l0 + l0_index;
|
||||
|
||||
@ -153,6 +153,11 @@ uint32_t platform_get_timer_interrupt(void){
|
||||
|
||||
// TODO get this right
|
||||
void platform_get_dev_range(lpaddr_t* start, size_t* size){
|
||||
*start = 0;
|
||||
*size = 0;
|
||||
// the whole platform_get_dev_range is rather a hack.
|
||||
// to make the Qemu work with the approach of imx8x.
|
||||
|
||||
// see: https://github.com/qemu/qemu/blob/master/hw/arm/virt.c
|
||||
*start = 0x08000000;
|
||||
|
||||
*size = 0x01010000; // just include up to the uart
|
||||
}
|
||||
|
||||
@ -851,7 +851,9 @@ static struct sysret dispatcher_dump_ptables(
|
||||
assert(3 == argc);
|
||||
|
||||
struct dcb *dispatcher = to->u.dispatcher.dcb;
|
||||
paging_dump_tables(dispatcher);
|
||||
|
||||
struct registers_aarch64_syscall_args* sa = &context->syscall_args;
|
||||
paging_dump_tables(dispatcher, sa->arg2);
|
||||
|
||||
return SYSRET(SYS_ERR_OK);
|
||||
}
|
||||
@ -1312,6 +1314,9 @@ void sys_syscall(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3,
|
||||
case SYSCALL_NOP:
|
||||
r.error = SYS_ERR_OK;
|
||||
break;
|
||||
case SYSCALL_REBOOT:
|
||||
psci_system_reset();
|
||||
break;
|
||||
|
||||
case SYSCALL_PRINT:
|
||||
if (argc == 3) {
|
||||
|
||||
@ -28,9 +28,9 @@
|
||||
VMSAv8_64_L3_BUFFERABLE | \
|
||||
VMSAv8_64_L3_USR_RW)
|
||||
|
||||
#define INIT_L0_SIZE ARMv8_L0_ENTRIES(ARMV8_INIT_SPACE_LIMIT)
|
||||
#define INIT_L1_SIZE ARMv8_L1_ENTRIES(ARMV8_INIT_SPACE_LIMIT)
|
||||
#define INIT_L2_SIZE ARMv8_L2_ENTRIES(ARMV8_INIT_SPACE_LIMIT)
|
||||
#define INIT_L0_SIZE (1)
|
||||
#define INIT_L1_SIZE ARMv8_L0_ENTRIES(ARMV8_INIT_SPACE_LIMIT)
|
||||
#define INIT_L2_SIZE ARMv8_L1_ENTRIES(ARMV8_INIT_SPACE_LIMIT)
|
||||
#define INIT_L3_SIZE ARMv8_L2_ENTRIES(ARMV8_INIT_SPACE_LIMIT)
|
||||
|
||||
void create_module_caps(struct spawn_state *st);
|
||||
|
||||
@ -145,7 +145,7 @@ errval_t ptable_modify_flags(struct capability *leaf_pt, size_t offset,
|
||||
errval_t paging_modify_flags(struct capability *frame, uintptr_t offset,
|
||||
uintptr_t pages, uintptr_t kpi_paging_flags);
|
||||
void paging_dump_tables_around(struct dcb *dispatcher, lvaddr_t vaddr);
|
||||
void paging_dump_tables(struct dcb *dispatcher);
|
||||
void paging_dump_tables(struct dcb *dispatcher, lvaddr_t va);
|
||||
|
||||
errval_t caps_retype(enum objtype type, gensize_t objsize, size_t count,
|
||||
struct capability *dest_cnode, cslot_t dest_slot,
|
||||
|
||||
@ -61,7 +61,7 @@ aos_rpc_serial_putchar(struct aos_rpc *rpc, char c) {
|
||||
errval_t
|
||||
aos_rpc_process_spawn(struct aos_rpc *rpc, char *cmdline,
|
||||
coreid_t core, domainid_t *newpid) {
|
||||
// TODO (M5): implement spawn new process rpc
|
||||
// TODO: implement spawn new process rpc
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ aos_rpc_process_spawn(struct aos_rpc *rpc, char *cmdline,
|
||||
|
||||
errval_t
|
||||
aos_rpc_process_get_name(struct aos_rpc *rpc, domainid_t pid, char **name) {
|
||||
// TODO (M5): implement name lookup for process given a process id
|
||||
// TODO: implement name lookup for process given a process id
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ aos_rpc_process_get_name(struct aos_rpc *rpc, domainid_t pid, char **name) {
|
||||
errval_t
|
||||
aos_rpc_process_get_all_pids(struct aos_rpc *rpc, domainid_t **pids,
|
||||
size_t *pid_count) {
|
||||
// TODO (M5): implement process id discovery
|
||||
// TODO: implement process id discovery
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -95,6 +95,9 @@ static inline bool havework_disabled(dispatcher_handle_t handle)
|
||||
{
|
||||
struct dispatcher_generic *disp = get_dispatcher_generic(handle);
|
||||
return disp->runq != NULL
|
||||
#ifdef CONFIG_INTERCONNECT_DRIVER_LMP
|
||||
|| disp->lmp_send_events_list != NULL
|
||||
#endif
|
||||
|| disp->polled_channels != NULL
|
||||
|| disp->notificators != NULL
|
||||
;
|
||||
|
||||
@ -115,7 +115,6 @@ errval_t paging_init_state_foreign(struct paging_state *st, lvaddr_t start_vaddr
|
||||
*/
|
||||
errval_t paging_init(void)
|
||||
{
|
||||
debug_printf("paging_init\n");
|
||||
// TODO (M2): Call paging_init_state for ¤t
|
||||
// TODO (M4): initialize self-paging handler
|
||||
// TIP: use thread_set_exception_handler() to setup a page fault handler
|
||||
@ -194,7 +193,6 @@ errval_t paging_map_frame_attr(struct paging_state *st, void **buf, size_t bytes
|
||||
return LIB_ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief mapps the provided frame at the supplied address in the paging state
|
||||
*
|
||||
@ -233,8 +231,6 @@ errval_t paging_map_fixed_attr(struct paging_state *st, lvaddr_t vaddr,
|
||||
* @return SYS_ERR_OK on success, or error code indicating the kind of failure
|
||||
*
|
||||
* The supplied `region` must be the start of a previously mapped frame.
|
||||
*
|
||||
* @NOTE: Implementing this function is optional.
|
||||
*/
|
||||
errval_t paging_unmap(struct paging_state *st, const void *region)
|
||||
{
|
||||
|
||||
@ -179,10 +179,20 @@ size_t slab_freecount(struct slab_allocator *slabs)
|
||||
*/
|
||||
static errval_t slab_refill_pages(struct slab_allocator *slabs, size_t bytes)
|
||||
{
|
||||
// Hint: you can't just use malloc here...
|
||||
// Hint: For M1, just use the fixed mapping funcionality, however you may want to replace
|
||||
// the fixed mapping later to avoid conflicts.
|
||||
return LIB_ERR_NOT_IMPLEMENTED;
|
||||
errval_t err;
|
||||
struct capref cap;
|
||||
|
||||
err = slot_alloc(&cap);
|
||||
if (err_is_fail(err)) {
|
||||
return err_push(err, LIB_ERR_SLOT_ALLOC);
|
||||
}
|
||||
|
||||
err = slab_refill_no_pagefault(slabs, cap, bytes);
|
||||
if (err_is_fail(err)) {
|
||||
slot_free(cap);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@ -190,18 +200,15 @@ static errval_t slab_refill_pages(struct slab_allocator *slabs, size_t bytes)
|
||||
* @brief refills the slab allocator without causing a page fault
|
||||
*
|
||||
* @param slabs the slab allocator to be refilled
|
||||
* @param frame an empty slot to hold the frame capability
|
||||
* @param minbytes the minimum about of bytes to refill
|
||||
* @param frame_slot an empty capability slot for the frames
|
||||
* @param minbytes the minimum number of bytes to allocate
|
||||
*
|
||||
* @return SYS_ERR_OK on success, errval on failure
|
||||
*
|
||||
* Note, the frame here is an empty slot that can be used as storage for a frame.
|
||||
* @return SYS_ERR_OK on success, error code on failure
|
||||
*/
|
||||
errval_t slab_refill_no_pagefault(struct slab_allocator *slabs, struct capref frame,
|
||||
errval_t slab_refill_no_pagefault(struct slab_allocator *slabs, struct capref frame_slot,
|
||||
size_t minbytes)
|
||||
{
|
||||
// Refill the slot allocator without causing a page fault
|
||||
// Hint: you can't just use malloc here...
|
||||
// Refill the slot allocator without causing a page-fault
|
||||
return LIB_ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
@ -70,6 +70,8 @@ errval_t slot_alloc_root(struct capref *ret)
|
||||
}
|
||||
state->rootca.refilling = false;
|
||||
}
|
||||
// If we got below two here somehow it's game over
|
||||
assert(rootcn_free > 2);
|
||||
struct slot_allocator *ca = (struct slot_allocator*)(&state->rootca);
|
||||
return ca->alloc(ca, ret);
|
||||
}
|
||||
|
||||
@ -64,8 +64,10 @@ errval_t two_level_alloc(struct slot_allocator *ca, struct capref *ret)
|
||||
struct slot_alloc_state *state = get_slot_alloc_state();
|
||||
struct slot_allocator *rca = (struct slot_allocator *)(&state->rootca);
|
||||
// Need to refill when one slot left, otherwise it's too late
|
||||
// We can't leave it at one though either as the code in slot_alloc_root()
|
||||
// assumes there are always at least 2 slots left, so refill at 2 or less
|
||||
size_t rootcn_free = single_slot_alloc_freecount(&state->rootca);
|
||||
if (rootcn_free == 1) {
|
||||
if (rootcn_free <= 2) {
|
||||
// resize root slot allocator (and rootcn)
|
||||
err = root_slot_allocator_refill(NULL, NULL);
|
||||
if (err_is_fail(err)) {
|
||||
|
||||
@ -6,16 +6,16 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
size_t (*_libc_terminal_read_func)(char *, size_t);
|
||||
size_t (*_libc_terminal_write_func)(const char *, size_t);
|
||||
extern size_t (*_libc_terminal_read_func)(char *, size_t);
|
||||
extern size_t (*_libc_terminal_write_func)(const char *, size_t);
|
||||
|
||||
void (*_libc_assert_func)(const char *, const char *, const char *, int);
|
||||
|
||||
typedef void *(*morecore_alloc_func_t)(size_t bytes, size_t *retbytes);
|
||||
morecore_alloc_func_t sys_morecore_alloc;
|
||||
extern morecore_alloc_func_t sys_morecore_alloc;
|
||||
|
||||
typedef void (*morecore_free_func_t)(void *base, size_t bytes);
|
||||
morecore_free_func_t sys_morecore_free;
|
||||
extern morecore_free_func_t sys_morecore_free;
|
||||
|
||||
int system(const char *cmd)
|
||||
{
|
||||
|
||||
@ -53,6 +53,7 @@ static void armv8_set_registers(void *arch_load_info,
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* TODO(M2): Implement this function.
|
||||
* \brief Spawn a new dispatcher called 'argv[0]' with 'argc' arguments.
|
||||
|
||||
@ -28,6 +28,15 @@ mkdir -p $BF_BUILD
|
||||
|
||||
# run the command in the docker image with the same userid to avoid
|
||||
# permission problems later.
|
||||
docker run -u $(id -u) -i -t \
|
||||
|
||||
if [[ "$@" == "" ]]; then
|
||||
docker run -u $(id -u) -i -t \
|
||||
--mount type=bind,source=$BF_SOURCE,target=/source \
|
||||
$BF_DOCKER
|
||||
$BF_DOCKER "$@"
|
||||
else
|
||||
docker run -u $(id -u) \
|
||||
--mount type=bind,source=$BF_SOURCE,target=/source \
|
||||
$BF_DOCKER "$@"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
@ -18,8 +18,8 @@ build: Dockerfile install.sh entrypoint.sh
|
||||
docker build -t $(IMAGE_NAME):$(IMAGE_TAG) .
|
||||
|
||||
publish: build
|
||||
docker tag $(IMAGE_NAME):20.04-lts-aos $(DOCKER_HUB_USER)/$(IMAGE_NAME):$(IMAGE_TAG)
|
||||
docker tag $(IMAGE_NAME):20.04-lts-aos $(DOCKER_HUB_USER)/$(IMAGE_NAME):latest
|
||||
docker tag $(IMAGE_NAME):$(IMAGE_TAG) $(DOCKER_HUB_USER)/$(IMAGE_NAME):$(IMAGE_TAG)
|
||||
docker tag $(IMAGE_NAME):$(IMAGE_TAG) $(DOCKER_HUB_USER)/$(IMAGE_NAME):latest
|
||||
docker push $(DOCKER_HUB_USER)/$(IMAGE_NAME):$(IMAGE_TAG)
|
||||
|
||||
test:
|
||||
|
||||
@ -1,11 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2021 The University of British Columbia.
|
||||
# Copyright (c) 2021,2022 The University of British Columbia.
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is distributed under the terms in the attached LICENSE file.
|
||||
|
||||
cd /source
|
||||
# create the build directory if it doesn't exist
|
||||
mkdir -p /source/build
|
||||
|
||||
# cd into the build directory
|
||||
cd /source/build
|
||||
|
||||
|
||||
if [ "$1" == "" ]; then
|
||||
exec "/bin/bash"
|
||||
|
||||
@ -14,7 +14,7 @@ DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
python3 parted wget mtools
|
||||
|
||||
# install barrelfish dependencies
|
||||
apt-get update
|
||||
apt-get update && apt-get upgrade
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
build-essential bison flex ghc libghc-src-exts-dev \
|
||||
libghc-ghc-paths-dev libghc-parsec3-dev libghc-random-dev\
|
||||
@ -27,6 +27,10 @@ DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
cabal v1-update
|
||||
cabal v1-install --global bytestring-trie
|
||||
|
||||
# install the autograder dependencies
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||
python3 python3-pexpect python3-plumbum
|
||||
|
||||
# get the uuu tool
|
||||
wget -P /bin https://github.com/NXPmicro/mfgtools/releases/download/uuu_1.4.165/uuu
|
||||
chmod 755 /bin/uuu
|
||||
|
||||
19
usr/drivers/pl011/Hakefile
Normal file
19
usr/drivers/pl011/Hakefile
Normal file
@ -0,0 +1,19 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- Copyright (c) 2020, ETH Zurich.
|
||||
-- All rights reserved.
|
||||
--
|
||||
-- This file is distributed under the terms in the attached LICENSE file.
|
||||
-- If you do not find this file, copies can be found by writing to:
|
||||
-- ETH Zurich D-INFK, CAB F.78, Universitaetstr 6, CH-8092 Zurich.
|
||||
--
|
||||
-- Hakefile for lpuart
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
[
|
||||
build library { target = "pl011",
|
||||
cFiles = ["main.c"],
|
||||
mackerelDevices = [ "pl011_uart" ],
|
||||
architectures = ["armv8"]
|
||||
}
|
||||
]
|
||||
132
usr/drivers/pl011/main.c
Normal file
132
usr/drivers/pl011/main.c
Normal file
@ -0,0 +1,132 @@
|
||||
/**
|
||||
* \file
|
||||
* \brief Serial port driver.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2020, ETH Zurich.
|
||||
* Copyright (c) 2022, The University of British Columbia.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is distributed under the terms in the attached LICENSE file.
|
||||
* If you do not find this file, copies can be found by writing to:
|
||||
* ETH Zurich D-INFK, CAB F.78, Universitaetstrasse 6, CH-8092 Zurich,
|
||||
* Attn: Systems Group.
|
||||
*/
|
||||
|
||||
#include <drivers/pl011.h>
|
||||
#include <dev/pl011_uart_dev.h>
|
||||
|
||||
struct pl011_s {
|
||||
struct event_closure int_handler;
|
||||
struct pl011_uart_t dev;
|
||||
};
|
||||
|
||||
|
||||
static void hw_init(struct pl011_s *s)
|
||||
{
|
||||
pl011_uart_t *u = &s->dev;
|
||||
|
||||
/* Mask all interrupts: set all bits to zero. */
|
||||
pl011_uart_IMSC_rawwr(u, 0);
|
||||
|
||||
/* Disable the UART before reconfiguring it. */
|
||||
pl011_uart_CR_uarten_wrf(u, 0);
|
||||
|
||||
// Configure port to 38400 baud, 8 data, no parity, 1 stop (8-N-1)
|
||||
//
|
||||
// (This is a mild scam as system is running in QEMU)
|
||||
//
|
||||
// Note baud rate changes not committed in h/w until lcr_h
|
||||
// written.
|
||||
pl011_uart_IBRD_divint_wrf(u, 0xc); // Assuming UARTCLK is 7.3728MHz
|
||||
pl011_uart_FBRD_divfrac_wrf(u, 0);
|
||||
|
||||
/* Configure the line control register. */
|
||||
pl011_uart_LCR_H_t lcr = (pl011_uart_LCR_H_t)0;
|
||||
/* Disable FIFOs. There's no way to get an interrupt when a single
|
||||
* character arrives with FIFOs, so it's useless as a console. */
|
||||
lcr = pl011_uart_LCR_H_fen_insert(lcr, 0);
|
||||
/* Eight data bits. */
|
||||
lcr = pl011_uart_LCR_H_wlen_insert(lcr, pl011_uart_bits8);
|
||||
/* No parity. */
|
||||
lcr = pl011_uart_LCR_H_pen_insert(lcr, 0);
|
||||
/* One stop bit. */
|
||||
lcr = pl011_uart_LCR_H_stp2_insert(lcr, 0);
|
||||
pl011_uart_LCR_H_wr(u, lcr);
|
||||
|
||||
/* Configure the main control register. */
|
||||
pl011_uart_CR_t cr = (pl011_uart_CR_t)0;
|
||||
/* No flow control. */
|
||||
cr = pl011_uart_CR_ctsen_insert(cr, 0);
|
||||
cr = pl011_uart_CR_rtsen_insert(cr, 0);
|
||||
/* Enable transmit and receive. */
|
||||
cr = pl011_uart_CR_txe_insert(cr, 1);
|
||||
cr = pl011_uart_CR_rxe_insert(cr, 1);
|
||||
/* Enable UART. */
|
||||
cr = pl011_uart_CR_uarten_insert(cr, 1);
|
||||
pl011_uart_CR_wr(u, cr);
|
||||
}
|
||||
|
||||
errval_t pl011_init(struct pl011_s **s_ret, void *base)
|
||||
{
|
||||
PL011_DEBUG("Driver init\n");
|
||||
|
||||
assert(s_ret != NULL);
|
||||
assert(base != NULL);
|
||||
|
||||
struct pl011_s *s = calloc(1, sizeof(struct pl011_s));
|
||||
if (s == NULL) {
|
||||
return LIB_ERR_MALLOC_FAIL;
|
||||
}
|
||||
|
||||
*s_ret = s;
|
||||
|
||||
pl011_uart_initialize(&s->dev, base);
|
||||
|
||||
PL011_DEBUG("Initializing hw...");
|
||||
hw_init(s);
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
errval_t pl011_getchar(struct pl011_s *s, char *c)
|
||||
{
|
||||
pl011_uart_t *u = &s->dev;
|
||||
assert(u->base != 0);
|
||||
|
||||
/* Acknowledge any interrupt. */
|
||||
pl011_uart_ICR_rxic_wrf(u, 1);
|
||||
|
||||
/* check if there is data */
|
||||
if (pl011_uart_FR_rxfe_rdf(u) == 1) {
|
||||
return LPUART_ERR_NO_DATA;
|
||||
}
|
||||
|
||||
/* store the return character */
|
||||
*c = (char)pl011_uart_DR_data_rdf(u);
|
||||
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
errval_t pl011_enable_interrupt(struct pl011_s *s)
|
||||
{
|
||||
pl011_uart_t *u = &s->dev;
|
||||
assert(u->base != 0);
|
||||
|
||||
// Receive interrupt enable
|
||||
pl011_uart_ICR_rxic_wrf(u, 1);
|
||||
pl011_uart_IMSC_rxim_wrf(u, 1);
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
errval_t pl011_putchar(struct pl011_s *s, char c)
|
||||
{
|
||||
pl011_uart_t *u = &s->dev;
|
||||
assert(u->base != 0);
|
||||
|
||||
while (pl011_uart_FR_txff_rdf(u) == 1)
|
||||
;
|
||||
pl011_uart_DR_rawwr(u, c);
|
||||
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
@ -31,6 +31,7 @@
|
||||
struct bootinfo *bi;
|
||||
|
||||
coreid_t my_core_id;
|
||||
struct platform_info platform_info;
|
||||
|
||||
|
||||
|
||||
@ -56,6 +57,7 @@ bsp_main(int argc, char *argv[]) {
|
||||
// Grading
|
||||
grading_test_early();
|
||||
|
||||
|
||||
// TODO: Spawn system processes, boot second core etc. here
|
||||
|
||||
// Grading
|
||||
@ -85,23 +87,45 @@ app_main(int argc, char *argv[]) {
|
||||
return LIB_ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
errval_t err;
|
||||
|
||||
/* obtain the core information from the kernel*/
|
||||
err = invoke_kernel_get_core_id(cap_kernel, &my_core_id);
|
||||
if (err_is_fail(err)) {
|
||||
USER_PANIC_ERR(err, "failed to obtain the core id from the kernel\n");
|
||||
}
|
||||
|
||||
/* Set the core id in the disp_priv struct */
|
||||
err = invoke_kernel_get_core_id(cap_kernel, &my_core_id);
|
||||
assert(err_is_ok(err));
|
||||
disp_set_core_id(my_core_id);
|
||||
|
||||
debug_printf("init: on core %" PRIuCOREID ", invoked as:", my_core_id);
|
||||
/* obtain the platform information */
|
||||
err = invoke_kernel_get_platform_info(cap_kernel, &platform_info);
|
||||
if (err_is_fail(err)) {
|
||||
USER_PANIC_ERR(err, "failed to obtain the platform info from the kernel\n");
|
||||
}
|
||||
|
||||
char *platform;
|
||||
switch (platform_info.platform) {
|
||||
case PI_PLATFORM_QEMU:
|
||||
platform = "QEMU";
|
||||
break;
|
||||
case PI_PLATFORM_IMX8X:
|
||||
platform = "IMX8X";
|
||||
break;
|
||||
default:
|
||||
platform = "UNKNOWN";
|
||||
}
|
||||
|
||||
debug_printf("init domain starting on core %" PRIuCOREID " (%s), invoked as:", my_core_id, platform);
|
||||
for (int i = 0; i < argc; i++) {
|
||||
printf(" %s", argv[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user