├── libco ├── doc │ ├── examples │ │ ├── .gitignore │ │ ├── test.h │ │ ├── build.bat │ │ ├── build.sh │ │ ├── valgrind-wrapper.sh │ │ ├── test_timing.cpp │ │ ├── test_args.cpp │ │ └── test_serialization.cpp │ ├── targets.md │ └── usage.md ├── CMakeLists.txt ├── libco.h ├── LICENSE ├── README.md ├── libco.c ├── fiber.c ├── arm.c ├── ucontext.c ├── aarch64.c ├── x86.c ├── sjlj.c └── settings.h ├── .stylefilter ├── sos ├── src │ ├── debugger.h │ ├── tests.h │ ├── sys │ │ ├── thread.c │ │ ├── execinfo.h │ │ ├── time.c │ │ ├── exit.c │ │ ├── morecore.c │ │ └── backtrace.c │ ├── sos.lds │ ├── elfload.h │ ├── utils.h │ ├── drivers │ │ ├── uart.h │ │ └── uart.c │ ├── backtrace.h │ ├── network.h │ ├── vmem_layout.h │ ├── utils.c │ ├── threads.h │ ├── syscalls.h │ ├── bootstrap.h │ ├── dma.h │ ├── irq.h │ ├── dma.c │ ├── channel.h │ ├── mapping.h │ └── frame_table.h └── CMakeLists.txt ├── libethernet ├── src │ ├── uboot │ │ ├── config.h │ │ ├── bitops.h │ │ ├── err.h │ │ ├── common.h │ │ └── miiphy.h │ ├── unimplemented.c │ └── ethernet.c ├── CMakeLists.txt └── include │ └── ethernet │ └── ethernet.h ├── libsosapi ├── src │ ├── sys_thread.c │ ├── sys_exit.c │ ├── sys_time.c │ ├── vsyscall.c │ ├── sys_morecore.c │ ├── sos.c │ └── sys_stdio.c ├── CMakeLists.txt └── include │ ├── syscalls.h │ └── sos.h ├── apps ├── sosh │ ├── src │ │ └── benchmark.h │ ├── CMakeLists.txt │ └── parse_results.py └── console_test │ ├── CMakeLists.txt │ └── src │ └── console_test.c ├── libclock ├── CMakeLists.txt ├── include │ └── clock │ │ ├── device.h │ │ ├── timestamp.h │ │ ├── clock.h │ │ └── watchdog.h └── src │ ├── clock.c │ ├── device.c │ └── device.h ├── libsel4cspace ├── CMakeLists.txt └── include │ └── cspace │ └── bitfield.h ├── libnetworkconsole ├── CMakeLists.txt ├── include │ └── networkconsole │ │ └── networkconsole.h └── src │ └── networkconsole.c ├── reset.sh ├── libaos ├── include │ └── aos │ │ ├── strerror.h │ │ ├── debug.h │ │ ├── vsyscall.h │ │ ├── sel4_zf_logif.h │ │ └── registers.h ├── CMakeLists.txt └── src │ ├── strerror.c │ ├── vsyscall.c │ └── debug.c ├── CMakeLists.txt ├── init-build.sh ├── .gitignore ├── settings.cmake ├── aos-make-project.sh └── backtrace.py /libco/doc/examples/.gitignore: -------------------------------------------------------------------------------- 1 | test_args 2 | test_serialization 3 | test_timing 4 | *.o 5 | -------------------------------------------------------------------------------- /libco/doc/examples/test.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | -------------------------------------------------------------------------------- /libco/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(libco STATIC libco.c aarch64.c arm.c settings.h libco.h) 2 | target_include_directories(libco PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 3 | target_link_libraries(libco muslc) -------------------------------------------------------------------------------- /.stylefilter: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2020, Data61 3 | # Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | # ABN 41 687 119 230. 5 | # 6 | # This software may be distributed and modified according to the terms of 7 | # the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | # See "LICENSE_GPLv2.txt" for details. 9 | # 10 | # @TAG(DATA61_GPL) 11 | # 12 | 13 | libethernet 14 | -------------------------------------------------------------------------------- /sos/src/debugger.h: -------------------------------------------------------------------------------- 1 | #include 2 | #define VIRTUAL_UART_RECV_IRQ 0xfff 3 | 4 | #ifdef CONFIG_SOS_GDB_ENABLED 5 | #define DEBUGGER_FAULT_BIT BIT(62) 6 | seL4_Error debugger_init(cspace_t *cspace, seL4_IRQControl irq_control, seL4_CPtr recv_ep); 7 | void debugger_register_thread(seL4_CPtr ep, seL4_Word badge, seL4_CPtr tcb); 8 | void debugger_deregister_thread(seL4_CPtr ep, seL4_Word badge); 9 | #endif /* CONFIG_SOS_GDB_ENABLED */ -------------------------------------------------------------------------------- /libethernet/src/uboot/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @TAG(OTHER_GPL) 3 | */ 4 | 5 | #pragma once 6 | 7 | #define CONFIG_PHY_REALTEK 1 8 | #define CONFIG_SYS_HZ 1000 /* Current timer header uses milliseconds for get_timer */ 9 | #define CONFIG_ARM 1 10 | #define CONFIG_ARCH_MESON 1 11 | #define CONFIG_MESON_GXBB 1 12 | #define CONFIG_TARGET_ODROID_C2 1 13 | #define CONFIG_NET_RANDOM_ETHADDR 1 14 | #define CONFIG_ETH_DESIGNWARE 1 15 | #define CONFIG_PHYLIB 1 16 | -------------------------------------------------------------------------------- /sos/src/tests.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | void run_tests(cspace_t *cspace); 15 | -------------------------------------------------------------------------------- /libco/doc/examples/build.bat: -------------------------------------------------------------------------------- 1 | cc -O3 -fomit-frame-pointer -I../.. -o libco.o -c ../../libco.c 2 | c++ -O3 -fomit-frame-pointer -I../.. -c test_timing.cpp 3 | c++ -O3 -fomit-frame-pointer -o test_timing libco.o test_timing.o 4 | c++ -O3 -fomit-frame-pointer -I../.. -c test_args.cpp 5 | c++ -O3 -fomit-frame-pointer -o test_args libco.o test_args.o 6 | c++ -O3 -fomit-frame-pointer -I../.. -c test_serialization.cpp 7 | c++ -O3 -fomit-frame-pointer -o test_serialization libco.o test_serialization.o 8 | @del *.o 9 | -------------------------------------------------------------------------------- /libco/doc/examples/build.sh: -------------------------------------------------------------------------------- 1 | cc -O3 -fomit-frame-pointer -I../.. -o libco.o -c ../../libco.c 2 | c++ -O3 -fomit-frame-pointer -I../.. -c test_timing.cpp 3 | c++ -O3 -fomit-frame-pointer -o test_timing libco.o test_timing.o 4 | c++ -O3 -fomit-frame-pointer -I../.. -c test_args.cpp 5 | c++ -O3 -fomit-frame-pointer -o test_args libco.o test_args.o 6 | c++ -O3 -fomit-frame-pointer -std=c++11 -I../.. -c test_serialization.cpp 7 | c++ -O3 -fomit-frame-pointer -o test_serialization libco.o test_serialization.o 8 | rm -f *.o 9 | -------------------------------------------------------------------------------- /libsosapi/src/sys_thread.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | 15 | long sys_set_tid_address(va_list ap) 16 | { 17 | return -ENOSYS; 18 | } 19 | -------------------------------------------------------------------------------- /apps/sosh/src/benchmark.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | /* tell the compiler to only include this file once */ 13 | #pragma once 14 | 15 | /* run the benchmark */ 16 | int sos_benchmark(int debug_mode); 17 | -------------------------------------------------------------------------------- /libco/libco.h: -------------------------------------------------------------------------------- 1 | /* 2 | libco v20 (2019-10-16) 3 | author: byuu 4 | license: ISC 5 | */ 6 | 7 | #ifndef LIBCO_H 8 | #define LIBCO_H 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | typedef void* cothread_t; 15 | 16 | cothread_t co_active(void); 17 | cothread_t co_derive(void*, unsigned int, void (*)(void)); 18 | cothread_t co_create(unsigned int, void (*)(void)); 19 | void co_delete(cothread_t); 20 | void co_switch(cothread_t); 21 | int co_serializable(void); 22 | 23 | #ifdef __cplusplus 24 | } 25 | #endif 26 | 27 | /* ifndef LIBCO_H */ 28 | #endif 29 | -------------------------------------------------------------------------------- /sos/src/sys/thread.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | #include 15 | 16 | long sys_set_tid_address(UNUSED va_list ap) 17 | { 18 | return -ENOSYS; 19 | } 20 | -------------------------------------------------------------------------------- /sos/src/sos.lds: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | SECTIONS 13 | { 14 | .eh_frame : 15 | { 16 | PROVIDE (__eh_frame_start = .); 17 | KEEP (*(.eh_frame)) *(.eh_frame.*) 18 | } 19 | } 20 | INSERT AFTER .rodata; 21 | -------------------------------------------------------------------------------- /sos/src/elfload.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | int elf_load(cspace_t *cspace, seL4_CPtr loadee_vspace, elf_t *elf_file); 20 | -------------------------------------------------------------------------------- /libclock/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2019, Data61 3 | # Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | # ABN 41 687 119 230. 5 | # 6 | # This software may be distributed and modified according to the terms of 7 | # the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | # See "LICENSE_GPLv2.txt" for details. 9 | # 10 | # @TAG(DATA61_GPL) 11 | # 12 | cmake_minimum_required(VERSION 3.7.2) 13 | 14 | project(libclock C) 15 | 16 | add_library(clock EXCLUDE_FROM_ALL src/clock.c src/device.c) 17 | target_include_directories(clock PUBLIC include) 18 | target_link_libraries(clock muslc sel4 utils) 19 | -------------------------------------------------------------------------------- /libsel4cspace/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2019, Data61 3 | # Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | # ABN 41 687 119 230. 5 | # 6 | # This software may be distributed and modified according to the terms of 7 | # the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | # See "LICENSE_GPLv2.txt" for details. 9 | # 10 | # @TAG(DATA61_GPL) 11 | # 12 | cmake_minimum_required(VERSION 3.7.2) 13 | 14 | project(libsel4cspace C) 15 | 16 | add_library(sel4cspace EXCLUDE_FROM_ALL src/cspace.c) 17 | target_include_directories(sel4cspace PUBLIC include) 18 | target_link_libraries(sel4cspace muslc sel4 aos utils) 19 | -------------------------------------------------------------------------------- /sos/src/utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | #include "ut.h" 16 | 17 | extern cspace_t cspace; 18 | 19 | /* helper to allocate a ut + cslot, and retype the ut into the cslot */ 20 | ut_t *alloc_retype(seL4_CPtr *cptr, seL4_Word type, size_t size_bits); 21 | -------------------------------------------------------------------------------- /libnetworkconsole/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2019, Data61 3 | # Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | # ABN 41 687 119 230. 5 | # 6 | # This software may be distributed and modified according to the terms of 7 | # the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | # See "LICENSE_GPLv2.txt" for details. 9 | # 10 | # @TAG(DATA61_GPL) 11 | # 12 | cmake_minimum_required(VERSION 3.7.2) 13 | 14 | project(libnetworkconsole C) 15 | 16 | add_library(networkconsole EXCLUDE_FROM_ALL src/networkconsole.c) 17 | target_include_directories(networkconsole PUBLIC include) 18 | target_link_libraries(networkconsole muslc sel4 picotcp utils sos_Config) 19 | -------------------------------------------------------------------------------- /reset.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2019, Data61 4 | # Commonwealth Scientific and Industrial Research Organisation (CSIRO) 5 | # ABN 41 687 119 230. 6 | # 7 | # This software may be distributed and modified according to the terms of 8 | # the GNU General Public License version 2. Note that NO WARRANTY is provided. 9 | # See "LICENSE_GPLv2.txt" for details. 10 | # 11 | # @TAG(DATA61_GPL) 12 | # 13 | set -e 14 | 15 | PATH="${0%/*}:$PATH" 16 | 17 | echo odroid upload-boot "${PWD}/images/sos-image-arm-odroidc2" 18 | odroid upload-boot "${PWD}/images/sos-image-arm-odroidc2" 19 | 20 | echo odroid upload "${PWD}/apps/*" 21 | odroid upload "${PWD}/apps/"* 22 | 23 | echo odroid reset 24 | odroid reset 25 | -------------------------------------------------------------------------------- /libaos/include/aos/strerror.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #define sel4_error(e, str) ((e == seL4_NoError) ? (void)0 : __sel4_error(e, __FILE__, __func__, __LINE__, str)) 15 | 16 | void __sel4_error(int, const char *, const char *, int, char *); 17 | 18 | const char *sel4_strerror(int errcode); 19 | extern char *sel4_errlist[]; 20 | -------------------------------------------------------------------------------- /sos/src/drivers/uart.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | /* A very basic UART (universal asynchronous receiver and transmitter) driver */ 14 | 15 | /* initialise the uart device */ 16 | void uart_init(cspace_t *cspace); 17 | /* output a single chart on the uart device */ 18 | void uart_putchar(char c); 19 | void uart_putchar_gdb(char c); 20 | -------------------------------------------------------------------------------- /libaos/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2019, Data61 3 | # Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | # ABN 41 687 119 230. 5 | # 6 | # This software may be distributed and modified according to the terms of 7 | # the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | # See "LICENSE_GPLv2.txt" for details. 9 | # 10 | # @TAG(DATA61_GPL) 11 | # 12 | cmake_minimum_required(VERSION 3.7.2) 13 | 14 | project(libaos C) 15 | 16 | add_library(aos EXCLUDE_FROM_ALL src/debug.c src/strerror.c src/vsyscall.c) 17 | target_include_directories(aos PUBLIC include) 18 | target_link_libraries(aos sel4_autoconf muslc sel4 utils) 19 | 20 | # warn about everything 21 | add_compile_options(-Wall -Werror -W -Wextra) 22 | -------------------------------------------------------------------------------- /sos/src/sys/execinfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | //#include 14 | 15 | extern int backtrace(void **__array, int __size); 16 | //libc_hidden_proto (__backtrace) 17 | 18 | //extern char **backtrace_symbols (void *const *__array, int __size); 19 | 20 | //extern void backtrace_symbols_fd (void *const *__array, int __size, 21 | // int __fd); 22 | //libc_hidden_proto (__backtrace_symbols_fd) 23 | -------------------------------------------------------------------------------- /sos/src/backtrace.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | #include "sys/execinfo.h" 16 | 17 | static inline void print_backtrace(void) 18 | { 19 | void *array[10] = {NULL}; 20 | int size = 0; 21 | 22 | size = backtrace(array, 10); 23 | if (size) { 24 | printf("Backtracing stack PCs: \n"); 25 | for (int i = 0; i < size; i++) { 26 | printf("%p\n", array[i]); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /libethernet/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2019, Data61 3 | # Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | # ABN 41 687 119 230. 5 | # 6 | # This software may be distributed and modified according to the terms of 7 | # the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | # See "LICENSE_GPLv2.txt" for details. 9 | # 10 | # @TAG(DATA61_GPL) 11 | # 12 | cmake_minimum_required(VERSION 3.7.2) 13 | 14 | project(libethernet C) 15 | 16 | add_library( 17 | ethernet 18 | EXCLUDE_FROM_ALL 19 | src/ethernet.c 20 | src/unimplemented.c 21 | src/uboot/designware.c 22 | src/uboot/miiphyutil.c 23 | src/uboot/phy.c 24 | src/uboot/realtek.c 25 | ) 26 | target_include_directories(ethernet PUBLIC include) 27 | target_link_libraries(ethernet sel4_autoconf muslc sel4 utils clock) 28 | -------------------------------------------------------------------------------- /apps/sosh/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2019, Data61 3 | # Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | # ABN 41 687 119 230. 5 | # 6 | # This software may be distributed and modified according to the terms of 7 | # the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | # See "LICENSE_GPLv2.txt" for details. 9 | # 10 | # @TAG(DATA61_GPL) 11 | # 12 | cmake_minimum_required(VERSION 3.7.2) 13 | 14 | project(sosh C) 15 | 16 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -u __vsyscall_ptr") 17 | 18 | add_executable(sosh EXCLUDE_FROM_ALL src/benchmark.c src/sosh.c) 19 | target_include_directories(sosh PRIVATE include) 20 | target_link_libraries(sosh sel4runtime muslc sel4 sosapi utils) 21 | 22 | # warn about everything 23 | add_compile_options(-Wall -Werror -W -Wextra) 24 | 25 | add_app(sosh) 26 | -------------------------------------------------------------------------------- /apps/console_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2019, Data61 3 | # Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | # ABN 41 687 119 230. 5 | # 6 | # This software may be distributed and modified according to the terms of 7 | # the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | # See "LICENSE_GPLv2.txt" for details. 9 | # 10 | # @TAG(DATA61_GPL) 11 | # 12 | cmake_minimum_required(VERSION 3.7.2) 13 | 14 | project(console_test C) 15 | 16 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -u __vsyscall_ptr") 17 | 18 | add_executable(console_test EXCLUDE_FROM_ALL src/console_test.c) 19 | target_include_directories(console_test PRIVATE include) 20 | target_link_libraries(console_test sel4runtime muslc sel4 sosapi) 21 | 22 | # warn about everything 23 | add_compile_options(-Wall -Werror -W -Wextra) 24 | 25 | add_app(console_test) 26 | -------------------------------------------------------------------------------- /libethernet/src/uboot/bitops.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @TAG(OTHER_GPL) 3 | */ 4 | 5 | #ifndef _LINUX_BITOPS_H 6 | #define _LINUX_BITOPS_H 7 | 8 | #include "../unimplemented.h" 9 | 10 | /* 11 | * ffs: find first bit set. This is defined the same way as 12 | * the libc and compiler builtin ffs routines, therefore 13 | * differs in spirit from the above ffz (man ffs). 14 | */ 15 | 16 | static inline int generic_ffs(int x) 17 | { 18 | int r = 1; 19 | 20 | if (!x) 21 | return 0; 22 | if (!(x & 0xffff)) { 23 | x >>= 16; 24 | r += 16; 25 | } 26 | if (!(x & 0xff)) { 27 | x >>= 8; 28 | r += 8; 29 | } 30 | if (!(x & 0xf)) { 31 | x >>= 4; 32 | r += 4; 33 | } 34 | if (!(x & 3)) { 35 | x >>= 2; 36 | r += 2; 37 | } 38 | if (!(x & 1)) { 39 | x >>= 1; 40 | r += 1; 41 | } 42 | return r; 43 | } 44 | 45 | #ifndef PLATFORM_FFS 46 | # define ffs generic_ffs 47 | #endif 48 | #endif 49 | -------------------------------------------------------------------------------- /libco/LICENSE: -------------------------------------------------------------------------------- 1 | ISC License (ISC) 2 | 3 | Copyright byuu and the higan team 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 8 | 9 | The above applies to all files in this project except valgrind.h which is licensed under a BSD-style license. See the license text and copyright notice contained within that file. 10 | -------------------------------------------------------------------------------- /libaos/include/aos/debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #ifdef CONFIG_DEBUG_BUILD 22 | #define NAME_THREAD(_tcbcap, _name) seL4_DebugNameThread(_tcbcap, _name); 23 | #else 24 | #define NAME_THREAD(_tcbcap, _name) 25 | #endif 26 | 27 | void debug_cap_identify(seL4_CPtr cap); 28 | void debug_print_bootinfo(seL4_BootInfo *info); 29 | void debug_print_fault(seL4_MessageInfo_t fault, const char *thread_name); 30 | void debug_dump_registers(seL4_CPtr tcb); 31 | 32 | -------------------------------------------------------------------------------- /libsosapi/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2019, Data61 3 | # Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | # ABN 41 687 119 230. 5 | # 6 | # This software may be distributed and modified according to the terms of 7 | # the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | # See "LICENSE_GPLv2.txt" for details. 9 | # 10 | # @TAG(DATA61_GPL) 11 | # 12 | cmake_minimum_required(VERSION 3.7.2) 13 | 14 | project(libsosapi C) 15 | 16 | add_library( 17 | sosapi 18 | EXCLUDE_FROM_ALL 19 | src/sos.c 20 | src/sys_exit.c 21 | src/sys_morecore.c 22 | src/sys_stdio.c 23 | src/sys_thread.c 24 | src/sys_time.c 25 | src/vsyscall.c 26 | ) 27 | target_link_options(sosapi BEFORE INTERFACE "-Wl,-usosapi_init_syscall_table") 28 | target_include_directories(sosapi PUBLIC include) 29 | target_link_libraries(sosapi sel4runtime muslc sel4 utils aos) 30 | 31 | # warn about everything 32 | add_compile_options(-Wall -Werror -W -Wextra) 33 | -------------------------------------------------------------------------------- /libco/README.md: -------------------------------------------------------------------------------- 1 | # libco 2 | 3 | libco is a cooperative multithreading library written in C89. 4 | 5 | Although cooperative multithreading is limited to a single CPU core, it scales substantially better than preemptive multithreading. 6 | 7 | For applications that need 100,000 or more context switches per second, the kernel overhead involved in preemptive multithreading can end up becoming the bottleneck in the application. libco can easily scale to 10,000,000 or more context switches per second. 8 | 9 | Ideal use cases include servers (HTTP, RDBMS) and emulators (CPU cores, etc.) 10 | 11 | It currently includes backends for: 12 | 13 | * x86 CPUs 14 | * amd64 CPUs 15 | * PowerPC CPUs 16 | * PowerPC64 ELFv1 CPUs 17 | * PowerPC64 ELFv2 CPUs 18 | * ARM 32-bit CPUs 19 | * ARM 64-bit (AArch64) CPUs 20 | * POSIX platforms (setjmp) 21 | * Windows platforms (fibers) 22 | 23 | See [doc/targets.md] for details. 24 | 25 | See [doc/usage.md] for documentation. 26 | 27 | ## License 28 | 29 | libco is released under the ISC license. 30 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2019, Data61 3 | # Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | # ABN 41 687 119 230. 5 | # 6 | # This software may be distributed and modified according to the terms of 7 | # the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | # See "LICENSE_GPLv2.txt" for details. 9 | # 10 | # @TAG(DATA61_GPL) 11 | # 12 | cmake_minimum_required(VERSION 3.7.2) 13 | 14 | # add apps 15 | add_subdirectory(apps/console_test) 16 | add_subdirectory(apps/sosh) 17 | # add any additional apps here 18 | 19 | # add sos itself, this is your OS 20 | # and root task 21 | add_subdirectory(sos) 22 | 23 | # add libraries 24 | add_subdirectory(libaos) 25 | add_subdirectory(libclock) 26 | add_subdirectory(libco) 27 | add_subdirectory(libethernet) 28 | add_subdirectory(libsel4cspace) 29 | add_subdirectory(libnetworkconsole) 30 | add_subdirectory(libsosapi) 31 | # add any additional libs here 32 | 33 | # enable our networking libs 34 | set(LibPicotcp ON CACHE BOOL "" FORCE) 35 | set(LibPicotcpBsd ON CACHE BOOL "" FORCE) 36 | set(LibNfs ON CACHE BOOL "" FORCE) 37 | -------------------------------------------------------------------------------- /libco/libco.c: -------------------------------------------------------------------------------- 1 | #if defined(__clang__) 2 | #pragma clang diagnostic ignored "-Wparentheses" 3 | 4 | /* placing code in section(text) does not mark it executable with Clang. */ 5 | #undef LIBCO_MPROTECT 6 | #define LIBCO_MPROTECT 7 | #endif 8 | 9 | #if defined(__clang__) || defined(__GNUC__) 10 | #if defined(__i386__) 11 | #include "x86.c" 12 | #elif defined(__amd64__) 13 | #include "amd64.c" 14 | #elif defined(__arm__) 15 | #include "arm.c" 16 | #elif defined(__aarch64__) 17 | #include "aarch64.c" 18 | #elif defined(__powerpc64__) && defined(_CALL_ELF) && _CALL_ELF == 2 19 | #include "ppc64v2.c" 20 | #elif defined(_ARCH_PPC) && !defined(__LITTLE_ENDIAN__) 21 | #include "ppc.c" 22 | #elif defined(_WIN32) 23 | #include "fiber.c" 24 | #else 25 | #include "sjlj.c" 26 | #endif 27 | #elif defined(_MSC_VER) 28 | #if defined(_M_IX86) 29 | #include "x86.c" 30 | #elif defined(_M_AMD64) 31 | #include "amd64.c" 32 | #else 33 | #include "fiber.c" 34 | #endif 35 | #else 36 | #error "libco: unsupported processor, compiler or operating system" 37 | #endif 38 | -------------------------------------------------------------------------------- /libco/doc/examples/valgrind-wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | FAILURE=99 3 | SUCCESS=0 4 | 5 | expect_failure=0 6 | if [ "$1" = "--expect-failure" ]; then 7 | expect_failure=1 8 | shift 9 | fi 10 | 11 | valgrind --error-exitcode="$FAILURE" --log-file="valgrind.log" "$@" 12 | exitcode=$? 13 | # Report the log messages just in case there was anything interesting 14 | cat "valgrind.log" >&2 15 | 16 | if [ "$exitcode" -eq "$SUCCESS" ]; then 17 | # Valgrind didn't reject our code, but if it warned 18 | # about stack-switching, we care about that too. 19 | # None of our tests should use enough stack 20 | # to trigger this by accident. 21 | if grep -qlF "Warning: client switching stacks?" "valgrind.log"; then 22 | echo "Test confused Valgrind by switching stacks" >&2 23 | exitcode=$FAILURE 24 | fi 25 | fi 26 | 27 | if [ "$expect_failure" -eq 1 ]; then 28 | if [ "$exitcode" -eq "$SUCCESS" ]; then 29 | echo "Test passed, but was expected to fail?" >&2 30 | exitcode=$FAILURE 31 | else 32 | echo "Task failed as expected" >&2 33 | exitcode=$SUCCESS 34 | fi 35 | fi 36 | 37 | exit "$exitcode" 38 | -------------------------------------------------------------------------------- /sos/src/network.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | #include 16 | 17 | /** 18 | * Initialises the network stack 19 | * 20 | * @param cspace for creating slots for mappings 21 | * @param ntfn_irq badged notification object bound to SOS's endpoint, for ethernet IRQs 22 | * @param ntfn_tick badged notification object bound to SOS's endpoint, for network tick IRQs 23 | * @param timer_vaddr mapped timer device. network_init will set up a periodic network_tick 24 | * using the SoC's watchdog timer (which is not used by your timer driver 25 | * and has a completely different programming model!) 26 | */ 27 | void network_init(cspace_t *cspace, void *timer_vaddr, seL4_CPtr irq_ntfn); 28 | -------------------------------------------------------------------------------- /libsosapi/include/syscalls.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | 16 | /* call this to initialise the syscall table for muslc, this 17 | * will install the following functions such that the C library will 18 | * use them to interact with sos */ 19 | void sosapi_init_syscall_table(void); 20 | 21 | /* prototype all the syscalls we implement */ 22 | long sys_set_tid_address(va_list ap); 23 | long sys_exit(va_list ap); 24 | long sys_rt_sigprocmask(va_list ap); 25 | long sys_gettid(va_list ap); 26 | long sys_getpid(va_list ap); 27 | long sys_tgkill(va_list ap); 28 | long sys_exit_group(va_list ap); 29 | long sys_openat(va_list ap); 30 | long sys_close(va_list ap); 31 | long sys_readv(va_list ap); 32 | long sys_read(va_list ap); 33 | long sys_ioctl(va_list ap); 34 | long sys_brk(va_list ap); 35 | long sys_mmap(va_list ap); 36 | long sys_writev(va_list ap); 37 | long sys_write(va_list ap); 38 | -------------------------------------------------------------------------------- /libsosapi/src/sys_exit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include "sos.h" 16 | 17 | static void sosapi_abort() 18 | { 19 | sos_process_delete(sos_my_id()); 20 | while (1); /* We don't return after this */ 21 | } 22 | 23 | long sys_rt_sigprocmask(va_list ap) 24 | { 25 | /* abort messages with signals in order to kill itself */ 26 | return 0; 27 | } 28 | 29 | long sys_gettid(va_list ap) 30 | { 31 | /* return dummy for now */ 32 | return 0; 33 | } 34 | 35 | long sys_getpid(va_list ap) 36 | { 37 | /* assuming process IDs are the same as thread IDs*/ 38 | return 0; 39 | } 40 | 41 | long sys_exit(va_list ap) 42 | { 43 | sosapi_abort(); 44 | return 0; 45 | } 46 | 47 | long sys_exit_group(va_list ap) 48 | { 49 | sosapi_abort(); 50 | return 0; 51 | } 52 | 53 | long sys_tgkill(va_list ap) 54 | { 55 | sosapi_abort(); 56 | return 0; 57 | } 58 | 59 | -------------------------------------------------------------------------------- /libco/fiber.c: -------------------------------------------------------------------------------- 1 | #define LIBCO_C 2 | #include "libco.h" 3 | #include "settings.h" 4 | 5 | #define WINVER 0x0400 6 | #define _WIN32_WINNT 0x0400 7 | #include 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | 13 | static thread_local cothread_t co_active_ = 0; 14 | 15 | static void __stdcall co_thunk(void* coentry) { 16 | ((void (*)(void))coentry)(); 17 | } 18 | 19 | cothread_t co_active(void) { 20 | if(!co_active_) { 21 | ConvertThreadToFiber(0); 22 | co_active_ = GetCurrentFiber(); 23 | } 24 | return co_active_; 25 | } 26 | 27 | cothread_t co_derive(void* memory, unsigned int heapsize, void (*coentry)(void)) { 28 | /* Windows fibers do not allow users to supply their own memory */ 29 | return (cothread_t)0; 30 | } 31 | 32 | cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) { 33 | if(!co_active_) { 34 | ConvertThreadToFiber(0); 35 | co_active_ = GetCurrentFiber(); 36 | } 37 | return (cothread_t)CreateFiber(heapsize, co_thunk, (void*)coentry); 38 | } 39 | 40 | void co_delete(cothread_t cothread) { 41 | DeleteFiber(cothread); 42 | } 43 | 44 | void co_switch(cothread_t cothread) { 45 | co_active_ = cothread; 46 | SwitchToFiber(cothread); 47 | } 48 | 49 | int co_serializable(void) { 50 | return 0; 51 | } 52 | 53 | #ifdef __cplusplus 54 | } 55 | #endif 56 | -------------------------------------------------------------------------------- /libnetworkconsole/include/networkconsole/networkconsole.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | 13 | /* 14 | * Initialise the network console by setting up the udp socket 15 | * to communicate with your local "serial" interface. 16 | * Note that this function will fail if called before the network has 17 | * initialised. 18 | */ 19 | struct network_console *network_console_init(void); 20 | 21 | /* 22 | * Send data over the network to appear on your local "serial" interface. 23 | * Returns the length of data sent, which may be less than len, or -1 on error. 24 | */ 25 | int network_console_send(struct network_console *network_console, char *data, int len); 26 | 27 | /* 28 | * Register a handler function to be called when the network receives 29 | * incoming data from the "serial" interface. 30 | */ 31 | int network_console_register_handler(struct network_console *network_console, 32 | void (*handler)(struct network_console *network_console, char c)); 33 | -------------------------------------------------------------------------------- /libco/doc/examples/test_timing.cpp: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | enum { Iterations = 500000000 }; 3 | 4 | namespace thread { 5 | cothread_t x; 6 | cothread_t y; 7 | volatile int counter; 8 | } 9 | 10 | void co_timingtest() { 11 | for(;;) { 12 | thread::counter++; 13 | co_switch(thread::x); 14 | } 15 | } 16 | 17 | void sub_timingtest() { 18 | thread::counter++; 19 | } 20 | 21 | int main() { 22 | printf("context-switching timing test\n\n"); 23 | time_t start, end; 24 | int i, t1, t2; 25 | 26 | start = clock(); 27 | for(thread::counter = 0, i = 0; i < Iterations; i++) { 28 | sub_timingtest(); 29 | } 30 | end = clock(); 31 | 32 | t1 = (int)difftime(end, start); 33 | printf("%2.3f seconds per 50 million subroutine calls (%d iterations)\n", (float)t1 / CLOCKS_PER_SEC, thread::counter); 34 | 35 | thread::x = co_active(); 36 | thread::y = co_create(65536, co_timingtest); 37 | 38 | start = clock(); 39 | for(thread::counter = 0, i = 0; i < Iterations; i++) { 40 | co_switch(thread::y); 41 | } 42 | end = clock(); 43 | 44 | co_delete(thread::y); 45 | 46 | t2 = (int)difftime(end, start); 47 | printf("%2.3f seconds per 100 million co_switch calls (%d iterations)\n", (float)t2 / CLOCKS_PER_SEC, thread::counter); 48 | 49 | printf("co_switch skew = %fx\n\n", (double)t2 / (double)t1); 50 | return 0; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /libethernet/src/uboot/err.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @TAG(OTHER_GPL) 3 | */ 4 | #ifndef _LINUX_ERR_H 5 | #define _LINUX_ERR_H 6 | 7 | #include 8 | 9 | 10 | /* 11 | * Kernel pointers have redundant information, so we can use a 12 | * scheme where we can return either an error code or a dentry 13 | * pointer with the same return value. 14 | * 15 | * This should be a per-architecture thing, to allow different 16 | * error and pointer decisions. 17 | */ 18 | #define MAX_ERRNO 4095 19 | 20 | #ifndef __ASSEMBLY__ 21 | 22 | #define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO) 23 | 24 | static inline void *ERR_PTR(long error) 25 | { 26 | return (void *) error; 27 | } 28 | 29 | static inline long PTR_ERR(const void *ptr) 30 | { 31 | return (long) ptr; 32 | } 33 | 34 | static inline long IS_ERR(const void *ptr) 35 | { 36 | return IS_ERR_VALUE((unsigned long)ptr); 37 | } 38 | 39 | /** 40 | * ERR_CAST - Explicitly cast an error-valued pointer to another pointer type 41 | * @ptr: The pointer to cast. 42 | * 43 | * Explicitly cast an error-valued pointer to another pointer type in such a 44 | * way as to make it clear that's what's going on. 45 | */ 46 | static inline void * __must_check ERR_CAST(__force const void *ptr) 47 | { 48 | /* cast away the const */ 49 | return (void *) ptr; 50 | } 51 | 52 | #endif 53 | 54 | #endif /* _LINUX_ERR_H */ 55 | -------------------------------------------------------------------------------- /sos/src/vmem_layout.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | /* Constants for the layout of the SOS address space */ 15 | 16 | /* Address where memory used for DMA starts getting mapped. 17 | * Do not use the address range between SOS_DMA_VSTART and SOS_DMA_VEND */ 18 | #define SOS_DMA_SIZE_BITS (seL4_LargePageBits) 19 | 20 | #define SOS_SCRATCH (0xA0000000) 21 | #define SOS_DEVICE_START (0xB0000000) 22 | #define SOS_STACK (0xC0000000) 23 | #define SOS_IPC_BUFFER (0xD0000000) 24 | #define SOS_UART_RECV_BUF_ADDRESS (0xE0000000) 25 | #define SOS_STACK_PAGES 100 26 | #define SOS_UT_TABLE (0x8000000000) 27 | #define SOS_FRAME_TABLE (0x8100000000) 28 | #define SOS_FRAME_DATA (0x8200000000) 29 | 30 | /* Constants for how SOS will layout the address space of any processes it loads up */ 31 | #define PROCESS_STACK_TOP (0x90000000) 32 | #define PROCESS_IPC_BUFFER (0xA0000000) 33 | #define PROCESS_VMEM_START (0xC0000000) 34 | 35 | -------------------------------------------------------------------------------- /libsosapi/src/sys_time.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | long sys_nanosleep(va_list ap) 29 | { 30 | struct timespec *req = va_arg(ap, struct timespec *); 31 | /* construct a sleep call */ 32 | int micros = req->tv_sec * US_IN_S; 33 | micros += req->tv_nsec / NS_IN_US; 34 | sos_usleep(micros); 35 | return 0; 36 | } 37 | 38 | long sys_clock_gettime(va_list ap) 39 | { 40 | clockid_t clk_id = va_arg(ap, clockid_t); 41 | struct timespec *res = va_arg(ap, struct timespec *); 42 | if (clk_id != CLOCK_REALTIME) { 43 | return -EINVAL; 44 | } 45 | int64_t micros = sos_time_stamp(); 46 | res->tv_sec = micros / US_IN_S; 47 | res->tv_nsec = (micros % US_IN_S) * NS_IN_US; 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /init-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2019, Data61 4 | # Commonwealth Scientific and Industrial Research Organisation (CSIRO) 5 | # ABN 41 687 119 230. 6 | # 7 | # This software may be distributed and modified according to the terms of 8 | # the GNU General Public License version 2. Note that NO WARRANTY is provided. 9 | # See "LICENSE_GPLv2.txt" for details. 10 | # 11 | # @TAG(DATA61_GPL) 12 | # 13 | # This script is intended to be symlinked into the same location as your root CMakeLists.txt file 14 | # and then invoked from a clean build directory 15 | 16 | set -eu 17 | 18 | # Determine path to this script (fast, cheap "dirname"). 19 | SCRIPT_PATH=${0%/*} 20 | # Save script name for diagnostic messages (fast, cheap "basename"). 21 | SCRIPT_NAME=${0##*/} 22 | 23 | # Ensure script path and current working directory are not the same. 24 | if [ "$PWD" = "$SCRIPT_PATH" ] 25 | then 26 | echo "\"$SCRIPT_NAME\" should not be invoked from top-level directory" >&2 27 | exit 1 28 | fi 29 | 30 | # Try and make sure we weren't invoked from a source directory by checking for a 31 | # CMakeLists.txt file. 32 | if [ -e CMakeLists.txt ] 33 | then 34 | echo "\"$SCRIPT_NAME\" should be invoked from a build directory and not" \ 35 | "source directories containing a CMakeLists.txt file" >&2 36 | exit 1 37 | fi 38 | 39 | # Initialize cmake 40 | cmake \ 41 | -DAARCH64=TRUE \ 42 | -DCMAKE_TOOLCHAIN_FILE=${SCRIPT_PATH}/kernel/gcc.cmake \ 43 | -G Ninja \ 44 | $@ \ 45 | ${SCRIPT_PATH} 46 | -------------------------------------------------------------------------------- /sos/src/utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include "utils.h" 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include "ut.h" 19 | 20 | /* helper to allocate a ut + cslot, and retype the ut into the cslot */ 21 | ut_t *alloc_retype(seL4_CPtr *cptr, seL4_Word type, size_t size_bits) 22 | { 23 | /* Allocate the object */ 24 | ut_t *ut = ut_alloc(size_bits, &cspace); 25 | if (ut == NULL) { 26 | ZF_LOGE("No memory for object of size %zu", size_bits); 27 | return NULL; 28 | } 29 | 30 | /* allocate a slot to retype the memory for object into */ 31 | *cptr = cspace_alloc_slot(&cspace); 32 | if (*cptr == seL4_CapNull) { 33 | ut_free(ut); 34 | ZF_LOGE("Failed to allocate slot"); 35 | return NULL; 36 | } 37 | 38 | /* now do the retype */ 39 | seL4_Error err = cspace_untyped_retype(&cspace, ut->cap, *cptr, type, size_bits); 40 | ZF_LOGE_IFERR(err, "Failed retype untyped"); 41 | if (err != seL4_NoError) { 42 | ut_free(ut); 43 | cspace_free_slot(&cspace, *cptr); 44 | return NULL; 45 | } 46 | 47 | return ut; 48 | } 49 | -------------------------------------------------------------------------------- /libethernet/src/unimplemented.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | #include 15 | 16 | #include "unimplemented.h" 17 | 18 | uint64_t uboot_timestamp_freq = 0; 19 | 20 | void uboot_timer_init() 21 | { 22 | uboot_timestamp_freq = timestamp_get_freq(); 23 | } 24 | 25 | unsigned long simple_strtoul(const char *cp, char **endp, 26 | unsigned int base) 27 | { 28 | unsigned long result = 0; 29 | unsigned long value; 30 | 31 | if (*cp == '0') { 32 | cp++; 33 | if ((*cp == 'x') && isxdigit(cp[1])) { 34 | base = 16; 35 | cp++; 36 | } 37 | 38 | if (!base) { 39 | base = 8; 40 | } 41 | } 42 | 43 | if (!base) { 44 | base = 10; 45 | } 46 | 47 | while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp - '0' : (islower(*cp) 48 | ? toupper(*cp) : *cp) - 'A' + 10) < base) { 49 | result = result * base + value; 50 | cp++; 51 | } 52 | 53 | if (endp) { 54 | *endp = (char *)cp; 55 | } 56 | 57 | return result; 58 | } 59 | 60 | -------------------------------------------------------------------------------- /libaos/include/aos/vsyscall.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #define MUSLC_HIGHEST_SYSCALL SYS_pkey_free 21 | #define MUSLC_NUM_SYSCALLS (MUSLC_HIGHEST_SYSCALL + 1) 22 | 23 | typedef long (*muslcsys_syscall_t)(va_list); 24 | 25 | /* Installs a new handler for the given syscall. Any previous handler is returned 26 | * and can be used to provide layers of syscall handling */ 27 | muslcsys_syscall_t muslcsys_install_syscall(int syscall, muslcsys_syscall_t new_syscall); 28 | 29 | /* Some syscalls happen in the C library prior the init constructors being called, 30 | * and hence prior to syscall handlers being able to be installed. For such cases 31 | * we simply record such occurances and provide functions here for retrieving the 32 | * arguments allow a process to do anything necessary once they get to `main`. 33 | * These functions return true/false if the syscall was called on boot, and take 34 | * pointers for returning the arguments. Pointers must be non NULL 35 | */ 36 | bool muslcsys_get_boot_set_tid_address(int **arg) NONNULL(1); 37 | -------------------------------------------------------------------------------- /libclock/include/clock/device.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | 16 | #if defined(CONFIG_PLAT_ODROIDC2) 17 | #define TIMER_BASE 0xc1100000 18 | #define TIMER_MAP_BASE 0xc1109000 19 | 20 | #define TIMER_REG_START 0x940 // TIMER_MUX 21 | #elif defined(CONFIG_PLAT_ODROIDC4) 22 | #define TIMER_BASE 0xffd00000 23 | #define TIMER_MAP_BASE 0xffd0f000 24 | 25 | #define TIMER_REG_START 0x3c50 // TIMER_MUX 26 | #else 27 | #error "only odroid-c2 and odroid-c4 supported currently." 28 | #endif 29 | 30 | /** 31 | * Identifiers for each of the timeout timers. 32 | * 33 | * Whilst there are 8 countdown timers provided by the hardware, we only 34 | * make 4 accessible here as timers F-I cannot have their current 35 | * timeout read. 36 | */ 37 | typedef enum { 38 | MESON_TIMER_A, 39 | MESON_TIMER_B, 40 | MESON_TIMER_C, 41 | MESON_TIMER_D, 42 | } timeout_id_t; 43 | 44 | /** 45 | * Get the IRQ associated with a particular timer. 46 | * 47 | * @param timer The timer to find the associated IRQ for. 48 | * @return The IRQ number needed to handle timeouts for the timer. 49 | */ 50 | seL4_Word meson_timeout_irq(timeout_id_t timer); 51 | -------------------------------------------------------------------------------- /libsosapi/src/vsyscall.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | __attribute__((constructor)) 20 | void sosapi_init_syscall_table(void) 21 | { 22 | setbuf(stdout, NULL); 23 | muslcsys_install_syscall(__NR_exit, sys_exit); 24 | muslcsys_install_syscall(__NR_rt_sigprocmask, sys_rt_sigprocmask); 25 | muslcsys_install_syscall(__NR_gettid, sys_gettid); 26 | muslcsys_install_syscall(__NR_getpid, sys_getpid); 27 | muslcsys_install_syscall(__NR_tgkill, sys_tgkill); 28 | muslcsys_install_syscall(__NR_exit_group, sys_exit_group); 29 | muslcsys_install_syscall(__NR_close, sys_close); 30 | muslcsys_install_syscall(__NR_readv, sys_readv); 31 | muslcsys_install_syscall(__NR_read, sys_read); 32 | muslcsys_install_syscall(__NR_ioctl, sys_ioctl); 33 | muslcsys_install_syscall(__NR_openat, sys_openat); 34 | muslcsys_install_syscall(__NR_brk, sys_brk); 35 | muslcsys_install_syscall(__NR_writev, sys_writev); 36 | muslcsys_install_syscall(__NR_write, sys_write); 37 | muslcsys_install_syscall(__NR_set_tid_address, sys_set_tid_address); 38 | sel4runtime_set_exit(exit); 39 | } 40 | -------------------------------------------------------------------------------- /libaos/src/strerror.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | char *sel4_errlist[] = { 19 | [seL4_NoError] = "seL4_NoError", 20 | [seL4_InvalidArgument] = "seL4_InvalidArgument", 21 | [seL4_InvalidCapability] = "seL4_InvalidCapability", 22 | [seL4_IllegalOperation] = "seL4_IllegalOperation", 23 | [seL4_RangeError] = "seL4_RangeError", 24 | [seL4_AlignmentError] = "seL4_AlignmentError", 25 | [seL4_FailedLookup] = "seL4_FailedLookup", 26 | [seL4_TruncatedMessage] = "seL4_TruncatedMessage", 27 | [seL4_DeleteFirst] = "seL4_DeleteFirst", 28 | [seL4_RevokeFirst] = "seL4_RevokeFirst", 29 | [seL4_NotEnoughMemory] = "seL4_NotEnoughMemory", 30 | NULL 31 | }; 32 | 33 | const char *sel4_strerror(int errcode) 34 | { 35 | assert(errcode < sizeof(sel4_errlist) / sizeof(*sel4_errlist) - 1); 36 | return sel4_errlist[errcode]; 37 | } 38 | 39 | void __sel4_error(int sel4_error, const char *file, 40 | const char *function, int line, char *str) 41 | { 42 | printf("seL4 Error: %s, function %s, file %s, line %d: %s\n", 43 | sel4_errlist[sel4_error], 44 | function, file, line, str); 45 | abort(); 46 | } 47 | -------------------------------------------------------------------------------- /libclock/src/clock.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | #include 15 | 16 | /* The functions in src/device.h should help you interact with the timer 17 | * to set registers and configure timeouts. */ 18 | #include "device.h" 19 | 20 | static struct { 21 | volatile meson_timer_reg_t *regs; 22 | /* Add fields as you see necessary */ 23 | } clock; 24 | 25 | int start_timer(unsigned char *timer_vaddr) 26 | { 27 | int err = stop_timer(); 28 | if (err != 0) { 29 | return err; 30 | } 31 | 32 | clock.regs = (meson_timer_reg_t *)(timer_vaddr + TIMER_REG_START); 33 | 34 | return CLOCK_R_OK; 35 | } 36 | 37 | uint32_t register_timer(uint64_t delay, timer_callback_t callback, void *data) 38 | { 39 | return 0; 40 | } 41 | 42 | int remove_timer(uint32_t id) 43 | { 44 | return CLOCK_R_FAIL; 45 | } 46 | 47 | int timer_irq( 48 | void *data, 49 | seL4_Word irq, 50 | seL4_IRQHandler irq_handler 51 | ) 52 | { 53 | /* Handle the IRQ */ 54 | 55 | /* Acknowledge that the IRQ has been handled */ 56 | return CLOCK_R_FAIL; 57 | } 58 | 59 | int stop_timer(void) 60 | { 61 | /* Stop the timer from producing further interrupts and remove all 62 | * existing timeouts */ 63 | return CLOCK_R_FAIL; 64 | } 65 | -------------------------------------------------------------------------------- /sos/src/threads.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | #include 16 | #include 17 | #include "ut.h" 18 | 19 | extern cspace_t cspace; 20 | 21 | typedef struct { 22 | ut_t *tcb_ut; 23 | seL4_CPtr tcb; 24 | 25 | seL4_CPtr user_ep; 26 | seL4_CPtr fault_ep; 27 | ut_t *ipc_buffer_ut; 28 | seL4_CPtr ipc_buffer; 29 | seL4_Word ipc_buffer_vaddr; 30 | 31 | ut_t *sched_context_ut; 32 | seL4_CPtr sched_context; 33 | 34 | ut_t *stack_ut; 35 | seL4_CPtr stack; 36 | seL4_Word badge; 37 | 38 | uintptr_t tls_base; 39 | } sos_thread_t; 40 | 41 | typedef void thread_main_f(void *); 42 | 43 | extern __thread sos_thread_t *current_thread; 44 | 45 | void init_threads(seL4_CPtr ipc_ep, seL4_CPtr fault_ep, seL4_CPtr sched_ctrl_start_, seL4_CPtr sched_ctrl_end_); 46 | sos_thread_t *spawn(thread_main_f function, void *arg, seL4_Word badge, bool debugger_add); 47 | sos_thread_t *debugger_spawn(thread_main_f function, void *arg, seL4_Word badge, seL4_CPtr bound_ntfn); 48 | sos_thread_t *thread_create(thread_main_f function, void *arg, seL4_Word badge, bool resume, seL4_Word prio, 49 | seL4_CPtr bound_ntfn, bool debugger_add); 50 | int thread_suspend(sos_thread_t *thread); 51 | int thread_resume(sos_thread_t *thread); 52 | -------------------------------------------------------------------------------- /libaos/include/aos/sel4_zf_logif.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | /* sel4_zf_logif.h: 19 | * This file contains some convenience macros built on top of the ZF_LOG 20 | * library, to reduce source size and improve single-line readability. 21 | * 22 | * ZF_LOG?_IF(condition, fmt, ...): 23 | * These will call the relevant ZF_LOG?() macro if "condition" evaluates to 24 | * true at runtime. 25 | * 26 | */ 27 | 28 | #define ZF_LOGD_IFERR(err, fmt, ...) \ 29 | if ((err) != seL4_NoError) \ 30 | { ZF_LOGD("[Err %s]:\n\t" fmt, sel4_strerror(err), ## __VA_ARGS__); } 31 | 32 | #define ZF_LOGI_IFERR(err, fmt, ...) \ 33 | if ((err) != seL4_NoError) \ 34 | { ZF_LOGI("[Err %s]:\n\t" fmt, sel4_strerror(err), ## __VA_ARGS__); } 35 | 36 | #define ZF_LOGW_IFERR(err, fmt, ...) \ 37 | if ((err) != seL4_NoError) \ 38 | { ZF_LOGW("[Err %s]:\n\t" fmt, sel4_strerror(err), ## __VA_ARGS__); } 39 | 40 | #define ZF_LOGE_IFERR(err, fmt, ...) \ 41 | if ((err) != seL4_NoError) \ 42 | { ZF_LOGE("[Err %s]:\n\t" fmt, sel4_strerror(err), ## __VA_ARGS__); } 43 | 44 | #define ZF_LOGF_IFERR(err, fmt, ...) \ 45 | if ((err) != seL4_NoError) \ 46 | { ZF_LOGF("[Err %s]:\n\t" fmt, sel4_strerror(err), ## __VA_ARGS__); } 47 | 48 | -------------------------------------------------------------------------------- /apps/console_test/src/console_test.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | /**************************************************************************** 13 | * 14 | * $Id: $ 15 | * 16 | * Description: Simple milestone 0 test. 17 | * 18 | * Author: Godfrey van der Linden 19 | * Original Author: Ben Leslie 20 | * 21 | ****************************************************************************/ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | // Block a thread forever 28 | // we do this by making an unimplemented system call. 29 | static void thread_block(void) 30 | { 31 | /* construct some info about the IPC message console_test will send 32 | * to sos -- it's 1 word long */ 33 | seL4_MessageInfo_t tag = seL4_MessageInfo_new(0, 0, 0, 1); 34 | /* Set the first word in the message to 1 */ 35 | seL4_SetMR(0, 1); 36 | /* Now send the ipc -- call will send the ipc, then block until a reply 37 | * message is received */ 38 | seL4_Call(SOS_IPC_EP_CAP, tag); 39 | /* Currently SOS does not reply -- so we never come back here */ 40 | } 41 | 42 | int main(void) 43 | { 44 | do { 45 | fputs("task:\tHello world, I'm\tconsole_test!\n", stdout); 46 | thread_block(); 47 | // sleep(1); // Implement this as a syscall in the future 48 | } while (1); 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /sos/src/syscalls.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | 16 | typedef void (*vputchar_t)(char c); 17 | void update_vputchar(vputchar_t vputchar); 18 | 19 | /* prototype all the syscalls we implement */ 20 | long sys_set_tid_address(va_list ap); 21 | long sys_exit(va_list ap); 22 | long sys_rt_sigprocmask(va_list ap); 23 | long sys_gettid(va_list ap); 24 | long sys_getpid(va_list ap); 25 | long sys_tgkill(va_list ap); 26 | long sys_tkill(va_list ap); 27 | long sys_exit_group(va_list ap); 28 | long sys_ioctl(va_list ap); 29 | long sys_brk(va_list ap); 30 | long sys_mmap2(va_list ap); 31 | long sys_mmap(va_list ap); 32 | long sys_writev(va_list ap); 33 | long sys_nanosleep(va_list ap); 34 | long sys_clock_gettime(va_list ap); 35 | long sys_getuid(va_list ap); 36 | long sys_getgid(va_list ap); 37 | long sys_close(va_list ap); 38 | long sys_openat(va_list ap); 39 | long sys_socket(va_list ap); 40 | long sys_bind(va_list ap); 41 | long sys_listen(va_list ap); 42 | long sys_connect(va_list ap); 43 | long sys_accept(va_list ap); 44 | long sys_sendto(va_list ap); 45 | long sys_recvfrom(va_list ap); 46 | long sys_readv(va_list ap); 47 | long sys_getsockname(va_list ap); 48 | long sys_getpeername(va_list ap); 49 | long sys_fcntl(va_list ap); 50 | long sys_setsockopt(va_list ap); 51 | long sys_getsockopt(va_list ap); 52 | long sys_ppoll(va_list ap); 53 | long sys_madvise(UNUSED va_list ap); 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # @TAG(PUBLIC_DOMAIN) 2 | # 3 | # Much if this has been taken from https://github.com/github/gitignore 4 | 5 | ## AOS 6 | 7 | build/ 8 | 9 | ## CMAKE 10 | 11 | CMakeLists.txt.user 12 | CMakeCache.txt 13 | CMakeFiles 14 | CMakeScripts 15 | cmake_install.cmake 16 | install_manifest.txt 17 | compile_commands.json 18 | CTestTestfile.cmake 19 | _deps 20 | 21 | ## C 22 | 23 | # Prerequisites 24 | *.d 25 | 26 | # Object files 27 | *.o 28 | *.ko 29 | *.obj 30 | *.elf 31 | 32 | # Linker output 33 | *.ilk 34 | *.map 35 | *.exp 36 | 37 | # Precompiled Headers 38 | *.gch 39 | *.pch 40 | 41 | # Libraries 42 | *.lib 43 | *.a 44 | *.la 45 | *.lo 46 | 47 | # Shared objects (inc. Windows DLLs) 48 | *.dll 49 | *.so 50 | *.so.* 51 | *.dylib 52 | 53 | # Executables 54 | *.exe 55 | *.out 56 | *.app 57 | *.i*86 58 | *.x86_64 59 | *.hex 60 | 61 | # Debug files 62 | *.dSYM/ 63 | *.su 64 | *.idb 65 | *.pdb 66 | 67 | # Kernel Module Compile Results 68 | *.mod* 69 | *.cmd 70 | .tmp_versions/ 71 | modules.order 72 | Module.symvers 73 | Mkfile.old 74 | dkms.conf 75 | 76 | ## Python 77 | 78 | # Byte-compiled / optimized / DLL files 79 | __pycache__/ 80 | *.py[cod] 81 | *$py.class 82 | 83 | # C extensions 84 | *.so 85 | 86 | # Installer logs 87 | pip-log.txt 88 | pip-delete-this-directory.txt 89 | 90 | # mypy 91 | .mypy_cache/ 92 | .dmypy.json 93 | dmypy.json 94 | 95 | # Pyre type checker 96 | .pyre/ 97 | 98 | ## Editors 99 | 100 | # Swap 101 | [._]*.s[a-v][a-z] 102 | [._]*.sw[a-p] 103 | [._]s[a-rt-v][a-z] 104 | [._]ss[a-gi-z] 105 | [._]sw[a-p] 106 | 107 | # Temporary 108 | .netrwhist 109 | *~ 110 | # Auto-generated tag files 111 | tags 112 | cscope.out 113 | # Persistent undo 114 | [._]*.un~ 115 | -------------------------------------------------------------------------------- /libclock/include/clock/timestamp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | /* Timestamp and non-blocking timer functionality using the ARMv8 generic timer, 20 | * exported by the seL4 to user level. This cannot be used for blocking timeouts, 21 | * as the kernel does not export control of this timer to the user. */ 22 | 23 | static inline uint64_t timestamp_get_freq(void) 24 | { 25 | /* ask the coprocessor for the frequency of the timer */ 26 | uint64_t freq; 27 | asm volatile("mrs %0, cntfrq_el0" : "=r"(freq)); 28 | return freq; 29 | } 30 | 31 | /* return the timestamp in raw clock ticks */ 32 | static inline uint64_t timestamp_ticks(void) 33 | { 34 | uint64_t time = 0; 35 | /* ask the coprocessor for the current time */ 36 | asm volatile("mrs %0, cntvct_el0" : "=r"(time)); 37 | return time; 38 | } 39 | 40 | static inline uint64_t timestamp_ms(uint64_t freq) 41 | { 42 | assert(freq != 0); 43 | return timestamp_ticks() / (freq / MS_IN_S); 44 | } 45 | 46 | static inline uint64_t timestamp_us(uint64_t freq) 47 | { 48 | assert(freq != 0); 49 | return (US_IN_S * timestamp_ticks()) / freq; 50 | } 51 | 52 | static inline void udelay(uint64_t us, uint64_t freq) 53 | { 54 | uint64_t start = timestamp_us(freq); 55 | while (timestamp_us(freq) - start < us); 56 | } 57 | -------------------------------------------------------------------------------- /sos/src/sys/time.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | static uint64_t freq = 0; 22 | 23 | long sys_nanosleep(va_list ap) 24 | { 25 | if (unlikely(freq == 0)) { 26 | freq = timestamp_get_freq(); 27 | } 28 | 29 | struct timespec *req = va_arg(ap, struct timespec *); 30 | 31 | /* for now we just spin and yield -- TODO consider using a continuation 32 | * and setting a timeout so interrupts can be handled while sos sleeps, after the timer 33 | * milestone has been implemented */ 34 | uint64_t us = req->tv_sec * US_IN_S; 35 | us += req->tv_nsec / NS_IN_US; 36 | 37 | uint64_t start = timestamp_us(freq); 38 | while (timestamp_us(freq) - start < us) { 39 | seL4_Yield(); 40 | } 41 | 42 | return 0; 43 | } 44 | 45 | long sys_clock_gettime(va_list ap) 46 | { 47 | if (unlikely(freq == 0)) { 48 | freq = timestamp_get_freq(); 49 | } 50 | 51 | clockid_t clk_id = va_arg(ap, clockid_t); 52 | struct timespec *res = va_arg(ap, struct timespec *); 53 | if (clk_id != CLOCK_REALTIME) { 54 | return -EINVAL; 55 | } 56 | uint64_t micros = timestamp_us(freq); 57 | res->tv_sec = micros / US_IN_S; 58 | res->tv_nsec = (micros % US_IN_S) * NS_IN_US; 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /sos/src/sys/exit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | static void sos_abort(void) 18 | { 19 | printf("SOS aborted\n"); 20 | printf("To get a stack trace, call print_backtrace() from sos/src/backtrace.h\n"); 21 | printf("at the location of the cause of the abort.\n"); 22 | printf("And paste the resulting addresses into backtrace.py\n"); 23 | while (1) { 24 | seL4_Yield(); 25 | } 26 | /* We don't return after this */ 27 | } 28 | 29 | long sys_exit(UNUSED va_list ap) 30 | { 31 | abort(); 32 | return 0; 33 | } 34 | 35 | long sys_rt_sigprocmask(UNUSED va_list ap) 36 | { 37 | ZF_LOGV("Ignoring call to %s\n", __FUNCTION__); 38 | return 0; 39 | } 40 | 41 | long sys_gettid(UNUSED va_list ap) 42 | { 43 | ZF_LOGV("Ignoring call to %s\n", __FUNCTION__); 44 | return 0; 45 | } 46 | 47 | long sys_getpid(UNUSED va_list ap) 48 | { 49 | ZF_LOGV("Ignoring call to %s\n", __FUNCTION__); 50 | return 0; 51 | } 52 | 53 | long sys_tgkill(UNUSED va_list ap) 54 | { 55 | ZF_LOGV("%s assuming self kill\n", __FUNCTION__); 56 | sos_abort(); 57 | return 0; 58 | } 59 | 60 | long sys_tkill(UNUSED va_list ap) 61 | { 62 | ZF_LOGV("%s assuming self kill\n", __FUNCTION__); 63 | sos_abort(); 64 | return 0; 65 | } 66 | 67 | long sys_exit_group(UNUSED va_list ap) 68 | { 69 | ZF_LOGV("Ignoring call to %s", __FUNCTION__); 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /libsel4cspace/include/cspace/bitfield.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #define WORD_BITS (sizeof(unsigned long) * 8u) 20 | #define WORD_INDEX(bit) ((bit) / WORD_BITS) 21 | #define BIT_INDEX(bit) ((bit) % WORD_BITS) 22 | 23 | /* A bit field is simply an array of words, indexed by bit */ 24 | 25 | /* set a bit in the bitfield to 1 */ 26 | static inline void bf_set_bit(unsigned long *bits, unsigned long bit) 27 | { 28 | bits[WORD_INDEX(bit)] |= (BIT(BIT_INDEX(bit))); 29 | } 30 | 31 | /* set a bit in the bitfield to 0 */ 32 | static inline void bf_clr_bit(unsigned long *bits, unsigned long bit) 33 | { 34 | bits[WORD_INDEX(bit)] &= ~(BIT(BIT_INDEX(bit))); 35 | } 36 | 37 | static inline bool bf_get_bit(unsigned long *bits, unsigned long bit) 38 | { 39 | return (bool) !!(bits[WORD_INDEX(bit)] & (BIT(BIT_INDEX(bit)))); 40 | } 41 | 42 | static inline unsigned long bf_first_free(size_t words, unsigned long bits[words]) 43 | { 44 | /* find the first free word */ 45 | unsigned int i = 0; 46 | for (; i < words && bits[i] == ULONG_MAX; i++); 47 | 48 | unsigned long bit = i * WORD_BITS; 49 | 50 | if (i < words) { 51 | /* we want to find the first 0 bit, do this by inverting the value */ 52 | unsigned long val = ~bits[i]; 53 | /* it's illegal to call CLZL on 0, so check first */ 54 | assert(val != 0); 55 | 56 | bit += (CTZL(val)); 57 | } 58 | return bit; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /libco/doc/targets.md: -------------------------------------------------------------------------------- 1 | # Supported targets 2 | In the following lists, supported targets are only those that have been tested 3 | and confirmed working. It is quite possible that libco will work on more 4 | processors, compilers and operating systems than those listed below. 5 | 6 | The "Overhead" is the cost of switching co-routines, as compared to an ordinary 7 | C function call. 8 | 9 | ## libco.x86 10 | * **Overhead:** ~5x 11 | * **Supported processor(s):** 32-bit x86 12 | * **Supported compiler(s):** any 13 | * **Supported operating system(s):** 14 | * Windows 15 | * Mac OS X 16 | * Linux 17 | * BSD 18 | 19 | ## libco.amd64 20 | * **Overhead:** ~10x (Windows), ~6x (all other platforms) 21 | * **Supported processor(s):** 64-bit amd64 22 | * **Supported compiler(s):** any 23 | * **Supported operating system(s):** 24 | * Windows 25 | * Mac OS X 26 | * Linux 27 | * BSD 28 | 29 | ## libco.ppc 30 | * **Overhead:** ~20x 31 | * **Supported processor(s):** 32-bit PowerPC, 64-bit PowerPC 32 | * **Supported compiler(s):** GNU GCC 33 | * **Supported operating system(s):** 34 | * Mac OS X 35 | * Linux 36 | * BSD 37 | * Playstation 3 38 | 39 | **Note:** this module contains compiler flags to enable/disable FPU and Altivec 40 | support. 41 | 42 | ## libco.fiber 43 | This uses Windows' "fibers" API. 44 | * **Overhead:** ~15x 45 | * **Supported processor(s):** Processor independent 46 | * **Supported compiler(s):** any 47 | * **Supported operating system(s):** 48 | * Windows 49 | 50 | ## libco.sjlj 51 | This uses the C standard library's `setjump`/`longjmp` APIs. 52 | * **Overhead:** ~30x 53 | * **Supported processor(s):** Processor independent 54 | * **Supported compiler(s):** any 55 | * **Supported operating system(s):** 56 | * Mac OS X 57 | * Linux 58 | * BSD 59 | * Solaris 60 | 61 | ## libco.ucontext 62 | This uses the POSIX "ucontext" API. 63 | * **Overhead:** ***~300x*** 64 | * **Supported processor(s):** Processor independent 65 | * **Supported compiler(s):** any 66 | * **Supported operating system(s):** 67 | * Linux 68 | * BSD 69 | -------------------------------------------------------------------------------- /sos/src/drivers/uart.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | 14 | #include "../mapping.h" 15 | #include "uart.h" 16 | 17 | #if defined(CONFIG_PLAT_ODROIDC2) 18 | #define UART_PADDR 0xc81004c0 19 | #elif defined(CONFIG_PLAT_ODROIDC4) 20 | #define UART_PADDR 0xFF803000 21 | #else 22 | #error "only odroid-c2 and odroid-c4 supported currently." 23 | #endif 24 | 25 | static volatile struct { 26 | uint32_t wfifo; 27 | uint32_t rfifo; 28 | uint32_t control; 29 | uint32_t status; 30 | uint32_t misc; 31 | uint32_t reg5; 32 | } *uart; 33 | 34 | #define UART_STATUS_TX_FIFO_FULL BIT(21) 35 | #define UART_CONTROL_TX_ENABLE BIT(12) 36 | 37 | void uart_init(cspace_t *cspace) 38 | { 39 | /* map the device */ 40 | void *uart_vaddr = sos_map_device(cspace, PAGE_ALIGN_4K(UART_PADDR), PAGE_SIZE_4K); 41 | ZF_LOGF_IF(uart_vaddr == NULL, "Failed to map uart"); 42 | 43 | uart = uart_vaddr + (UART_PADDR & MASK((size_t) seL4_PageBits)); 44 | 45 | /* enable the device */ 46 | uart->control |= UART_CONTROL_TX_ENABLE; 47 | } 48 | 49 | void uart_putchar(char c) 50 | { 51 | /* spin until there is space in the buffer */ 52 | while (uart->status & UART_STATUS_TX_FIFO_FULL); 53 | uart->wfifo = c; 54 | 55 | /* Escape special gdb-related characters */ 56 | if (c == '$' || c == '%' || c == '+' || c == '-') { 57 | while (uart->status & UART_STATUS_TX_FIFO_FULL); 58 | uart->wfifo = c; 59 | } 60 | 61 | if (c == '\n') { 62 | uart_putchar('\r'); 63 | } 64 | } 65 | 66 | void uart_putchar_gdb(char c) { 67 | /* spin until there is space in the buffer */ 68 | while (uart->status & UART_STATUS_TX_FIFO_FULL); 69 | uart->wfifo = c; 70 | 71 | if (c == '\n') { 72 | uart_putchar('\r'); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /sos/src/bootstrap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | /* top level cspace node size, for the root cnode, in bits, where size = 2^bits */ 20 | #define INITIAL_TASK_CNODE_SIZE_BITS 18u 21 | #define INITIAL_TASK_CSPACE_BITS (CNODE_SLOT_BITS(INITIAL_TASK_CNODE_SIZE_BITS) + \ 22 | CNODE_SLOT_BITS(CNODE_SIZE_BITS)) 23 | #define INITIAL_TASK_CSPACE_SLOTS BIT(INITIAL_TASK_CSPACE_BITS) 24 | 25 | /* The total physical memory range that should be considered by SOS. 26 | * Device untypeds outside of this range will not be made available. */ 27 | #define PHYSICAL_ADDRESS_LIMIT 0xdfffffffllu 28 | /* Maximum size of untyped to consider for mapping */ 29 | #define MAX_PHYSICAL_SIZE_BITS 32llu 30 | 31 | static inline bool untyped_in_range(seL4_UntypedDesc untyped) 32 | { 33 | return untyped.paddr <= PHYSICAL_ADDRESS_LIMIT && untyped.sizeBits <= MAX_PHYSICAL_SIZE_BITS; 34 | } 35 | 36 | /** 37 | * Bootstrap the initial tasks cspace and 4k untyped allocator from what seL4 provides to the initial task. 38 | */ 39 | void sos_bootstrap(cspace_t *cspace, const seL4_BootInfo *bi); 40 | 41 | /* Map a frame, using cspace to allocate any slots. Must *not* be called from 42 | * cspace code. Frames are allocated contiguously from SOS_UT_TABLE, and no 43 | * mechanism is implemented to free them, avoid using for memory you would like 44 | * to be able to free. 45 | */ 46 | void *bootstrap_map_frame(cspace_t *cspace, seL4_CPtr cap); 47 | 48 | /* these are exported for the tests to use */ 49 | void *bootstrap_cspace_map_frame(void *cookie, seL4_CPtr cap, seL4_CPtr free_slots[MAPPING_SLOTS], seL4_Word *used); 50 | void *bootstrap_cspace_alloc_4k_ut(void *cookie, seL4_CPtr *cap); 51 | void bootstrap_cspace_free_4k_ut(void *cookie, void *untyped); 52 | -------------------------------------------------------------------------------- /sos/src/dma.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | 14 | typedef struct { 15 | uintptr_t vaddr; // virtual address of the allocated DMA memory 16 | uintptr_t paddr; // physical address of the allocated DMA memory 17 | } dma_addr_t; 18 | 19 | /** 20 | * Initialises a pool of DMA memory. 21 | * 22 | * @param cspace cspace that this allocator can use to allocate a slot with and 23 | * retype the passed in untyped with. Only used in init. 24 | * @param vspace cptr to the vspace to use for mapping and cache operations. 25 | * @param ut cptr to a ut that is seL4_LargePageBits in size 26 | * @param pstart The base physical address of the ut 27 | * @param vstart Virtual address to map the large page 28 | * @return 0 on success 29 | */ 30 | int dma_init(cspace_t *cspace, seL4_CPtr vspace, seL4_CPtr ut, uintptr_t pstart, uintptr_t vstart); 31 | 32 | /** 33 | * Allocate an amount of DMA memory. 34 | * 35 | * @param size in bytes to allocate 36 | * @param align alignment to align start of address to 37 | * @return a dma_addr_t representing the memory. On failure values will be 0. 38 | */ 39 | dma_addr_t sos_dma_malloc(size_t size, int align); 40 | 41 | /** 42 | * Convert the provided physical DMA address into a virtual address 43 | * 44 | * @param address to convert 45 | */ 46 | uintptr_t sos_dma_phys_to_virt(uintptr_t phys); 47 | 48 | /** 49 | * Convert the provided virtual DMA address into a physical address 50 | * 51 | * @param address to convert 52 | */ 53 | uintptr_t sos_dma_virt_to_phys(uintptr_t virt); 54 | 55 | /* Cache operation functions. 56 | * @param addr the start address to operate on. 57 | * @param size amount in bytes to operate on. 58 | * @return seL4_Error code that results from the invocation. 59 | */ 60 | seL4_Error sos_dma_cache_invalidate(uintptr_t addr, size_t size); 61 | seL4_Error sos_dma_cache_clean(uintptr_t addr, size_t size); 62 | seL4_Error sos_dma_cache_clean_invalidate(uintptr_t addr, size_t size); 63 | -------------------------------------------------------------------------------- /libclock/include/clock/clock.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | /* 20 | * Return codes for driver functions 21 | */ 22 | #define CLOCK_R_OK 0 /* success */ 23 | #define CLOCK_R_UINT (-1) /* driver not initialised */ 24 | #define CLOCK_R_CNCL (-2) /* operation cancelled (driver stopped) */ 25 | #define CLOCK_R_FAIL (-3) /* operation failed for other reason */ 26 | 27 | typedef uint64_t timestamp_t; 28 | typedef void (*timer_callback_t)(uint32_t id, void *data); 29 | 30 | 31 | /* 32 | * Initialise driver. Performs implicit stop_timer() if already initialised. 33 | * 34 | * @param timer_vaddr Virtual address of mapped page containing device 35 | * registers 36 | * @return CLOCK_R_OK iff successful. 37 | */ 38 | int start_timer(unsigned char *timer_vaddr); 39 | 40 | /** 41 | * Get the current clock time in microseconds. 42 | */ 43 | timestamp_t get_time(void); 44 | 45 | /** 46 | * Register a callback to be called after a given delay 47 | * 48 | * @param delay Delay time in microseconds before callback is invoked 49 | * @param callback Function to be called 50 | * @param data Custom data to be passed to callback function 51 | * @return 0 on failure, otherwise an unique ID for this timeout 52 | */ 53 | uint32_t register_timer(uint64_t delay, timer_callback_t callback, void *data); 54 | 55 | /** 56 | * Remove a previously registered callback by its ID 57 | * 58 | * @param id Unique ID returned by register_time 59 | * @return CLOCK_R_OK iff successful. 60 | */ 61 | int remove_timer(uint32_t id); 62 | 63 | /* 64 | * Stop clock driver operation. 65 | * 66 | * @return CLOCK_R_OK iff successful. 67 | */ 68 | int stop_timer(void); 69 | 70 | /* 71 | * Signal to the timer than an IRQ was received. 72 | */ 73 | int timer_irq( 74 | void *data, 75 | seL4_Word irq, 76 | seL4_IRQHandler irq_handler 77 | ); 78 | -------------------------------------------------------------------------------- /libco/arm.c: -------------------------------------------------------------------------------- 1 | #define LIBCO_C 2 | #include "libco.h" 3 | #include "settings.h" 4 | #include "valgrind.h" 5 | 6 | #ifdef LIBCO_MPROTECT 7 | #include 8 | #include 9 | #endif 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | static thread_local unsigned long co_active_buffer[64]; 16 | static thread_local cothread_t co_active_handle = 0; 17 | static void (*co_swap)(cothread_t, cothread_t) = 0; 18 | 19 | #ifdef LIBCO_MPROTECT 20 | alignas(4096) 21 | #else 22 | section(text) 23 | #endif 24 | static const unsigned long co_swap_function[1024] = { 25 | 0xe8a16ff0, /* stmia r1!, {r4-r11,sp,lr} */ 26 | 0xe8b0aff0, /* ldmia r0!, {r4-r11,sp,pc} */ 27 | 0xe12fff1e, /* bx lr */ 28 | }; 29 | 30 | static void co_init(void) { 31 | #ifdef LIBCO_MPROTECT 32 | unsigned long addr = (unsigned long)co_swap_function; 33 | unsigned long base = addr - (addr % sysconf(_SC_PAGESIZE)); 34 | unsigned long size = (addr - base) + sizeof co_swap_function; 35 | mprotect((void*)base, size, PROT_READ | PROT_EXEC); 36 | #endif 37 | } 38 | 39 | cothread_t co_active(void) { 40 | if(!co_active_handle) co_active_handle = &co_active_buffer; 41 | return co_active_handle; 42 | } 43 | 44 | cothread_t co_derive(void* memory, unsigned int size, void (*entrypoint)(void)) { 45 | unsigned long* handle; 46 | if(!co_swap) { 47 | co_init(); 48 | co_swap = (void (*)(cothread_t, cothread_t))co_swap_function; 49 | } 50 | if(!co_active_handle) co_active_handle = &co_active_buffer; 51 | 52 | VALGRIND_STACK_REGISTER(memory, memory + size); 53 | 54 | if((handle = (unsigned long*)memory)) { 55 | unsigned long stack_top = (unsigned long)handle + size; 56 | stack_top &= ~((unsigned long) 15); 57 | unsigned long *p = (unsigned long*)(stack_top); 58 | handle[8] = (unsigned long)p; 59 | handle[9] = (unsigned long)entrypoint; 60 | } 61 | 62 | return handle; 63 | } 64 | 65 | cothread_t co_create(unsigned int size, void (*entrypoint)(void)) { 66 | void* memory = LIBCO_MALLOC(size); 67 | if(!memory) return (cothread_t)0; 68 | return co_derive(memory, size, entrypoint); 69 | } 70 | 71 | void co_delete(cothread_t handle) { 72 | LIBCO_FREE(handle); 73 | } 74 | 75 | void co_switch(cothread_t handle) { 76 | cothread_t co_previous_handle = co_active_handle; 77 | co_swap(co_active_handle = handle, co_previous_handle); 78 | } 79 | 80 | int co_serializable(void) { 81 | return 1; 82 | } 83 | 84 | #ifdef __cplusplus 85 | } 86 | #endif 87 | -------------------------------------------------------------------------------- /libsosapi/src/sys_morecore.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | /* 22 | * Statically allocated morecore area. 23 | * 24 | * This is rather terrible, but is the simplest option without a 25 | * huge amount of infrastructure. 26 | */ 27 | #define MORECORE_AREA_BYTE_SIZE 0x100000 28 | char morecore_area[MORECORE_AREA_BYTE_SIZE]; 29 | 30 | /* Pointer to free space in the morecore area. */ 31 | static uintptr_t morecore_base = (uintptr_t) &morecore_area; 32 | static uintptr_t morecore_top = (uintptr_t) &morecore_area[MORECORE_AREA_BYTE_SIZE]; 33 | 34 | /* Actual morecore implementation 35 | returns 0 if failure, returns newbrk if success. 36 | */ 37 | 38 | long sys_brk(va_list ap) 39 | { 40 | 41 | uintptr_t ret; 42 | uintptr_t newbrk = va_arg(ap, uintptr_t); 43 | 44 | /*if the newbrk is 0, return the bottom of the heap*/ 45 | if (!newbrk) { 46 | ret = morecore_base; 47 | } else if (newbrk < morecore_top && newbrk > (uintptr_t)&morecore_area[0]) { 48 | ret = morecore_base = newbrk; 49 | } else { 50 | ret = 0; 51 | } 52 | 53 | return ret; 54 | } 55 | 56 | /* Large mallocs will result in muslc calling mmap, so we do a minimal implementation 57 | here to support that. We make a bunch of assumptions in the process */ 58 | long sys_mmap(va_list ap) 59 | { 60 | void *addr = va_arg(ap, void *); 61 | size_t length = va_arg(ap, size_t); 62 | int prot = va_arg(ap, int); 63 | int flags = va_arg(ap, int); 64 | int fd = va_arg(ap, int); 65 | off_t offset = va_arg(ap, off_t); 66 | 67 | if (flags & MAP_ANONYMOUS) { 68 | /* Check that we don't try and allocate more than exists */ 69 | if (length > morecore_top - morecore_base) { 70 | return -ENOMEM; 71 | } 72 | /* Steal from the top */ 73 | morecore_top -= length; 74 | return morecore_top; 75 | } 76 | ZF_LOGF("not implemented"); 77 | return -ENOMEM; 78 | } 79 | -------------------------------------------------------------------------------- /libco/doc/examples/test_args.cpp: -------------------------------------------------------------------------------- 1 | /***** 2 | * cothread parameterized function example 3 | ***** 4 | * entry point to cothreads cannot take arguments. 5 | * this is due to portability issues: each processor, 6 | * operating system, programming language and compiler 7 | * can use different parameter passing methods, so 8 | * arguments to the cothread entry points were omitted. 9 | * 10 | * however, the behavior can easily be simulated by use 11 | * of a specialized co_switch to set global parameters to 12 | * be used as function arguments. 13 | * 14 | * in this way, with a bit of extra red tape, one gains 15 | * even more flexibility than would be possible with a 16 | * fixed argument list entry point, such as void (*)(void*), 17 | * as any number of arguments can be used. 18 | * 19 | * this also eliminates race conditions where a pointer 20 | * passed to co_create may have changed or become invalidated 21 | * before call to co_switch, as said pointer would now be set 22 | * when calling co_switch, instead. 23 | *****/ 24 | 25 | #include "test.h" 26 | 27 | cothread_t thread[3]; 28 | 29 | namespace co_arg { 30 | int param_x; 31 | int param_y; 32 | }; 33 | 34 | //one could also call this co_init or somesuch if they preferred ... 35 | void co_switch(cothread_t thread, int param_x, int param_y) { 36 | co_arg::param_x = param_x; 37 | co_arg::param_y = param_y; 38 | co_switch(thread); 39 | } 40 | 41 | void co_entrypoint() { 42 | int param_x = co_arg::param_x; 43 | int param_y = co_arg::param_y; 44 | printf("co_entrypoint(%d, %d)\n", param_x, param_y); 45 | co_switch(thread[0]); 46 | 47 | //co_arg::param_x will change here (due to co_switch(cothread_t, int, int) call changing values), 48 | //however, param_x and param_y will persist as they are thread local 49 | 50 | printf("co_entrypoint(%d, %d)\n", param_x, param_y); 51 | co_switch(thread[0]); 52 | throw; 53 | } 54 | 55 | int main() { 56 | printf("cothread parameterized function example\n\n"); 57 | 58 | thread[0] = co_active(); 59 | thread[1] = co_create(65536, co_entrypoint); 60 | thread[2] = co_create(65536, co_entrypoint); 61 | 62 | //use specialized co_switch(cothread_t, int, int) for initial co_switch call 63 | co_switch(thread[1], 1, 2); 64 | co_switch(thread[2], 4, 8); 65 | 66 | //after first call, entry point arguments have been initialized, standard 67 | //co_switch(cothread_t) can be used from now on 68 | co_switch(thread[2]); 69 | co_switch(thread[1]); 70 | 71 | printf("\ndone\n"); 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /libclock/include/clock/watchdog.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | #include 16 | 17 | /* This file provides the hardware details about the watchdog timer on the odroid-c2. This device 18 | * is used by the network & reset infrastructure of this project. It has a different programming model 19 | * to ordinary timers. Do not use it for your timer driver! See the TIMER chapter, 26, in the manual 20 | * for further info, and device.h for registers intended for use by your timer driver */ 21 | 22 | #define WATCHDOG_IRQ (32) 23 | 24 | /* Watchdog device offset from TIMER_PADDR as defined in device.h */ 25 | #define WDOG_OFFSET 0x8D0 26 | 27 | /* Register offsets from TIMER_PADDR+WDOG_OFFSET */ 28 | #define WDOG_CNTL 0x0 29 | #define WDOG_TCNT 0x8 30 | #define WDOG_RESET 0xC 31 | 32 | /* Parts of CNTL register */ 33 | #define WDOG_CNTL_EN BIT(18) 34 | #define WDOG_CNTL_SYS_RESET_EN BIT(21) 35 | #define WDOG_CNTL_INTERRUPT_EN BIT(23) 36 | #define WDOG_CNTL_CLK_EN BIT(24) 37 | #define WDOG_CNTL_CLK_DIV_EN BIT(25) 38 | #define WDOG_CNTL_SYS_RESET_NOW BIT(26) 39 | #define WDOG_CNTL_CNTL_WDOG_RESET BIT(31) 40 | 41 | static volatile void *wdog = NULL; 42 | 43 | static inline void watchdog_init(void *timer_vaddr, uint16_t timeout_us) 44 | { 45 | wdog = timer_vaddr + WDOG_OFFSET; 46 | 47 | /* enable the watchdog timer in interrupt mode */ 48 | RAW_WRITE32( 49 | (WDOG_CNTL_EN | 50 | WDOG_CNTL_CLK_EN | 51 | WDOG_CNTL_CLK_DIV_EN | 52 | WDOG_CNTL_INTERRUPT_EN | 53 | 24), 54 | wdog + WDOG_CNTL); /* For 24MHz => 1 watchdog tick/us */ 55 | COMPILER_MEMORY_FENCE(); 56 | 57 | /* Set the expiry and restart it */ 58 | RAW_WRITE32(timeout_us, wdog + WDOG_TCNT); 59 | RAW_WRITE32(0, wdog + WDOG_RESET); 60 | COMPILER_MEMORY_FENCE(); 61 | } 62 | 63 | static inline void watchdog_reset(void) 64 | { 65 | ZF_LOGF_IF(wdog == NULL, "WDOG uninitialised!"); 66 | 67 | RAW_WRITE32(0, wdog + WDOG_RESET); 68 | COMPILER_MEMORY_FENCE(); 69 | } 70 | -------------------------------------------------------------------------------- /sos/src/sys/morecore.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | /* 22 | * Statically allocated morecore area. 23 | * 24 | * This is rather terrible, but is the simplest option without a 25 | * huge amount of infrastructure. 26 | */ 27 | #define MORECORE_AREA_BYTE_SIZE 0x100000 28 | char morecore_area[MORECORE_AREA_BYTE_SIZE]; 29 | 30 | /* Pointer to free space in the morecore area. */ 31 | static uintptr_t morecore_base = (uintptr_t) &morecore_area; 32 | static uintptr_t morecore_top = (uintptr_t) &morecore_area[MORECORE_AREA_BYTE_SIZE]; 33 | 34 | /* Actual morecore implementation 35 | returns 0 if failure, returns newbrk if success. 36 | */ 37 | 38 | long sys_brk(va_list ap) 39 | { 40 | uintptr_t ret; 41 | uintptr_t newbrk = va_arg(ap, uintptr_t); 42 | 43 | /*if the newbrk is 0, return the bottom of the heap*/ 44 | if (!newbrk) { 45 | ret = morecore_base; 46 | } else if (newbrk < morecore_top && newbrk > (uintptr_t)&morecore_area[0]) { 47 | ret = morecore_base = newbrk; 48 | } else { 49 | ret = 0; 50 | } 51 | 52 | return ret; 53 | } 54 | 55 | /* Large mallocs will result in muslc calling mmap, so we do a minimal implementation 56 | here to support that. We make a bunch of assumptions in the process */ 57 | 58 | long sys_mmap(va_list ap) 59 | { 60 | UNUSED void *addr = va_arg(ap, void *); 61 | size_t length = va_arg(ap, size_t); 62 | UNUSED int prot = va_arg(ap, int); 63 | int flags = va_arg(ap, int); 64 | UNUSED int fd = va_arg(ap, int); 65 | UNUSED off_t offset = va_arg(ap, off_t); 66 | 67 | if (flags & MAP_ANONYMOUS) { 68 | /* Check that we don't try and allocate more than exists */ 69 | if (length > morecore_top - morecore_base) { 70 | return -ENOMEM; 71 | } 72 | /* Steal from the top */ 73 | morecore_top -= length; 74 | return morecore_top; 75 | } 76 | ZF_LOGF("not implemented"); 77 | return -ENOMEM; 78 | } 79 | 80 | long sys_madvise(UNUSED va_list ap) 81 | { 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /sos/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2019, Data61 3 | # Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | # ABN 41 687 119 230. 5 | # 6 | # This software may be distributed and modified according to the terms of 7 | # the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | # See "LICENSE_GPLv2.txt" for details. 9 | # 10 | # @TAG(DATA61_GPL) 11 | # 12 | project(sos C) 13 | 14 | set(configure_string "") 15 | 16 | config_string(SosNFSDir SOS_NFS_DIR "NFS directory" DEFAULT "/export/odroid") 17 | 18 | config_string(SosGateway SOS_GATEWAY "Gateway IP address" DEFAULT "192.168.168.1") 19 | 20 | config_string(SosFrameLimit SOS_FRAME_LIMIT "Frame table frame limit" UNQUOTE DEFAULT "0ul") 21 | 22 | config_option( 23 | SosGDBSupport SOS_GDB_ENABLED 24 | "Debugger support" 25 | DEFAULT OFF 26 | DEPENDS "HardwareDebugAPI" 27 | ) 28 | 29 | add_config_library(sos "${configure_string}") 30 | 31 | # warn about everything 32 | add_compile_options(-Wall -W -Wextra) 33 | # enable stack unwind tables -- this allows backtrace() to work. 34 | add_compile_options(-funwind-tables) 35 | add_definitions(-DSTDSOCKET) 36 | add_definitions(-U__linux__) 37 | add_definitions(-D_SYS_POLL_H) 38 | 39 | # list of apps to include in the cpio archive 40 | get_property(apps GLOBAL PROPERTY apps_property) 41 | MakeCPIO(archive.o "${apps}") 42 | 43 | # add any new c files here 44 | add_executable( 45 | sos 46 | EXCLUDE_FROM_ALL 47 | src/bootstrap.c 48 | src/dma.c 49 | src/elf.c 50 | src/frame_table.c 51 | src/irq.c 52 | src/main.c 53 | src/mapping.c 54 | src/network.c 55 | src/ut.c 56 | src/tests.c 57 | src/sys/backtrace.c 58 | src/sys/exit.c 59 | src/sys/morecore.c 60 | src/sys/stdio.c 61 | src/sys/thread.c 62 | src/sys/time.c 63 | src/drivers/uart.c 64 | archive.o 65 | src/sos.lds 66 | src/utils.c 67 | src/threads.c 68 | src/debugger.c 69 | ) 70 | target_include_directories(sos PRIVATE "include") 71 | target_link_libraries( 72 | sos 73 | sel4_autoconf 74 | sel4runtime 75 | muslc 76 | sel4 77 | elf 78 | cpio 79 | networkconsole 80 | clock 81 | sel4cspace 82 | aos 83 | utils 84 | picotcp 85 | picotcp_bsd 86 | nfs 87 | ethernet 88 | sos_Config 89 | ) 90 | 91 | if(SosGDBSupport) 92 | target_link_libraries(sos gdb libco) 93 | endif() 94 | 95 | set_property( 96 | TARGET sos 97 | APPEND_STRING 98 | PROPERTY LINK_FLAGS " -T ${CMAKE_CURRENT_SOURCE_DIR}/src/sos.lds " 99 | ) 100 | # Set this image as the rootserver 101 | DeclareRootserver(sos) 102 | -------------------------------------------------------------------------------- /libethernet/src/uboot/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @TAG(OTHER_GPL) 3 | */ 4 | 5 | /* 6 | * (C) Copyright 2000-2009 7 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 8 | * 9 | * See file CREDITS for list of people who contributed to this 10 | * project. 11 | * 12 | * This program is free software; you can redistribute it and/or 13 | * modify it under the terms of the GNU General Public License as 14 | * published by the Free Software Foundation; either version 2 of 15 | * the License, or (at your option) any later version. 16 | * 17 | * This program is distributed in the hope that it will be useful, 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 | * GNU General Public License for more details. 21 | * 22 | * You should have received a copy of the GNU General Public License 23 | * along with this program; if not, write to the Free Software 24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 25 | * MA 02111-1307 USA 26 | */ 27 | #ifndef __COMMON_H_ 28 | #define __COMMON_H_ 1 29 | 30 | #undef _LINUX_CONFIG_H 31 | #define _LINUX_CONFIG_H 1 /* avoid reading Linux autoconf.h file */ 32 | 33 | #include "config.h" 34 | #include "../unimplemented.h" 35 | 36 | 37 | #ifdef CONFIG_POST 38 | #define CONFIG_HAS_POST 39 | #ifndef CONFIG_POST_ALT_LIST 40 | #define CONFIG_POST_STD_LIST 41 | #endif 42 | #endif 43 | 44 | #ifdef CONFIG_INIT_CRITICAL 45 | #error CONFIG_INIT_CRITICAL is deprecated! 46 | #error Read section CONFIG_SKIP_LOWLEVEL_INIT in README. 47 | #endif 48 | 49 | 50 | #define ROUND(a,b) (((a) + (b) - 1) & ~((b) - 1)) 51 | #define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) 52 | 53 | #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) 54 | 55 | 56 | 57 | #ifdef ETH_DEBUG 58 | #define _DEBUG 1 59 | #else 60 | #define _DEBUG 0 61 | #endif 62 | 63 | /* 64 | * Output a debug text when condition "cond" is met. The "cond" should be 65 | * computed by a preprocessor in the best case, allowing for the best 66 | * optimization. 67 | */ 68 | #define debug_cond(cond, fmt, args...) \ 69 | do { \ 70 | if (cond) \ 71 | printf(fmt, ##args); \ 72 | } while (0) 73 | 74 | #define debug(fmt, args...) \ 75 | debug_cond(_DEBUG, fmt, ##args) 76 | 77 | /** 78 | * container_of - cast a member of a structure out to the containing structure 79 | * @ptr: the pointer to the member. 80 | * @type: the type of the container struct this is embedded in. 81 | * @member: the name of the member within the struct. 82 | * 83 | */ 84 | #define container_of(ptr, type, member) ({ \ 85 | const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 86 | (type *)( (char *)__mptr - offsetof(type,member) );}) 87 | 88 | 89 | #endif /* __COMMON_H_ */ 90 | -------------------------------------------------------------------------------- /sos/src/irq.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | /* 13 | * Asynchronous IRQ handling and dispatch. 14 | */ 15 | 16 | #include 17 | #include 18 | 19 | #pragma once 20 | 21 | /* 22 | * An IRQ handler captures its own state and can be invoked for IRQs 23 | * that it needs to handle. 24 | */ 25 | typedef int (*sos_irq_callback_t)( 26 | void *data, 27 | seL4_Word irq, 28 | seL4_IRQHandler irq_handler 29 | ); 30 | 31 | /* 32 | * Initialise the IRQ dispatch system. 33 | * 34 | * @cspace The cspace for the sos root task 35 | * @irq_control CPtr for the IRQ control capability 36 | * @notification CPtr for the notification to which IRQs should be 37 | * attached. 38 | * @flag_bits Bits to set on badges of minted notifications to 39 | * indicate that a notification rather than an IPC was 40 | * sent. 41 | * @ident_bits Bits that can be set in minted notifications to 42 | * uniquely identify IRQs. 43 | */ 44 | void sos_init_irq_dispatch( 45 | cspace_t *cspace, 46 | seL4_IRQControl irq_control, 47 | seL4_CPtr notification, 48 | seL4_Word flag_bits, 49 | seL4_Word ident_bits 50 | ); 51 | 52 | /* 53 | * Register a new IRQ handler. 54 | * 55 | * @irq The irq number for which a handler should be 56 | * registered. 57 | * @edge_triggered Whether or not the IRQ is edge triggered. 58 | * @callback Callback to trigger for the IRQ. 59 | * @data Data to pass to the callback. 60 | * @irq_handler Pointer to a CPtr for an IRQHandler. This will be 61 | * set to the CPtr for the handler to be used to 62 | * acknowledge the IRQ (this is the same handler passed 63 | * to the registered callback). 64 | */ 65 | int sos_register_irq_handler( 66 | seL4_Word irq, 67 | bool edge_triggered, 68 | sos_irq_callback_t callback, 69 | void *data, 70 | seL4_IRQHandler *irq_handler 71 | ); 72 | 73 | /* 74 | * Handle all IRQs triggered by a notification. 75 | * 76 | * Will check all bits of the badge and call registered callbacks for 77 | * any associated IRQs, unsetting them in the badge when they have been 78 | * handled. 79 | * 80 | * Returns any errors raised during handling IRQs or 0 on success. 81 | */ 82 | int sos_handle_irq_notification(seL4_Word *badge, bool *have_reply); 83 | -------------------------------------------------------------------------------- /libco/doc/examples/test_serialization.cpp: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | #include 3 | 4 | namespace Thread { 5 | cothread_t host; 6 | cothread_t cpu; 7 | cothread_t apu; 8 | } 9 | 10 | namespace Buffer { 11 | uint8_t cpu[65536]; 12 | uint8_t apu[65536]; 13 | } 14 | 15 | namespace Memory { 16 | uint8_t* buffer; 17 | } 18 | 19 | struct CPU { 20 | static auto Enter() -> void; 21 | auto main() -> void; 22 | auto sub() -> void; 23 | auto leaf() -> void; 24 | } cpu; 25 | 26 | struct APU { 27 | static auto Enter() -> void; 28 | auto main() -> void; 29 | auto sub() -> void; 30 | auto leaf() -> void; 31 | } apu; 32 | 33 | auto CPU::Enter() -> void { 34 | while(true) cpu.main(); 35 | } 36 | 37 | auto CPU::main() -> void { 38 | printf("2\n"); 39 | sub(); 40 | } 41 | 42 | auto CPU::sub() -> void { 43 | co_switch(Thread::apu); 44 | printf("4\n"); 45 | leaf(); 46 | } 47 | 48 | auto CPU::leaf() -> void { 49 | int x = 42; 50 | co_switch(Thread::host); 51 | printf("6\n"); 52 | co_switch(Thread::apu); 53 | printf("8 (%d)\n", x); 54 | co_switch(Thread::host); 55 | } 56 | 57 | auto APU::Enter() -> void { 58 | while(true) apu.main(); 59 | } 60 | 61 | auto APU::main() -> void { 62 | printf("3\n"); 63 | sub(); 64 | } 65 | 66 | auto APU::sub() -> void { 67 | co_switch(Thread::cpu); 68 | printf("7\n"); 69 | leaf(); 70 | } 71 | 72 | auto APU::leaf() -> void { 73 | co_switch(Thread::cpu); 74 | } 75 | 76 | auto main() -> int { 77 | if(!co_serializable()) { 78 | printf("This implementation does not support serialization\n"); 79 | return 1; 80 | } 81 | 82 | Memory::buffer = (uint8_t*)malloc(2 * 65536); 83 | Memory::buffer[0] = 42; 84 | printf("%p (%u)\n", Memory::buffer, Memory::buffer[0]); 85 | 86 | Thread::host = co_active(); 87 | Thread::cpu = co_derive((void*)(Memory::buffer + 0 * 65536), 65536, CPU::Enter); 88 | Thread::apu = co_derive((void*)(Memory::buffer + 1 * 65536), 65536, APU::Enter); 89 | 90 | printf("1\n"); 91 | co_switch(Thread::cpu); 92 | 93 | printf("5\n"); 94 | memcpy(Buffer::cpu, Thread::cpu, 65536); 95 | memcpy(Buffer::apu, Thread::apu, 65536); 96 | co_switch(Thread::cpu); 97 | 98 | Thread::cpu = nullptr; 99 | Thread::apu = nullptr; 100 | Thread::cpu = co_derive((void*)(Memory::buffer + 0 * 65536), 65536, CPU::Enter); 101 | Thread::apu = co_derive((void*)(Memory::buffer + 1 * 65536), 65536, APU::Enter); 102 | 103 | printf("9\n"); 104 | memcpy(Thread::cpu, Buffer::cpu, 65536); 105 | memcpy(Thread::apu, Buffer::apu, 65536); 106 | co_switch(Thread::cpu); 107 | 108 | Thread::cpu = nullptr; 109 | Thread::apu = nullptr; 110 | free(Memory::buffer); 111 | return 0; 112 | } 113 | -------------------------------------------------------------------------------- /libsosapi/src/sos.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | static size_t sos_debug_print(const void *vData, size_t count) 21 | { 22 | #ifdef CONFIG_DEBUG_BUILD 23 | size_t i; 24 | const char *realdata = vData; 25 | for (i = 0; i < count; i++) { 26 | seL4_DebugPutChar(realdata[i]); 27 | } 28 | #endif 29 | return count; 30 | } 31 | 32 | int sos_open(const char *path, fmode_t mode) 33 | { 34 | assert(!"You need to implement this"); 35 | return -1; 36 | } 37 | 38 | int sos_close(int file) 39 | { 40 | assert(!"You need to implement this"); 41 | return -1; 42 | } 43 | 44 | int sos_read(int file, char *buf, size_t nbyte) 45 | { 46 | assert(!"You need to implement this"); 47 | return -1; 48 | } 49 | 50 | int sos_write(int file, const char *buf, size_t nbyte) 51 | { 52 | /* MILESTONE 0: implement this to use your syscall and 53 | * writes to the network console! 54 | * Writing to files will come in later milestones. 55 | */ 56 | return sos_debug_print(buf, nbyte); 57 | } 58 | 59 | int sos_getdirent(int pos, char *name, size_t nbyte) 60 | { 61 | assert(!"You need to implement this"); 62 | return -1; 63 | } 64 | 65 | int sos_stat(const char *path, sos_stat_t *buf) 66 | { 67 | assert(!"You need to implement this"); 68 | return -1; 69 | } 70 | 71 | pid_t sos_process_create(const char *path) 72 | { 73 | assert(!"You need to implement this"); 74 | return -1; 75 | } 76 | 77 | int sos_process_delete(pid_t pid) 78 | { 79 | assert(!"You need to implement this"); 80 | return -1; 81 | } 82 | 83 | pid_t sos_my_id(void) 84 | { 85 | assert(!"You need to implement this"); 86 | return -1; 87 | 88 | } 89 | 90 | int sos_process_status(sos_process_t *processes, unsigned max) 91 | { 92 | assert(!"You need to implement this"); 93 | return -1; 94 | } 95 | 96 | pid_t sos_process_wait(pid_t pid) 97 | { 98 | assert(!"You need to implement this"); 99 | return -1; 100 | 101 | } 102 | 103 | void sos_usleep(int msec) 104 | { 105 | assert(!"You need to implement this"); 106 | } 107 | 108 | int64_t sos_time_stamp(void) 109 | { 110 | assert(!"You need to implement this"); 111 | return -1; 112 | } 113 | -------------------------------------------------------------------------------- /settings.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2019, Data61 3 | # Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | # ABN 41 687 119 230. 5 | # 6 | # This software may be distributed and modified according to the terms of 7 | # the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | # See "LICENSE_GPLv2.txt" for details. 9 | # 10 | # @TAG(DATA61_GPL) 11 | # 12 | cmake_minimum_required(VERSION 3.7.2) 13 | 14 | # set the build platform 15 | set(PLATFORM odroidc2 CACHE STRING "" FORCE) 16 | 17 | # build all libs as static 18 | set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) 19 | 20 | set(project_dir "${CMAKE_CURRENT_LIST_DIR}") 21 | get_filename_component(resolved_path ${CMAKE_CURRENT_LIST_FILE} REALPATH) 22 | # repo_dir is distinct from project_dir as this file is symlinked. 23 | # project_dir corresponds to the top level project directory, and 24 | # repo_dir is the absolute path after following the symlink. 25 | get_filename_component(repo_dir ${resolved_path} DIRECTORY) 26 | 27 | include(${project_dir}/tools/seL4/cmake-tool/helpers/application_settings.cmake) 28 | 29 | correct_platform_strings() 30 | 31 | include(${project_dir}/kernel/configs/seL4Config.cmake) 32 | 33 | function(add_app app) 34 | set(destination "${CMAKE_BINARY_DIR}/apps/${app}") 35 | set_property(GLOBAL APPEND PROPERTY apps_property "$") 36 | add_custom_command( 37 | TARGET ${app} POST_BUILD 38 | COMMAND 39 | ${CMAKE_COMMAND} -E copy $ ${destination} BYPRODUCTS ${destination} 40 | ) 41 | endfunction() 42 | 43 | # set the variables for the AOS platform 44 | 45 | # export the generic timer virtual count for delay functions 46 | set(KernelArmExportVCNTUser ON CACHE BOOL "" FORCE) 47 | 48 | # export the PMU so the cycle counter can be configured at user level 49 | set(KernelArmExportPMUUser ON CACHE BOOL "" FORCE) 50 | 51 | # domains == 1 for AOS 52 | set(KernelNumDomains 1 CACHE STRING "") 53 | 54 | # just 1 core 55 | set(KernelMaxNumNodes 1 CACHE STRING "") 56 | 57 | # Enable MCS 58 | set(KernelIsMCS ON CACHE BOOL "" FORCE) 59 | 60 | # Elfloader settings that correspond to how Data61 sets its boards up. 61 | ApplyData61ElfLoaderSettings(${KernelPlatform} ${KernelSel4Arch}) 62 | 63 | # turn on all the nice features for debugging 64 | # TODO for benchmarking, you should turn these OFF. 65 | set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "" FORCE) 66 | set(KernelVerificationBuild OFF CACHE BOOL "" FORCE) 67 | set(KernelIRQReporting ON CACHE BOOL "" FORCE) 68 | set(KernelPrinting ON CACHE BOOL "" FORCE) 69 | set(KernelDebugBuild ON CACHE BOOL "" FORCE) 70 | set(HardwareDebugAPI ON CACHE BOOL "" FORCE) 71 | set(SosGDBSupport OFF CACHE BOOL "" FORCE) # Enable debugger 72 | 73 | # enable our networking libs 74 | set(LibPicotcp ON CACHE BOOL "" FORCE) 75 | set(LibPicotcpBsd ON CACHE BOOL "" FORCE) 76 | set(LibNfs ON CACHE BOOL "" FORCE) 77 | -------------------------------------------------------------------------------- /libco/ucontext.c: -------------------------------------------------------------------------------- 1 | /* 2 | WARNING: the overhead of POSIX ucontext is very high, 3 | assembly versions of libco or libco_sjlj should be much faster 4 | 5 | this library only exists for two reasons: 6 | 1: as an initial test for the viability of a ucontext implementation 7 | 2: to demonstrate the power and speed of libco over existing implementations, 8 | such as pth (which defaults to wrapping ucontext on unix targets) 9 | 10 | use this library only as a *last resort* 11 | */ 12 | 13 | #define LIBCO_C 14 | #include "libco.h" 15 | #include "settings.h" 16 | #include "valgrind.h" 17 | 18 | #define _BSD_SOURCE 19 | #define _XOPEN_SOURCE 500 20 | #include 21 | #include 22 | 23 | #ifdef __cplusplus 24 | extern "C" { 25 | #endif 26 | 27 | static thread_local ucontext_t co_primary; 28 | static thread_local ucontext_t* co_running = 0; 29 | 30 | cothread_t co_active(void) { 31 | if(!co_running) co_running = &co_primary; 32 | return (cothread_t)co_running; 33 | } 34 | 35 | cothread_t co_derive(void* memory, unsigned int heapsize, void (*coentry)(void)) { 36 | if(!co_running) co_running = &co_primary; 37 | ucontext_t* thread = (ucontext_t*)memory; 38 | memory = (unsigned char*)memory + sizeof(ucontext_t); 39 | heapsize -= sizeof(ucontext_t); 40 | if(thread) { 41 | if((!getcontext(thread) && !(thread->uc_stack.ss_sp = 0)) && (thread->uc_stack.ss_sp = memory)) { 42 | thread->uc_link = co_running; 43 | thread->uc_stack.ss_size = heapsize; 44 | makecontext(thread, coentry, 0); 45 | VALGRIND_STACK_REGISTER(thread->uc_stack.ss_sp, thread->uc_stack.ss_sp + heapsize); 46 | } else { 47 | thread = 0; 48 | } 49 | } 50 | return (cothread_t)thread; 51 | } 52 | 53 | cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) { 54 | if(!co_running) co_running = &co_primary; 55 | ucontext_t* thread = (ucontext_t*)malloc(sizeof(ucontext_t)); 56 | if(thread) { 57 | if((!getcontext(thread) && !(thread->uc_stack.ss_sp = 0)) && (thread->uc_stack.ss_sp = malloc(heapsize))) { 58 | thread->uc_link = co_running; 59 | thread->uc_stack.ss_size = heapsize; 60 | makecontext(thread, coentry, 0); 61 | VALGRIND_STACK_REGISTER(thread->uc_stack.ss_sp, thread->uc_stack.ss_sp + heapsize); 62 | } else { 63 | co_delete((cothread_t)thread); 64 | thread = 0; 65 | } 66 | } 67 | return (cothread_t)thread; 68 | } 69 | 70 | void co_delete(cothread_t cothread) { 71 | if(cothread) { 72 | if(((ucontext_t*)cothread)->uc_stack.ss_sp) { free(((ucontext_t*)cothread)->uc_stack.ss_sp); } 73 | free(cothread); 74 | } 75 | } 76 | 77 | void co_switch(cothread_t cothread) { 78 | ucontext_t* old_thread = co_running; 79 | co_running = (ucontext_t*)cothread; 80 | swapcontext(old_thread, co_running); 81 | } 82 | 83 | int co_serializable(void) { 84 | return 0; 85 | } 86 | 87 | #ifdef __cplusplus 88 | } 89 | #endif 90 | -------------------------------------------------------------------------------- /apps/sosh/parse_results.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # 3 | # Copyright 2019, Data61 4 | # Commonwealth Scientific and Industrial Research Organisation (CSIRO) 5 | # ABN 41 687 119 230. 6 | # 7 | # This software may be distributed and modified according to the terms of 8 | # the GNU General Public License version 2. Note that NO WARRANTY is provided. 9 | # See "LICENSE_GPLv2.txt" for details. 10 | # 11 | # @TAG(DATA61_GPL) 12 | # 13 | import argparse 14 | import json 15 | import numpy 16 | import matplotlib.pyplot as plt 17 | import matplotlib.ticker as ticker 18 | import sys 19 | import scipy.stats as stats 20 | 21 | KB = 1024.0 22 | CCNT_SCALE = 64 23 | CLOCK_HZ = (792000000) 24 | 25 | 26 | def kb_per_s(cycles, size): 27 | return CLOCK_HZ * size / (CCNT_SCALE * cycles) / KB 28 | 29 | 30 | def main(): 31 | parser = argparse.ArgumentParser(description='Parse AOS filesystem benchmark results') 32 | parser.add_argument('--file', type=str, help='Results file', required='True', dest='file') 33 | args = parser.parse_args() 34 | 35 | xs = dict() 36 | ys = dict() 37 | errors = dict() 38 | all_samples = [] 39 | 40 | with open(args.file, 'r') as json_in: 41 | try: 42 | rows = json.load(json_in) 43 | except ValueError as e: 44 | print("Json data invalid! error:\n {0}".format(e)) 45 | return -1 46 | 47 | for row in rows: 48 | # append the buf size to the x axis 49 | if row['name'] not in xs: 50 | xs[row['name']] = [] 51 | ys[row['name']] = [] 52 | errors[row['name']] = [] 53 | 54 | xs[row['name']].append(row.get('buf_size') / KB) 55 | 56 | # compute the checksum 57 | check_sum = sum(row['samples']) 58 | if check_sum != row['check_sum']: 59 | print('error! checksum incomplete (got {0} expected {1}) for row:\n {0}'.format( 60 | check_sum, row['check_sum'], row)) 61 | return -1 62 | 63 | samples = [kb_per_s(sample, row['file_size']) for sample in row['samples']] 64 | all_samples = all_samples + samples 65 | # compute mean and stddev 66 | average = numpy.mean(samples) 67 | error = numpy.std(samples) 68 | 69 | ys[row['name']].append(average) 70 | errors[row['name']].append(error) 71 | 72 | figure, ax = plt.subplots(len(xs.keys()), sharex=True) 73 | 74 | # construct the graph 75 | for i, key in enumerate(xs): 76 | print(xs[key]) 77 | ax[i].errorbar(xs[key], ys[key], yerr=errors[key], label=key, marker='o', linewidth=2) 78 | ax[i].grid(True) 79 | ax[i].set_ylabel('Speed (KB/s)') 80 | ax[i].set_title(key) 81 | ax[i].set_xscale('log', base=2) 82 | ax[i].xaxis.set_ticks(xs[key]) 83 | ax[i].xaxis.set_major_formatter(ticker.ScalarFormatter()) 84 | 85 | ax[len(xs.keys())-1].set_xlabel('Buffer (KB)') 86 | plt.savefig('results.png') 87 | 88 | print("Harmonic mean of all samples: {} (KB/S)".format(str(stats.hmean(all_samples)))) 89 | 90 | 91 | if __name__ == '__main__': 92 | sys.exit(main()) 93 | -------------------------------------------------------------------------------- /sos/src/dma.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | /** 13 | * This file implements very simple DMA for sos. 14 | * 15 | * It does not free. 16 | */ 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | #include "dma.h" 25 | #include "mapping.h" 26 | #include "ut.h" 27 | #include "vmem_layout.h" 28 | 29 | #define DMA_ALIGN_BITS 7 /* 128 */ 30 | #define DMA_ALIGN(a) ROUND_UP((a), DMA_ALIGN_BITS) 31 | 32 | typedef struct { 33 | /* the first virtual address */ 34 | uintptr_t vstart; 35 | /* the first physical address */ 36 | uintptr_t pstart; 37 | /* the next available physical address */ 38 | uintptr_t pnext; 39 | /* the last available physical address */ 40 | uintptr_t pend; 41 | /* a ut cptr, sufficient to allocate */ 42 | seL4_CPtr cap; 43 | /* vspace for flushing address ranges */ 44 | seL4_CPtr vspace; 45 | } dma_t; 46 | 47 | /* global dma data structure */ 48 | static dma_t dma; 49 | 50 | uintptr_t sos_dma_phys_to_virt(uintptr_t phys) 51 | { 52 | return dma.vstart + (phys - dma.pstart); 53 | } 54 | 55 | uintptr_t sos_dma_virt_to_phys(uintptr_t vaddr) 56 | { 57 | return dma.pstart + (vaddr - dma.vstart); 58 | } 59 | 60 | int dma_init(cspace_t *cspace, seL4_CPtr vspace, seL4_CPtr ut, uintptr_t pstart, uintptr_t vstart) 61 | { 62 | if (ut == seL4_CapNull || vspace == seL4_CapNull || cspace == NULL || pstart == 0) { 63 | return -1; 64 | } 65 | 66 | dma.pstart = pstart; 67 | dma.vstart = vstart; 68 | dma.pend = dma.pstart + BIT(seL4_LargePageBits); 69 | dma.pnext = dma.pstart; 70 | dma.vspace = vspace; 71 | 72 | /* now map the frame */ 73 | uintptr_t vaddr = sos_dma_phys_to_virt(dma.pstart); 74 | ZF_LOGI("DMA initialised %p <--> %p\n", (void *) vaddr, (void *) sos_dma_phys_to_virt(dma.pend)); 75 | return map_frame(NULL, ut, dma.vspace, vaddr, seL4_AllRights, seL4_ARM_Default_VMAttributes); 76 | } 77 | 78 | dma_addr_t sos_dma_malloc(size_t size, int align) 79 | { 80 | dma_addr_t addr = {0, 0}; 81 | 82 | dma.pnext = DMA_ALIGN(dma.pnext); 83 | 84 | /* Round up to the alignment */ 85 | dma.pnext = ROUND_UP(dma.pnext, align); 86 | 87 | if (dma.pnext + size >= dma.pend) { 88 | ZF_LOGE("Out of DMA memory"); 89 | return addr; 90 | } 91 | 92 | addr.vaddr = sos_dma_phys_to_virt(dma.pnext); 93 | addr.paddr = dma.pnext; 94 | 95 | /* set return values */ 96 | dma.pnext += size; 97 | ZF_LOGD("DMA: 0x%x\n", (uintptr_t) addr.vaddr); 98 | 99 | /* Clean invalidate the range to prevent seL4 cache bombs */ 100 | sos_dma_cache_clean_invalidate(addr.vaddr, size); 101 | return addr; 102 | } 103 | 104 | seL4_Error sos_dma_cache_invalidate(uintptr_t addr, size_t size) 105 | { 106 | return seL4_ARM_VSpace_Invalidate_Data(dma.vspace, addr, addr + size); 107 | } 108 | 109 | seL4_Error sos_dma_cache_clean(uintptr_t addr, size_t size) 110 | { 111 | return seL4_ARM_VSpace_Clean_Data(dma.vspace, addr, addr + size); 112 | } 113 | 114 | seL4_Error sos_dma_cache_clean_invalidate(uintptr_t addr, size_t size) 115 | { 116 | return seL4_ARM_VSpace_CleanInvalidate_Data(dma.vspace, addr, addr + size); 117 | } 118 | -------------------------------------------------------------------------------- /sos/src/channel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | #include 16 | #include "utils.h" 17 | 18 | #define CHANNEL_TYPE(name) name##_channel_t 19 | #define CHANNEL_CREATE(name, ntfn) name##_channel_create(ntfn) 20 | #define CHANNEL_SEND(name, channel, message) name##_channel_send(channel, message) 21 | #define CHANNEL_RECV(name, channel) name##_channel_recv(channel) 22 | #define CHANNEL_IS_EMPTY(name, channel) name##_channel_is_empty(channel) 23 | 24 | #define CHANNEL_DEFINE_HEADER(name, type, size) \ 25 | typedef struct { \ 26 | /* index of the next message in the buffer */ \ 27 | size_t next_msg; \ 28 | /* index of the next empty slot in the buffer */ \ 29 | size_t next_empty; \ 30 | /* Notification to indicate a message has been read (an additional shared notification) */ \ 31 | seL4_CPtr read_ntfn; \ 32 | /* Notification to indicate a message has been written (probably badged from the SOS bound notification) */ \ 33 | seL4_CPtr write_ntfn; \ 34 | type messages[size]; \ 35 | } CHANNEL_TYPE(name); \ 36 | \ 37 | CHANNEL_TYPE(name) *name##_channel_create(seL4_CPtr read_available); \ 38 | void name##_channel_send(CHANNEL_TYPE(name) *channel, type message); \ 39 | type name##_channel_recv(CHANNEL_TYPE(name) *channel); \ 40 | bool name##_channel_is_empty(CHANNEL_TYPE(name) *channel); 41 | 42 | #define CHANNEL_DEFINE_SOURCE(name, type, size) \ 43 | CHANNEL_TYPE(name) *name##_channel_create(seL4_CPtr read_available) { \ 44 | CHANNEL_TYPE(name) *channel = malloc(sizeof(*channel)); \ 45 | channel->next_msg = 0; \ 46 | channel->next_empty = 0; \ 47 | ut_t *ut = alloc_retype(&channel->read_ntfn, seL4_NotificationObject, seL4_NotificationBits); \ 48 | if (ut == NULL) { \ 49 | return NULL; \ 50 | } \ 51 | channel->write_ntfn = read_available; \ 52 | return channel; \ 53 | } \ 54 | \ 55 | void name##_channel_send(CHANNEL_TYPE(name) *channel, type message) { \ 56 | /* Wait for an empty slot in the channel */ \ 57 | while ((channel->next_empty + 1) % (size) == channel->next_msg) seL4_Wait(channel->read_ntfn, NULL); \ 58 | /* Write the message into the channel */ \ 59 | channel->messages[channel->next_empty] = message; \ 60 | /* Update the write index */ \ 61 | channel->next_empty += 1; \ 62 | channel->next_empty %= size; \ 63 | /* Signal any blocked receiver */ \ 64 | seL4_Signal(channel->write_ntfn); \ 65 | } \ 66 | \ 67 | type name##_channel_recv(CHANNEL_TYPE(name) *channel) { \ 68 | /* assert at least one message */ \ 69 | assert (channel->next_empty % (size) != channel->next_msg); \ 70 | /* read the message from the channel */ \ 71 | type message = channel->messages[channel->next_msg]; \ 72 | /* Update the read index */ \ 73 | channel->next_msg += 1; \ 74 | channel->next_msg %= size; \ 75 | /* Signal any blocked receiver */ \ 76 | seL4_Signal(channel->read_ntfn); \ 77 | return message; \ 78 | } \ 79 | \ 80 | bool name##_channel_is_empty(CHANNEL_TYPE(name) *channel) { \ 81 | return channel->next_empty % (size) == channel->next_msg % (size); \ 82 | } 83 | -------------------------------------------------------------------------------- /libco/aarch64.c: -------------------------------------------------------------------------------- 1 | #define LIBCO_C 2 | #include "libco.h" 3 | #include "settings.h" 4 | 5 | #include 6 | #ifdef LIBCO_MPROTECT 7 | #include 8 | #include 9 | #endif 10 | 11 | #include "valgrind.h" 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | static thread_local unsigned long co_active_buffer[64]; 18 | static thread_local cothread_t co_active_handle = 0; 19 | static void (*co_swap)(cothread_t, cothread_t) = 0; 20 | 21 | #ifdef LIBCO_MPROTECT 22 | alignas(4096) 23 | #else 24 | section(text) 25 | #endif 26 | static const uint32_t co_swap_function[1024] = { 27 | 0x910003f0, /* mov x16,sp */ 28 | 0xa9007830, /* stp x16,x30,[x1] */ 29 | 0xa9407810, /* ldp x16,x30,[x0] */ 30 | 0x9100021f, /* mov sp,x16 */ 31 | 0xa9015033, /* stp x19,x20,[x1, 16] */ 32 | 0xa9415013, /* ldp x19,x20,[x0, 16] */ 33 | 0xa9025835, /* stp x21,x22,[x1, 32] */ 34 | 0xa9425815, /* ldp x21,x22,[x0, 32] */ 35 | 0xa9036037, /* stp x23,x24,[x1, 48] */ 36 | 0xa9436017, /* ldp x23,x24,[x0, 48] */ 37 | 0xa9046839, /* stp x25,x26,[x1, 64] */ 38 | 0xa9446819, /* ldp x25,x26,[x0, 64] */ 39 | 0xa905703b, /* stp x27,x28,[x1, 80] */ 40 | 0xa945701b, /* ldp x27,x28,[x0, 80] */ 41 | 0xf900303d, /* str x29, [x1, 96] */ 42 | 0xf940301d, /* ldr x29, [x0, 96] */ 43 | 0x6d072428, /* stp d8, d9, [x1,112] */ 44 | 0x6d472408, /* ldp d8, d9, [x0,112] */ 45 | 0x6d082c2a, /* stp d10,d11,[x1,128] */ 46 | 0x6d482c0a, /* ldp d10,d11,[x0,128] */ 47 | 0x6d09342c, /* stp d12,d13,[x1,144] */ 48 | 0x6d49340c, /* ldp d12,d13,[x0,144] */ 49 | 0x6d0a3c2e, /* stp d14,d15,[x1,160] */ 50 | 0x6d4a3c0e, /* ldp d14,d15,[x0,160] */ 51 | 0xd61f03c0, /* br x30 */ 52 | }; 53 | 54 | static void co_init(void) { 55 | #ifdef LIBCO_MPROTECT 56 | unsigned long addr = (unsigned long)co_swap_function; 57 | unsigned long base = addr - (addr % sysconf(_SC_PAGESIZE)); 58 | unsigned long size = (addr - base) + sizeof co_swap_function; 59 | mprotect((void*)base, size, PROT_READ | PROT_EXEC); 60 | #endif 61 | } 62 | 63 | cothread_t co_active(void) { 64 | if(!co_active_handle) co_active_handle = &co_active_buffer; 65 | return co_active_handle; 66 | } 67 | 68 | cothread_t co_derive(void* memory, unsigned int size, void (*entrypoint)(void)) { 69 | unsigned long* handle; 70 | if(!co_swap) { 71 | co_init(); 72 | co_swap = (void (*)(cothread_t, cothread_t))co_swap_function; 73 | } 74 | if(!co_active_handle) co_active_handle = &co_active_buffer; 75 | 76 | VALGRIND_STACK_REGISTER(memory, memory + size); 77 | 78 | if((handle = (unsigned long*)memory)) { 79 | unsigned long stack_top = (unsigned long)handle + size; 80 | stack_top &= ~((unsigned long) 15); 81 | unsigned long *p = (unsigned long*)(stack_top); 82 | handle[0] = (unsigned long)p; /* x16 (stack pointer) */ 83 | handle[1] = (unsigned long)entrypoint; /* x30 (link register) */ 84 | handle[12] = (unsigned long)p; /* x29 (frame pointer) */ 85 | } 86 | 87 | return handle; 88 | } 89 | 90 | cothread_t co_create(unsigned int size, void (*entrypoint)(void)) { 91 | void* memory = LIBCO_MALLOC(size); 92 | if(!memory) return (cothread_t)0; 93 | return co_derive(memory, size, entrypoint); 94 | } 95 | 96 | void co_delete(cothread_t handle) { 97 | LIBCO_FREE(handle); 98 | } 99 | 100 | void co_switch(cothread_t handle) { 101 | cothread_t co_previous_handle = co_active_handle; 102 | co_swap(co_active_handle = handle, co_previous_handle); 103 | } 104 | 105 | int co_serializable(void) { 106 | return 1; 107 | } 108 | 109 | #ifdef __cplusplus 110 | } 111 | #endif 112 | -------------------------------------------------------------------------------- /aos-make-project.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Copyright 2020, Data61 4 | # Commonwealth Scientific and Industrial Research Organisation (CSIRO) 5 | # ABN 41 687 119 230. 6 | # 7 | # This software may be distributed and modified according to the terms of 8 | # the GNU General Public License version 2. Note that NO WARRANTY is provided. 9 | # See "LICENSE_GPLv2.txt" for details. 10 | # 11 | # @TAG(DATA61_GPL) 12 | # 13 | 14 | # Script to extract the aos sources from a repo managed repository into 15 | # a single dir, and maintaining the correct symbolic links. If no 16 | # directory exists a git repository is initialised. All updates to the 17 | # directory are then added and the user is then prompted for a commit 18 | # message. 19 | # 20 | # usage ./aos-make-project.sh 21 | # 22 | 23 | set -e 24 | 25 | if [ $# -eq 1 ]; then 26 | DEST_REPO=$(realpath -m "$1"); shift 27 | else 28 | echo "Usage: $0 REPOSITORY_DESITNATION" >&2 29 | exit 1 30 | fi 31 | 32 | SCRIPT_DIR=$(realpath -e "${0%/*}") 33 | 34 | main () { 35 | src_repo=$(find_repo) 36 | cd "${src_repo}" 37 | 38 | clean_repo "${src_repo}" 39 | 40 | git_try_create "${DEST_REPO}" 41 | 42 | copy_to_repo \ 43 | "${src_repo}" "${DEST_REPO}" "kernel/" \ 44 | --links 45 | copy_to_repo \ 46 | "${src_repo}" "${DEST_REPO}" "libnfs/" \ 47 | --links --exclude ".gitignore" 48 | copy_to_repo \ 49 | "${src_repo}" "${DEST_REPO}" "projects/" \ 50 | --copy-links --exclude "aos-make-project.sh" 51 | copy_to_repo \ 52 | "${src_repo}" "${DEST_REPO}" "tools/" \ 53 | --links 54 | 55 | cd "${DEST_REPO}" 56 | ln \ 57 | -srf \ 58 | "projects/aos/reset.sh" \ 59 | "${DEST_REPO}/reset.sh" 60 | ln \ 61 | -srf \ 62 | "projects/aos/odroid" \ 63 | "${DEST_REPO}/odroid" 64 | ln \ 65 | -srf \ 66 | "projects/aos/init-build.sh" \ 67 | "${DEST_REPO}/init-build.sh" 68 | mv \ 69 | "projects/aos/.gitignore" \ 70 | "${DEST_REPO}" 71 | ln \ 72 | -srf \ 73 | "projects/aos/settings.cmake" \ 74 | "${DEST_REPO}/settings.cmake" 75 | ln \ 76 | -srf \ 77 | "tools/seL4/cmake-tool/default-CMakeLists.txt" \ 78 | "${DEST_REPO}/CMakeLists.txt" 79 | 80 | git add . 81 | git commit -e 82 | echo "Repository updated in '${DEST_REPO}'" 83 | } 84 | 85 | # Find the root of the AOS repo. 86 | find_repo () { 87 | dir=$SCRIPT_DIR 88 | 89 | while ! [ "${dir}" = "/" ] && ! [ -d "${dir}/.repo" ]; do 90 | dir=$(dirname "${dir}") 91 | done 92 | 93 | if [ ! -d "${dir}/.repo" ]; then 94 | echo "Failed to find root of AOS repo" >&2 95 | exit 1 96 | else 97 | echo "${dir}" 98 | fi 99 | } 100 | 101 | # Initialise the git repository if it doesn't exist 102 | git_try_create () { 103 | repo_dir=$1; shift 104 | 105 | if [ -d "${repo_dir}/.git" ]; then 106 | echo "Adding to existing git repository \"${repo_dir}\"..." 107 | return 108 | fi 109 | 110 | echo "Creating new git repository in \"${repo_dir}\"..." 111 | git init "${repo_dir}" 112 | } 113 | 114 | # Copy files into a git repository 115 | copy_to_repo () { 116 | src_dir=$1; shift 117 | dest_dir=$1; shift 118 | relative_path=$1; shift 119 | 120 | echo "Copying ${src_dir}/${relative_path} to ${dest_dir}/${relative_path}" 121 | 122 | rsync \ 123 | -r \ 124 | --exclude ".git" \ 125 | "$@" \ 126 | "${src_dir}/${relative_path}" \ 127 | "${dest_dir}/${relative_path}" 128 | } 129 | 130 | # clean repo projects 131 | clean_repo () { 132 | repo_dir=$1; shift 133 | cd "${repo_dir}" 134 | 135 | projects=$(repo list | cut -d ':' -f 1) 136 | 137 | for project in ${projects}; do 138 | echo "Cleaning '${repo_dir}/${project}'..." 139 | cd "${repo_dir}/${project}" 140 | git clean -fX 141 | git clean -i 142 | done 143 | } 144 | 145 | # Run the script 146 | main 147 | -------------------------------------------------------------------------------- /libaos/src/vsyscall.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | /* For each TLS syscalls we record up to one occurance here that happens 20 | * on startup before the syscall table is initialized. In the case of more 21 | * than one occurance we will panic */ 22 | static bool boot_set_tid_address_happened; 23 | static int *boot_set_tid_address_arg; 24 | 25 | static long boot_set_tid_address(va_list ap) 26 | { 27 | int *tid = va_arg(ap, int *); 28 | if (boot_set_tid_address_happened) { 29 | ZF_LOGE("Boot version of set_tid_address somehow got called twice"); 30 | return 1; 31 | } 32 | boot_set_tid_address_happened = true; 33 | boot_set_tid_address_arg = tid; 34 | return 1; 35 | } 36 | 37 | bool muslcsys_get_boot_set_tid_address(int **arg) 38 | { 39 | *arg = boot_set_tid_address_arg; 40 | return boot_set_tid_address_happened; 41 | } 42 | 43 | 44 | /* Basic sys_writev for use during booting that will only use seL4_DebugPutChar */ 45 | long boot_sys_writev(va_list ap) 46 | { 47 | int UNUSED fildes = va_arg(ap, int); 48 | struct iovec *iov = va_arg(ap, struct iovec *); 49 | int iovcnt = va_arg(ap, int); 50 | 51 | ssize_t ret = 0; 52 | 53 | for (int i = 0; i < iovcnt; i++) { 54 | char *UNUSED base = (char *)iov[i].iov_base; 55 | for (int j = 0; j < iov[i].iov_len; j++) { 56 | #ifdef CONFIG_PRINTING 57 | seL4_DebugPutChar(base[j]); 58 | #endif 59 | ret++; 60 | } 61 | } 62 | 63 | return ret; 64 | } 65 | 66 | static muslcsys_syscall_t syscall_table[MUSLC_NUM_SYSCALLS] = { 67 | [__NR_set_tid_address] = boot_set_tid_address, 68 | [__NR_writev] = boot_sys_writev, 69 | }; 70 | 71 | muslcsys_syscall_t muslcsys_install_syscall(int syscall, muslcsys_syscall_t new_syscall) 72 | { 73 | muslcsys_syscall_t ret; 74 | if (syscall >= ARRAY_SIZE(syscall_table)) { 75 | ZF_LOGF("Syscall %d exceeds syscall table size of %zu", syscall, ARRAY_SIZE(syscall_table)); 76 | } else { 77 | ret = syscall_table[syscall]; 78 | syscall_table[syscall] = new_syscall; 79 | } 80 | return ret; 81 | } 82 | 83 | static void debug_error(int sysnum) 84 | { 85 | char buf[100]; 86 | int i; 87 | sprintf(buf, "aos: Error attempting syscall %d\n", sysnum); 88 | for (i = 0; buf[i]; i++) { 89 | #ifdef CONFIG_PRINTING 90 | seL4_DebugPutChar(buf[i]); 91 | #endif 92 | } 93 | } 94 | 95 | long sel4_vsyscall(long sysnum, ...) 96 | { 97 | va_list al; 98 | va_start(al, sysnum); 99 | muslcsys_syscall_t syscall; 100 | if (sysnum < 0 || sysnum >= ARRAY_SIZE(syscall_table)) { 101 | debug_error(sysnum); 102 | return -ENOSYS; 103 | } else { 104 | syscall = syscall_table[sysnum]; 105 | } 106 | /* Check a syscall is implemented there */ 107 | if (!syscall) { 108 | debug_error(sysnum); 109 | return -ENOSYS; 110 | } 111 | /* Call it */ 112 | long ret = syscall(al); 113 | va_end(al); 114 | return ret; 115 | } 116 | 117 | extern void *__sysinfo; 118 | 119 | __attribute__((constructor)) 120 | static void init_vsyscall(void) 121 | { 122 | __sysinfo = sel4_vsyscall; 123 | } 124 | 125 | /* Put a pointer to sel4_vsyscall in a special section so anyone loading us 126 | * knows how to configure our syscall table */ 127 | uintptr_t VISIBLE SECTION("__vsyscall") __vsyscall_ptr = (uintptr_t) sel4_vsyscall; 128 | -------------------------------------------------------------------------------- /libethernet/src/ethernet.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | 15 | #include "uboot/common.h" 16 | #include "uboot/net.h" 17 | #include "uboot/miiphy.h" 18 | #include "io.h" 19 | #include "uboot/netdev.h" 20 | #include "unimplemented.h" 21 | 22 | #include 23 | #include 24 | 25 | static struct eth_device uboot_eth_dev; 26 | 27 | ethif_dma_ops_t dma_ops = {NULL}; 28 | ethif_recv_callback_t ethif_recv_callback = NULL; 29 | 30 | ethif_err_t ethif_send(uint8_t *buf, uint32_t len) 31 | { 32 | assert(buf); 33 | return (uboot_eth_dev.send(&uboot_eth_dev, buf, len) == 0) ? ETHIF_NOERROR : ETHIF_ERROR; 34 | } 35 | 36 | ethif_err_t ethif_recv(int *len) 37 | { 38 | assert(len); 39 | int result = uboot_eth_dev.recv(&uboot_eth_dev); 40 | if (result >= 0) { 41 | *len = result; 42 | return ETHIF_NOERROR; 43 | } 44 | return ETHIF_ERROR; 45 | } 46 | 47 | void uboot_process_received_packet(uint8_t *in_packet, int len) 48 | { 49 | ethif_recv_callback(in_packet, len); 50 | } 51 | 52 | ethif_dma_ops_t *uboot_get_dma_ops() 53 | { 54 | return &dma_ops; 55 | } 56 | 57 | int designware_ack(struct eth_device *dev); 58 | void ethif_irq(void) 59 | { 60 | designware_ack(&uboot_eth_dev); 61 | } 62 | 63 | ethif_err_t ethif_init(uint64_t base_addr, uint8_t mac_out[6], ethif_dma_ops_t *ops, 64 | ethif_recv_callback_t recv_callback) 65 | { 66 | assert(ops); 67 | assert(recv_callback); 68 | assert(mac_out); 69 | 70 | ZF_LOGI("Initialising ethernet interface..."); 71 | 72 | /* Save a copy of the DMA ops for use by the driver */ 73 | memcpy(&dma_ops, ops, sizeof(ethif_dma_ops_t)); 74 | 75 | ethif_recv_callback = recv_callback; 76 | 77 | uboot_timer_init(); 78 | 79 | /* Initialise the MII abstraction layer */ 80 | miiphy_init(); 81 | 82 | /* Initialise the actual Realtek PHY */ 83 | phy_init(); 84 | 85 | /* Populate the eth_dev functions, also does some more PHY init */ 86 | int ret = designware_initialize(base_addr, 0, &uboot_eth_dev); 87 | 88 | if (ret != 0) { 89 | ZF_LOGE("Failed: designware_initialize."); 90 | return ETHIF_ERROR; 91 | } 92 | 93 | /* We must read the MAC address out of the device after the register 94 | * addresses have been initialized (designware_initialize), but before 95 | * initializing the hardware (uboot_eth_dev.init), because initializing 96 | * the hardware involves a soft reset which will wipe the MAC address 97 | * which was configured by u-boot */ 98 | 99 | ret = designware_read_hwaddr(&uboot_eth_dev, mac_out); 100 | 101 | if (ret != 0) { 102 | ZF_LOGE("Failed: designware_read_hwaddr."); 103 | return ETHIF_ERROR; 104 | } 105 | 106 | ZF_LOGI("Read MAC as [%02x:%02x:%02x:%02x:%02x:%02x]", 107 | mac_out[0], 108 | mac_out[1], 109 | mac_out[2], 110 | mac_out[3], 111 | mac_out[4], 112 | mac_out[5]); 113 | 114 | /* NOTE: This line determines what our MAC address will be, it is 115 | * internally programmed into the device during the next init step*/ 116 | memcpy(uboot_eth_dev.enetaddr, mac_out, 6); 117 | 118 | /* Bring up the interface - the last initialisation step */ 119 | ret = uboot_eth_dev.init(&uboot_eth_dev); 120 | 121 | if (ret != 0) { 122 | ZF_LOGE("Failed: uboot_eth_dev.init()."); 123 | return ETHIF_ERROR; 124 | } 125 | 126 | ZF_LOGI("interface UP"); 127 | 128 | return ETHIF_NOERROR; 129 | } 130 | -------------------------------------------------------------------------------- /sos/src/mapping.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | /** 19 | * Maps a page. 20 | * 21 | * Intermediate paging structures will be created if required, but empty slots must be provided to 22 | * allocate them. 23 | * 24 | * This function is used by the bootstrapped cspace to allocate new bookkeeping data. To avoid 25 | * infinite recursion, we provide MAPPING_SLOTS free slots to this function: pre allocated slots 26 | * which we know are free. Without this, allocating a slot could cause recursion into the map_frame 27 | * function, which could then recurse back to allocating slots... etc. 28 | * 29 | * TODO: any allocated intermediate paging structures are thrown away by this function. 30 | * This is fine for basic SOS, but once you have a structure for tracking process virtual memory, 31 | * you'll need to modify this function, or write a new one, that stores the intermediate structures, such that 32 | * they can be deleted later. 33 | * 34 | * @param cspace CSpace which can be used to retype slots. 35 | * @param frame_cap A capbility to the frame to be mapped (seL4_ARM_SmallPageObject). 36 | * @param vspace A capability to the vspace (seL4_ARM_PageGlobalDirectoryObject). 37 | * @param vaddr The virtual address to map the frame. 38 | * @param rights The access rights for the mapping 39 | * @param attr The VM attributes to use for the mapping 40 | * @param free_slots free slots in cspace to use in case paging structures must be allocated. 41 | * @param[out] used the function will mark each bit for each slot used. 42 | * e.g if slot 0 is used, BIT(0) in used will be set. 43 | * @return 0 on success 44 | */ 45 | seL4_Error map_frame_cspace(cspace_t *cspace, seL4_CPtr frame_cap, seL4_CPtr vspace, seL4_Word vaddr, 46 | seL4_CapRights_t rights, seL4_ARM_VMAttributes attr, 47 | seL4_CPtr free_slots[MAPPING_SLOTS], seL4_Word *used); 48 | 49 | 50 | /* Maps a page, allocating intermediate structures and cslots with the cspace provided. 51 | * 52 | * If you *know* you can map the vaddr without allocating any other paging structures, or that it is 53 | * safe to allocate cslots, you can provide NULL as the cspace. 54 | 55 | * TODO: any allocated intermediate paging structures and slots are thrown away by this function. 56 | * This is fine for basic SOS, but once you have a structure for tracking process virtual memory, 57 | * you'll need to modify this function, or write a new one, that stores the intermediate structures, such that 58 | * they can be deleted later. 59 | * 60 | * @param cspace CSpace which can be used to allocate slots for intermediate paging structures. 61 | * @param frame_cap A capbility to the frame to be mapped (seL4_ARM_SmallPageObject). 62 | * @param vspace A capability to the vspace (seL4_ARM_PageGlobalDirectoryObject). 63 | * @param vaddr The virtual address to map the frame. 64 | * @param rights The access rights for the mapping 65 | * @param attr The VM attributes to use for the mapping 66 | * 67 | * @return 0 on success 68 | */ 69 | seL4_Error map_frame(cspace_t *cspace, seL4_CPtr frame_cap, seL4_CPtr vspace, seL4_Word vaddr, seL4_CapRights_t rights, 70 | seL4_ARM_VMAttributes attr); 71 | 72 | /* 73 | * Map a device and return the virtual address it is mapped to. 74 | * 75 | * @param cspace cspace to use to allocate slots 76 | * @param addr physical address of the device 77 | * @param size size of the device in bytes 78 | * @return address that the device is mapped at. 79 | * */ 80 | void *sos_map_device(cspace_t *cspace, uintptr_t addr, size_t size); 81 | -------------------------------------------------------------------------------- /libethernet/include/ethernet/ethernet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | 16 | #include 17 | 18 | /** 19 | * This file provides a low-level interface to the designware ethernet MAC on this platform. 20 | * Link-layer frames move between this driver and higher layers through ethif_send/recv. 21 | * Most of this driver is ported from u-boot. 22 | */ 23 | 24 | /** 25 | * MMIO address of the ethernet MAC, for use by sos_map_device. The virtual address 26 | * that the device is mapped at should then be passed to ethif_init as the base address. 27 | */ 28 | #if defined(CONFIG_PLAT_ODROIDC2) 29 | #define ETH_PHYS_ADDR 0xc9410000 30 | #define ETH_PHYS_SIZE 0x10000 31 | #elif defined(CONFIG_PLAT_ODROIDC4) 32 | #define ETH_PHYS_ADDR 0xFF3F0000 33 | #define ETH_PHYS_SIZE 0x10000 34 | #else 35 | #error "only odroid-c2 and odroid-c4 supported currently." 36 | #endif 37 | 38 | #define MAXIMUM_TRANSFER_UNIT 1500 39 | 40 | typedef enum { 41 | ETHIF_NOERROR = 0, 42 | ETHIF_ERROR = -1 43 | } ethif_err_t; 44 | 45 | typedef struct { 46 | uintptr_t vaddr; /* virtual address of the allocated DMA memory */ 47 | uintptr_t paddr; /* physical address of the allocated DMA memory */ 48 | size_t size; /* size of the allocated DMA memory */ 49 | } ethif_dma_addr_t; 50 | 51 | /* 52 | * DMA operations required by the ethernet interface driver 53 | */ 54 | typedef struct { 55 | ethif_dma_addr_t (*dma_malloc)(uint32_t size, uint32_t align); 56 | uintptr_t (*dma_phys_to_virt)(uintptr_t phys); 57 | uint32_t (*flush_dcache_range)(uintptr_t addr, size_t size); 58 | uint32_t (*invalidate_dcache_range)(uintptr_t addr, size_t size); 59 | } ethif_dma_ops_t; 60 | 61 | /** 62 | * Called by ethernet driver when a frame is received (inside an ethif_recv()) 63 | * This function must be defined by code which uses this driver, and passed into ethif_init. 64 | * 65 | * See ethif_recv for more information. 66 | * 67 | * @param in_packet packet received - *must* be copied in this function, memory will be re-used later 68 | * @param len length of received packet 69 | */ 70 | typedef void (*ethif_recv_callback_t)(uint8_t *in_packet, int len); 71 | 72 | /** 73 | * Initialise the ethernet interface. 74 | * 75 | * @param base_addr virtual address of the ethernet MAC (from sos_map_device) 76 | * @param mac pointer to MAC address to be populated (using u-boot settings) 77 | * @param ops populated ethif_dma_ops_t containg DMA operations for use by the driver 78 | * @param recv_callback user-defined ethif_recv_callback_t. 79 | * @return ethif_err_t 80 | */ 81 | ethif_err_t ethif_init(uint64_t base_addr, uint8_t mac_out[6], ethif_dma_ops_t *ops, 82 | ethif_recv_callback_t recv_callback); 83 | 84 | /** 85 | * Queue the provided frame for transmission, and send at next opportunity. 86 | * 87 | * This function does not block. 88 | * If there are no free transmit descriptors, the packet will be dropped and ETHIF_ERROR returned 89 | * 90 | * @param buf buffer containing frame contents to send 91 | * @param len length of buffer to send 92 | * @return ethif_err_t 93 | */ 94 | ethif_err_t ethif_send(uint8_t *buf, uint32_t len); 95 | 96 | /** 97 | * Poll the receive buffers for a packet. 98 | * 99 | * This function does not block. 100 | * Calls user-defined 'ethif_recv_callback_t' if a packet arrives, with the packet contents. 101 | * Note that ETHIF_NOERROR is still returned if no packets are available, however the packet 102 | * length will be set to 0. 103 | * 104 | * @param len pointer to variable to store packet length (0 if no packets) 105 | * @return ethif_err_t 106 | */ 107 | ethif_err_t ethif_recv(int *len); 108 | 109 | void ethif_irq(void); 110 | -------------------------------------------------------------------------------- /libco/x86.c: -------------------------------------------------------------------------------- 1 | #define LIBCO_C 2 | #include "libco.h" 3 | #include "settings.h" 4 | 5 | #ifdef __cplusplus 6 | extern "C" { 7 | #endif 8 | 9 | #if defined(__clang__) || defined(__GNUC__) 10 | #define fastcall __attribute__((fastcall)) 11 | #elif defined(_MSC_VER) 12 | #define fastcall __fastcall 13 | #else 14 | #error "libco: please define fastcall macro" 15 | #endif 16 | 17 | static thread_local long co_active_buffer[64]; 18 | static thread_local cothread_t co_active_handle = 0; 19 | static void (fastcall *co_swap)(cothread_t, cothread_t) = 0; 20 | 21 | #ifdef LIBCO_MPROTECT 22 | alignas(4096) 23 | #else 24 | section(text) 25 | #endif 26 | /* ABI: fastcall */ 27 | static const unsigned char co_swap_function[4096] = { 28 | 0x89, 0x22, /* mov [edx],esp */ 29 | 0x8b, 0x21, /* mov esp,[ecx] */ 30 | 0x58, /* pop eax */ 31 | 0x89, 0x6a, 0x04, /* mov [edx+ 4],ebp */ 32 | 0x89, 0x72, 0x08, /* mov [edx+ 8],esi */ 33 | 0x89, 0x7a, 0x0c, /* mov [edx+12],edi */ 34 | 0x89, 0x5a, 0x10, /* mov [edx+16],ebx */ 35 | 0x8b, 0x69, 0x04, /* mov ebp,[ecx+ 4] */ 36 | 0x8b, 0x71, 0x08, /* mov esi,[ecx+ 8] */ 37 | 0x8b, 0x79, 0x0c, /* mov edi,[ecx+12] */ 38 | 0x8b, 0x59, 0x10, /* mov ebx,[ecx+16] */ 39 | 0xff, 0xe0, /* jmp eax */ 40 | }; 41 | 42 | #ifdef _WIN32 43 | /* The macro logic below matches what valgrind.h is able to handle. Although 44 | * there's no Valgrind on Windows, it's possible to run a Windows exe on Linux 45 | * with Wine and Valgrind. See https://wiki.winehq.org/Wine_and_Valgrind. */ 46 | #if defined(__GNUC__) || defined(_MSC_VER) 47 | #include "valgrind.h" 48 | #endif 49 | 50 | #include 51 | 52 | static void co_init(void) { 53 | #ifdef LIBCO_MPROTECT 54 | DWORD old_privileges; 55 | VirtualProtect((void*)co_swap_function, sizeof co_swap_function, PAGE_EXECUTE_READ, &old_privileges); 56 | #endif 57 | } 58 | #else 59 | #include "valgrind.h" 60 | #ifdef LIBCO_MPROTECT 61 | #include 62 | #include 63 | #endif 64 | 65 | static void co_init(void) { 66 | #ifdef LIBCO_MPROTECT 67 | unsigned long addr = (unsigned long)co_swap_function; 68 | unsigned long base = addr - (addr % sysconf(_SC_PAGESIZE)); 69 | unsigned long size = (addr - base) + sizeof co_swap_function; 70 | mprotect((void*)base, size, PROT_READ | PROT_EXEC); 71 | #endif 72 | } 73 | #endif 74 | 75 | static void crash(void) { 76 | LIBCO_ASSERT(0); /* called only if cothread_t entrypoint returns */ 77 | } 78 | 79 | cothread_t co_active(void) { 80 | if(!co_active_handle) co_active_handle = &co_active_buffer; 81 | return co_active_handle; 82 | } 83 | 84 | cothread_t co_derive(void* memory, unsigned int size, void (*entrypoint)(void)) { 85 | cothread_t handle; 86 | if(!co_swap) { 87 | co_init(); 88 | co_swap = (void (fastcall*)(cothread_t, cothread_t))co_swap_function; 89 | } 90 | if(!co_active_handle) co_active_handle = &co_active_buffer; 91 | 92 | #if defined(__VALGRIND_MAJOR__) 93 | VALGRIND_STACK_REGISTER(memory, (char*)memory + size); 94 | #endif 95 | 96 | if((handle = (cothread_t)memory)) { 97 | unsigned long stack_top = (unsigned long)handle + size; 98 | stack_top -= 32; 99 | stack_top &= ~((unsigned long) 15); 100 | long *p = (long*)(stack_top); /* seek to top of stack */ 101 | *--p = (long)crash; /* crash if entrypoint returns */ 102 | *--p = (long)entrypoint; /* start of function */ 103 | *(long*)handle = (long)p; /* stack pointer */ 104 | } 105 | 106 | return handle; 107 | } 108 | 109 | cothread_t co_create(unsigned int size, void (*entrypoint)(void)) { 110 | void* memory = LIBCO_MALLOC(size); 111 | if(!memory) return (cothread_t)0; 112 | return co_derive(memory, size, entrypoint); 113 | } 114 | 115 | void co_delete(cothread_t handle) { 116 | LIBCO_FREE(handle); 117 | } 118 | 119 | void co_switch(cothread_t handle) { 120 | register cothread_t co_previous_handle = co_active_handle; 121 | co_swap(co_active_handle = handle, co_previous_handle); 122 | } 123 | 124 | int co_serializable(void) { 125 | return 1; 126 | } 127 | 128 | #ifdef __cplusplus 129 | } 130 | #endif 131 | -------------------------------------------------------------------------------- /libco/sjlj.c: -------------------------------------------------------------------------------- 1 | /* 2 | note this was designed for UNIX systems. Based on ideas expressed in a paper by Ralf Engelschall. 3 | for SJLJ on other systems, one would want to rewrite springboard() and co_create() and hack the jmb_buf stack pointer. 4 | */ 5 | 6 | #define LIBCO_C 7 | #include "libco.h" 8 | #include "settings.h" 9 | #include "valgrind.h" 10 | 11 | #define _BSD_SOURCE 12 | #define _XOPEN_SOURCE 500 13 | #include 14 | #include 15 | #include 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | typedef struct { 22 | sigjmp_buf context; 23 | void (*coentry)(void); 24 | void* stack; 25 | } cothread_struct; 26 | 27 | static thread_local cothread_struct co_primary; 28 | static thread_local cothread_struct* creating; 29 | static thread_local cothread_struct* co_running = 0; 30 | 31 | static void springboard(int ignored) { 32 | if(sigsetjmp(creating->context, 0)) { 33 | co_running->coentry(); 34 | } 35 | } 36 | 37 | cothread_t co_active(void) { 38 | if(!co_running) co_running = &co_primary; 39 | return (cothread_t)co_running; 40 | } 41 | 42 | cothread_t co_derive(void* memory, unsigned int size, void (*coentry)(void)) { 43 | if(!co_running) co_running = &co_primary; 44 | 45 | cothread_struct* thread = (cothread_struct*)memory; 46 | memory = (unsigned char*)memory + sizeof(cothread_struct); 47 | size -= sizeof(cothread_struct); 48 | if(thread) { 49 | struct sigaction handler; 50 | struct sigaction old_handler; 51 | 52 | stack_t stack; 53 | stack_t old_stack; 54 | 55 | thread->coentry = thread->stack = 0; 56 | 57 | stack.ss_flags = 0; 58 | stack.ss_size = size; 59 | thread->stack = stack.ss_sp = memory; 60 | if(stack.ss_sp && !sigaltstack(&stack, &old_stack)) { 61 | handler.sa_handler = springboard; 62 | handler.sa_flags = SA_ONSTACK; 63 | sigemptyset(&handler.sa_mask); 64 | creating = thread; 65 | 66 | if(!sigaction(SIGUSR1, &handler, &old_handler)) { 67 | if(!raise(SIGUSR1)) { 68 | thread->coentry = coentry; 69 | } 70 | sigaltstack(&old_stack, 0); 71 | sigaction(SIGUSR1, &old_handler, 0); 72 | } 73 | } 74 | 75 | if(thread->coentry != coentry) { 76 | co_delete(thread); 77 | thread = 0; 78 | } else { 79 | VALGRIND_STACK_REGISTER(stack.ss_sp, stack.ss_sp + size); 80 | } 81 | } 82 | 83 | return (cothread_t)thread; 84 | } 85 | 86 | cothread_t co_create(unsigned int size, void (*coentry)(void)) { 87 | if(!co_running) co_running = &co_primary; 88 | 89 | cothread_struct* thread = (cothread_struct*)malloc(sizeof(cothread_struct)); 90 | if(thread) { 91 | struct sigaction handler; 92 | struct sigaction old_handler; 93 | 94 | stack_t stack; 95 | stack_t old_stack; 96 | 97 | thread->coentry = thread->stack = 0; 98 | 99 | stack.ss_flags = 0; 100 | stack.ss_size = size; 101 | thread->stack = stack.ss_sp = malloc(size); 102 | if(stack.ss_sp && !sigaltstack(&stack, &old_stack)) { 103 | handler.sa_handler = springboard; 104 | handler.sa_flags = SA_ONSTACK; 105 | sigemptyset(&handler.sa_mask); 106 | creating = thread; 107 | 108 | if(!sigaction(SIGUSR1, &handler, &old_handler)) { 109 | if(!raise(SIGUSR1)) { 110 | thread->coentry = coentry; 111 | } 112 | sigaltstack(&old_stack, 0); 113 | sigaction(SIGUSR1, &old_handler, 0); 114 | } 115 | } 116 | 117 | if(thread->coentry != coentry) { 118 | co_delete(thread); 119 | thread = 0; 120 | } else { 121 | VALGRIND_STACK_REGISTER(stack.ss_sp, stack.ss_sp + size); 122 | } 123 | } 124 | 125 | return (cothread_t)thread; 126 | } 127 | 128 | void co_delete(cothread_t cothread) { 129 | if(cothread) { 130 | if(((cothread_struct*)cothread)->stack) { 131 | free(((cothread_struct*)cothread)->stack); 132 | } 133 | free(cothread); 134 | } 135 | } 136 | 137 | void co_switch(cothread_t cothread) { 138 | if(!sigsetjmp(co_running->context, 0)) { 139 | co_running = (cothread_struct*)cothread; 140 | siglongjmp(co_running->context, 1); 141 | } 142 | } 143 | 144 | int co_serializable(void) { 145 | return 0; 146 | } 147 | 148 | #ifdef __cplusplus 149 | } 150 | #endif 151 | -------------------------------------------------------------------------------- /sos/src/sys/backtrace.c: -------------------------------------------------------------------------------- 1 | /* 2 | * @TAG(OTHER_GPL) 3 | */ 4 | /* Return backtrace of current program state. 5 | Copyright (C) 2003-2005,2007,2009,2011,2012 Free Software Foundation, Inc. 6 | This file is part of the GNU C Library. 7 | Contributed by Jakub Jelinek , 2003. 8 | 9 | The GNU C Library is free software; you can redistribute it and/or 10 | modify it under the terms of the GNU Lesser General Public 11 | License as published by the Free Software Foundation; either 12 | version 2.1 of the License, or (at your option) any later version. 13 | 14 | The GNU C Library is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | Lesser General Public License for more details. 18 | 19 | You should have received a copy of the GNU Lesser General Public 20 | License along with the GNU C Library; if not, see 21 | . */ 22 | 23 | //#include 24 | #include 25 | //#include 26 | #include 27 | #include 28 | #include "unwind.h" 29 | 30 | struct trace_arg { 31 | void **array; 32 | _Unwind_Word cfa; 33 | int cnt; 34 | int size; 35 | }; 36 | 37 | #ifdef SHARED 38 | static _Unwind_Reason_Code(*unwind_backtrace)(_Unwind_Trace_Fn, void *); 39 | static _Unwind_Ptr(*unwind_getip)(struct _Unwind_Context *); 40 | static _Unwind_Word(*unwind_getcfa)(struct _Unwind_Context *); 41 | static void *libgcc_handle; 42 | 43 | 44 | /* Dummy version in case libgcc_s does not contain the real code. */ 45 | static _Unwind_Word dummy_getcfa(struct _Unwind_Context *ctx __attribute__((unused))) 46 | { 47 | return 0; 48 | } 49 | 50 | 51 | static void init(void) 52 | { 53 | libgcc_handle = __libc_dlopen("libgcc_s.so.1"); 54 | 55 | if (libgcc_handle == NULL) { 56 | return; 57 | } 58 | 59 | unwind_backtrace = __libc_dlsym(libgcc_handle, "_Unwind_Backtrace"); 60 | unwind_getip = __libc_dlsym(libgcc_handle, "_Unwind_GetIP"); 61 | if (unwind_getip == NULL) { 62 | unwind_backtrace = NULL; 63 | } 64 | unwind_getcfa = (__libc_dlsym(libgcc_handle, "_Unwind_GetCFA") 65 | ? : dummy_getcfa); 66 | } 67 | #else 68 | # define unwind_backtrace _Unwind_Backtrace 69 | # define unwind_getip _Unwind_GetIP 70 | # define unwind_getcfa _Unwind_GetCFA 71 | #endif 72 | 73 | static _Unwind_Reason_Code backtrace_helper(struct _Unwind_Context *ctx, void *a) 74 | { 75 | struct trace_arg *arg = a; 76 | 77 | /* We are first called with address in the __backtrace function. 78 | Skip it. */ 79 | if (arg->cnt != -1) { 80 | arg->array[arg->cnt] = (void *) unwind_getip(ctx); 81 | 82 | /* Check whether we make any progress. */ 83 | _Unwind_Word cfa = unwind_getcfa(ctx); 84 | 85 | if (arg->cnt > 0 && arg->array[arg->cnt - 1] == arg->array[arg->cnt] 86 | && cfa == arg->cfa) { 87 | return _URC_END_OF_STACK; 88 | } 89 | arg->cfa = cfa; 90 | } 91 | if (++arg->cnt == arg->size) { 92 | return _URC_END_OF_STACK; 93 | } 94 | return _URC_NO_REASON; 95 | } 96 | 97 | int 98 | backtrace(array, size) 99 | void **array; 100 | int size; 101 | { 102 | struct trace_arg arg = { .array = array, .cfa = 0, .size = size, .cnt = -1 }; 103 | #ifdef SHARED 104 | __libc_once_define(static, once); 105 | 106 | __libc_once(once, init); 107 | if (unwind_backtrace == NULL) { 108 | return 0; 109 | } 110 | #endif 111 | 112 | if (size >= 1) { 113 | unwind_backtrace(backtrace_helper, &arg); 114 | } 115 | 116 | /* _Unwind_Backtrace seems to put NULL address above 117 | _start. Fix it up here. */ 118 | if (arg.cnt > 1 && arg.array[arg.cnt - 1] == NULL) { 119 | --arg.cnt; 120 | } 121 | return arg.cnt != -1 ? arg.cnt : 0; 122 | } 123 | //weak_alias (__backtrace, backtrace) 124 | //libc_hidden_def (__backtrace) 125 | 126 | 127 | #ifdef SHARED 128 | /* Free all resources if necessary. */ 129 | libc_freeres_fn(free_mem) 130 | { 131 | unwind_backtrace = NULL; 132 | if (libgcc_handle != NULL) { 133 | __libc_dlclose(libgcc_handle); 134 | libgcc_handle = NULL; 135 | } 136 | } 137 | #endif 138 | -------------------------------------------------------------------------------- /libnetworkconsole/src/networkconsole.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #undef PACKED /* picotcp redefines this */ 19 | #include 20 | #include 21 | 22 | #define AOS_BASEPORT (26700) 23 | #define MAX_PAYLOAD_SIZE 1024 24 | 25 | struct network_console { 26 | struct pico_ip4 inaddr_any; 27 | struct pico_socket *pico_socket; 28 | void (*handler)(struct network_console *network_console, char c); 29 | uint32_t peer; 30 | uint16_t port; 31 | }; 32 | 33 | /* Incoming data is read into this buffer */ 34 | static char buf[MAX_PAYLOAD_SIZE]; 35 | static struct network_console network_console = {}; 36 | 37 | /* 38 | * This function will be called from the network stack on any networking event, such as receiving data. 39 | * If you have a registered handler to receive incoming data, it gets called from here. 40 | */ 41 | static void network_console_recv_handler(uint16_t ev, struct pico_socket *s) 42 | { 43 | if (ev == PICO_SOCK_EV_RD && network_console.handler) { 44 | int read = 0; 45 | do { 46 | read = pico_socket_recvfrom(network_console.pico_socket, buf, MAX_PAYLOAD_SIZE, &network_console.peer, &network_console.port); 47 | for (int i = 0; i < read; i++) { 48 | network_console.handler(&network_console, buf[i]); 49 | } 50 | } while (read > 0); 51 | } else if (ev == PICO_SOCK_EV_ERR) { 52 | ZF_LOGE("Pico recv error"); 53 | } 54 | } 55 | 56 | struct network_console *network_console_init(void) 57 | { 58 | if (network_console.pico_socket != NULL) { 59 | ZF_LOGE("Network console already initialised!"); 60 | return NULL; 61 | } 62 | 63 | network_console.pico_socket = pico_socket_open(PICO_PROTO_IPV4, PICO_PROTO_UDP, &network_console_recv_handler); 64 | if (!network_console.pico_socket) { 65 | ZF_LOGE("Network console connection failed"); 66 | return NULL; 67 | } 68 | 69 | struct pico_ip4 gateway; 70 | pico_string_to_ipv4(CONFIG_SOS_GATEWAY, &gateway.addr); 71 | 72 | struct pico_ip4 *src = pico_ipv4_source_find(&gateway); 73 | unsigned char *octects = (unsigned char *) &src->addr; 74 | printf("libnetworkconsole using udp port %d\n", AOS_BASEPORT + octects[3]); 75 | 76 | /* Configure peer/port for sendto */ 77 | pico_string_to_ipv4(CONFIG_SOS_GATEWAY, &network_console.peer); 78 | uint16_t port_be = short_be(AOS_BASEPORT + octects[3]); 79 | network_console.port = port_be; 80 | 81 | int err = pico_socket_bind(network_console.pico_socket, &network_console.inaddr_any, &port_be); 82 | if (err) { 83 | return NULL; 84 | } 85 | 86 | err = pico_socket_connect(network_console.pico_socket, &network_console.peer, network_console.port); 87 | if (err < 0) { 88 | ZF_LOGE("Network console failed to connect to UDP server"); 89 | return NULL; 90 | } 91 | 92 | return &network_console; 93 | } 94 | 95 | int network_console_send(struct network_console *network_console, char *data, int len) 96 | { 97 | assert(network_console->pico_socket != NULL); 98 | int total_sent = 0; 99 | while (total_sent < len) { 100 | int sent = pico_socket_sendto(network_console->pico_socket, data, len, &network_console->peer, network_console->port); 101 | if (sent == -1) { 102 | ZF_LOGE("Pico send failed"); 103 | return -1; 104 | } 105 | if (sent == 0) { 106 | return total_sent; 107 | } 108 | total_sent += sent; 109 | } 110 | return len; 111 | } 112 | 113 | int network_console_register_handler(struct network_console *network_console, 114 | void (*handler)(struct network_console *network_console, char c)) 115 | { 116 | network_console->handler = handler; 117 | return 0; 118 | } 119 | -------------------------------------------------------------------------------- /libclock/src/device.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "device.h" 19 | 20 | typedef struct { 21 | seL4_Word irq; 22 | seL4_Word input_clk; 23 | seL4_Word enable; 24 | seL4_Word mode; 25 | } timeout_info_t; 26 | 27 | #define DEFINE_TIMEOUT(timeout) \ 28 | [MESON_##timeout] = { \ 29 | .irq = timeout##_IRQ, \ 30 | .input_clk = timeout##_INPUT_CLK, \ 31 | .enable = timeout##_EN, \ 32 | .mode = timeout##_MODE, \ 33 | } 34 | 35 | static timeout_info_t timeouts[] = { 36 | DEFINE_TIMEOUT(TIMER_A), 37 | DEFINE_TIMEOUT(TIMER_B), 38 | DEFINE_TIMEOUT(TIMER_C), 39 | DEFINE_TIMEOUT(TIMER_D), 40 | }; 41 | 42 | void configure_timestamp(volatile meson_timer_reg_t *regs, timestamp_timebase_t timebase) 43 | { 44 | uint32_t mux = regs->mux; 45 | mux &= ~(TIMESTAMP_TIMEBASE_MASK << TIMER_E_INPUT_CLK); 46 | mux |= timebase << TIMER_E_INPUT_CLK; 47 | regs->mux = mux; 48 | COMPILER_MEMORY_FENCE(); 49 | } 50 | 51 | uint64_t read_timestamp(volatile meson_timer_reg_t *timer) 52 | { 53 | COMPILER_MEMORY_FENCE(); 54 | uint64_t lo = timer->timer_e; 55 | uint64_t hi = timer->timer_e_hi; 56 | COMPILER_MEMORY_FENCE(); 57 | uint64_t new_lo = timer->timer_e; 58 | if (new_lo < lo) { 59 | lo = new_lo; 60 | hi = timer->timer_e_hi; 61 | } 62 | 63 | timestamp_t time = hi << 32; 64 | time |= lo & MASK(32); 65 | return time; 66 | } 67 | 68 | void configure_timeout(volatile meson_timer_reg_t *regs, timeout_id_t timer, bool enable, bool periodic, 69 | timeout_timebase_t timebase, uint16_t timeout) 70 | { 71 | assert(timer < ARRAY_SIZE(timeouts)); 72 | timeout_info_t info = timeouts[timer]; 73 | 74 | /* Disable the timer */ 75 | uint32_t mux = regs->mux; 76 | mux &= ~info.enable; 77 | regs->mux = mux; 78 | COMPILER_MEMORY_FENCE(); 79 | 80 | if (!enable) { 81 | /* If not enabling the timer, just diable and exit */ 82 | return; 83 | } 84 | 85 | /* Configure the timeout */ 86 | write_timeout(regs, timer, timeout); 87 | 88 | /* Configure the timer */ 89 | mux = regs->mux; 90 | mux |= info.enable; 91 | 92 | if (periodic) { 93 | mux |= info.mode; 94 | } else { 95 | mux &= ~info.mode; 96 | } 97 | 98 | /* Clear the existing clock rate */ 99 | mux &= ~(TIMEOUT_TIMEBASE_MASK << info.input_clk); 100 | 101 | /* Set the new clock rate */ 102 | mux |= timebase << info.input_clk; 103 | 104 | regs->mux = mux; 105 | COMPILER_MEMORY_FENCE(); 106 | } 107 | 108 | uint16_t read_timeout(volatile meson_timer_reg_t *regs, timeout_id_t timer) 109 | { 110 | assert(timer < ARRAY_SIZE(timeouts)); 111 | 112 | COMPILER_MEMORY_FENCE(); 113 | 114 | uint32_t value; 115 | switch (timer) { 116 | case MESON_TIMER_A: 117 | value = regs->timer_a; 118 | break; 119 | case MESON_TIMER_B: 120 | value = regs->timer_b; 121 | break; 122 | case MESON_TIMER_C: 123 | value = regs->timer_c; 124 | break; 125 | case MESON_TIMER_D: 126 | value = regs->timer_d; 127 | break; 128 | } 129 | 130 | return value >> 16; 131 | } 132 | 133 | void write_timeout(volatile meson_timer_reg_t *regs, timeout_id_t timer, uint16_t value) 134 | { 135 | switch (timer) { 136 | case MESON_TIMER_A: 137 | regs->timer_a = value; 138 | break; 139 | case MESON_TIMER_B: 140 | regs->timer_b = value; 141 | break; 142 | case MESON_TIMER_C: 143 | regs->timer_c = value; 144 | break; 145 | case MESON_TIMER_D: 146 | regs->timer_d = value; 147 | break; 148 | } 149 | COMPILER_MEMORY_FENCE(); 150 | } 151 | 152 | seL4_Word meson_timeout_irq(timeout_id_t timer) 153 | { 154 | assert(timer < ARRAY_SIZE(timeouts)); 155 | return timeouts[timer].irq; 156 | } 157 | -------------------------------------------------------------------------------- /sos/src/frame_table.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include "bootstrap.h" 15 | #include "ut.h" 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | /* 23 | * Every frame in the frame table is referenced by a compact index into 24 | * the table. As the table is only large enough to contain 2GiB worth of 25 | * frames, every frame reference will be 2^19 bits. 26 | */ 27 | typedef size_t frame_ref_t; 28 | 29 | /* 30 | * The 0 frame is a sentinel NULL frame and indicates a lack of 31 | * reference to any particular frame. 32 | */ 33 | #define NULL_FRAME ((frame_ref_t)0) 34 | 35 | /* 36 | * Identifiers of the different lists in the frame table. 37 | * 38 | * These are used to ensure that frame table entries move correctly 39 | * between the two lists and that those lists maintain a consistently 40 | * correct structure. 41 | */ 42 | typedef enum { 43 | NO_LIST = 1, 44 | FREE_LIST = 2, 45 | ALLOCATED_LIST = 3, 46 | } list_id_t; 47 | 48 | /* Array of names for each of the lists above. */ 49 | extern char *frame_table_list_names[]; 50 | 51 | /* Debugging macro to get the human-readable name of a particular list ID. */ 52 | #define LIST_ID_NAME(list_id) (frame_table_list_names[list_id]) 53 | 54 | /* The actual representation of a frame in the frame table. */ 55 | typedef struct frame frame_t; 56 | PACKED struct frame { 57 | /* Page used to map frame into SOS memory. */ 58 | seL4_ARM_Page sos_page: 20; 59 | /* Index in frame table of previous element in list. */ 60 | frame_ref_t prev : 19; 61 | /* Index in frame table of next element in list. */ 62 | frame_ref_t next : 19; 63 | /* Indicates which list the frame is in. */ 64 | list_id_t list_id : 2; 65 | /* Unused bits */ 66 | size_t unused : 4; 67 | }; 68 | compile_time_assert("Small CPtr size", 20 >= INITIAL_TASK_CSPACE_BITS); 69 | 70 | /* 71 | * Initialise frame table. 72 | * 73 | * @param cspace root cspace object from SOS. 74 | * @param vspace virtual address space of SOS. 75 | */ 76 | void frame_table_init(cspace_t *cspace, seL4_CPtr vspace); 77 | 78 | /* 79 | * Get the cspace used by the frame table. 80 | */ 81 | cspace_t *frame_table_cspace(void); 82 | 83 | /* 84 | * Allocate a frame from the frame table. 85 | * 86 | * This allocates a frame from the frame table, using a 4K untyped if no 87 | * frames are spare. This frame may be dirty so make sure to zero-out 88 | * any memory in the frame that is not explicitly written over with 89 | * data. 90 | * 91 | * DO NOT append the untypeds returned from this function into another 92 | * list. When they are allocated they are still tracked in a list within 93 | * the frame table. 94 | * 95 | * The capability associated with a frame returned from this is a 96 | * Page, referring to the mapping of the frame in SOS, rather than to an 97 | * untyped. This means that additional mappings to the frame can be made 98 | * by copying the capability. 99 | * 100 | * This function returns NULL if there are no free untypeds and an 101 | * untyped could not be allocated from the untyped manager. 102 | * 103 | * You will need to modify the frame table to deal with the case where 104 | * only a limited number of frames may be held by the frame table. 105 | */ 106 | frame_ref_t alloc_frame(void); 107 | 108 | /* 109 | * Free a frame allocated by the frame table. 110 | * 111 | * This returns the frame to the frame table for re-use rather than 112 | * returning it to the untyped allocator. 113 | */ 114 | void free_frame(frame_ref_t frame_ref); 115 | 116 | /* 117 | * Get the contents of a frame as mapped into SOS. 118 | * 119 | * @returns a pointer to a 4096 byte character array representing the 120 | * frame data as mapped into SOS. 121 | */ 122 | unsigned char *frame_data(frame_ref_t frame_ref); 123 | 124 | /* 125 | * Get the capability to the page used to map the frame into SOS. 126 | * 127 | * This can be copied to create mappings into additional virtual address 128 | * spaces. 129 | */ 130 | seL4_ARM_Page frame_page(frame_ref_t frame_ref); 131 | 132 | /* 133 | * Get the underlying frame reference by a frame ID. 134 | * 135 | * This should only be used for debugging. 136 | */ 137 | frame_t *frame_from_ref(frame_ref_t frame_ref); 138 | -------------------------------------------------------------------------------- /libclock/src/device.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | /* IRQs */ 20 | 21 | #define TIMER_A_IRQ 42 22 | #define TIMER_B_IRQ 43 23 | #define TIMER_C_IRQ 38 24 | #define TIMER_D_IRQ 61 25 | 26 | #define TIMER_F_IRQ 92 27 | #define TIMER_G_IRQ 93 28 | #define TIMER_H_IRQ 94 29 | #define TIMER_I_IRQ 95 30 | 31 | /* Timer mux 0 */ 32 | 33 | #define TIMER_E_INPUT_CLK 8 34 | 35 | #define TIMER_A_INPUT_CLK 0 36 | #define TIMER_B_INPUT_CLK 2 37 | #define TIMER_C_INPUT_CLK 4 38 | #define TIMER_D_INPUT_CLK 6 39 | 40 | #define TIMER_A_EN BIT(16) 41 | #define TIMER_B_EN BIT(17) 42 | #define TIMER_C_EN BIT(18) 43 | #define TIMER_D_EN BIT(19) 44 | #define TIMER_A_MODE BIT(12) 45 | #define TIMER_B_MODE BIT(13) 46 | #define TIMER_C_MODE BIT(14) 47 | #define TIMER_D_MODE BIT(15) 48 | 49 | /* Timer mux 1 */ 50 | 51 | #define TIMER_F_INPUT_CLK 0 52 | #define TIMER_G_INPUT_CLK 2 53 | #define TIMER_H_INPUT_CLK 4 54 | #define TIMER_I_INPUT_CLK 6 55 | 56 | #define TIMER_F_EN BIT(16) 57 | #define TIMER_G_EN BIT(17) 58 | #define TIMER_H_EN BIT(18) 59 | #define TIMER_I_EN BIT(19) 60 | #define TIMER_F_MODE BIT(12) 61 | #define TIMER_G_MODE BIT(13) 62 | #define TIMER_H_MODE BIT(14) 63 | #define TIMER_I_MODE BIT(15) 64 | 65 | #define TIMESTAMP_TIMEBASE_MASK MASK(3) 66 | #define TIMEOUT_TIMEBASE_MASK MASK(2) 67 | 68 | /** 69 | * The layout of the timer device in memory. 70 | */ 71 | typedef struct { 72 | uint32_t mux; 73 | uint32_t timer_a; 74 | uint32_t timer_b; 75 | uint32_t timer_c; 76 | uint32_t timer_d; 77 | uint32_t unused[13]; 78 | uint32_t timer_e; 79 | uint32_t timer_e_hi; 80 | uint32_t mux1; 81 | uint32_t timer_f; 82 | uint32_t timer_g; 83 | uint32_t timer_h; 84 | uint32_t timer_i; 85 | } meson_timer_reg_t; 86 | 87 | /** 88 | * Frequency configuration options for the timestamp of the timer. 89 | */ 90 | typedef enum { 91 | /* Synchronise with system */ 92 | TIMESTAMP_TIMEBASE_SYSTEM = 0b000, 93 | /* Tick every 1us */ 94 | TIMESTAMP_TIMEBASE_1_US = 0b001, 95 | /* Tick every 10us */ 96 | TIMESTAMP_TIMEBASE_10_US = 0b010, 97 | /* Tick every 100us */ 98 | TIMESTAMP_TIMEBASE_100_US = 0b011, 99 | /* Tick every 1ms */ 100 | TIMESTAMP_TIMEBASE_1_MS = 0b100, 101 | } timestamp_timebase_t; 102 | 103 | /** 104 | * Frequency configuration options for the timeout timers. 105 | */ 106 | typedef enum { 107 | /* Tick every 1us */ 108 | TIMEOUT_TIMEBASE_1_US = 0b00, 109 | /* Tick every 10us */ 110 | TIMEOUT_TIMEBASE_10_US = 0b01, 111 | /* Tick every 100us */ 112 | TIMEOUT_TIMEBASE_100_US = 0b10, 113 | /* Tick every 1ms */ 114 | TIMEOUT_TIMEBASE_1_MS = 0b11, 115 | } timeout_timebase_t; 116 | 117 | /** 118 | * Configure the counter timer (timer E) to tick with a given frequency. 119 | * 120 | * @param regs The timer registers. 121 | * @param timebase Timer tick frequency for the timestamp. 122 | */ 123 | void configure_timestamp(volatile meson_timer_reg_t *regs, timestamp_timebase_t timebase); 124 | 125 | /** 126 | * Read the current value from the timestamp timer (timer E). 127 | * 128 | * @param regs The timer registers. 129 | * @return The current value of the timestamp. 130 | */ 131 | uint64_t read_timestamp(volatile meson_timer_reg_t *regs); 132 | 133 | /** 134 | * Configure a timeout timer. 135 | * 136 | * @param regs The timer registers. 137 | * @param timer The timer to be configured. 138 | * @param enable Whether or not to enable the timer. 139 | * @param periodic Whether the timer should fire periodically (or just 140 | * once). 141 | * @param timebase Timer tick frequency. 142 | */ 143 | void configure_timeout( 144 | volatile meson_timer_reg_t *regs, 145 | timeout_id_t timer, 146 | bool enable, 147 | bool periodic, 148 | timeout_timebase_t timebase, 149 | uint16_t timeout 150 | ); 151 | 152 | /** 153 | * Read the time remaining on a timeout. 154 | * 155 | * @param regs The timer registers. 156 | * @param timer The timer to be configured. 157 | * @return Numer of ticks until the timeout. 158 | */ 159 | uint16_t read_timeout( 160 | volatile meson_timer_reg_t *regs, 161 | timeout_id_t timer 162 | ); 163 | 164 | /** 165 | * Write the time until the next timeout. 166 | * 167 | * @param regs The timer registers. 168 | * @param timer The timer to be configured. 169 | * @param value The number of ticks to set until the next timeout. 170 | */ 171 | void write_timeout( 172 | volatile meson_timer_reg_t *regs, 173 | timeout_id_t timer, 174 | uint16_t value 175 | ); 176 | -------------------------------------------------------------------------------- /libco/settings.h: -------------------------------------------------------------------------------- 1 | #if defined(LIBCO_C) 2 | 3 | /*[amd64, arm, ppc, x86]: 4 | by default, co_swap_function is marked as a text (code) section 5 | if not supported, uncomment the below line to use mprotect instead */ 6 | /* #define LIBCO_MPROTECT */ 7 | 8 | /*[amd64]: 9 | Win64 only: provides a substantial speed-up, but will thrash XMM regs 10 | do not use this unless you are certain your application won't use SSE */ 11 | /* #define LIBCO_NO_SSE */ 12 | 13 | #if !defined(thread_local) /* User can override thread_local for obscure compilers */ 14 | #if !defined(LIBCO_MP) /* Running in single-threaded environment */ 15 | #define thread_local 16 | #else /* Running in multi-threaded environment */ 17 | #if defined(__STDC__) /* Compiling as C Language */ 18 | #if defined(_MSC_VER) /* Don't rely on MSVC's C11 support */ 19 | #define thread_local __declspec(thread) 20 | #elif __STDC_VERSION__ < 201112L /* If we are on C90/99 */ 21 | #if defined(__clang__) || defined(__GNUC__) /* Clang and GCC */ 22 | #define thread_local __thread 23 | #else /* Otherwise, we ignore the directive (unless user provides their own) */ 24 | #define thread_local 25 | #endif 26 | #else /* C11 and newer define thread_local in threads.h */ 27 | #include 28 | #endif 29 | #elif defined(__cplusplus) /* Compiling as C++ Language */ 30 | #if __cplusplus < 201103L /* thread_local is a C++11 feature */ 31 | #if defined(_MSC_VER) 32 | #define thread_local __declspec(thread) 33 | #elif defined(__clang__) || defined(__GNUC__) 34 | #define thread_local __thread 35 | #else /* Otherwise, we ignore the directive (unless user provides their own) */ 36 | #define thread_local 37 | #endif 38 | #else /* In C++ >= 11, thread_local in a builtin keyword */ 39 | /* Don't do anything */ 40 | #endif 41 | #endif 42 | #endif 43 | #endif 44 | 45 | /* In alignas(a), 'a' should be a power of two that is at least the type's 46 | alignment and at most the implementation's alignment limit. This limit is 47 | 2**13 on MSVC. To be portable to MSVC through at least version 10.0, 48 | 'a' should be an integer constant, as MSVC does not support expressions 49 | such as 1 << 3. 50 | 51 | The following C11 requirements are NOT supported on MSVC: 52 | 53 | - If 'a' is zero, alignas has no effect. 54 | - alignas can be used multiple times; the strictest one wins. 55 | - alignas (TYPE) is equivalent to alignas (alignof (TYPE)). 56 | */ 57 | #if !defined(alignas) 58 | #if defined(__STDC__) /* C Language */ 59 | #if defined(_MSC_VER) /* Don't rely on MSVC's C11 support */ 60 | #define alignas(bytes) __declspec(align(bytes)) 61 | #elif __STDC_VERSION__ >= 201112L /* C11 and above */ 62 | #include 63 | #elif defined(__clang__) || defined(__GNUC__) /* C90/99 on Clang/GCC */ 64 | #define alignas(bytes) __attribute__ ((aligned (bytes))) 65 | #else /* Otherwise, we ignore the directive (user should provide their own) */ 66 | #define alignas(bytes) 67 | #endif 68 | #elif defined(__cplusplus) /* C++ Language */ 69 | #if __cplusplus < 201103L 70 | #if defined(_MSC_VER) 71 | #define alignas(bytes) __declspec(align(bytes)) 72 | #elif defined(__clang__) || defined(__GNUC__) /* C++98/03 on Clang/GCC */ 73 | #define alignas(bytes) __attribute__ ((aligned (bytes))) 74 | #else /* Otherwise, we ignore the directive (unless user provides their own) */ 75 | #define alignas(bytes) 76 | #endif 77 | #else /* C++ >= 11 has alignas keyword */ 78 | /* Do nothing */ 79 | #endif 80 | #endif /* = !defined(__STDC_VERSION__) && !defined(__cplusplus) */ 81 | #endif 82 | 83 | #if !defined(LIBCO_ASSERT) 84 | #include 85 | #define LIBCO_ASSERT assert 86 | #endif 87 | 88 | #if defined (__OpenBSD__) 89 | #if !defined(LIBCO_MALLOC) || !defined(LIBCO_FREE) 90 | #include 91 | #include 92 | 93 | static void* malloc_obsd(size_t size) { 94 | long pagesize = sysconf(_SC_PAGESIZE); 95 | char* memory = (char*)mmap(NULL, size + pagesize, PROT_READ|PROT_WRITE, MAP_STACK|MAP_PRIVATE|MAP_ANON, -1, 0); 96 | if (memory == MAP_FAILED) return NULL; 97 | *(size_t*)memory = size + pagesize; 98 | memory += pagesize; 99 | return (void*)memory; 100 | } 101 | 102 | static void free_obsd(void *ptr) { 103 | char* memory = (char*)ptr - sysconf(_SC_PAGESIZE); 104 | munmap(memory, *(size_t*)memory); 105 | } 106 | 107 | #define LIBCO_MALLOC malloc_obsd 108 | #define LIBCO_FREE free_obsd 109 | #endif 110 | #endif 111 | 112 | #if !defined(LIBCO_MALLOC) || !defined(LIBCO_FREE) 113 | #include 114 | #define LIBCO_MALLOC malloc 115 | #define LIBCO_FREE free 116 | #endif 117 | 118 | #if defined(_MSC_VER) 119 | #define section(name) __declspec(allocate("." #name)) 120 | #elif defined(__APPLE__) 121 | #define section(name) __attribute__((section("__TEXT,__" #name))) 122 | #else 123 | #define section(name) __attribute__((section("." #name "#"))) 124 | #endif 125 | 126 | 127 | /* if defined(LIBCO_C) */ 128 | #endif 129 | -------------------------------------------------------------------------------- /libethernet/src/uboot/miiphy.h: -------------------------------------------------------------------------------- 1 | /* 2 | * @TAG(OTHER_GPL) 3 | */ 4 | 5 | /*----------------------------------------------------------------------------+ 6 | | This source code is dual-licensed. You may use it under the terms of the 7 | | GNU General Public License version 2, or under the license below. 8 | | 9 | | This source code has been made available to you by IBM on an AS-IS 10 | | basis. Anyone receiving this source is licensed under IBM 11 | | copyrights to use it in any way he or she deems fit, including 12 | | copying it, modifying it, compiling it, and redistributing it either 13 | | with or without modifications. No license under IBM patents or 14 | | patent applications is to be implied by the copyright license. 15 | | 16 | | Any user of this software should understand that IBM cannot provide 17 | | technical support for this software and will not be responsible for 18 | | any consequences resulting from the use of this software. 19 | | 20 | | Any person who transfers this source code or any derivative work 21 | | must include the IBM copyright notice, this paragraph, and the 22 | | preceding two paragraphs in the transferred software. 23 | | 24 | | COPYRIGHT I B M CORPORATION 1999 25 | | LICENSED MATERIAL - PROGRAM PROPERTY OF I B M 26 | | 27 | | Additions (C) Copyright 2009 Industrie Dial Face S.p.A. 28 | +----------------------------------------------------------------------------*/ 29 | /*----------------------------------------------------------------------------+ 30 | | 31 | | File Name: miiphy.h 32 | | 33 | | Function: Include file defining PHY registers. 34 | | 35 | | Author: Mark Wisner 36 | | 37 | +----------------------------------------------------------------------------*/ 38 | #ifndef _miiphy_h_ 39 | #define _miiphy_h_ 40 | 41 | #include "common.h" 42 | #include "list.h" 43 | #include "phy.h" 44 | 45 | struct legacy_mii_dev { 46 | int (*read)(const char *devname, unsigned char addr, 47 | unsigned char reg, unsigned short *value); 48 | int (*write)(const char *devname, unsigned char addr, 49 | unsigned char reg, unsigned short value); 50 | }; 51 | 52 | int miiphy_read(const char *devname, unsigned char addr, unsigned char reg, 53 | unsigned short *value); 54 | int miiphy_write(const char *devname, unsigned char addr, unsigned char reg, 55 | unsigned short value); 56 | int miiphy_info(const char *devname, unsigned char addr, unsigned int *oui, 57 | unsigned char *model, unsigned char *rev); 58 | int miiphy_reset(const char *devname, unsigned char addr); 59 | int miiphy_speed(const char *devname, unsigned char addr); 60 | int miiphy_duplex(const char *devname, unsigned char addr); 61 | int miiphy_is_1000base_x(const char *devname, unsigned char addr); 62 | #ifdef CONFIG_SYS_FAULT_ECHO_LINK_DOWN 63 | int miiphy_link(const char *devname, unsigned char addr); 64 | #endif 65 | 66 | void miiphy_init(void); 67 | 68 | void miiphy_register(const char *devname, 69 | int (*read)(const char *devname, unsigned char addr, 70 | unsigned char reg, unsigned short *value), 71 | int (*write)(const char *devname, unsigned char addr, 72 | unsigned char reg, unsigned short value)); 73 | 74 | int miiphy_set_current_dev(const char *devname); 75 | const char *miiphy_get_current_dev(void); 76 | struct mii_dev *mdio_get_current_dev(void); 77 | struct mii_dev *miiphy_get_dev_by_name(const char *devname); 78 | struct phy_device *mdio_phydev_for_ethname(const char *devname); 79 | 80 | void miiphy_listdev(void); 81 | 82 | struct mii_dev *mdio_alloc(void); 83 | int mdio_register(struct mii_dev *bus); 84 | void mdio_list_devices(void); 85 | 86 | #ifdef CONFIG_BITBANGMII 87 | 88 | #define BB_MII_DEVNAME "bb_miiphy" 89 | 90 | struct bb_miiphy_bus { 91 | char name[16]; 92 | int (*init)(struct bb_miiphy_bus *bus); 93 | int (*mdio_active)(struct bb_miiphy_bus *bus); 94 | int (*mdio_tristate)(struct bb_miiphy_bus *bus); 95 | int (*set_mdio)(struct bb_miiphy_bus *bus, int v); 96 | int (*get_mdio)(struct bb_miiphy_bus *bus, int *v); 97 | int (*set_mdc)(struct bb_miiphy_bus *bus, int v); 98 | int (*delay)(struct bb_miiphy_bus *bus); 99 | #ifdef CONFIG_BITBANGMII_MULTI 100 | void *priv; 101 | #endif 102 | }; 103 | 104 | extern struct bb_miiphy_bus bb_miiphy_buses[]; 105 | extern int bb_miiphy_buses_num; 106 | 107 | void bb_miiphy_init(void); 108 | int bb_miiphy_read(const char *devname, unsigned char addr, 109 | unsigned char reg, unsigned short *value); 110 | int bb_miiphy_write(const char *devname, unsigned char addr, 111 | unsigned char reg, unsigned short value); 112 | #endif 113 | 114 | /* phy seed setup */ 115 | #define AUTO 99 116 | #define _1000BASET 1000 117 | #define _100BASET 100 118 | #define _10BASET 10 119 | #define HALF 22 120 | #define FULL 44 121 | 122 | /* phy register offsets */ 123 | #define MII_MIPSCR 0x11 124 | 125 | /* MII_LPA */ 126 | #define PHY_ANLPAR_PSB_802_3 0x0001 127 | #define PHY_ANLPAR_PSB_802_9 0x0002 128 | 129 | /* MII_CTRL1000 masks */ 130 | #define PHY_1000BTCR_1000FD 0x0200 131 | #define PHY_1000BTCR_1000HD 0x0100 132 | 133 | /* MII_STAT1000 masks */ 134 | #define PHY_1000BTSR_MSCF 0x8000 135 | #define PHY_1000BTSR_MSCR 0x4000 136 | #define PHY_1000BTSR_LRS 0x2000 137 | #define PHY_1000BTSR_RRS 0x1000 138 | #define PHY_1000BTSR_1000FD 0x0800 139 | #define PHY_1000BTSR_1000HD 0x0400 140 | 141 | /* phy EXSR */ 142 | #define ESTATUS_1000XF 0x8000 143 | #define ESTATUS_1000XH 0x4000 144 | 145 | #endif 146 | -------------------------------------------------------------------------------- /libsosapi/include/sos.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | /* Simple operating system interface */ 13 | 14 | #pragma once 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | /* System calls for SOS */ 21 | 22 | /* Endpoint for talking to SOS */ 23 | #define SOS_IPC_EP_CAP (0x1) 24 | #define TIMER_IPC_EP_CAP (0x2) 25 | 26 | /* Limits */ 27 | #define PROCESS_MAX_FILES 16 28 | #define MAX_IO_BUF 0x1000 29 | #define N_NAME 32 30 | 31 | /* file modes */ 32 | #define FM_EXEC 1 33 | #define FM_WRITE 2 34 | #define FM_READ 4 35 | typedef int fmode_t; 36 | 37 | /* stat file types */ 38 | #define ST_FILE 1 /* plain file */ 39 | #define ST_SPECIAL 2 /* special (console) file */ 40 | typedef int st_type_t; 41 | 42 | 43 | typedef struct { 44 | st_type_t st_type; /* file type */ 45 | fmode_t st_fmode; /* access mode */ 46 | unsigned st_size; /* file size in bytes */ 47 | long st_ctime; /* Unix file creation time (ms) */ 48 | long st_atime; /* Unix file last access (open) time (ms) */ 49 | } sos_stat_t; 50 | 51 | typedef int pid_t; 52 | 53 | typedef struct { 54 | pid_t pid; 55 | unsigned size; /* in pages */ 56 | unsigned stime; /* start time in msec since booting */ 57 | char command[N_NAME]; /* Name of exectuable */ 58 | } sos_process_t; 59 | 60 | /* I/O system calls */ 61 | 62 | int sos_open(const char *path, fmode_t mode); 63 | /* Open file and return file descriptor, -1 if unsuccessful 64 | * (too many open files, console already open for reading). 65 | * A new file should be created if 'path' does not already exist. 66 | * A failed attempt to open the console for reading (because it is already 67 | * open) will result in a context switch to reduce the cost of busy waiting 68 | * for the console. 69 | * "path" is file name, "mode" is one of O_RDONLY, O_WRONLY, O_RDWR. 70 | */ 71 | 72 | int sos_close(int file); 73 | /* Closes an open file. Returns 0 if successful, -1 if not (invalid "file"). 74 | */ 75 | 76 | int sos_read(int file, char *buf, size_t nbyte); 77 | /* Read from an open file, into "buf", max "nbyte" bytes. 78 | * Returns the number of bytes read. 79 | * Will block when reading from console and no input is presently 80 | * available. Returns -1 on error (invalid file). 81 | */ 82 | 83 | int sos_write(int file, const char *buf, size_t nbyte); 84 | /* Write to an open file, from "buf", max "nbyte" bytes. 85 | * Returns the number of bytes written. +D to process and exit\n> ") 53 | addresses = [] 54 | while True: 55 | try: 56 | addr = input("> ") 57 | for i in addr.split(): 58 | try: 59 | val = int(i, 16) 60 | addresses.append(val) 61 | except ValueError: 62 | print('ERROR: \'' + i + "\' is not a valid hex address") 63 | exit(1) 64 | except EOFError: 65 | break 66 | 67 | print("Processing.", end='', flush='True') 68 | 69 | # run nm and parse the symbol table 70 | nm = subprocess.run([args.toolchain + 'nm', '-n', args.file.name], 71 | stdout=subprocess.PIPE, universal_newlines=True) 72 | print(".", end='', flush='True') 73 | if nm.returncode != 0: 74 | print(nm.stderr) 75 | exit(1) 76 | nm_dict = {} # a dict of addr = symbol 77 | ordered_addrs = [] # ordered list of addresses 78 | nm_regex = re.compile('([0-9A-Fa-f]{8,16})\s[A-Za-z]\s(.*)') 79 | for line in nm.stdout.split('\n'): 80 | nm_match = nm_regex.match(line) 81 | if nm_match: 82 | addr = int(nm_match.group(1), 16) 83 | nm_dict[addr] = nm_match.group(2) 84 | ordered_addrs.append(addr) 85 | 86 | # load up the objdump 87 | dis = subprocess.run(objdump_cmd, stdout=subprocess.PIPE, universal_newlines=True) 88 | print(".", end='', flush='True') 89 | if dis.returncode != 0: 90 | print(dis.stderr) 91 | exit(1) 92 | dis_output = dis.stdout.split('\n') 93 | print(".") 94 | 95 | level = 0 96 | for addr in addresses: 97 | print ('--------------------------------------------------------------------------------') 98 | # find the name of the symbol 99 | if addr in nm_dict: 100 | name = nm_dict[addr] 101 | else: 102 | index = bisect.bisect_right(ordered_addrs, addr) 103 | if index: 104 | name = nm_dict.get(ordered_addrs[index-1]) 105 | 106 | if name: 107 | print ("{0} {1:16x} in {2}".format(level, addr, name)) 108 | else: 109 | print ("{0} {1:16x} can not be resolved".format(level, addr)) 110 | continue 111 | level += 1 112 | 113 | # now output some of the dissassembly line 114 | start_addr = addr - args.width * 4 115 | end_addr = addr + (args.width + 1) * 4 116 | 117 | dis_regex = re.compile('\s*([0-9A-Fa-f]{4,16}):') 118 | output = False 119 | bold = False 120 | for line in dis_output: 121 | dis_match = dis_regex.match(line) 122 | if dis_match: 123 | line_addr = int(dis_match.group(1), 16) 124 | if line_addr == addr: 125 | bold = True 126 | if line_addr >= start_addr: 127 | output = True 128 | if line_addr == end_addr: 129 | break 130 | if bold: 131 | print('\033[1m', end='') 132 | if output: 133 | print(line) 134 | if bold: 135 | print("\033[0m", end='', flush=True) 136 | bold = False 137 | -------------------------------------------------------------------------------- /libaos/include/aos/registers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #pragma once 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | static inline bool debug_is_read_fault(void) 19 | { 20 | seL4_Word fsr = seL4_GetMR(seL4_VMFault_FSR); 21 | return (fsr & (BIT(6))) == 0; 22 | } 23 | 24 | static UNUSED const char *register_names[] = { 25 | "pc", 26 | "sp", 27 | "spsr", 28 | "x0", 29 | "x1", 30 | "x2", 31 | "x3", 32 | "x4", 33 | "x5", 34 | "x6", 35 | "x7", 36 | "x8", 37 | "x16", 38 | "x17", 39 | "x18", 40 | "x29", 41 | "x30", 42 | "x9", 43 | "x10", 44 | "x11", 45 | "x12", 46 | "x13", 47 | "x14", 48 | "x15", 49 | "x19", 50 | "x20", 51 | "x21", 52 | "x22", 53 | "x23", 54 | "x24", 55 | "x25", 56 | "x26", 57 | "x27", 58 | "x28", 59 | "tpidr_el0", 60 | "tpidrro_el0", 61 | }; 62 | 63 | compile_time_assert(register_names_length, ARRAY_SIZE(register_names) == sizeof(seL4_UserContext) / sizeof(seL4_Word)); 64 | 65 | /* assert that register_names correspond to seL4_UserContext */ 66 | compile_time_assert(pc_correct_position, offsetof(seL4_UserContext, pc) == 0); 67 | compile_time_assert(sp_correct_position, offsetof(seL4_UserContext, sp) == 1 * sizeof(seL4_Word)); 68 | compile_time_assert(spsr_correct_position, offsetof(seL4_UserContext, spsr) == 2 * sizeof(seL4_Word)); 69 | compile_time_assert(x0_correct_position, offsetof(seL4_UserContext, x0) == 3 * sizeof(seL4_Word)); 70 | compile_time_assert(x1_correct_position, offsetof(seL4_UserContext, x1) == 4 * sizeof(seL4_Word)); 71 | compile_time_assert(x2_correct_position, offsetof(seL4_UserContext, x2) == 5 * sizeof(seL4_Word)); 72 | compile_time_assert(x3_correct_position, offsetof(seL4_UserContext, x3) == 6 * sizeof(seL4_Word)); 73 | compile_time_assert(x4_correct_position, offsetof(seL4_UserContext, x4) == 7 * sizeof(seL4_Word)); 74 | compile_time_assert(x5_correct_position, offsetof(seL4_UserContext, x5) == 8 * sizeof(seL4_Word)); 75 | compile_time_assert(x6_correct_position, offsetof(seL4_UserContext, x6) == 9 * sizeof(seL4_Word)); 76 | compile_time_assert(x7_correct_position, offsetof(seL4_UserContext, x7) == 10 * sizeof(seL4_Word)); 77 | compile_time_assert(x8_correct_position, offsetof(seL4_UserContext, x8) == 11 * sizeof(seL4_Word)); 78 | compile_time_assert(x16_correct_position, offsetof(seL4_UserContext, x16) == 12 * sizeof(seL4_Word)); 79 | compile_time_assert(x17_correct_position, offsetof(seL4_UserContext, x17) == 13 * sizeof(seL4_Word)); 80 | compile_time_assert(x18_correct_position, offsetof(seL4_UserContext, x18) == 14 * sizeof(seL4_Word)); 81 | compile_time_assert(x29_correct_position, offsetof(seL4_UserContext, x29) == 15 * sizeof(seL4_Word)); 82 | compile_time_assert(x30_correct_position, offsetof(seL4_UserContext, x30) == 16 * sizeof(seL4_Word)); 83 | compile_time_assert(x9_correct_position, offsetof(seL4_UserContext, x9) == 17 * sizeof(seL4_Word)); 84 | compile_time_assert(x10_correct_position, offsetof(seL4_UserContext, x10) == 18 * sizeof(seL4_Word)); 85 | compile_time_assert(x11_correct_position, offsetof(seL4_UserContext, x11) == 19 * sizeof(seL4_Word)); 86 | compile_time_assert(x12_correct_position, offsetof(seL4_UserContext, x12) == 20 * sizeof(seL4_Word)); 87 | compile_time_assert(x13_correct_position, offsetof(seL4_UserContext, x13) == 21 * sizeof(seL4_Word)); 88 | compile_time_assert(x14_correct_position, offsetof(seL4_UserContext, x14) == 22 * sizeof(seL4_Word)); 89 | compile_time_assert(x15_correct_position, offsetof(seL4_UserContext, x15) == 23 * sizeof(seL4_Word)); 90 | compile_time_assert(x19_correct_position, offsetof(seL4_UserContext, x19) == 24 * sizeof(seL4_Word)); 91 | compile_time_assert(x20_correct_position, offsetof(seL4_UserContext, x20) == 25 * sizeof(seL4_Word)); 92 | compile_time_assert(x21_correct_position, offsetof(seL4_UserContext, x21) == 26 * sizeof(seL4_Word)); 93 | compile_time_assert(x22_correct_position, offsetof(seL4_UserContext, x22) == 27 * sizeof(seL4_Word)); 94 | compile_time_assert(x23_correct_position, offsetof(seL4_UserContext, x23) == 28 * sizeof(seL4_Word)); 95 | compile_time_assert(x24_correct_position, offsetof(seL4_UserContext, x24) == 29 * sizeof(seL4_Word)); 96 | compile_time_assert(x25_correct_position, offsetof(seL4_UserContext, x25) == 30 * sizeof(seL4_Word)); 97 | compile_time_assert(x26_correct_position, offsetof(seL4_UserContext, x26) == 31 * sizeof(seL4_Word)); 98 | compile_time_assert(x27_correct_position, offsetof(seL4_UserContext, x27) == 32 * sizeof(seL4_Word)); 99 | compile_time_assert(x28_correct_position, offsetof(seL4_UserContext, x28) == 33 * sizeof(seL4_Word)); 100 | compile_time_assert(tpidr_el0_correct_position, offsetof(seL4_UserContext, tpidr_el0) == 34 * sizeof(seL4_Word)); 101 | compile_time_assert(tpidrro_el0_correct_position, offsetof(seL4_UserContext, tpidrro_el0) == 35 * sizeof(seL4_Word)); 102 | 103 | -------------------------------------------------------------------------------- /libaos/src/debug.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | void debug_cap_identify(seL4_CPtr cap) 18 | { 19 | #ifdef CONFIG_DEBUG_BUILD 20 | int type = seL4_DebugCapIdentify(cap); 21 | printf("Cap type number is %d\n", type); 22 | #endif /* CONFIG_DEBUG_BUILD */ 23 | } 24 | 25 | void debug_print_bootinfo(seL4_BootInfo *info) 26 | { 27 | ZF_LOGD("Node %lu of %lu", (long)info->nodeID, (long)info->numNodes); 28 | ZF_LOGD("IOPT levels: %u", (int)info->numIOPTLevels); 29 | ZF_LOGD("IPC buffer: %p", info->ipcBuffer); 30 | ZF_LOGD("Empty slots: [%lu --> %lu)", (long)info->empty.start, (long)info->empty.end); 31 | ZF_LOGD("sharedFrames: [%lu --> %lu)", (long)info->sharedFrames.start, (long)info->sharedFrames.end); 32 | ZF_LOGD("userImageFrames: [%lu --> %lu)", (long)info->userImageFrames.start, (long)info->userImageFrames.end); 33 | ZF_LOGD("userImagePaging: [%lu --> %lu)", (long)info->userImagePaging.start, (long)info->userImagePaging.end); 34 | ZF_LOGD("untypeds: [%lu --> %lu)", (long)info->untyped.start, (long)info->untyped.end); 35 | ZF_LOGD("Initial thread domain: %u\n", (int)info->initThreadDomain); 36 | ZF_LOGD("Initial thread cnode size: %u", info->initThreadCNodeSizeBits); 37 | ZF_LOGD("List of untypeds"); 38 | ZF_LOGD("------------------"); 39 | ZF_LOGD("Paddr | Size | Device"); 40 | 41 | int sizes[CONFIG_WORD_SIZE] = {0}; 42 | for (int i = 0; i < CONFIG_MAX_NUM_BOOTINFO_UNTYPED_CAPS && i < (info->untyped.end - info->untyped.start); i++) { 43 | int index = info->untypedList[i].sizeBits; 44 | assert(index < ARRAY_SIZE(sizes)); 45 | sizes[index]++; 46 | ZF_LOGD("%p | %zu | %d", (void *)info->untypedList[i].paddr, (size_t)info->untypedList[i].sizeBits, 47 | (int)info->untypedList[i].isDevice); 48 | } 49 | 50 | ZF_LOGD("Untyped summary\n"); 51 | for (int i = 0; i < ARRAY_SIZE(sizes); i++) { 52 | if (sizes[i] != 0) { 53 | ZF_LOGD("%d untypeds of size %d\n", sizes[i], i); 54 | } 55 | } 56 | } 57 | 58 | void debug_print_fault(seL4_MessageInfo_t tag, const char *thread_name) 59 | { 60 | seL4_Fault_t fault = seL4_getFault(tag); 61 | switch (seL4_Fault_get_seL4_FaultType(fault)) { 62 | case seL4_Fault_VMFault: 63 | assert(seL4_MessageInfo_get_length(tag) == seL4_VMFault_Length); 64 | printf("%sPagefault from [%s]: %s %s at PC: %p vaddr: %p, FSR %p%s\n", 65 | COLOR_ERROR, 66 | thread_name, 67 | debug_is_read_fault() ? "read" : "write", 68 | seL4_Fault_VMFault_get_PrefetchFault(fault) ? "prefetch fault" : "fault", 69 | (void *)seL4_Fault_VMFault_get_IP(fault), 70 | (void *)seL4_Fault_VMFault_get_Addr(fault), 71 | (void *)seL4_Fault_VMFault_get_FSR(fault), 72 | COLOR_NORMAL); 73 | break; 74 | 75 | case seL4_Fault_UnknownSyscall: 76 | assert(seL4_MessageInfo_get_length(tag) == seL4_UnknownSyscall_Length); 77 | printf("%sBad syscall from [%s]: scno %"PRIuPTR" at PC: %p%s\n", 78 | COLOR_ERROR, 79 | thread_name, 80 | seL4_Fault_UnknownSyscall_get_Syscall(fault), 81 | (void *) seL4_Fault_UnknownSyscall_get_FaultIP(fault), 82 | COLOR_NORMAL 83 | ); 84 | 85 | break; 86 | 87 | case seL4_Fault_UserException: 88 | assert(seL4_MessageInfo_get_length(tag) == seL4_UserException_Length); 89 | printf("%sInvalid instruction from [%s] at PC: %p%s\n", 90 | COLOR_ERROR, 91 | thread_name, 92 | (void *)seL4_Fault_UserException_get_FaultIP(fault), 93 | COLOR_NORMAL); 94 | break; 95 | 96 | case seL4_Fault_CapFault: 97 | printf("%sCap fault from [%s] in phase %s\nPC = %p\nCPtr = %p%s\n", 98 | COLOR_ERROR, thread_name, 99 | seL4_Fault_CapFault_get_InRecvPhase(fault) ? "receive" : "send", 100 | (void *) seL4_Fault_CapFault_get_IP(fault), 101 | (void *) seL4_Fault_CapFault_get_Addr(fault), 102 | COLOR_NORMAL); 103 | break; 104 | default: 105 | /* What? Why are we here? What just happened? */ 106 | printf("Unknown fault from [%s]: %"PRIuPTR" (length = %"PRIuPTR")\n", thread_name, 107 | seL4_MessageInfo_get_label(tag), seL4_MessageInfo_get_length(tag)); 108 | break; 109 | } 110 | } 111 | 112 | void debug_dump_registers(seL4_CPtr tcb) 113 | { 114 | seL4_UserContext context; 115 | int error; 116 | const int num_regs = sizeof(context) / sizeof(seL4_Word); 117 | 118 | error = seL4_TCB_ReadRegisters(tcb, false, 0, num_regs, &context); 119 | if (error) { 120 | ZF_LOGE("Failed to read registers for tcb 0x%lx, error %d", (long) tcb, error); 121 | return; 122 | } 123 | 124 | printf("Register dump:\n"); 125 | for (int i = 0; i < num_regs; i++) { 126 | printf("%s\t:0x%lx\n", register_names[i], (long) ((seL4_Word * )&context)[i]); 127 | } 128 | } 129 | 130 | 131 | -------------------------------------------------------------------------------- /libsosapi/src/sys_stdio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, Data61 3 | * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 | * ABN 41 687 119 230. 5 | * 6 | * This software may be distributed and modified according to the terms of 7 | * the GNU General Public License version 2. Note that NO WARRANTY is provided. 8 | * See "LICENSE_GPLv2.txt" for details. 9 | * 10 | * @TAG(DATA61_GPL) 11 | */ 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | #include 32 | 33 | #define STDIN_FD 0 34 | #define STDOUT_FD 1 35 | #define STDERR_FD 2 36 | 37 | long sys_writev(va_list ap) 38 | { 39 | int fildes = va_arg(ap, int); 40 | struct iovec *iov = va_arg(ap, struct iovec *); 41 | int iovcnt = va_arg(ap, int); 42 | 43 | long long sum = 0; 44 | long ret = 0; 45 | 46 | /* The iovcnt argument is valid if greater than 0 and less than or equal to IOV_MAX. */ 47 | if (iovcnt <= 0 || iovcnt > IOV_MAX) { 48 | return -EINVAL; 49 | } 50 | 51 | /* The sum of iov_len is valid if less than or equal to SSIZE_MAX i.e. cannot overflow 52 | a ssize_t. */ 53 | for (int i = 0; i < iovcnt; i++) { 54 | sum += (long long)iov[i].iov_len; 55 | if (sum > SSIZE_MAX) { 56 | return -EINVAL; 57 | } 58 | } 59 | 60 | /* If all the iov_len members in the array are 0, return 0. */ 61 | if (!sum) { 62 | return 0; 63 | } 64 | 65 | for (int i = 0; i < iovcnt; i++) { 66 | if (iov[i].iov_len == 0) { 67 | continue; 68 | } 69 | 70 | int nr = sos_write(fildes, iov[i].iov_base, iov[i].iov_len); 71 | 72 | if (nr < 0) { 73 | if (!ret) { 74 | ret = nr; 75 | } 76 | break; 77 | } 78 | 79 | ret += nr; 80 | if (nr != iov[i].iov_len) { 81 | break; 82 | } 83 | } 84 | 85 | return ret; 86 | } 87 | 88 | long sys_readv(va_list ap) 89 | { 90 | int fd = va_arg(ap, int); 91 | struct iovec *iov = va_arg(ap, struct iovec *); 92 | int iovcnt = va_arg(ap, int); 93 | int i; 94 | long ret = 0; 95 | 96 | for (i = 0; i < iovcnt; i++) { 97 | int nr = sos_read(fd, iov[i].iov_base, iov[i].iov_len); 98 | 99 | if (nr < 0) { 100 | if (!ret) { 101 | ret = nr; 102 | } 103 | break; 104 | } 105 | 106 | ret += nr; 107 | if (nr != iov[i].iov_len) { 108 | break; 109 | } 110 | } 111 | 112 | return ret; 113 | } 114 | 115 | long sys_read(va_list ap) 116 | { 117 | int fd = va_arg(ap, int); 118 | void *buf = va_arg(ap, void *); 119 | size_t count = va_arg(ap, size_t); 120 | /* construct an iovec and call readv */ 121 | struct iovec iov = {.iov_base = buf, .iov_len = count }; 122 | return readv(fd, &iov, 1); 123 | } 124 | 125 | long sys_write(va_list ap) 126 | { 127 | int fd = va_arg(ap, int); 128 | void *buf = va_arg(ap, void *); 129 | size_t count = va_arg(ap, size_t); 130 | /* construct an iovec and call readv */ 131 | struct iovec iov = {.iov_base = buf, .iov_len = count }; 132 | return writev(fd, &iov, 1); 133 | } 134 | 135 | long sys_ioctl(va_list ap) 136 | { 137 | int fd = va_arg(ap, int); 138 | int request = va_arg(ap, int); 139 | (void)request; 140 | /* muslc does some ioctls to stdout, so just allow these to silently 141 | go through */ 142 | if (fd == STDOUT_FD) { 143 | return 0; 144 | } 145 | assert(!"not implemented"); 146 | return 0; 147 | } 148 | 149 | static long sos_open_wrapper(const char *pathname, int flags) 150 | { 151 | long fd = sos_open(pathname, flags); 152 | if (fd == STDIN_FD || fd == STDOUT_FD || fd == STDERR_FD) { 153 | /* Internally muslc believes it is on a posix system with 154 | * stdin, stdout and stderr already open with fd's 0, 1 and 2 155 | * respectively. To make the system semi-sane we want to 156 | * allow muslc to keep using them so that such usages 157 | * can easily be detected. This means that your system 158 | * should not be returning these fd's as a result of 159 | * open calls otherwise things will get confusing. If you 160 | * do chose to have these fd's already open and existing 161 | * then you can remove this check. But make sure you 162 | * understand what is going on first! */ 163 | assert(!"muslc is now going to be very confused"); 164 | return -ENOMEM; 165 | } 166 | 167 | return fd; 168 | } 169 | 170 | long sys_openat(va_list ap) 171 | { 172 | int dirfd = va_arg(ap, int); 173 | const char *pathname = va_arg(ap, const char *); 174 | int flags = va_arg(ap, int); 175 | UNUSED mode_t mode = va_arg(ap, mode_t); 176 | /* mask out flags we don't support */ 177 | flags &= ~O_LARGEFILE; 178 | /* someone at some point got confused about what are flags and what the mode 179 | * is. so this does actually make sense */ 180 | return sos_open_wrapper(pathname, flags); 181 | } 182 | 183 | long sys_close(va_list ap) 184 | { 185 | int fd = va_arg(ap, int); 186 | return sos_close(fd); 187 | } 188 | -------------------------------------------------------------------------------- /libco/doc/usage.md: -------------------------------------------------------------------------------- 1 | # License 2 | libco is released under the ISC license. 3 | 4 | # Foreword 5 | libco is a cross-platform, permissively licensed implementation of 6 | cooperative-multithreading; a feature that is sorely lacking from the ISO C/C++ 7 | standard. 8 | 9 | The library is designed for maximum speed and portability, and not for safety or 10 | features. If safety or extra functionality is desired, a wrapper API can easily 11 | be written to encapsulate all library functions. 12 | 13 | Behavior of executing operations that are listed as not permitted below result 14 | in undefined behavior. They may work anyway, they may cause undesired / unknown 15 | behavior, or they may crash the program entirely. 16 | 17 | The goal of this library was to simplify the base API as much as possible, 18 | implementing only that which cannot be implemented using pure C. Additional 19 | functionality after this would only complicate ports of this library to new 20 | platforms. 21 | 22 | # Porting 23 | This document is included as a reference for porting libco. Please submit any 24 | ports you create to me, so that libco can become more useful. Please note that 25 | since libco is permissively licensed, you must submit your code as a work of the 26 | public domain in order for it to be included in the official distribution. 27 | 28 | Full credit will be given in the source code of the official release. Please 29 | do not bother submitting code to me under any other license -- including GPL, 30 | LGPL, BSD or CC -- I am not interested in creating a library with multiple 31 | different licenses depending on which targets are used. 32 | 33 | Note that there are a variety of compile-time options in `settings.h`, 34 | so if you want to use libco on a platform where it is not supported by default, 35 | you may be able to configure the implementation appropriately without having 36 | to make a whole new port. 37 | 38 | # Synopsis 39 | ```c 40 | typedef void* cothread_t; 41 | 42 | cothread_t co_active(void); 43 | cothread_t co_create(unsigned int heapsize, void (*coentry)(void)); 44 | void co_delete(cothread_t cothread); 45 | void co_switch(cothread_t cothread); 46 | ``` 47 | 48 | # Usage 49 | ## cothread_t 50 | ```c 51 | typedef void* cothread_t; 52 | ``` 53 | Handle to cothread. 54 | 55 | Handle must be of type `void*`. 56 | 57 | A value of null (0) indicates an uninitialized or invalid handle, whereas a 58 | non-zero value indicates a valid handle. A valid handle is backed by execution 59 | state to which the execution can be co_switch()ed to. 60 | 61 | ## co_active 62 | ```c 63 | cothread_t co_active(void); 64 | ``` 65 | Return handle to current cothread. 66 | 67 | Note that the handle is valid even if the function is called from a non-cothread 68 | context. To achieve this, we save the execution state in an internal buffer, 69 | instead of using the user-provided memory. Since this handle is valid, it can 70 | be used to co_switch to this context from another cothread. In multi-threaded 71 | applications, make sure to not switch non-cothread context across CPU cores, 72 | to prevent any possible conflicts with the OS scheduler. 73 | 74 | ## co_derive 75 | ```c 76 | cothread_t co_derive(void* memory, 77 | unsigned int heapsize, 78 | void (*coentry)(void)); 79 | ``` 80 | Initializes new cothread. 81 | 82 | This function is identical to `co_create`, only it attempts to use the provided 83 | memory instead of allocating new memory on the heap. Please note that certain 84 | implementations (currently only Windows Fibers) cannot be created using existing 85 | memory, and as such, this function will fail. 86 | 87 | ## co_create 88 | ```c 89 | cothread_t co_create(unsigned int heapsize, 90 | void (*coentry)(void)); 91 | ``` 92 | Create new cothread. 93 | 94 | `heapsize` is the amount of memory allocated for the cothread stack, specified 95 | in bytes. This is unfortunately impossible to make fully portable. It is 96 | recommended to specify sizes using `n * sizeof(void*)`. It is better to err 97 | on the side of caution and allocate more memory than will be needed to ensure 98 | compatibility with other platforms, within reason. A typical heapsize for a 99 | 32-bit architecture is ~1MB. 100 | 101 | When the new cothread is first called, program execution jumps to coentry. 102 | This function does not take any arguments, due to portability issues with 103 | passing function arguments. However, arguments can be simulated by the use 104 | of global variables, which can be set before the first call to each cothread. 105 | 106 | `coentry()` must not return, and should end with an appropriate `co_switch()` 107 | statement. Behavior is undefined if entry point returns normally. 108 | 109 | Library is responsible for allocating cothread stack memory, to free 110 | the user from needing to allocate special memory capable of being used 111 | as program stack memory on platforms where this is required. 112 | 113 | User is always responsible for deleting cothreads with `co_delete()`. 114 | 115 | Return value of `null` (0) indicates cothread creation failed. 116 | 117 | ## co_delete 118 | ```c 119 | void co_delete(cothread_t cothread); 120 | ``` 121 | Delete specified cothread. 122 | 123 | `null` (0) or invalid cothread handle is not allowed. 124 | 125 | Passing handle of active cothread to this function is not allowed. 126 | 127 | Passing handle of primary cothread is not allowed. 128 | 129 | ## co_serializable 130 | 131 | ```c 132 | int co_serializable(void); 133 | ``` 134 | 135 | Returns non-zero if the implementation keeps the entire coroutine state in the 136 | buffer passed to `co_derive()`. That is, if `co_serializable()` returns 137 | non-zero, and if your cothread does not modify the heap or any process-wide 138 | state, then you can "snapshot" the cothread's state by taking a copy of the 139 | buffer originally passed to `co_derive()`, and "restore" a previous state 140 | by copying the snapshot back into the buffer it came from. 141 | 142 | ## co_switch 143 | ```c 144 | void co_switch(cothread_t cothread); 145 | ``` 146 | Switch to specified cothread. 147 | 148 | `null` (0) or invalid cothread handle is not allowed. 149 | 150 | Passing handle of active cothread to this function is not allowed. 151 | --------------------------------------------------------------------------------