├── .gitignore ├── .gitmodules ├── Kconfig ├── LICENSE ├── Makefile ├── README.md ├── arch ├── Kconfig └── arm │ ├── Kconfig │ ├── Makefile │ ├── arch_regs.c │ ├── cp15.c │ ├── cp15.h │ ├── cp15_64.c │ ├── fault.c │ ├── init.c │ ├── irq.c │ ├── lpae.c │ ├── lpae.h │ ├── optee.c │ ├── paging.c │ ├── paging.h │ ├── psci.c │ ├── smccc.c │ ├── traps.c │ └── v7 │ ├── Makefile │ ├── context.S │ ├── head.S │ ├── mutex.S │ ├── smccc.S │ └── vector.S ├── configs ├── bananapi_defconfig ├── lager_defconfig ├── odroidxu_defconfig └── rtsm_defconfig ├── core ├── Kconfig ├── Makefile ├── kmus.c ├── main.c ├── sched │ ├── Makefile │ ├── rr.c │ ├── rt-edf.c │ ├── rt-rm.c │ ├── sched-config.c │ └── scheduler.c ├── timer.c ├── vdev.c ├── vm │ ├── Makefile │ ├── atags.c │ ├── context_switch.c │ ├── vcpu.c │ ├── virq_map.c │ ├── vm.c │ └── vmem.c └── vm_config.c ├── drivers ├── Kconfig ├── Makefile ├── dma │ ├── Makefile │ └── sun4i-dma.c ├── generic_timer.c ├── gic-v2.c ├── mct.c ├── serial │ ├── Kconfig │ ├── Makefile │ ├── serial_ns16550.c │ ├── serial_pl01x.c │ ├── serial_s5p.c │ └── serial_sh.c ├── sp804.c └── vdev │ ├── Kconfig │ ├── Makefile │ ├── vdev_cp.c │ ├── vdev_gicd.c │ ├── vdev_hvc_ping.c │ ├── vdev_hvc_stay.c │ ├── vdev_hvc_yield.c │ ├── vdev_pl01x.c │ ├── vdev_pl180.c │ ├── vdev_sample.c │ ├── vdev_sp804.c │ ├── vdev_sysreg.c │ └── vdev_timer.c ├── include ├── arch │ ├── armv7.h │ ├── gicv2_bit.h │ ├── irq.h │ ├── optee.h │ ├── psci.h │ ├── smccc.h │ └── v7 │ │ ├── barrier.h │ │ ├── cache.h │ │ ├── cp15.h │ │ ├── cpsr.h │ │ ├── generic_timer.h │ │ ├── hcr.h │ │ ├── hint_inst.h │ │ ├── hsctlr.h │ │ ├── hsr.h │ │ ├── local_irq.h │ │ ├── mcrmrc.h │ │ ├── mutex.h │ │ ├── smp.h │ │ ├── tlb.h │ │ └── vmsa.h ├── arch_regs.h ├── asm │ ├── asm.h │ └── macro.h ├── atags.h ├── core │ ├── context_switch.h │ ├── kmus.h │ ├── sched │ │ ├── sched-config.h │ │ └── scheduler_skeleton.h │ ├── scheduler.h │ ├── timer.h │ └── vm │ │ ├── vcpu.h │ │ ├── vm.h │ │ └── vmem.h ├── debug.h ├── device.h ├── drivers │ ├── dma │ │ └── sun4i-dma.h │ ├── gic-v2.h │ ├── mct.h │ ├── pl180.h │ ├── serial_ns16550.h │ ├── serial_pl01x.h │ ├── serial_s5p.h │ ├── serial_sh.h │ ├── sp804.h │ └── vdev │ │ ├── vdev_gicd.h │ │ └── vdev_timer.h ├── generated │ └── .gitignore ├── io.h ├── irq-chip.h ├── lib │ ├── list.h │ └── stringify.h ├── serial.h ├── size.h ├── types.h ├── vdev.h ├── vm_config.h └── vm_map.h ├── lib └── c │ ├── include │ ├── assert.h │ ├── complex.h │ ├── ctype.h │ ├── errno.h │ ├── format.h │ ├── inttypes.h │ ├── iso646.h │ ├── k_r_malloc.h │ ├── libc_init.h │ ├── limits.h │ ├── locale.h │ ├── setjmp.h │ ├── stdarg.h │ ├── stdbool.h │ ├── stddef.h │ ├── stdint.h │ ├── stdio.h │ ├── stdlib.h │ ├── string.h │ └── time.h │ ├── src │ ├── Makefile │ ├── aligned_alloc.c │ ├── arch-arm │ │ ├── Makefile │ │ ├── aeabi_div0.c │ │ ├── aeabi_uidivmod.S │ │ ├── aeabi_uldivmod.S │ │ ├── assembly.h │ │ ├── divmodsi4.S │ │ ├── jmp.S │ │ ├── udivmoddi4.c │ │ └── udivmodsi4.S │ ├── asctime.c │ ├── assert.c │ ├── calloc.c │ ├── clearerr.c │ ├── clock.c │ ├── ctype.c │ ├── difftime.c │ ├── errno.c │ ├── exit.c │ ├── fclose.c │ ├── feof.c │ ├── ferror.c │ ├── fflush.c │ ├── fgetc.c │ ├── fgets.c │ ├── format.c │ ├── fprintf.c │ ├── fputc.c │ ├── fputs.c │ ├── fread.c │ ├── fs-bootinfo │ │ └── fopen.c │ ├── fs-null │ │ └── fopen.c │ ├── fscanf.c │ ├── fseek.c │ ├── ftell.c │ ├── fwrite.c │ ├── getchar.c │ ├── getenv.c │ ├── gmtime.c │ ├── init_libc.c │ ├── locale.c │ ├── localtime.c │ ├── malloc.c │ ├── memchr.c │ ├── memcmp.c │ ├── memcpy.c │ ├── memmove.c │ ├── memset.c │ ├── mktime.c │ ├── printf.c │ ├── putchar.c │ ├── puts.c │ ├── qsort.c │ ├── rand.c │ ├── realloc.c │ ├── remove.c │ ├── rename.c │ ├── rewind.c │ ├── snprintf.c │ ├── sprintf.c │ ├── srand.c │ ├── strcat.c │ ├── strchr.c │ ├── strcmp.c │ ├── strcoll.c │ ├── strcpy.c │ ├── strcspn.c │ ├── strdup.c │ ├── strerror.c │ ├── strftime.c │ ├── strlen.c │ ├── strncat.c │ ├── strncmp.c │ ├── strncpy.c │ ├── strpbrk.c │ ├── strrchr.c │ ├── strspn.c │ ├── strstr.c │ ├── strtod.c │ ├── strtok.c │ ├── strtol.c │ ├── strtoul.c │ ├── sys-baremetal │ │ ├── Makefile │ │ ├── arch-arm │ │ │ ├── Makefile │ │ │ ├── sys_fgetc.c │ │ │ ├── sys_fputc.c │ │ │ ├── sys_morecore.c │ │ │ ├── sys_stdio.c │ │ │ └── sys_tmpfile.c │ │ └── sys_abort.c │ ├── system.c │ ├── time.c │ ├── tmpfile.c │ ├── ungetc.c │ ├── vfprintf.c │ ├── vprintf.c │ └── vsnprintf.c │ └── test │ ├── fs-bootinfo │ ├── data │ │ └── foo │ └── test_fs.c │ ├── fs-null │ └── test_fs.c │ ├── test_libs_c.c │ └── test_libs_c.h ├── platform ├── Kconfig ├── Makefile ├── bananapi │ ├── bananapi.lds.S │ ├── config.h │ ├── devicetree.h │ ├── guest.c │ ├── interrupt.c │ ├── platform.c │ └── platform.h ├── config.h ├── lager │ ├── config.h │ ├── devicetree.h │ ├── guest.c │ ├── interrupt.c │ ├── lager.lds.S │ ├── platform.c │ └── platform.h ├── odroidxu │ ├── config.h │ ├── devicetree.h │ ├── guest.c │ ├── interrupt.c │ ├── odroidxu.lds.S │ ├── platform.c │ └── platform.h └── rtsm │ ├── config.h │ ├── guest.c │ ├── interrupt.c │ ├── platform.c │ ├── platform.h │ └── rtsm.lds.S ├── scripts ├── Kbuild.include ├── Makefile.build ├── Makefile.host ├── Makefile.lib ├── basic │ ├── Makefile │ ├── docproc.c │ ├── fixdep.c │ └── split-include.c ├── defconfig └── kconfig │ ├── Makefile │ ├── POTFILES.in │ ├── check.sh │ ├── conf.c │ ├── confdata.c │ ├── expr.c │ ├── expr.h │ ├── gconf.c │ ├── gconf.glade │ ├── images.c │ ├── kconfig_load.c │ ├── kxgettext.c │ ├── lex.zconf.c │ ├── lkc.h │ ├── lkc_proto.h │ ├── lxdialog │ ├── Makefile │ ├── check-lxdialog.sh │ ├── checklist.c │ ├── colors.h │ ├── dialog.h │ ├── inputbox.c │ ├── lxdialog.c │ ├── menubox.c │ ├── msgbox.c │ ├── textbox.c │ ├── util.c │ └── yesno.c │ ├── mconf.c │ ├── menu.c │ ├── qconf.cc │ ├── qconf.h │ ├── symbol.c │ ├── util.c │ ├── zconf.gperf │ ├── zconf.hash.c │ ├── zconf.l │ ├── zconf.tab.c │ └── zconf.y ├── tests ├── Makefile ├── arch │ └── arm │ │ ├── armv7 │ │ └── armv7_boot_code_here.S │ │ └── armv8 │ │ └── armv8_boot_code_here.S ├── core │ ├── sched │ │ └── sched_related_test_code_here.c │ └── vm │ │ └── vm_related_test_code_here.c ├── driver │ ├── driver_test_code_here.c │ └── vdev │ │ └── vdev_test_code_here.c ├── include │ └── header_file_here.h ├── libs │ ├── Makefile │ ├── test_malloc.c │ └── test_malloc.h ├── tests.c ├── tests.h ├── tests_gic_timer.c ├── tests_gic_timer.h ├── tests_vdev.c └── tests_vdev.h └── toolchain.mk /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | *.o 3 | .* 4 | *.axf 5 | *.map 6 | tags 7 | *.lds 8 | *.orig 9 | dump 10 | scripts/* 11 | toolchains 12 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "qemu"] 2 | path = qemu 3 | url = https://github.com/qemu/qemu.git 4 | -------------------------------------------------------------------------------- /Kconfig: -------------------------------------------------------------------------------- 1 | source "arch/Kconfig" 2 | 3 | menu "Compile-time checks and compiler options" 4 | 5 | config DEBUG 6 | bool "Debug compile option" 7 | default y 8 | 9 | config GCC_V 10 | bool "GCC option v" 11 | default n 12 | 13 | endmenu 14 | 15 | menu "VM configuration" 16 | 17 | config NR_VMS 18 | int "Number of Virtual Machines(or Guest OS)" 19 | default 1 20 | range 1 256 21 | 22 | config VA_START 23 | hex "Virtual address of guest OS" 24 | default 0x00000000 25 | 26 | endmenu 27 | 28 | source "drivers/Kconfig" 29 | 30 | menu "Timer/Scheduler options" 31 | 32 | config SCHED_RM_REPORT 33 | bool "Enable rate monotonic policy report printing" 34 | default n 35 | 36 | config SCHED_EDF_REPORT 37 | bool "Enable earlist deadline first policy report printing" 38 | default n 39 | 40 | config SCHED_STOPWATCH 41 | bool "Enable timing scheduler routine" 42 | default n 43 | 44 | config TIMER_IRQ_STOPWATCH 45 | bool "Enable timing timer IRQ routine" 46 | default n 47 | 48 | config TIMER_DEBUG 49 | bool "Enable printing timer debug info" 50 | default n 51 | 52 | config TIMER_ACCESS_TRAP 53 | bool "Enable vTimer, catch timer accesses from guest" 54 | default y 55 | 56 | config VTIMER_PERIODIC 57 | bool "Use vTimer periodic mode" 58 | default n 59 | 60 | endmenu 61 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2016, Kookmin University Embedded Systems Lab. 2 | All rights reserved. 3 | 4 | This project and its source code are property of Kookmin University Embedded Systems Lab. 5 | 6 | You may grant permission from us to redistribute the original or modified source code and documentation of this project, or the binary produced from it. The word "binary" implies the redistribution of binary in any forms - such as binary image file or product with binary code loaded. 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # How to build khypervisor-v2 2 | 1. Prerequisite 3 | The binary file of Guest OS is located in $(PROJECT_ROOT_DIR)/../guestimages/guest0.bin 4 | 2. Build 5 | >> make 6 | 7 | Github Pages URL : http://kmu-embedded.github.io/k-hypervisor 8 | -------------------------------------------------------------------------------- /arch/Kconfig: -------------------------------------------------------------------------------- 1 | choice 2 | prompt "Architecture select" 3 | default ARM 4 | 5 | config ARM 6 | bool "ARM architecture" 7 | 8 | endchoice # Architecture select 9 | 10 | source "arch/arm/Kconfig" 11 | -------------------------------------------------------------------------------- /arch/arm/Kconfig: -------------------------------------------------------------------------------- 1 | source "core/Kconfig" 2 | 3 | menu "ARM architecture" 4 | depends on ARM 5 | 6 | config ARMV7_VIRT 7 | bool 8 | 9 | config CPU_A7 10 | bool 11 | 12 | config CPU_A15 13 | bool 14 | 15 | choice 16 | prompt "Target select" 17 | 18 | config ARCH_VERSATILE 19 | bool "ARM Ltd. Versatile family" 20 | select ARMV7_VIRT 21 | select CPU_A15 22 | select PL01X_SERIAL 23 | select VDEV_SAMPLE 24 | select VDEV_SP804 25 | select VDEV_SYSREG 26 | select VDEV_PL01X_SERIAL 27 | 28 | config RMOBILE 29 | bool "Renesas ARM SoCs" 30 | select ARMV7_VIRT 31 | select CPU_A15 32 | select SH_SERIAL 33 | 34 | config ARCH_EXYNOS 35 | bool "Samsung EXYNOS" 36 | select ARMV7_VIRT 37 | select CPU_A15 38 | select S5P_SERIAL 39 | select MCT 40 | 41 | config ARCH_SUNXI 42 | bool "Allwinner SUNXI SoCs" 43 | select ARMV7_VIRT 44 | select CPU_A15 45 | select NS16550_SERIAL 46 | 47 | endchoice 48 | 49 | source "platform/Kconfig" 50 | 51 | menuconfig ARM_PSCI 52 | bool "Support for ARM PSCI" 53 | 54 | if ARM_PSCI 55 | 56 | choice 57 | prompt "ARM PSCI version" 58 | 59 | config ARM_PSCI_VERSION_0_1 60 | bool "ARM PSCI version 0.1" 61 | 62 | config ARM_PSCI_VERSION_1_0 63 | bool "ARM PSCI version 1.0" 64 | 65 | config ARM_PSCI_VERSION_1_1 66 | bool "ARM PSCI version 1.1" 67 | 68 | endchoice 69 | 70 | config ARM_PSCI_FN_BASE 71 | hex "ARM PSCI base function id" 72 | default 0x84000000 if ARM_PSCI_VERSION_1_0 || ARM_PSCI_VERSION_1_1 73 | 74 | endif 75 | 76 | menuconfig OPTEE 77 | bool "Support for OP-TEE Trusted OS" 78 | 79 | if OPTEE 80 | 81 | config NR_OPTEE_THREAD 82 | int "Number of OP-TEE threads" 83 | default 8 84 | range 1 256 85 | 86 | endif 87 | 88 | endmenu 89 | 90 | -------------------------------------------------------------------------------- /arch/arm/Makefile: -------------------------------------------------------------------------------- 1 | include ${SOURCE_PATH}/arch/arm/v7/Makefile 2 | 3 | objs-y:= 4 | 5 | objs-y += cp15.o 6 | objs-y += cp15_64.o 7 | objs-y += traps.o 8 | objs-y += init.o 9 | objs-y += irq.o 10 | objs-y += lpae.o 11 | objs-y += paging.o 12 | objs-y += arch_regs.o 13 | objs-y += fault.o 14 | objs-$(CONFIG_OPTEE) += optee.o 15 | objs-$(CONFIG_ARM_PSCI) += psci.o 16 | objs-y += smccc.o 17 | 18 | obj-y += $(patsubst %, arch/arm/%, ${objs-y}) 19 | 20 | SUBDIRECTORIES += arch/arm/v7 21 | -------------------------------------------------------------------------------- /arch/arm/cp15.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define opc2_bit (0x7 << 17) 6 | #define opc1_bit (0x7 << 14) 7 | #define crn_bit (0xf << 10) 8 | #define rt_bit (0xf << 5) 9 | #define crm_bit (0xf << 1) 10 | 11 | #define opc2(iss) (((iss) & opc2_bit) >> 17) 12 | #define opc1(iss) (((iss) & opc1_bit) >> 14) 13 | #define crn(iss) (((iss) & crn_bit) >> 10) 14 | #define rt(iss) (((iss) & rt_bit) >> 5) 15 | #define crm(iss) (((iss) & crm_bit) >> 1) 16 | 17 | #define decode_dir(iss) (iss & 1) 18 | #define decode_cp15(iss) __CP32(15, crn(iss), opc1(iss), crm(iss), opc2(iss)) 19 | 20 | int32_t emulate_cp15_32(struct core_regs *regs, uint32_t iss) 21 | { 22 | int32_t ret = 0; 23 | uint8_t rt = rt(iss); 24 | uint8_t dir = decode_dir(iss); 25 | 26 | switch (decode_cp15(iss)) { 27 | case CP32(MIDR): { 28 | if (!dir) { 29 | write_cp32(regs->gpr[rt], MIDR); 30 | } else { 31 | regs->gpr[rt] = read_cp32(MIDR); 32 | } 33 | ret = 0; 34 | break; 35 | } 36 | case CP32(DCISW): 37 | write_cp32(regs->gpr[rt], DCCISW); 38 | break; 39 | case CP32(DCCSW): 40 | write_cp32(regs->gpr[rt], DCCSW); 41 | break; 42 | case CP32(DCCISW): 43 | write_cp32(regs->gpr[rt], DCCISW); 44 | break; 45 | case CP32(CNTFRQ) : 46 | case CP32(CNTKCTL) : 47 | case CP32(CNTP_TVAL) : 48 | case CP32(CNTP_CTL) : 49 | case CP32(CNTV_TVAL) : 50 | case CP32(CNTV_CTL) : 51 | vdev_timer_access32(dir, decode_cp15(iss), ®s->gpr[rt]); 52 | break; 53 | default: 54 | printf("not implement: %x\n", decode_cp15(iss)); 55 | ret = -1; 56 | break; 57 | } 58 | 59 | return ret; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /arch/arm/cp15.h: -------------------------------------------------------------------------------- 1 | #ifndef __CP_15_H__ 2 | #define __CP_15_H__ 3 | 4 | #include 5 | 6 | int32_t emulate_cp15_32(struct core_regs *regs, uint32_t iss); 7 | int32_t emulate_cp15_64(struct core_regs *regs, uint32_t iss); 8 | 9 | #endif // __CP15_H__ 10 | -------------------------------------------------------------------------------- /arch/arm/cp15_64.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define opc1_bit (0xf << 16) 6 | #define rt2_bit (0xf << 10) 7 | #define rt_bit (0xf << 5) 8 | #define crm_bit (0xf << 1) 9 | 10 | #define opc1(iss) (((iss) & opc1_bit) >> 16) 11 | #define rt2(iss) (((iss) & rt2_bit) >> 10) 12 | #define rt(iss) (((iss) & rt_bit) >> 5) 13 | #define crm(iss) (((iss) & crm_bit) >> 1) 14 | 15 | #define decode_dir(iss) ((iss) & 1) 16 | #define decode_cp15(iss) __CP64(15, opc1(iss), crm(iss)) 17 | 18 | int32_t emulate_cp15_64(struct core_regs *regs, uint32_t iss) 19 | { 20 | int32_t ret = 0; 21 | uint8_t rt = rt(iss); 22 | uint8_t rt2 = rt2(iss); 23 | uint8_t dir = decode_dir(iss); 24 | 25 | switch (decode_cp15(iss)) { 26 | case CP64(CNTPCT) : 27 | case CP64(CNTVCT) : 28 | case CP64(CNTP_CVAL) : 29 | case CP64(CNTV_CVAL) : 30 | vdev_timer_access64(dir, decode_cp15(iss), ®s->gpr[rt], ®s->gpr[rt2]); 31 | break; 32 | default: 33 | printf("not implement: %x\n", decode_cp15(iss)); 34 | ret = -1; 35 | break; 36 | } 37 | 38 | return ret; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /arch/arm/fault.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "lpae.h" 8 | 9 | int handle_data_abort(struct core_regs *regs, uint32_t iss) 10 | { 11 | int ret = -1; 12 | uint32_t fipa = read_cp32(HPFAR) << IPA_SHIFT; 13 | fipa |= (read_cp32(HDFAR) & PAGE_OFFSET_MASK); 14 | fipa = read_cp32(HPFAR) << IPA_SHIFT; 15 | 16 | switch (DFSC(iss)) { 17 | // TODO: remove unused cases. 18 | case TRANS_FAULT(1) ... TRANS_FAULT(3): 19 | printf("Translation Fault!!\n"); 20 | printf("\tWe do not allow translation fault from guest in stage 2 address\n"); 21 | printf("\ttranslation, so if you see this message, you have to add a mapping\n"); 22 | printf("\ttable into platform//guest.c\n"); 23 | printf("\tfault address is here: 0x%08x\n", fipa); 24 | 25 | ret = 0; 26 | break; 27 | 28 | case ACCESS_FAULT(1) ... ACCESS_FAULT(3): 29 | vdev_handler(regs, iss); 30 | ret = 0; 31 | break; 32 | 33 | case PERM_FAULT(1) ... PERM_FAULT(3): 34 | printf("PERM_FAULT: fipa 0x%08x\n", fipa); 35 | break; 36 | 37 | case SYNC_ABORT: 38 | printf("SYNC_FAULT: fipa 0x%08x\n", fipa); 39 | break; 40 | 41 | case ASYNC_ABORT: 42 | printf("ASYNC_ABORT\n"); 43 | break; 44 | 45 | case ABORT_ON_TABLE_WALK(1) ... ABORT_ON_TABLE_WALK(3): 46 | printf("ABORT_ON_TABLE_WALK\n"); 47 | break; 48 | 49 | case SYNC_PERORR: 50 | printf("SYNC_PERORR\n"); 51 | break; 52 | 53 | case ASYNC_PERORR: 54 | printf("ASYNC_PERORR\n"); 55 | break; 56 | 57 | case PERORR_ON_TABLE_WALK(1) ... PERORR_ON_TABLE_WALK(3): 58 | printf("PERORR_ON_TABLE_WALK\n"); 59 | break; 60 | 61 | case ALINGMENT_FAULT: { 62 | uint32_t hcr = read_cp32(HCR); 63 | 64 | printf("Alignment Fault!!\n"); 65 | printf("ARM defines the root cause of alignment fault taken into hypervisor as belows\n"); 66 | 67 | if (regs->cpsr == CPSR_MODE(HYP)) { 68 | printf("\t1. When the processor is in Hyp mode.\n"); 69 | } else { 70 | if ((hcr & HCR_BIT(TGE)) != 1) { 71 | printf("\t2. When the processor is in a PL1 or PL0 mode and the exception is generated\n"); 72 | printf("\t because the Non-secure PL1&0 stage 2 translation identifies the target of\n"); 73 | printf("\t an unaligned access as Device or Strongly-ordered memory.\n"); 74 | printf("\t NOTE: please check memory attribute at platform//guest.c\n"); 75 | } else { 76 | printf("\t3. The processor is in the PL0 mode and HCR.TGE is set to 1.\n"); 77 | printf("\t For more information see Synchronous external abort, when HCR.TGE is\n"); 78 | printf("\t set to 1 on page B1-1193.\n"); 79 | } 80 | } 81 | printf("HCR: %x\n", hcr); 82 | printf("HDCR %x\n", read_cp32(HDCR)); 83 | printf("HPFAR 0x%08x is UNK\n", read_cp32(HPFAR)); 84 | printf("HDFAR 0x%08x is available\n", fipa); 85 | break; 86 | } 87 | case DEBUG_EVENT: 88 | printf("DEBUG_EVENT\n"); 89 | break; 90 | 91 | case TLB_CONFLICT: 92 | printf("TLB_CONFLICT\n"); 93 | break; 94 | 95 | case DOMAIN_FAULT(1) ... DOMAIN_FAULT(3): 96 | printf("DOMAIN_FAULT"); 97 | break; 98 | 99 | default: 100 | break; 101 | } 102 | return ret; 103 | } 104 | -------------------------------------------------------------------------------- /arch/arm/init.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "paging.h" 11 | 12 | #ifdef CONFIG_ARM_PSCI 13 | #include 14 | #endif 15 | 16 | extern void start_hypervisor(void); 17 | 18 | extern addr_t __hvc_vector; 19 | extern addr_t __HYP_PGTABLE; 20 | uint8_t secondary_smp_pen; 21 | 22 | void boot_secondary_cpus() 23 | { 24 | unsigned long i; 25 | 26 | for (i = 1; i < NR_CPUS; i++) { 27 | #ifdef CONFIG_ARM_PSCI 28 | psci_cpu_on(i, CFG_HYP_START_ADDRESS); 29 | #endif 30 | } 31 | } 32 | 33 | void init_cpu() 34 | { 35 | uint8_t cpuid = smp_processor_id(); 36 | addr_t pgtable = (uint32_t) &__HYP_PGTABLE; 37 | uint32_t hsctlr, hcr; 38 | 39 | // For console debugging. 40 | console_init(); 41 | libc_init(); 42 | 43 | // Set HYP vector table. 44 | write_cp32((uint32_t) &__hvc_vector, HVBAR); 45 | assert(read_cp32(HVBAR) == (uint32_t) &__hvc_vector); 46 | 47 | // Set pgtable for HYP mode. 48 | write_cp64((uint64_t) pgtable, HTTBR); 49 | assert(read_cp64(HTTBR) == pgtable); 50 | 51 | // Set memory attributes. 52 | write_cp32(HTCR_VALUE, HTCR); 53 | write_cp32(HMAIR0_VALUE, HMAIR0); 54 | write_cp32(HMAIR1_VALUE, HMAIR1); 55 | 56 | // Two lines as below will be removed. 57 | paging_create((addr_t) &__HYP_PGTABLE); 58 | platform_init(); 59 | 60 | hsctlr = read_cp32(HSCTLR); 61 | hsctlr |= HSCTLR_BIT(M) | HSCTLR_BIT(A) | HSCTLR_BIT(C) | HSCTLR_BIT(I); 62 | write_cp32(hsctlr, HSCTLR); 63 | 64 | hcr = read_cp32(HCR); 65 | hcr |= HCR_BIT(TSC) | HCR_BIT(TSW); 66 | write_cp32(hcr, HCR); 67 | 68 | irq_init(); 69 | 70 | dev_init(); /* we don't have */ 71 | 72 | vdev_init(); /* Already we have */ 73 | 74 | setup_vm_mmap(); 75 | 76 | #ifdef CONFIG_SMP 77 | printf("wake up...other CPUs\n"); 78 | boot_secondary_cpus(); 79 | secondary_smp_pen = 1; 80 | #endif 81 | 82 | printf("%s[%d]: CPU[%d]\n", __func__, __LINE__, cpuid); 83 | 84 | start_hypervisor(); 85 | } 86 | 87 | void init_secondary_cpus() 88 | { 89 | uint8_t cpuid = smp_processor_id(); 90 | addr_t pgtable = (uint32_t) &__HYP_PGTABLE; 91 | uint32_t hsctlr, hcr; 92 | 93 | write_cp32((uint32_t) &__hvc_vector, HVBAR); 94 | assert(read_cp32(HVBAR) == (uint32_t) &__hvc_vector); 95 | 96 | write_cp64((uint64_t) pgtable, HTTBR); 97 | assert(read_cp64(HTTBR) == pgtable); 98 | 99 | write_cp32(HTCR_VALUE, HTCR); 100 | write_cp32(HMAIR0_VALUE, HMAIR0); 101 | write_cp32(HMAIR1_VALUE, HMAIR1); 102 | 103 | hsctlr = read_cp32(HSCTLR); 104 | hsctlr |= HSCTLR_BIT(M) | HSCTLR_BIT(A) | HSCTLR_BIT(C) | HSCTLR_BIT(I); 105 | write_cp32(hsctlr, HSCTLR); 106 | 107 | hcr = read_cp32(HCR); 108 | hcr |= HCR_BIT(TSC) | HCR_BIT(TSW); 109 | write_cp32(hcr, HCR); 110 | 111 | irq_init(); 112 | 113 | printf("%s[%d]: CPU[%d]\n", __func__, __LINE__, cpuid); 114 | 115 | start_hypervisor(); 116 | } 117 | 118 | /* Set Hyp System Trap Register(HSTR) */ 119 | void enable_traps(void) 120 | { 121 | uint32_t hstr = 0; 122 | 123 | hstr = 1 << 0; 124 | write_cp32(hstr, HSTR); 125 | } 126 | -------------------------------------------------------------------------------- /arch/arm/irq.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define VIRQ_MIN_VALID_PIRQ 16 11 | #define VIRQ_NUM_MAX_PIRQS MAX_IRQS 12 | 13 | static irq_handler_t irq_handlers[MAX_IRQS]; 14 | 15 | hvmm_status_t do_irq(struct core_regs *regs) 16 | { 17 | uint32_t irq = irq_hw->ack(); 18 | 19 | irq_hw->eoi(irq); 20 | 21 | if (irq_handlers[irq](irq, regs, 0) != VM_IRQ) { 22 | irq_hw->dir(irq); 23 | } 24 | 25 | return HVMM_STATUS_SUCCESS; 26 | } 27 | 28 | void irq_init() 29 | { 30 | uint32_t hcr; 31 | 32 | set_irqchip_type(); 33 | 34 | hcr = read_cp32(HCR); 35 | hcr |= HCR_BIT(IMO) | HCR_BIT(FMO); 36 | write_cp32(hcr, HCR); 37 | 38 | irq_handler_init(irq_handlers); 39 | } 40 | 41 | void register_irq_handler(uint32_t irq, irq_handler_t handler, uint8_t polarity) 42 | { 43 | if (irq < MAX_IRQS) { 44 | irq_handlers[irq] = handler; 45 | } 46 | irq_hw->set_irq_type(irq, polarity); 47 | irq_hw->enable(irq); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /arch/arm/lpae.c: -------------------------------------------------------------------------------- 1 | #include "lpae.h" 2 | #include 3 | 4 | pgentry set_table(addr_t pa) 5 | { 6 | pgentry entry; 7 | 8 | entry.raw = 0; 9 | entry.table.valid = 0; 10 | entry.table.type = 1; 11 | entry.table.base = pa >> PAGE_SHIFT; 12 | 13 | return entry; 14 | } 15 | 16 | static pgentry set_entry(addr_t pa, uint8_t mem_attr, uint8_t ap, uint8_t af) 17 | { 18 | pgentry entry; 19 | 20 | entry.raw = 0; 21 | entry.page.valid = 1; 22 | entry.page.type = 1; 23 | entry.page.base = pa >> L3_SHIFT; 24 | entry.page.mem_attr = mem_attr; 25 | entry.page.ap = ap; 26 | entry.page.sh = 3; 27 | entry.page.af = af; 28 | entry.page.ng = 1; 29 | entry.page.cb = 0; 30 | entry.page.pxn = 0; 31 | entry.page.xn = 0; 32 | 33 | return entry; 34 | } 35 | 36 | void write_pgentry(addr_t base, addr_t va, addr_t pa, uint8_t mem_attr, uint8_t ap, uint8_t af) 37 | { 38 | uint32_t l1_index, l2_index, l3_index; 39 | addr_t l1_entry_addr, l2_entry_addr, l3_entry_addr; 40 | 41 | l1_index = ((va & 0xC0000) >> ENTRY_SHIFT) >> ENTRY_SHIFT; 42 | l2_index = ((va & 0x3FE00) >> ENTRY_SHIFT); 43 | l3_index = (va & 0x001FF); 44 | 45 | l1_entry_addr = base + GET_OFFSET(l1_index); 46 | l2_entry_addr = (base + 0x1000) + GET_L2_INDEX(l1_index) + GET_OFFSET(l2_index); 47 | l3_entry_addr = (base + 0x5000) + GET_L3_INDEX(l1_index) + GET_L2_INDEX(l2_index) 48 | + GET_OFFSET(l3_index); 49 | 50 | write64(read64(l1_entry_addr) | set_valid, l1_entry_addr); 51 | write64(read64(l2_entry_addr) | set_valid, l2_entry_addr); 52 | write64(set_entry(pa, mem_attr, ap, af).raw, l3_entry_addr); 53 | } 54 | 55 | pgentry read_pgentry(addr_t base, addr_t va) 56 | { 57 | uint32_t l1_index, l2_index, l3_index; 58 | addr_t l3_entry_addr; 59 | 60 | l1_index = ((va & 0xC0000) >> ENTRY_SHIFT) >> ENTRY_SHIFT; 61 | l2_index = ((va & 0x3FE00) >> ENTRY_SHIFT); 62 | l3_index = (va & 0x001FF); 63 | 64 | l3_entry_addr = (base + 0x5000) + GET_L3_INDEX(l1_index) + GET_L2_INDEX(l2_index) 65 | + GET_OFFSET(l3_index); 66 | 67 | return (pgentry) read64(l3_entry_addr); 68 | } 69 | -------------------------------------------------------------------------------- /arch/arm/optee.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "paging.h" 9 | 10 | struct optee_thread threads[CONFIG_NR_OPTEE_THREAD]; 11 | 12 | void handle_optee_get_shm_config(struct core_regs *regs); 13 | int handle_optee_return_from_rpc(struct core_regs *regs); 14 | void handle_optee_rpc(struct core_regs *regs); 15 | 16 | void handle_optee_smc(struct core_regs *regs) 17 | { 18 | uint32_t function_id = regs->gpr[0]; 19 | 20 | switch (function_id) { 21 | case OPTEE_SMC_GET_SHM_CONFIG: 22 | handle_optee_get_shm_config(regs); 23 | return; 24 | case OPTEE_SMC_RETURN_FROM_RPC: 25 | if (handle_optee_return_from_rpc(regs)) 26 | return; 27 | } 28 | 29 | arm_smccc_smc(regs->gpr[0], regs->gpr[1], regs->gpr[2], regs->gpr[3], 30 | regs->gpr[4], regs->gpr[5], regs->gpr[6], regs->gpr[7], 31 | (struct arm_smccc_res *) regs->gpr); 32 | 33 | if (OPTEE_SMC_RET_IS_RPC(regs->gpr[0])) { 34 | handle_optee_rpc(regs); 35 | } 36 | 37 | return; 38 | } 39 | 40 | void handle_optee_get_shm_config(struct core_regs *regs) 41 | { 42 | static struct optee_shm shm = { -1, -1 }; 43 | struct vmcb *vm = get_current_vm(); 44 | 45 | if (shm.base == (uint32_t) -1) { 46 | arm_smccc_smc(regs->gpr[0], 0, 0, 0, 0, 0, 0, 0, 47 | (struct arm_smccc_res *) regs->gpr); 48 | 49 | shm.base = regs->gpr[1]; 50 | shm.size = regs->gpr[2]; 51 | shm.cached = regs->gpr[3]; 52 | 53 | paging_add_mapping(shm.base, shm.base, MT_WRITEBACK_RW_ALLOC, shm.size); 54 | } 55 | 56 | // TODO: need alignment if CONFIG_NR_VMS is not a multiple of 2 57 | regs->gpr[3] = shm.cached; 58 | regs->gpr[2] = shm.size / CONFIG_NR_VMS; 59 | regs->gpr[1] = shm.base + (regs->gpr[2] * vm->vmid); 60 | regs->gpr[0] = OPTEE_SMC_RET_OK; 61 | 62 | paging_add_ipa_mapping(vm->vmem.base, shm.base, shm.base, 63 | MEMATTR_NORMAL_WT_CACHEABLE, 1, shm.size); 64 | } 65 | 66 | int handle_optee_return_from_rpc(struct core_regs *regs) 67 | { 68 | uint32_t thread_id = regs->gpr[3]; 69 | struct optee_thread *thread = &threads[thread_id]; 70 | 71 | switch (thread->rpc) { 72 | case OPTEE_RPC_FUNC_ALLOC: 73 | thread->msg = (struct optee_msg_arg *) regs->gpr[2]; 74 | break; 75 | case OPTEE_RPC_FUNC_FREE: 76 | thread->msg = NULL; 77 | break; 78 | case OPTEE_RPC_FUNC_DUMMY: 79 | if (thread->is_sleep) { // make normal world's thread to do busy waiting 80 | regs->gpr[0] = OPTEE_RPC_FUNC_DUMMY; 81 | return 1; 82 | } else { 83 | thread->msg->ret = 0; 84 | } 85 | } 86 | 87 | thread->rpc = -1; 88 | return 0; 89 | } 90 | 91 | void handle_optee_rpc(struct core_regs *regs) 92 | { 93 | uint32_t thread_id = regs->gpr[3]; 94 | struct optee_thread *thread = &threads[thread_id]; 95 | 96 | thread->rpc = regs->gpr[0]; 97 | 98 | if (thread->rpc != OPTEE_RPC_FUNC_CMD) return; 99 | 100 | struct optee_msg_arg *msg = thread->msg; 101 | 102 | switch (msg->cmd) { 103 | case OPTEE_RPC_CMD_WAIT_QUEUE: 104 | if (msg->params[0].u.val.a) { // OPTEE_RPC_CMD_WQ_WAKE 105 | thread = &threads[msg->params[0].u.val.b]; 106 | thread->is_sleep = false; 107 | } else { // OPTEE_RPC_CMD_WQ_SLEEP 108 | thread->rpc = regs->gpr[0] = OPTEE_RPC_FUNC_DUMMY; 109 | thread->is_sleep = true; 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /arch/arm/paging.c: -------------------------------------------------------------------------------- 1 | #include "paging.h" 2 | #include 3 | #include 4 | 5 | void paging_create(addr_t base) 6 | { 7 | int i = 0; 8 | 9 | uint32_t second_base = base + 0x1000; 10 | uint32_t third_base = second_base + 0x4000; 11 | 12 | for (i = 0; i < L1_ENTRY; i++) { 13 | write64(set_table(second_base + GET_L2_INDEX(i)).raw, base + GET_OFFSET(i)); 14 | } 15 | 16 | for (i = 0; i < L1_ENTRY * L2_ENTRY; i++) { 17 | write64(set_table(third_base + GET_L2_INDEX(i)).raw, second_base + GET_OFFSET(i)); 18 | } 19 | } 20 | 21 | void paging_add_mapping(addr_t va, addr_t pa, uint8_t mem_attr, uint32_t size) 22 | { 23 | int i = 0; 24 | uint64_t httbr = read_cp64(HTTBR); 25 | 26 | for (i = 0; i < size; i += 0x1000, va += 0x1000, pa += 0x1000) { 27 | write_pgentry((addr_t) httbr, va >> PAGE_SHIFT, pa, mem_attr, 0, 1); 28 | } 29 | } 30 | 31 | void paging_add_ipa_mapping(addr_t base, addr_t ipa, addr_t pa, uint8_t mem_attr, uint8_t af, uint32_t size) 32 | { 33 | int i = 0; 34 | 35 | for (i = 0; i < size; i += 0x1000, ipa += 0x1000, pa += 0x1000) { 36 | write_pgentry(base, ipa >> PAGE_SHIFT, pa, mem_attr, 3, af); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /arch/arm/paging.h: -------------------------------------------------------------------------------- 1 | #ifndef __PAGING_H__ 2 | #define __PAGING_H__ 3 | 4 | #include 5 | #include "lpae.h" 6 | 7 | void paging_init(); 8 | void paging_create(addr_t base); 9 | void paging_add_mapping(addr_t va, addr_t pa, uint8_t mem_attr, uint32_t size); 10 | void paging_add_ipa_mapping(addr_t base, addr_t ipa, addr_t pa, uint8_t mem_attr, uint8_t af, uint32_t size); 11 | 12 | #endif /* __MM_H__*/ 13 | -------------------------------------------------------------------------------- /arch/arm/psci.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int psci_cpu_suspend(uint32_t state, unsigned long entry_point) 10 | { 11 | struct arm_smccc_res res; 12 | 13 | arm_smccc_smc(PSCI_FN_CPU_SUSPEND, state, entry_point, 0, 0, 0, 0, 0, &res); 14 | return res.a0; 15 | } 16 | 17 | int psci_cpu_off(uint32_t state) 18 | { 19 | struct arm_smccc_res res; 20 | 21 | arm_smccc_smc(PSCI_FN_CPU_OFF, state, 0, 0, 0, 0, 0, 0, &res); 22 | return res.a0; 23 | } 24 | 25 | int psci_cpu_on(unsigned long cpu_id, unsigned long entry_point) 26 | { 27 | struct arm_smccc_res res; 28 | 29 | arm_smccc_smc(PSCI_FN_CPU_ON, cpu_id, entry_point, 0, 0, 0, 0, 0, &res); 30 | return res.a0; 31 | } 32 | 33 | int psci_migrate(unsigned long cpu_id) 34 | { 35 | struct arm_smccc_res res; 36 | 37 | arm_smccc_smc(PSCI_FN_MIGRATE, cpu_id, 0, 0, 0, 0, 0, 0, &res); 38 | return res.a0; 39 | } 40 | 41 | int emulate_psci_cpu_on(struct core_regs *regs) 42 | { 43 | uint32_t vcpuid = regs->gpr[1]; 44 | uint32_t entry_point = regs->gpr[2]; 45 | 46 | struct vmcb *vm = get_current_vm(); 47 | struct vcpu *target_vcpu = NULL; 48 | 49 | if (vcpuid >= vm->num_vcpus) { 50 | return PSCI_RET_INVALID_PARAMS; 51 | } 52 | 53 | target_vcpu = vm->vcpu[vcpuid]; 54 | target_vcpu->regs.core_regs.pc = entry_point; 55 | 56 | sched_vcpu_attach(target_vcpu->vcpuid, target_vcpu->pcpuid); 57 | target_vcpu->state = VCPU_ACTIVATED; 58 | 59 | printf("vcpu[%d] attatched to pcpu[%d] \n", target_vcpu->vcpuid, target_vcpu->pcpuid); 60 | 61 | return PSCI_RET_SUCCESS; 62 | } 63 | -------------------------------------------------------------------------------- /arch/arm/smccc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifdef CONFIG_OPTEE 6 | #include 7 | #endif 8 | 9 | #ifdef CONFIG_ARM_PSCI 10 | #include 11 | #endif 12 | 13 | static inline void handle_misc_arm_smccc(struct core_regs *regs); 14 | 15 | int handle_arm_smccc(struct core_regs *regs) 16 | { 17 | uint32_t function_id = regs->gpr[0]; 18 | 19 | switch (SMCCC_SERVICE(function_id)) { 20 | case SMCCC_SERVICE_ARCH: 21 | case SMCCC_SERVICE_CPU: 22 | case SMCCC_SERVICE_SIP: 23 | case SMCCC_SERVICE_OEM: 24 | case SMCCC_SERVICE_STANDARD: 25 | case SMCCC_SERVICE_HYPERVISOR: 26 | break; 27 | case SMCCC_SERVICE_TRUSTED_APP ... SMCCC_SERVICE_TRUSTED_APP_END: 28 | case SMCCC_SERVICE_TRUSTED_OS ... SMCCC_SERVICE_TRUSTED_OS_END: 29 | #ifdef CONFIG_OPTEE 30 | handle_optee_smc(regs); 31 | #endif 32 | break; 33 | default: 34 | handle_misc_arm_smccc(regs); 35 | } 36 | 37 | return 0; 38 | } 39 | 40 | static inline void handle_misc_arm_smccc(struct core_regs *regs) 41 | { 42 | uint32_t function_id = regs->gpr[0]; 43 | 44 | switch (function_id) { 45 | #ifdef CONFIG_ARM_PSCI 46 | case PSCI_FN_CPU_ON: 47 | regs->gpr[0] = emulate_psci_cpu_on(regs); 48 | break; 49 | #endif 50 | default: 51 | arm_smccc_smc(regs->gpr[0], regs->gpr[1], regs->gpr[2], regs->gpr[3], 52 | regs->gpr[4], regs->gpr[5], regs->gpr[6], regs->gpr[7], 53 | (struct arm_smccc_res *) regs->gpr); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /arch/arm/traps.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "cp15.h" 6 | 7 | // TODO(wonseok): If the traps cause the undefined exception or 8 | // abort exception, we must forward the exception to guest VM. 9 | #define INVALID_HSR -1 10 | 11 | int do_hyp_trap(struct core_regs *regs) 12 | { 13 | uint8_t pcpuid = smp_processor_id(); 14 | int ret = INVALID_HSR; 15 | uint32_t hsr = read_cp32(HSR); 16 | uint32_t ec = EC(hsr); 17 | uint32_t il = IL(hsr); 18 | uint32_t iss = ISS(hsr); 19 | 20 | switch (ec) { 21 | case EC_UNK: 22 | /* 23 | * if (HCR.TGE == 1) 24 | * handling undefined instruction 25 | * else 26 | * invalid_hsr; 27 | */ 28 | case EC_WFI_WFE: 29 | /* if (CV(iss) == 1) { 30 | * condition = COND(ISS); 31 | * } 32 | */ 33 | break; 34 | case EC_MCR_MRC_CP15: 35 | ret = emulate_cp15_32(regs, iss); 36 | break; 37 | case EC_MCRR_MRRC_CP15: 38 | ret = emulate_cp15_64(regs, iss); 39 | break; 40 | case EC_MCR_MRC_CP14: 41 | case EC_LDC_STC_CP14: 42 | case EC_HCRTR_CP0_CP13: 43 | case EC_MRC_VMRS_CP10: 44 | case EC_BXJ: 45 | case EC_MRRC_CP14: 46 | case EC_SVC: 47 | case EC_HVC: 48 | break; 49 | case EC_SMC: 50 | ret = handle_arm_smccc(regs); 51 | break; 52 | case EC_PABT_FROM_GUEST: 53 | case EC_PABT_FROM_HYP: 54 | break; 55 | case EC_DABT_FROM_GUEST: 56 | ret = handle_data_abort(regs, iss); 57 | break; 58 | case EC_DABT_FROM_HYP: 59 | break; 60 | default: 61 | break; 62 | } 63 | 64 | if (ret == INVALID_HSR) { 65 | goto trap_error; 66 | } 67 | 68 | if (il == IL_ARM) { 69 | regs->pc += 4; 70 | } else { 71 | regs->pc += 2; 72 | } 73 | 74 | return 0; 75 | 76 | trap_error: 77 | printf("CPU[%d] %s EC: 0x%x ISS: 0x%x\n", pcpuid, __func__, ec, iss); 78 | printf("r0 %x\n", regs->gpr[0]); 79 | printf("r1 %x\n", regs->gpr[1]); 80 | printf("r2 %x\n", regs->gpr[2]); 81 | printf("r3 %x\n", regs->gpr[3]); 82 | printf("guest pc is %x\n", regs->pc); 83 | printf("hifar %x\n", read_cp32(HIFAR)); 84 | while (1) ; 85 | 86 | return INVALID_HSR; 87 | } 88 | -------------------------------------------------------------------------------- /arch/arm/v7/Makefile: -------------------------------------------------------------------------------- 1 | objs-y := 2 | 3 | objs-y += head.o 4 | objs-y += context.o 5 | objs-y += mutex.o 6 | objs-y += vector.o 7 | objs-y += smccc.o 8 | 9 | obj-y += $(patsubst %, arch/arm/v7/%, ${objs-y}) 10 | -------------------------------------------------------------------------------- /arch/arm/v7/context.S: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | BEGIN_PROC(__set_vcpu_context_first_time) 4 | @ r0 = vcpu_regs->core_regs 5 | ldmfd r0!, {r1, r2, r3} 6 | msr spsr_hyp, r1 @ set spsr 7 | msr elr_hyp, r2 @ set return address 8 | @msr r2, r3 @ set return address 9 | ldm r0, {r0-r12} @ Currently, vcpu has no stack pointer. 10 | @ so, restoring r0-r12 is enough. 11 | clrex 12 | eret 13 | END_PROC(__set_vcpu_context_first_time) 14 | -------------------------------------------------------------------------------- /arch/arm/v7/mutex.S: -------------------------------------------------------------------------------- 1 | /* Refer to ARM Synchronization Primitives(DHT0008A) */ 2 | 3 | #ifdef CONFIG_SMP 4 | #define UNLOCKED 0xFFFFFFFF 5 | 6 | .global init_mutex 7 | init_mutex: 8 | mov r1, #UNLOCKED 9 | str r1, [r0] 10 | 11 | bx lr 12 | 13 | .global lock_mutex 14 | lock_mutex: 15 | @ is mutex locked? 16 | ldrex r1, [r0] 17 | cmp r1, #UNLOCKED 18 | 19 | wfene 20 | bne lock_mutex 21 | 22 | @ attempt to lock mutex 23 | mrc p15, 0, r1, c0, c0, 5 @ MPIDR (ARMv7 only) 24 | mov r2, #0x03 25 | orr r2, r2, #0x100 @ For cluster0/1 26 | and r1, r1, r2 27 | strex r2, r1, [r0] 28 | cmp r2, #0x0 29 | bne lock_mutex 30 | 31 | dmb 32 | 33 | bx lr 34 | 35 | .global unlock_mutex 36 | unlock_mutex: 37 | @ is this CPU owned the mutex? 38 | mrc p15, 0, r1, c0, c0, 5 @ MPIDR (ARMv7 only) 39 | mov r2, #0x03 40 | orr r2, r2, #0x100 @ For cluster0/1 41 | and r1, r1, r2 42 | ldr r2, [r0] 43 | cmp r1, r2 44 | movne r0, #0x1 45 | bxne lr 46 | 47 | @ unlock mutex 48 | dmb 49 | 50 | mov r1, #UNLOCKED 51 | str r1, [r0] 52 | 53 | dsb 54 | 55 | sev 56 | 57 | mov r0, #0x0 58 | bx lr 59 | 60 | .global is_mutex_locked 61 | is_mutex_locked: 62 | ldr r0, [r0] 63 | cmp r0, #UNLOCKED 64 | moveq r0, #0x0 65 | movne r0, #0x0 66 | bx lr 67 | 68 | #else // ifdef CONFIG_UP 69 | 70 | #define UNLOCKED 0 71 | #define LOCKED 1 72 | .global lock_mutex 73 | lock_mutex: 74 | ldr r1, =LOCKED 75 | 1: ldrex r2, [r0] 76 | cmp r2, r1 77 | beq 2f 78 | strexne r2, r1, [r0] 79 | cmpne r2, #1 80 | beq 1b 81 | # Lock acquired 82 | dmb 83 | bx lr 84 | 85 | 2: b 1b 86 | 87 | .global unlock_mutex 88 | unlock_mutex: 89 | ldr r1, =UNLOCKED 90 | dmb 91 | str r1, [r0] 92 | bx lr 93 | #endif 94 | -------------------------------------------------------------------------------- /arch/arm/v7/smccc.S: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | .syntax unified 4 | .arch_extension sec 5 | .arch_extension virt 6 | 7 | BEGIN_PROC(arm_smccc_smc) 8 | mov r12, sp 9 | push {r4-r7} 10 | ldm r12, {r4-r7} 11 | 12 | smc #0 13 | 14 | pop {r4-r7} 15 | ldr r12, [sp, #(4 * 4)] 16 | stm r12, {r0-r3} 17 | bx lr 18 | END_PROC(arm_smccc_smc) 19 | 20 | BEGIN_PROC(arm_smccc_hvc) 21 | mov r12, sp 22 | push {r4-r7} 23 | ldm r12, {r4-r7} 24 | 25 | hvc #0 26 | 27 | pop {r4-r7} 28 | ldr r12, [sp, #(4 * 4)] 29 | stm r12, {r0-r3} 30 | bx lr 31 | END_PROC(arm_smccc_hvc) 32 | -------------------------------------------------------------------------------- /arch/arm/v7/vector.S: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | .syntax unified 6 | .arch_extension sec 7 | .arch_extension virt 8 | 9 | BEGIN_PROC(__monitor_vector) 10 | .word 0 /* reset */ 11 | nop /* und */ 12 | b smc_handler /* smc */ 13 | nop /* pabt */ 14 | nop /* dabt */ 15 | b hvc_handler /* hvc */ 16 | nop /* irq */ 17 | nop /* fiq */ 18 | END_PROC(__monitor_vector) 19 | 20 | smc_handler: 21 | write_cp32(r0, MVBAR) 22 | 23 | // Configure SCR 24 | @ SCR.NS=1, IRQ,FIQ,EA=0, FW,AW=1, nET=0, SCD=1, HCE=1 25 | read_cp32(r1, SCR) 26 | bic r1, r1, #0x07f 27 | ldr r2, = 0x1b1 28 | orr r1, r1, r2 29 | write_cp32(r2, SCR) 30 | isb 31 | 32 | @ Reuse __monitor_vector to enter NSHyp mode temporarily. 33 | ldr r1, = __monitor_vector 34 | write_cp32(r1, HVBAR) 35 | movs pc, lr @ return in NS state 36 | 37 | hvc_handler: 38 | mrs lr, elr_hyp 39 | mov pc, lr 40 | 41 | .align 5 42 | BEGIN_PROC(__hvc_vector) 43 | .word 0 /* reset */ 44 | nop /* undef */ 45 | nop /* svc */ 46 | nop /* pabt */ 47 | nop /* dabt */ 48 | b __do_hvc /* hvc */ 49 | b __do_irq /* irq */ 50 | nop /* fiq */ 51 | END_PROC(__hvc_vector) 52 | 53 | __do_hvc: 54 | @ Push registers 55 | push {r0-r12} 56 | mrs r0, spsr_hyp 57 | mrs r1, elr_hyp 58 | push {r0, r1, lr} 59 | 60 | @ service other argument values -> _hyp_hvc_service(sp) 61 | mov r0, sp 62 | bl do_hyp_trap @ r0: HSR 63 | 64 | @ r0 = return 65 | tst r0, #1 66 | @ if return == HYP_RET_STAY -> stay in Hyp mode 67 | bne 1f 68 | 69 | @ Pop registers 70 | pop {r0-r1, lr} 71 | msr spsr_hyp, r0 72 | msr elr_hyp, r1 73 | pop {r0-r12} 74 | 75 | @ else if return == HYP_RET_ERET -> Exception Return 76 | eret 77 | 78 | 1: 79 | @ Pop registers 80 | pop {r0-r1, lr} 81 | tst r0, #0x1f 82 | msrne spsr_hyp, r0 83 | msr elr_hyp, r1 84 | pop {r0-r12} 85 | @ stay in Hyp mode 86 | mrs lr, elr_hyp 87 | mov pc, lr 88 | 89 | __do_irq: 90 | @ Push registers 91 | push {r0-r12} 92 | mrs r0, spsr_hyp 93 | mrs r1, elr_hyp 94 | push {r0, r1, lr} 95 | 96 | @ service other argument values -> trap_irq(sp) 97 | mov r0, sp 98 | bl do_irq @ r0: HSR 99 | 100 | @ Pop registers 101 | pop {r0-r1, lr} 102 | msr spsr_hyp, r0 103 | msr elr_hyp, r1 104 | pop {r0-r12} 105 | eret 106 | 107 | -------------------------------------------------------------------------------- /configs/bananapi_defconfig: -------------------------------------------------------------------------------- 1 | CONFIG_ARM=y 2 | CONFIG_ARCH_SUNXI=y 3 | CONFIG_CPU_A15=y 4 | 5 | CONFIG_ARM_PSCI=y 6 | CONFIG_ARM_PSCI_VERSION_0_1=y 7 | CONFIG_ARM_PSCI_FN_BASE=0x95c1ba5e 8 | 9 | CONFIG_SMP=y 10 | 11 | CONFIG_NS16550_SERIAL=y 12 | 13 | CONFIG_DEBUG=y 14 | 15 | CONFIG_VA_START=0x48000000 16 | -------------------------------------------------------------------------------- /configs/lager_defconfig: -------------------------------------------------------------------------------- 1 | CONFIG_ARM=y 2 | CONFIG_RMOBILE=y 3 | CONFIG_CPU_A15=y 4 | 5 | CONFIG_SMP=y 6 | 7 | CONFIG_SH_SERIAL=y 8 | 9 | CONIFG_DEBUG=y 10 | 11 | -------------------------------------------------------------------------------- /configs/odroidxu_defconfig: -------------------------------------------------------------------------------- 1 | CONFIG_ARM=y 2 | CONFIG_ARCH_EXYNOS=y 3 | CONFIG_CPU_A15=y 4 | 5 | CONFIG_MCT=y 6 | CONFIG_S5P_SERIAL=y 7 | 8 | CONFIG_DEBUG=y 9 | 10 | CONFIG_SMP=y 11 | -------------------------------------------------------------------------------- /configs/rtsm_defconfig: -------------------------------------------------------------------------------- 1 | CONFIG_ARM=y 2 | CONFIG_ARCH_VERSATILE=y 3 | CONFIG_CPU_A15=y 4 | 5 | CONFIG_SMP=y 6 | CONFIG_ATAGS=y 7 | 8 | CONFIG_PL01X_SERIAL=y 9 | CONFIG_VDEV_SAMPLE=y 10 | CONFIG_VDEV_SP804=y 11 | CONFIG_VDEV_SYSREG=y 12 | CONFIG_VDEV_PL01X_SERIAL=y 13 | 14 | CONFIG_DEBUG=y 15 | 16 | CONFIG_VA_START=0x80000000 17 | -------------------------------------------------------------------------------- /core/Kconfig: -------------------------------------------------------------------------------- 1 | menu "CORE" 2 | config SMP 3 | bool "Set SMP" 4 | 5 | config ATAGS 6 | bool "Set ATAGS" 7 | 8 | endmenu 9 | -------------------------------------------------------------------------------- /core/Makefile: -------------------------------------------------------------------------------- 1 | include ${SOURCE_PATH}/core/sched/Makefile 2 | include ${SOURCE_PATH}/core/vm/Makefile 3 | 4 | objs-y := 5 | 6 | objs-y += main.o 7 | objs-y += vdev.o 8 | objs-y += timer.o 9 | objs-y += vm_config.o 10 | objs-y += kmus.o 11 | 12 | SUBDIRECTORIES += core/sched core/vm 13 | 14 | obj-y += $(patsubst %, core/%, ${objs-y}) 15 | -------------------------------------------------------------------------------- /core/kmus.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | static inline unsigned __get_cpsr(void) 7 | { 8 | unsigned long retval; 9 | asm volatile (" mrs %0, cpsr" : "=r" (retval) : ); 10 | return retval; 11 | } 12 | 13 | static inline void __set_cpsr(unsigned val) 14 | { 15 | asm volatile (" msr cpsr, %0": :"r" (val)); 16 | } 17 | 18 | void kmus_snapshot(vmid_t normal_id, vmid_t kmus_id, struct core_regs *regs) 19 | { 20 | printf("%s start\n", __func__); 21 | 22 | int i, j; 23 | struct vcpu *vcpu = NULL; 24 | struct vmcb *vm = vm_find(normal_id); 25 | 26 | for (i = 0; i < vm->num_vcpus; i++) { 27 | vcpu = vm->vcpu[i]; 28 | arch_regs_save(&vcpu->regs, regs); 29 | 30 | for (j = 0; j < GICv2.num_lr; j++) 31 | vcpu->lr[j] = GICH_READ(GICH_LR(j)); 32 | 33 | vcpu->vmcr = GICH_READ(GICH_VMCR); 34 | } 35 | vm_copy(normal_id, kmus_id, regs); 36 | 37 | printf("%s end\n", __func__); 38 | } 39 | 40 | void kmus_start(vmid_t normal_id, vmid_t kmus_id, struct core_regs *regs) 41 | { 42 | printf("%s start\n", __func__); 43 | unsigned long cpsr; 44 | 45 | // stop the VM (unregister from scheduler) 46 | vm_suspend(normal_id, regs); 47 | 48 | // change the type of back-up VM 49 | struct vmcb *vm = vm_find(kmus_id); 50 | vm->vcpu[0]->type = VCPU_NORMAL; 51 | 52 | // start the VM (register VM to scheduler) 53 | vm_start(kmus_id); 54 | 55 | // delete the VM struct (free the memory) 56 | vm_delete(normal_id); 57 | 58 | // enable irq for waiting next tick 59 | cpsr = __get_cpsr(); 60 | cpsr &= (~CPSR_BIT(I)); 61 | __set_cpsr(cpsr); 62 | 63 | printf("%s end\n", __func__); 64 | 65 | while(1); 66 | // Shoule be never reach here 67 | 68 | return; 69 | } 70 | -------------------------------------------------------------------------------- /core/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | extern struct vm_config vm_conf[]; 10 | 11 | static uint32_t smp_pen = 0; 12 | 13 | void start_hypervisor() 14 | { 15 | int i; 16 | 17 | uint32_t pcpu = smp_processor_id(); 18 | 19 | if (pcpu == 0) { 20 | timemanager_init(); 21 | sched_init(); 22 | 23 | vm_setup(); 24 | 25 | for (i = 0; i < CONFIG_NR_VMS; i++) { 26 | vmid_t vmid; 27 | 28 | if ((vmid = vm_create(vm_conf[i].nr_vcpus, vm_conf[i].vmcb_type)) == VM_CREATE_FAILED) { 29 | printf("vm_create(vm[%d]) is failed\n", i); 30 | goto error; 31 | } 32 | if (vm_init(vmid) != HALTED) { 33 | printf("vm_init(vm[%d]) is failed\n", i); 34 | goto error; 35 | } 36 | if (vm_start(vmid) != RUNNING) { 37 | printf("vm_start(vm[%d]) is failed\n", i); 38 | goto error; 39 | } 40 | } 41 | 42 | smp_pen = 1; 43 | } else { 44 | while (!smp_pen) ; 45 | printf("cpu[%d] is enabled\n", pcpu); 46 | } 47 | 48 | #ifdef CONFIG_TIMER_ACCESS_TRAP 49 | /* FIXME:(igkang) WORKAROUND - enable timer access trap */ 50 | uint32_t val; 51 | val = read_cp32(CNTHCTL); 52 | write_cp32(val & ~(ARM_CNTHCTL_PL1PCEN | ARM_CNTHCTL_PL1PCTEN), CNTHCTL); 53 | #endif 54 | 55 | /* 56 | * TODO: Add a function - return vmid or vcpu_id to execute for the first time. 57 | * TODO: Rename guest_sched_start to do_schedule or something others. 58 | * do_schedule(vmid) or do_schedule(vcpu_id) 59 | */ 60 | printf("sched_start!!!\n"); 61 | sched_start(); 62 | 63 | /* The code flow must not reach here */ 64 | error: 65 | printf("-------- [%s] ERROR: K-Hypervisor must not reach here\n", __func__); 66 | abort(); 67 | } 68 | -------------------------------------------------------------------------------- /core/sched/Makefile: -------------------------------------------------------------------------------- 1 | objs-y := 2 | 3 | objs-y += scheduler.o 4 | objs-y += sched-config.o 5 | 6 | objs-y += rr.o 7 | objs-y += rt-rm.o 8 | objs-y += rt-edf.o 9 | 10 | obj-y += $(patsubst %, core/sched/%, ${objs-y}) 11 | -------------------------------------------------------------------------------- /core/sched/sched-config.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* Description notation: 5 | * 6 | * what array index meaning -> array element meaning 7 | * in short, 8 | * index -> element 9 | * 10 | * use ZERO for UNUSED config datas 11 | */ 12 | 13 | /***** 14 | * Global configs for scheduler 15 | */ 16 | 17 | /* pcpu -> policy */ 18 | const struct sched_policy *schedconf_g_policy[] = { 19 | &sched_rr, 20 | &sched_rr, 21 | &sched_rr, 22 | &sched_rr 23 | }; 24 | 25 | /* vcpu -> pcpu to be maped to */ 26 | uint32_t schedconf_g_vcpu_to_pcpu_map[TOTAL_VCPUS] = { 27 | 0, 28 | 1, 29 | 2, 30 | 3, 31 | }; 32 | 33 | /***** 34 | * Round Robin policy configs 35 | */ 36 | 37 | /* vcpu -> {budget} in ms */ 38 | uint32_t schedconf_rr_slice[TOTAL_VCPUS] = { 39 | 5, 40 | 5, 41 | 5, 42 | 5 43 | }; 44 | 45 | /***** 46 | * Rate Monotonic policy configs 47 | */ 48 | 49 | /* pcpu(=policy) -> scheduler tick interval (microsecond) */ 50 | uint32_t schedconf_rm_tick_interval_us[NR_CPUS] = { 51 | 0, 52 | }; 53 | 54 | /* vcpu -> {period, budget} in tick count */ 55 | uint32_t schedconf_rm_period_budget[TOTAL_VCPUS][2] = { 56 | {0, }, 57 | }; 58 | 59 | /***** 60 | * Earlist Deadline First policy configs 61 | */ 62 | 63 | /* pcpu(=policy) -> scheduler tick interval (microsecond) */ 64 | uint32_t schedconf_edf_tick_interval_us[NR_CPUS] = { 65 | 0, 66 | }; 67 | 68 | /* vcpu -> {period, budget} in tick count */ 69 | uint32_t schedconf_edf_period_budget[TOTAL_VCPUS][2] = { 70 | {0, }, 71 | }; 72 | 73 | -------------------------------------------------------------------------------- /core/vdev.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define MAX_VDEV 256 10 | 11 | static struct list_head vdev_list; 12 | 13 | void vdev_handler(struct core_regs *regs, uint32_t iss) 14 | { 15 | struct vmcb *vm = get_current_vm(); 16 | uint32_t fipa = 0; 17 | uint8_t wnr = WNR(iss); 18 | uint8_t srt = SRT(iss); 19 | 20 | fipa = read_cp32(HPFAR) << IPA_SHIFT; 21 | fipa |= (read_cp32(HDFAR) & PAGE_OFFSET_MASK); 22 | 23 | struct vdev_instance *instance; 24 | list_for_each_entry(struct vdev_instance, instance, &vm->vdevs.head, head) { 25 | uint32_t vdev_base = instance->module->base; 26 | uint32_t vdev_size = instance->module->size; 27 | 28 | if (vdev_base <= fipa && fipa < vdev_base + vdev_size) { 29 | uint32_t offset = fipa - vdev_base; 30 | if (wnr) { 31 | instance->module->write(instance->pdata, offset, &(regs->gpr[srt])); 32 | } else { 33 | regs->gpr[srt] = instance->module->read(instance->pdata, offset); 34 | } 35 | 36 | break; 37 | } 38 | } 39 | } 40 | void vdev_register(struct vdev_module *module) 41 | { 42 | if (module == NULL) { 43 | printf("Failed register vdev %s\n", module->name); 44 | return; 45 | } 46 | 47 | LIST_ADDTAIL(&module->head, &vdev_list); 48 | } 49 | 50 | void vdev_create(struct vdev_instance *vdevs, vmid_t vmid) 51 | { 52 | LIST_INITHEAD(&vdevs->head); 53 | 54 | struct vdev_module *module; 55 | list_for_each_entry(struct vdev_module, module, &vdev_list, head) { 56 | struct vdev_instance *vdev = malloc(sizeof(struct vdev_instance)); 57 | 58 | vdev->owner = vmid; 59 | vdev->module = module; 60 | vdev->module->create(&vdev->pdata); 61 | 62 | LIST_ADDTAIL(&vdev->head, &vdevs->head); 63 | } 64 | } 65 | 66 | void vdev_delete(struct vdev_instance *vdevs) 67 | { 68 | LIST_DEL(&vdevs->head); 69 | } 70 | 71 | static uint32_t vdev_module_initcall(initcall_t fn) 72 | { 73 | return fn(); 74 | } 75 | 76 | #include 77 | void SECTION(".init.vdev") vdev_init(void) 78 | { 79 | LIST_INITHEAD(&vdev_list); 80 | 81 | initcall_t *fn; 82 | for (fn = __vdev_module_start; fn < __vdev_module_end; fn++) { 83 | vdev_module_initcall(*fn); 84 | } 85 | } 86 | 87 | void vdev_copy(struct vdev_instance *vdev_from, struct vdev_instance *vdev_to) 88 | { 89 | struct vdev_instance *from_instance; 90 | struct vdev_instance *to_instance; 91 | 92 | list_for_each_entry(struct vdev_instance, from_instance, &vdev_from->head, head) { 93 | list_for_each_entry(struct vdev_instance, to_instance, &vdev_to->head, head) { 94 | if (from_instance->module->base == to_instance->module->base) { 95 | printf("kmus [%s] vdev copy\n", from_instance->module->name); 96 | if (from_instance->module->copy) 97 | from_instance->module->copy(&from_instance->pdata, &to_instance->pdata); 98 | break; 99 | } 100 | } 101 | } 102 | } 103 | 104 | -------------------------------------------------------------------------------- /core/vm/Makefile: -------------------------------------------------------------------------------- 1 | objs-y := 2 | 3 | objs-y += atags.o 4 | objs-y += context_switch.o 5 | objs-y += vcpu.o 6 | objs-y += virq_map.o 7 | objs-y += vm.o 8 | objs-y += vmem.o 9 | 10 | obj-y += $(patsubst %, core/vm/%, ${objs-y}) 11 | -------------------------------------------------------------------------------- /core/vm/context_switch.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | hvmm_status_t do_context_switch(vcpuid_t current_id, vcpuid_t next_id, struct core_regs *current_regs) 8 | { 9 | struct vcpu *current = vcpu_find(current_id); 10 | struct vcpu *next = vcpu_find(next_id); 11 | 12 | if (current_id == VCPUID_INVALID) { 13 | vm_restore(next->vmid); 14 | vcpu_restore(next, current_regs); 15 | 16 | return HVMM_STATUS_SUCCESS; 17 | } 18 | 19 | vcpu_save(current, current_regs); 20 | if (current->vmid != next->vmid) { 21 | vm_save(current->vmid); 22 | // TODO(casionwoo) : vm_save, vm_restore two functions will be merged later. 23 | vm_restore(next->vmid); 24 | } 25 | vcpu_restore(next, current_regs); 26 | return HVMM_STATUS_SUCCESS; 27 | } 28 | -------------------------------------------------------------------------------- /core/vm/virq_map.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | uint32_t virq_to_pirq(struct vcpu *v, uint32_t virq) 9 | { 10 | return v->map[virq].pirq; 11 | } 12 | 13 | uint32_t pirq_to_virq(struct vcpu *v, uint32_t pirq) 14 | { 15 | return v->map[pirq].virq; 16 | } 17 | 18 | void virq_enable(struct vcpu *v, uint32_t pirq, uint32_t virq) 19 | { 20 | v->map[virq].pirq = pirq; 21 | v->map[virq].enabled = GUEST_IRQ_ENABLE; 22 | } 23 | 24 | void virq_disable(struct vcpu *v, uint32_t virq) 25 | { 26 | v->map[virq].enabled = GUEST_IRQ_DISABLE; 27 | } 28 | 29 | void pirq_enable(struct vcpu *v, uint32_t pirq, uint32_t virq) 30 | { 31 | v->map[pirq].virq = virq; 32 | v->map[pirq].enabled = GUEST_IRQ_ENABLE; 33 | } 34 | 35 | void pirq_disable(struct vcpu *v, uint32_t pirq) 36 | { 37 | v->map[pirq].enabled = GUEST_IRQ_DISABLE; 38 | } 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | static irqreturn_t is_guest_sgi(int irq, void *pregs, void *pdata) 48 | { 49 | printf("SGI[%d] is not handled in khypervisor\n", irq); 50 | return VM_IRQ; 51 | } 52 | 53 | static irqreturn_t is_guest_ppi(int irq, void *pregs, void *pdata) 54 | { 55 | struct vcpu *vcpu; 56 | uint32_t virq; 57 | uint32_t pcpu = smp_processor_id(); 58 | struct sched_entry *rve; 59 | struct list_head *rvs_list = &sched[pcpu]->inflight_entries; 60 | 61 | list_for_each_entry(struct sched_entry, rve, rvs_list, head_inflight) { 62 | vcpu = vcpu_find(rve->vcpuid); 63 | virq = pirq_to_virq(vcpu, irq); 64 | 65 | if (virq == VIRQ_INVALID) { 66 | continue; 67 | } 68 | 69 | virq_hw->forward_irq(vcpu, virq, irq, INJECT_SW); 70 | } 71 | 72 | return VM_IRQ; 73 | } 74 | 75 | static irqreturn_t is_guest_spi(int irq, void *pregs, void *pdata) 76 | { 77 | struct vcpu *vcpu; 78 | struct vmcb *vm; 79 | uint32_t virq; 80 | struct list_head *vm_list = get_all_vms(); 81 | 82 | list_for_each_entry(struct vmcb, vm, vm_list, head) { 83 | vcpu = vm->vcpu[0]; 84 | virq = pirq_to_virq(vcpu, irq); 85 | 86 | if (virq == VIRQ_INVALID || vm->state != RUNNING) { 87 | continue; 88 | } 89 | 90 | virq_hw->forward_irq(vcpu, virq, irq, INJECT_SW); 91 | } 92 | 93 | return VM_IRQ; 94 | } 95 | 96 | void irq_handler_init(irq_handler_t *handler) 97 | { 98 | int i; 99 | 100 | for (i = 0; i < 16; i++) { 101 | if (handler[i]) { 102 | continue; 103 | } 104 | handler[i] = is_guest_sgi; 105 | } 106 | 107 | for (i = 16; i < 32; i++) { 108 | if (handler[i]) { 109 | continue; 110 | } 111 | handler[i] = is_guest_ppi; 112 | } 113 | 114 | for (i = 32; i < 1025; i++) { 115 | if (handler[i]) { 116 | continue; 117 | } 118 | handler[i] = is_guest_spi; 119 | } 120 | } 121 | 122 | -------------------------------------------------------------------------------- /core/vm/vmem.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "../../arch/arm/paging.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | extern uint32_t __VM_PGTABLE; 12 | 13 | #define PGTABLE_SIZE 0x805000 14 | 15 | #define VTTBR_VMID_MASK 0x00FF000000000000ULL 16 | #define VTTBR_VMID_SHIFT 48 17 | #define VTTBR_BADDR_MASK 0x000000FFFFFFFFFFULL 18 | 19 | extern struct vm_config vm_conf[]; 20 | extern struct Queue trans_queue; 21 | 22 | void vmem_create(struct vmem *vmem, vmid_t vmid) 23 | { 24 | vmem->base = (uint32_t) &__VM_PGTABLE + (PGTABLE_SIZE * vmid); 25 | paging_create(vmem->base); 26 | 27 | vmem->vttbr = ((uint64_t) vmid << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK; 28 | vmem->vttbr &= ~(VTTBR_BADDR_MASK); 29 | vmem->vttbr |= (uint32_t) vmem->base & VTTBR_BADDR_MASK; 30 | 31 | vmem->mmap = vm_mmap[vmid]; 32 | 33 | vmem->dram.pa = vm_conf[vmid].pa_start; 34 | vmem->dram.ipa = CONFIG_VA_START; 35 | vmem->dram.size = vm_conf[vmid].va_offsets; 36 | } 37 | 38 | hvmm_status_t vmem_init(struct vmem *vmem, vmid_t vmid) 39 | { 40 | int j = 0; 41 | 42 | while (vmem->mmap[j].label != 0) { 43 | paging_add_ipa_mapping(vmem->base, vmem->mmap[j].ipa, vmem->mmap[j].pa, vmem->mmap[j].attr, vmem->mmap[j].af, 44 | vmem->mmap[j].size); 45 | j++; 46 | } 47 | 48 | #ifdef CONFIG_OPTEE 49 | // for now, we need to make ipa equal to pa to support op-tee 50 | paging_add_ipa_mapping(vmem->base, vm_conf[vmid].pa_start, vm_conf[vmid].pa_start, MEMATTR_NORMAL_WB_CACHEABLE, 1, 51 | vm_conf[vmid].va_offsets); 52 | #else 53 | paging_add_ipa_mapping(vmem->base, vmem->dram.ipa, vmem->dram.pa, MEMATTR_NORMAL_WB_CACHEABLE, 1, 54 | vmem->dram.size); 55 | #endif 56 | 57 | vmem->actlr = read_cp32(ACTLR); 58 | 59 | if (vm_conf[vmid].nr_vcpus > 1) { 60 | vmem->actlr |= (1 << 6); 61 | } 62 | 63 | vmem->vtcr = (VTCR_SL0_FIRST_LEVEL << VTCR_SL0_BIT); 64 | vmem->vtcr |= (WRITEBACK_CACHEABLE << VTCR_ORGN0_BIT); 65 | vmem->vtcr |= (WRITEBACK_CACHEABLE << VTCR_IRGN0_BIT); 66 | write_cp32(vmem->vtcr, VTCR); 67 | 68 | return HVMM_STATUS_SUCCESS; 69 | } 70 | 71 | hvmm_status_t vmem_save(void) 72 | { 73 | uint32_t hcr = 0; 74 | hcr = read_cp32(HCR); 75 | write_cp32((hcr & ~HCR_BIT(VM)), HCR); 76 | 77 | return HVMM_STATUS_SUCCESS; 78 | } 79 | 80 | hvmm_status_t vmem_restore(struct vmem *vmem) 81 | { 82 | uint32_t hcr = 0; 83 | 84 | write_cp32(vmem->vtcr, VTCR); 85 | write_cp32(vmem->actlr, ACTLR); 86 | write_cp64(vmem->vttbr, VTTBR); 87 | 88 | hcr = read_cp32(HCR); 89 | write_cp32((hcr | HCR_BIT(VM)), HCR); 90 | 91 | return HVMM_STATUS_SUCCESS; 92 | } 93 | 94 | #include 95 | #include 96 | void vmem_copy(struct vmem *from, struct vmem *to) 97 | { 98 | to->vtcr = from->vtcr; 99 | to->actlr = from->actlr; 100 | 101 | // copy all of the physical memory 102 | uint32_t from_mem = from->dram.pa; 103 | uint32_t to_mem = to->dram.pa; 104 | InitQueue(&trans_queue); 105 | 106 | chain_enqueue((uint32_t)from_mem, (uint32_t)to_mem, from->dram.size); 107 | dma_wait *value = (dma_wait*) malloc (sizeof(dma_wait)); 108 | *value = Dequeue(&trans_queue); 109 | 110 | dma_transfer(0, (uint32_t)value->src_addr, (uint32_t)value->dst_addr, SZ_4K); 111 | printf("%s end\n", __func__); 112 | } 113 | -------------------------------------------------------------------------------- /core/vm_config.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct vm_config vm_conf[] = { 6 | { 1, SZ_256M, CFG_MEMMAP_GUEST0_ATAGS_OFFSET, VM_NORMAL }, 7 | { 1, SZ_256M, CFG_MEMMAP_GUEST0_ATAGS_OFFSET + SZ_256M, VM_KMUS } 8 | }; 9 | -------------------------------------------------------------------------------- /drivers/Kconfig: -------------------------------------------------------------------------------- 1 | source "drivers/serial/Kconfig" 2 | source "drivers/vdev/Kconfig" 3 | 4 | menu "Device Drivers" 5 | 6 | config MCT 7 | bool 8 | 9 | menuconfig DMA_ENGINE 10 | bool "DMA Engine support" 11 | 12 | if DMA_ENGINE 13 | 14 | config SUN4I_DMA 15 | bool "Support for sun4i DMA controller" 16 | depends on ARCH_SUNXI 17 | default ARCH_SUNXI 18 | 19 | endif 20 | 21 | endmenu 22 | -------------------------------------------------------------------------------- /drivers/Makefile: -------------------------------------------------------------------------------- 1 | include ${SOURCE_PATH}/drivers/vdev/Makefile 2 | include ${SOURCE_PATH}/drivers/serial/Makefile 3 | include ${SOURCE_PATH}/drivers/dma/Makefile 4 | 5 | objs-y := 6 | 7 | SUBDIRECTORIES += drivers/vdev 8 | SUBDIRECTORIES += drivers/dma 9 | SUBDIRECTORIES += drivers/serial 10 | 11 | objs-y += generic_timer.o 12 | objs-y += gic-v2.o 13 | objs-$(CONFIG_MCT) += mct.o 14 | 15 | obj-y += $(patsubst %, drivers/%, ${objs-y}) 16 | -------------------------------------------------------------------------------- /drivers/dma/Makefile: -------------------------------------------------------------------------------- 1 | objs-y := 2 | 3 | objs-$(CONFIG_SUN4I_DMA) += sun4i-dma.o 4 | 5 | obj-y += $(patsubst %, drivers/dma/%, ${objs-y}) 6 | -------------------------------------------------------------------------------- /drivers/mct.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "../include/arch/v7/local_irq.h" 5 | 6 | static inline uint32_t mct_read(uint32_t offset) 7 | { 8 | return readl((void *) EXYNOS5_MCT_BASE + offset); 9 | } 10 | 11 | static void mct_write(uint32_t value, uint32_t offset) 12 | { 13 | uint32_t addr; 14 | uint32_t mask; 15 | 16 | writel(value, (EXYNOS5_MCT_BASE + offset)); 17 | switch (offset) { 18 | case EXYNOS5_MCT_G_TCON: 19 | addr = EXYNOS5_MCT_G_WSTAT; 20 | mask = 1 << 16; /* G_TCON write status */ 21 | break; 22 | case EXYNOS5_MCT_G_CNT_L: 23 | addr = EXYNOS5_MCT_G_CNT_WSTAT; 24 | mask = 1 << 0; /* G_CNT_L write status */ 25 | break; 26 | case EXYNOS5_MCT_G_CNT_U: 27 | addr = EXYNOS5_MCT_G_CNT_WSTAT; 28 | mask = 1 << 1; /* G_CNT_U write status */ 29 | break; 30 | default: 31 | return; 32 | } 33 | writel(mask, EXYNOS5_MCT_BASE + addr); 34 | } 35 | 36 | void mct_init(void) 37 | { 38 | uint32_t reg; 39 | 40 | mct_write(0, EXYNOS5_MCT_G_CNT_L); 41 | mct_write(0, EXYNOS5_MCT_G_CNT_U); 42 | reg = mct_read(EXYNOS5_MCT_G_TCON); 43 | reg |= MCT_G_TCON_START; 44 | mct_write(reg, EXYNOS5_MCT_G_TCON); 45 | } 46 | -------------------------------------------------------------------------------- /drivers/serial/Kconfig: -------------------------------------------------------------------------------- 1 | config PL01X_SERIAL 2 | bool 3 | 4 | config SH_SERIAL 5 | bool 6 | 7 | config S5P_SERIAL 8 | bool 9 | 10 | config NS16550_SERIAL 11 | bool 12 | -------------------------------------------------------------------------------- /drivers/serial/Makefile: -------------------------------------------------------------------------------- 1 | objs-y := 2 | 3 | objs-$(CONFIG_PL01X_SERIAL) += serial_pl01x.o 4 | objs-$(CONFIG_SH_SERIAL) += serial_sh.o 5 | objs-$(CONFIG_S5P_SERIAL) += serial_s5p.o 6 | objs-$(CONFIG_NS16550_SERIAL) += serial_ns16550.o 7 | 8 | obj-y += $(patsubst %, drivers/serial/%, ${objs-y}) 9 | -------------------------------------------------------------------------------- /drivers/serial/serial_ns16550.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void serial_init() 5 | { 6 | while (!(readb(NS16550_BASE + NS16550_LSR) & UART_LSR_TEMT)) 7 | ; 8 | 9 | writeb(0x0, NS16550_BASE + NS16550_IER); 10 | writeb(0x3, NS16550_BASE + NS16550_MCR); 11 | writeb(0x7, NS16550_BASE + NS16550_FCR); 12 | } 13 | 14 | void ns16550_putc(const char c) 15 | { 16 | while (!(readb(NS16550_BASE + NS16550_LSR) & UART_LSR_THRE)) 17 | ; 18 | 19 | writeb(c, NS16550_BASE + NS16550_THR); 20 | } 21 | 22 | int serial_putc(const char c) 23 | { 24 | if (c == '\n') { 25 | ns16550_putc('\r'); 26 | } 27 | 28 | ns16550_putc(c); 29 | 30 | return 0; 31 | } 32 | 33 | int serial_getc() 34 | { 35 | while (!(readb(NS16550_BASE + NS16550_LSR) & UART_LSR_DR)) 36 | ; 37 | 38 | return readb(NS16550_BASE + NS16550_RBR); 39 | } 40 | -------------------------------------------------------------------------------- /drivers/serial/serial_s5p.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int serial_init(void) 5 | { 6 | writel(0x117, S5P_BASE + S5P_UFCON); 7 | writel(0, S5P_BASE + S5P_UMCON); 8 | writel(0x3, S5P_BASE + S5P_ULCON); 9 | writel(0x3C5, S5P_BASE + S5P_UCON); 10 | 11 | return 0; 12 | } 13 | 14 | static int read_err_check(void) 15 | { 16 | return readl(S5P_BASE + S5P_UERSTAT) & 0xf; 17 | } 18 | 19 | static int write_err_check(void) 20 | { 21 | return readl(S5P_BASE + S5P_UERSTAT) & 0x8; 22 | } 23 | 24 | int serial_getc(void) 25 | { 26 | while (!(readl(S5P_BASE + S5P_UTRSTAT) & 0x1)) { 27 | if (read_err_check()) { 28 | return 0; 29 | } 30 | } 31 | 32 | return readb(S5P_BASE + S5P_URXH) & 0xFF; 33 | } 34 | 35 | int serial_putc(const char c) 36 | { 37 | while (!(readl(S5P_BASE + S5P_UTRSTAT) & 0x2)) { 38 | if (write_err_check()) { 39 | return -1; 40 | } 41 | } 42 | writeb(c, S5P_BASE + S5P_UTXH); 43 | 44 | if (c == '\n') { 45 | serial_putc('\r'); 46 | } 47 | return c; 48 | } 49 | 50 | -------------------------------------------------------------------------------- /drivers/serial/serial_sh.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../../include/arch/v7/local_irq.h" 4 | 5 | int serial_init(void) 6 | { 7 | writew((SCSCR_TE_ENABLE | SCSCR_RE_ENABLE | SCSCR_CKE1_ENABLE), SCIF_BASE + SCSCR); 8 | writew(0, SCIF_BASE + SCSMR); 9 | writew(SCFCR_RFRST_ENABLE | SCFCR_TFRST_ENABLE, SCIF_BASE + SCFCR); 10 | 11 | readw(SCIF_BASE + SCFCR); 12 | 13 | writew(0, SCIF_BASE + SCFCR); 14 | 15 | return 0; 16 | } 17 | 18 | static void handle_error(void) 19 | { 20 | writew((SCFSR_ER_ENABLE | SCFSR_TEND_ENABLE | SCFSR_TDFE_ENABLE | SCFSR_BRK_ENABLE), SCIF_BASE + SCFSR); 21 | writew(0x00, SCIF_BASE + SCLSR); 22 | } 23 | 24 | static void serial_raw_putc(const char c) 25 | { 26 | while (1) { 27 | if (readw(SCIF_BASE + SCFSR) & SCFSR_TEND) { 28 | break; 29 | } 30 | } 31 | 32 | writeb(c, SCIF_BASE + SCFTDR); 33 | writew(readw(SCIF_BASE + SCFSR) & ~SCFSR_TEND, SCIF_BASE + SCFSR); 34 | } 35 | 36 | int serial_putc(const char c) 37 | { 38 | if (c == '\n') { 39 | serial_raw_putc('\r'); 40 | } 41 | serial_raw_putc(c); 42 | return c; 43 | } 44 | 45 | 46 | static int serial_getc_check(void) 47 | { 48 | unsigned short status; 49 | 50 | status = readw(SCIF_BASE + SCFSR); 51 | 52 | if (status & (SCFSR_PER | SCFSR_FER | SCFSR_ER | SCFSR_BRK)) { 53 | handle_error(); 54 | } 55 | if (readw(SCIF_BASE + SCLSR) & SCLSR_ORER) { 56 | handle_error(); 57 | } 58 | return status & (SCFSR_DR | SCFSR_RDF); 59 | } 60 | 61 | int serial_getc(void) 62 | { 63 | unsigned short status; 64 | char ch; 65 | 66 | while (!serial_getc_check()) { 67 | ; 68 | } 69 | 70 | ch = readb(SCIF_BASE + SCFRDR); 71 | status = readw(SCIF_BASE + SCFSR); 72 | 73 | writew((SCFSR_ER_ENABLE | SCFSR_TEND_ENABLE | SCFSR_TDFE_ENABLE | SCFSR_BRK_ENABLE), SCIF_BASE + SCFSR); 74 | 75 | if (status & (SCFSR_PER | SCFSR_FER | SCFSR_ER | SCFSR_BRK)) { 76 | handle_error(); 77 | } 78 | if (readw(SCIF_BASE + SCLSR) & SCLSR_ORER) { 79 | handle_error(); 80 | } 81 | return ch; 82 | } 83 | 84 | -------------------------------------------------------------------------------- /drivers/sp804.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | //#include 5 | #include 6 | 7 | static uint64_t tickcount = 0; 8 | 9 | void sp804_handler(int irq, void *pregs, void *pdata) 10 | { 11 | #if 0 12 | printf("SP804 IRQ[%d]: T1 %x, T2: %x\n", irq, readl(TIMER1_VALUE(TIMER1_BASE)), 13 | readl(TIMER2_VALUE(TIMER1_BASE))); 14 | #endif 15 | tickcount++; 16 | //printf("tickcount: %d\n", tickcount); 17 | 18 | writel(0x1, TIMER1_INTCLR(TIMER1_BASE)); 19 | } 20 | 21 | void sp804_init() 22 | { 23 | writel(0x10, TIMER1_LOAD(TIMER1_BASE)); 24 | } 25 | 26 | void sp804_enable() 27 | { 28 | sp804_init(); 29 | writel(0xE2, TIMER1_CONTROL(TIMER1_BASE)); 30 | 31 | register_irq_handler(34, &sp804_handler); 32 | } 33 | -------------------------------------------------------------------------------- /drivers/vdev/Kconfig: -------------------------------------------------------------------------------- 1 | config VDEV_SAMPLE 2 | bool 3 | 4 | config VDEV_SP804 5 | bool 6 | 7 | config VDEV_SYSREG 8 | bool 9 | 10 | config VDEV_PL01X_SERIAL 11 | bool 12 | -------------------------------------------------------------------------------- /drivers/vdev/Makefile: -------------------------------------------------------------------------------- 1 | objs-y := 2 | 3 | objs-y += vdev_gicd.o 4 | objs-y += vdev_timer.o 5 | objs-$(CONFIG_VDEV_SAMPLE) += vdev_sample.o 6 | objs-$(CONFIG_VDEV_SP804) += vdev_sp804.o 7 | objs-$(CONFIG_VDEV_SYSREG) += vdev_sysreg.o 8 | objs-$(CONFIG_VDEV_PL01X_SERIAL) += vdev_pl01x.o 9 | 10 | obj-y += $(patsubst %, drivers/vdev/%, ${objs-y}) 11 | 12 | -------------------------------------------------------------------------------- /drivers/vdev/vdev_hvc_ping.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define DEBUG 3 | #include 4 | 5 | static int32_t vdev_hvc_ping_write(struct arch_vdev_trigger_info *info) 6 | { 7 | printf("[hyp] _hyp_hvc_service:ping\n\r"); 8 | return 0; 9 | } 10 | 11 | static int32_t vdev_hvc_ping_check(struct arch_vdev_trigger_info *info) 12 | { 13 | if ((info->iss & 0xFFFF) == 0xFFFE) { 14 | return 0; 15 | } 16 | 17 | return VDEV_NOT_FOUND; 18 | } 19 | 20 | static hvmm_status_t vdev_hvc_ping_reset(void) 21 | { 22 | return HVMM_STATUS_SUCCESS; 23 | } 24 | 25 | struct vdev_ops _vdev_hvc_ping_ops = { 26 | .init = vdev_hvc_ping_reset, 27 | .check = vdev_hvc_ping_check, 28 | .write = vdev_hvc_ping_write, 29 | }; 30 | 31 | struct vdev_module _vdev_hvc_ping_module = { 32 | .name = "K-Hypervisor vDevice HVC Ping Module", 33 | .author = "Kookmin Univ.", 34 | .ops = &_vdev_hvc_ping_ops, 35 | }; 36 | 37 | hvmm_status_t vdev_hvc_ping_init() 38 | { 39 | hvmm_status_t result = HVMM_STATUS_BUSY; 40 | 41 | result = vdev_register(VDEV_LEVEL_MIDDLE, &_vdev_hvc_ping_module); 42 | if (result == HVMM_STATUS_SUCCESS) { 43 | printf("vdev registered:'%s'\n", _vdev_hvc_ping_module.name); 44 | } else { 45 | printf("%s: Unable to register vdev:'%s' code=%x\n", 46 | __func__, _vdev_hvc_ping_module.name, result); 47 | } 48 | 49 | return result; 50 | } 51 | vdev_module_middle_init(vdev_hvc_ping_init); 52 | -------------------------------------------------------------------------------- /drivers/vdev/vdev_hvc_stay.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define DEBUG 3 | #include 4 | 5 | static int32_t vdev_hvc_stay_write(struct arch_vdev_trigger_info *info) 6 | { 7 | printf("[hyp] _hyp_hvc_service:stay\n\r"); 8 | return 0; 9 | } 10 | 11 | static int32_t vdev_hvc_stay_check(struct arch_vdev_trigger_info *info) 12 | { 13 | if ((info->iss & 0xFFFF) == 0xFFFF) { 14 | return 0; 15 | } 16 | 17 | return VDEV_NOT_FOUND; 18 | } 19 | 20 | static hvmm_status_t vdev_hvc_stay_reset_values(void) 21 | { 22 | return HVMM_STATUS_SUCCESS; 23 | } 24 | 25 | struct vdev_ops _vdev_hvc_stay_ops = { 26 | .init = vdev_hvc_stay_reset_values, 27 | .check = vdev_hvc_stay_check, 28 | .write = vdev_hvc_stay_write, 29 | }; 30 | 31 | struct vdev_module _vdev_hvc_stay_module = { 32 | .name = "K-Hypervisor vDevice HVC Stay Module", 33 | .author = "Kookmin Univ.", 34 | .ops = &_vdev_hvc_stay_ops, 35 | }; 36 | 37 | hvmm_status_t vdev_hvc_stay_init() 38 | { 39 | hvmm_status_t result = HVMM_STATUS_BUSY; 40 | 41 | 42 | result = vdev_register(VDEV_LEVEL_MIDDLE, &_vdev_hvc_stay_module); 43 | if (result == HVMM_STATUS_SUCCESS) { 44 | printf("vdev registered:'%s'\n", _vdev_hvc_stay_module.name); 45 | } else { 46 | printf("%s: Unable to register vdev:'%s' code=%x\n", 47 | __func__, _vdev_hvc_stay_module.name, result); 48 | } 49 | 50 | return result; 51 | } 52 | vdev_module_middle_init(vdev_hvc_stay_init); 53 | -------------------------------------------------------------------------------- /drivers/vdev/vdev_hvc_yield.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define DEBUG 3 | #include 4 | #include 5 | 6 | static int32_t vdev_hvc_yield_write(struct arch_vdev_trigger_info *info) 7 | { 8 | printf("[hyp] _hyp_hvc_service:yield\n\r"); 9 | 10 | /* FIXME:(igkang) sched */ // guest_switchto(sched_policy_determ_next()); 11 | return 0; 12 | } 13 | 14 | static int32_t vdev_hvc_yield_check(struct arch_vdev_trigger_info *info) 15 | { 16 | if ((info->iss & 0xFFFF) == 0xFFFD) { 17 | return 0; 18 | } 19 | 20 | return VDEV_NOT_FOUND; 21 | } 22 | 23 | static hvmm_status_t vdev_hvc_yield_reset_values(void) 24 | { 25 | return HVMM_STATUS_SUCCESS; 26 | } 27 | 28 | struct vdev_ops _vdev_hvc_yield_ops = { 29 | .init = vdev_hvc_yield_reset_values, 30 | .check = vdev_hvc_yield_check, 31 | .write = vdev_hvc_yield_write, 32 | }; 33 | 34 | struct vdev_module _vdev_hvc_yield_module = { 35 | .name = "K-Hypervisor vDevice HVC Yield Module", 36 | .author = "Kookmin Univ.", 37 | .ops = &_vdev_hvc_yield_ops, 38 | }; 39 | 40 | hvmm_status_t vdev_hvc_yield_init() 41 | { 42 | hvmm_status_t result = HVMM_STATUS_BUSY; 43 | 44 | result = vdev_register(VDEV_LEVEL_MIDDLE, &_vdev_hvc_yield_module); 45 | if (result == HVMM_STATUS_SUCCESS) { 46 | printf("vdev registered:'%s'\n", _vdev_hvc_yield_module.name); 47 | } else { 48 | printf("%s: Unable to register vdev:'%s' code=%x\n", 49 | __func__, _vdev_hvc_yield_module.name, result); 50 | } 51 | 52 | return result; 53 | } 54 | /* FIXME:(igkang) sched */ // vdev_module_middle_init(vdev_hvc_yield_init); 55 | -------------------------------------------------------------------------------- /drivers/vdev/vdev_sample.c: -------------------------------------------------------------------------------- 1 | #include 2 | #define DEBUG 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define SAMPLE_BASE_ADDR 0x3FFFF000 10 | 11 | 12 | struct vdev_sample_regs { 13 | uint32_t axis_x; 14 | uint32_t axis_y; 15 | uint32_t axis_z; 16 | }; 17 | 18 | static int32_t vdev_sample_read(void *pdata, uint32_t offset); 19 | static int32_t vdev_sample_write(void *pdata, uint32_t offset, uint32_t *addr); 20 | int32_t vdev_sample_create_instance(void **pdata); 21 | 22 | struct vdev_module vdev_sample = { 23 | .name = "vdev_sample", 24 | .base = SAMPLE_BASE_ADDR, 25 | .size = 0x1000, 26 | .read = vdev_sample_read, 27 | .write = vdev_sample_write, 28 | .create = vdev_sample_create_instance, 29 | }; 30 | 31 | int32_t vdev_sample_create_instance(void **pdata) 32 | { 33 | *pdata = malloc(sizeof(struct vdev_sample_regs)); 34 | return 0; 35 | } 36 | 37 | static int32_t vdev_sample_read(void *pdata, uint32_t offset) 38 | { 39 | struct vdev_sample_regs *sample_regs = pdata; 40 | 41 | /* READ */ 42 | switch (offset) { 43 | case 0x0: 44 | return sample_regs->axis_x; 45 | break; 46 | case 0x4: 47 | return sample_regs->axis_y; 48 | break; 49 | case 0x8: 50 | return sample_regs->axis_x + sample_regs->axis_y; 51 | break; 52 | } 53 | return 0; 54 | } 55 | 56 | static int32_t vdev_sample_write(void *pdata, uint32_t offset, uint32_t *addr) 57 | { 58 | 59 | struct vdev_sample_regs *sample_regs = pdata; 60 | 61 | /* WRITE */ 62 | switch (offset) { 63 | case 0x0: 64 | sample_regs->axis_x = readl(addr); 65 | break; 66 | case 0x4: 67 | sample_regs->axis_y = readl(addr); 68 | break; 69 | case 0x8: 70 | /* read-only register, ignored, but no error */ 71 | break; 72 | } 73 | return 0; 74 | } 75 | 76 | 77 | hvmm_status_t vdev_sample_init() 78 | { 79 | hvmm_status_t result = HVMM_STATUS_BUSY; 80 | 81 | vdev_register(&vdev_sample); 82 | printf("vdev registered:'%s'\n", vdev_sample.name); 83 | 84 | return result; 85 | } 86 | vdev_module_init(vdev_sample_init); 87 | -------------------------------------------------------------------------------- /include/arch/armv7.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARMV7_H__ 2 | #define __ARMV7_H__ 3 | 4 | #include 5 | 6 | #include "v7/cache.h" 7 | #include "v7/tlb.h" 8 | #include "v7/vmsa.h" 9 | #include "v7/generic_timer.h" 10 | #include "v7/smp.h" 11 | #include "v7/mutex.h" 12 | #include "v7/cp15.h" 13 | #include "v7/barrier.h" 14 | #include "v7/local_irq.h" 15 | #include "v7/hsr.h" 16 | #include "v7/cpsr.h" 17 | #include "v7/hcr.h" 18 | #include "v7/hsctlr.h" 19 | 20 | /* co-processor registers: cp15, cp2 */ 21 | struct cp15 { 22 | uint32_t vbar; 23 | uint32_t ttbr0; 24 | uint32_t ttbr1; 25 | uint32_t ttbcr; 26 | uint32_t sctlr; 27 | uint32_t vmpidr; 28 | 29 | uint32_t csselr; 30 | uint32_t cpacr; 31 | 32 | uint32_t contextidr; 33 | uint32_t tpidrurw; 34 | uint32_t tpidruro; 35 | uint32_t tpidrprw; 36 | 37 | uint32_t cntkctl; 38 | 39 | uint32_t dacr; 40 | uint32_t par; 41 | 42 | uint32_t mair0; 43 | uint32_t mair1; 44 | uint32_t amair0; 45 | uint32_t amair1; 46 | 47 | uint32_t dfar; 48 | uint32_t ifar; 49 | uint32_t dfsr; 50 | uint32_t ifsr; 51 | 52 | uint32_t adfsr; 53 | uint32_t aifsr; 54 | }; 55 | 56 | /* banked registers */ 57 | struct banked_regs { 58 | uint32_t sp_usr; 59 | 60 | uint32_t spsr_svc; 61 | uint32_t sp_svc; 62 | uint32_t lr_svc; 63 | uint32_t spsr_abt; 64 | uint32_t sp_abt; 65 | uint32_t lr_abt; 66 | uint32_t spsr_und; 67 | uint32_t sp_und; 68 | uint32_t lr_und; 69 | uint32_t spsr_irq; 70 | uint32_t sp_irq; 71 | uint32_t lr_irq; 72 | 73 | uint32_t spsr_fiq; 74 | /* unsupported sp_fiq, uint32_t sp_fiq; */ 75 | uint32_t lr_fiq; 76 | uint32_t r8_fiq; 77 | uint32_t r9_fiq; 78 | uint32_t r10_fiq; 79 | uint32_t r11_fiq; 80 | uint32_t r12_fiq; 81 | }; 82 | 83 | #define NR_ARCH_GPR_REGS 13 84 | 85 | /* Defines the architecture core registers */ 86 | struct core_regs { 87 | uint32_t cpsr; /* CPSR */ 88 | uint32_t pc; /* Program Counter */ 89 | uint32_t lr; 90 | uint32_t gpr[NR_ARCH_GPR_REGS]; /* R0 - R12 */ 91 | } __attribute((packed)); 92 | 93 | struct arch_regs { 94 | struct core_regs core_regs; 95 | struct cp15 cp15; 96 | struct banked_regs banked_regs; 97 | }; 98 | 99 | int handle_data_abort(struct core_regs *regs, uint32_t iss); 100 | 101 | #endif /* armv7.h */ 102 | -------------------------------------------------------------------------------- /include/arch/irq.h: -------------------------------------------------------------------------------- 1 | #ifndef __INTERRUPT_H__ 2 | #define __INTERRUPT_H__ 3 | 4 | #include 5 | #include "armv7.h" 6 | 7 | // CBAR has base address of GIC interrupt controller. 8 | static inline uint64_t get_periphbase(void) 9 | { 10 | uint64_t periphbase = 0UL; 11 | unsigned long cbar = read_cp32(CBAR); 12 | uint64_t upper_periphbase = cbar & 0xFF; 13 | 14 | if (upper_periphbase != 0x0) { 15 | periphbase |= upper_periphbase << 32; 16 | cbar &= ~(0xFF); 17 | } 18 | periphbase |= cbar; 19 | 20 | return periphbase; 21 | } 22 | 23 | typedef enum { 24 | VMM_IRQ, 25 | VMM_VM_BOTH_IRQ, 26 | VM_IRQ, 27 | MAINTENANCE_IRQ, 28 | UNEXCEPTED_IRQ 29 | } irqreturn_t; 30 | 31 | typedef irqreturn_t (*irq_handler_t)(int irq, void *regs, void *pdata); 32 | void irq_init(); 33 | void register_irq_handler(uint32_t irq, irq_handler_t handler, uint8_t polarity); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /include/arch/psci.h: -------------------------------------------------------------------------------- 1 | #ifndef __PSCI_H__ 2 | #define __PSCI_H__ 3 | 4 | #include 5 | #include 6 | 7 | #ifdef CONFIG_ARM_PSCI_VERSION_0_1 8 | 9 | typedef enum { 10 | PSCI_FN_CPU_SUSPEND = CONFIG_ARM_PSCI_FN_BASE, 11 | PSCI_FN_CPU_OFF, 12 | PSCI_FN_CPU_ON, 13 | PSCI_FN_MIGRATE, 14 | 15 | PSCI_FN_LAST = PSCI_FN_MIGRATE 16 | } psci_fn; 17 | 18 | #else 19 | 20 | typedef enum { 21 | PSCI_FN_PSCI_VERSION = CONFIG_ARM_PSCI_FN_BASE, 22 | PSCI_FN_CPU_SUSPEND, 23 | PSCI_FN_CPU_OFF, 24 | PSCI_FN_CPU_ON, 25 | PSCI_FN_AFFINITY_INFO, 26 | PSCI_FN_MIGRATE, 27 | PSCI_FN_MIGRATE_INFO_TYPE, 28 | PSCI_FN_INFO_UP_CPU, 29 | PSCI_FN_SYSTEM_OFF, 30 | PSCI_FN_SYSTEM_RESET, 31 | PSCI_FN_PSCI_FEATURES, 32 | PSCI_FN_PSCI_CPU_FREEZE, 33 | PSCI_FN_CPU_DEFAULT_SUSPEND, 34 | PSCI_FN_NODE_HW_STATE, 35 | PSCI_FN_SYSTEM_SUSPEND, 36 | PSCI_FN_PSCI_SET_SUSPEND_MODE, 37 | PSCI_FN_PSCI_STAT_RESIDENCY, 38 | PSCI_FN_PSCI_STAT_COUNT, 39 | 40 | #ifdef CONFIG_ARM_PSCI_VERSION_1_0 41 | PSCI_FN_LAST = PSCI_FN_PSCI_STAT_COUNT 42 | #else 43 | PSCI_FN_SYSTEM_RESET2, 44 | PSCI_FN_MEM_PROTECT, 45 | PSCI_FN_MEM_PROTECT_CHECK_RANGE, 46 | 47 | PSCI_FN_LAST = PSCI_FN_MEM_PROTECT_CHECK_RANGE 48 | #endif 49 | } psci_fn; 50 | 51 | #endif 52 | 53 | #define PSCI_RET_SUCCESS 0 54 | #define PSCI_RET_NOT_SUPPORTED -1 55 | #define PSCI_RET_INVALID_PARAMS -2 56 | #define PSCI_RET_DENIED -3 57 | #define PSCI_RET_ALREADY_ON -4 58 | #define PSCI_RET_ON_PENDING -5 59 | #define PSCI_RET_INTERNAL_FAILURE -6 60 | #define PSCI_RET_NOT_PRESENT -7 61 | #define PSCI_RET_DISABLED -8 62 | #define PSCI_RET_INVALID_ADDRESS -9 63 | 64 | int psci_cpu_suspend(uint32_t state, unsigned long entry_point); 65 | int psci_cpu_off(uint32_t state); 66 | int psci_cpu_on(unsigned long cpu_id, unsigned long entry_point); 67 | int psci_migrate(unsigned long cpu_id); 68 | 69 | int emulate_psci_cpu_on(struct core_regs *regs); 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /include/arch/smccc.h: -------------------------------------------------------------------------------- 1 | #ifndef __SMCCC_H__ 2 | #define __SMCCC_H__ 3 | 4 | #include 5 | 6 | #define SMCCC_TYPE_SHIFT 31 7 | #define SMCCC_CONV_SHIFT 30 8 | #define SMCCC_SERVICE_SHIFT 24 9 | #define SMCCC_FN_NUM_SHIFT 0 10 | 11 | #define SMCCC_TYPE_MASK 0x1 12 | #define SMCCC_CONV_MASK 0x1 13 | #define SMCCC_SERVICE_MASK 0x3f 14 | #define SMCCC_FN_NUM_MASK 0xffff 15 | 16 | #define __SMCCC_GET_FROM_ID(desc, id) \ 17 | (((id) >> SMCCC_##desc##_SHIFT) & SMCCC_##desc##_MASK) 18 | 19 | #define SMCCC_IS_FAST_CALL(fn) __SMCCC_GET_FROM_ID(TYPE, fn) 20 | #define SMCCC_IS_64(fn) __SMCCC_GET_FROM_ID(CONV, fn) 21 | #define SMCCC_SERVICE(fn) __SMCCC_GET_FROM_ID(SERVICE, fn) 22 | #define SMCCC_FN_NUM(fn) __SMCCC_GET_FROM_ID(FN_NUM, fn) 23 | 24 | #define SMCCC_FN_ID(type, conv, service, fn_num) ( \ 25 | (((type) & SMCCC_CALL_TYPE_MASK) << SMCCC_CALL_TYPE_SHIFT) | \ 26 | (((conv) & SMCCC_CONV_MASK) << SMCCC_CONV_SHIFT) | \ 27 | (((service) & SMCCC_SERVICE_MASK) << SMCCC_SERVICE_SHIFT) | \ 28 | (((fn_num) & SMCCC_FN_NUM_MASK) << SMCCC_FN_NUM_SHIFT)) 29 | 30 | enum smccc_call_type { 31 | SMCCC_TYPE_STD = 0, 32 | SMCCC_TYPE_FAST 33 | }; 34 | 35 | enum smccc_convention { 36 | SMCCC_CONV_32 = 0, 37 | SMCCC_CONV_64 38 | }; 39 | 40 | enum smccc_service_range { 41 | SMCCC_SERVICE_ARCH = 0, 42 | SMCCC_SERVICE_CPU, 43 | SMCCC_SERVICE_SIP, 44 | SMCCC_SERVICE_OEM, 45 | SMCCC_SERVICE_STANDARD, 46 | SMCCC_SERVICE_HYPERVISOR, 47 | 48 | // SMCCC_SERVICE_RESERVED = 7, 49 | // SMCCC_SERVICE_RESERVED_END = 47, 50 | 51 | SMCCC_SERVICE_TRUSTED_APP = 48, 52 | SMCCC_SERVICE_TRUSTED_APP_END = 49, 53 | 54 | SMCCC_SERVICE_TRUSTED_OS = 50, 55 | SMCCC_SERVICE_TRUSTED_OS_END = 63 56 | }; 57 | 58 | struct arm_smccc_res { 59 | unsigned long a0; 60 | unsigned long a1; 61 | unsigned long a2; 62 | unsigned long a3; 63 | }; 64 | 65 | void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, 66 | unsigned long a3, unsigned long a4, unsigned long a5, 67 | unsigned long a6, unsigned long a7, 68 | struct arm_smccc_res *res); 69 | 70 | void arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, 71 | unsigned long a3, unsigned long a4, unsigned long a5, 72 | unsigned long a6, unsigned long a7, 73 | struct arm_smccc_res *res); 74 | 75 | int handle_arm_smccc(struct core_regs *regs); 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /include/arch/v7/barrier.h: -------------------------------------------------------------------------------- 1 | #ifndef __BARRIER_H__ 2 | #define __BARRIER_H__ 3 | 4 | #include 5 | 6 | /* Defined memory barrier at 10.2 section in DEN0013D */ 7 | 8 | #define isb() asm __volatile__ ("isb" : : : "memory") 9 | #define dsb(option) asm __volatile__ ("dsb " #option : : : "memory") 10 | #define dmb(option) asm __volatile__ ("dmb " #option : : : "memory") 11 | 12 | #define mb() dmb(sy) 13 | #define rmb() dmb(sy) 14 | #define wmb() dmb(st) 15 | 16 | #define smp_mb() dmb(ish) 17 | #define smp_rmb() dmb(ish) 18 | #define smp_wmb() dmb(ishst) 19 | 20 | #endif /* __BARRIER_H__ */ 21 | -------------------------------------------------------------------------------- /include/arch/v7/cache.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARMV7_CACHE_H__ 2 | #define __ARMV7_CACHE_H__ 3 | 4 | #include 5 | 6 | // TODO: add cache-related operations 7 | 8 | 9 | 10 | #endif /* cp15_cache.h */ 11 | -------------------------------------------------------------------------------- /include/arch/v7/cpsr.h: -------------------------------------------------------------------------------- 1 | #ifndef __CPSR_H__ 2 | #define __CPSR_H__ 3 | 4 | /* Define CPSR(SPSR) and processor modes at B1.3 section in DDI0406C_C */ 5 | 6 | #define CPSR_N 31 7 | #define CPSR_Z 30 8 | #define CPSR_C 29 9 | #define CPSR_V 28 10 | #define CPSR_Q 27 11 | #define CPSR_IT0 25 12 | #define CPSR_J 24 13 | #define CPSR_RESERVED 20 14 | #define CPSR_GE 16 15 | #define CPSR_IT1 10 16 | #define CPSR_E 9 17 | #define CPSR_A 8 18 | #define CPSR_I 7 19 | #define CPSR_F 6 20 | #define CPSR_T 5 21 | #define CPSR_M 0 22 | 23 | #define N (0b1) 24 | #define Z (0b1) 25 | #define C (0b1) 26 | #define V (0b1) 27 | #define Q (0b1) 28 | #define IT0 (0b11) 29 | #define J (0b11) 30 | // #define RESERVED (0b1111) 31 | #define GE (0b1111) 32 | #define IT1 (0b111111) 33 | #define E (0b1) 34 | #define A (0b1) 35 | #define I (0b1) 36 | #define F (0b1) 37 | #define T (0b1) 38 | #define M (0b11111) 39 | 40 | #define MODE_USR (0b10000) 41 | #define MODE_FIQ (0b10001) 42 | #define MODE_IRQ (0b10010) 43 | #define MODE_SVC (0b10011) 44 | #define MODE_MON (0b10110) 45 | #define MODE_ABT (0b10011) 46 | #define MODE_HYP (0b11010) 47 | #define MODE_UND (0b11011) 48 | #define MODE_SYS (0b11111) 49 | 50 | #define CPSR_BIT(x) ( x << CPSR_##x ) 51 | #define CPSR_MODE(x) ( MODE_##x << CPSR_M ) 52 | #define CPSR(x) ( x ) 53 | 54 | #endif /* __CPSR_H__ */ 55 | -------------------------------------------------------------------------------- /include/arch/v7/hcr.h: -------------------------------------------------------------------------------- 1 | #ifndef __HCR_H__ 2 | #define __HCR_H__ 3 | 4 | #define HCR_TGE 27 5 | #define HCR_TVE 26 6 | #define HCR_TTLB 25 7 | #define HCR_TPU 24 8 | #define HCR_TPC 23 9 | #define HCR_TSW 22 10 | #define HCR_TAC 21 11 | #define HCR_TIDCP 20 12 | #define HCR_TSC 19 13 | #define HCR_TID3 18 14 | #define HCR_TID2 17 15 | #define HCR_TID1 16 16 | #define HCR_TID0 15 17 | #define HCR_TWE 14 18 | #define HCR_TWI 13 19 | #define HCR_DC 12 20 | #define HCR_BSU 10 21 | #define HCR_FB 9 22 | #define HCR_VA 8 23 | #define HCR_VI 7 24 | #define HCR_VF 6 25 | #define HCR_AMO 5 26 | #define HCR_IMO 4 27 | #define HCR_FMO 3 28 | #define HCR_PTW 2 29 | #define HCR_SWIO 1 30 | #define HCR_VM 0 31 | 32 | 33 | #define TGE_BIT (0b1) 34 | #define TVE_BIT (0b1) 35 | #define TTLB_BIT (0b1) 36 | #define TPU_BIT (0b1) 37 | #define TPC_BIT (0b1) 38 | #define TSW_BIT (0b1) 39 | #define TAC_BIT (0b1) 40 | #define TIDCP_BIT (0b1) 41 | #define TSC_BIT (0b1) 42 | #define TID3_BIT (0b1) 43 | #define TID2_BIT (0b1) 44 | #define TID1_BIT (0b1) 45 | #define TID0_BIT (0b1) 46 | #define TWE_BIT (0b1) 47 | #define TWI_BIT (0b1) 48 | #define DC_BIT (0b1) 49 | #define BSU_BIT (0b11) 50 | #define FB_BIT (0b1) 51 | #define VA_BIT (0b1) 52 | #define VI_BIT (0b1) 53 | #define VF_BIT (0b1) 54 | #define AMO_BIT (0b1) 55 | #define IMO_BIT (0b1) 56 | #define FMO_BIT (0b1) 57 | #define PTW_BIT (0b1) 58 | #define SWIO_BIT (0b1) 59 | #define VM_BIT (0b1) 60 | 61 | #define HCR_BIT(x) ( x##_BIT << HCR_##x ) 62 | 63 | #endif //__HCR_H__ 64 | -------------------------------------------------------------------------------- /include/arch/v7/hint_inst.h: -------------------------------------------------------------------------------- 1 | #ifndef __HINT_INSTRUCTION_H__ 2 | #define __HINT_INSTRUCTION_H__ 3 | 4 | #include 5 | 6 | #define sev() asm __volatile__ ("sev" : : : "memory") 7 | #define wfe() asm __volatile__ ("wfe" : : : "memory") 8 | #define wfi() asm __volatile__ ("wfi" : : : "memory") 9 | #define nop() asm __volatile__ ("nop") 10 | #define yield() asm __volatile__ ("yield") 11 | 12 | #endif /* __HINT_INSTRUCTION_H__ */ 13 | -------------------------------------------------------------------------------- /include/arch/v7/hsctlr.h: -------------------------------------------------------------------------------- 1 | #ifndef __HSCTLR_H__ 2 | #define __HSCTLR_H__ 3 | 4 | #define HSCTLR_TE 30 5 | #define HSCTLR_EE 25 6 | #define HSCTLR_FI 21 7 | #define HSCTLR_WXN 19 8 | #define HSCTLR_I 12 9 | #define HSCTLR_CP15BEN 5 10 | #define HSCTLR_C 2 11 | #define HSCTLR_A 1 12 | #define HSCTLR_M 0 13 | 14 | 15 | #define TE_BIT (0b1) 16 | #define EE_BIT (0b1) 17 | #define FI_BIT (0b1) 18 | #define WXN_BIT (0b1) 19 | #define I_BIT (0b1) 20 | #define CP15BEN_BIT (0b1) 21 | #define C_BIT (0b1) 22 | #define A_BIT (0b1) 23 | #define M_BIT (0b1) 24 | 25 | #define HSCTLR_BIT(x) ( x##_BIT << HSCTLR_##x ) 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/arch/v7/local_irq.h: -------------------------------------------------------------------------------- 1 | #ifndef __LOCAL_IRQ__ 2 | #define __LOCAL_IRQ__ 3 | 4 | #include 5 | #include 6 | 7 | // TODO(wonseok): Refactor every functions 8 | 9 | #define asm_clz(x) ({ uint32_t rval; asm volatile(\ 10 | " clz %0, %1\n\t" \ 11 | : "=r" (rval) : "r" (x) : ); rval; }) 12 | 13 | #define irq_enable() asm volatile("cpsie i" : : : "memory") 14 | #define irq_disable() asm volatile ("cpsid i" : : : "memory") 15 | 16 | #define irq_disabled() ({ unsigned long tf; \ 17 | asm volatile (" mrs %0, cpsr\n\t" \ 18 | : "=r" (tf) \ 19 | : \ 20 | : "memory", "cc"); \ 21 | (tf & CPSR_IRQ_DISABLED) ? TRUE : FALSE; }) 22 | 23 | #define irq_save(flags) do { \ 24 | asm volatile ( \ 25 | "mrs %0, cpsr\n\t" \ 26 | "cpsid i\n\t" \ 27 | : "=r" ((flags)) : : "memory", "cc"); \ 28 | } while (0) 29 | 30 | 31 | #define irq_restore(flags) do { \ 32 | asm volatile (" msr cpsr_c, %0" \ 33 | : : "r" ((flags)) : "memory", "cc"); \ 34 | } while (0) 35 | 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /include/arch/v7/mutex.h: -------------------------------------------------------------------------------- 1 | #ifndef __MUTEX_H__ 2 | #define __MUTEX_H__ 3 | 4 | #include 5 | 6 | #ifdef CONFIG_SMP 7 | #define __ARCH_MUTEX_UNLOCKED 0xFFFFFFFF 8 | 9 | extern void init_mutex(void * mutex); 10 | extern void lock_mutex(void * mutex); 11 | extern void unlock_mutex(void * mutex); 12 | extern void is_mutex_locked(void * mutex); 13 | #else 14 | #define __ARCH_MUTEX_UNLOCKED 0 15 | #define __ARCH_MUTEX_LOCKED 1 16 | 17 | extern void lock_mutex(void * mutex); 18 | extern void unlock_mutex(void * mutex); 19 | #endif 20 | 21 | typedef struct { 22 | volatile uint32_t mutex; 23 | } mutex_t; 24 | 25 | #define MUTEX_UNLOCKED(m) \ 26 | { .mutex = __ARCH_MUTEX_UNLOCKED, } 27 | 28 | #define DEFINE_MUTEX(m) mutex_t m = MUTEX_UNLOCKED(m); 29 | 30 | #endif //__MUTEX_H__ 31 | -------------------------------------------------------------------------------- /include/arch/v7/smp.h: -------------------------------------------------------------------------------- 1 | #ifndef __SMP_H__ 2 | #define __SMP_H__ 3 | 4 | #include 5 | #include "cp15.h" 6 | 7 | /** 8 | * @brief Gets current CPU ID of the Symmetric MultiProcessing(SMP). 9 | * 10 | * Read the value from Multiprocessor ID Register(MPIDR) and obtains the CPU ID 11 | * by masking. 12 | * - Coretex-A15 13 | * - MPIDR[1:0] - CPUID - 0, 1, 2, OR 3 14 | * - MPIDR[7:2] - Reserved, Read as zero 15 | * @return The current CPU ID. 16 | */ 17 | #define NR_MAX_CLUSTERS 15 18 | #define CLUSTER_BIT_MASK (NR_MAX_CLUSTERS << 8) 19 | #define NR_CPUS_PER_CLUSTER 4 20 | #define NR_CPUS_BIT_MASK 0x3 21 | 22 | static inline uint32_t smp_processor_id(void) 23 | { 24 | uint32_t mpidr = read_cp32(MPIDR); 25 | uint8_t cluster_id = ((mpidr & CLUSTER_BIT_MASK) >> 8) * NR_CPUS_PER_CLUSTER; 26 | 27 | return (mpidr & NR_CPUS_BIT_MASK) + cluster_id; 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /include/arch/v7/tlb.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARMV7_TLB_H__ 2 | #define __ARMV7_TLB_H__ 3 | 4 | #include 5 | #include 6 | 7 | // TODO: add tlb-related operations 8 | /* Invalidate entire unified TLB */ 9 | 10 | #endif /* tlb.h */ 11 | -------------------------------------------------------------------------------- /include/arch/v7/vmsa.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARMV7_MM_H__ 2 | #define __ARMV7_MM_H__ 3 | 4 | #define HTCR_IRGN0_BIT 8 5 | #define HTCR_ORGN0_BIT 10 6 | #define HTCR_SH0_BIT 12 7 | 8 | /* VTCR ATTRIBUTES */ 9 | #define VTCR_SL0_SECOND_LEVEL 0x0 10 | #define VTCR_SL0_FIRST_LEVEL 0x1 11 | #define VTCR_SL0_BIT 6 12 | 13 | /* ORGN0 & IRGN0 bit are the same */ 14 | //#define VTCR_NONCACHEABLE 0X0 15 | //#define VTCR_WRITEBACK_CACHEABLE 0x1 16 | //#define VTCR_WRITE_THROUGH_CACHEABLE 0x2 17 | //#define VTCR_WRITEBACK_NO_CACHEABLE 0x3 18 | 19 | #define VTCR_ORGN0_BIT 10 20 | #define VTCR_IRGN0_BIT 8 21 | 22 | /* 23 | * CP15 Barrier instructions 24 | */ 25 | //#define CP15ISB asm volatile ("mcr p15, 0, %0, c7, c5, 4" : : "r" (0)) 26 | //#define CP15DSB asm volatile ("mcr p15, 0, %0, c7, c10, 4" : : "r" (0)) 27 | //#define CP15DMB asm volatile ("mcr p15, 0, %0, c7, c10, 5" : : "r" (0)) 28 | 29 | #endif /* armv7-mm.h */ 30 | -------------------------------------------------------------------------------- /include/arch_regs.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARCH_REGS_H__ 2 | #define __ARCH_REGS_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | /* moved from scheduler.h */ 9 | hvmm_status_t arch_regs_init(struct arch_regs *regs); 10 | hvmm_status_t arch_regs_save(struct arch_regs *regs, struct core_regs *current_regs); 11 | hvmm_status_t arch_regs_restore(struct arch_regs *regs, struct core_regs *current_regs); 12 | 13 | void arch_regs_copy(struct arch_regs *from, struct arch_regs *to, struct core_regs *regs); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /include/asm/asm.h: -------------------------------------------------------------------------------- 1 | #ifndef __ASM_H__ 2 | #define __ASM_H__ 3 | 4 | #ifdef CONFIG_C99 5 | #define asm __asm__ 6 | #endif // CONFIG_C99 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /include/asm/macro.h: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | * 3 | * Copyright (C) 2003-2004, National ICT Australia (NICTA) 4 | * 5 | * File path: l4/arm/asm.h 6 | * Description: Assembler macros etc. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | * 29 | * $Id: asm.h,v 1.3 2004/06/04 08:20:12 htuch Exp $ 30 | * 31 | ********************************************************************/ 32 | 33 | #ifndef __MACRO_H__ 34 | #define __MACRO_H__ 35 | 36 | #ifndef __ARMCC_VERSION 37 | /* GNU tools */ 38 | #define BEGIN_PROC(name) \ 39 | .global name; \ 40 | .align; \ 41 | name: 42 | 43 | #define END_PROC(name) \ 44 | ; 45 | 46 | #define END 47 | 48 | #define LABEL(name) \ 49 | name: 50 | 51 | #else 52 | /* ARM tools */ 53 | MACRO 54 | begin_proc $name 55 | EXPORT $name 56 | ALIGN 57 | $name 58 | MEND 59 | #define BEGIN_PROC(name) \ 60 | begin_proc name 61 | 62 | #define END_PROC(name) \ 63 | ; 64 | 65 | /* 66 | * The ADS and RVCT cpps do different things. ADS puts blank space at the 67 | * start of lines, while RVCT puts no space at all! :( 68 | */ 69 | #if __ARMCC_VERSION < 200000 70 | MACRO 71 | label $name 72 | $name 73 | MEND 74 | #define LABEL(name) label name 75 | #else 76 | #define LABEL(name) name 77 | #endif 78 | 79 | #endif 80 | 81 | #define SECTION(x) __attribute__((section(x))) 82 | 83 | #endif /* __MACRO_H__ */ 84 | -------------------------------------------------------------------------------- /include/atags.h: -------------------------------------------------------------------------------- 1 | #ifndef __ATAGS_H__ 2 | #define __ATAGS_H__ 3 | 4 | #include 5 | #include 6 | 7 | /* list of possible tags */ 8 | #define ATAG_NONE 0x00000000 9 | #define ATAG_CORE 0x54410001 10 | #define ATAG_MEM 0x54410002 11 | #define ATAG_VIDEOTEXT 0x54410003 12 | #define ATAG_RAMDISK 0x54410004 13 | #define ATAG_INITRD2 0x54420005 14 | #define ATAG_SERIAL 0x54410006 15 | #define ATAG_REVISION 0x54410007 16 | #define ATAG_VIDEOLFB 0x54410008 17 | #define ATAG_CMDLINE 0x54410009 18 | 19 | #define tag_next(t) ((struct atag *)((uint32_t *)(t) + (t)->hdr.size)) 20 | #define tag_size(type) ((sizeof(struct atag_header) \ 21 | + sizeof(struct type)) >> 2) 22 | 23 | /* structures for each atag */ 24 | struct atag_header { 25 | uint32_t size; /* length of tag in words including this header */ 26 | uint32_t tag; /* tag type */ 27 | }; 28 | struct atag_core { 29 | uint32_t flags; 30 | uint32_t pagesize; 31 | uint32_t rootdev; 32 | }; 33 | struct atag_mem { 34 | uint32_t size; 35 | uint32_t start; 36 | }; 37 | struct atag_serialnr { 38 | uint32_t low; 39 | uint32_t high; 40 | }; 41 | struct atag_revision { 42 | uint32_t rev; 43 | }; 44 | struct atag_cmdline { 45 | char cmdline[1]; 46 | }; 47 | struct atag_ramdisk { 48 | uint32_t flags; /* bit 0 = load, bit 1 = prompt */ 49 | uint32_t size; /* decompressed ramdisk size in _kilo_ bytes */ 50 | uint32_t start; /* starting block of floppy-based RAM disk image */ 51 | }; 52 | struct atag_videotext { 53 | uint8_t x; /* width of display */ 54 | uint8_t y; /* height of display */ 55 | uint16_t video_page; 56 | uint8_t video_mode; 57 | uint8_t video_cols; 58 | uint16_t video_ega_bx; 59 | uint8_t video_lines; 60 | uint8_t video_isvga; 61 | uint16_t video_points; 62 | }; 63 | struct atag_initrd2 { 64 | uint32_t start; /* physical start address */ 65 | uint32_t size; /* size of compressed ramdisk image in bytes */ 66 | }; 67 | struct atag_videolfb { 68 | uint16_t lfb_width; 69 | uint16_t lfb_height; 70 | uint16_t lfb_depth; 71 | uint16_t lfb_linelength; 72 | uint32_t lfb_base; 73 | uint32_t lfb_size; 74 | uint8_t red_size; 75 | uint8_t red_pos; 76 | uint8_t green_size; 77 | uint8_t green_pos; 78 | uint8_t blue_size; 79 | uint8_t blue_pos; 80 | uint8_t rsvd_size; 81 | uint8_t rsvd_pos; 82 | }; 83 | struct atag { 84 | struct atag_header hdr; 85 | union { 86 | struct atag_core core; 87 | struct atag_mem mem; 88 | struct atag_videotext videotext; 89 | struct atag_ramdisk ramdisk; 90 | struct atag_initrd2 initrd2; 91 | struct atag_serialnr serialnr; 92 | struct atag_revision revision; 93 | struct atag_videolfb videolfb; 94 | struct atag_cmdline cmdline; 95 | } u; 96 | }; 97 | 98 | #define INVALID 0 99 | 100 | void atags_setup(void); 101 | uint32_t *linuxloader_get_atags_addr(void); 102 | 103 | #endif /* __ATAGS_H__ */ 104 | -------------------------------------------------------------------------------- /include/core/context_switch.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONTEXT_SWITCH_TO_H__ 2 | #define __CONTEXT_SWITCH_TO_H__ 3 | 4 | #include "../types.h" 5 | #include 6 | 7 | hvmm_status_t do_context_switch(vcpuid_t from_id, vcpuid_t to_id, struct core_regs *current_core_regs); 8 | 9 | #endif /* __CONTEXT_SWITCH_TO_H__ */ 10 | -------------------------------------------------------------------------------- /include/core/kmus.h: -------------------------------------------------------------------------------- 1 | #ifndef __KMUS_H__ 2 | #define __KMUS_H__ 3 | 4 | #include 5 | #include 6 | 7 | void kmus_start(vmid_t normal_id, vmid_t kmus_id, struct core_regs *regs); 8 | void kmus_snapshot(vmid_t normal_id, vmid_t kmus_id, struct core_regs *regs); 9 | 10 | #endif /* __KMUS_H__ */ 11 | 12 | -------------------------------------------------------------------------------- /include/core/sched/sched-config.h: -------------------------------------------------------------------------------- 1 | #ifndef _SCHEDULER_CONFIG_H_ 2 | #define _SCHEDULER_CONFIG_H_ 3 | 4 | #include 5 | 6 | /* TODO:(igkang) merge this macro with NR_VCPUS in vdev_gicd.h */ 7 | #define TOTAL_VCPUS 8 8 | 9 | extern const struct sched_policy * 10 | schedconf_g_policy[]; 11 | 12 | extern uint32_t 13 | schedconf_g_vcpu_to_pcpu_map[TOTAL_VCPUS]; 14 | 15 | extern uint32_t 16 | schedconf_rr_slice[TOTAL_VCPUS]; 17 | 18 | extern uint32_t 19 | schedconf_rm_tick_interval_us[NR_CPUS]; 20 | 21 | extern uint32_t 22 | schedconf_rm_period_budget[TOTAL_VCPUS][2]; 23 | 24 | extern uint32_t 25 | schedconf_edf_tick_interval_us[NR_CPUS]; 26 | 27 | extern uint32_t 28 | schedconf_edf_period_budget[TOTAL_VCPUS][2]; 29 | 30 | #endif /* _SCHEDULER_CONFIG_H_ */ 31 | -------------------------------------------------------------------------------- /include/core/sched/scheduler_skeleton.h: -------------------------------------------------------------------------------- 1 | #ifndef _SCHEDULER_SKELETON_H_ 2 | #define _SCHEDULER_SKELETON_H_ 3 | 4 | #include 5 | #include 6 | #include "../../types.h" 7 | #include 8 | #include 9 | 10 | typedef uint32_t sched_id_t; 11 | 12 | struct scheduler; 13 | struct sched_entry; 14 | 15 | typedef enum { 16 | SCHED_DETACHED, 17 | SCHED_WAITING, 18 | SCHED_RUNNING 19 | } sched_state; 20 | 21 | struct sched_policy { 22 | size_t size_sched_extra; 23 | size_t size_entry_extra; 24 | 25 | void (*init)(struct scheduler *); 26 | int (*register_vcpu)(struct scheduler *, struct sched_entry *); 27 | int (*unregister_vcpu)(struct scheduler *, struct sched_entry *); 28 | int (*attach_vcpu)(struct scheduler *, struct sched_entry *); 29 | int (*detach_vcpu)(struct scheduler *, struct sched_entry *); 30 | int (*do_schedule)(struct scheduler *, uint64_t *); 31 | }; 32 | 33 | struct sched_entry { 34 | vcpuid_t vcpuid; 35 | sched_state state; 36 | // struct vcpu *vcpu; /* TODO:(igkang) direct vcpu referencing */ 37 | 38 | struct list_head head_standby; 39 | struct list_head head_inflight; 40 | 41 | /* policy-specific data follows (allocation) */ 42 | void *ed; 43 | }; 44 | 45 | struct scheduler { 46 | sched_id_t id; 47 | uint32_t pcpuid; 48 | 49 | struct timer timer; 50 | 51 | vcpuid_t current_vcpuid; 52 | vcpuid_t next_vcpuid; 53 | struct vcpu *current_vcpu; 54 | struct vmcb *current_vm; 55 | 56 | struct list_head standby_entries; 57 | struct list_head inflight_entries; 58 | 59 | const struct sched_policy *policy; 60 | 61 | /* policy-specific data follows (allocation) */ 62 | void *sd; 63 | }; 64 | 65 | extern const struct sched_policy sched_rr; 66 | extern const struct sched_policy sched_rt_rm; 67 | extern const struct sched_policy sched_rt_edf; 68 | 69 | extern struct scheduler *sched[NR_CPUS]; 70 | 71 | #endif /* _SCHEDULER_SKELETON_H_ */ 72 | -------------------------------------------------------------------------------- /include/core/scheduler.h: -------------------------------------------------------------------------------- 1 | #ifndef __SCHEDULER_H__ 2 | #define __SCHEDULER_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define GUEST_VERBOSE_ALL 0xFF 10 | #define GUEST_VERBOSE_LEVEL_0 0x01 11 | #define GUEST_VERBOSE_LEVEL_1 0x02 12 | #define GUEST_VERBOSE_LEVEL_2 0x04 13 | #define GUEST_VERBOSE_LEVEL_3 0x08 14 | #define GUEST_VERBOSE_LEVEL_4 0x10 15 | #define GUEST_VERBOSE_LEVEL_5 0x20 16 | #define GUEST_VERBOSE_LEVEL_6 0x40 17 | #define GUEST_VERBOSE_LEVEL_7 0x80 18 | 19 | void sched_init(); 20 | 21 | int sched_vcpu_register(vcpuid_t vcpuid, uint32_t pcpu); 22 | int sched_vcpu_register_to_current_pcpu(vcpuid_t vcpuid); 23 | int sched_vcpu_unregister(vcpuid_t vcpuid, uint32_t pcpu); 24 | 25 | int sched_vcpu_attach(vcpuid_t vcpuid, uint32_t pcpu); 26 | int sched_vcpu_attach_to_current_pcpu(vcpuid_t vcpuid); 27 | int sched_vcpu_detach(vcpuid_t vcpuid, uint32_t pcpu); 28 | 29 | void do_schedule(void *pdata, uint64_t *expiration); 30 | void sched_start(void); 31 | 32 | vmid_t get_current_vcpuid(void); 33 | vcpuid_t get_current_vcpuidx(void); 34 | struct vcpu *get_current_vcpu(void); 35 | struct vmcb *get_current_vm(void); 36 | 37 | hvmm_status_t guest_switchto(vmid_t vmid); 38 | hvmm_status_t sched_perform_switch(struct core_regs *regs); 39 | 40 | #endif /* __SCHEDULER_H__ */ 41 | -------------------------------------------------------------------------------- /include/core/timer.h: -------------------------------------------------------------------------------- 1 | #ifndef __TIMER_H__ 2 | #define __TIMER_H__ 3 | 4 | #include 5 | #include "../types.h" 6 | 7 | #include 8 | 9 | #define GUEST_TIMER 0 10 | #define HOST_TIMER 1 11 | 12 | /* bigger time units into nanoseconds */ 13 | #define NOW() ((uint64_t)timer_get_timenow()) 14 | #define SEC(s) ((uint64_t)((s) * 1000000000ULL)) 15 | #define MSEC(ms) ((uint64_t)((ms) * 1000000ULL)) 16 | #define USEC(us) ((uint64_t)((us) * 1000ULL)) 17 | 18 | typedef void(*timer_callback_t)(void *pdata, uint64_t *expiration); 19 | 20 | struct timer { 21 | struct list_head head_active; 22 | struct list_head head_inactive; 23 | 24 | uint32_t state; 25 | uint64_t expiration; 26 | timer_callback_t callback; 27 | }; 28 | 29 | struct timer_ops { 30 | hvmm_status_t (*init)(void); 31 | hvmm_status_t (*enable)(void); 32 | hvmm_status_t (*disable)(void); 33 | uint64_t (*get_counter)(void); 34 | hvmm_status_t (*set_absolute)(uint64_t); 35 | hvmm_status_t (*set_interval_relative)(uint32_t); 36 | hvmm_status_t (*set_interval_absolute)(uint64_t); 37 | hvmm_status_t (*dump)(void); 38 | }; 39 | 40 | struct timer_module { 41 | uint32_t version; 42 | const char *id; 43 | const char *name; 44 | const char *author; 45 | struct timer_ops *ops; 46 | }; 47 | 48 | extern struct timer_module _timer_module; 49 | 50 | /* cummulative stopwatch */ 51 | struct stopwatch { 52 | uint64_t start; 53 | uint64_t lastdiff; 54 | 55 | uint64_t min; 56 | uint64_t max; 57 | uint64_t total; 58 | 59 | uint32_t cnt; 60 | }; 61 | 62 | /* 63 | * Calling this function is required only once in the entire system 64 | * prior to calls to other functions of Timer module. 65 | */ 66 | hvmm_status_t timer_hw_init(uint32_t irq); 67 | 68 | hvmm_status_t timemanager_init(); 69 | hvmm_status_t tm_register_timer(struct timer *t, timer_callback_t callback); 70 | hvmm_status_t tm_set_timer(struct timer *t, uint64_t expiration, bool timer_stopstart); 71 | hvmm_status_t tm_activate_timer(struct timer *t); 72 | hvmm_status_t tm_deactivate_timer(struct timer *t); 73 | 74 | hvmm_status_t timer_stop(void); 75 | hvmm_status_t timer_start(void); 76 | 77 | uint64_t timer_count_to_time_ns(uint64_t count); 78 | uint64_t timer_time_to_count_ns(uint64_t time); 79 | uint64_t timer_get_syscounter(void); 80 | uint64_t timer_get_timenow(void); 81 | 82 | void stopwatch_init(struct stopwatch *w); 83 | void stopwatch_reset(struct stopwatch *w); 84 | void stopwatch_start(struct stopwatch *w); 85 | void stopwatch_stop(struct stopwatch *w); 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /include/core/vm/vcpu.h: -------------------------------------------------------------------------------- 1 | #ifndef __VCPU_H__ 2 | #define __VCPU_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define VCPU_CREATE_FAILED NULL 12 | #define VCPU_NOT_EXISTED NULL 13 | 14 | typedef enum vcpu_type { 15 | VCPU_NORMAL, 16 | VCPU_KMUS, 17 | } vcpu_type_t; 18 | 19 | typedef enum vcpu_state { 20 | VCPU_UNDEFINED, 21 | VCPU_DEFINED, 22 | VCPU_REGISTERED, 23 | VCPU_ACTIVATED, 24 | } vcpu_state_t; 25 | 26 | #define MAX_PENDING_VIRQS 64 27 | #define MAX_NR_IRQ 1024 28 | #define GUEST_IRQ_ENABLE 1 29 | #define GUEST_IRQ_DISABLE 0 30 | 31 | #define INJECT_SW 0 32 | #define INJECT_HW 1 33 | 34 | struct virq_table { 35 | uint32_t enabled; 36 | uint32_t virq; 37 | uint32_t pirq; 38 | }; 39 | 40 | 41 | struct vcpu { 42 | vcpuid_t vcpuid; // Unique ID that vcpu has 43 | 44 | // TODO(casionwoo): Might be needed like 'get_current_vcpuidx()' API 45 | vcpuid_t id; // ID that order of vcpu of VM 46 | 47 | pcpuid_t pcpuid; // Physical CPU ID that vcpu is assigned 48 | 49 | vmid_t vmid; 50 | 51 | struct arch_regs regs; 52 | 53 | lr_entry_t pending_irqs[MAX_PENDING_VIRQS + 1]; 54 | 55 | uint32_t lr[64]; 56 | 57 | uint32_t vmcr; 58 | 59 | unsigned int period; 60 | 61 | unsigned int deadline; 62 | 63 | uint64_t running_time; 64 | 65 | uint64_t actual_running_time; 66 | 67 | vcpu_type_t type; 68 | vcpu_state_t state; 69 | 70 | // TODO(casionwoo): it will be removed. 71 | struct virq_table map[MAX_NR_IRQ]; 72 | 73 | struct vdev_timer vtimer; /* TODO:(igkang) need to move cntfrq, offset to vm? */ 74 | 75 | struct list_head head; 76 | }; 77 | 78 | void vcpu_setup(); 79 | 80 | struct vcpu *vcpu_create(vcpu_type_t type); 81 | vcpu_state_t vcpu_init(struct vcpu *vcpu); 82 | vcpu_state_t vcpu_start(struct vcpu *vcpu); 83 | vcpu_state_t vcpu_suspend(struct vcpu *vcpu, struct core_regs *regs); 84 | vcpu_state_t vcpu_delete(struct vcpu *vcpu); 85 | 86 | void vcpu_save(struct vcpu *vcpu, struct core_regs *regs); 87 | void vcpu_restore(struct vcpu *vcpu, struct core_regs *regs); 88 | 89 | void vcpu_copy(struct vcpu *from, struct vcpu *to, struct core_regs *regs); 90 | 91 | struct vcpu *vcpu_find(vcpuid_t vcpuid); 92 | void print_all_vcpu(); 93 | void print_vcpu(struct vcpu *vcpu); 94 | 95 | uint32_t virq_to_pirq(struct vcpu *v, uint32_t virq); 96 | uint32_t pirq_to_virq(struct vcpu *v, uint32_t pirq); 97 | 98 | void virq_enable(struct vcpu *v, uint32_t pirq, uint32_t virq); 99 | void virq_disable(struct vcpu *v, uint32_t virq); 100 | void pirq_enable(struct vcpu *v, uint32_t pirq, uint32_t virq); 101 | void pirq_disable(struct vcpu *v, uint32_t pirq); 102 | 103 | void irq_handler_init(irq_handler_t *handlers); 104 | 105 | struct list_head *get_all_vcpus(); 106 | 107 | #endif /* __VCPU_H__ */ 108 | -------------------------------------------------------------------------------- /include/core/vm/vm.h: -------------------------------------------------------------------------------- 1 | #ifndef __VM_H__ 2 | #define __VM_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define SIZE_OF_NAME 32 11 | #define NO_VM_FOUND NULL 12 | #define VM_NOT_EXISTED (-1) 13 | #define VM_CREATE_FAILED (-2) 14 | 15 | typedef enum vmcb_type { 16 | VM_NORMAL, 17 | VM_KMUS, 18 | } vmcb_type_t; 19 | 20 | typedef enum vmcb_state { 21 | UNDEFINED, 22 | DEFINED, 23 | HALTED, 24 | RUNNING, 25 | SUSPENDED 26 | } vmcb_state_t; 27 | 28 | struct vmcb { 29 | vmid_t vmid; 30 | char name[SIZE_OF_NAME]; 31 | 32 | uint8_t num_vcpus; 33 | 34 | struct vcpu **vcpu; 35 | struct vmem vmem; 36 | 37 | struct vdev_instance vdevs; 38 | 39 | vmcb_type_t type; 40 | vmcb_state_t state; 41 | struct list_head head; 42 | }; 43 | 44 | void vm_setup(); 45 | vmid_t vm_create(uint8_t num_vcpu, vmcb_type_t vmcb_type); 46 | vmcb_state_t vm_init(vmid_t vmid); 47 | vmcb_state_t vm_start(vmid_t vmid); 48 | vmcb_state_t vm_suspend(vmid_t vmid, struct core_regs *regs); 49 | vmcb_state_t vm_delete(vmid_t vmid); 50 | 51 | // TODO(casionwoo) : resume, shutdown 52 | void vm_save(vmid_t vmid); 53 | void vm_restore(vmid_t vmid); 54 | 55 | void vm_copy(vmid_t from, vmid_t to, struct core_regs *regs); 56 | 57 | struct vmcb *vm_find(vmid_t vmid); 58 | void print_all_vm(); 59 | 60 | struct list_head *get_all_vms(); 61 | 62 | #endif /* __VM_H__ */ 63 | 64 | -------------------------------------------------------------------------------- /include/core/vm/vmem.h: -------------------------------------------------------------------------------- 1 | #ifndef __VMEM_H__ 2 | #define __VMEM_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | struct vmem { 9 | struct memdesc_t dram; 10 | struct memdesc_t *mmap; 11 | uint32_t base; 12 | uint32_t vtcr; 13 | uint32_t actlr; 14 | uint64_t vttbr; 15 | }; 16 | 17 | void vmem_setup(); 18 | void vmem_copy(struct vmem *from, struct vmem *to); 19 | void vmem_create(struct vmem *vmem, vmid_t vmid); 20 | hvmm_status_t vmem_init(struct vmem *vmem, vmid_t vmid); 21 | hvmm_status_t vmem_save(void); 22 | hvmm_status_t vmem_restore(struct vmem *vmem); 23 | 24 | #endif /* __VMEM_H__ */ 25 | -------------------------------------------------------------------------------- /include/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEBUG_H__ 2 | #define __DEBUG_H__ 3 | 4 | #include 5 | 6 | //#define CONFIG_ENABLE_DEBUG 7 | 8 | #if defined (CONFIG_ENABLE_DEBUG) 9 | #define debug_print(fmt, args...) printf(fmt, #args) 10 | #else 11 | #define debug_print(fmt, args...) 12 | #endif 13 | 14 | #endif //__DEBUG_PRINTF_H__ 15 | -------------------------------------------------------------------------------- /include/device.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEVICE_H__ 2 | #define __DEVICE_H__ 3 | 4 | #include 5 | 6 | struct device { 7 | 8 | int32_t (* init) (); 9 | 10 | }; 11 | 12 | 13 | 14 | #endif /* __DEVICE_H__ */ 15 | -------------------------------------------------------------------------------- /include/drivers/gic-v2.h: -------------------------------------------------------------------------------- 1 | #ifndef __GIC_H__ 2 | #define __GIC_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "../include/types.h" 8 | 9 | #include <../platform/config.h> 10 | 11 | #include 12 | 13 | #define HW_IRQ 1 14 | #define SW_IRQ 0 15 | 16 | #define GIC_NUM_MAX_IRQS 1024 17 | #define GIC_INT_PRIORITY_DEFAULT 0xa0 18 | #define VGIC_NUM_MAX_SLOTS 64 19 | 20 | enum virq_state { 21 | VIRQ_STATE_INACTIVE = 0x00, 22 | VIRQ_STATE_PENDING = 0x01, 23 | VIRQ_STATE_ACTIVE = 0x02, 24 | VIRQ_STATE_PENDING_ACTIVE = 0x03, 25 | }; 26 | 27 | union LR { 28 | uint32_t raw; 29 | struct { 30 | uint32_t virtualid: 10; 31 | uint32_t physicalid: 10; 32 | uint32_t reserved: 3; 33 | uint32_t priority: 5; 34 | uint32_t state: 2; 35 | uint32_t grp1: 1; 36 | uint32_t hw: 1; 37 | } entry __attribute__((__packed__)); 38 | }; 39 | 40 | typedef union LR lr_entry_t; 41 | 42 | struct GICv2_HW { 43 | uint32_t gicd_base; 44 | uint32_t gicc_base; 45 | uint32_t gich_base; 46 | uint32_t ITLinesNumber; 47 | uint32_t CPUNumber; 48 | uint32_t num_lr; 49 | } GICv2; 50 | 51 | 52 | #define IRQ_LEVEL_SENSITIVE 0 53 | #define IRQ_EDGE_TRIGGERED 1 54 | 55 | enum gic_sgi { 56 | GIC_SGI_SLOT_CHECK = 1, 57 | }; 58 | 59 | void gic_init(void); 60 | void gic_enable_irq(uint32_t irq); 61 | void gic_disable_irq(uint32_t irq); 62 | uint32_t gic_get_irq_number(void); 63 | void gic_completion_irq(uint32_t irq); 64 | void gic_deactivate_irq(uint32_t irq); 65 | void gic_configure_irq(uint32_t irq, uint8_t polarity); 66 | 67 | void gic_set_sgi(const uint32_t target, uint32_t sgi); 68 | 69 | /* GICH related functions */ 70 | void gich_init(void); 71 | void gich_enable(void); 72 | void gich_disable(void); 73 | hvmm_status_t gic_inject_pending_irqs(vcpuid_t vcpuid); 74 | struct vcpu; 75 | bool virq_inject(struct vcpu *vcpu, uint32_t virq, uint32_t pirq, uint8_t hw); 76 | 77 | void update_lr(uint32_t offset, uint32_t value); 78 | void gic_inject_virq(lr_entry_t lr_entry, uint32_t slot); 79 | 80 | #include 81 | #define GICD_READ(offset) __readl(GICv2.gicd_base + offset) 82 | #define GICD_WRITE(offset, value) __writel(value, GICv2.gicd_base + offset) 83 | 84 | #define GICC_READ(offset) __readl(GICv2.gicc_base + offset) 85 | #define GICC_WRITE(offset, value) __writel(value, GICv2.gicc_base + offset) 86 | 87 | #define GICH_READ(offset) __readl(GICv2.gich_base + offset) 88 | #define GICH_WRITE(offset, value) __writel(value, GICv2.gich_base + offset) 89 | 90 | #endif 91 | 92 | -------------------------------------------------------------------------------- /include/drivers/mct.h: -------------------------------------------------------------------------------- 1 | #ifndef __MCT__H__ 2 | #define __MCT__H__ 3 | 4 | #define EXYNOS5_MCT_BASE 0x101C0000 5 | #define EXYNOS5_MCT_G_TCON 0x240 6 | #define EXYNOS5_MCT_G_WSTAT 0x24C 7 | #define EXYNOS5_MCT_G_CNT_WSTAT 0x110 8 | #define EXYNOS5_MCT_G_CNT_L 0x100 9 | #define EXYNOS5_MCT_G_CNT_U 0x104 10 | #define MCT_G_TCON_START (1 << 8) 11 | 12 | void mct_init(void); 13 | #endif 14 | -------------------------------------------------------------------------------- /include/drivers/pl180.h: -------------------------------------------------------------------------------- 1 | #ifndef __PL180_MCI_H__ 2 | #define __PL180_MCI_H__ 3 | 4 | 5 | #define PL180_BASE 0x1C050000 6 | 7 | #define MCI_POWER(x) (x + 0x000) // RW 8 | #define MCI_CLOCK(x) (x + 0x004) // RW 9 | #define MCI_ARG(x) (x + 0x008) // RW 10 | #define MCI_CMD(x) (x + 0x00C) // RW 11 | #define MCI_RES_CMD(x) (x + 0x010) // RW 12 | 13 | #define MCI_RES0(x) (x + 0x014) // RO 14 | #define MCI_RES1(x) (x + 0x018) // RO 15 | #define MCI_RES2(x) (x + 0x01C) // RO 16 | #define MCI_RES3(x) (x + 0x020) // RO 17 | 18 | #define MCI_DTIMER(x) (x + 0x024) // RW 19 | #define MCI_DLENGTH(x) (x + 0x028) // RW 20 | #define MCI_DCTRL(x) (x + 0x02C) // RW 21 | #define MCI_DCNT(x) (x + 0x030) // RW 22 | 23 | #define MCI_STATUS(x) (x + 0x034) // RO 24 | #define MCI_CLEAR(x) (x + 0x038) // WO 25 | 26 | #define MCI_MASK0(x) (x + 0x03C) //RW 27 | #define MCI_MASK1(x) (x + 0x040) //RW 28 | #define MCI_SELECT(x) (x + 0x044) //RW 29 | 30 | #define MCI_FIFO_CNT(x) (x + 0x048) //RO 31 | #define MCI_FIFO(x) (x + 0x080) //RW 32 | 33 | #define MCI_PERIPHID0(x) (x + 0xFE0) //RO 34 | #define MCI_PERIPHID1(x) (x + 0xFE4) //RO 35 | #define MCI_PERIPHID2(x) (x + 0xFE8) //RO 36 | #define MCI_PERIPHID3(x) (x + 0xFEC) //RO 37 | 38 | #define MCI_PCELL0(x) (x + 0xFF0) //RO 39 | #define MCI_PCELL1(x) (x + 0xFF4) //RO 40 | #define MCI_PCELL2(x) (x + 0xFF8) //RO 41 | #define MCI_PCELL3(x) (x + 0xFFC) //RO 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /include/drivers/serial_ns16550.h: -------------------------------------------------------------------------------- 1 | #ifndef __NS16550_H__ 2 | #define __NS16550_H__ 3 | 4 | #define NS16550_BASE 0x01C28000 5 | 6 | #define NS16550_RBR 0x00 7 | #define NS16550_THR 0x00 8 | #define NS16550_DLL 0x00 9 | #define NS16550_DLH 0x04 10 | #define NS16550_IER 0x04 11 | #define NS16550_IIR 0x08 12 | #define NS16550_FCR 0x08 13 | #define NS16550_LCR 0x0C 14 | #define NS16550_MCR 0x10 15 | #define NS16550_LSR 0x14 16 | #define NS16550_MSR 0x18 17 | #define NS16550_SCH 0x1C 18 | #define NS16550_USR 0x7C 19 | #define NS16550_TFL 0x80 20 | #define NS16550_RFL 0x84 21 | #define NS16550_HALT 0xA4 22 | 23 | #define UART_LSR_DR 0x01 24 | #define UART_LSR_THRE 0x20 25 | #define UART_LSR_TEMT 0x40 26 | 27 | void serial_init(); 28 | int serial_putc(const char c); 29 | int serial_getc(); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /include/drivers/serial_s5p.h: -------------------------------------------------------------------------------- 1 | #ifndef __S5P_H__ 2 | #define __S5P_H_ 3 | 4 | #define S5P_BASE 0x12c20000 5 | 6 | #define S5P_ULCON 0x00 7 | #define S5P_UCON 0x04 8 | #define S5P_UFCON 0x08 9 | #define S5P_UMCON 0x0C 10 | #define S5P_UTRSTAT 0x10 11 | #define S5P_UERSTAT 0x14 12 | #define S5P_UFSTAT 0x18 13 | #define S5P_UMSTAT 0x1C 14 | #define S5P_UTXH 0x20 15 | #define S5P_RES1_0 0x21 16 | #define S5P_RES1_1 0x22 17 | #define S5P_RES1_2 0x23 18 | #define S5P_URXH 0x24 19 | #define S5P_RES2_0 0x25 20 | #define S5P_RES2_1 0x26 21 | #define S5P_RES2_2 0x27 22 | #define S5P_UBRDIV 0x28 23 | #define S5P_REST 0x2C 24 | 25 | #define ULCON_OVERRUN 1<<0 26 | #define ULCON_PARITY 1<<1 27 | #define ULCON_FRAME 1<<2 28 | #define ULCON_BREAK 1<<3 29 | 30 | int serial_init(void); 31 | int serial_putc(const char c); 32 | int serial_getc(void); 33 | #endif 34 | -------------------------------------------------------------------------------- /include/drivers/serial_sh.h: -------------------------------------------------------------------------------- 1 | #ifndef __SH_H__ 2 | #define __SH_H__ 3 | 4 | #define SCIF_BASE 0xE6E60000 5 | 6 | #define SCSCR_TE_ENABLE 0x0020 7 | #define SCSCR_RE_ENABLE 0x0010 8 | #define SCSCR_CKE1_ENABLE 0x0002 9 | 10 | #define SCFSR_ER 0x0080 11 | #define SCFSR_TEND 0x0040 12 | #define SCFSR_BRK 0x0010 13 | #define SCFSR_FER 0x0008 14 | #define SCFSR_PER 0x0004 15 | #define SCFSR_RDF 0x0002 16 | #define SCFSR_DR 0x0001 17 | 18 | #define SCLSR_ORER 0x0000 19 | 20 | #define SCFSR_ER_ENABLE 0x0080 21 | #define SCFSR_TEND_ENABLE 0x0040 22 | #define SCFSR_TDFE_ENABLE 0x0020 23 | #define SCFSR_BRK_ENABLE 0x0010 24 | 25 | #define SCFCR_RFRST_ENABLE 0x0002 26 | #define SCFCR_TFRST_ENABLE 0x0004 27 | 28 | #define SCSCR 0x08 29 | #define SCSMR 0x00 30 | #define SCFCR 0x18 31 | #define SCFSR 0x10 32 | #define SCFTDR 0x0c 33 | #define SCFRDR 0x14 34 | #define SCLSR 0x24 35 | 36 | int serial_init(void); 37 | int serial_putc(const char c); 38 | int serial_getc(void); 39 | #endif 40 | -------------------------------------------------------------------------------- /include/drivers/sp804.h: -------------------------------------------------------------------------------- 1 | #ifndef __SP804_H__ 2 | #define __SP804_H__ 3 | 4 | #define TIMER1_IRQ 34 5 | #define TIMER2_IRQ 35 6 | 7 | #define TIMER1_BASE 0x1C110000 8 | #define TIMER2_BASE 0x1C120000 9 | 10 | #define TIMER1_LOAD(x) (x + 0x00) // RW 11 | #define TIMER1_VALUE(x) (x + 0x04) // RO 12 | #define TIMER1_CONTROL(x) (x + 0x08) // RW 13 | #define TIMER1_INTCLR(x) (x + 0x0C) // WO 14 | #define TIMER1_RIS(x) (x + 0x10) // RO 15 | #define TIMER1_MIS(x) (x + 0x14) // RO 16 | #define TIMER1_BGLOAD(x) (x + 0x18) // RW 17 | 18 | #define TIMER2_LOAD(x) (x + 0x20) // RW 19 | #define TIMER2_VALUE(x) (x + 0x24) // RO 20 | #define TIMER2_CONTROL(x) (x + 0x28) // RW 21 | #define TIMER2_INTCLR(x) (x + 0x2C) // WO 22 | #define TIMER2_RIS(x) (x + 0x30) // RO 23 | #define TIMER2_MIS(x) (x + 0x34) // RO 24 | #define TIMER2_BGLOAD(x) (x + 0x38) // RW 25 | 26 | #define TIMER_ITCR(x) (x + 0xF00) //RW 27 | #define TIMER_ITOP(x) (x + 0xF04) //WO 28 | 29 | #define TIMER_RERIPHID0(x) (x + 0xFE0) //RO 30 | #define TIMER_RERIPHID1(x) (x + 0xFE4) //RO 31 | #define TIMER_RERIPHID2(x) (x + 0xFE8) //RO 32 | #define TIMER_RERIPHID3(x) (x + 0xFEC) //RO 33 | 34 | #define TIMER_RPCELL0(x) (x + 0xFF0) //RO 35 | #define TIMER_RPCELL1(x) (x + 0xFF4) //RO 36 | #define TIMER_RPCELL2(x) (x + 0xFF8) //RO 37 | #define TIMER_RPCELL3(x) (x + 0xFFC) //RO 38 | 39 | void sp804_init(); 40 | void sp804_enable(); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /include/drivers/vdev/vdev_gicd.h: -------------------------------------------------------------------------------- 1 | #ifndef __VDEV_GICD_H__ 2 | #define __VDEV_GICD_H__ 3 | 4 | /* Banked Registers Size */ 5 | #define NR_BANKED_IPRIORITYR 8 6 | #define NR_BANKED_ITARGETSR 8 7 | #define NR_BANKED_CPENDSGIR 4 8 | #define NR_BANKED_SPENDSGIR 4 9 | 10 | /* We assume that ITLinesNumber has maximum number */ 11 | #define NR_IRQS 31 12 | 13 | #define NR_IGROUPR (NR_IRQS + 1) 14 | #define NR_ISENABLER (NR_IRQS + 1) 15 | #define NR_ICENABLER (NR_IRQS + 1) 16 | #define NR_ISPENDR (NR_IRQS + 1) 17 | #define NR_ICPENDR (NR_IRQS + 1) 18 | #define NR_ISACTIVER (NR_IRQS + 1) 19 | #define NR_ICACTIVER (NR_IRQS + 1) 20 | #define NR_IPRIORITYR (8 * (NR_IRQS + 1)) 21 | #define NR_ITARGETSR (8 * (NR_IRQS + 1)) 22 | #define NR_ICFGR (2 * (NR_IRQS + 1)) 23 | #define NR_NSACR 32 24 | 25 | #define NR_VCPUS 8 26 | 27 | struct vgicd { 28 | uint32_t ctlr; 29 | uint32_t typer; 30 | uint32_t iidr; 31 | 32 | uint32_t igroupr0[NR_VCPUS]; 33 | uint32_t igroupr[NR_IGROUPR]; 34 | 35 | uint32_t isenabler0[NR_VCPUS]; 36 | uint32_t isenabler[NR_ISENABLER]; 37 | 38 | uint32_t icenabler0[NR_VCPUS]; 39 | uint32_t icenabler[NR_ICENABLER]; 40 | 41 | uint32_t ispendr0[NR_VCPUS]; 42 | uint32_t ispendr[NR_ISPENDR]; 43 | 44 | uint32_t icpendr0[NR_VCPUS]; 45 | uint32_t icpendr[NR_ICPENDR]; 46 | 47 | uint32_t isactiver0[NR_VCPUS]; 48 | uint32_t isactiver[NR_ISACTIVER]; 49 | 50 | uint32_t icactiver0[NR_VCPUS]; 51 | uint32_t icactiver[NR_ICACTIVER]; 52 | 53 | uint32_t ipriorityr0[NR_VCPUS][NR_BANKED_IPRIORITYR]; 54 | uint32_t ipriorityr[NR_IPRIORITYR]; 55 | 56 | uint32_t itargetsr0[NR_VCPUS][NR_BANKED_ITARGETSR]; 57 | uint32_t itargetsr[NR_ITARGETSR]; 58 | 59 | uint32_t icfgr0[NR_VCPUS]; 60 | uint32_t icfgr[NR_ICFGR]; 61 | 62 | uint32_t nsacr[NR_NSACR]; // unused 63 | 64 | uint32_t sgir; 65 | 66 | uint32_t cpendsgir0[NR_VCPUS][NR_BANKED_CPENDSGIR]; 67 | uint32_t spendsgir0[NR_VCPUS][NR_BANKED_SPENDSGIR]; 68 | }; 69 | 70 | 71 | #endif /* __VDEV_GICD_H__ */ 72 | -------------------------------------------------------------------------------- /include/drivers/vdev/vdev_timer.h: -------------------------------------------------------------------------------- 1 | #ifndef __VDEV_TIMER_H__ 2 | #define __VDEV_TIMER_H__ 3 | 4 | #include 5 | 6 | #define VTIMER_PERIODIC 7 | 8 | /* represents a generic timer w/o SE,VE (Physical, virtual timer) */ 9 | struct vdev_timer { 10 | /* data for hypervisor */ 11 | uint64_t p_ct_offset; 12 | 13 | /* regs for guest */ 14 | uint32_t frq; 15 | uint32_t k_ctl; 16 | 17 | uint32_t p_ctl; 18 | uint64_t p_cval; 19 | /* tval is a diff between CNTPCT and CNTP_CVAL */ 20 | 21 | uint32_t v_ctl; 22 | uint64_t v_cval; 23 | // uint64_t v_off; 24 | /* ARM DDI 0406C.c B8-1969 claims that CNTVOFF is only for VE */ 25 | 26 | /* FIXME:(igkang) This is a workaround. Periodic mode should become configurable */ 27 | #ifdef VTIMER_PERIODIC 28 | bool periodic_mode; 29 | uint32_t periodic_interval; 30 | #endif 31 | 32 | struct timer swtimer; /* for Physical Timer (?) */ 33 | }; 34 | 35 | int vdev_timer_access64(uint8_t read, uint32_t what, uint32_t *rt_low, uint32_t *rt_high); 36 | int vdev_timer_access32(uint8_t read, uint32_t what, uint32_t *rt); 37 | void init_vdev_timer(struct vdev_timer *v); 38 | 39 | #endif /* __VDEV_TIMER_H__ */ 40 | -------------------------------------------------------------------------------- /include/generated/.gitignore: -------------------------------------------------------------------------------- 1 | *.h 2 | -------------------------------------------------------------------------------- /include/io.h: -------------------------------------------------------------------------------- 1 | #ifndef __IO_H__ 2 | #define __IO_H__ 3 | #include 4 | 5 | #define __writel(v, a) (*(volatile uint32_t *)(a) = (v)) 6 | #define __readl(a) (*(volatile uint32_t *)(a)) 7 | #define __writew(v, a) (*(volatile uint16_t *)(a) = (v)) 8 | #define __readw(a) (*(volatile uint16_t *)(a)) 9 | #define __writeb(v, a) (*(volatile uint8_t *)(a) = (v)) 10 | #define __readb(a) (*(volatile uint8_t *)(a)) 11 | 12 | #define writel(v, a) ({ uint32_t vl = v; __writel(vl, a); }) 13 | #define readl(a) ({ uint32_t vl = __readl(a); vl; }) 14 | #define writew(v, a) ({ uint16_t vl = v; __writew(vl, a); }) 15 | #define readw(a) ({ uint16_t vl = __readw(a); vl; }) 16 | #define writeb(v, a) ({ uint8_t vl = v; __writeb(vl, a); }) 17 | #define readb(a) ({ uint8_t vl = __readb(a); vl; }) 18 | 19 | #include 20 | #include 21 | static inline void write64(uint64_t value, addr_t addr) 22 | { 23 | dsb(); 24 | asm volatile ("strd\t" "%0, %H0, [%1];" : : "r" (value), "r" (addr) : "memory"); 25 | dsb(); 26 | } 27 | 28 | static inline uint64_t read64(addr_t addr) 29 | { 30 | uint64_t value; 31 | asm volatile ("ldrd\t" "%0, %H0, [%1];" : "=r" (value) : "r" (addr): "memory"); 32 | return value; 33 | } 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /include/irq-chip.h: -------------------------------------------------------------------------------- 1 | #ifndef __IRQ_CHIP_H__ 2 | #define __IRQ_CHIP_H__ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include "types.h" 9 | 10 | struct irq_hw { 11 | void (* init) (void); 12 | void (* enable) (uint32_t irq); 13 | void (* disable) (uint32_t irq); 14 | uint32_t (* ack) (void); 15 | void (* eoi) (uint32_t irq); 16 | void (* dir) (uint32_t irq); 17 | void (* set_irq_type) (uint32_t irq, uint8_t polarity); 18 | }; 19 | 20 | 21 | struct virq_hw { 22 | void (* init) (void); 23 | void (* enable) (void); 24 | void (* disable) (void); 25 | bool (* forward_irq) (struct vcpu *vcpu, uint32_t virq, uint32_t pirq, uint8_t hw); 26 | hvmm_status_t (* forward_pending_irq) (vcpuid_t vcpuid); 27 | }; 28 | 29 | struct irq_hw *irq_hw; 30 | struct virq_hw *virq_hw; 31 | 32 | void set_irqchip_type(); 33 | 34 | #endif //__IRQ_CHIP_H__ 35 | -------------------------------------------------------------------------------- /include/lib/stringify.h: -------------------------------------------------------------------------------- 1 | #ifndef __STRINGIFY_H__ 2 | #define __STRINGIFY_H__ 3 | 4 | #define __stringify_1(x...) #x 5 | #define __stringify(x...) __stringify_1(x) 6 | 7 | #endif /* stringify.h */ 8 | -------------------------------------------------------------------------------- /include/serial.h: -------------------------------------------------------------------------------- 1 | #ifndef __SERIAL_H__ 2 | #define __SERIAL_H__ 3 | 4 | #ifdef CONFIG_PL01X_SERIAL 5 | #include 6 | #elif CONFIG_SH_SERIAL 7 | #include 8 | #elif CONFIG_S5P_SERIAL 9 | #include 10 | #elif CONFIG_NS16550_SERIAL 11 | #include 12 | #endif 13 | 14 | #endif //__SERIAL_H__ 15 | -------------------------------------------------------------------------------- /include/size.h: -------------------------------------------------------------------------------- 1 | #ifndef __SIZE_H__ 2 | #define __SIZE_H__ 3 | 4 | /* Definition of K/M/G in Hexadecimal*/ 5 | #define SZ_1 0x00000001 6 | #define SZ_2 0x00000002 7 | #define SZ_4 0x00000004 8 | #define SZ_8 0x00000008 9 | #define SZ_16 0x00000010 10 | #define SZ_32 0x00000020 11 | #define SZ_64 0x00000040 12 | #define SZ_128 0x00000080 13 | #define SZ_256 0x00000100 14 | #define SZ_512 0x00000200 15 | 16 | #define SZ_1K 0x00000400 17 | #define SZ_2K 0x00000800 18 | #define SZ_4K 0x00001000 19 | #define SZ_8K 0x00002000 20 | #define SZ_16K 0x00004000 21 | #define SZ_32K 0x00008000 22 | #define SZ_64K 0x00010000 23 | #define SZ_128K 0x00020000 24 | #define SZ_256K 0x00040000 25 | #define SZ_512K 0x00080000 26 | 27 | #define SZ_1M 0x00100000 28 | #define SZ_2M 0x00200000 29 | #define SZ_4M 0x00400000 30 | #define SZ_8M 0x00800000 31 | #define SZ_16M 0x01000000 32 | #define SZ_32M 0x02000000 33 | #define SZ_64M 0x04000000 34 | #define SZ_128M 0x08000000 35 | #define SZ_256M 0x10000000 36 | #define SZ_512M 0x20000000 37 | 38 | #define SZ_1G 0x40000000 39 | #define SZ_2G 0x80000000 40 | 41 | #define size_4k 1 42 | #define size_8k 2 43 | 44 | #endif //__SIZE_H__ 45 | -------------------------------------------------------------------------------- /include/types.h: -------------------------------------------------------------------------------- 1 | #ifndef __TYPES_H__ 2 | #define __TYPES_H__ 3 | 4 | #define VMID_INVALID 0xFF 5 | #define VCPUID_INVALID 0xFF 6 | #define PIRQ_INVALID 0xFFFFFFFF 7 | #define VIRQ_INVALID PIRQ_INVALID 8 | 9 | typedef enum hvmm_status { 10 | HVMM_STATUS_SUCCESS = 0, 11 | HVMM_STATUS_UNKNOWN_ERROR = -1, 12 | HVMM_STATUS_UNSUPPORTED_FEATURE = -2, 13 | HVMM_STATUS_BUSY = -3, 14 | HVMM_STATUS_BAD_ACCESS = -4, 15 | HVMM_STATUS_NOT_FOUND = -5, 16 | HVMM_STATUS_IGNORED = -6, 17 | } hvmm_status_t; 18 | 19 | typedef int vmid_t; 20 | typedef int vcpuid_t; 21 | typedef int pcpuid_t; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/vdev.h: -------------------------------------------------------------------------------- 1 | #ifndef __VDEV_H_ 2 | #define __VDEV_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | typedef hvmm_status_t (*initcall_t)(void); 11 | 12 | extern initcall_t __vdev_module_start[]; 13 | extern initcall_t __vdev_module_end[]; 14 | 15 | #define __define_vdev_module(fn) \ 16 | static initcall_t __initcall_##fn __attribute__((__used__)) \ 17 | __attribute__((__section__(".vdev_module.init"))) = fn 18 | 19 | #define vdev_module_init(fn) __define_vdev_module(fn) 20 | 21 | struct vdev_module { 22 | uint32_t id; 23 | 24 | uint32_t base; 25 | uint32_t size; 26 | 27 | const char *name; 28 | 29 | int32_t (* create) (void **pdata); 30 | int32_t (* read) (void *pdata, uint32_t offset); 31 | int32_t (* write) (void *pdata, uint32_t offset, uint32_t *addr); 32 | int32_t (* handle_irq) (void); 33 | int32_t (* copy) (void **pdata_from, void **pdata_to); 34 | 35 | struct list_head head; 36 | }; 37 | 38 | struct vdev_instance { 39 | const struct vdev_module *module; 40 | void *pdata; 41 | 42 | vmid_t owner; 43 | 44 | struct list_head head; 45 | }; 46 | 47 | void vdev_register(struct vdev_module *module); 48 | void vdev_init(void); 49 | 50 | void vdev_create(struct vdev_instance *, vmid_t); 51 | void vdev_delete(struct vdev_instance *vdevs); 52 | void vdev_handler(struct core_regs *regs, uint32_t iss); 53 | void vdev_copy(struct vdev_instance *vdev_from, struct vdev_instance *vdev_to); 54 | 55 | #endif /* __VDEV_H_ */ 56 | -------------------------------------------------------------------------------- /include/vm_config.h: -------------------------------------------------------------------------------- 1 | #ifndef __VM_CONFIG_H__ 2 | #define __VM_CONFIG_H__ 3 | 4 | #include 5 | #include 6 | 7 | struct vm_config { 8 | uint8_t nr_vcpus; 9 | uint32_t va_offsets; 10 | addr_t pa_start; 11 | vmcb_type_t vmcb_type; 12 | }; 13 | 14 | extern struct vm_config vm_conf[]; 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /include/vm_map.h: -------------------------------------------------------------------------------- 1 | /* 2 | * vm_map.h 3 | * 4 | * Created on: 18 Mar 2016 5 | * Author: wonseok 6 | */ 7 | 8 | #ifndef __VM_MMAP_H__ 9 | #define __VM_MMAP_H__ 10 | 11 | #include 12 | #include 13 | 14 | struct memdesc_t { 15 | char *label; 16 | uint32_t ipa; 17 | uint32_t pa; 18 | uint32_t size; 19 | uint8_t attr; 20 | uint8_t af; 21 | }; 22 | 23 | // TODO(casionwoo) : These memory mapping variables should be removed after DTB implementation 24 | enum memattr { 25 | MEMATTR_STRONGLY_ORDERED = 0x0, // 00_00 26 | MEMATTR_DEVICE_MEMORY = 0x1, // 00_01 27 | MEMATTR_NORMAL_NON_CACHEABLE = 0x5, // 01_01 28 | MEMATTR_NORMAL_WT_CACHEABLE = 0xA, // 10_10 29 | MEMATTR_NORMAL_WB_CACHEABLE = 0xF, // 11_11 30 | }; 31 | 32 | extern struct memdesc_t *vm_mmap[CONFIG_NR_VMS]; 33 | 34 | void setup_vm_mmap(void); 35 | 36 | 37 | 38 | #endif /* INCLUDE_VM_MAP_H_ */ 39 | -------------------------------------------------------------------------------- /lib/c/include/k_r_malloc.h: -------------------------------------------------------------------------------- 1 | #ifndef _LIBC_K_R_MALLOC_H_ 2 | #define _LIBC_K_R_MALLOC_H_ 3 | 4 | #define NALLOC 0x10000 /* minimum #units to request */ 5 | 6 | typedef long long Align; /* for alignment to long long boundary */ 7 | 8 | union header { /* block header */ 9 | struct { 10 | union header *ptr; /* next block if on free list */ 11 | unsigned size; /* size of this block */ 12 | } s; 13 | Align x; /* force alignment of blocks */ 14 | }; 15 | 16 | typedef union header Header; 17 | 18 | Header *morecore(unsigned nu); 19 | //void __malloc_init(); 20 | void __malloc_init(void*, void*); 21 | #endif /* _LIBC_K_R_MALLOC_H_ */ 22 | -------------------------------------------------------------------------------- /lib/c/include/libc_init.h: -------------------------------------------------------------------------------- 1 | #ifndef __LIBC_INIT_H__ 2 | #define __LIBC_INIT_H__ 3 | 4 | #include "k_r_malloc.h" 5 | 6 | typedef int (*__fputc_p)(int c); 7 | extern __fputc_p __libc_putc; 8 | typedef void (*__fgetc_p)(); 9 | extern __fgetc_p __libc_getc; 10 | 11 | void libc_init(); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /lib/c/src/Makefile: -------------------------------------------------------------------------------- 1 | include ${SOURCE_PATH}/lib/c/src/arch-arm/Makefile 2 | include ${SOURCE_PATH}/lib/c/src/sys-baremetal/Makefile 3 | 4 | objs-y := 5 | 6 | #FOR ALL STANDARD C LIBRARY 7 | #LIBC_SRCS+= memcpy.c strncat.c fgetc.c strpbrk.c fflush.c strcat.c rand.c memcmp.c \ 8 | clearerr.c strcspn.c calloc.c vprintf.c strrchr.c putchar.c srand.c sprintf.c \ 9 | feof.c system.c realloc.c memset.c ftell.c clock.c time.c strerror.c vsnprintf.c \ 10 | strstr.c fwrite.c gmtime.c fputc.c ferror.c format.c strcmp.c strlen.c difftime.c \ 11 | locale.c memmove.c strcoll.c errno.c strncmp.c strftime.c fputs.c malloc.c \ 12 | printf.c strtoul.c remove.c getenv.c getchar.c snprintf.c vfprintf.c fclose.c \ 13 | fscanf.c assert.c puts.c strchr.c asctime.c fread.c strtod.c tmpfile.c ungetc.c \ 14 | memchr.c localtime.c fseek.c strspn.c rename.c exit.c strncpy.c mktime.c strtol.c \ 15 | qsort.c rewind.c strtok.c init_libc.c strcpy.c aligned_alloc.c fprintf.c fgets.c \ 16 | strdup.c ctype.c 17 | 18 | SUBDIRECTORIES += lib/c/src/arch-arm 19 | SUBDIRECTORIES += lib/c/src/sys-baremetal 20 | SUBDIRECTORIES += lib/c/src/sys-baremetal/arch-arm 21 | 22 | objs-y += init_libc.o malloc.o strlen.o strcpy.o printf.o memset.o realloc.o 23 | objs-y += fputc.o memcpy.o vfprintf.o fprintf.o format.o assert.o 24 | objs-y += sprintf.o 25 | 26 | obj-y += $(patsubst %, lib/c/src/%, ${objs-y}) 27 | -------------------------------------------------------------------------------- /lib/c/src/aligned_alloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void * 5 | aligned_alloc(size_t nbytes, size_t alignment) 6 | { 7 | void *p; 8 | void **aligned_p; 9 | int offset = alignment - 1 + sizeof(void *); 10 | 11 | p = (void *) malloc (nbytes + offset); 12 | if (p == NULL) { 13 | return p; 14 | } 15 | 16 | aligned_p = (void **)(((size_t)(p) + offset) & ~(alignment - 1)); 17 | aligned_p[-1] = p; 18 | 19 | return aligned_p; 20 | } 21 | 22 | void 23 | aligned_free(void *p) 24 | { 25 | free(((void**)p)[-1]); 26 | } 27 | -------------------------------------------------------------------------------- /lib/c/src/arch-arm/Makefile: -------------------------------------------------------------------------------- 1 | objs-y := 2 | 3 | objs-y += aeabi_uidivmod.o 4 | objs-y += aeabi_uldivmod.o 5 | objs-y += divmodsi4.o 6 | objs-y += jmp.o 7 | objs-y += udivmodsi4.o 8 | objs-y += aeabi_div0.o 9 | objs-y += udivmoddi4.o 10 | 11 | obj-y += $(patsubst %, lib/c/src/arch-arm/%, ${objs-y}) 12 | -------------------------------------------------------------------------------- /lib/c/src/arch-arm/aeabi_div0.c: -------------------------------------------------------------------------------- 1 | /* ===-- aeabi_div0.c - ARM Runtime ABI support routines for compiler-rt ---=== 2 | * 3 | * The LLVM Compiler Infrastructure 4 | * 5 | * This file is dual licensed under the MIT and the University of Illinois Open 6 | * Source Licenses. See LICENSE.TXT for details. 7 | * 8 | * ===----------------------------------------------------------------------=== 9 | * 10 | * This file implements the division by zero helper routines as specified by the 11 | * Run-time ABI for the ARM Architecture. 12 | * 13 | * ===----------------------------------------------------------------------=== 14 | */ 15 | 16 | /* 17 | * RTABI 4.3.2 - Division by zero 18 | * 19 | * The *div0 functions: 20 | * - Return the value passed to them as a parameter 21 | * - Or, return a fixed value defined by the execution environment (such as 0) 22 | * - Or, raise a signal (often SIGFPE) or throw an exception, and do not return 23 | * 24 | * An application may provide its own implementations of the *div0 functions to 25 | * for a particular behaviour from the *div and *divmod functions called out of 26 | * line. 27 | */ 28 | 29 | /* provide an unused declaration to pacify pendantic compilation */ 30 | extern unsigned char declaration; 31 | 32 | #if defined(__ARM_EABI__) 33 | int __attribute__((weak)) __attribute__((visibility("hidden"))) 34 | __aeabi_idiv0(int return_value) 35 | { 36 | return return_value; 37 | } 38 | 39 | long long __attribute__((weak)) __attribute__((visibility("hidden"))) 40 | __aeabi_ldiv0(long long return_value) 41 | { 42 | return return_value; 43 | } 44 | #endif 45 | 46 | -------------------------------------------------------------------------------- /lib/c/src/arch-arm/aeabi_uidivmod.S: -------------------------------------------------------------------------------- 1 | //===-- aeabi_uidivmod.S - EABI uidivmod implementation -------------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is dual licensed under the MIT and the University of Illinois Open 6 | // Source Licenses. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | 10 | #include "assembly.h" 11 | 12 | // struct { unsigned quot, unsigned rem} 13 | // __aeabi_uidivmod(unsigned numerator, unsigned denominator) { 14 | // unsigned rem, quot; 15 | // quot = __udivmodsi4(numerator, denominator, &rem); 16 | // return {quot, rem}; 17 | // } 18 | 19 | .syntax unified 20 | .p2align 2 21 | DEFINE_COMPILERRT_FUNCTION(__aeabi_uidivmod) 22 | push { lr } 23 | sub sp, sp, #4 24 | mov r2, sp 25 | bl SYMBOL_NAME(__udivmodsi4) 26 | ldr r1, [sp] 27 | add sp, sp, #4 28 | pop { pc } 29 | END_COMPILERRT_FUNCTION(__aeabi_uidivmod) 30 | -------------------------------------------------------------------------------- /lib/c/src/arch-arm/aeabi_uldivmod.S: -------------------------------------------------------------------------------- 1 | //===-- aeabi_uldivmod.S - EABI uldivmod implementation -------------------===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is dual licensed under the MIT and the University of Illinois Open 6 | // Source Licenses. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | 10 | #include "assembly.h" 11 | 12 | // struct { uint64_t quot, uint64_t rem} 13 | // __aeabi_uldivmod(uint64_t numerator, uint64_t denominator) { 14 | // uint64_t rem, quot; 15 | // quot = __udivmoddi4(numerator, denominator, &rem); 16 | // return {quot, rem}; 17 | // } 18 | 19 | .syntax unified 20 | .p2align 2 21 | DEFINE_COMPILERRT_FUNCTION(__aeabi_uldivmod) 22 | push {r11, lr} 23 | sub sp, sp, #16 24 | add r12, sp, #8 25 | str r12, [sp] 26 | bl SYMBOL_NAME(__udivmoddi4) 27 | ldr r2, [sp, #8] 28 | ldr r3, [sp, #12] 29 | add sp, sp, #16 30 | pop {r11, pc} 31 | END_COMPILERRT_FUNCTION(__aeabi_uldivmod) 32 | -------------------------------------------------------------------------------- /lib/c/src/arch-arm/divmodsi4.S: -------------------------------------------------------------------------------- 1 | /*===-- divmodsi4.S - 32-bit signed integer divide and modulus ------------===// 2 | * 3 | * The LLVM Compiler Infrastructure 4 | * 5 | * This file is dual licensed under the MIT and the University of Illinois Open 6 | * Source Licenses. See LICENSE.TXT for details. 7 | * 8 | *===----------------------------------------------------------------------===// 9 | * 10 | * This file implements the __divmodsi4 (32-bit signed integer divide and 11 | * modulus) function for the ARM architecture. A naive digit-by-digit 12 | * computation is employed for simplicity. 13 | * 14 | *===----------------------------------------------------------------------===*/ 15 | 16 | #include "assembly.h" 17 | 18 | #define ESTABLISH_FRAME \ 19 | push {r4-r7, lr} ;\ 20 | add r7, sp, #12 21 | #define CLEAR_FRAME_AND_RETURN \ 22 | pop {r4-r7, pc} 23 | 24 | .syntax unified 25 | .text 26 | #if __ARM_ARCH_ISA_THUMB == 2 27 | .thumb 28 | #endif 29 | 30 | @ int __divmodsi4(int divident, int divisor, int *remainder) 31 | @ Calculate the quotient and remainder of the (signed) division. The return 32 | @ value is the quotient, the remainder is placed in the variable. 33 | 34 | .p2align 3 35 | DEFINE_COMPILERRT_FUNCTION(__divmodsi4) 36 | #if __ARM_ARCH_EXT_IDIV__ 37 | tst r1, r1 38 | beq LOCAL_LABEL(divzero) 39 | mov r3, r0 40 | sdiv r0, r3, r1 41 | mls r1, r0, r1, r3 42 | str r1, [r2] 43 | bx lr 44 | LOCAL_LABEL(divzero): 45 | mov r0, #0 46 | bx lr 47 | #else 48 | ESTABLISH_FRAME 49 | // Set aside the sign of the quotient and modulus, and the address for the 50 | // modulus. 51 | eor r4, r0, r1 52 | mov r5, r0 53 | mov r6, r2 54 | // Take the absolute value of a and b via abs(x) = (x^(x >> 31)) - (x >> 31). 55 | eor ip, r0, r0, asr #31 56 | eor lr, r1, r1, asr #31 57 | sub r0, ip, r0, asr #31 58 | sub r1, lr, r1, asr #31 59 | // Unsigned divmod: 60 | bl SYMBOL_NAME(__udivmodsi4) 61 | // Apply the sign of quotient and modulus 62 | ldr r1, [r6] 63 | eor r0, r0, r4, asr #31 64 | eor r1, r1, r5, asr #31 65 | sub r0, r0, r4, asr #31 66 | sub r1, r1, r5, asr #31 67 | str r1, [r6] 68 | CLEAR_FRAME_AND_RETURN 69 | #endif 70 | END_COMPILERRT_FUNCTION(__divmodsi4) 71 | -------------------------------------------------------------------------------- /lib/c/src/ctype.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmu-embedded/k-hypervisor/7682467e586b2233703874882710f1ac6eb88ff9/lib/c/src/ctype.c -------------------------------------------------------------------------------- /lib/c/src/fputc.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int 4 | fputc(int c, FILE *stream) 5 | { 6 | unsigned char ch = (unsigned char) c; 7 | /* This is where we should do output buffering */ 8 | 9 | lock_stream(stream); 10 | if (stream->write_fn(&ch, stream->current_pos, 1, stream->handle) == 1) { 11 | /* Success */ 12 | stream->current_pos++; 13 | unlock_stream(stream); 14 | return c; 15 | } else { 16 | unlock_stream(stream); 17 | return EOF; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /lib/c/src/init_libc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // The variables for heap should be defined in Linker Script. 5 | extern unsigned int __begin_heap; 6 | extern unsigned int __end_heap; 7 | 8 | void libc_init() 9 | { 10 | __malloc_init(&__begin_heap, &__end_heap); 11 | __libc_putc = (__fputc_p) &serial_putc; 12 | __libc_getc = (__fgetc_p) &serial_getc; 13 | } 14 | -------------------------------------------------------------------------------- /lib/c/src/qsort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | static 7 | void swap(void *base, size_t i, size_t j, size_t size) 8 | { 9 | void *tmp = malloc(size); 10 | 11 | assert(tmp); 12 | 13 | memcpy(tmp, (char*) base + i * size, size); 14 | memmove((char*) base + i * size, (char*) base + j * size, size); 15 | memcpy((char*) base + j * size, tmp, size); 16 | free(tmp); 17 | } 18 | 19 | /* qsort: sort v[left]...v[right] into increasing order */ 20 | void 21 | qsort(void *base, size_t nmemb, size_t size, 22 | int(*compar)(const void *, const void *)) 23 | { 24 | int i, last; 25 | 26 | if (nmemb <= 1) { 27 | return; 28 | } 29 | 30 | swap(base, 0, nmemb / 2, size); 31 | 32 | last = 0; 33 | for (i = 1; i < nmemb; i++) 34 | if (compar((char*) base + (i * size), base) < 0) { 35 | swap(base, i, ++last, size); 36 | } 37 | 38 | swap(base, 0, last, size); 39 | 40 | qsort(base, last, size, compar); 41 | qsort((char*) base + (last + 1) * size, nmemb - last - 1, size, compar); 42 | } 43 | -------------------------------------------------------------------------------- /lib/c/src/realloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * K&R Malloc 3 | * 4 | * System specifc code should implement `more_core' 5 | */ 6 | 7 | #include "k_r_malloc.h" 8 | #include 9 | #include 10 | 11 | void * 12 | realloc(void *ptr, size_t size) 13 | { 14 | Header *bp; 15 | void *new_ptr; 16 | size_t old_size; 17 | 18 | if (ptr == NULL) { 19 | return malloc(size); 20 | } 21 | bp = (Header *) ptr - 1; /* point to block header */ 22 | old_size = sizeof(Header) * (bp->s.size - 1); 23 | new_ptr = malloc(size); 24 | if (new_ptr == NULL) { 25 | return NULL; 26 | } 27 | if (old_size <= size) { 28 | memcpy(new_ptr, ptr, old_size); 29 | } else { 30 | memcpy(new_ptr, ptr, size); 31 | } 32 | free(ptr); 33 | return new_ptr; 34 | } 35 | -------------------------------------------------------------------------------- /lib/c/src/snprintf.c: -------------------------------------------------------------------------------- 1 | /* 2 | Author: Ben Leslie 3 | */ 4 | 5 | #include 6 | #include "format.h" 7 | 8 | #include 9 | 10 | int 11 | snprintf(char *s, size_t size, const char *format, ...) 12 | { 13 | int ret; 14 | va_list ap; 15 | 16 | va_start(ap, format); 17 | ret = vsnprintf(s, size, format, ap); 18 | va_end(ap); 19 | return ret; 20 | } 21 | -------------------------------------------------------------------------------- /lib/c/src/strdup.c: -------------------------------------------------------------------------------- 1 | #define _USE_XOPEN 2 | #include 3 | #include 4 | 5 | char * 6 | strdup(const char *s) 7 | { 8 | int len = strlen(s); 9 | char *d; 10 | d = malloc(len); 11 | if (d == NULL) { 12 | return NULL; 13 | } 14 | strcpy(d, s); 15 | return d; 16 | } 17 | -------------------------------------------------------------------------------- /lib/c/src/sys-baremetal/Makefile: -------------------------------------------------------------------------------- 1 | include ${SOURCE_PATH}/lib/c/src/sys-baremetal/arch-arm/Makefile 2 | 3 | objs-y := 4 | 5 | SUBDIRECTORIES += arch-arm 6 | 7 | objs-y += sys_abort.o 8 | 9 | obj-y += $(patsubst %, lib/c/src/sys-baremetal/%, ${objs-y}) 10 | -------------------------------------------------------------------------------- /lib/c/src/sys-baremetal/arch-arm/Makefile: -------------------------------------------------------------------------------- 1 | objs-y := 2 | 3 | objs-y += sys_fgetc.o 4 | objs-y += sys_fputc.o 5 | objs-y += sys_morecore.o 6 | objs-y += sys_stdio.o 7 | objs-y += sys_tmpfile.o 8 | 9 | obj-y += $(patsubst %, lib/c/src/sys-baremetal/arch-arm/%, ${objs-y}) 10 | -------------------------------------------------------------------------------- /lib/c/src/sys-baremetal/arch-arm/sys_fgetc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | extern int __fgetc(); 6 | /* Put character for khypervisor */ 7 | __fgetc_p __libc_getc; 8 | 9 | int 10 | __fgetc() 11 | { 12 | return (int) __libc_getc; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /lib/c/src/sys-baremetal/arch-arm/sys_stdio.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | int __fputc(int c, FILE *stream); 4 | int __fgetc(); 5 | 6 | static int 7 | ser_out(int c) 8 | { 9 | __fputc(c, 0); 10 | if (c == '\n') { 11 | ser_out('\r'); 12 | } 13 | return 0; 14 | } 15 | 16 | static size_t 17 | __io_write(const void *data, long int position, size_t count, void *handle /*unused*/) 18 | { 19 | size_t i; 20 | const char *real_data = data; 21 | for (i = 0; i < count; i++) { 22 | ser_out(real_data[i]); 23 | } 24 | return count; 25 | } 26 | 27 | static size_t 28 | __io_read(void *data, long int position, size_t count, void *handle /*unused*/) 29 | { 30 | size_t i; 31 | char *real_data = data; 32 | for (i = 0; i < count; i++) { 33 | real_data[i] = __fgetc(); 34 | if (real_data[i] == '\r') { 35 | real_data[i] = '\n'; 36 | break; 37 | } 38 | __fputc(real_data[i], 0); 39 | } 40 | return count; 41 | } 42 | 43 | struct __file __stdin = { 44 | .handle = NULL, 45 | .read_fn = __io_read, 46 | .write_fn = NULL, 47 | .close_fn = NULL, 48 | .eof_fn = NULL, 49 | .buffering_mode = _IONBF, 50 | .buffer = NULL, 51 | .unget_pos = 0, 52 | .current_pos = 0, 53 | .eof = 0 54 | }; 55 | 56 | 57 | struct __file __stdout = { 58 | .handle = NULL, 59 | .read_fn = NULL, 60 | .write_fn = __io_write, 61 | .close_fn = NULL, 62 | .eof_fn = NULL, 63 | .buffering_mode = _IONBF, 64 | .buffer = NULL, 65 | .unget_pos = 0, 66 | .current_pos = 0, 67 | .eof = 0 68 | }; 69 | 70 | 71 | struct __file __stderr = { 72 | .handle = NULL, 73 | .read_fn = NULL, 74 | .write_fn = __io_write, 75 | .close_fn = NULL, 76 | .eof_fn = NULL, 77 | .buffering_mode = _IONBF, 78 | .buffer = NULL, 79 | .unget_pos = 0, 80 | .current_pos = 0, 81 | .eof = 0 82 | }; 83 | 84 | FILE *stdin = &__stdin; 85 | FILE *stdout = &__stdout; 86 | FILE *stderr = &__stderr; 87 | -------------------------------------------------------------------------------- /lib/c/src/sys-baremetal/arch-arm/sys_tmpfile.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | extern FILE * sys_tmpfile(void); 7 | 8 | struct tmp { 9 | long int total_size; 10 | char * buffer; 11 | }; 12 | 13 | static long int 14 | tmp_eof(void *handle) 15 | { 16 | struct tmp *tmp = handle; 17 | return tmp->total_size; 18 | } 19 | 20 | static size_t 21 | tmp_write(const void *data, long int position, size_t count, void *handle) 22 | { 23 | void *tmp_buf; 24 | struct tmp *tmp = handle; 25 | if (position + count > tmp->total_size) { 26 | tmp->total_size = position + count; 27 | tmp_buf = realloc(tmp->buffer, tmp->total_size); 28 | assert(tmp_buf != NULL); 29 | tmp->buffer = tmp_buf; 30 | } 31 | memcpy(&tmp->buffer[position], data, count); 32 | return count; 33 | } 34 | 35 | static size_t 36 | tmp_read(void *data, long int position, size_t count, void *handle) 37 | { 38 | struct tmp *tmp = handle; 39 | if (position + count > tmp->total_size) { 40 | count = tmp->total_size - position; 41 | } 42 | memcpy(data, &tmp->buffer[position], count); 43 | return count; 44 | } 45 | 46 | static int 47 | tmp_close(void *handle) 48 | { 49 | struct tmp *tmp = handle; 50 | free(tmp->buffer); 51 | free(handle); 52 | return 0; 53 | } 54 | 55 | FILE * 56 | sys_tmpfile(void) 57 | { 58 | /* Note: We may want to allocate from a different pool 59 | of memory to minimise this being tramped on a by a 60 | user */ 61 | struct tmp *tmp; 62 | FILE *tmpf; 63 | tmpf = malloc(sizeof(FILE)); 64 | if (tmpf == NULL) { 65 | return NULL; 66 | } 67 | tmp = malloc(sizeof(struct tmp)); 68 | if (tmp == NULL) { 69 | free(tmpf); 70 | return NULL; 71 | } 72 | 73 | tmp->total_size = 0; 74 | tmp->buffer = NULL; 75 | 76 | tmpf->handle = tmp; 77 | tmpf->write_fn = tmp_write; 78 | tmpf->read_fn = tmp_read; 79 | tmpf->close_fn = tmp_close; 80 | tmpf->eof_fn = tmp_eof; 81 | tmpf->current_pos = 0; 82 | tmpf->buffering_mode = _IONBF; 83 | tmpf->buffer = NULL; 84 | tmpf->unget_pos = 0; 85 | tmpf->eof = 0; 86 | #ifdef THREAD_SAFE 87 | mutex_init(&tmpf->mutex); 88 | #endif 89 | 90 | return tmpf; 91 | } 92 | -------------------------------------------------------------------------------- /lib/c/test/fs-bootinfo/data/foo: -------------------------------------------------------------------------------- 1 | Test -------------------------------------------------------------------------------- /lib/c/test/fs-bootinfo/test_fs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "test_libs_c.h" 4 | #include 5 | 6 | START_TEST(open_close_test) 7 | { 8 | FILE *foo = fopen("foo", "r"); 9 | fail_unless(foo != NULL, "Should be able to open foo"); 10 | fail_unless(fclose(foo) == 0, "Should be able to close foo"); 11 | } 12 | END_TEST 13 | 14 | START_TEST(read_test) 15 | { 16 | FILE *foo = fopen("foo", "r"); 17 | char data[4]; 18 | int r; 19 | fail_unless(foo != NULL, "Should be able to open foo"); 20 | r = fread(data, 1, 4, foo); 21 | fail_unless(r == 4, "Should read 4 bytes from foo"); 22 | fail_unless(strncmp(data, "Test", 4) == 0, "Data read should be 'Test'"); 23 | fail_unless(fclose(foo) == 0, "Should be able to close foo"); 24 | } 25 | END_TEST 26 | 27 | START_TEST(partial_read_test) 28 | { 29 | FILE *foo = fopen("foo", "r"); 30 | char data[4]; 31 | int r; 32 | 33 | fail_unless(foo != NULL, "Should be able to open foo"); 34 | 35 | r = fread(data, 1, 2, foo); 36 | fail_unless(r == 2, "Should read 2 bytes from foo"); 37 | fail_unless(strncmp(data, "Te", 2) == 0, "Data read should be 'Te'"); 38 | 39 | r = fread(data, 1, 2, foo); 40 | fail_unless(r == 2, "Should read 2 bytes from foo"); 41 | fail_unless(strncmp(data, "st", 2) == 0, "Data read should be 'st'"); 42 | 43 | r = fread(data, 1, 2, foo); 44 | fail_unless(r == 0, "Should now return 0"); 45 | fail_unless(feof(foo) == 1, "Should now return 0"); 46 | 47 | fail_unless(fclose(foo) == 0, "Should be able to close foo"); 48 | } 49 | END_TEST 50 | 51 | START_TEST(rewind_test) 52 | { 53 | FILE *foo = fopen("foo", "r"); 54 | char data[4]; 55 | int r; 56 | fail_unless(foo != NULL, "Should be able to open foo"); 57 | r = fread(data, 1, 4, foo); 58 | fail_unless(r == 4, "Should read 2 bytes from foo"); 59 | fail_unless(strncmp(data, "Test", 4) == 0, "Data read should be 'Test'"); 60 | 61 | rewind(foo); 62 | 63 | r = fread(data, 1, 4, foo); 64 | fail_unless(r == 4, "Should read 4 bytes from foo"); 65 | fail_unless(strncmp(data, "Test", 4) == 0, "Data read should be 'Test'"); 66 | 67 | r = fread(data, 1, 2, foo); 68 | fail_unless(r == 0, "Should now return 0"); 69 | fail_unless(feof(foo) == 1, "Should now return 0"); 70 | 71 | fail_unless(fclose(foo) == 0, "Should be able to close foo"); 72 | } 73 | END_TEST 74 | 75 | 76 | void 77 | fs_test_init(Suite *suite) 78 | { 79 | TCase *tc; 80 | tc = tcase_create("fopen"); 81 | tcase_add_test(tc, open_close_test); 82 | tcase_add_test(tc, read_test); 83 | tcase_add_test(tc, partial_read_test); 84 | tcase_add_test(tc, rewind_test); 85 | suite_add_tcase(suite, tc); 86 | } 87 | -------------------------------------------------------------------------------- /lib/c/test/fs-null/test_fs.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "test_libs_c.h" 4 | #include 5 | 6 | START_TEST(fopen_test) 7 | { 8 | fail_unless(fopen("foo", "r") == NULL, "Any opened file should return NULL"); 9 | } 10 | END_TEST 11 | 12 | void 13 | fs_test_init(Suite *suite) 14 | { 15 | TCase *tc; 16 | tc = tcase_create("fopen"); 17 | tcase_add_test(tc, fopen_test); 18 | suite_add_tcase(suite, tc); 19 | } 20 | -------------------------------------------------------------------------------- /lib/c/test/test_libs_c.h: -------------------------------------------------------------------------------- 1 | /* Tests for the pthread library. */ 2 | #include 3 | 4 | /* A filesystem tcase is made available */ 5 | void fs_test_init(Suite *); 6 | 7 | Suite *make_test_libs_c_suite(void); 8 | -------------------------------------------------------------------------------- /platform/Kconfig: -------------------------------------------------------------------------------- 1 | config ARCH_NAME 2 | string 3 | default "armv7-a" if ARMV7_VIRT 4 | 5 | config CPU_NAME 6 | string 7 | default "cortex-a15" if CPU_A15 8 | 9 | config TARGET_NAME 10 | string 11 | default "rtsm" if ARCH_VERSATILE 12 | default "lager" if RMOBILE 13 | default "odroidxu" if ARCH_EXYNOS 14 | default "bananapi" if ARCH_SUNXI 15 | -------------------------------------------------------------------------------- /platform/Makefile: -------------------------------------------------------------------------------- 1 | objs-y := 2 | 3 | SUBDIRECTORIES += platform/${TARGET} 4 | 5 | objs-y += interrupt.o 6 | objs-y += guest.o 7 | objs-y += platform.o 8 | 9 | obj-y += $(patsubst %, platform/${TARGET}/%, ${objs-y}) 10 | -------------------------------------------------------------------------------- /platform/bananapi/bananapi.lds.S: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | OUTPUT_FORMAT("elf32-littlearm") 4 | OUTPUT_ARCH(arm) 5 | TARGET(binary) 6 | ENTRY(__start) 7 | 8 | HEAP_SIZE = 0x00010000; 9 | 10 | SECTIONS 11 | { 12 | . = CFG_HYP_START_ADDRESS; 13 | . = ALIGN(4); 14 | .text : 15 | { 16 | *(.text.vector) 17 | *(.text.startup) 18 | *(.text) 19 | __vdev_module_start = .; 20 | *(.vdev_module.init) 21 | __vdev_module_end = .; 22 | } 23 | _end_text = .; 24 | 25 | . = ALIGN(4); 26 | .init : 27 | { 28 | *(.init.head) 29 | *(.init) 30 | *(.init.*) 31 | } 32 | _end_init = ALIGN(4); 33 | 34 | . = ALIGN(4); 35 | .rodata : { 36 | *(.rodata) 37 | } 38 | 39 | . = ALIGN(4); 40 | .data : { 41 | *(.data) 42 | } 43 | 44 | . = ALIGN(0x1000); 45 | PROVIDE(__begin_bss = .); 46 | .bss : { 47 | *(.bss) 48 | . = ALIGN(4); 49 | } 50 | PROVIDE(__end_bss = .); 51 | 52 | . = ALIGN(0x1000); 53 | PROVIDE(__begin_heap = .); 54 | .heap : { 55 | *(.heap) 56 | . = . + HEAP_SIZE; 57 | . = ALIGN(4); 58 | } 59 | PROVIDE(__end_heap = .); 60 | 61 | . = ALIGN(0x1000); 62 | 63 | .stack : { 64 | __start_stack__ = .; 65 | . = . + (HYP_STACK_SIZE * NR_CPUS); 66 | . = ALIGN(4); 67 | __end_stack = .; 68 | } 69 | 70 | . = ALIGN(0x1000); 71 | PROVIDE(__HYP_PGTABLE = .); 72 | .pgtable : { 73 | *(.pgtable) 74 | . = . + 0x805000; 75 | . = ALIGN(4); 76 | } 77 | PROVIDE(__END_HYP_PGTABLE = .); 78 | 79 | . = ALIGN(0x1000); 80 | PROVIDE(__VM_PGTABLE = .); 81 | .vm_pgtable : { 82 | *(.vm_pgtable) 83 | . = . + 0x805000 * CONFIG_NR_VMS; 84 | . = ALIGN(4); 85 | } 86 | PROVIDE(__END_VM_PGTABLE = .); 87 | __end = .; 88 | } 89 | -------------------------------------------------------------------------------- /platform/bananapi/config.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_H__ 2 | #define __CONFIG_H__ 3 | 4 | #define MACHINE_TYPE 4283 5 | #define CFG_CNTFRQ 24000000 6 | 7 | #define HYP_STACK_SIZE 8192 8 | #define NR_CPUS 2 9 | #define BOOTABLE_CPUID (0 << 8) 10 | 11 | /* 12 | * SOC param 13 | */ 14 | #define CFG_GIC_BASE_PA 0x01c80000 15 | #define CFG_GICD_BASE_PA 0x01c81000 16 | #define CFG_GICC_BASE_PA 0x01c82000 17 | 18 | #define NSEC_DIV 1000000000 19 | #define TIMER_RESOLUTION_NS (NSEC_DIV/CFG_CNTFRQ) 20 | 21 | #define MAX_IRQS 1024 22 | 23 | #define CFG_MEMMAP_GUEST_SIZE 0x10000000 24 | 25 | #define CFG_MEMMAP_GUEST0_ATAGS_OFFSET 0x48000000 26 | #define CFG_MEMMAP_GUEST0_OFFSET 0x48000000 27 | 28 | #define CFG_MEMMAP_GUEST1_ATAGS_OFFSET 0x58000000 29 | #define CFG_MEMMAP_GUEST1_OFFSET 0x58000000 30 | 31 | #define CFG_MEMMAP_GUEST2_ATAGS_OFFSET 0x68000000 32 | #define CFG_MEMMAP_GUEST2_OFFSET 0x68000000 33 | 34 | #define CFG_GUEST_ATAGS_START_ADDRESS 0x48000000 35 | 36 | #define CFG_GUEST_START_ADDRESS 0x48000000 37 | 38 | #define CFG_HYP_START_ADDRESS 0xb0000000 39 | 40 | 41 | #endif /* BANANAPI_CONFIG_H */ 42 | -------------------------------------------------------------------------------- /platform/bananapi/guest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "devicetree.h" 4 | 5 | struct memdesc_t *vm_mmap[CONFIG_NR_VMS]; 6 | 7 | void setup_vm_mmap(void) 8 | { 9 | int i; 10 | 11 | for(i = 0; i < CONFIG_NR_VMS; i++) { 12 | vm_mmap[i] = vm_device_md; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /platform/bananapi/interrupt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct irq_hw gic_v2 = { 5 | .init = gic_init, 6 | .enable = gic_enable_irq, 7 | .disable = gic_disable_irq, 8 | .ack = gic_get_irq_number, 9 | .eoi = gic_completion_irq, 10 | .dir = gic_deactivate_irq, 11 | .set_irq_type = gic_configure_irq, 12 | }; 13 | 14 | struct virq_hw vgic_v2 = { 15 | .init = gich_init, 16 | .enable = gich_enable, 17 | .disable = gich_disable, 18 | .forward_pending_irq = gic_inject_pending_irqs, 19 | .forward_irq = virq_inject, 20 | }; 21 | 22 | void set_irqchip_type(void) 23 | { 24 | irq_hw = &gic_v2; 25 | virq_hw = &vgic_v2; 26 | 27 | irq_hw->init(); 28 | virq_hw->init(); 29 | } 30 | -------------------------------------------------------------------------------- /platform/bananapi/platform.c: -------------------------------------------------------------------------------- 1 | #include "platform.h" 2 | #include 3 | #include 4 | 5 | // TODO(wonseok): moved header files from arch/arm to proper dir. 6 | #include "../../arch/arm/paging.h" 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include "../../include/arch/gicv2_bit.h" 15 | 16 | void platform_init() 17 | { 18 | uint32_t gic_base = (uint32_t)(get_periphbase() & 0x000000FFFFFFFFFFULL); 19 | 20 | gic_base = CFG_GIC_BASE_PA; 21 | paging_add_mapping(gic_base + GICD_OFFSET, gic_base + GICD_OFFSET, MT_DEVICE, SZ_4K); 22 | paging_add_mapping(gic_base + GICC_OFFSET, gic_base + GICC_OFFSET, MT_DEVICE, SZ_8K); 23 | 24 | paging_add_mapping(gic_base + GICH_OFFSET, gic_base + GICH_OFFSET, MT_DEVICE, SZ_8K); 25 | paging_add_mapping(gic_base + GICV_OFFSET, gic_base + GICV_OFFSET, MT_DEVICE, SZ_8K); 26 | 27 | // add mapping for serial devices 28 | paging_add_mapping(0x01c28000, 0x01c28000, MT_DEVICE, SZ_1K); 29 | // add mapping for dma 30 | paging_add_mapping(0x01c02000, 0x01c02000, MT_DEVICE, SZ_4K); 31 | 32 | paging_add_mapping(CFG_HYP_START_ADDRESS, CFG_HYP_START_ADDRESS, MT_WRITEBACK_RW_ALLOC, SZ_128M); 33 | } 34 | 35 | void console_init() 36 | { 37 | // TODO(wonseok): add general initialization for console devices. 38 | serial_init(); 39 | } 40 | 41 | #include 42 | 43 | #if defined(CONFIG_DMA_ENGINE) && defined(CONFIG_SUN4I_DMA) 44 | #include 45 | #endif 46 | 47 | void dev_init() 48 | { 49 | // init .text.dev section like vdev. 50 | timer_hw_init(NS_PL2_PTIMER_IRQ); 51 | #if defined(CONFIG_DMA_ENGINE) && defined(CONFIG_SUN4I_DMA) 52 | dma_irq_enable(); 53 | #endif 54 | } 55 | -------------------------------------------------------------------------------- /platform/bananapi/platform.h: -------------------------------------------------------------------------------- 1 | #ifndef __PLATFORM_H__ 2 | #define __PLATFORM_H__ 3 | 4 | void platform_init(); 5 | void console_init(); 6 | void dev_init(); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /platform/config.h: -------------------------------------------------------------------------------- 1 | #ifdef CONFIG_ARCH_VERSATILE 2 | #include "./rtsm/config.h" 3 | #elif CONFIG_RMOBILE 4 | #include "./lager/config.h" 5 | #elif CONFIG_ARCH_EXYNOS 6 | #include "./odroidxu/config.h" 7 | #elif CONFIG_ARCH_SUNXI 8 | #include "./bananapi/config.h" 9 | #endif 10 | -------------------------------------------------------------------------------- /platform/lager/config.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_H__ 2 | #define __CONFIG_H__ 3 | 4 | #define MACHINE_TYPE 4538 5 | #define CFG_CNTFRQ 10000000 6 | 7 | #define HYP_STACK_SIZE 8192 8 | #define NR_CPUS 1 9 | #define BOOTABLE_CPUID (0 << 8) 10 | 11 | /* 12 | * SOC param 13 | */ 14 | #define CFG_GIC_BASE_PA 0xF1000000 15 | #define CFG_GICD_BASE_PA 0xF1001000 16 | #define CFG_GICC_BASE_PA 0xF1002000 17 | 18 | #define NSEC_DIV 1000000000 19 | #define TIMER_RESOLUTION_NS (NSEC_DIV/CFG_CNTFRQ) 20 | 21 | #define MAX_IRQS 1024 22 | 23 | #define CFG_MEMMAP_GUEST_SIZE 0x00100000 24 | 25 | #define CFG_MEMMAP_GUEST0_ATAGS_OFFSET 0x40000000 26 | #define CFG_MEMMAP_GUEST0_OFFSET 0x40500000 27 | 28 | #define CFG_MEMMAP_GUEST1_ATAGS_OFFSET 0x50000000 29 | #define CFG_MEMMAP_GUEST1_OFFSET 0x50500000 30 | 31 | #define CFG_MEMMAP_GUEST2_ATAGS_OFFSET 0x60000000 32 | #define CFG_MEMMAP_GUEST2_OFFSET 0x60500000 33 | 34 | #define CFG_GUEST_ATAGS_START_ADDRESS 0x40f00000 35 | 36 | #define CFG_GUEST_START_ADDRESS 0x40007fc0 37 | 38 | #define CFG_HYP_START_ADDRESS 0x70000000 39 | 40 | 41 | #endif /* LAGER_CONFIG_H */ 42 | -------------------------------------------------------------------------------- /platform/lager/guest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "devicetree.h" 4 | 5 | struct memdesc_t *vm_mmap[CONFIG_NR_VMS]; 6 | 7 | void setup_vm_mmap(void) 8 | { 9 | int i; 10 | 11 | for(i = 0; i < CONFIG_NR_VMS; i++) { 12 | vm_mmap[i] = vm_device_md; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /platform/lager/interrupt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct irq_hw gic_v2 = { 5 | .init = gic_init, 6 | .enable = gic_enable_irq, 7 | .disable = gic_disable_irq, 8 | .ack = gic_get_irq_number, 9 | .eoi = gic_completion_irq, 10 | .dir = gic_deactivate_irq, 11 | .set_irq_type = gic_configure_irq, 12 | }; 13 | 14 | struct virq_hw vgic_v2 = { 15 | .init = gich_init, 16 | .enable = gich_enable, 17 | .disable = gich_disable, 18 | .forward_pending_irq = gic_inject_pending_irqs, 19 | .forward_irq = virq_inject, 20 | }; 21 | 22 | void set_irqchip_type(void) 23 | { 24 | irq_hw = &gic_v2; 25 | virq_hw = &vgic_v2; 26 | 27 | irq_hw->init(); 28 | virq_hw->init(); 29 | } 30 | -------------------------------------------------------------------------------- /platform/lager/lager.lds.S: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | OUTPUT_FORMAT("elf32-littlearm") 4 | OUTPUT_ARCH(arm) 5 | TARGET(binary) 6 | ENTRY(__start) 7 | 8 | HEAP_SIZE = 0x00010000; 9 | 10 | SECTIONS 11 | { 12 | . = CFG_HYP_START_ADDRESS; 13 | . = ALIGN(4); 14 | .text : 15 | { 16 | *(.text.vector) 17 | *(.text.startup) 18 | *(.text) 19 | __vdev_module_start = .; 20 | *(.vdev_module.init) 21 | __vdev_module_end = .; 22 | } 23 | _end_text = .; 24 | 25 | . = ALIGN(4); 26 | .init : 27 | { 28 | *(.init.head) 29 | *(.init) 30 | *(.init.*) 31 | } 32 | _end_init = ALIGN(4); 33 | 34 | . = ALIGN(4); 35 | .rodata : { 36 | *(.rodata) 37 | } 38 | 39 | . = ALIGN(4); 40 | .data : { 41 | *(.data) 42 | } 43 | 44 | . = ALIGN(0x1000); 45 | PROVIDE(__begin_bss = .); 46 | .bss : { 47 | *(.bss) 48 | . = ALIGN(4); 49 | } 50 | PROVIDE(__end_bss = .); 51 | 52 | . = ALIGN(0x1000); 53 | PROVIDE(__begin_heap = .); 54 | .heap : { 55 | *(.heap) 56 | . = . + HEAP_SIZE; 57 | . = ALIGN(4); 58 | } 59 | PROVIDE(__end_heap = .); 60 | 61 | . = ALIGN(0x1000); 62 | 63 | .stack : { 64 | __start_stack__ = .; 65 | . = . + (HYP_STACK_SIZE * NR_CPUS); 66 | . = ALIGN(4); 67 | __end_stack = .; 68 | } 69 | 70 | . = ALIGN(0x1000); 71 | PROVIDE(__HYP_PGTABLE = .); 72 | .pgtable : { 73 | *(.pgtable) 74 | . = . + 0x805000; 75 | . = ALIGN(4); 76 | } 77 | PROVIDE(__END_HYP_PGTABLE = .); 78 | 79 | . = ALIGN(0x1000); 80 | PROVIDE(__VM_PGTABLE = .); 81 | .vm_pgtable : { 82 | *(.vm_pgtable) 83 | . = . + 0x805000 * CONFIG_NR_VMS; 84 | . = ALIGN(4); 85 | } 86 | PROVIDE(__END_VM_PGTABLE = .); 87 | __end = .; 88 | } 89 | -------------------------------------------------------------------------------- /platform/lager/platform.c: -------------------------------------------------------------------------------- 1 | #include "platform.h" 2 | #include 3 | #include 4 | 5 | // TODO(wonseok): moved header files from arch/arm to proper dir. 6 | #include "../../arch/arm/paging.h" 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include "../../include/arch/gicv2_bit.h" 15 | 16 | void platform_init() 17 | { 18 | uint32_t gic_base = (uint32_t)(get_periphbase() & 0x000000FFFFFFFFFFULL); 19 | 20 | gic_base = CFG_GIC_BASE_PA; 21 | paging_add_mapping(gic_base + GICD_OFFSET, gic_base + GICD_OFFSET, MT_DEVICE, SZ_4K); 22 | paging_add_mapping(gic_base + GICC_OFFSET, gic_base + GICC_OFFSET, MT_DEVICE, SZ_8K); 23 | 24 | paging_add_mapping(gic_base + GICH_OFFSET, gic_base + GICH_OFFSET, MT_DEVICE, SZ_4K); 25 | paging_add_mapping(gic_base + GICV_OFFSET, gic_base + GICV_OFFSET, MT_DEVICE, SZ_8K); 26 | 27 | // add mapping for serial devices 28 | paging_add_mapping(0xE6E60000, 0xE6E60000, MT_DEVICE, SZ_64K); 29 | 30 | paging_add_mapping(CFG_HYP_START_ADDRESS, CFG_HYP_START_ADDRESS, MT_WRITEBACK_RW_ALLOC, SZ_128M); 31 | } 32 | 33 | void console_init() 34 | { 35 | // TODO(wonseok): add general initialization for console devices. 36 | serial_init(); 37 | } 38 | #include 39 | 40 | void dev_init() 41 | { 42 | // init .text.dev section like vdev. 43 | timer_hw_init(NS_PL2_PTIMER_IRQ); 44 | } 45 | -------------------------------------------------------------------------------- /platform/lager/platform.h: -------------------------------------------------------------------------------- 1 | #ifndef __PLATFORM_H__ 2 | #define __PLATFORM_H__ 3 | 4 | void platform_init(); 5 | void console_init(); 6 | void dev_init(); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /platform/odroidxu/config.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_H__ 2 | #define __CONFIG_H__ 3 | 4 | #define MACHINE_TYPE 4289 5 | #define CFG_CNTFRQ 100000000 6 | 7 | #define HYP_STACK_SIZE 4096 8 | #define NR_CPUS 2 9 | #define BOOTABLE_CPUID (1 << 8) 10 | 11 | /* 12 | * SOC param 13 | */ 14 | #define CFG_GIC_BASE_PA 0x10480000 15 | #define CFG_GICD_BASE_PA 0x10481000 16 | #define CFG_GICC_BASE_PA 0x10482000 17 | 18 | #define NSEC_DIV 1000000000 19 | #define TIMER_RESOLUTION_NS (NSEC_DIV/CFG_CNTFRQ) 20 | 21 | #define TICKTIME_1MS 1000 22 | #define MAX_IRQS 1024 23 | 24 | #define CFG_MEMMAP_GUEST_SIZE 0x00100000 25 | 26 | #define CFG_MEMMAP_GUEST0_ATAGS_OFFSET 0x44000000 27 | #define CFG_MEMMAP_GUEST0_OFFSET 0x40000000 28 | 29 | #define CFG_MEMMAP_GUEST1_ATAGS_OFFSET 0x50000000 30 | #define CFG_MEMMAP_GUEST1_OFFSET 0x50500000 31 | 32 | #define CFG_MEMMAP_GUEST2_ATAGS_OFFSET 0x60000000 33 | #define CFG_MEMMAP_GUEST2_OFFSET 0x60500000 34 | 35 | #define CFG_GUEST_ATAGS_START_ADDRESS 0x44000000 36 | 37 | #define CFG_GUEST_START_ADDRESS 0x40008000 38 | 39 | #define CFG_HYP_START_ADDRESS 0x70000000 40 | 41 | 42 | #endif /* ODROIDXU_CONFIG_H */ 43 | -------------------------------------------------------------------------------- /platform/odroidxu/guest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "devicetree.h" 4 | 5 | struct memdesc_t *vm_mmap[CONFIG_NR_VMS]; 6 | 7 | void setup_vm_mmap(void) 8 | { 9 | int i; 10 | 11 | for(i = 0; i < CONFIG_NR_VMS; i++) { 12 | vm_mmap[i] = vm_device_md; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /platform/odroidxu/interrupt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct irq_hw gic_v2 = { 5 | .init = gic_init, 6 | .enable = gic_enable_irq, 7 | .disable = gic_disable_irq, 8 | .ack = gic_get_irq_number, 9 | .eoi = gic_completion_irq, 10 | .dir = gic_deactivate_irq, 11 | .set_irq_type = gic_configure_irq, 12 | }; 13 | 14 | struct virq_hw vgic_v2 = { 15 | .init = gich_init, 16 | .enable = gich_enable, 17 | .disable = gich_disable, 18 | .forward_pending_irq = gic_inject_pending_irqs, 19 | .forward_irq = virq_inject, 20 | }; 21 | 22 | void set_irqchip_type(void) 23 | { 24 | irq_hw = &gic_v2; 25 | virq_hw = &vgic_v2; 26 | 27 | irq_hw->init(); 28 | virq_hw->init(); 29 | } 30 | -------------------------------------------------------------------------------- /platform/odroidxu/odroidxu.lds.S: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | OUTPUT_FORMAT("elf32-littlearm") 4 | OUTPUT_ARCH(arm) 5 | TARGET(binary) 6 | ENTRY(__start) 7 | 8 | HEAP_SIZE = 0x00010000; 9 | 10 | SECTIONS 11 | { 12 | . = CFG_HYP_START_ADDRESS; 13 | . = ALIGN(4); 14 | .text : 15 | { 16 | *(.text.vector) 17 | *(.text.startup) 18 | *(.text) 19 | __vdev_module_start = .; 20 | *(.vdev_module.init) 21 | __vdev_module_end = .; 22 | } 23 | _end_text = .; 24 | 25 | . = ALIGN(4); 26 | .init : 27 | { 28 | *(.init.head) 29 | *(.init) 30 | *(.init.*) 31 | } 32 | _end_init = ALIGN(4); 33 | 34 | . = ALIGN(4); 35 | .rodata : { 36 | *(.rodata) 37 | } 38 | 39 | . = ALIGN(4); 40 | .data : { 41 | *(.data) 42 | } 43 | 44 | . = ALIGN(0x1000); 45 | PROVIDE(__begin_bss = .); 46 | .bss : { 47 | *(.bss) 48 | . = ALIGN(4); 49 | } 50 | PROVIDE(__end_bss = .); 51 | 52 | . = ALIGN(0x1000); 53 | PROVIDE(__begin_heap = .); 54 | .heap : { 55 | *(.heap) 56 | . = . + HEAP_SIZE; 57 | . = ALIGN(4); 58 | } 59 | PROVIDE(__end_heap = .); 60 | 61 | . = ALIGN(0x1000); 62 | 63 | .stack : { 64 | __start_stack__ = .; 65 | . = . + (HYP_STACK_SIZE * NR_CPUS); 66 | . = ALIGN(4); 67 | __end_stack = .; 68 | } 69 | 70 | . = ALIGN(0x1000); 71 | PROVIDE(__HYP_PGTABLE = .); 72 | .pgtable : { 73 | *(.pgtable) 74 | . = . + 0x805000; 75 | . = ALIGN(4); 76 | } 77 | PROVIDE(__END_HYP_PGTABLE = .); 78 | 79 | . = ALIGN(0x1000); 80 | PROVIDE(__VM_PGTABLE = .); 81 | .vm_pgtable : { 82 | *(.vm_pgtable) 83 | . = . + 0x805000 * CONFIG_NR_VMS; 84 | . = ALIGN(4); 85 | } 86 | PROVIDE(__END_VM_PGTABLE = .); 87 | __end = .; 88 | } 89 | -------------------------------------------------------------------------------- /platform/odroidxu/platform.c: -------------------------------------------------------------------------------- 1 | #include "platform.h" 2 | #include 3 | #include 4 | 5 | // TODO(wonseok): moved header files from arch/arm to proper dir. 6 | #include "../../arch/arm/paging.h" 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include "../../include/arch/gicv2_bit.h" 15 | 16 | void platform_init() 17 | { 18 | uint32_t gic_base = (uint32_t)(get_periphbase() & 0x000000FFFFFFFFFFULL); 19 | 20 | gic_base = CFG_GIC_BASE_PA; 21 | paging_add_mapping(gic_base + GICD_OFFSET, gic_base + GICD_OFFSET, MT_DEVICE, SZ_4K); 22 | paging_add_mapping(gic_base + GICC_OFFSET, gic_base + GICC_OFFSET, MT_DEVICE, SZ_8K); 23 | 24 | paging_add_mapping(gic_base + GICH_OFFSET, gic_base + GICH_OFFSET, MT_DEVICE, SZ_4K); 25 | paging_add_mapping(gic_base + GICV_OFFSET, gic_base + GICV_OFFSET, MT_DEVICE, SZ_8K); 26 | 27 | // add mapping for serial devices 28 | paging_add_mapping(0x12c20000, 0x12c20000, MT_DEVICE, SZ_64K); 29 | // add mapping for timer devices 30 | paging_add_mapping(0x101c0000, 0x101c0000, MT_DEVICE, SZ_4K); 31 | 32 | paging_add_mapping(CFG_HYP_START_ADDRESS, CFG_HYP_START_ADDRESS, MT_WRITEBACK_RW_ALLOC, SZ_128M); 33 | } 34 | 35 | void console_init() 36 | { 37 | // TODO(wonseok): add general initialization for console devices. 38 | serial_init(); 39 | } 40 | 41 | #include 42 | #include 43 | 44 | void dev_init() 45 | { 46 | #ifdef CONFIG_MCT 47 | mct_init(); 48 | #endif 49 | timer_hw_init(NS_PL2_PTIMER_IRQ); 50 | // init .text.dev section like vdev. 51 | } 52 | -------------------------------------------------------------------------------- /platform/odroidxu/platform.h: -------------------------------------------------------------------------------- 1 | #ifndef __PLATFORM_H__ 2 | #define __PLATFORM_H__ 3 | 4 | void platform_init(); 5 | void console_init(); 6 | void dev_init(); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /platform/rtsm/config.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_H__ 2 | #define __CONFIG_H__ 3 | 4 | #define MACHINE_TYPE 2272 5 | #define CFG_CNTFRQ 100000000 6 | 7 | #define HYP_STACK_SIZE 4096 8 | #define NR_CPUS 4 9 | 10 | #define BOOTABLE_CPUID (0 << 8) 11 | 12 | // TODO(casionwoo) : CONFIG_VSERIAL setting should be moved to menuconfig 13 | /* 14 | CONFIG_VSERIAL == 0 : Use vdev_serial 15 | CONFIG_VSERIAL == 1 : Not use vdev_serial 16 | */ 17 | #define CONFIG_VSERIAL 1 18 | 19 | // TODO(casionwoo) : CONFIG_LOG_LEVEL setting should be moved to menuconfig 20 | /* 21 | CONFIG_LOG_LEVEL == 0 : Normal printf 22 | CONFIG_LOG_LEVEL == 1 : CPUID prefix + Normal printf 23 | CONFIG_LOG_LEVEL == 2 : CPUID prefix + __func__, __LINE + Normal printf 24 | */ 25 | #define CONFIG_LOG_LEVEL 0 26 | 27 | /* 28 | * SOC param 29 | */ 30 | #define CFG_GIC_BASE_PA 0x2C000000 31 | #define CFG_GICD_BASE_PA 0x2C001000 32 | #define CFG_GICC_BASE_PA 0x2C002000 33 | 34 | #define NSEC_DIV 1000000000 35 | #define TIMER_RESOLUTION_NS (NSEC_DIV/CFG_CNTFRQ) 36 | 37 | #define MAX_IRQS 1024 38 | 39 | #define CFG_MEMMAP_PHYS_START 0x80000000 40 | 41 | #define CFG_MEMMAP_GUEST_SIZE 0x10000000 42 | #define CFG_MEMMAP_GUEST0_ATAGS_OFFSET 0x80000000 43 | #define CFG_MEMMAP_GUEST0_OFFSET 0x80500000 44 | #define CFG_MEMMAP_GUEST1_ATAGS_OFFSET 0x90000000 45 | #define CFG_MEMMAP_GUEST1_OFFSET 0x90500000 46 | #define CFG_MEMMAP_GUEST2_ATAGS_OFFSET 0xA0000000 47 | #define CFG_MEMMAP_GUEST2_OFFSET 0xA0500000 48 | #define CFG_MEMMAP_GUEST3_ATAGS_OFFSET 0xB0000000 49 | #define CFG_MEMMAP_GUEST3_OFFSET 0xB0500000 50 | #define CFG_GUEST_ATAGS_START_ADDRESS 0x80000000 51 | #define CFG_GUEST_START_ADDRESS 0x80500000 52 | 53 | #define CFG_HYP_START_ADDRESS 0xF0000000 54 | 55 | #endif /* RTSM_CONFIG_H */ 56 | -------------------------------------------------------------------------------- /platform/rtsm/interrupt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct irq_hw gic_v2 = { 5 | .init = gic_init, 6 | .enable = gic_enable_irq, 7 | .disable = gic_disable_irq, 8 | .ack = gic_get_irq_number, 9 | .eoi = gic_completion_irq, 10 | .dir = gic_deactivate_irq, 11 | .set_irq_type = gic_configure_irq, 12 | }; 13 | 14 | struct virq_hw vgic_v2 = { 15 | .init = gich_init, 16 | .enable = gich_enable, 17 | .disable = gich_disable, 18 | .forward_pending_irq = gic_inject_pending_irqs, 19 | .forward_irq = virq_inject, 20 | }; 21 | 22 | void set_irqchip_type(void) 23 | { 24 | irq_hw = &gic_v2; 25 | virq_hw = &vgic_v2; 26 | 27 | irq_hw->init(); 28 | virq_hw->init(); 29 | } 30 | -------------------------------------------------------------------------------- /platform/rtsm/platform.c: -------------------------------------------------------------------------------- 1 | #include "platform.h" 2 | #include 3 | #include 4 | #include 5 | 6 | // TODO(wonseok): moved header files from arch/arm to proper dir. 7 | #include "../../arch/arm/paging.h" 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include "../../include/arch/gicv2_bit.h" 15 | 16 | #define CFG_HYP_START_ADDRESS 0xF0000000 17 | void platform_init() 18 | { 19 | uint32_t gic_base = (uint32_t)(get_periphbase() & 0x000000FFFFFFFFFFULL); 20 | gic_base = CFG_GIC_BASE_PA; 21 | 22 | paging_add_mapping(gic_base + GICD_OFFSET, gic_base + GICD_OFFSET, MT_DEVICE, SZ_4K); 23 | paging_add_mapping(gic_base + GICC_OFFSET, gic_base + GICC_OFFSET, MT_DEVICE, SZ_8K); 24 | paging_add_mapping(gic_base + GICH_OFFSET, gic_base + GICH_OFFSET, MT_DEVICE, SZ_4K); 25 | paging_add_mapping(gic_base + GICV_OFFSET, gic_base + GICV_OFFSET, MT_DEVICE, SZ_8K); 26 | 27 | // add mapping for write to sysregs instead of VM 28 | paging_add_mapping(0x1C010000, 0x1C010000, MT_DEVICE, SZ_4K); 29 | 30 | paging_add_mapping(0x1C050000, 0x1C050000, MT_DEVICE, SZ_4K); 31 | 32 | // add mapping for serial devices 33 | paging_add_mapping(0x1C090000, 0x1C090000, MT_DEVICE, SZ_4K); 34 | paging_add_mapping(0x1C0A0000, 0x1C0A0000, MT_DEVICE, SZ_4K); 35 | paging_add_mapping(0x1C0B0000, 0x1C0B0000, MT_DEVICE, SZ_4K); 36 | paging_add_mapping(0x1C0C0000, 0x1C0C0000, MT_DEVICE, SZ_4K); 37 | 38 | // for SP804 39 | paging_add_mapping(0x1C110000, 0x1C110000, MT_DEVICE, SZ_4K); 40 | paging_add_mapping(0x1C120000, 0x1C120000, MT_DEVICE, SZ_4K); 41 | 42 | paging_add_mapping(0xF0000000, CFG_HYP_START_ADDRESS, MT_WRITEBACK_RW_ALLOC, SZ_256M); 43 | paging_add_mapping(0x80000000, 0x80000000, MT_WRITEBACK_RW_ALLOC, SZ_256M); 44 | paging_add_mapping(0x90000000, 0x90000000, MT_WRITEBACK_RW_ALLOC, SZ_256M); 45 | paging_add_mapping(0xA0000000, 0xA0000000, MT_WRITEBACK_RW_ALLOC, SZ_256M); 46 | paging_add_mapping(0xB0000000, 0xB0000000, MT_WRITEBACK_RW_ALLOC, SZ_256M); 47 | } 48 | 49 | void console_init() 50 | { 51 | // TODO(wonseok): add general initialization for console devices. 52 | serial_init(115200, 24000000); 53 | } 54 | 55 | #include 56 | void dev_init() 57 | { 58 | // sp804_enable(); 59 | timer_hw_init(NS_PL2_PTIMER_IRQ); 60 | } 61 | -------------------------------------------------------------------------------- /platform/rtsm/platform.h: -------------------------------------------------------------------------------- 1 | #ifndef __PLATFORM_H__ 2 | #define __PLATFORM_H__ 3 | 4 | void platform_init(); 5 | void console_init(); 6 | void dev_init(); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /platform/rtsm/rtsm.lds.S: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | OUTPUT_FORMAT("elf32-littlearm") 4 | OUTPUT_ARCH(arm) 5 | TARGET(binary) 6 | ENTRY(__start) 7 | 8 | INPUT(../guestimages/guest0.bin) 9 | INPUT(../guestimages/guest1.bin) 10 | INPUT(../guestimages/guest2.bin) 11 | INPUT(../guestimages/guest3.bin) 12 | 13 | HEAP_SIZE = 0x04000000; 14 | 15 | SECTIONS 16 | { 17 | . = CFG_MEMMAP_PHYS_START; 18 | /* Guest 0 */ 19 | . = CFG_MEMMAP_GUEST0_ATAGS_OFFSET; 20 | . = CFG_MEMMAP_GUEST0_OFFSET; 21 | _guest0_bin_start = .; 22 | .guest0 : { ../guestimages/guest0.bin} 23 | _guest0_bin_end = .; 24 | 25 | . = ALIGN(4); 26 | 27 | /* Guest 1*/ 28 | . = CFG_MEMMAP_GUEST1_ATAGS_OFFSET; 29 | . = CFG_MEMMAP_GUEST1_OFFSET; 30 | _guest1_bin_start = .; 31 | .guest1 : { ../guestimages/guest1.bin } 32 | _guest1_bin_end = .; 33 | 34 | . = ALIGN(4); 35 | 36 | /* Guest 2 */ 37 | . = CFG_MEMMAP_GUEST2_ATAGS_OFFSET; 38 | . = CFG_MEMMAP_GUEST2_OFFSET; 39 | _guest2_bin_start = .; 40 | .guest2 : { ../guestimages/guest2.bin } 41 | _guest2_bin_end = .; 42 | 43 | . = ALIGN(4); 44 | 45 | /* Guest 3 */ 46 | . = CFG_MEMMAP_GUEST3_ATAGS_OFFSET; 47 | . = CFG_MEMMAP_GUEST3_OFFSET; 48 | _guest3_bin_start = .; 49 | .guest3 : { ../guestimages/guest3.bin } 50 | _guest3_bin_end = .; 51 | 52 | . = CFG_HYP_START_ADDRESS; 53 | . = ALIGN(4); 54 | .text : 55 | { 56 | *(.text.vector) 57 | *(.text.startup) 58 | *(.text) 59 | __vdev_module_start = .; 60 | *(.vdev_module.init) 61 | __vdev_module_end = .; 62 | } 63 | _end_text = .; 64 | 65 | . = ALIGN(4); 66 | .init : 67 | { 68 | *(.init.head) 69 | *(.init) 70 | *(.init.*) 71 | } 72 | _end_init = ALIGN(4); 73 | 74 | . = ALIGN(4); 75 | .rodata : { 76 | *(.rodata) 77 | } 78 | 79 | . = ALIGN(4); 80 | .data : { 81 | *(.data) 82 | } 83 | 84 | . = ALIGN(0x1000); 85 | PROVIDE(__begin_bss = .); 86 | .bss : { 87 | *(.bss) 88 | . = ALIGN(4); 89 | } 90 | PROVIDE(__end_bss = .); 91 | 92 | . = ALIGN(0x1000); 93 | PROVIDE(__begin_heap = .); 94 | .heap : { 95 | *(.heap) 96 | . = . + HEAP_SIZE; 97 | . = ALIGN(4); 98 | } 99 | PROVIDE(__end_heap = .); 100 | 101 | . = ALIGN(0x1000); 102 | 103 | .stack : { 104 | __start_stack__ = .; 105 | . = . + (HYP_STACK_SIZE * NR_CPUS); 106 | . = ALIGN(4); 107 | __end_stack = .; 108 | } 109 | 110 | . = ALIGN(0x1000); 111 | PROVIDE(__HYP_PGTABLE = .); 112 | .pgtable : { 113 | *(.pgtable) 114 | . = . + 0x805000; 115 | . = ALIGN(4); 116 | } 117 | PROVIDE(__END_HYP_PGTABLE = .); 118 | 119 | . = ALIGN(0x1000); 120 | PROVIDE(__VM_PGTABLE = .); 121 | .vm_pgtable : { 122 | *(.vm_pgtable) 123 | . = . + 0x805000 * CONFIG_NR_VMS; 124 | . = ALIGN(4); 125 | } 126 | PROVIDE(__END_VM_PGTABLE = .); 127 | __end = .; 128 | } 129 | -------------------------------------------------------------------------------- /scripts/Makefile.build: -------------------------------------------------------------------------------- 1 | # ========================================================================== 2 | # Building 3 | # ========================================================================== 4 | 5 | src := $(obj) 6 | 7 | PHONY := __build 8 | __build: 9 | 10 | # Read .config if it exist, otherwise ignore 11 | -include .config 12 | 13 | include scripts/Kbuild.include 14 | 15 | # The filename Kbuild has precedence over Makefile 16 | kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) 17 | include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile) 18 | 19 | always := $(addprefix $(obj)/,$(always)) 20 | 21 | ifdef host-progs 22 | ifneq ($(hostprogs-y),$(host-progs)) 23 | $(warning kbuild: $(obj)/Makefile - Usage of host-progs is deprecated. Please replace with hostprogs-y!) 24 | hostprogs-y += $(host-progs) 25 | endif 26 | endif 27 | 28 | # Do not include host rules unles needed 29 | ifneq ($(hostprogs-y)$(hostprogs-m),) 30 | include scripts/Makefile.host 31 | endif 32 | 33 | 34 | 35 | 36 | # We keep a list of all modules in $(MODVERDIR) 37 | 38 | __build: $(always) 39 | 40 | # Add FORCE to the prequisites of a target to force it to be always rebuilt. 41 | # --------------------------------------------------------------------------- 42 | 43 | PHONY += FORCE 44 | 45 | FORCE: 46 | 47 | # Read all saved command lines and dependencies for the $(targets) we 48 | # may be building above, using $(if_changed{,_dep}). As an 49 | # optimization, we don't need to read them if the target does not 50 | # exist, we will rebuild anyway in that case. 51 | 52 | targets := $(wildcard $(sort $(targets))) 53 | cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) 54 | 55 | ifneq ($(cmd_files),) 56 | include $(cmd_files) 57 | endif 58 | 59 | 60 | # Declare the contents of the .PHONY variable as phony. We keep that 61 | # information in a variable se we can use it in if_changed and friends. 62 | 63 | .PHONY: $(PHONY) 64 | -------------------------------------------------------------------------------- /scripts/basic/Makefile: -------------------------------------------------------------------------------- 1 | ### 2 | # Makefile.basic list the most basic programs used during the build process. 3 | # The programs listed herein is what is needed to do the basic stuff, 4 | # such as splitting .config and fix dependency file. 5 | # This initial step is needed to avoid files to be recompiled 6 | # when configuration changes (which is what happens when 7 | # .config is included by main Makefile. 8 | # --------------------------------------------------------------------------- 9 | # fixdep: Used to generate dependency information during build process 10 | # split-include: Divide all config symbols up in a number of files in 11 | # include/config/... 12 | # docproc: Used in Documentation/docbook 13 | 14 | hostprogs-y := fixdep split-include docproc 15 | always := $(hostprogs-y) 16 | 17 | # fixdep is needed to compile other host programs 18 | $(addprefix $(obj)/,$(filter-out fixdep,$(always))): $(obj)/fixdep 19 | -------------------------------------------------------------------------------- /scripts/basic/docproc.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmu-embedded/k-hypervisor/7682467e586b2233703874882710f1ac6eb88ff9/scripts/basic/docproc.c -------------------------------------------------------------------------------- /scripts/defconfig: -------------------------------------------------------------------------------- 1 | # 2 | # Example Menuconfig 3 | # 4 | CONFIG_String_Example="abcdef" 5 | CONFIG_INT_Example=0 6 | CONFIG_Bool_1_Example=y 7 | # CONFIG_Bool_2_Example is not set 8 | CONFIG_Depend_1_example=y 9 | CONFIG_Depend_2_example=y 10 | CONFIG_OPTION_1=y 11 | # CONFIG_OPTION_2 is not set 12 | # CONFIG_OPTION_3 is not set 13 | 14 | # 15 | # Applets 16 | # 17 | -------------------------------------------------------------------------------- /scripts/kconfig/POTFILES.in: -------------------------------------------------------------------------------- 1 | scripts/kconfig/mconf.c 2 | scripts/kconfig/conf.c 3 | scripts/kconfig/confdata.c 4 | scripts/kconfig/gconf.c 5 | scripts/kconfig/qconf.cc 6 | -------------------------------------------------------------------------------- /scripts/kconfig/check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Needed for systems without gettext 3 | $* -xc -o /dev/null - > /dev/null 2>&1 << EOF 4 | #include 5 | int main() 6 | { 7 | gettext(""); 8 | return 0; 9 | } 10 | EOF 11 | if [ ! "$?" -eq "0" ]; then 12 | echo -DKBUILD_NO_NLS; 13 | fi 14 | 15 | -------------------------------------------------------------------------------- /scripts/kconfig/kconfig_load.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "lkc.h" 6 | 7 | #define P(name,type,arg) type (*name ## _p) arg 8 | #include "lkc_proto.h" 9 | #undef P 10 | 11 | void kconfig_load(void) 12 | { 13 | void *handle; 14 | char *error; 15 | 16 | handle = dlopen("./libkconfig.so", RTLD_LAZY); 17 | if (!handle) { 18 | handle = dlopen("./scripts/kconfig/libkconfig.so", RTLD_LAZY); 19 | if (!handle) { 20 | fprintf(stderr, "%s\n", dlerror()); 21 | exit(1); 22 | } 23 | } 24 | 25 | #define P(name,type,arg) \ 26 | { \ 27 | name ## _p = dlsym(handle, #name); \ 28 | if ((error = dlerror())) { \ 29 | fprintf(stderr, "%s\n", error); \ 30 | exit(1); \ 31 | } \ 32 | } 33 | #include "lkc_proto.h" 34 | #undef P 35 | } 36 | -------------------------------------------------------------------------------- /scripts/kconfig/lkc_proto.h: -------------------------------------------------------------------------------- 1 | 2 | /* confdata.c */ 3 | P(conf_parse, void, (const char *name)); 4 | P(conf_read, int, (const char *name)); 5 | P(conf_read_simple, int, (const char *name)); 6 | P(conf_write, int, (const char *name)); 7 | 8 | /* menu.c */ 9 | P(rootmenu, struct menu,); 10 | 11 | P(menu_is_visible, bool, (struct menu *menu)); 12 | P(menu_get_prompt, const char *, (struct menu *menu)); 13 | P(menu_get_root_menu, struct menu *, (struct menu *menu)); 14 | P(menu_get_parent_menu, struct menu *, (struct menu *menu)); 15 | 16 | /* symbol.c */ 17 | P(symbol_hash, struct symbol *, [SYMBOL_HASHSIZE]); 18 | P(sym_change_count, int,); 19 | 20 | P(sym_lookup, struct symbol *, (const char *name, int isconst)); 21 | P(sym_find, struct symbol *, (const char *name)); 22 | P(sym_re_search, struct symbol **, (const char *pattern)); 23 | P(sym_type_name, const char *, (enum symbol_type type)); 24 | P(sym_calc_value, void, (struct symbol *sym)); 25 | P(sym_get_type, enum symbol_type, (struct symbol *sym)); 26 | P(sym_tristate_within_range, bool, (struct symbol *sym, tristate tri)); 27 | P(sym_set_tristate_value, bool, (struct symbol *sym, tristate tri)); 28 | P(sym_toggle_tristate_value, tristate, (struct symbol *sym)); 29 | P(sym_string_valid, bool, (struct symbol *sym, const char *newval)); 30 | P(sym_string_within_range, bool, (struct symbol *sym, const char *str)); 31 | P(sym_set_string_value, bool, (struct symbol *sym, const char *newval)); 32 | P(sym_is_changable, bool, (struct symbol *sym)); 33 | P(sym_get_choice_prop, struct property *, (struct symbol *sym)); 34 | P(sym_get_default_prop, struct property *, (struct symbol *sym)); 35 | P(sym_get_string_value, const char *, (struct symbol *sym)); 36 | 37 | P(prop_get_type_name, const char *, (enum prop_type type)); 38 | 39 | /* expr.c */ 40 | P(expr_compare_type, int, (enum expr_type t1, enum expr_type t2)); 41 | P(expr_print, void, (struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken)); 42 | -------------------------------------------------------------------------------- /scripts/kconfig/lxdialog/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile to build lxdialog package 2 | # 3 | 4 | check-lxdialog := $(srctree)/$(src)/check-lxdialog.sh 5 | 6 | # Use reursively expanded variables so we do not call gcc unless 7 | # we really need to do so. (Do not call gcc as part of make mrproper) 8 | HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) 9 | HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) 10 | 11 | HOST_EXTRACFLAGS += -DLOCALE 12 | 13 | PHONY += dochecklxdialog 14 | $(obj)/dochecklxdialog: 15 | $(Q)$(CONFIG_SHELL) $(check-lxdialog) -check $(HOSTCC) $(HOST_EXTRACFLAGS) $(HOST_LOADLIBES) 16 | 17 | hostprogs-y := lxdialog 18 | always := $(hostprogs-y) dochecklxdialog 19 | 20 | lxdialog-objs := checklist.o menubox.o textbox.o yesno.o inputbox.o \ 21 | util.o lxdialog.o msgbox.o 22 | -------------------------------------------------------------------------------- /scripts/kconfig/lxdialog/check-lxdialog.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Check ncurses compatibility 3 | 4 | # What library to link 5 | ldflags() 6 | { 7 | for ext in so a dylib ; do 8 | for lib in ncursesw ncurses curses ; do 9 | $cc -print-file-name=lib${lib}.${ext} | grep -q / 10 | if [ $? -eq 0 ]; then 11 | echo "-l${lib}" 12 | exit 13 | fi 14 | done 15 | done 16 | exit 1 17 | } 18 | 19 | # Where is ncurses.h? 20 | ccflags() 21 | { 22 | if [ -f /usr/include/ncurses/ncurses.h ]; then 23 | echo '-I/usr/include/ncurses -DCURSES_LOC=""' 24 | elif [ -f /usr/include/ncurses/curses.h ]; then 25 | echo '-I/usr/include/ncurses -DCURSES_LOC=""' 26 | elif [ -f /usr/include/ncurses.h ]; then 27 | echo '-DCURSES_LOC=""' 28 | else 29 | echo '-DCURSES_LOC=""' 30 | fi 31 | } 32 | 33 | # Temp file, try to clean up after us 34 | tmp=.lxdialog.tmp 35 | trap "rm -f $tmp" 0 1 2 3 15 36 | 37 | # Check if we can link to ncurses 38 | check() { 39 | $cc -xc - -o $tmp 2>/dev/null <<'EOF' 40 | #include CURSES_LOC 41 | main() {} 42 | EOF 43 | if [ $? != 0 ]; then 44 | echo " *** Unable to find the ncurses libraries or the" 1>&2 45 | echo " *** required header files." 1>&2 46 | echo " *** 'make menuconfig' requires the ncurses libraries." 1>&2 47 | echo " *** " 1>&2 48 | echo " *** Install ncurses (ncurses-devel) and try again." 1>&2 49 | echo " *** " 1>&2 50 | exit 1 51 | fi 52 | } 53 | 54 | usage() { 55 | printf "Usage: $0 [-check compiler options|-header|-library]\n" 56 | } 57 | 58 | if [ $# -eq 0 ]; then 59 | usage 60 | exit 1 61 | fi 62 | 63 | cc="" 64 | case "$1" in 65 | "-check") 66 | shift 67 | cc="$@" 68 | check 69 | ;; 70 | "-ccflags") 71 | ccflags 72 | ;; 73 | "-ldflags") 74 | shift 75 | cc="$@" 76 | ldflags 77 | ;; 78 | "*") 79 | usage 80 | exit 1 81 | ;; 82 | esac 83 | -------------------------------------------------------------------------------- /scripts/kconfig/lxdialog/msgbox.c: -------------------------------------------------------------------------------- 1 | /* 2 | * msgbox.c -- implements the message box and info box 3 | * 4 | * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) 5 | * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * as published by the Free Software Foundation; either version 2 10 | * of the License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | */ 21 | 22 | #include "dialog.h" 23 | 24 | /* 25 | * Display a message box. Program will pause and display an "OK" button 26 | * if the parameter 'pause' is non-zero. 27 | */ 28 | int dialog_msgbox(const char *title, const char *prompt, int height, int width, 29 | int pause) 30 | { 31 | int i, x, y, key = 0; 32 | WINDOW *dialog; 33 | 34 | /* center dialog box on screen */ 35 | x = (COLS - width) / 2; 36 | y = (LINES - height) / 2; 37 | 38 | draw_shadow(stdscr, y, x, height, width); 39 | 40 | dialog = newwin(height, width, y, x); 41 | keypad(dialog, TRUE); 42 | 43 | draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); 44 | 45 | print_title(dialog, title, width); 46 | 47 | wattrset(dialog, dialog_attr); 48 | print_autowrap(dialog, prompt, width - 2, 1, 2); 49 | 50 | if (pause) { 51 | wattrset(dialog, border_attr); 52 | mvwaddch(dialog, height - 3, 0, ACS_LTEE); 53 | for (i = 0; i < width - 2; i++) { 54 | waddch(dialog, ACS_HLINE); 55 | } 56 | wattrset(dialog, dialog_attr); 57 | waddch(dialog, ACS_RTEE); 58 | 59 | print_button(dialog, " Ok ", height - 2, width / 2 - 4, TRUE); 60 | 61 | wrefresh(dialog); 62 | while (key != ESC && key != '\n' && key != ' ' && 63 | key != 'O' && key != 'o' && key != 'X' && key != 'x') { 64 | key = wgetch(dialog); 65 | } 66 | } else { 67 | key = '\n'; 68 | wrefresh(dialog); 69 | } 70 | 71 | delwin(dialog); 72 | return key == ESC ? -1 : 0; 73 | } 74 | -------------------------------------------------------------------------------- /scripts/kconfig/lxdialog/yesno.c: -------------------------------------------------------------------------------- 1 | /* 2 | * yesno.c -- implements the yes/no box 3 | * 4 | * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) 5 | * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) 6 | * 7 | * This program is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU General Public License 9 | * as published by the Free Software Foundation; either version 2 10 | * of the License, or (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | */ 21 | 22 | #include "dialog.h" 23 | 24 | /* 25 | * Display termination buttons 26 | */ 27 | static void print_buttons(WINDOW * dialog, int height, int width, int selected) 28 | { 29 | int x = width / 2 - 10; 30 | int y = height - 2; 31 | 32 | print_button(dialog, " Yes ", y, x, selected == 0); 33 | print_button(dialog, " No ", y, x + 13, selected == 1); 34 | 35 | wmove(dialog, y, x + 1 + 13 * selected); 36 | wrefresh(dialog); 37 | } 38 | 39 | /* 40 | * Display a dialog box with two buttons - Yes and No 41 | */ 42 | int dialog_yesno(const char *title, const char *prompt, int height, int width) 43 | { 44 | int i, x, y, key = 0, button = 0; 45 | WINDOW *dialog; 46 | 47 | /* center dialog box on screen */ 48 | x = (COLS - width) / 2; 49 | y = (LINES - height) / 2; 50 | 51 | draw_shadow(stdscr, y, x, height, width); 52 | 53 | dialog = newwin(height, width, y, x); 54 | keypad(dialog, TRUE); 55 | 56 | draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); 57 | wattrset(dialog, border_attr); 58 | mvwaddch(dialog, height - 3, 0, ACS_LTEE); 59 | for (i = 0; i < width - 2; i++) { 60 | waddch(dialog, ACS_HLINE); 61 | } 62 | wattrset(dialog, dialog_attr); 63 | waddch(dialog, ACS_RTEE); 64 | 65 | print_title(dialog, title, width); 66 | 67 | wattrset(dialog, dialog_attr); 68 | print_autowrap(dialog, prompt, width - 2, 1, 3); 69 | 70 | print_buttons(dialog, height, width, 0); 71 | 72 | while (key != ESC) { 73 | key = wgetch(dialog); 74 | switch (key) { 75 | case 'Y': 76 | case 'y': 77 | delwin(dialog); 78 | return 0; 79 | case 'N': 80 | case 'n': 81 | delwin(dialog); 82 | return 1; 83 | 84 | case TAB: 85 | case KEY_LEFT: 86 | case KEY_RIGHT: 87 | button = ((key == KEY_LEFT ? --button : ++button) < 0) ? 1 : (button > 1 ? 0 : button); 88 | 89 | print_buttons(dialog, height, width, button); 90 | wrefresh(dialog); 91 | break; 92 | case ' ': 93 | case '\n': 94 | delwin(dialog); 95 | return button; 96 | case ESC: 97 | break; 98 | } 99 | } 100 | 101 | delwin(dialog); 102 | return -1; /* ESC pressed */ 103 | } 104 | -------------------------------------------------------------------------------- /scripts/kconfig/util.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2002-2005 Roman Zippel 3 | * Copyright (C) 2002-2005 Sam Ravnborg 4 | * 5 | * Released under the terms of the GNU GPL v2.0. 6 | */ 7 | 8 | #include 9 | #include "lkc.h" 10 | 11 | /* file already present in list? If not add it */ 12 | struct file *file_lookup(const char *name) 13 | { 14 | struct file *file; 15 | 16 | for (file = file_list; file; file = file->next) { 17 | if (!strcmp(name, file->name)) { 18 | return file; 19 | } 20 | } 21 | 22 | file = malloc(sizeof(*file)); 23 | memset(file, 0, sizeof(*file)); 24 | file->name = strdup(name); 25 | file->next = file_list; 26 | file_list = file; 27 | return file; 28 | } 29 | 30 | /* write a dependency file as used by kbuild to track dependencies */ 31 | int file_write_dep(const char *name) 32 | { 33 | struct file *file; 34 | FILE *out; 35 | 36 | if (!name) { 37 | name = ".kconfig.d"; 38 | } 39 | out = fopen("..config.tmp", "w"); 40 | if (!out) { 41 | return 1; 42 | } 43 | fprintf(out, "deps_config := \\\n"); 44 | for (file = file_list; file; file = file->next) { 45 | if (file->next) { 46 | fprintf(out, "\t%s \\\n", file->name); 47 | } else { 48 | fprintf(out, "\t%s\n", file->name); 49 | } 50 | } 51 | fprintf(out, 52 | "\n" 53 | ".config include/autoconf.h: $(deps_config)\n" 54 | "\n" 55 | "include/autoconf.h: .config\n" /* bbox */ 56 | "\n" 57 | "$(deps_config):\n"); 58 | fclose(out); 59 | rename("..config.tmp", name); 60 | return 0; 61 | } 62 | 63 | 64 | /* Allocate initial growable sting */ 65 | struct gstr str_new(void) 66 | { 67 | struct gstr gs; 68 | gs.s = malloc(sizeof(char) * 64); 69 | gs.len = 16; 70 | strcpy(gs.s, "\0"); 71 | return gs; 72 | } 73 | 74 | /* Allocate and assign growable string */ 75 | struct gstr str_assign(const char *s) 76 | { 77 | struct gstr gs; 78 | gs.s = strdup(s); 79 | gs.len = strlen(s) + 1; 80 | return gs; 81 | } 82 | 83 | /* Free storage for growable string */ 84 | void str_free(struct gstr *gs) 85 | { 86 | if (gs->s) { 87 | free(gs->s); 88 | } 89 | gs->s = NULL; 90 | gs->len = 0; 91 | } 92 | 93 | /* Append to growable string */ 94 | void str_append(struct gstr *gs, const char *s) 95 | { 96 | size_t l = strlen(gs->s) + strlen(s) + 1; 97 | if (l > gs->len) { 98 | gs->s = realloc(gs->s, l); 99 | gs->len = l; 100 | } 101 | strcat(gs->s, s); 102 | } 103 | 104 | /* Append printf formatted string to growable string */ 105 | void str_printf(struct gstr *gs, const char *fmt, ...) 106 | { 107 | va_list ap; 108 | char s[10000]; /* big enough... */ 109 | va_start(ap, fmt); 110 | vsnprintf(s, sizeof(s), fmt, ap); 111 | str_append(gs, s); 112 | va_end(ap); 113 | } 114 | 115 | /* Retrieve value of growable string */ 116 | const char *str_get(struct gstr *gs) 117 | { 118 | return gs->s; 119 | } 120 | 121 | -------------------------------------------------------------------------------- /scripts/kconfig/zconf.gperf: -------------------------------------------------------------------------------- 1 | %language=ANSI-C 2 | %define hash-function-name kconf_id_hash 3 | %define lookup-function-name kconf_id_lookup 4 | %define string-pool-name kconf_id_strings 5 | %compare-strncmp 6 | %enum 7 | %pic 8 | %struct-type 9 | 10 | struct kconf_id; 11 | 12 | %% 13 | mainmenu, T_MAINMENU, TF_COMMAND 14 | menu, T_MENU, TF_COMMAND 15 | endmenu, T_ENDMENU, TF_COMMAND 16 | source, T_SOURCE, TF_COMMAND 17 | choice, T_CHOICE, TF_COMMAND 18 | endchoice, T_ENDCHOICE, TF_COMMAND 19 | comment, T_COMMENT, TF_COMMAND 20 | config, T_CONFIG, TF_COMMAND 21 | menuconfig, T_MENUCONFIG, TF_COMMAND 22 | help, T_HELP, TF_COMMAND 23 | if, T_IF, TF_COMMAND|TF_PARAM 24 | endif, T_ENDIF, TF_COMMAND 25 | depends, T_DEPENDS, TF_COMMAND 26 | requires, T_REQUIRES, TF_COMMAND 27 | optional, T_OPTIONAL, TF_COMMAND 28 | default, T_DEFAULT, TF_COMMAND, S_UNKNOWN 29 | prompt, T_PROMPT, TF_COMMAND 30 | tristate, T_TYPE, TF_COMMAND, S_TRISTATE 31 | def_tristate, T_DEFAULT, TF_COMMAND, S_TRISTATE 32 | bool, T_TYPE, TF_COMMAND, S_BOOLEAN 33 | boolean, T_TYPE, TF_COMMAND, S_BOOLEAN 34 | def_bool, T_DEFAULT, TF_COMMAND, S_BOOLEAN 35 | def_boolean, T_DEFAULT, TF_COMMAND, S_BOOLEAN 36 | int, T_TYPE, TF_COMMAND, S_INT 37 | hex, T_TYPE, TF_COMMAND, S_HEX 38 | string, T_TYPE, TF_COMMAND, S_STRING 39 | select, T_SELECT, TF_COMMAND 40 | enable, T_SELECT, TF_COMMAND 41 | range, T_RANGE, TF_COMMAND 42 | on, T_ON, TF_PARAM 43 | %% 44 | -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | include ../config.mk 2 | 3 | ROOT_PATH = .. 4 | 5 | SRCS = $(wildcard *.c) 6 | OBJS = $(SRCS:%.c=%.o) 7 | 8 | all: $(OBJS) 9 | 10 | %.o: %.c 11 | $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ 12 | 13 | clean: 14 | #rm -rf $(OBJS_DIR) 15 | 16 | .PHONY: clean 17 | -------------------------------------------------------------------------------- /tests/arch/arm/armv7/armv7_boot_code_here.S: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmu-embedded/k-hypervisor/7682467e586b2233703874882710f1ac6eb88ff9/tests/arch/arm/armv7/armv7_boot_code_here.S -------------------------------------------------------------------------------- /tests/arch/arm/armv8/armv8_boot_code_here.S: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmu-embedded/k-hypervisor/7682467e586b2233703874882710f1ac6eb88ff9/tests/arch/arm/armv8/armv8_boot_code_here.S -------------------------------------------------------------------------------- /tests/core/sched/sched_related_test_code_here.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmu-embedded/k-hypervisor/7682467e586b2233703874882710f1ac6eb88ff9/tests/core/sched/sched_related_test_code_here.c -------------------------------------------------------------------------------- /tests/core/vm/vm_related_test_code_here.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmu-embedded/k-hypervisor/7682467e586b2233703874882710f1ac6eb88ff9/tests/core/vm/vm_related_test_code_here.c -------------------------------------------------------------------------------- /tests/driver/driver_test_code_here.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmu-embedded/k-hypervisor/7682467e586b2233703874882710f1ac6eb88ff9/tests/driver/driver_test_code_here.c -------------------------------------------------------------------------------- /tests/driver/vdev/vdev_test_code_here.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmu-embedded/k-hypervisor/7682467e586b2233703874882710f1ac6eb88ff9/tests/driver/vdev/vdev_test_code_here.c -------------------------------------------------------------------------------- /tests/include/header_file_here.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kmu-embedded/k-hypervisor/7682467e586b2233703874882710f1ac6eb88ff9/tests/include/header_file_here.h -------------------------------------------------------------------------------- /tests/libs/Makefile: -------------------------------------------------------------------------------- 1 | include ../../config.mk 2 | 3 | ROOT_PATH = ../.. 4 | 5 | SRCS = $(wildcard *.c) 6 | OBJS = $(SRCS:.c=%.o) 7 | 8 | all: $(OBJS) 9 | 10 | %.o: %.c 11 | $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ 12 | 13 | clean: 14 | #rm -rf $(OBJS_DIR) 15 | 16 | .PHONY: clean 17 | -------------------------------------------------------------------------------- /tests/libs/test_malloc.c: -------------------------------------------------------------------------------- 1 | #include "test_malloc.h" 2 | #include 3 | #include 4 | #include 5 | 6 | void malloc_simple() 7 | { 8 | void *mem = malloc(213); 9 | printf("mem: %p\n", mem); 10 | free(mem); 11 | } 12 | 13 | void malloc_lots() 14 | { 15 | void *mem[1024]; 16 | int i; 17 | 18 | for (i = 0; i < 1024; i++) { 19 | mem[i] = malloc(123); 20 | } 21 | 22 | for (i--; i >= 0; i--) { 23 | free(mem[i]); 24 | } 25 | } 26 | 27 | void free_simple() 28 | { 29 | /* check we can free NULL */ 30 | free(NULL); 31 | } 32 | 33 | void test_malloc(void) 34 | { 35 | malloc_simple(); 36 | malloc_lots(); 37 | free_simple(); 38 | } 39 | -------------------------------------------------------------------------------- /tests/libs/test_malloc.h: -------------------------------------------------------------------------------- 1 | #ifndef __TEST_MALLOC_H__ 2 | #define __TEST_MALLOC_H__ 3 | 4 | void test_malloc(void); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /tests/tests.c: -------------------------------------------------------------------------------- 1 | #include "tests.h" 2 | 3 | #include "tests_gic_timer.h" 4 | #include "tests_gic_timer.h" 5 | #include "tests_vdev.h" 6 | 7 | hvmm_status_t basic_tests_run(uint32_t tests) 8 | { 9 | hvmm_status_t result = HVMM_STATUS_UNKNOWN_ERROR; 10 | /* Entry point for sequence of test code */ 11 | if (tests & TESTS_ENABLE_GIC_TIMER) { 12 | result = hvmm_tests_gic_timer(); 13 | } 14 | 15 | if (tests & TESTS_ENABLE_VGIC) { 16 | result = hvmm_tests_vgic(); 17 | } 18 | 19 | if (tests & TESTS_VDEV) { 20 | result = hvmm_tests_vdev(); 21 | } 22 | 23 | return result; 24 | } 25 | -------------------------------------------------------------------------------- /tests/tests.h: -------------------------------------------------------------------------------- 1 | #ifndef __TESTS__ 2 | #define __TESTS__ 3 | 4 | #include 5 | #include "../include/types.h" 6 | 7 | /* Enable/Disable Test Items */ 8 | 9 | /* 10 | * GIC/Timer test disabled due to scheduler test does 11 | * context switching based on timer ticks 12 | */ 13 | #define TESTS_ENABLE_GIC_TIMER 0x01 14 | #define TESTS_ENABLE_GIC_PWM_TIMER 0x02 15 | #define TESTS_ENABLE_MALLOC 0x04 16 | #define TESTS_ENABLE_VGIC 0x08 17 | #define TESTS_VDEV 0x10 18 | #define TESTS_ENABLE_SP804 0x20 19 | 20 | hvmm_status_t basic_tests_run(uint32_t tests); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /tests/tests_gic_timer.h: -------------------------------------------------------------------------------- 1 | #ifndef __TESTS_GIC_TIMER_H__ 2 | #define __TESTS_GIC_TIMER_H__ 3 | 4 | #include "../include/types.h" 5 | 6 | hvmm_status_t hvmm_tests_gic_timer(void); 7 | hvmm_status_t hvmm_tests_vgic(void); 8 | hvmm_status_t hvmm_tests_gic_pwm_timer(void); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /tests/tests_vdev.c: -------------------------------------------------------------------------------- 1 | #include "tests_vdev.h" 2 | 3 | #include "../include/types.h" 4 | 5 | //#include 6 | //#include 7 | //#include 8 | //#include 9 | 10 | //#include 11 | 12 | hvmm_status_t hvmm_tests_vdev(void) 13 | { 14 | return HVMM_STATUS_UNKNOWN_ERROR; 15 | } 16 | 17 | hvmm_status_t hvmm_tests_vdev_gicd(void) 18 | { 19 | return HVMM_STATUS_UNKNOWN_ERROR; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /tests/tests_vdev.h: -------------------------------------------------------------------------------- 1 | #ifndef __TESTS_VDEV_H__ 2 | #define __TESTS_VDEV_H__ 3 | #include "../include/types.h" 4 | 5 | hvmm_status_t hvmm_tests_vdev(void); 6 | hvmm_status_t hvmm_tests_vdev_gicd(void); 7 | #endif 8 | -------------------------------------------------------------------------------- /toolchain.mk: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Toolchains 3 | ################################################################################ 4 | ROOT ?= $(CURDIR) 5 | TOOLCHAIN_ROOT ?= $(ROOT)/toolchains 6 | 7 | AARCH32_PATH ?= $(TOOLCHAIN_ROOT)/aarch32 8 | AARCH32_CROSS_COMPILE ?= $(AARCH32_PATH)/bin/arm-linux-gnueabihf- 9 | AARCH32_GCC_VERSION ?= gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf 10 | SRC_AARCH32_GCC ?= https://releases.linaro.org/components/toolchain/binaries/6.2-2016.11/arm-linux-gnueabihf/${AARCH32_GCC_VERSION}.tar.xz 11 | 12 | AARCH64_PATH ?= $(TOOLCHAIN_ROOT)/aarch64 13 | AARCH64_CROSS_COMPILE ?= $(AARCH64_PATH)/bin/aarch64-linux-gnu- 14 | AARCH64_GCC_VERSION ?= gcc-linaro-6.2.1-2016.11-x86_64_aarch64-linux-gnu 15 | SRC_AARCH64_GCC ?= https://releases.linaro.org/components/toolchain/binaries/6.2-2016.11/aarch64-linux-gnu/${AARCH64_GCC_VERSION}.tar.xz 16 | 17 | # Due to relocation error on the 96board edk forest, let's keep the old 18 | # toolchain for a while. 19 | LEGACY_AARCH64_PATH ?= $(TOOLCHAIN_ROOT)/aarch64-legacy 20 | LEGACY_AARCH64_CROSS_COMPILE ?= $(LEGACY_AARCH64_PATH)/bin/aarch64-linux-gnu- 21 | LEGACY_AARCH64_GCC_VERSION ?= gcc-linaro-aarch64-linux-gnu-4.9-2014.08_linux 22 | LEGACY_SRC_AARCH64_GCC ?= https://releases.linaro.org/archive/14.08/components/toolchain/binaries/${LEGACY_AARCH64_GCC_VERSION}.tar.xz 23 | 24 | # Download toolchain macro for saving some repetition 25 | # $(1) is $AARCH.._PATH : i.e., path to the destination 26 | # $(2) is $SRC_AARCH.._GCC : is the downloaded tar.gz file 27 | # $(3) is $.._GCC_VERSION : the name of the file to download 28 | define dltc 29 | @if [ ! -d "$(1)" ]; then \ 30 | mkdir -p $(1); \ 31 | echo "Downloading $(3) ..."; \ 32 | curl -s -L $(2) -o $(TOOLCHAIN_ROOT)/$(3).tar.xz; \ 33 | tar xf $(TOOLCHAIN_ROOT)/$(3).tar.xz -C $(1) --strip-components=1; \ 34 | fi 35 | endef 36 | 37 | .PHONY: toolchains 38 | toolchains: aarch32 aarch64 aarch64-legacy 39 | 40 | .PHONY: aarch32 41 | aarch32: 42 | $(call dltc,$(AARCH32_PATH),$(SRC_AARCH32_GCC),$(AARCH32_GCC_VERSION)) 43 | 44 | .PHONY: aarch64 45 | aarch64: 46 | $(call dltc,$(AARCH64_PATH),$(SRC_AARCH64_GCC),$(AARCH64_GCC_VERSION)) 47 | 48 | .PHONY: aarch64-legacy 49 | aarch64-legacy: 50 | $(call dltc,$(LEGACY_AARCH64_PATH),$(LEGACY_SRC_AARCH64_GCC),$(LEGACY_AARCH64_GCC_VERSION)) 51 | 52 | 53 | --------------------------------------------------------------------------------