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
|
||||||
.clang_complete
|
.clang_complete
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
|
test-logs
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
#include <barrelfish_kpi/distcaps.h> // for distcap_state_t
|
#include <barrelfish_kpi/distcaps.h> // for distcap_state_t
|
||||||
#include <barrelfish_kpi/lmp.h> // invoking lmp endpoint requires flags
|
#include <barrelfish_kpi/lmp.h> // invoking lmp endpoint requires flags
|
||||||
#include <barrelfish_kpi/syscalls.h>
|
#include <barrelfish_kpi/syscalls.h>
|
||||||
|
#include <barrelfish_kpi/platform.h> // for struct platform info
|
||||||
#include <aos/caddr.h>
|
#include <aos/caddr.h>
|
||||||
#include <barrelfish_kpi/paging_arch.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;
|
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
|
#endif
|
||||||
|
|||||||
@ -19,6 +19,7 @@
|
|||||||
#include <aos/static_assert.h>
|
#include <aos/static_assert.h>
|
||||||
|
|
||||||
enum pi_arch {
|
enum pi_arch {
|
||||||
|
PI_ARCH_UNKNOWN,
|
||||||
PI_ARCH_X86,
|
PI_ARCH_X86,
|
||||||
PI_ARCH_ARMV7A,
|
PI_ARCH_ARMV7A,
|
||||||
PI_ARCH_ARMV8A,
|
PI_ARCH_ARMV8A,
|
||||||
|
|||||||
@ -38,6 +38,7 @@ enum debug_message {
|
|||||||
DEBUG_CREATE_IRQ_SRC_CAP,
|
DEBUG_CREATE_IRQ_SRC_CAP,
|
||||||
DEBUG_GET_MDB_SIZE,
|
DEBUG_GET_MDB_SIZE,
|
||||||
DEBUG_PRINT_MDB_COUNTERS,
|
DEBUG_PRINT_MDB_COUNTERS,
|
||||||
|
DEBUG_GET_PLATFORM_INFO,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //BARRELFISH_KPI_SYS_DEBUG_H
|
#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,
|
void *bsearch(const void *, const void *, size_t,
|
||||||
size_t, int (*)(const void *, const void *));
|
size_t, int (*)(const void *, const void *));
|
||||||
void *calloc(size_t, size_t) __malloc_like __result_use_check
|
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;
|
div_t div(int, int) __pure2;
|
||||||
_Noreturn void exit(int);
|
_Noreturn void exit(int);
|
||||||
void free(void *);
|
void free(void *);
|
||||||
@ -303,8 +303,8 @@ void qsort_r(void *, size_t, size_t, void *,
|
|||||||
int (*)(void *, const void *, const void *));
|
int (*)(void *, const void *, const void *));
|
||||||
int radixsort(const unsigned char **, int, const unsigned char *,
|
int radixsort(const unsigned char **, int, const unsigned char *,
|
||||||
unsigned);
|
unsigned);
|
||||||
void *reallocarray(void *, size_t, size_t) __result_use_check __alloc_size(2)
|
void *reallocarray(void *, size_t, size_t) __result_use_check
|
||||||
__alloc_size(3);
|
__attribute__((__alloc_size__(2, 3)));
|
||||||
void *reallocf(void *, size_t) __alloc_size(2);
|
void *reallocf(void *, size_t) __alloc_size(2);
|
||||||
int rpmatch(const char *);
|
int rpmatch(const char *);
|
||||||
void setprogname(const char *);
|
void setprogname(const char *);
|
||||||
|
|||||||
@ -28,7 +28,8 @@ extern lpaddr_t platform_gic_distributor_base;
|
|||||||
// Command line arguments
|
// Command line arguments
|
||||||
static struct cmdarg cmdargs[] = {
|
static struct cmdarg cmdargs[] = {
|
||||||
{"gic", ArgType_UInt, { .uinteger = &platform_gic_cpu_interface_base }},
|
{"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 {
|
enum IrqType {
|
||||||
|
|||||||
@ -26,7 +26,8 @@ extern lpaddr_t platform_gic_distributor_base;
|
|||||||
// Command line arguments
|
// Command line arguments
|
||||||
static struct cmdarg cmdargs[] = {
|
static struct cmdarg cmdargs[] = {
|
||||||
{"gic", ArgType_ULong, { .ulonginteger = &platform_gic_cpu_interface_base }},
|
{"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
|
// Command line arguments
|
||||||
static struct cmdarg cmdargs[] = {
|
static struct cmdarg cmdargs[] = {
|
||||||
{"gicdist", ArgType_ULong, { .ulonginteger = &platform_gic_distributor_base }},
|
{"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,8 +525,14 @@ caps_map_l3(struct capability* dest,
|
|||||||
{
|
{
|
||||||
assert(0 == (kpi_paging_flags & ~KPI_PAGING_FLAGS_MASK));
|
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
|
||||||
return SYS_ERR_VNODE_SLOT_INVALID;
|
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) {
|
if (src->type != ObjType_Frame && src->type != ObjType_DevFrame) {
|
||||||
@ -534,16 +540,11 @@ caps_map_l3(struct capability* dest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check offset within frame
|
// 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)) {
|
((offset % BASE_PAGE_SIZE) != 0)) {
|
||||||
return SYS_ERR_FRAME_OFFSET_INVALID;
|
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
|
// Destination
|
||||||
lpaddr_t dest_lpaddr = gen_phys_to_local_phys(get_address(dest));
|
lpaddr_t dest_lpaddr = gen_phys_to_local_phys(get_address(dest));
|
||||||
lvaddr_t dest_lvaddr = local_phys_to_mem(dest_lpaddr);
|
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;
|
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)) {
|
if (!local_phys_is_valid(dispatcher->vspace)) {
|
||||||
printk(LOG_ERR, "dispatcher->vspace = 0x%"PRIxLPADDR": too high!\n" ,
|
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);
|
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++) {
|
for (int l0_index = 0; l0_index < VMSAv8_64_PTABLE_NUM_ENTRIES; l0_index++) {
|
||||||
// get level0 table
|
// get level0 table
|
||||||
union armv8_ttable_entry *l0_e = (union armv8_ttable_entry *) l0 + l0_index;
|
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
|
// TODO get this right
|
||||||
void platform_get_dev_range(lpaddr_t* start, size_t* size){
|
void platform_get_dev_range(lpaddr_t* start, size_t* size){
|
||||||
*start = 0;
|
// the whole platform_get_dev_range is rather a hack.
|
||||||
*size = 0;
|
// 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);
|
assert(3 == argc);
|
||||||
|
|
||||||
struct dcb *dispatcher = to->u.dispatcher.dcb;
|
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);
|
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:
|
case SYSCALL_NOP:
|
||||||
r.error = SYS_ERR_OK;
|
r.error = SYS_ERR_OK;
|
||||||
break;
|
break;
|
||||||
|
case SYSCALL_REBOOT:
|
||||||
|
psci_system_reset();
|
||||||
|
break;
|
||||||
|
|
||||||
case SYSCALL_PRINT:
|
case SYSCALL_PRINT:
|
||||||
if (argc == 3) {
|
if (argc == 3) {
|
||||||
|
|||||||
@ -28,9 +28,9 @@
|
|||||||
VMSAv8_64_L3_BUFFERABLE | \
|
VMSAv8_64_L3_BUFFERABLE | \
|
||||||
VMSAv8_64_L3_USR_RW)
|
VMSAv8_64_L3_USR_RW)
|
||||||
|
|
||||||
#define INIT_L0_SIZE ARMv8_L0_ENTRIES(ARMV8_INIT_SPACE_LIMIT)
|
#define INIT_L0_SIZE (1)
|
||||||
#define INIT_L1_SIZE ARMv8_L1_ENTRIES(ARMV8_INIT_SPACE_LIMIT)
|
#define INIT_L1_SIZE ARMv8_L0_ENTRIES(ARMV8_INIT_SPACE_LIMIT)
|
||||||
#define INIT_L2_SIZE ARMv8_L2_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)
|
#define INIT_L3_SIZE ARMv8_L2_ENTRIES(ARMV8_INIT_SPACE_LIMIT)
|
||||||
|
|
||||||
void create_module_caps(struct spawn_state *st);
|
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,
|
errval_t paging_modify_flags(struct capability *frame, uintptr_t offset,
|
||||||
uintptr_t pages, uintptr_t kpi_paging_flags);
|
uintptr_t pages, uintptr_t kpi_paging_flags);
|
||||||
void paging_dump_tables_around(struct dcb *dispatcher, lvaddr_t vaddr);
|
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,
|
errval_t caps_retype(enum objtype type, gensize_t objsize, size_t count,
|
||||||
struct capability *dest_cnode, cslot_t dest_slot,
|
struct capability *dest_cnode, cslot_t dest_slot,
|
||||||
|
|||||||
@ -61,7 +61,7 @@ aos_rpc_serial_putchar(struct aos_rpc *rpc, char c) {
|
|||||||
errval_t
|
errval_t
|
||||||
aos_rpc_process_spawn(struct aos_rpc *rpc, char *cmdline,
|
aos_rpc_process_spawn(struct aos_rpc *rpc, char *cmdline,
|
||||||
coreid_t core, domainid_t *newpid) {
|
coreid_t core, domainid_t *newpid) {
|
||||||
// TODO (M5): implement spawn new process rpc
|
// TODO: implement spawn new process rpc
|
||||||
return SYS_ERR_OK;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ aos_rpc_process_spawn(struct aos_rpc *rpc, char *cmdline,
|
|||||||
|
|
||||||
errval_t
|
errval_t
|
||||||
aos_rpc_process_get_name(struct aos_rpc *rpc, domainid_t pid, char **name) {
|
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;
|
return SYS_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ aos_rpc_process_get_name(struct aos_rpc *rpc, domainid_t pid, char **name) {
|
|||||||
errval_t
|
errval_t
|
||||||
aos_rpc_process_get_all_pids(struct aos_rpc *rpc, domainid_t **pids,
|
aos_rpc_process_get_all_pids(struct aos_rpc *rpc, domainid_t **pids,
|
||||||
size_t *pid_count) {
|
size_t *pid_count) {
|
||||||
// TODO (M5): implement process id discovery
|
// TODO: implement process id discovery
|
||||||
return SYS_ERR_OK;
|
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);
|
struct dispatcher_generic *disp = get_dispatcher_generic(handle);
|
||||||
return disp->runq != NULL
|
return disp->runq != NULL
|
||||||
|
#ifdef CONFIG_INTERCONNECT_DRIVER_LMP
|
||||||
|
|| disp->lmp_send_events_list != NULL
|
||||||
|
#endif
|
||||||
|| disp->polled_channels != NULL
|
|| disp->polled_channels != NULL
|
||||||
|| disp->notificators != NULL
|
|| disp->notificators != NULL
|
||||||
;
|
;
|
||||||
|
|||||||
@ -29,8 +29,8 @@ static struct paging_state current;
|
|||||||
* \brief Helper function that allocates a slot and
|
* \brief Helper function that allocates a slot and
|
||||||
* creates a aarch64 page table capability for a certain level
|
* creates a aarch64 page table capability for a certain level
|
||||||
*/
|
*/
|
||||||
static errval_t pt_alloc(struct paging_state * st, enum objtype type,
|
static errval_t pt_alloc(struct paging_state * st, enum objtype type,
|
||||||
struct capref *ret)
|
struct capref *ret)
|
||||||
{
|
{
|
||||||
errval_t err;
|
errval_t err;
|
||||||
err = st->slot_alloc->alloc(st->slot_alloc, ret);
|
err = st->slot_alloc->alloc(st->slot_alloc, ret);
|
||||||
@ -56,7 +56,7 @@ __attribute__((unused)) static errval_t pt_alloc_l2(struct paging_state * st, st
|
|||||||
return pt_alloc(st, ObjType_VNode_AARCH64_l2, ret);
|
return pt_alloc(st, ObjType_VNode_AARCH64_l2, ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((unused)) static errval_t pt_alloc_l3(struct paging_state * st, struct capref *ret)
|
__attribute__((unused)) static errval_t pt_alloc_l3(struct paging_state * st, struct capref *ret)
|
||||||
{
|
{
|
||||||
return pt_alloc(st, ObjType_VNode_AARCH64_l3, ret);
|
return pt_alloc(st, ObjType_VNode_AARCH64_l3, ret);
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ __attribute__((unused)) static errval_t pt_alloc_l3(struct paging_state * st, st
|
|||||||
* TODO(M4): Improve this function.
|
* TODO(M4): Improve this function.
|
||||||
* \brief Initialize the paging_state struct for the paging
|
* \brief Initialize the paging_state struct for the paging
|
||||||
* state of the calling process.
|
* state of the calling process.
|
||||||
*
|
*
|
||||||
* \param st The struct to be initialized, must not be NULL.
|
* \param st The struct to be initialized, must not be NULL.
|
||||||
* \param start_vaddr Virtual address allocation should start at
|
* \param start_vaddr Virtual address allocation should start at
|
||||||
* this address.
|
* this address.
|
||||||
@ -90,7 +90,7 @@ errval_t paging_init_state(struct paging_state *st, lvaddr_t start_vaddr,
|
|||||||
* TODO(M4): Improve this function.
|
* TODO(M4): Improve this function.
|
||||||
* \brief Initialize the paging_state struct for the paging state
|
* \brief Initialize the paging_state struct for the paging state
|
||||||
* of a child process.
|
* of a child process.
|
||||||
*
|
*
|
||||||
* \param st The struct to be initialized, must not be NULL.
|
* \param st The struct to be initialized, must not be NULL.
|
||||||
* \param start_vaddr Virtual address allocation should start at
|
* \param start_vaddr Virtual address allocation should start at
|
||||||
* this address.
|
* this address.
|
||||||
@ -115,7 +115,6 @@ errval_t paging_init_state_foreign(struct paging_state *st, lvaddr_t start_vaddr
|
|||||||
*/
|
*/
|
||||||
errval_t paging_init(void)
|
errval_t paging_init(void)
|
||||||
{
|
{
|
||||||
debug_printf("paging_init\n");
|
|
||||||
// TODO (M2): Call paging_init_state for ¤t
|
// TODO (M2): Call paging_init_state for ¤t
|
||||||
// TODO (M4): initialize self-paging handler
|
// TODO (M4): initialize self-paging handler
|
||||||
// TIP: use thread_set_exception_handler() to setup a page fault 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;
|
return LIB_ERR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief mapps the provided frame at the supplied address in the paging state
|
* @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
|
* @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.
|
* 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)
|
errval_t paging_unmap(struct paging_state *st, const void *region)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -179,29 +179,36 @@ size_t slab_freecount(struct slab_allocator *slabs)
|
|||||||
*/
|
*/
|
||||||
static errval_t slab_refill_pages(struct slab_allocator *slabs, size_t bytes)
|
static errval_t slab_refill_pages(struct slab_allocator *slabs, size_t bytes)
|
||||||
{
|
{
|
||||||
// Hint: you can't just use malloc here...
|
errval_t err;
|
||||||
// Hint: For M1, just use the fixed mapping funcionality, however you may want to replace
|
struct capref cap;
|
||||||
// the fixed mapping later to avoid conflicts.
|
|
||||||
return LIB_ERR_NOT_IMPLEMENTED;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief refills the slab allocator without causing a page fault
|
* @brief refills the slab allocator without causing a page fault
|
||||||
*
|
*
|
||||||
* @param slabs the slab allocator to be refilled
|
* @param slabs the slab allocator to be refilled
|
||||||
* @param frame an empty slot to hold the frame capability
|
* @param frame_slot an empty capability slot for the frames
|
||||||
* @param minbytes the minimum about of bytes to refill
|
* @param minbytes the minimum number of bytes to allocate
|
||||||
*
|
*
|
||||||
* @return SYS_ERR_OK on success, errval on failure
|
* @return SYS_ERR_OK on success, error code on failure
|
||||||
*
|
|
||||||
* Note, the frame here is an empty slot that can be used as storage for a frame.
|
|
||||||
*/
|
*/
|
||||||
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)
|
size_t minbytes)
|
||||||
{
|
{
|
||||||
// Refill the slot allocator without causing a page fault
|
// Refill the slot allocator without causing a page-fault
|
||||||
// Hint: you can't just use malloc here...
|
|
||||||
return LIB_ERR_NOT_IMPLEMENTED;
|
return LIB_ERR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -70,6 +70,8 @@ errval_t slot_alloc_root(struct capref *ret)
|
|||||||
}
|
}
|
||||||
state->rootca.refilling = false;
|
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);
|
struct slot_allocator *ca = (struct slot_allocator*)(&state->rootca);
|
||||||
return ca->alloc(ca, ret);
|
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_alloc_state *state = get_slot_alloc_state();
|
||||||
struct slot_allocator *rca = (struct slot_allocator *)(&state->rootca);
|
struct slot_allocator *rca = (struct slot_allocator *)(&state->rootca);
|
||||||
// Need to refill when one slot left, otherwise it's too late
|
// 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);
|
size_t rootcn_free = single_slot_alloc_freecount(&state->rootca);
|
||||||
if (rootcn_free == 1) {
|
if (rootcn_free <= 2) {
|
||||||
// resize root slot allocator (and rootcn)
|
// resize root slot allocator (and rootcn)
|
||||||
err = root_slot_allocator_refill(NULL, NULL);
|
err = root_slot_allocator_refill(NULL, NULL);
|
||||||
if (err_is_fail(err)) {
|
if (err_is_fail(err)) {
|
||||||
|
|||||||
@ -6,16 +6,16 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
size_t (*_libc_terminal_read_func)(char *, size_t);
|
extern size_t (*_libc_terminal_read_func)(char *, size_t);
|
||||||
size_t (*_libc_terminal_write_func)(const 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);
|
void (*_libc_assert_func)(const char *, const char *, const char *, int);
|
||||||
|
|
||||||
typedef void *(*morecore_alloc_func_t)(size_t bytes, size_t *retbytes);
|
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);
|
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)
|
int system(const char *cmd)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -53,6 +53,7 @@ static void armv8_set_registers(void *arch_load_info,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO(M2): Implement this function.
|
* TODO(M2): Implement this function.
|
||||||
* \brief Spawn a new dispatcher called 'argv[0]' with 'argc' arguments.
|
* \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
|
# run the command in the docker image with the same userid to avoid
|
||||||
# permission problems later.
|
# permission problems later.
|
||||||
docker run -u $(id -u) -i -t \
|
|
||||||
--mount type=bind,source=$BF_SOURCE,target=/source \
|
if [[ "$@" == "" ]]; then
|
||||||
$BF_DOCKER
|
docker run -u $(id -u) -i -t \
|
||||||
|
--mount type=bind,source=$BF_SOURCE,target=/source \
|
||||||
|
$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) .
|
docker build -t $(IMAGE_NAME):$(IMAGE_TAG) .
|
||||||
|
|
||||||
publish: build
|
publish: build
|
||||||
docker tag $(IMAGE_NAME):20.04-lts-aos $(DOCKER_HUB_USER)/$(IMAGE_NAME):$(IMAGE_TAG)
|
docker tag $(IMAGE_NAME):$(IMAGE_TAG) $(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):latest
|
||||||
docker push $(DOCKER_HUB_USER)/$(IMAGE_NAME):$(IMAGE_TAG)
|
docker push $(DOCKER_HUB_USER)/$(IMAGE_NAME):$(IMAGE_TAG)
|
||||||
|
|
||||||
test:
|
test:
|
||||||
|
|||||||
@ -1,11 +1,16 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Copyright (c) 2021 The University of British Columbia.
|
# Copyright (c) 2021,2022 The University of British Columbia.
|
||||||
# All rights reserved.
|
# All rights reserved.
|
||||||
#
|
#
|
||||||
# This file is distributed under the terms in the attached LICENSE file.
|
# 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
|
if [ "$1" == "" ]; then
|
||||||
exec "/bin/bash"
|
exec "/bin/bash"
|
||||||
|
|||||||
@ -14,7 +14,7 @@ DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
|||||||
python3 parted wget mtools
|
python3 parted wget mtools
|
||||||
|
|
||||||
# install barrelfish dependencies
|
# install barrelfish dependencies
|
||||||
apt-get update
|
apt-get update && apt-get upgrade
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||||
build-essential bison flex ghc libghc-src-exts-dev \
|
build-essential bison flex ghc libghc-src-exts-dev \
|
||||||
libghc-ghc-paths-dev libghc-parsec3-dev libghc-random-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-update
|
||||||
cabal v1-install --global bytestring-trie
|
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
|
# get the uuu tool
|
||||||
wget -P /bin https://github.com/NXPmicro/mfgtools/releases/download/uuu_1.4.165/uuu
|
wget -P /bin https://github.com/NXPmicro/mfgtools/releases/download/uuu_1.4.165/uuu
|
||||||
chmod 755 /bin/uuu
|
chmod 755 /bin/uuu
|
||||||
@ -39,4 +43,4 @@ chmod 755 /source
|
|||||||
apt-get clean && apt-get autoclean && apt-get autoremove -y
|
apt-get clean && apt-get autoclean && apt-get autoremove -y
|
||||||
|
|
||||||
# make sure it's executable
|
# make sure it's executable
|
||||||
chmod 755 /entrypoint.sh
|
chmod 755 /entrypoint.sh
|
||||||
|
|||||||
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;
|
struct bootinfo *bi;
|
||||||
|
|
||||||
coreid_t my_core_id;
|
coreid_t my_core_id;
|
||||||
|
struct platform_info platform_info;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -56,6 +57,7 @@ bsp_main(int argc, char *argv[]) {
|
|||||||
// Grading
|
// Grading
|
||||||
grading_test_early();
|
grading_test_early();
|
||||||
|
|
||||||
|
|
||||||
// TODO: Spawn system processes, boot second core etc. here
|
// TODO: Spawn system processes, boot second core etc. here
|
||||||
|
|
||||||
// Grading
|
// Grading
|
||||||
@ -85,23 +87,45 @@ app_main(int argc, char *argv[]) {
|
|||||||
return LIB_ERR_NOT_IMPLEMENTED;
|
return LIB_ERR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
errval_t err;
|
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 */
|
/* 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);
|
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++) {
|
for (int i = 0; i < argc; i++) {
|
||||||
printf(" %s", argv[i]);
|
printf(" %s", argv[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user