├── srcs ├── configs │ ├── base.config │ ├── aarch64.config │ ├── rpi4.config │ ├── imx8qm.config │ └── tx2.config ├── lloader │ ├── loader_aarch32.ld │ ├── loader_aarch64.ld │ ├── loader_riscv64.ld │ ├── riscv64.S │ ├── aarch32.S │ ├── aarch64.S │ ├── Makefile │ └── LICENSE ├── patches │ ├── v6.1 │ │ ├── 0001-compile-for-armv7ve-instead-of-armv7-a.patch │ │ ├── 0002-bao-add-mmap-for-shmem-ipc.patch │ │ └── 0001-add-bao-ipcshmem-driver.patch │ ├── v5.11 │ │ └── 0001-add-bao-ipcshmem-driver.patch │ └── rel_imx_5.4.24_2.1.0 │ │ └── 0001-add-bao-ipcshmem-driver.patch └── devicetrees │ ├── qemu-aarch64-virt │ ├── linux.dts │ └── linux-shmem.dts │ └── zcu104 │ └── linux.dts ├── .github ├── CODEOWNERS ├── CONTRIBUTORS ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── templates │ ├── ISSUE_TEMPLATE │ │ ├── bug_report.md │ │ └── feature_request.md │ └── pull_request_template.md ├── workflows │ └── base.yml └── pull_request_template.md ├── img ├── shmem-IPC.png ├── System_Init.png ├── TF-A_U-boot.png └── single-guest.svg ├── configs ├── baremetal.c ├── baremetal-freeRTOS.c ├── baremetal-freeRTOS-linux.c └── baremetal-freeRTOS-linux-shmem.c └── README.md /srcs/configs/base.config: -------------------------------------------------------------------------------- 1 | CONFIG_BAO_SHMEM=y -------------------------------------------------------------------------------- /srcs/configs/aarch64.config: -------------------------------------------------------------------------------- 1 | CONFIG_DRM=n 2 | -------------------------------------------------------------------------------- /srcs/configs/rpi4.config: -------------------------------------------------------------------------------- 1 | CONFIG_BROADCOM_PHY=y 2 | CONFIG_BCMGENET=y -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Maintainers 2 | * @Diogo21Costa @danielRep @josecm 3 | -------------------------------------------------------------------------------- /srcs/configs/imx8qm.config: -------------------------------------------------------------------------------- 1 | CONFIG_DRM_IMX_DCSS=n 2 | CONFIG_IMX_LCDIF_CORE=n 3 | -------------------------------------------------------------------------------- /img/shmem-IPC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bao-project/bao-helloworld/HEAD/img/shmem-IPC.png -------------------------------------------------------------------------------- /img/System_Init.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bao-project/bao-helloworld/HEAD/img/System_Init.png -------------------------------------------------------------------------------- /img/TF-A_U-boot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bao-project/bao-helloworld/HEAD/img/TF-A_U-boot.png -------------------------------------------------------------------------------- /srcs/configs/tx2.config: -------------------------------------------------------------------------------- 1 | CONFIG_DWMAC_DWC_QOS_ETH=y 2 | CONFIG_STMMAC_ETH=y 3 | CONFIG_STMMAC_PLATFORM=y 4 | CONFIG_BCMGENET=n 5 | CONFIG_BROADCOM_PHY=n 6 | 7 | 8 | -------------------------------------------------------------------------------- /.github/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # File with a list of people who contributed to this repository 2 | # List sorted by first names. 3 | 4 | Diogo Costa -------------------------------------------------------------------------------- /srcs/lloader/loader_aarch32.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | .nloader : { 6 | KEEP(*(.nloader)) 7 | } 8 | 9 | .dtb : ALIGN(8) { 10 | __dtb_start = ABSOLUTE(.); 11 | KEEP(*(.dtb)) 12 | __dtb_end = .; 13 | } 14 | 15 | .linux 0x8000 : { 16 | __linux_start = .; 17 | KEEP(*(.linux)) 18 | __linux_end = .; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /srcs/lloader/loader_aarch64.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | .nloader : { 6 | KEEP(*(.nloader)) 7 | } 8 | 9 | .dtb : ALIGN(8) { 10 | __dtb_start = ABSOLUTE(.); 11 | KEEP(*(.dtb)) 12 | __dtb_end = .; 13 | } 14 | 15 | .linux 0x80000 : { 16 | __linux_start = .; 17 | KEEP(*(.linux)) 18 | __linux_end = .; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /srcs/lloader/loader_riscv64.ld: -------------------------------------------------------------------------------- 1 | ENTRY(_start) 2 | 3 | SECTIONS 4 | { 5 | .nloader : { 6 | KEEP(*(.nloader)) 7 | } 8 | 9 | .linux : ALIGN(0x200000) { 10 | __linux_start = .; 11 | KEEP(*(.linux)) 12 | __linux_end = .; 13 | } 14 | 15 | .dtb : ALIGN(0x200000) { 16 | __dtb_start = ABSOLUTE(.); 17 | KEEP(*(.dtb)) 18 | __dtb_end = .; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /srcs/lloader/riscv64.S: -------------------------------------------------------------------------------- 1 | #define STRINGIFY2(X) #X 2 | #define STRINGIFY(X) STRINGIFY2(X) 3 | 4 | .section .nloader, "a" 5 | .global _start 6 | _start: 7 | 8 | /* boot protocol */ 9 | /* We are expecting hartid in a0 */ 10 | la a1, __dtb_start 11 | 12 | /* jump to linux */ 13 | la t0, __linux_start 14 | jalr t0 15 | j . 16 | 17 | .section .linux, "a" 18 | .incbin STRINGIFY(IMAGE) 19 | 20 | .section .dtb, "a" 21 | .incbin STRINGIFY(DTB) 22 | 23 | -------------------------------------------------------------------------------- /srcs/lloader/aarch32.S: -------------------------------------------------------------------------------- 1 | #define STRINGIFY2(X) #X 2 | #define STRINGIFY(X) STRINGIFY2(X) 3 | 4 | .section .nloader, "a" 5 | .global _start 6 | _start: 7 | 8 | adr r3, _start 9 | 10 | cpsid if 11 | 12 | mrc p15, 0, r1, c1, c0, 0 // sctlr 13 | mov r1, #0x1007 14 | bic r0, r0, r1 15 | mcr p15, 0, r0, c1, c0, 0 // sctlr 16 | 17 | mov r0, #0 18 | mov r1, #0xffffffff 19 | ldr r2, =__dtb_start 20 | add r2, r2, r3 21 | 22 | ldr r4, =__linux_start 23 | add r4, r4, r3 24 | bx r4 25 | 26 | .section .linux, "a" 27 | .incbin STRINGIFY(IMAGE) 28 | 29 | .section .dtb, "a" 30 | .incbin STRINGIFY(DTB) 31 | 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG] add short description of bug" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior : 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Additional context** 27 | Add any other context about the problem here. 28 | -------------------------------------------------------------------------------- /.github/templates/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG] add short description of bug" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior : 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Additional context** 27 | Add any other context about the problem here. 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEAT-REQ] add short description of the feat-request" 5 | labels: feature-request 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/templates/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[FEAT-REQ] add short description of the feat-request" 5 | labels: feature-request 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /srcs/lloader/aarch64.S: -------------------------------------------------------------------------------- 1 | #define STRINGIFY2(X) #X 2 | #define STRINGIFY(X) STRINGIFY2(X) 3 | 4 | .section .nloader, "a" 5 | .global _start 6 | _start: 7 | /* make sure all exceptions disabled */ 8 | msr daifset, 0xf 9 | 10 | /* make sure mmu disable */ 11 | mrs x0, sctlr_el1 12 | mov x1, #1 13 | bic x0, x0, x1 14 | msr sctlr_el1, x0 15 | 16 | isb 17 | 18 | /* boot protocol */ 19 | adr x0, __dtb_start 20 | mov x1, xzr 21 | mov x2, xzr 22 | mov x3, xzr 23 | 24 | /* jump to linux */ 25 | ldr x4, =_start 26 | ldr x5, =__linux_start 27 | sub x4, x5, x4 28 | adr x5, _start 29 | add x5, x5, x4 30 | br x5 31 | 32 | .section .linux, "a" 33 | .incbin STRINGIFY(IMAGE) 34 | 35 | .section .dtb, "a" 36 | .incbin STRINGIFY(DTB) 37 | 38 | -------------------------------------------------------------------------------- /.github/workflows/base.yml: -------------------------------------------------------------------------------- 1 | name: Bao hello world base workflow 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | workflow_dispatch: 8 | 9 | jobs: 10 | 11 | gitlint: 12 | runs-on: ubuntu-latest 13 | container: baoproject/bao:latest 14 | steps: 15 | - uses: actions/checkout@v2 16 | with: 17 | submodules: recursive 18 | fetch-depth: 0 19 | - run: git config --global --add safe.directory $(realpath .) 20 | - if: ${{ github.event_name == 'pull_request' }} 21 | run: make gitlint GITLINT_BASE=${{ github.event.pull_request.base.sha }} 22 | - if: ${{ github.event_name == 'push' }} 23 | run: make gitlint GITLINT_BASE=${{ github.event.before }} 24 | - if: ${{ github.event_name == 'workflow_dispatch' }} 25 | run: make gitlint GITLINT_BASE=HEAD -------------------------------------------------------------------------------- /srcs/lloader/Makefile: -------------------------------------------------------------------------------- 1 | 2 | ifeq ($(and $(IMAGE), $(DTB), $(TARGET), $(ARCH)),) 3 | ifneq ($(MAKECMDGOALS), clean) 4 | $(error Linux image (IMAGE) and/or device tree (DTB) and/or target name \ 5 | (TARGET) and/or architecture (ARCH) not specified) 6 | endif 7 | endif 8 | 9 | ARCH=aarch64 10 | ifeq ($(ARCH), aarch64) 11 | CROSS_COMPILE?=aarch64-none-elf- 12 | OPTIONS=-mcmodel=large 13 | else ifeq ($(ARCH), aarch32) 14 | CROSS_COMPILE?=arm-none-eabi- 15 | OPTIONS=-march=armv7-a 16 | else ifeq ($(ARCH), riscv64) 17 | CROSS_COMPILE?=riscv64-unknown-elf- 18 | OPTIONS=-mcmodel=medany 19 | else 20 | $(error unkown architecture $(ARCH)) 21 | endif 22 | 23 | all: $(TARGET).bin 24 | 25 | clean: 26 | -rm *.elf *.bin 27 | 28 | .PHONY: all clean 29 | 30 | $(TARGET).bin: $(TARGET).elf 31 | $(CROSS_COMPILE)objcopy -S -O binary $(TARGET).elf $(TARGET).bin 32 | 33 | $(TARGET).elf: $(ARCH).S $(IMAGE) $(DTB) loader_$(ARCH).ld 34 | $(CROSS_COMPILE)gcc -Wl,-build-id=none -nostdlib -T loader_$(ARCH).ld\ 35 | -o $(TARGET).elf $(OPTIONS) $(ARCH).S -I. -D IMAGE=$(IMAGE) -D DTB=$(DTB) 36 | -------------------------------------------------------------------------------- /srcs/patches/v6.1/0001-compile-for-armv7ve-instead-of-armv7-a.patch: -------------------------------------------------------------------------------- 1 | From 981d9057119072f485a2320a177c14f52bbc405e Mon Sep 17 00:00:00 2001 2 | From: Jose Martins 3 | Date: Sat, 28 Jan 2023 20:39:50 +0000 4 | Subject: [PATCH] compile for armv7ve instead of armv7-a 5 | 6 | Signed-off-by: Jose Martins 7 | --- 8 | arch/arm/Makefile | 2 +- 9 | 1 file changed, 1 insertion(+), 1 deletion(-) 10 | 11 | diff --git a/arch/arm/Makefile b/arch/arm/Makefile 12 | index c846119c4..10a29fc58 100644 13 | --- a/arch/arm/Makefile 14 | +++ b/arch/arm/Makefile 15 | @@ -64,7 +64,7 @@ KBUILD_CFLAGS += $(call cc-option,-fno-ipa-sra) 16 | # macro, but instead defines a whole series of macros which makes 17 | # testing for a specific architecture or later rather impossible. 18 | arch-$(CONFIG_CPU_32v7M) =-D__LINUX_ARM_ARCH__=7 -march=armv7-m 19 | -arch-$(CONFIG_CPU_32v7) =-D__LINUX_ARM_ARCH__=7 -march=armv7-a 20 | +arch-$(CONFIG_CPU_32v7) =-D__LINUX_ARM_ARCH__=7 -march=armv7ve 21 | arch-$(CONFIG_CPU_32v6) =-D__LINUX_ARM_ARCH__=6 -march=armv6 22 | # Only override the compiler option if ARMv6. The ARMv6K extensions are 23 | # always available in ARMv7 24 | -- 25 | 2.34.1 26 | 27 | -------------------------------------------------------------------------------- /configs/baremetal.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | VM_IMAGE(baremetal_image, XSTR(BAO_WRKDIR_IMGS/guests/baremetal-setup/baremetal.bin)); 4 | 5 | struct config config = { 6 | 7 | CONFIG_HEADER 8 | 9 | .vmlist_size = 1, 10 | .vmlist = { 11 | { 12 | .image = { 13 | .base_addr = 0x50000000, 14 | .load_addr = VM_IMAGE_OFFSET(baremetal_image), 15 | .size = VM_IMAGE_SIZE(baremetal_image) 16 | }, 17 | 18 | .entry = 0x50000000, 19 | 20 | .platform = { 21 | .cpu_num = 4, 22 | 23 | .region_num = 1, 24 | .regions = (struct vm_mem_region[]) { 25 | { 26 | .base = 0x50000000, 27 | .size = 0x4000000 28 | } 29 | }, 30 | 31 | .dev_num = 2, 32 | .devs = (struct vm_dev_region[]) { 33 | { 34 | /* PL011 */ 35 | .pa = 0x9000000, 36 | .va = 0x9000000, 37 | .size = 0x10000, 38 | .interrupt_num = 1, 39 | .interrupts = (irqid_t[]) {33} 40 | }, 41 | { 42 | /* Arch timer interrupt */ 43 | .interrupt_num = 1, 44 | .interrupts = 45 | (irqid_t[]) {27} 46 | } 47 | }, 48 | 49 | .arch = { 50 | .gic = { 51 | .gicd_addr = 0x08000000, 52 | .gicr_addr = 0x080A0000, 53 | } 54 | } 55 | }, 56 | } 57 | }, 58 | }; -------------------------------------------------------------------------------- /srcs/patches/v6.1/0002-bao-add-mmap-for-shmem-ipc.patch: -------------------------------------------------------------------------------- 1 | From 8f4fda3fc844413b2d12623b0665ca66715cc369 Mon Sep 17 00:00:00 2001 2 | From: Clay Chang 3 | Date: Mon, 26 Jun 2023 21:48:16 +0800 4 | Subject: [PATCH 2/2] bao: add mmap for shmem ipc 5 | 6 | Signed-off-by: Clay Chang 7 | --- 8 | drivers/bao/bao-ipcshmem.c | 20 ++++++++++++++++++++ 9 | 1 file changed, 20 insertions(+) 10 | 11 | diff --git a/drivers/bao/bao-ipcshmem.c b/drivers/bao/bao-ipcshmem.c 12 | index daa9903d0..e9cc304ea 100644 13 | --- a/drivers/bao/bao-ipcshmem.c 14 | +++ b/drivers/bao/bao-ipcshmem.c 15 | @@ -21,6 +21,7 @@ 16 | #include 17 | #include 18 | #include 19 | +#include 20 | 21 | #if defined(CONFIG_ARM64) || defined(CONFIG_ARM) 22 | #include 23 | @@ -47,6 +48,7 @@ struct bao_ipcshmem 24 | size_t read_size; 25 | void* write_base; 26 | size_t write_size; 27 | + void* physical_base; 28 | }; 29 | 30 | #ifdef CONFIG_ARM64 31 | @@ -132,6 +134,22 @@ static ssize_t bao_ipcshmem_write_fops(struct file *filp, 32 | return count; 33 | } 34 | 35 | +static int bao_ipcshmem_mmap_fops(struct file *filp, struct vm_area_struct *vma) 36 | +{ 37 | + struct bao_ipcshmem *bao = filp->private_data; 38 | + 39 | + unsigned long vsize = vma->vm_end - vma->vm_start; 40 | + 41 | + if (remap_pfn_range(vma, vma->vm_start, 42 | + (unsigned long)bao->physical_base >> PAGE_SHIFT, vsize, 43 | + vma->vm_page_prot)) { 44 | + printk(KERN_ERR "failed to remap physical address of shmem\n"); 45 | + return -EFAULT; 46 | + } 47 | + 48 | + return 0; 49 | +} 50 | + 51 | static int bao_ipcshmem_open_fops(struct inode *inode, struct file *filp) 52 | { 53 | struct bao_ipcshmem *bao_ipcshmem = container_of(inode->i_cdev, 54 | @@ -158,6 +176,7 @@ static struct file_operations bao_ipcshmem_fops = { 55 | .owner = THIS_MODULE, 56 | .read = bao_ipcshmem_read_fops, 57 | .write = bao_ipcshmem_write_fops, 58 | + .mmap = bao_ipcshmem_mmap_fops, 59 | .open = bao_ipcshmem_open_fops, 60 | .release = bao_ipcshmem_release_fops 61 | }; 62 | @@ -220,6 +239,7 @@ int bao_ipcshmem_register(struct platform_device *pdev) 63 | bao->write_size = write_size; 64 | bao->read_base = shmem_base_addr + read_offset; 65 | bao->write_base = shmem_base_addr + write_offset; 66 | + bao->physical_base = (void *)r->start; 67 | 68 | cdev_init(&bao->cdev, &bao_ipcshmem_fops); 69 | bao->cdev.owner = owner; 70 | -- 71 | 2.34.1 72 | 73 | -------------------------------------------------------------------------------- /srcs/devicetrees/qemu-aarch64-virt/linux.dts: -------------------------------------------------------------------------------- 1 | /dts-v1/; 2 | 3 | / { 4 | #size-cells = <0x2>; 5 | #address-cells = <0x2>; 6 | interrupt-parent = <&gic>; 7 | 8 | cpus { 9 | #size-cells = <0x0>; 10 | #address-cells = <0x1>; 11 | 12 | cpu@0 { 13 | compatible = "arm,cortex-a53", "arm,armv8"; 14 | device_type = "cpu"; 15 | enable-method = "psci"; 16 | reg = <0x0>; 17 | }; 18 | 19 | cpu@1 { 20 | compatible = "arm,cortex-a53", "arm,armv8"; 21 | device_type = "cpu"; 22 | enable-method = "psci"; 23 | reg = <0x1>; 24 | }; 25 | 26 | }; 27 | 28 | psci { 29 | compatible = "arm,psci-0.2"; 30 | method = "smc"; 31 | }; 32 | 33 | memory@60000000 { 34 | device_type = "memory"; 35 | reg = <0x0 0x60000000 0x0 0x40000000>; 36 | }; 37 | 38 | gic: intc@8000000 { 39 | interrupts = <0x01 0x09 0x04>; 40 | reg = <0x00 0x8000000 0x00 0x10000 0x00 0x80a0000 0x00 0xf60000>; 41 | #redistributor-regions = <0x01>; 42 | compatible = "arm,gic-v3"; 43 | ranges; 44 | #size-cells = <0x02>; 45 | #address-cells = <0x02>; 46 | interrupt-controller; 47 | #interrupt-cells = <0x03>; 48 | }; 49 | 50 | timer { 51 | interrupts = <0x1 0xd 0xf04 0x1 0xe 0xf04 0x1 0xb 0xf04 0x1 0xa 0xf04>; 52 | always-on; 53 | compatible = "arm,armv8-timer", "arm,armv7-timer"; 54 | }; 55 | 56 | virtio_mmio@a003000 { 57 | dma-coherent; 58 | interrupts = <0x0 0x28 0x1>; 59 | reg = <0x0 0xa003000 0x0 0x200>; 60 | compatible = "virtio,mmio"; 61 | }; 62 | 63 | virtio_mmio@a003200 { 64 | dma-coherent; 65 | interrupts = <0x0 0x29 0x1>; 66 | reg = <0x0 0xa003200 0x0 0x200>; 67 | compatible = "virtio,mmio"; 68 | }; 69 | 70 | virtio_mmio@a003400 { 71 | dma-coherent; 72 | interrupts = <0x0 0x2a 0x1>; 73 | reg = <0x0 0xa003400 0x0 0x200>; 74 | compatible = "virtio,mmio"; 75 | }; 76 | 77 | virtio_mmio@a003600 { 78 | dma-coherent; 79 | interrupts = <0x0 0x2b 0x1>; 80 | reg = <0x0 0xa003600 0x0 0x200>; 81 | compatible = "virtio,mmio"; 82 | }; 83 | 84 | virtio_mmio@a003800 { 85 | dma-coherent; 86 | interrupts = <0x0 0x2c 0x1>; 87 | reg = <0x0 0xa003800 0x0 0x200>; 88 | compatible = "virtio,mmio"; 89 | }; 90 | 91 | virtio_mmio@a003a00 { 92 | dma-coherent; 93 | interrupts = <0x0 0x2d 0x1>; 94 | reg = <0x0 0xa003a00 0x0 0x200>; 95 | compatible = "virtio,mmio"; 96 | }; 97 | 98 | virtio_mmio@a003c00 { 99 | dma-coherent; 100 | interrupts = <0x0 0x2e 0x1>; 101 | reg = <0x0 0xa003c00 0x0 0x200>; 102 | compatible = "virtio,mmio"; 103 | }; 104 | 105 | virtio_mmio@a003e00 { 106 | dma-coherent; 107 | interrupts = <0x0 0x2f 0x1>; 108 | reg = <0x0 0xa003e00 0x0 0x200>; 109 | compatible = "virtio,mmio"; 110 | }; 111 | 112 | chosen { 113 | bootargs = "earlycon console=hvc0 ip=192.168.42.15"; 114 | }; 115 | 116 | }; 117 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## PR Description 2 | 3 | Before saving the PR, please delete this description and add only your summary/description of the PR. 4 | Please include a summary of the change that tries to answer the following general questions: 5 | - What does this change introduces? Why is it required? 6 | - Which main blocks are affected? 7 | 8 | If your changes are included in the following categories, please try also to answer to these specific questions if they enhance your summary: 9 | - The PR changes introduces a new feature... 10 | - What new feature is being introduced? 11 | - Is the feature described in any of the requirements? 12 | - The PR changes solves a bug... 13 | - What bug does it solve? What was the previous behavior/warning/error? 14 | - Is the bug described in any issue ticket number? 15 | - The PR changes refactors a code/doc block... 16 | - Why the code/doc block needed to be refactored? 17 | - Is the improvement described in any issue ticket number? 18 | - The PR changes the build system... 19 | - What building block of the build system was changed? 20 | - Has any external dependency introduced? 21 | - The PR changes improves the overall performance of the system... 22 | - Did you quantify the improvement on performance? Please share the numbers. 23 | - The PR changes or adds new tests... 24 | - What new tests were introduced or corrected? 25 | 26 | ### Type of change 27 | 28 | Before saving the PR, please delete this description and the below options that are not relevant. 29 | If you are not sure which type of change are you introducing, please read [Contributing](https://github.com/bao-project/bao-docs/blob/main/source/development/contributing.rst) documentation. 30 | 31 | - **feat**: introduces a new functionality 32 | - Logical unit: 33 | - **fix**: bug fix 34 | - Logical unit: 35 | - Fixes a specific issue: <#ticket-number> 36 | - **ref**: refactoring of a code/doc block 37 | - Logical unit: 38 | - **build**: changes that affect the build system or external dependencies 39 | - Logical unit: 40 | - **doc**: documentation only changes 41 | - Files affected: 42 | - **perf**: a code change that improves performance 43 | - Logical unit: 44 | - **test**: adding missing tests or correcting existing ones 45 | - Test unit/suite: 46 | - **opt**: modifications pertaining only to optimizations 47 | - Logical unit: 48 | - **style**: changes that do not affect the meaning of the code (formatting, typos, naming, etc.) 49 | - **update**: changes that brings a feature, setup, or configuration up to date by adding new or updated information 50 | - Logical unit: 51 | 52 | ## Checklist: 53 | 54 | - [ ] The changes generate no new warnings when building the project. If so, I have justified above. 55 | - [ ] I have run the CI checkers before submitting the PR to avoid unnecessary runs of the workflow. 56 | -------------------------------------------------------------------------------- /srcs/devicetrees/qemu-aarch64-virt/linux-shmem.dts: -------------------------------------------------------------------------------- 1 | /dts-v1/; 2 | 3 | / { 4 | #size-cells = <0x2>; 5 | #address-cells = <0x2>; 6 | interrupt-parent = <&gic>; 7 | 8 | cpus { 9 | #size-cells = <0x0>; 10 | #address-cells = <0x1>; 11 | 12 | cpu@0 { 13 | compatible = "arm,cortex-a53", "arm,armv8"; 14 | device_type = "cpu"; 15 | enable-method = "psci"; 16 | reg = <0x0>; 17 | }; 18 | 19 | cpu@1 { 20 | compatible = "arm,cortex-a53", "arm,armv8"; 21 | device_type = "cpu"; 22 | enable-method = "psci"; 23 | reg = <0x1>; 24 | }; 25 | 26 | }; 27 | 28 | psci { 29 | compatible = "arm,psci-0.2"; 30 | method = "smc"; 31 | }; 32 | 33 | memory@60000000 { 34 | device_type = "memory"; 35 | reg = <0x0 0x60000000 0x0 0x40000000>; 36 | }; 37 | 38 | gic: intc@8000000 { 39 | interrupts = <0x01 0x09 0x04>; 40 | reg = <0x00 0x8000000 0x00 0x10000 0x00 0x80a0000 0x00 0xf60000>; 41 | #redistributor-regions = <0x01>; 42 | compatible = "arm,gic-v3"; 43 | ranges; 44 | #size-cells = <0x02>; 45 | #address-cells = <0x02>; 46 | interrupt-controller; 47 | #interrupt-cells = <0x03>; 48 | }; 49 | 50 | timer { 51 | interrupts = <0x1 0xd 0xf04 0x1 0xe 0xf04 0x1 0xb 0xf04 0x1 0xa 0xf04>; 52 | always-on; 53 | compatible = "arm,armv8-timer", "arm,armv7-timer"; 54 | }; 55 | 56 | virtio_mmio@a003000 { 57 | dma-coherent; 58 | interrupts = <0x0 0x28 0x1>; 59 | reg = <0x0 0xa003000 0x0 0x200>; 60 | compatible = "virtio,mmio"; 61 | }; 62 | 63 | virtio_mmio@a003200 { 64 | dma-coherent; 65 | interrupts = <0x0 0x29 0x1>; 66 | reg = <0x0 0xa003200 0x0 0x200>; 67 | compatible = "virtio,mmio"; 68 | }; 69 | 70 | virtio_mmio@a003400 { 71 | dma-coherent; 72 | interrupts = <0x0 0x2a 0x1>; 73 | reg = <0x0 0xa003400 0x0 0x200>; 74 | compatible = "virtio,mmio"; 75 | }; 76 | 77 | virtio_mmio@a003600 { 78 | dma-coherent; 79 | interrupts = <0x0 0x2b 0x1>; 80 | reg = <0x0 0xa003600 0x0 0x200>; 81 | compatible = "virtio,mmio"; 82 | }; 83 | 84 | virtio_mmio@a003800 { 85 | dma-coherent; 86 | interrupts = <0x0 0x2c 0x1>; 87 | reg = <0x0 0xa003800 0x0 0x200>; 88 | compatible = "virtio,mmio"; 89 | }; 90 | 91 | virtio_mmio@a003a00 { 92 | dma-coherent; 93 | interrupts = <0x0 0x2d 0x1>; 94 | reg = <0x0 0xa003a00 0x0 0x200>; 95 | compatible = "virtio,mmio"; 96 | }; 97 | 98 | virtio_mmio@a003c00 { 99 | dma-coherent; 100 | interrupts = <0x0 0x2e 0x1>; 101 | reg = <0x0 0xa003c00 0x0 0x200>; 102 | compatible = "virtio,mmio"; 103 | }; 104 | 105 | virtio_mmio@a003e00 { 106 | dma-coherent; 107 | interrupts = <0x0 0x2f 0x1>; 108 | reg = <0x0 0xa003e00 0x0 0x200>; 109 | compatible = "virtio,mmio"; 110 | }; 111 | 112 | bao-ipc@f0000000 { 113 | compatible = "bao,ipcshmem"; 114 | reg = <0x0 0xf0000000 0x0 0x00010000>; 115 | read-channel = <0x0 0x2000>; 116 | write-channel = <0x2000 0x2000>; 117 | interrupts = <0 52 1>; 118 | id = <0>; 119 | }; 120 | 121 | chosen { 122 | bootargs = "earlycon console=hvc0 ip=192.168.42.15"; 123 | }; 124 | 125 | }; 126 | -------------------------------------------------------------------------------- /.github/templates/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## PR Description 2 | 3 | Before saving the PR, please delete this description and add only your summary/description of the PR. 4 | Please include a summary of the change that tries to answer the following general questions: 5 | - What does this change introduces? Why is it required? 6 | - Which main blocks are affected? 7 | 8 | If your changes are included in the following categories, please try also to answer to these specific questions if they enhance your summary: 9 | - The PR changes introduces a new feature... 10 | - What new feature is being introduced? 11 | - Is the feature described in any of the requirements? 12 | - The PR changes solves a bug... 13 | - What bug does it solve? What was the previous behavior/warning/error? 14 | - Is the bug described in any issue ticket number? 15 | - The PR changes refactors a code/doc block... 16 | - Why the code/doc block needed to be refactored? 17 | - Is the improvement described in any issue ticket number? 18 | - The PR changes the build system... 19 | - What building block of the build system was changed? 20 | - Has any external dependency introduced? 21 | - The PR changes improves the overall performance of the system... 22 | - Did you quantify the improvement on performance? Please share the numbers. 23 | - The PR changes or adds new tests... 24 | - What new tests were introduced or corrected? 25 | 26 | ### Type of change 27 | 28 | Before saving the PR, please delete this description and the below options that are not relevant. 29 | If you are not sure which type of change are you introducing, please read [Contributing](https://github.com/bao-project/bao-docs/blob/main/source/development/contributing.rst) documentation. 30 | 31 | - **feat**: introduces a new functionality 32 | - Logical unit: 33 | - **fix**: bug fix 34 | - Logical unit: 35 | - Fixes a specific issue: <#ticket-number> 36 | - **ref**: refactoring of a code/doc block 37 | - Logical unit: 38 | - **build**: changes that affect the build system or external dependencies 39 | - Logical unit: 40 | - **doc**: documentation only changes 41 | - Files affected: 42 | - **perf**: a code change that improves performance 43 | - Logical unit: 44 | - **test**: adding missing tests or correcting existing ones 45 | - Test unit/suite: 46 | - **opt**: modifications pertaining only to optimizations 47 | - Logical unit: 48 | - **ci**: changes to the CI configuration files and scripts 49 | - CI checker unit: 50 | - **style**: changes that do not affect the meaning of the code (formatting, typos, naming, etc.) 51 | - **update**: changes that brings a feature, setup, or configuration up to date by adding new or updated information 52 | - Logical unit: 53 | 54 | ## Checklist: 55 | 56 | - [ ] The changes follows the documentation guidelines described in [here](https://github.com/bao-project/bao-docs/blob/main/source/development/doc_guidelines.rst). 57 | - [ ] The changes follows the code documentation guidelines described in [here](https://github.com/bao-project/bao-docs/blob/main/source/development/code_documentation.rst). 58 | - [ ] The changes follows the coding style guidelines described in [here](https://github.com/bao-project/bao-docs/blob/main/source/development/coding_style.rst). 59 | - [ ] The changes follows the MISRA guidelines described in [here](https://github.com/bao-project/bao-docs/blob/main/source/development/misra.rst). 60 | - [ ] The changes generate no new warnings when building the project. If so, I have justified above. 61 | - [ ] I have run the CI checkers before submitting the PR to avoid unnecessary runs of the workflow. 62 | -------------------------------------------------------------------------------- /srcs/devicetrees/zcu104/linux.dts: -------------------------------------------------------------------------------- 1 | /dts-v1/; 2 | 3 | / { 4 | #address-cells = <0x2>; 5 | #size-cells = <0x2>; 6 | interrupt-parent = <&gic>; 7 | 8 | cpus { 9 | #size-cells = <0x0>; 10 | #address-cells = <0x1>; 11 | 12 | cpu@0 { 13 | compatible = "arm,cortex-a53", "arm,armv8"; 14 | device_type = "cpu"; 15 | enable-method = "psci"; 16 | reg = <0x0>; 17 | }; 18 | }; 19 | 20 | psci { 21 | compatible = "arm,psci-0.2"; 22 | method = "smc"; 23 | }; 24 | 25 | memory@0 { 26 | device_type = "memory"; 27 | reg = <0x0 0x40000000 0x0 0x10000000>; 28 | }; 29 | 30 | 31 | gic: interrupt-controller@f9010000 { 32 | compatible = "arm,gic-400", "arm,cortex-a15-gic"; 33 | #interrupt-cells = <0x3>; 34 | reg = <0x0 0xf9010000 0x0 0x10000 0x0 0xf9020000 0x0 0x20000 0x0 0xf9040000 0x0 0x20000 0x0 0xf9060000 0x0 0x20000>; 35 | interrupt-controller; 36 | interrupt-parent = <0x4>; 37 | interrupts = <0x1 0x9 0xf04>; 38 | }; 39 | 40 | timer { 41 | compatible = "arm,armv8-timer"; 42 | always-on; 43 | interrupts = <0x1 0xd 0xf08 0x1 0xe 0xf08 0x1 0xb 0xf08 0x1 0xa 0xf08>; 44 | }; 45 | 46 | pmu { 47 | compatible = "arm,armv8-pmuv3"; 48 | interrupt-parent = <0x4>; 49 | interrupts = <0 143 4>, 50 | <0 144 4>, 51 | <0 145 4>, 52 | <0 146 4>; 53 | }; 54 | 55 | uartclk: uartclk { 56 | compatible = "fixed-clock"; 57 | #clock-cells = <0x0>; 58 | clock-frequency = <100000000>; 59 | phandle = <0x1>; 60 | }; 61 | 62 | ethclk: ethclk { 63 | compatible = "fixed-clock"; 64 | #clock-cells = <0x0>; 65 | clock-frequency = <125000000>; 66 | phandle = <0x2>; 67 | }; 68 | 69 | amba { 70 | compatible = "simple-bus"; 71 | #address-cells = <0x2>; 72 | #size-cells = <0x2>; 73 | ranges; 74 | 75 | serial@ff010000 { 76 | u-boot,dm-pre-reloc; 77 | compatible = "cdns,uart-r1p12", "xlnx,xuartps"; 78 | status = "okay"; 79 | interrupts = <0x0 0x16 0x4>; 80 | reg = <0x0 0xff010000 0x0 0x1000>; 81 | clock-names = "uart_clk", "pclk"; 82 | clocks = <&uartclk &uartclk>; 83 | }; 84 | 85 | ethernet@ff0e0000 { 86 | compatible = "cdns,zynqmp-gem", "cdns,gem"; 87 | status = "okay"; 88 | interrupt-parent = <&gic>; 89 | interrupts = <0x0 0x3f 0x4 0x0 0x3f 0x4>; 90 | reg = <0x0 0xff0e0000 0x0 0x1000>; 91 | clock-names = "pclk", "hclk", "tx_clk", "rx_clk"; 92 | phy-mode = "rgmii-id"; 93 | #address-cells = <0x1>; 94 | #size-cells = <0x0>; 95 | clocks = <ðclk ðclk ðclk ðclk>; 96 | phy-handle = <&phy>; 97 | 98 | phy: phy@c { 99 | reg = <0xc>; 100 | ti,rx-internal-delay = <0x8>; 101 | ti,tx-internal-delay = <0xa>; 102 | ti,fifo-depth = <0x1>; 103 | ti,dp83867-rxctrl-strap-quirk; 104 | }; 105 | }; 106 | 107 | zynqmp_phy@fd400000 { 108 | compatible = "xlnx,zynqmp-psgtr-v1.1"; 109 | status = "disabled"; 110 | reg = <0x0 0xfd400000 0x0 0x40000 0x0 0xfd3d0000 0x0 0x1000>; 111 | reg-names = "serdes", "siou"; 112 | 113 | lane0 { 114 | #phy-cells = <0x4>; 115 | }; 116 | 117 | lane1 { 118 | #phy-cells = <0x4>; 119 | }; 120 | 121 | lane2 { 122 | #phy-cells = <0x4>; 123 | }; 124 | 125 | lane3 { 126 | #phy-cells = <0x4>; 127 | }; 128 | }; 129 | }; 130 | 131 | bao-ipc@f0000000 { 132 | compatible = "bao,ipcshmem"; 133 | reg = <0x0 0xf0000000 0x0 0x00010000>; 134 | read-channel = <0x0 0x2000>; 135 | write-channel = <0x2000 0x2000>; 136 | interrupts = <0 52 1>; 137 | id = <0>; 138 | }; 139 | 140 | aliases { 141 | ethernet0 = "/amba/ethernet@ff0e0000"; 142 | serial0 = "/amba/serial@ff010000"; 143 | }; 144 | 145 | chosen { 146 | bootargs = "earlycon console=ttyPS0,115200n8 clk_ignore_unused ip=192.168.42.15 carrier_timeout=0"; 147 | stdout-path = "serial0:115200n8"; 148 | }; 149 | }; 150 | -------------------------------------------------------------------------------- /configs/baremetal-freeRTOS.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | VM_IMAGE(baremetal_image, XSTR(BAO_WRKDIR_IMGS/guests/baremetal-freeRTOS-setup/baremetal.bin)); 4 | VM_IMAGE(freertos_image, XSTR(BAO_WRKDIR_IMGS/guests/baremetal-freeRTOS-setup/free-rtos.bin)); 5 | 6 | struct config config = { 7 | 8 | CONFIG_HEADER 9 | 10 | .shmemlist_size = 1, 11 | .shmemlist = (struct shmem[]) { 12 | [0] = { .size = 0x00010000, } 13 | }, 14 | 15 | .vmlist_size = 2, 16 | .vmlist = { 17 | { 18 | .image = { 19 | .base_addr = 0x50000000, 20 | .load_addr = VM_IMAGE_OFFSET(baremetal_image), 21 | .size = VM_IMAGE_SIZE(baremetal_image) 22 | }, 23 | 24 | .entry = 0x50000000, 25 | 26 | .platform = { 27 | .cpu_num = 2, 28 | 29 | .region_num = 1, 30 | .regions = (struct vm_mem_region[]) { 31 | { 32 | .base = 0x50000000, 33 | .size = 0x4000000 34 | } 35 | }, 36 | 37 | .dev_num = 2, 38 | .devs = (struct vm_dev_region[]) { 39 | { 40 | /* PL011 */ 41 | .pa = 0x9000000, 42 | .va = 0x9000000, 43 | .size = 0x10000, 44 | }, 45 | { 46 | /* Arch timer interrupt */ 47 | .interrupt_num = 1, 48 | .interrupts = 49 | (irqid_t[]) {27} 50 | } 51 | }, 52 | 53 | .arch = { 54 | .gic = { 55 | .gicd_addr = 0x08000000, 56 | .gicr_addr = 0x080A0000, 57 | } 58 | } 59 | }, 60 | }, 61 | { 62 | .image = { 63 | .base_addr = 0x0, 64 | .load_addr = VM_IMAGE_OFFSET(freertos_image), 65 | .size = VM_IMAGE_SIZE(freertos_image) 66 | }, 67 | 68 | .entry = 0x0, 69 | 70 | .platform = { 71 | .cpu_num = 2, 72 | 73 | .region_num = 1, 74 | .regions = (struct vm_mem_region[]) { 75 | { 76 | .base = 0x0, 77 | .size = 0x8000000 78 | } 79 | }, 80 | 81 | .ipc_num = 1, 82 | .ipcs = (struct ipc[]) { 83 | { 84 | .base = 0x70000000, 85 | .size = 0x00010000, 86 | .shmem_id = 0, 87 | .interrupt_num = 1, 88 | .interrupts = (irqid_t[]) {52} 89 | } 90 | }, 91 | 92 | .dev_num = 2, 93 | .devs = (struct vm_dev_region[]) { 94 | { 95 | /* PL011 */ 96 | .pa = 0x9000000, 97 | .va = 0xff000000, 98 | .size = 0x10000 99 | }, 100 | { 101 | .interrupt_num = 1, 102 | .interrupts = (irqid_t[]) {27} 103 | } 104 | }, 105 | 106 | .arch = { 107 | .gic = { 108 | .gicd_addr = 0xf9010000, 109 | .gicr_addr = 0xf9020000, 110 | } 111 | } 112 | }, 113 | }, 114 | }, 115 | }; -------------------------------------------------------------------------------- /configs/baremetal-freeRTOS-linux.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | VM_IMAGE(baremetal_image, XSTR(BAO_WRKDIR_IMGS/guests/baremetal-freeRTOS-linux-setup/baremetal.bin)); 4 | VM_IMAGE(freertos_image, XSTR(BAO_WRKDIR_IMGS/guests/baremetal-freeRTOS-linux-setup/freertos.bin)); 5 | VM_IMAGE(linux, XSTR(BAO_WRKDIR_IMGS/guests/baremetal-freeRTOS-linux-setup/linux.bin)); 6 | 7 | struct config config = { 8 | 9 | CONFIG_HEADER 10 | 11 | .shmemlist_size = 1, 12 | .shmemlist = (struct shmem[]) { 13 | [0] = { .size = 0x00010000, } 14 | }, 15 | 16 | .vmlist_size = 3, 17 | .vmlist = { 18 | { 19 | .image = { 20 | .base_addr = 0x50000000, 21 | .load_addr = VM_IMAGE_OFFSET(baremetal_image), 22 | .size = VM_IMAGE_SIZE(baremetal_image) 23 | }, 24 | 25 | .entry = 0x50000000, 26 | 27 | .platform = { 28 | .cpu_num = 1, 29 | 30 | .region_num = 1, 31 | .regions = (struct vm_mem_region[]) { 32 | { 33 | .base = 0x50000000, 34 | .size = 0x4000000 35 | } 36 | }, 37 | 38 | .dev_num = 2, 39 | .devs = (struct vm_dev_region[]) { 40 | { 41 | /* PL011 */ 42 | .pa = 0x9000000, 43 | .va = 0x9000000, 44 | .size = 0x10000, 45 | }, 46 | { 47 | /* Arch timer interrupt */ 48 | .interrupt_num = 1, 49 | .interrupts = 50 | (irqid_t[]) {27} 51 | } 52 | }, 53 | 54 | .arch = { 55 | .gic = { 56 | .gicd_addr = 0x08000000, 57 | .gicr_addr = 0x080A0000, 58 | } 59 | } 60 | }, 61 | }, 62 | { 63 | .image = { 64 | .base_addr = 0x0, 65 | .load_addr = VM_IMAGE_OFFSET(freertos_image), 66 | .size = VM_IMAGE_SIZE(freertos_image) 67 | }, 68 | 69 | .entry = 0x0, 70 | 71 | .platform = { 72 | .cpu_num = 1, 73 | 74 | .region_num = 1, 75 | .regions = (struct vm_mem_region[]) { 76 | { 77 | .base = 0x0, 78 | .size = 0x8000000 79 | } 80 | }, 81 | 82 | .ipc_num = 1, 83 | .ipcs = (struct ipc[]) { 84 | { 85 | .base = 0x70000000, 86 | .size = 0x00010000, 87 | .shmem_id = 0, 88 | .interrupt_num = 1, 89 | .interrupts = (irqid_t[]) {52} 90 | } 91 | }, 92 | 93 | .dev_num = 2, 94 | .devs = (struct vm_dev_region[]) { 95 | { 96 | /* PL011 */ 97 | .pa = 0x9000000, 98 | .va = 0xff000000, 99 | .size = 0x10000 100 | }, 101 | { 102 | .interrupt_num = 1, 103 | .interrupts = (irqid_t[]) {27} 104 | } 105 | }, 106 | 107 | .arch = { 108 | .gic = { 109 | .gicd_addr = 0xf9010000, 110 | .gicr_addr = 0xf9020000, 111 | } 112 | } 113 | }, 114 | }, 115 | { 116 | .image = { 117 | .base_addr = 0x60000000, 118 | .load_addr = VM_IMAGE_OFFSET(linux_image), 119 | .size = VM_IMAGE_SIZE(linux_image) 120 | }, 121 | 122 | .entry = 0x60000000, 123 | 124 | .platform = { 125 | .cpu_num = 2, 126 | 127 | .region_num = 1, 128 | .regions = (struct vm_mem_region[]) { 129 | { 130 | .base = 0x60000000, 131 | .size = 0x40000000, 132 | .place_phys = true, 133 | .phys = 0x60000000 134 | } 135 | }, 136 | 137 | .ipc_num = 1, 138 | .ipcs = (struct ipc[]) { 139 | { 140 | .base = 0xf0000000, 141 | .size = 0x00010000, 142 | .shmem_id = 0, 143 | .interrupt_num = 1, 144 | .interrupts = (irqid_t[]) {52} 145 | } 146 | }, 147 | 148 | .dev_num = 2, 149 | .devs = (struct vm_dev_region[]) { 150 | { 151 | /* Arch timer interrupt */ 152 | .interrupt_num = 1, 153 | .interrupts = (irqid_t[]) {27} 154 | }, 155 | { 156 | /* virtio devices */ 157 | .pa = 0xa003000, 158 | .va = 0xa003000, 159 | .size = 0x1000, 160 | .interrupt_num = 8, 161 | .interrupts = (irqid_t[]) {72,73,74,75,76,77,78,79} 162 | }, 163 | }, 164 | 165 | .arch = { 166 | .gic = { 167 | .gicd_addr = 0x8000000, 168 | .gicr_addr = 0x80A0000 169 | } 170 | } 171 | }, 172 | } 173 | }, 174 | }; -------------------------------------------------------------------------------- /configs/baremetal-freeRTOS-linux-shmem.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | VM_IMAGE(baremetal_image, XSTR(BAO_WRKDIR_IMGS/guests/baremetal-freeRTOS-linux-setup/baremetal.bin)); 4 | VM_IMAGE(freertos_image, XSTR(BAO_WRKDIR_IMGS/guests/baremetal-freeRTOS-linux-setup/freertos.bin)); 5 | VM_IMAGE(linux, XSTR(BAO_WRKDIR_IMGS/guests/baremetal-freeRTOS-linux-setup/linux-shmem.bin)); 6 | 7 | struct config config = { 8 | 9 | CONFIG_HEADER 10 | 11 | .shmemlist_size = 1, 12 | .shmemlist = (struct shmem[]) { 13 | [0] = { .size = 0x00010000, } 14 | }, 15 | 16 | .vmlist_size = 3, 17 | .vmlist = { 18 | { 19 | .image = { 20 | .base_addr = 0x50000000, 21 | .load_addr = VM_IMAGE_OFFSET(baremetal_image), 22 | .size = VM_IMAGE_SIZE(baremetal_image) 23 | }, 24 | 25 | .entry = 0x50000000, 26 | 27 | .platform = { 28 | .cpu_num = 1, 29 | 30 | .region_num = 1, 31 | .regions = (struct vm_mem_region[]) { 32 | { 33 | .base = 0x50000000, 34 | .size = 0x4000000 35 | } 36 | }, 37 | 38 | .dev_num = 2, 39 | .devs = (struct vm_dev_region[]) { 40 | { 41 | /* PL011 */ 42 | .pa = 0x9000000, 43 | .va = 0x9000000, 44 | .size = 0x10000, 45 | }, 46 | { 47 | /* Arch timer interrupt */ 48 | .interrupt_num = 1, 49 | .interrupts = 50 | (irqid_t[]) {27} 51 | } 52 | }, 53 | 54 | .arch = { 55 | .gic = { 56 | .gicd_addr = 0x08000000, 57 | .gicr_addr = 0x080A0000, 58 | } 59 | } 60 | }, 61 | }, 62 | { 63 | .image = { 64 | .base_addr = 0x0, 65 | .load_addr = VM_IMAGE_OFFSET(freertos_image), 66 | .size = VM_IMAGE_SIZE(freertos_image) 67 | }, 68 | 69 | .entry = 0x0, 70 | 71 | .platform = { 72 | .cpu_num = 1, 73 | 74 | .region_num = 1, 75 | .regions = (struct vm_mem_region[]) { 76 | { 77 | .base = 0x0, 78 | .size = 0x8000000 79 | } 80 | }, 81 | 82 | .ipc_num = 1, 83 | .ipcs = (struct ipc[]) { 84 | { 85 | .base = 0x70000000, 86 | .size = 0x00010000, 87 | .shmem_id = 0, 88 | .interrupt_num = 1, 89 | .interrupts = (irqid_t[]) {52} 90 | } 91 | }, 92 | 93 | .dev_num = 2, 94 | .devs = (struct vm_dev_region[]) { 95 | { 96 | /* PL011 */ 97 | .pa = 0x9000000, 98 | .va = 0xff000000, 99 | .size = 0x10000 100 | }, 101 | { 102 | .interrupt_num = 1, 103 | .interrupts = (irqid_t[]) {27} 104 | } 105 | }, 106 | 107 | .arch = { 108 | .gic = { 109 | .gicd_addr = 0xf9010000, 110 | .gicr_addr = 0xf9020000, 111 | } 112 | } 113 | }, 114 | }, 115 | { 116 | .image = { 117 | .base_addr = 0x60000000, 118 | .load_addr = VM_IMAGE_OFFSET(linux_image), 119 | .size = VM_IMAGE_SIZE(linux_image) 120 | }, 121 | 122 | .entry = 0x60000000, 123 | 124 | .platform = { 125 | .cpu_num = 2, 126 | 127 | .region_num = 1, 128 | .regions = (struct vm_mem_region[]) { 129 | { 130 | .base = 0x60000000, 131 | .size = 0x40000000, 132 | .place_phys = true, 133 | .phys = 0x60000000 134 | } 135 | }, 136 | 137 | .ipc_num = 1, 138 | .ipcs = (struct ipc[]) { 139 | { 140 | .base = 0xf0000000, 141 | .size = 0x00010000, 142 | .shmem_id = 0, 143 | .interrupt_num = 1, 144 | .interrupts = (irqid_t[]) {52} 145 | } 146 | }, 147 | 148 | .dev_num = 2, 149 | .devs = (struct vm_dev_region[]) { 150 | { 151 | /* Arch timer interrupt */ 152 | .interrupt_num = 1, 153 | .interrupts = (irqid_t[]) {27} 154 | }, 155 | { 156 | /* virtio devices */ 157 | .pa = 0xa003000, 158 | .va = 0xa003000, 159 | .size = 0x1000, 160 | .interrupt_num = 8, 161 | .interrupts = (irqid_t[]) {72,73,74,75,76,77,78,79} 162 | }, 163 | }, 164 | 165 | .arch = { 166 | .gic = { 167 | .gicd_addr = 0x8000000, 168 | .gicr_addr = 0x80A0000 169 | } 170 | } 171 | }, 172 | } 173 | }, 174 | }; -------------------------------------------------------------------------------- /srcs/patches/v5.11/0001-add-bao-ipcshmem-driver.patch: -------------------------------------------------------------------------------- 1 | From 8b6f77465ca53540dfca7f0fda06620689543c11 Mon Sep 17 00:00:00 2001 2 | From: Jose Martins 3 | Date: Tue, 16 Feb 2021 16:37:13 +0000 4 | Subject: [PATCH] add bao ipcshmem driver 5 | 6 | Signed-off-by: Jose Martins 7 | --- 8 | drivers/Kconfig | 2 + 9 | drivers/Makefile | 1 + 10 | drivers/bao/Kconfig | 5 + 11 | drivers/bao/Makefile | 2 + 12 | drivers/bao/bao-ipcshmem.c | 288 +++++++++++++++++++++++++++++++++++++ 13 | 5 files changed, 298 insertions(+) 14 | create mode 100755 drivers/bao/Kconfig 15 | create mode 100644 drivers/bao/Makefile 16 | create mode 100644 drivers/bao/bao-ipcshmem.c 17 | 18 | diff --git a/drivers/Kconfig b/drivers/Kconfig 19 | index dcecc9f6e..1d6358888 100644 20 | --- a/drivers/Kconfig 21 | +++ b/drivers/Kconfig 22 | @@ -235,4 +235,6 @@ source "drivers/interconnect/Kconfig" 23 | source "drivers/counter/Kconfig" 24 | 25 | source "drivers/most/Kconfig" 26 | + 27 | +source "drivers/bao/Kconfig" 28 | endmenu 29 | diff --git a/drivers/Makefile b/drivers/Makefile 30 | index 576228037..5f45b99be 100644 31 | --- a/drivers/Makefile 32 | +++ b/drivers/Makefile 33 | @@ -189,3 +189,4 @@ obj-$(CONFIG_GNSS) += gnss/ 34 | obj-$(CONFIG_INTERCONNECT) += interconnect/ 35 | obj-$(CONFIG_COUNTER) += counter/ 36 | obj-$(CONFIG_MOST) += most/ 37 | +obj-$(CONFIG_BAO_SHMEM) += bao/ 38 | diff --git a/drivers/bao/Kconfig b/drivers/bao/Kconfig 39 | new file mode 100755 40 | index 000000000..dc5e9fc08 41 | --- /dev/null 42 | +++ b/drivers/bao/Kconfig 43 | @@ -0,0 +1,5 @@ 44 | +config BAO_SHMEM 45 | + tristate "Bao shared memory support" 46 | + 47 | + help 48 | + This implements an interface to communicate with bao hosted guests. 49 | diff --git a/drivers/bao/Makefile b/drivers/bao/Makefile 50 | new file mode 100644 51 | index 000000000..f900be88e 52 | --- /dev/null 53 | +++ b/drivers/bao/Makefile 54 | @@ -0,0 +1,2 @@ 55 | +obj-$(CONFIG_BAO_SHMEM) += bao.o 56 | +bao-objs += bao-ipcshmem.o 57 | diff --git a/drivers/bao/bao-ipcshmem.c b/drivers/bao/bao-ipcshmem.c 58 | new file mode 100644 59 | index 000000000..9a25367b0 60 | --- /dev/null 61 | +++ b/drivers/bao/bao-ipcshmem.c 62 | @@ -0,0 +1,288 @@ 63 | +/** 64 | + * TODO: licsense 65 | + */ 66 | + 67 | +#include 68 | +#include 69 | +#include 70 | +#include 71 | +#include 72 | +#include 73 | +#include 74 | +#include 75 | +#include 76 | +#include 77 | +#include 78 | +#include 79 | +#include 80 | +#include 81 | +#include 82 | +#include 83 | +#include 84 | +#include 85 | +#include 86 | + 87 | +#ifdef CONFIG_ARM64 88 | +#include 89 | +#elif CONFIG_RISCV 90 | +#include 91 | +#endif 92 | + 93 | +#define DEV_NAME "baoipc" 94 | +#define MAX_DEVICES 16 95 | +#define NAME_LEN 32 96 | + 97 | +static dev_t bao_ipcshmem_devt; 98 | +struct class *cl; 99 | + 100 | +struct bao_ipcshmem 101 | +{ 102 | + struct cdev cdev; 103 | + struct device *dev; 104 | + 105 | + int id; 106 | + char label[NAME_LEN]; 107 | + void* read_base; 108 | + size_t read_size; 109 | + void* write_base; 110 | + size_t write_size; 111 | +}; 112 | + 113 | +#ifdef CONFIG_ARM64 114 | +static uint64_t bao_ipcshmem_notify(struct bao_ipcshmem *dev) { 115 | + register uint64_t x0 asm("x0") = 1; 116 | + register uint64_t x1 asm("x1") = dev->id; 117 | + register uint64_t x2 asm("x2") = 0; 118 | + 119 | + asm volatile( 120 | + "hvc 0\t\n" 121 | + : "=r"(x0) 122 | + : "r"(x0), "r"(x1), "r"(x2) 123 | + ); 124 | + 125 | + return x0; 126 | +} 127 | +#elif CONFIG_RISCV 128 | +static uint64_t bao_ipcshmem_notify(struct bao_ipcshmem *dev) { 129 | + 130 | + struct sbiret ret = 131 | + sbi_ecall(0x08000ba0, 1, dev->id, 0, 0, 0, 0, 0); 132 | + 133 | + return ret.error; 134 | +} 135 | +#endif 136 | + 137 | +static ssize_t bao_ipcshmem_read_fops(struct file *filp, 138 | + char *buf, size_t count, loff_t *ppos) 139 | +{ 140 | + struct bao_ipcshmem *bao_ipcshmem = filp->private_data; 141 | + unsigned long missing = 0; 142 | + size_t len = 0; 143 | + 144 | + len = strnlen(bao_ipcshmem->read_base, bao_ipcshmem->read_size); 145 | + 146 | + if (*ppos >= len) return 0; 147 | + if ((len - *ppos) < count) count = len - *ppos; 148 | + 149 | + missing = 150 | + copy_to_user(buf, bao_ipcshmem->read_base + *ppos, count); 151 | + if(missing != 0) count = count - missing; 152 | + *ppos += count; 153 | + 154 | + return count; 155 | +} 156 | + 157 | +static ssize_t bao_ipcshmem_write_fops(struct file *filp, 158 | + const char *buf, size_t count, loff_t *ppos) 159 | +{ 160 | + struct bao_ipcshmem *bao_ipcshmem = filp->private_data; 161 | + unsigned long missing = 0; 162 | + 163 | + if (*ppos >= bao_ipcshmem->write_size) 164 | + return 0; 165 | + if(count > bao_ipcshmem->write_size) 166 | + count = bao_ipcshmem->write_size; 167 | + if((*ppos + count) > bao_ipcshmem->write_size) 168 | + count = bao_ipcshmem->write_size - *ppos; 169 | + 170 | + missing = 171 | + copy_from_user(bao_ipcshmem->write_base + *ppos, buf, count); 172 | + if (missing != 0) count = count - missing; 173 | + *ppos += count; 174 | + 175 | + bao_ipcshmem_notify(bao_ipcshmem); 176 | + 177 | + return count; 178 | +} 179 | + 180 | +static int bao_ipcshmem_open_fops(struct inode *inode, struct file *filp) 181 | +{ 182 | + struct bao_ipcshmem *bao_ipcshmem = container_of(inode->i_cdev, 183 | + struct bao_ipcshmem, cdev); 184 | + filp->private_data = bao_ipcshmem; 185 | + 186 | + kobject_get(&bao_ipcshmem->dev->kobj); 187 | + 188 | + return 0; 189 | +} 190 | + 191 | +static int bao_ipcshmem_release_fops(struct inode *inode, struct file *filp) 192 | +{ 193 | + struct bao_ipcshmem *bao_ipcshmem = container_of(inode->i_cdev, 194 | + struct bao_ipcshmem, cdev); 195 | + filp->private_data = NULL; 196 | + 197 | + kobject_put(&bao_ipcshmem->dev->kobj); 198 | + 199 | + return 0; 200 | +} 201 | + 202 | +static struct file_operations bao_ipcshmem_fops = { 203 | + .owner = THIS_MODULE, 204 | + .read = bao_ipcshmem_read_fops, 205 | + .write = bao_ipcshmem_write_fops, 206 | + .open = bao_ipcshmem_open_fops, 207 | + .release = bao_ipcshmem_release_fops 208 | +}; 209 | + 210 | +int bao_ipcshmem_register(struct platform_device *pdev) 211 | +{ 212 | + int ret = 0; 213 | + struct device *dev = &(pdev->dev); 214 | + struct device_node *np = dev->of_node; 215 | + struct module *owner = THIS_MODULE; 216 | + struct resource *r; 217 | + dev_t devt; 218 | + resource_size_t shmem_size; 219 | + u32 write_offset, read_offset, write_size, read_size; 220 | + bool rd_in_range, wr_in_range, disjoint; 221 | + void* shmem_base_addr = NULL; 222 | + int id = -1; 223 | + struct bao_ipcshmem *bao; 224 | + 225 | + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 226 | + if(r == NULL) 227 | + return -EINVAL; 228 | + of_property_read_u32_index(np, "read-channel", 0, &read_offset); 229 | + of_property_read_u32_index(np, "read-channel", 1, &read_size); 230 | + of_property_read_u32_index(np, "write-channel", 0, &write_offset); 231 | + of_property_read_u32_index(np, "write-channel", 1, &write_size); 232 | + 233 | + rd_in_range = (r->start + read_offset + read_size) < r->end; 234 | + wr_in_range = (r->start + write_offset + write_size) < r->end; 235 | + disjoint = ((read_offset + read_size) <= write_offset) || 236 | + ((write_offset + write_size) <= read_offset); 237 | + 238 | + if(!rd_in_range || !wr_in_range || !disjoint) { 239 | + dev_err(&pdev->dev,"invalid channel layout\n"); 240 | + dev_err(&pdev->dev,"rd_in_range = %d, wr_in_range = %d, disjoint = %d\n", 241 | + rd_in_range, wr_in_range, disjoint); 242 | + return -EINVAL; 243 | + } 244 | + 245 | + shmem_size = r->end - r->start + 1; 246 | + shmem_base_addr = memremap(r->start, shmem_size, MEMREMAP_WB); 247 | + if(shmem_base_addr == NULL) 248 | + return -ENOMEM; 249 | + 250 | + of_property_read_u32(np, "id", &id); 251 | + if (id >= MAX_DEVICES) { 252 | + dev_err(&pdev->dev,"invalid id %d\n", id); 253 | + ret = -EINVAL; 254 | + goto err_unmap; 255 | + } 256 | + 257 | + bao = devm_kzalloc(&pdev->dev, sizeof(struct bao_ipcshmem), GFP_KERNEL); 258 | + if(bao == NULL) { 259 | + ret = -ENOMEM; 260 | + goto err_unmap; 261 | + } 262 | + snprintf(bao->label, NAME_LEN, "%s%d", DEV_NAME, id); 263 | + bao->id = id; 264 | + bao->read_size = read_size; 265 | + bao->write_size = write_size; 266 | + bao->read_base = shmem_base_addr + read_offset; 267 | + bao->write_base = shmem_base_addr + write_offset; 268 | + 269 | + cdev_init(&bao->cdev, &bao_ipcshmem_fops); 270 | + bao->cdev.owner = owner; 271 | + 272 | + devt = MKDEV(MAJOR(bao_ipcshmem_devt), id); 273 | + ret = cdev_add(&bao->cdev, devt, 1); 274 | + if (ret) { 275 | + goto err_unmap; 276 | + } 277 | + 278 | + bao->dev = device_create(cl, &pdev->dev, devt, bao, bao->label); 279 | + if (IS_ERR(bao->dev)) { 280 | + ret = PTR_ERR(bao->dev); 281 | + goto err_cdev; 282 | + } 283 | + dev_set_drvdata(bao->dev, bao); 284 | + 285 | + return 0; 286 | + 287 | +err_cdev: 288 | + cdev_del(&bao->cdev); 289 | +err_unmap: 290 | + memunmap(shmem_base_addr); 291 | + 292 | + dev_err(&pdev->dev,"failed initialization\n"); 293 | + return ret; 294 | +} 295 | + 296 | +static int bao_ipcshmem_unregister(struct platform_device *pdev) 297 | +{ 298 | + /* TODO */ 299 | + return 0; 300 | +} 301 | + 302 | +static const struct of_device_id of_bao_ipcshmem_match[] = { 303 | + { 304 | + .compatible = "bao,ipcshmem", 305 | + }, 306 | + {/* sentinel */}}; 307 | +MODULE_DEVICE_TABLE(of, of_bao_ipcshmem_match); 308 | + 309 | +static struct platform_driver bao_ipcshmem_driver = { 310 | + .probe = bao_ipcshmem_register, 311 | + .remove = bao_ipcshmem_unregister, 312 | + .driver = { 313 | + .name = DEV_NAME, 314 | + .of_match_table = of_bao_ipcshmem_match, 315 | + }, 316 | +}; 317 | + 318 | +static int __init bao_ipcshmem_init(void) 319 | +{ 320 | + int ret; 321 | + 322 | + if ((cl = class_create(THIS_MODULE, DEV_NAME)) == NULL) { 323 | + ret = -1; 324 | + pr_err("unable to class_create " DEV_NAME " device\n"); 325 | + return ret; 326 | + } 327 | + 328 | + ret = alloc_chrdev_region(&bao_ipcshmem_devt, 0, MAX_DEVICES, DEV_NAME); 329 | + if (ret < 0) { 330 | + pr_err("unable to alloc_chrdev_region " DEV_NAME " device\n"); 331 | + return ret; 332 | + } 333 | + 334 | + return platform_driver_register(&bao_ipcshmem_driver); 335 | +} 336 | + 337 | +static void __exit bao_ipcshmem_exit(void) 338 | +{ 339 | + platform_driver_unregister(&bao_ipcshmem_driver); 340 | + unregister_chrdev(bao_ipcshmem_devt, DEV_NAME); 341 | + class_destroy(cl); 342 | +} 343 | + 344 | +module_init(bao_ipcshmem_init); 345 | +module_exit(bao_ipcshmem_exit); 346 | + 347 | +MODULE_LICENSE("GPL"); 348 | +MODULE_AUTHOR("David Cerdeira"); 349 | +MODULE_AUTHOR("José Martins"); 350 | +MODULE_DESCRIPTION("bao ipc through shared-memory sample driver"); 351 | -- 352 | 2.25.1 353 | 354 | -------------------------------------------------------------------------------- /srcs/patches/rel_imx_5.4.24_2.1.0/0001-add-bao-ipcshmem-driver.patch: -------------------------------------------------------------------------------- 1 | From fec89b9845b4d518ed8841f42f41d90370908be6 Mon Sep 17 00:00:00 2001 2 | From: Jose Martins 3 | Date: Sat, 6 Mar 2021 22:51:24 +0000 4 | Subject: [PATCH] add bao ipcshmem driver 5 | 6 | Signed-off-by: Jose Martins 7 | --- 8 | drivers/Kconfig | 2 + 9 | drivers/Makefile | 1 + 10 | drivers/bao/Kconfig | 5 + 11 | drivers/bao/Makefile | 2 + 12 | drivers/bao/bao-ipcshmem.c | 288 +++++++++++++++++++++++++++++++++++++ 13 | 5 files changed, 298 insertions(+) 14 | create mode 100755 drivers/bao/Kconfig 15 | create mode 100644 drivers/bao/Makefile 16 | create mode 100644 drivers/bao/bao-ipcshmem.c 17 | 18 | diff --git a/drivers/Kconfig b/drivers/Kconfig 19 | index 3986e201f..6a0bb385b 100644 20 | --- a/drivers/Kconfig 21 | +++ b/drivers/Kconfig 22 | @@ -229,4 +229,6 @@ source "drivers/interconnect/Kconfig" 23 | source "drivers/counter/Kconfig" 24 | 25 | source "drivers/mxc/Kconfig" 26 | + 27 | +source "drivers/bao/Kconfig" 28 | endmenu 29 | diff --git a/drivers/Makefile b/drivers/Makefile 30 | index 5792caca1..61ef5b5fd 100644 31 | --- a/drivers/Makefile 32 | +++ b/drivers/Makefile 33 | @@ -187,3 +187,4 @@ obj-$(CONFIG_GNSS) += gnss/ 34 | obj-$(CONFIG_INTERCONNECT) += interconnect/ 35 | obj-$(CONFIG_COUNTER) += counter/ 36 | obj-y += mxc/ 37 | +obj-$(CONFIG_BAO_SHMEM) += bao/ 38 | diff --git a/drivers/bao/Kconfig b/drivers/bao/Kconfig 39 | new file mode 100755 40 | index 000000000..dc5e9fc08 41 | --- /dev/null 42 | +++ b/drivers/bao/Kconfig 43 | @@ -0,0 +1,5 @@ 44 | +config BAO_SHMEM 45 | + tristate "Bao shared memory support" 46 | + 47 | + help 48 | + This implements an interface to communicate with bao hosted guests. 49 | diff --git a/drivers/bao/Makefile b/drivers/bao/Makefile 50 | new file mode 100644 51 | index 000000000..f900be88e 52 | --- /dev/null 53 | +++ b/drivers/bao/Makefile 54 | @@ -0,0 +1,2 @@ 55 | +obj-$(CONFIG_BAO_SHMEM) += bao.o 56 | +bao-objs += bao-ipcshmem.o 57 | diff --git a/drivers/bao/bao-ipcshmem.c b/drivers/bao/bao-ipcshmem.c 58 | new file mode 100644 59 | index 000000000..9a25367b0 60 | --- /dev/null 61 | +++ b/drivers/bao/bao-ipcshmem.c 62 | @@ -0,0 +1,288 @@ 63 | +/** 64 | + * TODO: licsense 65 | + */ 66 | + 67 | +#include 68 | +#include 69 | +#include 70 | +#include 71 | +#include 72 | +#include 73 | +#include 74 | +#include 75 | +#include 76 | +#include 77 | +#include 78 | +#include 79 | +#include 80 | +#include 81 | +#include 82 | +#include 83 | +#include 84 | +#include 85 | +#include 86 | + 87 | +#ifdef CONFIG_ARM64 88 | +#include 89 | +#elif CONFIG_RISCV 90 | +#include 91 | +#endif 92 | + 93 | +#define DEV_NAME "baoipc" 94 | +#define MAX_DEVICES 16 95 | +#define NAME_LEN 32 96 | + 97 | +static dev_t bao_ipcshmem_devt; 98 | +struct class *cl; 99 | + 100 | +struct bao_ipcshmem 101 | +{ 102 | + struct cdev cdev; 103 | + struct device *dev; 104 | + 105 | + int id; 106 | + char label[NAME_LEN]; 107 | + void* read_base; 108 | + size_t read_size; 109 | + void* write_base; 110 | + size_t write_size; 111 | +}; 112 | + 113 | +#ifdef CONFIG_ARM64 114 | +static uint64_t bao_ipcshmem_notify(struct bao_ipcshmem *dev) { 115 | + register uint64_t x0 asm("x0") = 1; 116 | + register uint64_t x1 asm("x1") = dev->id; 117 | + register uint64_t x2 asm("x2") = 0; 118 | + 119 | + asm volatile( 120 | + "hvc 0\t\n" 121 | + : "=r"(x0) 122 | + : "r"(x0), "r"(x1), "r"(x2) 123 | + ); 124 | + 125 | + return x0; 126 | +} 127 | +#elif CONFIG_RISCV 128 | +static uint64_t bao_ipcshmem_notify(struct bao_ipcshmem *dev) { 129 | + 130 | + struct sbiret ret = 131 | + sbi_ecall(0x08000ba0, 1, dev->id, 0, 0, 0, 0, 0); 132 | + 133 | + return ret.error; 134 | +} 135 | +#endif 136 | + 137 | +static ssize_t bao_ipcshmem_read_fops(struct file *filp, 138 | + char *buf, size_t count, loff_t *ppos) 139 | +{ 140 | + struct bao_ipcshmem *bao_ipcshmem = filp->private_data; 141 | + unsigned long missing = 0; 142 | + size_t len = 0; 143 | + 144 | + len = strnlen(bao_ipcshmem->read_base, bao_ipcshmem->read_size); 145 | + 146 | + if (*ppos >= len) return 0; 147 | + if ((len - *ppos) < count) count = len - *ppos; 148 | + 149 | + missing = 150 | + copy_to_user(buf, bao_ipcshmem->read_base + *ppos, count); 151 | + if(missing != 0) count = count - missing; 152 | + *ppos += count; 153 | + 154 | + return count; 155 | +} 156 | + 157 | +static ssize_t bao_ipcshmem_write_fops(struct file *filp, 158 | + const char *buf, size_t count, loff_t *ppos) 159 | +{ 160 | + struct bao_ipcshmem *bao_ipcshmem = filp->private_data; 161 | + unsigned long missing = 0; 162 | + 163 | + if (*ppos >= bao_ipcshmem->write_size) 164 | + return 0; 165 | + if(count > bao_ipcshmem->write_size) 166 | + count = bao_ipcshmem->write_size; 167 | + if((*ppos + count) > bao_ipcshmem->write_size) 168 | + count = bao_ipcshmem->write_size - *ppos; 169 | + 170 | + missing = 171 | + copy_from_user(bao_ipcshmem->write_base + *ppos, buf, count); 172 | + if (missing != 0) count = count - missing; 173 | + *ppos += count; 174 | + 175 | + bao_ipcshmem_notify(bao_ipcshmem); 176 | + 177 | + return count; 178 | +} 179 | + 180 | +static int bao_ipcshmem_open_fops(struct inode *inode, struct file *filp) 181 | +{ 182 | + struct bao_ipcshmem *bao_ipcshmem = container_of(inode->i_cdev, 183 | + struct bao_ipcshmem, cdev); 184 | + filp->private_data = bao_ipcshmem; 185 | + 186 | + kobject_get(&bao_ipcshmem->dev->kobj); 187 | + 188 | + return 0; 189 | +} 190 | + 191 | +static int bao_ipcshmem_release_fops(struct inode *inode, struct file *filp) 192 | +{ 193 | + struct bao_ipcshmem *bao_ipcshmem = container_of(inode->i_cdev, 194 | + struct bao_ipcshmem, cdev); 195 | + filp->private_data = NULL; 196 | + 197 | + kobject_put(&bao_ipcshmem->dev->kobj); 198 | + 199 | + return 0; 200 | +} 201 | + 202 | +static struct file_operations bao_ipcshmem_fops = { 203 | + .owner = THIS_MODULE, 204 | + .read = bao_ipcshmem_read_fops, 205 | + .write = bao_ipcshmem_write_fops, 206 | + .open = bao_ipcshmem_open_fops, 207 | + .release = bao_ipcshmem_release_fops 208 | +}; 209 | + 210 | +int bao_ipcshmem_register(struct platform_device *pdev) 211 | +{ 212 | + int ret = 0; 213 | + struct device *dev = &(pdev->dev); 214 | + struct device_node *np = dev->of_node; 215 | + struct module *owner = THIS_MODULE; 216 | + struct resource *r; 217 | + dev_t devt; 218 | + resource_size_t shmem_size; 219 | + u32 write_offset, read_offset, write_size, read_size; 220 | + bool rd_in_range, wr_in_range, disjoint; 221 | + void* shmem_base_addr = NULL; 222 | + int id = -1; 223 | + struct bao_ipcshmem *bao; 224 | + 225 | + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 226 | + if(r == NULL) 227 | + return -EINVAL; 228 | + of_property_read_u32_index(np, "read-channel", 0, &read_offset); 229 | + of_property_read_u32_index(np, "read-channel", 1, &read_size); 230 | + of_property_read_u32_index(np, "write-channel", 0, &write_offset); 231 | + of_property_read_u32_index(np, "write-channel", 1, &write_size); 232 | + 233 | + rd_in_range = (r->start + read_offset + read_size) < r->end; 234 | + wr_in_range = (r->start + write_offset + write_size) < r->end; 235 | + disjoint = ((read_offset + read_size) <= write_offset) || 236 | + ((write_offset + write_size) <= read_offset); 237 | + 238 | + if(!rd_in_range || !wr_in_range || !disjoint) { 239 | + dev_err(&pdev->dev,"invalid channel layout\n"); 240 | + dev_err(&pdev->dev,"rd_in_range = %d, wr_in_range = %d, disjoint = %d\n", 241 | + rd_in_range, wr_in_range, disjoint); 242 | + return -EINVAL; 243 | + } 244 | + 245 | + shmem_size = r->end - r->start + 1; 246 | + shmem_base_addr = memremap(r->start, shmem_size, MEMREMAP_WB); 247 | + if(shmem_base_addr == NULL) 248 | + return -ENOMEM; 249 | + 250 | + of_property_read_u32(np, "id", &id); 251 | + if (id >= MAX_DEVICES) { 252 | + dev_err(&pdev->dev,"invalid id %d\n", id); 253 | + ret = -EINVAL; 254 | + goto err_unmap; 255 | + } 256 | + 257 | + bao = devm_kzalloc(&pdev->dev, sizeof(struct bao_ipcshmem), GFP_KERNEL); 258 | + if(bao == NULL) { 259 | + ret = -ENOMEM; 260 | + goto err_unmap; 261 | + } 262 | + snprintf(bao->label, NAME_LEN, "%s%d", DEV_NAME, id); 263 | + bao->id = id; 264 | + bao->read_size = read_size; 265 | + bao->write_size = write_size; 266 | + bao->read_base = shmem_base_addr + read_offset; 267 | + bao->write_base = shmem_base_addr + write_offset; 268 | + 269 | + cdev_init(&bao->cdev, &bao_ipcshmem_fops); 270 | + bao->cdev.owner = owner; 271 | + 272 | + devt = MKDEV(MAJOR(bao_ipcshmem_devt), id); 273 | + ret = cdev_add(&bao->cdev, devt, 1); 274 | + if (ret) { 275 | + goto err_unmap; 276 | + } 277 | + 278 | + bao->dev = device_create(cl, &pdev->dev, devt, bao, bao->label); 279 | + if (IS_ERR(bao->dev)) { 280 | + ret = PTR_ERR(bao->dev); 281 | + goto err_cdev; 282 | + } 283 | + dev_set_drvdata(bao->dev, bao); 284 | + 285 | + return 0; 286 | + 287 | +err_cdev: 288 | + cdev_del(&bao->cdev); 289 | +err_unmap: 290 | + memunmap(shmem_base_addr); 291 | + 292 | + dev_err(&pdev->dev,"failed initialization\n"); 293 | + return ret; 294 | +} 295 | + 296 | +static int bao_ipcshmem_unregister(struct platform_device *pdev) 297 | +{ 298 | + /* TODO */ 299 | + return 0; 300 | +} 301 | + 302 | +static const struct of_device_id of_bao_ipcshmem_match[] = { 303 | + { 304 | + .compatible = "bao,ipcshmem", 305 | + }, 306 | + {/* sentinel */}}; 307 | +MODULE_DEVICE_TABLE(of, of_bao_ipcshmem_match); 308 | + 309 | +static struct platform_driver bao_ipcshmem_driver = { 310 | + .probe = bao_ipcshmem_register, 311 | + .remove = bao_ipcshmem_unregister, 312 | + .driver = { 313 | + .name = DEV_NAME, 314 | + .of_match_table = of_bao_ipcshmem_match, 315 | + }, 316 | +}; 317 | + 318 | +static int __init bao_ipcshmem_init(void) 319 | +{ 320 | + int ret; 321 | + 322 | + if ((cl = class_create(THIS_MODULE, DEV_NAME)) == NULL) { 323 | + ret = -1; 324 | + pr_err("unable to class_create " DEV_NAME " device\n"); 325 | + return ret; 326 | + } 327 | + 328 | + ret = alloc_chrdev_region(&bao_ipcshmem_devt, 0, MAX_DEVICES, DEV_NAME); 329 | + if (ret < 0) { 330 | + pr_err("unable to alloc_chrdev_region " DEV_NAME " device\n"); 331 | + return ret; 332 | + } 333 | + 334 | + return platform_driver_register(&bao_ipcshmem_driver); 335 | +} 336 | + 337 | +static void __exit bao_ipcshmem_exit(void) 338 | +{ 339 | + platform_driver_unregister(&bao_ipcshmem_driver); 340 | + unregister_chrdev(bao_ipcshmem_devt, DEV_NAME); 341 | + class_destroy(cl); 342 | +} 343 | + 344 | +module_init(bao_ipcshmem_init); 345 | +module_exit(bao_ipcshmem_exit); 346 | + 347 | +MODULE_LICENSE("GPL"); 348 | +MODULE_AUTHOR("David Cerdeira"); 349 | +MODULE_AUTHOR("José Martins"); 350 | +MODULE_DESCRIPTION("bao ipc through shared-memory sample driver"); 351 | -- 352 | 2.25.1 353 | 354 | -------------------------------------------------------------------------------- /srcs/lloader/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /srcs/patches/v6.1/0001-add-bao-ipcshmem-driver.patch: -------------------------------------------------------------------------------- 1 | From 94ceb8e38ba4984c0826edb5f4fc81e50e1a5ccd Mon Sep 17 00:00:00 2001 2 | From: Jose Martins 3 | Date: Sun, 8 Jan 2023 15:10:12 +0000 4 | Subject: [PATCH] add bao ipcshmem driver 5 | 6 | Signed-off-by: Jose Martins 7 | --- 8 | drivers/Kconfig | 1 + 9 | drivers/Makefile | 1 + 10 | drivers/bao/Kconfig | 5 + 11 | drivers/bao/Makefile | 2 + 12 | drivers/bao/bao-ipcshmem.c | 305 +++++++++++++++++++++++++++++++++++++ 13 | 5 files changed, 314 insertions(+) 14 | create mode 100755 drivers/bao/Kconfig 15 | create mode 100644 drivers/bao/Makefile 16 | create mode 100644 drivers/bao/bao-ipcshmem.c 17 | 18 | diff --git a/drivers/Kconfig b/drivers/Kconfig 19 | index 19ee995bd..8c19d8ff4 100644 20 | --- a/drivers/Kconfig 21 | +++ b/drivers/Kconfig 22 | @@ -239,4 +239,5 @@ source "drivers/peci/Kconfig" 23 | 24 | source "drivers/hte/Kconfig" 25 | 26 | +source "drivers/bao/Kconfig" 27 | endmenu 28 | diff --git a/drivers/Makefile b/drivers/Makefile 29 | index bdf1c6614..f8fa362c3 100644 30 | --- a/drivers/Makefile 31 | +++ b/drivers/Makefile 32 | @@ -189,3 +189,4 @@ obj-$(CONFIG_COUNTER) += counter/ 33 | obj-$(CONFIG_MOST) += most/ 34 | obj-$(CONFIG_PECI) += peci/ 35 | obj-$(CONFIG_HTE) += hte/ 36 | +obj-$(CONFIG_BAO_SHMEM) += bao/ 37 | diff --git a/drivers/bao/Kconfig b/drivers/bao/Kconfig 38 | new file mode 100755 39 | index 000000000..dc5e9fc08 40 | --- /dev/null 41 | +++ b/drivers/bao/Kconfig 42 | @@ -0,0 +1,5 @@ 43 | +config BAO_SHMEM 44 | + tristate "Bao shared memory support" 45 | + 46 | + help 47 | + This implements an interface to communicate with bao hosted guests. 48 | diff --git a/drivers/bao/Makefile b/drivers/bao/Makefile 49 | new file mode 100644 50 | index 000000000..f900be88e 51 | --- /dev/null 52 | +++ b/drivers/bao/Makefile 53 | @@ -0,0 +1,2 @@ 54 | +obj-$(CONFIG_BAO_SHMEM) += bao.o 55 | +bao-objs += bao-ipcshmem.o 56 | diff --git a/drivers/bao/bao-ipcshmem.c b/drivers/bao/bao-ipcshmem.c 57 | new file mode 100644 58 | index 000000000..b7ecd2656 59 | --- /dev/null 60 | +++ b/drivers/bao/bao-ipcshmem.c 61 | @@ -0,0 +1,305 @@ 62 | +/** 63 | + * TODO: licsense 64 | + */ 65 | + 66 | +#include 67 | +#include 68 | +#include 69 | +#include 70 | +#include 71 | +#include 72 | +#include 73 | +#include 74 | +#include 75 | +#include 76 | +#include 77 | +#include 78 | +#include 79 | +#include 80 | +#include 81 | +#include 82 | +#include 83 | +#include 84 | +#include 85 | + 86 | +#if defined(CONFIG_ARM64) || defined(CONFIG_ARM) 87 | +#include 88 | +#include 89 | +#elif CONFIG_RISCV 90 | +#include 91 | +#endif 92 | + 93 | +#define DEV_NAME "baoipc" 94 | +#define MAX_DEVICES 16 95 | +#define NAME_LEN 32 96 | + 97 | +static dev_t bao_ipcshmem_devt; 98 | +struct class *cl; 99 | + 100 | +struct bao_ipcshmem 101 | +{ 102 | + struct cdev cdev; 103 | + struct device *dev; 104 | + 105 | + int id; 106 | + char label[NAME_LEN]; 107 | + void* read_base; 108 | + size_t read_size; 109 | + void* write_base; 110 | + size_t write_size; 111 | +}; 112 | + 113 | +#ifdef CONFIG_ARM64 114 | +static uint64_t bao_ipcshmem_notify(struct bao_ipcshmem *dev) { 115 | + register uint64_t x0 asm("x0") = ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, 116 | + ARM_SMCCC_SMC_64, ARM_SMCCC_OWNER_VENDOR_HYP, 1); 117 | + register uint64_t x1 asm("x1") = dev->id; 118 | + register uint64_t x2 asm("x2") = 0; 119 | + 120 | + asm volatile( 121 | + "hvc 0\t\n" 122 | + : "=r"(x0) 123 | + : "r"(x0), "r"(x1), "r"(x2) 124 | + ); 125 | + 126 | + return x0; 127 | +} 128 | +#elif CONFIG_ARM 129 | +static uint32_t bao_ipcshmem_notify(struct bao_ipcshmem *dev) { 130 | + register uint32_t r0 asm("r0") = ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, 131 | + ARM_SMCCC_SMC_32, ARM_SMCCC_OWNER_VENDOR_HYP, 1); 132 | + register uint32_t r1 asm("r1") = dev->id; 133 | + register uint32_t r2 asm("r2") = 0; 134 | + 135 | + asm volatile( 136 | + "hvc #0\t\n" 137 | + : "=r"(r0) 138 | + : "r"(r0), "r"(r1), "r"(r2) 139 | + ); 140 | + 141 | + return r0; 142 | +} 143 | +#elif CONFIG_RISCV 144 | +static uint64_t bao_ipcshmem_notify(struct bao_ipcshmem *dev) { 145 | + 146 | + struct sbiret ret = 147 | + sbi_ecall(0x08000ba0, 1, dev->id, 0, 0, 0, 0, 0); 148 | + 149 | + return ret.error; 150 | +} 151 | +#endif 152 | + 153 | +static ssize_t bao_ipcshmem_read_fops(struct file *filp, 154 | + char *buf, size_t count, loff_t *ppos) 155 | +{ 156 | + struct bao_ipcshmem *bao_ipcshmem = filp->private_data; 157 | + unsigned long missing = 0; 158 | + size_t len = 0; 159 | + 160 | + len = strnlen(bao_ipcshmem->read_base, bao_ipcshmem->read_size); 161 | + 162 | + if (*ppos >= len) return 0; 163 | + if ((len - *ppos) < count) count = len - *ppos; 164 | + 165 | + missing = 166 | + copy_to_user(buf, bao_ipcshmem->read_base + *ppos, count); 167 | + if(missing != 0) count = count - missing; 168 | + *ppos += count; 169 | + 170 | + return count; 171 | +} 172 | + 173 | +static ssize_t bao_ipcshmem_write_fops(struct file *filp, 174 | + const char *buf, size_t count, loff_t *ppos) 175 | +{ 176 | + struct bao_ipcshmem *bao_ipcshmem = filp->private_data; 177 | + unsigned long missing = 0; 178 | + 179 | + if (*ppos >= bao_ipcshmem->write_size) 180 | + return 0; 181 | + if(count > bao_ipcshmem->write_size) 182 | + count = bao_ipcshmem->write_size; 183 | + if((*ppos + count) > bao_ipcshmem->write_size) 184 | + count = bao_ipcshmem->write_size - *ppos; 185 | + 186 | + missing = 187 | + copy_from_user(bao_ipcshmem->write_base + *ppos, buf, count); 188 | + if (missing != 0) count = count - missing; 189 | + *ppos += count; 190 | + 191 | + bao_ipcshmem_notify(bao_ipcshmem); 192 | + 193 | + return count; 194 | +} 195 | + 196 | +static int bao_ipcshmem_open_fops(struct inode *inode, struct file *filp) 197 | +{ 198 | + struct bao_ipcshmem *bao_ipcshmem = container_of(inode->i_cdev, 199 | + struct bao_ipcshmem, cdev); 200 | + filp->private_data = bao_ipcshmem; 201 | + 202 | + kobject_get(&bao_ipcshmem->dev->kobj); 203 | + 204 | + return 0; 205 | +} 206 | + 207 | +static int bao_ipcshmem_release_fops(struct inode *inode, struct file *filp) 208 | +{ 209 | + struct bao_ipcshmem *bao_ipcshmem = container_of(inode->i_cdev, 210 | + struct bao_ipcshmem, cdev); 211 | + filp->private_data = NULL; 212 | + 213 | + kobject_put(&bao_ipcshmem->dev->kobj); 214 | + 215 | + return 0; 216 | +} 217 | + 218 | +static struct file_operations bao_ipcshmem_fops = { 219 | + .owner = THIS_MODULE, 220 | + .read = bao_ipcshmem_read_fops, 221 | + .write = bao_ipcshmem_write_fops, 222 | + .open = bao_ipcshmem_open_fops, 223 | + .release = bao_ipcshmem_release_fops 224 | +}; 225 | + 226 | +int bao_ipcshmem_register(struct platform_device *pdev) 227 | +{ 228 | + int ret = 0; 229 | + struct device *dev = &(pdev->dev); 230 | + struct device_node *np = dev->of_node; 231 | + struct module *owner = THIS_MODULE; 232 | + struct resource *r; 233 | + dev_t devt; 234 | + resource_size_t shmem_size; 235 | + u32 write_offset, read_offset, write_size, read_size; 236 | + bool rd_in_range, wr_in_range, disjoint; 237 | + void* shmem_base_addr = NULL; 238 | + int id = -1; 239 | + struct bao_ipcshmem *bao; 240 | + 241 | + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 242 | + if(r == NULL) 243 | + return -EINVAL; 244 | + of_property_read_u32_index(np, "read-channel", 0, &read_offset); 245 | + of_property_read_u32_index(np, "read-channel", 1, &read_size); 246 | + of_property_read_u32_index(np, "write-channel", 0, &write_offset); 247 | + of_property_read_u32_index(np, "write-channel", 1, &write_size); 248 | + 249 | + rd_in_range = (r->start + read_offset + read_size) < r->end; 250 | + wr_in_range = (r->start + write_offset + write_size) < r->end; 251 | + disjoint = ((read_offset + read_size) <= write_offset) || 252 | + ((write_offset + write_size) <= read_offset); 253 | + 254 | + if(!rd_in_range || !wr_in_range || !disjoint) { 255 | + dev_err(&pdev->dev,"invalid channel layout\n"); 256 | + dev_err(&pdev->dev,"rd_in_range = %d, wr_in_range = %d, disjoint = %d\n", 257 | + rd_in_range, wr_in_range, disjoint); 258 | + return -EINVAL; 259 | + } 260 | + 261 | + shmem_size = r->end - r->start + 1; 262 | + shmem_base_addr = memremap(r->start, shmem_size, MEMREMAP_WB); 263 | + if(shmem_base_addr == NULL) 264 | + return -ENOMEM; 265 | + 266 | + of_property_read_u32(np, "id", &id); 267 | + if (id >= MAX_DEVICES) { 268 | + dev_err(&pdev->dev,"invalid id %d\n", id); 269 | + ret = -EINVAL; 270 | + goto err_unmap; 271 | + } 272 | + 273 | + bao = devm_kzalloc(&pdev->dev, sizeof(struct bao_ipcshmem), GFP_KERNEL); 274 | + if(bao == NULL) { 275 | + ret = -ENOMEM; 276 | + goto err_unmap; 277 | + } 278 | + snprintf(bao->label, NAME_LEN, "%s%d", DEV_NAME, id); 279 | + bao->id = id; 280 | + bao->read_size = read_size; 281 | + bao->write_size = write_size; 282 | + bao->read_base = shmem_base_addr + read_offset; 283 | + bao->write_base = shmem_base_addr + write_offset; 284 | + 285 | + cdev_init(&bao->cdev, &bao_ipcshmem_fops); 286 | + bao->cdev.owner = owner; 287 | + 288 | + devt = MKDEV(MAJOR(bao_ipcshmem_devt), id); 289 | + ret = cdev_add(&bao->cdev, devt, 1); 290 | + if (ret) { 291 | + goto err_unmap; 292 | + } 293 | + 294 | + bao->dev = device_create(cl, &pdev->dev, devt, bao, bao->label); 295 | + if (IS_ERR(bao->dev)) { 296 | + ret = PTR_ERR(bao->dev); 297 | + goto err_cdev; 298 | + } 299 | + dev_set_drvdata(bao->dev, bao); 300 | + 301 | + return 0; 302 | + 303 | +err_cdev: 304 | + cdev_del(&bao->cdev); 305 | +err_unmap: 306 | + memunmap(shmem_base_addr); 307 | + 308 | + dev_err(&pdev->dev,"failed initialization\n"); 309 | + return ret; 310 | +} 311 | + 312 | +static int bao_ipcshmem_unregister(struct platform_device *pdev) 313 | +{ 314 | + /* TODO */ 315 | + return 0; 316 | +} 317 | + 318 | +static const struct of_device_id of_bao_ipcshmem_match[] = { 319 | + { 320 | + .compatible = "bao,ipcshmem", 321 | + }, 322 | + {/* sentinel */}}; 323 | +MODULE_DEVICE_TABLE(of, of_bao_ipcshmem_match); 324 | + 325 | +static struct platform_driver bao_ipcshmem_driver = { 326 | + .probe = bao_ipcshmem_register, 327 | + .remove = bao_ipcshmem_unregister, 328 | + .driver = { 329 | + .name = DEV_NAME, 330 | + .of_match_table = of_bao_ipcshmem_match, 331 | + }, 332 | +}; 333 | + 334 | +static int __init bao_ipcshmem_init(void) 335 | +{ 336 | + int ret; 337 | + 338 | + if ((cl = class_create(THIS_MODULE, DEV_NAME)) == NULL) { 339 | + ret = -1; 340 | + pr_err("unable to class_create " DEV_NAME " device\n"); 341 | + return ret; 342 | + } 343 | + 344 | + ret = alloc_chrdev_region(&bao_ipcshmem_devt, 0, MAX_DEVICES, DEV_NAME); 345 | + if (ret < 0) { 346 | + pr_err("unable to alloc_chrdev_region " DEV_NAME " device\n"); 347 | + return ret; 348 | + } 349 | + 350 | + return platform_driver_register(&bao_ipcshmem_driver); 351 | +} 352 | + 353 | +static void __exit bao_ipcshmem_exit(void) 354 | +{ 355 | + platform_driver_unregister(&bao_ipcshmem_driver); 356 | + unregister_chrdev(bao_ipcshmem_devt, DEV_NAME); 357 | + class_destroy(cl); 358 | +} 359 | + 360 | +module_init(bao_ipcshmem_init); 361 | +module_exit(bao_ipcshmem_exit); 362 | + 363 | +MODULE_LICENSE("GPL"); 364 | +MODULE_AUTHOR("David Cerdeira"); 365 | +MODULE_AUTHOR("José Martins"); 366 | +MODULE_DESCRIPTION("bao ipc through shared-memory sample driver"); 367 | -- 368 | 2.34.1 369 | 370 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # "Hello world"? We prefer "Hello Bao!" 2 | 3 | Welcome to the Bao Hypervisor! Get ready for an interactive journey as we explore the world of Bao together. Whether you're a seasoned Bao user or a newcomer, this tour is designed to give you a practical and enthusiastic introduction to our powerful hypervisor. 4 | 5 | If you're already familiar with Bao or want to dive into specific setups provided by our team, feel free to skip ahead to the Bao demos section. 6 | 7 | In this guide, we will take a tour of the different components required to build a setup using the Bao hypervisor and learn how the different components interact. For this purpose, the guide contains the following topics: 8 | 9 | - A **getting started** to help users on preparing the environment to build the setup and also some pointers to documentations of Bao (in case you want to go deeper in any detail); 10 | 11 | - An **initial setup** for giving the first steps on this tour. This section aims to explore the different components of the system and get the first practical example of this guide; 12 | 13 | - An **interactive tutorial on changing the guests** running on top of Bao; 14 | 15 | - A **practical example** of changing the setup running; 16 | 17 | - An example of **how different guests can coexist and interact** with each other; 18 | 19 | ## 1. Getting Started 20 | 21 | Before we dive into the thrilling aspects of Bao, let's make sure you're all set up and ready to go. In this section, we'll guide you through preparing your environment to build the setup. Don't worry; we'll provide you with helpful pointers to Bao's documentation in case you want to explore any details further. 22 | 23 | ### 1.1 Recommended Operating System: Linux (e.g., Ubuntu 22.04 or older versions) 24 | To make the most of this tutorial and the Bao hypervisor, we recommend using a Linux-based operating system. While the instructions may work on other platforms, our focus is on Linux, specifically Ubuntu 22.04 or older versions. This will ensure compatibility and an optimal experience throughout the tour. 25 | 26 | ### 1.2 Installing Required Dependencies 27 | Before we can dive into the world of Bao, we need to install several dependencies to enable a seamless setup process. Open your terminal and run the following command to install the necessary packages: 28 | 29 | ```sh 30 | sudo apt install build-essential bison flex git libssl-dev ninja-build \ 31 | u-boot-tools pandoc libslirp-dev pkg-config libglib2.0-dev libpixman-1-dev \ 32 | gettext-base curl xterm cmake python3-pip 33 | ``` 34 | 35 | This command will install essential tools and libraries required for building and running Bao. 36 | Next, we need to install some Python packages. Execute the following command to do so: 37 | 38 | ```sh 39 | pip3 install pykwalify packaging pyelftools 40 | ``` 41 | 42 | ### 1.3 Download and setup the toolchain 43 | 44 | #### 1.3.1. Choosing the Right Toolchain 45 | 46 | [arm-toolchains]: https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads 47 | [riscv-toolchains]: https://github.com/sifive/freedom-tools/releases 48 | 49 | [arm-toolchains]: https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads 50 | [riscv-toolchains]: https://github.com/sifive/freedom-tools/releases 51 | 52 | Before we delve deeper, let's ensure you have the right tools at your disposal. We'll guide you through obtaining and configuring the appropriate cross-compile toolchain for your target architecture. This step is essential for a smooth development experience. 53 | 54 | | Architecture | Toolchain Name | Download Link | 55 | |--------------------------|:--------------------------:|:------------------------------------------:| 56 | | Armv8 Aarch64 | aarch64-none-elf- | [Arm Developer][arm-toolchains] | 57 | | Armv7 or Armv8 Aarch32 | arm-none-eabi- | [Arm Developer][arm-toolchains] | 58 | | RISC-V | riscv64-unknown-elf- | [SiFive's Freedom Tools][riscv-toolchains] | 59 | 60 | #### 1.3.2. Installing and Configuring the Toolchain 61 | 62 | Install the toolchain. Then, set the **CROSS_COMPILE** environment variable 63 | with the reference toolchain prefix path: 64 | 65 | ```sh 66 | export CROSS_COMPILE=/path/to/toolchain/install/dir/bin/your-toolchain-prefix- 67 | ``` 68 | 69 | ### 1.4 Ensuring Sufficient Free Space 70 | 71 | Please be aware that sufficient free space is crucial for this journey, especially due to the Linux image that will be built for the Linux guest VM. To ensure a smooth experience and avoid any space-related issues, we recommend having at least 20GB of free space available on your system. 72 | With your environment set up and all the dependencies installed, you're now ready to dive into the world of Bao hypervisor and create your virtualized wonders! 73 | 74 | --- 75 | 76 | ## 2. Initial setup - Taking the First Steps! 77 | 78 | Now that you're geared up, it's time to take the first steps on this tour. In the Initial Setup section, we'll explore the different components of the system and walk you through a practical example to give you a solid foundation. 79 | 80 | To ensure a smooth journey ahead, let's start by creating a development environment. We'll begin by establishing a directory structure for the various components of our setups. Open up your terminal and execute the following commands: 81 | ```sh 82 | export ROOT_DIR=$(realpath .) 83 | export SETUP_BUILD=$ROOT_DIR/bin 84 | 85 | export BUILD_GUESTS_DIR=$SETUP_BUILD/guests 86 | export BUILD_BAO_DIR=$SETUP_BUILD/bao 87 | export BUILD_FIRMWARE_DIR=$SETUP_BUILD/firmware 88 | 89 | mkdir -p $BUILD_GUESTS_DIR 90 | mkdir -p $BUILD_BAO_DIR 91 | mkdir -p $BUILD_FIRMWARE_DIR 92 | ``` 93 | 94 | Upon completing these commands, your directory should resemble the following: 95 | ``` sh 96 | ├── bin 97 | │   ├── bao 98 | │   ├── firmware 99 | │   └── guests 100 | ├── configs 101 | │   ├──... 102 | ├── img 103 | │  ├──... 104 | └──README.md 105 | ``` 106 | 107 | ### 2.1. Build Guest - Building Your First Bao Guest 108 | 109 | [bao-demos-platforms]: https://github.com/bao-project/bao-demos#appendix-i 110 | 111 | Let's kickstart your journey by building your inaugural Bao guest! Here, you'll gain hands-on experience crafting a Baremetal Guest. Let's get that virtual machine up and running!But before we dive into the hands-on excitement, let's understand the setup we're crafting. Our goal is to deploy a baremetal system atop the Bao hypervisor, as illustrated in the figure below: 112 | 113 | ![Init Setup](/img/single-guest.svg) 114 | 115 | > :information_source: For the sake of simplicity and accessibility, we'll detach from physical hardware and use QEMU (don't worry, we'll guide you through its installation later in the tutorial). However, remember that you can apply these steps to various [other platforms][arm-toolchains]. 116 | 117 | To start, let's define an environment variable for the baremetal app source code: 118 | ```c 119 | export BAREMETAL_SRCS=$ROOT_DIR/baremetal 120 | ``` 121 | 122 | Then, clone the Bao baremetal guest application we've prepared (you can skip this step if you already have your own baremetal source): 123 | ```c 124 | git clone https://github.com/bao-project/bao-baremetal-guest.git\ 125 | --branch demo $BAREMETAL_SRCS 126 | ``` 127 | 128 | And now, let's compile it (for simplicity, our example includes a Makefile to compile the baremetal compilation): 129 | ```c 130 | make -C $BAREMETAL_SRCS PLATFORM=qemu-aarch64-virt 131 | ``` 132 | 133 | Upon completing these steps, you'll find a binary file in the BAREMETAL_SRCS directory. If you followed our provided Makefile, this precious gem will bear the name ``baremetal.bin``. Now, move the binary file to your build directory (``BUILD_GUESTS_DIR``): 134 | 135 | ```sh 136 | mkdir -p $BUILD_GUESTS_DIR/baremetal-setup 137 | cp $BAREMETAL_SRCS/build/qemu-aarch64-virt/baremetal.bin $BUILD_GUESTS_DIR/baremetal-setup/baremetal.bin 138 | ``` 139 | 140 | ### 2.2. Build Bao Hypervisor - Laying the Foundation 141 | Next up, we'll guide you through building the Bao Hypervisor itself. This critical step forms the backbone of your virtualization environment. 142 | 143 | Our first stride in this journey involves configuring the hypervisor using Bao's configuration file. For this specific setup, we're offering you the [configuration file](configs/baremetal.c) to ease the process. If you're curious to explore different configuration options, our detailed our detailed Bao config documentation is [here](https://github.com/bao-project/bao-docs/tree/wip/bao-classic_config) to help. 144 | 145 | ```c 146 | VM_IMAGE(baremetal_image, XSTR(BUILD_GUESTS_DIR/baremetal-setup/baremetal.bin)); 147 | ``` 148 | 149 | > :warning: **Warning:** If you are using a directory structure of the one presented in the tutorial, please make sure to update the following code in the [configuration file](configs/baremetal.c). 150 | 151 | Undoubtedly, if we're envisioning our baremetal system dancing atop the hypervisor stage, we first need that hypervisor in place. Fear not, for our adept team has already shouldered the arduous task. Bao stands ready and waiting for you to harness its power. No need to roll up your sleeves; it's a breeze. Let's embark on this stage-setting journey: 152 | 153 | #### 2.2.1. Cloning the Bao Hypervisor 154 | Your gateway to seamless virtualization begins with cloning the Bao Hypervisor repository. Execute the following commands in your terminal to initiate this crucial step: 155 | ```sh 156 | export BAO_SRCS=$ROOT_DIR/bao 157 | git clone https://github.com/bao-project/bao-hypervisor $BAO_SRCS\ 158 | --branch demo 159 | ``` 160 | 161 | #### 2.2.2. Copying Your Configuration 162 | 163 | Now, let's ensure your unique configuration is seamlessly integrated. Copy your configuration file to the working directory with the following commands: 164 | ```sh 165 | mkdir -p $mkdir -p $BUILD_BAO_DIR/config 166 | cp -L $ROOT_DIR/configs/baremetal.c\ 167 | $BUILD_BAO_DIR/config/baremetal.c 168 | ``` 169 | 170 | #### 2.2.3. Compiling Bao Hypervisor 171 | With all set, it's time to bring your Bao Hypervisor to life. You now just need to compile it! 172 | ```sh 173 | make -C $BAO_SRCS\ 174 | PLATFORM=qemu-aarch64-virt\ 175 | CONFIG_REPO=$ROOT_DIR/configs\ 176 | CONFIG=baremetal\ 177 | CONFIG_BUILTIN=y\ 178 | CPPFLAGS=-DBAO_WRKDIR_IMGS=$SETUP_BUILD 179 | ``` 180 | 181 | Upon completing these steps, you'll find a binary file in the BAO_SRCS directory, called bao.bin. Now, move the binary file to your build directory (BUILD_BAO_DIR): 182 | 183 | ```sh 184 | cp $BAO_SRCS/bin/qemu-aarch64-virt/baremetal/bao.bin $BUILD_BAO_DIR/bao.bin 185 | ``` 186 | 187 | ## 3. Build Firmware - Powering Up Your Setup 188 | 189 | No journey is truly complete without firmware. It's the fuel that powers your virtual world. That's why we're here to guide you through acquiring the essential firmware tailored to your target platform (you can find the pointer to build the firmware to other platforms [here](https://github.com/bao-project/bao-demos#b5-build-firmware-and-deploy)). 190 | 191 | ### 3.1 Welcome to the QEMU platform! 192 | 193 | Why bother with a hardware platform when you have QEMU? If you haven't got it yet, fret not. We're here to guide you through the process of building and installing it. In this guide, our focus will be on Aarch64 QEMU. 194 | 195 | However, if you're already equipped with qemu-system-aarch64, or if compiling isn't your cup of tea and you'd rather install it directly using a package manager or another method, ensure that you're working with version 7.2.0 or higher. In that case, you can jump ahead to the next step. 196 | 197 | To install QEMU, simply run the following commands: 198 | 199 | ```sh 200 | export QEMU_DIR=$ROOT_DIR/tools/qemu-aarch64 201 | export TOOLS_DIR=$ROOT_DIR/tools/bin 202 | mkdir -p $ROOT_DIR/tools/bin 203 | mkdir -p $TOOLS_DIR 204 | git clone https://github.com/qemu/qemu.git $QEMU_DIR --depth 1\ 205 | --branch v7.2.0 206 | cd $QEMU_DIR 207 | ./configure --target-list=aarch64-softmmu --enable-slirp 208 | make -j$(nproc) 209 | sudo make install 210 | ``` 211 | 212 | ### 3.2 Now you need u-boot 213 | 214 | To build and install u-boot, execute the following commands: 215 | 216 | ```sh 217 | export UBOOT_DIR=$ROOT_DIR/tools/u-boot 218 | git clone https://github.com/u-boot/u-boot.git $UBOOT_DIR --depth 1\ 219 | --branch v2022.10 220 | 221 | cd $UBOOT_DIR 222 | make qemu_arm64_defconfig 223 | 224 | echo "CONFIG_TFABOOT=y" >> .config 225 | echo "CONFIG_SYS_TEXT_BASE=0x60000000" >> .config 226 | 227 | make -j$(nproc) 228 | 229 | cp $UBOOT_DIR/u-boot.bin $TOOLS_DIR 230 | ``` 231 | 232 | ### 3.3 Almost there, let's build TF-A 233 | 234 | One more tool to go! Let's build TF-A: 235 | ```sh 236 | export ATF_DIR=$ROOT_DIR/tools/arm-trusted-firmware 237 | git clone https://github.com/bao-project/arm-trusted-firmware.git\ 238 | $ATF_DIR --branch bao/demo --depth 1 239 | cd $ATF_DIR 240 | make PLAT=qemu bl1 fip BL33=$$TOOLS_DIR/u-boot.bin\ 241 | QEMU_USE_GIC_DRIVER=QEMU_GICV3 242 | dd if=$ATF_DIR/build/qemu/release/bl1.bin\ 243 | of=$TOOLS_DIR/flash.bin 244 | dd if=$ATF_DIR/build/qemu/release/fip.bin\ 245 | of=$TOOLS_DIR/flash.bin seek=64 bs=4096 conv=notrunc 246 | ``` 247 | 248 | 249 | ## 4. Let's Try It Out! - Unleash the Power 250 | 251 | Now that the stage is set, it's time to witness the magic firsthand. Brace yourself as we ignite the virtual flames and bring your creation to life. Get ready for an experience like no other as we embark on this journey: 252 | 253 | :white_check_mark: Build guest (baremetal) 254 | 255 | :white_check_mark: Build bao hypervisor 256 | 257 | :white_check_mark: Build firmware (qemu) 258 | 259 | With all the pieces in place, it's time to launch QEMU and behold the fruits of your labor. The moment of truth awaits, so let's dive right in: 260 | 261 | ```sh 262 | qemu-system-aarch64 -nographic\ 263 | -M virt,secure=on,virtualization=on,gic-version=3 \ 264 | -cpu cortex-a53 -smp 4 -m 4G\ 265 | -bios $TOOLS_DIR/flash.bin \ 266 | -device loader,file="$BUILD_BAO_DIR/bao.bin",addr=0x50000000,force-raw=on\ 267 | -device virtio-net-device,netdev=net0 -netdev user,id=net0,hostfwd=tcp:127.0.0.1:5555-:22\ 268 | -device virtio-serial-device -chardev pty,id=serial3 -device virtconsole,chardev=serial3 269 | ``` 270 | 271 | Now, you should see TF-A and U-boot initialization messages. After, set up connections and jump into the world of Bao. QEMU will reveal the pseudoterminals where it placed the virtio serial. Here's an example: 272 | 273 | ```sh 274 | char device redirected to /dev/pts/4 (label serial3) 275 | ``` 276 | 277 | 278 | 279 | To make the connection, open a fresh terminal window and establish a connection to the specified pseudoterminal. Here's how: 280 | 281 | ```sh 282 | screen /dev/pts/4 283 | ``` 284 | 285 | ![Qemu Boot](/img/TF-A_U-boot.png) 286 | 287 | Finally, make u-boot jump to where the bao image was loaded: 288 | ```sh 289 | go 0x50000000 290 | ``` 291 | 292 | And you should have an output as follows: 293 | 294 | ![System Init](/img/System_Init.png) 295 | 296 | When you want to leave QEMU press `Ctrl-a` then `x`. 297 | 298 | ## 5. Well, Maybe the Setup Was Not Perfect... 299 | 300 | As we continue on this thrilling tour, it's time to explore the art of changing your Bao setup. Mastering the ability to modify your virtual environment opens up endless possibilities. Don't worry if you encounter a few challenges along the way; learning through hands-on experience is the key! 301 | 302 | In the following sections, we'll walk you through step-by-step instructions to make various changes to your guests. By the end of this part of the tour, you'll have a deeper understanding of how the different components interact, and you'll be confidently making adjustments to suit your needs. 303 | 304 | ### 5.1 Add a second guest - freeRTOS 305 | 306 | In this section, we'll delve into various scenarios and demonstrate how to configure specific environments using Bao. One of Bao's notable strengths lies in its flexibility, allowing you to tailor your setup to a range of requirements. 307 | 308 | Let's kick things off by incorporating a second VM running FreeRTOS. 309 | 310 | ![Init Setup](/img/dual-guest-rtos.svg) 311 | 312 | First, we can use the baremetal compiled from the first setup: 313 | ```sh 314 | cp $BAREMETAL_SRCS/build/qemu-aarch64-virt/baremetal.bin $BUILD_GUESTS_DIR/baremetal-freeRTOS-setup/baremetal.bin 315 | ``` 316 | 317 | #### 5.1.1. Compile freeRTOS 318 | Then, let's compile our new guest: 319 | 320 | ```sh 321 | export FREERTOS_SRCS=$ROOT_DIR/freertos 322 | export FREERTOS_PARAMS="STD_ADDR_SPACE=y" 323 | 324 | git clone --recursive --shallow-submodules\ 325 | https://github.com/bao-project/freertos-over-bao.git\ 326 | $FREERTOS_SRCS --branch demo 327 | make -C $FREERTOS_SRCS PLATFORM=qemu-aarch64-virt $FREERTOS_PARAMS 328 | ``` 329 | 330 | Upon completing these steps, you'll find a binary file in the `FREERTOS_SRCS` directory, called `free_rtos.bin`. Move the binary file to your build directory (`BUILD_GUESTS_DIR`): 331 | 332 | ```sh 333 | mkdir -p $BUILD_GUESTS_DIR/baremetal-freeRTOS-setup 334 | cp $FREERTOS_SRCS/build/qemu-aarch64-virt/freertos.bin $BUILD_GUESTS_DIR/baremetal-freeRTOS-setup/free-rtos.bin 335 | ``` 336 | 337 | #### 5.1.2. Integrating the new guest 338 | 339 | Now, we have both guests needed for our setup. However, there are some steps required to fit the two VMs on our platform. Let's understand the differences between the configuration of the first setup and the configuration of the second setup. 340 | 341 | First of all, we need to add the second VM image: 342 | 343 | ```diff 344 | - VM_IMAGE(baremetal_image, XSTR(BAO_WRKDIR_IMGS/guests/baremetal-setup/baremetal.bin)); 345 | + VM_IMAGE(baremetal_image, XSTR(BAO_WRKDIR_IMGS/guests/baremetal-freeRTOS-setup/baremetal.bin)); 346 | + VM_IMAGE(baremetal_image, XSTR(BAO_WRKDIR_IMGS/guests/baremetal-freeRTOS-setup/free-rtos.bin)); 347 | ``` 348 | 349 | Also, since we now have 2 VMs, we need to change the `vm_list_size` in our configuration: 350 | 351 | ```diff 352 | - .vmlist_size = 1, 353 | + .vmlist_size = 2, 354 | ``` 355 | 356 | Next, we need to think about resources. In the first setup, we assigned 4 vCPUs to the baremetal. But this time, we need to split the vCPUs between the two VMs: 357 | 358 | ```diff 359 | - .cpu_num = 4, 360 | + .cpu_num = 2, 361 | ``` 362 | 363 | Additionally, we need to include all the configurations of the second VM. (Details are omitted for simplicity but you can check further details in the [configuration file](configs/baremetal-freeRTOS.c)): 364 | ```diff 365 | + { 366 | + .image = { 367 | + .base_addr = 0x0, 368 | + .load_addr = VM_IMAGE_OFFSET(freertos_image), 369 | + .size = VM_IMAGE_SIZE(freertos_image) 370 | + }, 371 | + 372 | + ... // omitted for simplicity 373 | + }, 374 | ``` 375 | 376 | #### 5.1.3. Let's rebuild Bao! 377 | 378 | As we've seen, changing the guests includes changing the configuration file. Therefore, we need to repeat the process of building Bao. First, copy your configuration file to the working directory with the following commands: 379 | 380 | ```sh 381 | mkdir -p $mkdir -p $BUILD_BAO_DIR/config 382 | cp -L $ROOT_DIR/configs/baremetal-freeRTOS.c\ 383 | $BUILD_BAO_DIR/config/baremetal-freeRTOS.c 384 | ``` 385 | 386 | Then, you just need to compile it. Please note that the flag `CONFIG` defines the configuration file to be used on the compilation of Bao! 387 | 388 | ```sh 389 | make -C $BAO_SRCS\ 390 | PLATFORM=qemu-aarch64-virt\ 391 | CONFIG_REPO=$ROOT_DIR/configs\ 392 | CONFIG=baremetal-freeRTOS\ 393 | CONFIG_BUILTIN=y\ 394 | CPPFLAGS=-DBAO_WRKDIR_IMGS=$SETUP_BUILD 395 | ``` 396 | 397 | Upon completing these steps, you'll find a binary file in the `BAO_SRCS` directory, called `bao.bin`. Move the binary file to your build directory (`BUILD_BAO_DIR`): 398 | 399 | ```sh 400 | cp $BAO_SRCS/bin/qemu-aarch64-virt/baremetal-freeRTOS/bao.bin $BUILD_BAO_DIR/bao.bin 401 | ``` 402 | 403 | #### 5.1.4. Ready for launch! 404 | 405 | Now, we have everything configured for testing our new setup! Just run the following command: 406 | ```sh 407 | qemu-system-aarch64 -nographic\ 408 | -M virt,secure=on,virtualization=on,gic-version=3 \ 409 | -cpu cortex-a53 -smp 4 -m 4G\ 410 | -bios $TOOLS_DIR/flash.bin \ 411 | -device loader,file="$BUILD_BAO_DIR/bao.bin",addr=0x50000000,force-raw=on\ 412 | -device virtio-net-device,netdev=net0 -netdev user,id=net0,hostfwd=tcp:127.0.0.1:5555-:22\ 413 | -device virtio-serial-device -chardev pty,id=serial3 -device virtconsole,chardev=serial3 414 | ``` 415 | 416 | ### 5.2 It was still not perfect right? Let's try out a Linux too 417 | 418 | Let's now introduce a third VM running the Linux OS. 419 | 420 | ![Init Setup](/img/triple-guest.svg) 421 | 422 | First, we can re-use our guests from the previous setup: 423 | ```sh 424 | mkdir -p $BUILD_GUESTS_DIR/baremetal-freeRTOS-linux-setup 425 | cp $BAREMETAL_SRCS/build/qemu-aarch64-virt/baremetal.bin $BUILD_GUESTS_DIR/baremetal-freeRTOS-linux-setup/baremetal.bin 426 | cp $FREERTOS_SRCS/build/qemu-aarch64-virt/freertos.bin $BUILD_GUESTS_DIR/baremetal-freeRTOS-linux-setup/freertos.bin 427 | ``` 428 | 429 | #### 5.2.1 Build Linux Guest 430 | 431 | Now let's start by building our linux guest. Setup linux environment variables: 432 | ```sh 433 | export LINUX_DIR=$ROOT_DIR/linux 434 | export LINUX_REPO=https://github.com/torvalds/linux.git 435 | export LINUX_VERSION=v6.1 436 | 437 | export LINUX_SRCS=$LINUX_DIR/linux-$LINUX_VERSION 438 | 439 | mkdir -p $LINUX_DIR/linux-$LINUX_VERSION 440 | mkdir -p $LINUX_DIR/linux-build 441 | 442 | git clone $LINUX_REPO $LINUX_SRCS\ 443 | --depth 1 --branch $LINUX_VERSION 444 | cd $LINUX_SRCS 445 | git apply $ROOT_DIR/srcs/patches/$LINUX_VERSION/*.patch 446 | ``` 447 | 448 | Setup and environment variable pointing to the target architecture and platform specific config to be used by buildroot: 449 | 450 | ```sh 451 | export LINUX_CFG_FRAG=$(ls $ROOT_DIR/srcs/configs/base.config\ 452 | $ROOT_DIR/srcs/configs/aarch64.config\ 453 | $ROOT_DIR/srcs/configs/qemu-aarch64-virt.config 2> /dev/null) 454 | ``` 455 | 456 | Setup buildroot environment variables: 457 | ```sh 458 | export BUILDROOT_SRCS=$LINUX_DIR/buildroot-aarch64-$LINUX_VERSION 459 | export BUILDROOT_DEFCFG=$ROOT_DIR/srcs/buildroot/aarch64.config 460 | export LINUX_OVERRIDE_SRCDIR=$LINUX_SRCS 461 | ``` 462 | 463 | Clone the latest buildroot at the latest stable version 464 | ```sh 465 | git clone https://github.com/buildroot/buildroot.git $BUILDROOT_SRCS\ 466 | --depth 1 --branch 2022.11 467 | cd $BUILDROOT_SRCS 468 | ``` 469 | 470 | Use our provided buildroot defconfig, which itselfs points to the a Linux kernel defconfig and patches and build 471 | ```sh 472 | make defconfig BR2_DEFCONFIG=$BUILDROOT_DEFCFG 473 | make linux-reconfigure all 474 | 475 | mv $BUILDROOT_SRCS/output/images/Image\ 476 | $BUILDROOT_SRCS/output/images/Image-qemu-aarch64-virt 477 | ``` 478 | The device tree for this setup is available in srcs/devicetrees/qemu-aarch64-virt. For a device tree file named linux.dts define a virtual machine variable and build: 479 | ```sh 480 | export LINUX_VM=linux 481 | dtc $ROOT_DIR/srcs/devicetrees/qemu-aarch64-virt/$LINUX_VM.dts >\ 482 | $LINUX_DIR/linux-build/$LINUX_VM.dtb 483 | ``` 484 | 485 | Wrap the kernel image and device tree blob in a single binary: 486 | ```sh 487 | make -j $(nproc) -C $ROOT_DIR/srcs/lloader\ 488 | ARCH=aarch64\ 489 | IMAGE=$BUILDROOT_SRCS/output/images/Image-qemu-aarch64-virt\ 490 | DTB=$LINUX_DIR/linux-build/$LINUX_VM.dtb\ 491 | TARGET=$LINUX_DIR/linux-build/$LINUX_VM 492 | ``` 493 | 494 | Finaly, copy the binary file to the (compiled) guests folder: 495 | ```sh 496 | cp $LINUX_DIR/linux-build/$LINUX_VM.bin $BUILD_GUESTS_DIR/baremetal-freeRTOS-linux-setup/linux.bin 497 | ``` 498 | 499 | 500 | #### 5.2.2 Welcome our new guest! 501 | 502 | After building our new guest, it's time to integrate in our setup. You can find all the details in the [configuration file](/configs/baremetal-freeRTOS-linux.c). 503 | 504 | After that, we need to load our guests: 505 | ```diff 506 | - VM_IMAGE(baremetal_image, XSTR(BAO_WRKDIR_IMGS/guests/baremetal-freeRTOS-setup/baremetal.bin)); 507 | - VM_IMAGE(freertos_image, XSTR(BAO_WRKDIR_IMGS/guests/baremetal-freeRTOS-setup/free-rtos.bin)); 508 | + VM_IMAGE(baremetal_image, XSTR(BAO_WRKDIR_IMGS/guests/baremetal-freeRTOS-linux-setup/baremetal.bin)); 509 | + VM_IMAGE(freertos_image, XSTR(BAO_WRKDIR_IMGS/guests/baremetal-freeRTOS-linux-setup/free-rtos.bin)); 510 | + VM_IMAGE(linux_image, XSTR(BAO_WRKDIR_IMGS/guests/baremetal-freeRTOS-linux-setup/linux.bin)); 511 | ``` 512 | 513 | Let's now update our VM list size to integrate our new guest: 514 | ```diff 515 | - .vmlist_size = 2, 516 | + .vmlist_size = 3, 517 | ``` 518 | 519 | Then, we need to rearrange the number of vCPUs: 520 | ```diff 521 | // baremetal configuration 522 | { 523 | - .cpu_num = 2, 524 | + .cpu_num = 1, 525 | ... 526 | }, 527 | 528 | // freeRTOS configuration 529 | { 530 | - .cpu_num = 2, 531 | + .cpu_num = 1, 532 | ... 533 | }, 534 | 535 | // linux configuration 536 | { 537 | + .cpu_num = 2, 538 | } 539 | ``` 540 | 541 | #### 5.2.3. Let's rebuild Bao! 542 | 543 | As we've seen, changing the guests includes changing the configuration file. Therefore, we need to repeat the process of building Bao. First, copy your configuration file to the working directory with the following commands: 544 | 545 | ```sh 546 | mkdir -p $mkdir -p $BUILD_BAO_DIR/config 547 | cp -L $ROOT_DIR/configs/baremetal-freeRTOS-linux.c\ 548 | $BUILD_BAO_DIR/config/baremetal-freeRTOS-linux.c 549 | ``` 550 | 551 | Then, you just need to compile it: 552 | ```sh 553 | make -C $BAO_SRCS\ 554 | PLATFORM=qemu-aarch64-virt\ 555 | CONFIG_REPO=$ROOT_DIR/configs\ 556 | CONFIG=baremetal-freeRTOS-linux\ 557 | CONFIG_BUILTIN=y\ 558 | CPPFLAGS=-DBAO_WRKDIR_IMGS=$SETUP_BUILD 559 | ``` 560 | 561 | Upon completing these steps, you'll find a binary file in the `BAO_SRCS` directory, called `bao.bin`. Move the binary file to your build directory (`BUILD_BAO_DIR`): 562 | 563 | ```sh 564 | cp $BAO_SRCS/bin/qemu-aarch64-virt/baremetal-freeRTOS-linux/bao.bin $BUILD_BAO_DIR/bao.bin 565 | ``` 566 | 567 | #### 5.2.4. Ready to go! 568 | 569 | With all the pieces in place, it's time to launch QEMU and behold the fruits of your labor. The moment of truth awaits, so let's dive right in: 570 | 571 | ```sh 572 | qemu-system-aarch64 -nographic\ 573 | -M virt,secure=on,virtualization=on,gic-version=3 \ 574 | -cpu cortex-a53 -smp 4 -m 4G\ 575 | -bios $TOOLS_DIR/flash.bin \ 576 | -device loader,file="$BUILD_BAO_DIR/bao.bin",addr=0x50000000,force-raw=on\ 577 | -device virtio-net-device,netdev=net0 -netdev user,id=net0,hostfwd=tcp:127.0.0.1:5555-:22\ 578 | -device virtio-serial-device -chardev pty,id=serial3 -device virtconsole,chardev=serial3 579 | ``` 580 | 581 | The platform's first available UART is assigned to the baremetal and the FreeRTOS guests. In this manner, you can connect to them using the following command: 582 | ```sh 583 | screen /dev/pts/4 584 | ``` 585 | 586 | The Linux guest is also accessible via ssh at the static address 192.168.42.15. 587 | The password for root is root. 588 | 589 | ## 5.3 Guests must socialize, right? 590 | 591 | In certain scenarios, it's imperative for guests to establish a communication channel. To accomplish this, we'll utilize shared memory and Inter-Process Communication (IPC) mechanisms, allowing the Linux VM to seamlessly interact with the system. 592 | 593 | ![Init Setup](/img/triple-guest-shmem.svg) 594 | 595 | 596 | ### 5.3.1. Add Shared Memory and IPC to our guest 597 | Let's kick off by integrating an IPC into Linux. To do this, we'll make the necessary additions to the Linux device-tree. For simplicity, the [linux-shmem.dts](/configs/baremetal-freeRTOS-linux-shmem.c) file already encompasses the following changes: 598 | 599 | ```diff 600 | + bao-ipc@f0000000 { 601 | + compatible = "bao,ipcshmem"; 602 | + reg = <0x0 0xf0000000 0x0 0x00010000>; 603 | + read-channel = <0x0 0x2000>; 604 | + write-channel = <0x2000 0x2000>; 605 | + interrupts = <0 52 1>; 606 | + id = <0>; 607 | + }; 608 | ``` 609 | 610 | Now, let's generate the updated device tree: 611 | 612 | ```sh 613 | export LINUX_VM=linux-shmem 614 | dtc $ROOT_DIR/srcs/devicetrees/qemu-aarch64-virt/$LINUX_VM.dts >\ 615 | $LINUX_DIR/linux-build/$LINUX_VM.dtb 616 | ``` 617 | 618 | > :warning: **Warning:**: To correctly introduce these changes, you need to ensure that you applied the patch to Linux, as described [before](#521-build-linux-guest). 619 | 620 | Bundle the kernel image and device tree blob into a single binary: 621 | ```sh 622 | make -j $(nproc) -C $ROOT_DIR/srcs/lloader\ 623 | ARCH=aarch64\ 624 | IMAGE=$BUILDROOT_SRCS/output/images/Image-qemu-aarch64-virt\ 625 | DTB=$LINUX_DIR/linux-build/$LINUX_VM.dtb\ 626 | TARGET=$LINUX_DIR/linux-build/$LINUX_VM 627 | ``` 628 | 629 | Finally, move the binary file to the (compiled) guests folder: 630 | ```sh 631 | cp $LINUX_DIR/linux-build/$LINUX_VM.bin $BUILD_GUESTS_DIR/baremetal-freeRTOS-linux-setup/$LINUX_VM.bin 632 | ``` 633 | 634 | ### 5.3.2. Rebuild Bao 635 | 636 | Given that you've modified one of the guests, it's now essential to rebuild Bao: 637 | ```sh 638 | mkdir -p $mkdir -p $BUILD_BAO_DIR/config 639 | cp -L $ROOT_DIR/configs/baremetal-freeRTOS-linux.c\ 640 | $BUILD_BAO_DIR/config/baremetal-freeRTOS-linux.c 641 | ``` 642 | 643 | Subsequently, compile it: 644 | ```sh 645 | make -C $BAO_SRCS\ 646 | PLATFORM=qemu-aarch64-virt\ 647 | CONFIG_REPO=$ROOT_DIR/configs\ 648 | CONFIG=baremetal-freeRTOS-linux\ 649 | CONFIG_BUILTIN=y\ 650 | CPPFLAGS=-DBAO_WRKDIR_IMGS=$SETUP_BUILD 651 | ``` 652 | 653 | Upon successful completion, you'll locate a binary file named bao.bin in the ``BAO_SRCS`` directory. Move it to your build directory (``BUILD_BAO_DIR``): 654 | 655 | ```sh 656 | cp $BAO_SRCS/bin/qemu-aarch64-virt/baremetal-freeRTOS-linux/bao.bin $BUILD_BAO_DIR/bao.bin 657 | ``` 658 | 659 | 660 | ### 5.3.3. Run Our Setup 661 | 662 | Now, you're ready to execute the final setup: 663 | 664 | ```sh 665 | qemu-system-aarch64 -nographic\ 666 | -M virt,secure=on,virtualization=on,gic-version=3 \ 667 | -cpu cortex-a53 -smp 4 -m 4G\ 668 | -bios $TOOLS_DIR/flash.bin \ 669 | -device loader,file="$BUILD_BAO_DIR/bao.bin",addr=0x50000000,force-raw=on\ 670 | -device virtio-net-device,netdev=net0 -netdev user,id=net0,hostfwd=tcp:127.0.0.1:5555-:22\ 671 | -device virtio-serial-device -chardev pty,id=serial3 -device virtconsole,chardev=serial3 672 | ``` 673 | 674 | If all went according to plan, you should be able to spot the IPC on Linux by running the following command: 675 | ```sh 676 | ls /dev 677 | ``` 678 | 679 | You'll see your IPC as depicted in the following image: 680 | ![Init Setup](/img/shmem-IPC.png) 681 | 682 | From here, you can employ the IPC on Linux to dispatch messages to FreeRTOS by writing to ``/dev/baoipc0``: 683 | ```sh 684 | echo "Hello, Bao!" > /dev/baoipc0 685 | ``` 686 | 687 | Or retrieve the latest FreeRTOS message by reading from ``/dev/baoipc0``: 688 | ```sh 689 | cat /dev/baoipc0 690 | ``` 691 | -------------------------------------------------------------------------------- /img/single-guest.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
Hardware
Hardware
VM [Baremetal]
VM [Baremetal]
Hypervisor
Hypervisor
64MiB Memory
64MiB Memory
UART
UART
Timer
Timer
4 vCPU
4 vCPU
Text is not SVG - cannot display
--------------------------------------------------------------------------------