menna@home:~$

How To Enable Optee In Morello Kernel

  1. Follow these steps to run kernel using Morello-SDK container and stop before this step make mrproper && make morello_transitional_pcuabi_defconfig && make

  2. Enable CONFIG_TEE and CONFIG_OPTEE in linux/arch/arm64/configs/morello_transitional_pcuabi_defconfig file.
    CONFIG_TEE=y							
    CONFIG_OPTEE=y
    

    NOTES

    1. CONFIG_TEE and CONFIG_OPTEE dependencies:
    2. This error will be generated after compiling the Morello when enabling CONFIG_TEE and CONFIG_OPTEE:

      /home/morello/workspace/linux/drivers/tee/tee_core.c:851:20: error: incompatible function
      pointer types initializing 'long (*)(struct file *, unsigned int, user_uintptr_t)'
      (aka 'long (*)(struct file *, unsigned int, unsigned __intcap)') with an expression
      of type 'long (struct file *, unsigned int, unsigned long)' [-Werror,-Wincompatible-function-pointer-types]
        .unlocked_ioctl = tee_ioctl,
                                ^~~~~~~~~
      1 error generated.
      make[4]: *** [/home/morello/workspace/linux/scripts/Makefile.build:250: drivers/tee/tee_core.o] Error 1
      make[3]: *** [/home/morello/workspace/linux/scripts/Makefile.build:500: drivers/tee] Error 2
      make[2]: *** [/home/morello/workspace/linux/scripts/Makefile.build:500: drivers] Error 2
      make[1]: *** [/home/morello/workspace/linux/Makefile:1999: .] Error 2
      make[1]: Leaving directory '/home/morello/workspace/linux-out'
      make: *** [Makefile:231: __sub-make] Error 2
      

      Fix it by changing the type unsigned long to user_uintptr_t [ see the following patch ]

      ---
      drivers/tee/tee_core.c | 2 +-
      1 file changed, 1 insertion(+), 1 deletion(-)
            
      diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c
      index 98da206cd761..780a094f16ac 100644
      --- a/drivers/tee/tee_core.c
      +++ b/drivers/tee/tee_core.c
      @@ -815,7 +815,7 @@ static int tee_ioctl_supp_send(struct tee_context *ctx,
            return rc;
      }
            
      -static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
      +static long tee_ioctl(struct file *filp, unsigned int cmd, user_uintptr_t arg)
        {
              struct tee_context *ctx = filp->private_data;
              void __user *uarg = (void __user *)arg;
       -- 
      

      This patch was sent but needs to resend V2, which will happen after successfully running Optee. This till the patch is merged.

  3. Compile Morello kernel make mrproper && make morello_transitional_pcuabi_defconfig && make.

  4. Start setting up optee using this steps.

    In particular:

     mkdir -p <optee-project>
     cd <optee-project>
     repo init -u https://github.com/OP-TEE/manifest.git -m fvp.xml
     repo sync -j4 --no-clone-bundle
    
  5. Then install the morello FVP :

    mkdir -p <optee-project>/morello
    cd <optee-project>/morello
    wget -O FVP_Morello_0.11_34.tgz https://developer.arm.com/-/media/Arm%20Developer%20Community/Downloads/OSS/FVP/Morello%20Platform/FVP_Morello_0.11_34.tgz?rev=5f34837ae6c14ede8493dfc24c9af397&hash=862883120C5638E0B3C5ACA6FDDC5558021E1886
    
    tar -xzvf FVP_Morello_0.11_34.tgz
    ./FVP_Morello.sh --force --destination ./FVP_Morello
       
    Please answer with one of: 'yes' or 'no/quit'
    Do you agree to the above terms and conditions? yes
    
    
  6. Then clone the relevant firmware for the board in :
    cd <optee-project>
    git clone https://git.morello-project.org/morello/fvp-firmware.git
    
    
  7. Then patch the /build/Makefile as follows:
    diff --git a/[fvp.mk](http://fvp.mk/) b/[fvp.mk](http://fvp.mk/)
    index 2f1f658caaad..78f9193903be 100644
    --- a/[fvp.mk](http://fvp.mk/)
    +++ b/[fvp.mk](http://fvp.mk/)
    @@ -52,16 +52,9 @@ else
     EDK2_BUILD		?= RELEASE
     endif
     EDK2_BIN		?= $(EDK2_PLATFORMS_PATH)/Build/ArmVExpress-FVP-AArch64/$(EDK2_BUILD)_$(EDK2_TOOLCHAIN)/FV/FVP_$(EDK2_ARCH)_EFI.fd
    -FVP_USE_BASE_PLAT	?= n
    -ifeq ($(FVP_USE_BASE_PLAT),y)
    -FVP_PATH		?= $(ROOT)/Base_RevC_AEMvA_pkg/models/Linux64_GCC-9.3
    -FVP_BIN			?= FVP_Base_RevC-2xAEMvA
    +FVP_PATH		?= $(ROOT)/morello/FVP_Morello/models/Linux64_GCC-6.4/
    +FVP_BIN			?= FVP_Morello
     FVP_LINUX_DTB		?= $(LINUX_PATH)/arch/arm64/boot/dts/arm/fvp-base-revc.dtb
    -else
    -FVP_PATH		?= $(ROOT)/Foundation_Platformpkg/models/Linux64_GCC-9.3
    -FVP_BIN			?= Foundation_Platform
    -FVP_LINUX_DTB		?= $(LINUX_PATH)/arch/arm64/boot/dts/arm/foundation-v8-gicv3-psci.dtb
    -endif
     ifeq ($(wildcard $(FVP_PATH)),)
     $(error $(FVP_PATH) does not exist)
     endif
    @@ -302,39 +295,26 @@
     run: all
     	$(MAKE) run-only
        
    -ifeq ($(FVP_USE_BASE_PLAT),y)
    -FVP_ARGS ?= \
    -	-C bp.ve_sysregs.exit_on_shutdown=1 \
    -	-C cache_state_modelled=0 \
    -	-C pctl.startup=0.0.0.0 \
    -	-C cluster0.NUM_CORES=4 \
    -	-C cluster1.NUM_CORES=4 \
    -	-C cluster0.cpu0.enable_crc32=1 \
    -	-C cluster0.cpu1.enable_crc32=1 \
    -	-C cluster0.cpu2.enable_crc32=1 \
    -	-C cluster0.cpu3.enable_crc32=1 \
    -	-C cluster1.cpu0.enable_crc32=1 \
    -	-C cluster1.cpu1.enable_crc32=1 \
    -	-C cluster1.cpu2.enable_crc32=1 \
    -	-C cluster1.cpu3.enable_crc32=1 \
    -	-C bp.secure_memory=1 \
    -	-C bp.secureflashloader.fname=$(TF_A_PATH)/build/fvp/$(TF_A_BUILD)/bl1.bin \
    -	-C bp.flashloader0.fname=$(TF_A_PATH)/build/fvp/$(TF_A_BUILD)/fip.bin \
    -	-C bp.virtioblockdevice.image_path=$(BOOT_IMG)
    -ifeq ($(FVP_VIRTFS_ENABLE),y)
    -	FVP_ARGS += -C bp.virtiop9device.root_path=$(FVP_VIRTFS_HOST_DIR)
    -endif
    -else
     FVP_ARGS ?= \
    -	--arm-v8.0 \
    -	--cores=4 \
    -	--secure-memory \
    -	--visualization \
    -	--gicv3 \
    -	--data="$(TF_A_PATH)/build/fvp/$(TF_A_BUILD)/bl1.bin"@0x0 \
    -	--data="$(TF_A_PATH)/build/fvp/$(TF_A_BUILD)/fip.bin"@0x8000000 \
    -	--block-device=$(BOOT_IMG)
    -endif
    +        --data Morello_Top.css.scp.armcortexm7ct=../fvp-firmware/scp_romfw.bin@0x0 \
    +        --data Morello_Top.css.mcp.armcortexm7ct=../fvp-firmware/mcp_romfw.bin@0x0 \
    +        -C Morello_Top.soc.scp_qspi_loader.fname=../fvp-firmware/scp_fw.bin \
    +        -C Morello_Top.soc.mcp_qspi_loader.fname=../fvp-firmware/mcp_fw.bin \
    +        -C css.scp.armcortexm7ct.INITVTOR=0x0 \
    +        -C css.mcp.armcortexm7ct.INITVTOR=0x0 \
    +        -C css.trustedBootROMloader.fname=../fvp-firmware/bl1.bin \
    +        -C board.ap_qspi_loader.fname=../fvp-firmware/fip.bin \
    +        -C board.virtioblockdevice.image_path=$(BOOT_IMG) \
    +        -C css.pl011_uart_ap.unbuffered_output=1 \
    +        -C displayController=1 \
    +        -C board.virtio_rng.enabled=1 \
    +        -C board.virtio_rng.seed=0 \
    +        -C num_clusters=2 \
    +        -C num_cores=2 \
    +        -C board.virtio_net.hostbridge.userNetworking=1 \
    +        -C board.virtio_net.enabled=1 \
    +        -C board.virtio_net.transport=legacy \
    +        -C board.virtio_net.hostbridge.userNetPorts=5555=5555
        
     run-only:
     	$(FVP_PATH)/$(FVP_BIN) $(FVP_ARGS) $(FVP_EXTRA_ARGS)
    
    
  8. After that:
     cd <optee-project>/build
     make -j2 toolchains
     make -j `nproc`
    

    After this step is complete you should be able to start the model and see the optee image booting issuing the command “make run-only” from /build. It will fail because you do not have the correct kernel and the correct device tree.

  9. To install the correct kernel and device tree you need to mount the “boot-fat.uefi.img” image as follows:
      cd <optee-project>/out
      mkdir -p mnt
      sudo mount -o loop boot-fat.uefi.img mnt/
      cd mnt
    
  10. Copy here the Morello kernel Image that was created from step 3 linux-out/arch/arm64/boot/Image and dtb file “morello-fvp.dtb” found here linux-out/arch/arm64/boot/dts/arm/morello-fvp.dtb which you need to rename into “fvp.dtb” in mnt directory.

    making sure that they are named “Image” and “fvp.dtb”.

  11. Then Sync sync.
  12. Back to out directory then unmount sudo umount mnt.
  13. Go again in /build and issue `make run-only` the FVP will run with Morello kernel and to check run `uname -a` to check kernel name.
  14. Run xtest to test OPTEE.

This command will fail, The problem is the Optee driver is not loaded. I posted this Github issue and added the following part to the Morello FVP device tree

	firmware {
		optee {
			compatible = "linaro,optee-tz";
			method = "smc";
		};
	};

As mentioned in the GitHub issue, this did not fix the problem. So, I think it will work by adding a new platform as mentioned here, because Optee supports these platforms only.

Here are more examples of porting to a new platform.

Suggested-By: Vincenzo Frascino vincenzo.frascino@arm.com