Changeset 06f10ac in mainline


Ignore:
Timestamp:
2021-08-22T19:08:44Z (3 years ago)
Author:
Martin Decky <martin@…>
Branches:
master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c21cc26
Parents:
95b7d4df
Message:

Implement support for HiKey 960

Initial support for the 96Boards HiKey 960 board.

  • The kernel identity mapping has been extended to 4 GiB. The initial bootstrap mapping maps 3 GiB as nornal memory and the next 1 GiB as device memory to support early UART debugging output.
  • The istate_t has been padded in order to preserve the stack pointer alignment invariant.

The current implementation is limited to UP and UART input/output.

Files:
6 added
17 edited
2 moved

Legend:

Unmodified
Added
Removed
  • HelenOS.config

    r95b7d4df r06f10ac  
    6868% Machine type
    6969@ "virt" QEMU virt
     70@ "hikey960" HiKey 960
    7071! [PLATFORM=arm64] MACHINE (choice)
    7172
     
    509510
    510511% Support for PL011 UART
    511 ! [CONFIG_HID_OUT=generic|(PLATFORM=arm64&MACHINE=virt)] CONFIG_PL011_UART (y)
     512! [CONFIG_HID_OUT=generic|(PLATFORM=arm64&(MACHINE=virt|MACHINE=hikey960))] CONFIG_PL011_UART (y)
    512513
    513514% Support for NS16550 controller (kernel console)
     
    539540
    540541% Support for ARM GICv2
    541 ! [PLATFORM=arm64&MACHINE=virt] CONFIG_GICV2 (y)
     542! [PLATFORM=arm64&(MACHINE=virt|MACHINE=hikey960)] CONFIG_GICV2 (y)
    542543
    543544% Support for i8042 controller
  • boot/arch/arm64/include/arch/arch.h

    r95b7d4df r06f10ac  
    4141
    4242#define BOOT_OFFSET  0x80000
     43
    4344#ifndef __ASSEMBLER__
    44 #define KA2PA(x)  (((uintptr_t) (x)) - UINT64_C(0xffffffff80000000))
     45#define KA2PA(x)  (((uintptr_t) (x)) - UINT64_C(0xffffffff00000000))
    4546#endif
    4647
  • boot/arch/arm64/meson.build

    r95b7d4df r06f10ac  
    2929BUILD = true
    3030
    31 POST_OUTPUT = 'image.iso'
    32 POSTBUILD = 'grub'
    33 GRUB_LOADER = 'chainloader'
     31if MACHINE == 'virt'
     32        POST_OUTPUT = 'image.iso'
     33        POSTBUILD = 'grub'
     34        GRUB_LOADER = 'chainloader'
     35endif
     36
     37if MACHINE == 'hikey960'
     38        POSTBUILD = 'raw'
     39        POST_OUTPUT = 'image.boot'
     40endif
    3441
    3542# Request binary output. The ARM64 port manually prepares the .text
  • kernel/arch/arm64/include/arch/barrier.h

    r95b7d4df r06f10ac  
    3737#define KERN_arm64_BARRIER_H_
    3838
    39 #include <stddef.h>
    40 
    41 #define COHERENCE_INVAL_MIN  4
    42 
    43 /** Ensure visibility of instruction updates for a multiprocessor.
    44  *
    45  * @param addr Address of the first instruction.
    46  * @param size Size of the instruction block (in bytes).
    47  */
    48 static inline void ensure_visibility(void *addr, size_t len)
    49 {
    50         size_t i;
    51 
    52         /*
    53          * Clean to Point of Unification to make the new instructions visible to
    54          * the instruction cache.
    55          */
    56         for (i = 0; i < len; i += COHERENCE_INVAL_MIN)
    57                 asm volatile (
    58                     "dc cvau, %[addr]\n"
    59                     : : [addr] "r" ((char *) addr + i)
    60                 );
    61 
    62         /* Ensure completion on all PEs. */
    63         asm volatile ("dsb ish" ::: "memory");
    64 
    65         /* Ensure instruction cache/branch predictor discards stale data. */
    66         for (i = 0; i < len; i += COHERENCE_INVAL_MIN)
    67                 asm volatile (
    68                     "ic ivau, %[addr]\n"
    69                     : : [addr] "r" ((char *) addr + i)
    70                 );
    71 
    72         /* Ensure completion on all PEs. */
    73         asm volatile ("dsb ish" ::: "memory");
    74 
    75         /* Synchronize context on this PE. */
    76         asm volatile ("isb");
    77 }
    78 
    7939#endif
    8040
  • kernel/arch/arm64/include/arch/istate_struct.h

    r95b7d4df r06f10ac  
    6565#define ISTATE_OFFSET_X29    0x108
    6666#define ISTATE_OFFSET_X30    0x110
    67 #define ISTATE_SIZE          0x118
     67#define ISTATE_OFFSET_PAD0   0x118
     68#define ISTATE_SIZE          0x120
    6869
    6970#ifndef __ASSEMBLER__
     
    109110        /* Link Register. */
    110111        uint64_t x30;
     112
     113        /*
     114         * ARM64 mandates that the stack pointer is always aligned to
     115         * a 16-byte boundary. To satisfy this condition, the size of
     116         * this data structure needs to be also a multiple of 16 bytes.
     117         * This is the reason for this padding.
     118         */
     119        uint64_t pad0;
    111120} istate_t;
    112121
    113122#endif
     123
    114124#endif
  • kernel/arch/arm64/include/arch/mach/hikey960/hikey960.h

    r95b7d4df r06f10ac  
    11/*
    2  * Copyright (c) 2019 Petr Pavlu
     2 * Copyright (c) 2021 Martin Decky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 #include <arch/barrier.h>
    30 #include <barrier.h>
     29/** @addtogroup kernel_arm64_hikey960
     30 * @brief HiKey 960 platform.
     31 * @ingroup kernel_arm64
     32 * @{
     33 */
     34/** @file
     35 * @brief HiKey 960 platform driver.
     36 */
    3137
    32 void smc_coherence(void *a, size_t l)
    33 {
    34         ensure_visibility(a, l);
    35 }
     38#ifndef KERN_arm64_mach_hikey960_H_
     39#define KERN_arm64_mach_hikey960_H_
     40
     41#include <arch/machine_func.h>
     42
     43extern struct arm_machine_ops hikey960_machine_ops;
     44
     45#endif
     46
     47/** @}
     48 */
  • kernel/arch/arm64/include/arch/mach/virt/virt.h

    r95b7d4df r06f10ac  
    3636 */
    3737
    38 #ifndef KERN_arm64_virt_H_
    39 #define KERN_arm64_virt_H_
     38#ifndef KERN_arm64_mach_virt_H_
     39#define KERN_arm64_mach_virt_H_
    4040
    4141#include <arch/machine_func.h>
  • kernel/arch/arm64/include/arch/mm/km.h

    r95b7d4df r06f10ac  
    4141#include <typedefs.h>
    4242
    43 #define KM_ARM64_IDENTITY_START  UINT64_C(0xffffffff80000000)
    44 #define KM_ARM64_IDENTITY_SIZE   UINT64_C(0x0000000080000000)
     43#define KM_ARM64_IDENTITY_START  UINT64_C(0xffffffff00000000)
     44#define KM_ARM64_IDENTITY_SIZE   UINT64_C(0x0000000100000000)
    4545
    4646#define KM_ARM64_NON_IDENTITY_START  UINT64_C(0xffff000000000000)
    47 #define KM_ARM64_NON_IDENTITY_SIZE   UINT64_C(0x0000ffff80000000)
     47#define KM_ARM64_NON_IDENTITY_SIZE   UINT64_C(0x0000ffff00000000)
    4848
    4949extern void km_identity_arch_init(void);
     
    5353#else /* __ASSEMBLER__ */
    5454
    55 #define KM_ARM64_IDENTITY_START  0xffffffff80000000
    56 #define KM_ARM64_IDENTITY_SIZE   0x0000000080000000
     55#define KM_ARM64_IDENTITY_START  0xffffffff00000000
     56#define KM_ARM64_IDENTITY_SIZE   0x0000000100000000
    5757
    5858#define KM_ARM64_NON_IDENTITY_START  0xffff000000000000
    59 #define KM_ARM64_NON_IDENTITY_SIZE   0x0000ffff80000000
     59#define KM_ARM64_NON_IDENTITY_SIZE   0x0000ffff00000000
    6060
    6161#endif /* __ASSEMBLER__ */
  • kernel/arch/arm64/include/arch/mm/page.h

    r95b7d4df r06f10ac  
    5353
    5454#define KA2PA(x) \
    55         (((uintptr_t) (x)) - UINT64_C(0xffffffff80000000) + physmem_base)
     55        (((uintptr_t) (x)) - UINT64_C(0xffffffff00000000) + physmem_base)
    5656#define PA2KA(x) \
    57         (((uintptr_t) (x)) + UINT64_C(0xffffffff80000000) - physmem_base)
     57        (((uintptr_t) (x)) + UINT64_C(0xffffffff00000000) - physmem_base)
    5858
    5959#endif /* __ASSEMBLER__ */
  • kernel/arch/arm64/meson.build

    r95b7d4df r06f10ac  
    4444        'src/mm/page.c',
    4545        'src/mm/tlb.c',
    46         'src/smc.c',
    4746        'src/smp/ipi.c',
    4847        'src/smp/smp.c',
     
    5251if MACHINE == 'virt'
    5352        arch_src += files('src/mach/virt/virt.c')
     53endif
     54
     55if MACHINE == 'hikey960'
     56        arch_src += files('src/mach/hikey960/hikey960.c')
    5457endif
    5558
  • kernel/arch/arm64/src/asm.S

    r95b7d4df r06f10ac  
    5959        ret
    6060FUNCTION_END(early_putuchar)
     61
     62/** Flush instruction caches
     63 *
     64 * @param x0 Starting address of the flushing.
     65 * @param x1 Number of bytes to flush.
     66 *
     67 */
     68FUNCTION_BEGIN(smc_coherence)
     69        /* Initialize loop */
     70        mov x9, x0
     71        mov x10, xzr
     72
     73        __dc_loop:
     74                /* Data or Unified Cache Line Clean */
     75                dc cvau, x9
     76                add x9, x9, #4
     77                add x10, x10, #4
     78                cmp x10, x1
     79                blo __dc_loop
     80
     81        dsb ish
     82
     83        /* Initialize loop */
     84        mov x9, x0
     85        mov x10, xzr
     86
     87        __ic_loop:
     88                /* Instruction Cache Line Invalidate */
     89                ic ivau, x9
     90                add x9, x9, #4
     91                add x10, x10, #4
     92                cmp x10, x1
     93                blo __ic_loop
     94
     95        dsb ish
     96        isb
     97        ret
     98FUNCTION_END(smc_coherence)
    6199
    62100/* Static checks for the istate_t save/load. */
  • kernel/arch/arm64/src/machine_func.c

    r95b7d4df r06f10ac  
    3737
    3838#include <arch/machine_func.h>
     39#include <arch/mach/hikey960/hikey960.h>
    3940#include <arch/mach/virt/virt.h>
    4041
     
    4748#if defined(MACHINE_virt)
    4849        machine_ops = &virt_machine_ops;
     50#elif defined(MACHINE_hikey960)
     51        machine_ops = &hikey960_machine_ops;
    4952#else
    5053#error Machine type not defined.
  • kernel/arch/arm64/src/start.S

    r95b7d4df r06f10ac  
    3535.section K_TEXT_START, "ax"
    3636
     37.macro dcache_flush addr size temp0 temp1
     38        mov \temp0, \addr
     39        mov \temp1, xzr
     40
     41        0:
     42                /* Data or Unified Cache Line Clean */
     43                dc cvau, \temp0
     44                add \temp0, \temp0, #4
     45                add \temp1, \temp1, #4
     46                cmp \temp1, \size
     47                blo 0b
     48
     49        dsb ish
     50        isb
     51.endm
     52
     53/** Kernel entry
     54 *
     55 * MMU must be disabled at this point.
     56 *
     57 * @param x0 Kernel entry point (kernel_image_start).
     58 * @param x1 Pointer to the bootinfo structure.
     59 *
     60 */
    3761SYMBOL(kernel_image_start)
    38         /*
    39          * Parameters:
    40          * x0 is kernel entry point (kernel_image_start).
    41          * x1 is pointer to the bootinfo structure.
    42          *
    43          * MMU must be disabled at this point.
    44          */
    45 
    4662        /* Get address of the main memory and remember it. */
    4763        adrp x20, kernel_image_start - BOOT_OFFSET
    4864        adrp x2, physmem_base
    49         /* add x2, x2, #:lo12:physmem_base */
    5065        str x20, [x2]
    5166
    52         /*
    53          * Set up address translation that identity maps the gigabyte area that
     67        /* Flush the data cache of physmem_base. */
     68        mov x28, #8
     69        dcache_flush x2 x28 x29 x30
     70
     71        /*
     72         * Set up address translation that identity maps the 1 GiB area that
    5473         * is holding the current execution page.
    5574         */
     
    7695        mov x3, #( \
    7796            1 << PTE_ACCESS_SHIFT | \
    78             MAIR_EL1_DEVICE_MEMORY_INDEX << PTE_ATTR_INDEX_SHIFT | \
     97            MAIR_EL1_NORMAL_MEMORY_INDEX << PTE_ATTR_INDEX_SHIFT | \
    7998            PTE_L012_TYPE_BLOCK << PTE_TYPE_SHIFT | \
    8099            1 << PTE_PRESENT_SHIFT)
     
    84103
    85104        /*
    86          * Set up address translation that maps the first gigabyte of the kernel
    87          * identity virtual address space to the first gigabyte of the physical
     105         * Set up address translation that maps the first 4 GiB of the kernel
     106         * identity virtual address space to the first 4 GiB of the physical
    88107         * memory.
    89108         */
    90109
    91110        mov x21, #KM_ARM64_IDENTITY_START
     111        ldr x22, =(1024 * 1024 * 1024)
    92112
    93113        /* Prepare the level 0 page table. */
     
    112132        mov x3, #( \
    113133            1 << PTE_ACCESS_SHIFT | \
     134            MAIR_EL1_NORMAL_MEMORY_INDEX << PTE_ATTR_INDEX_SHIFT | \
     135            PTE_L012_TYPE_BLOCK << PTE_TYPE_SHIFT | \
     136            1 << PTE_PRESENT_SHIFT)
     137        lsr x4, x20, #FRAME_WIDTH
     138        orr x3, x3, x4, lsl #PTE_OUTPUT_ADDRESS_SHIFT
     139        str x3, [x2]
     140
     141        /* 2nd GiB */
     142        add x23, x20, x22
     143        add x24, x21, x22
     144
     145        adrp x2, upper_page_table_level1
     146        lsr x3, x24, #PTL1_VA_SHIFT
     147        and x3, x3, #PTL1_VA_MASK
     148        add x2, x2, x3, lsl #PTL_ENTRY_SIZE_SHIFT
     149        mov x3, #( \
     150            1 << PTE_ACCESS_SHIFT | \
     151            MAIR_EL1_NORMAL_MEMORY_INDEX << PTE_ATTR_INDEX_SHIFT | \
     152            PTE_L012_TYPE_BLOCK << PTE_TYPE_SHIFT | \
     153            1 << PTE_PRESENT_SHIFT)
     154        lsr x4, x23, #FRAME_WIDTH
     155        orr x3, x3, x4, lsl #PTE_OUTPUT_ADDRESS_SHIFT
     156        str x3, [x2]
     157
     158        /* 3rd GiB */
     159        add x23, x23, x22
     160        add x24, x24, x22
     161
     162        adrp x2, upper_page_table_level1
     163        lsr x3, x24, #PTL1_VA_SHIFT
     164        and x3, x3, #PTL1_VA_MASK
     165        add x2, x2, x3, lsl #PTL_ENTRY_SIZE_SHIFT
     166        mov x3, #( \
     167            1 << PTE_ACCESS_SHIFT | \
     168            MAIR_EL1_NORMAL_MEMORY_INDEX << PTE_ATTR_INDEX_SHIFT | \
     169            PTE_L012_TYPE_BLOCK << PTE_TYPE_SHIFT | \
     170            1 << PTE_PRESENT_SHIFT)
     171        lsr x4, x23, #FRAME_WIDTH
     172        orr x3, x3, x4, lsl #PTE_OUTPUT_ADDRESS_SHIFT
     173        str x3, [x2]
     174
     175        /* 4th GiB */
     176        add x23, x23, x22
     177        add x24, x24, x22
     178
     179        adrp x2, upper_page_table_level1
     180        lsr x3, x24, #PTL1_VA_SHIFT
     181        and x3, x3, #PTL1_VA_MASK
     182        add x2, x2, x3, lsl #PTL_ENTRY_SIZE_SHIFT
     183        mov x3, #( \
     184            1 << PTE_ACCESS_SHIFT | \
    114185            MAIR_EL1_DEVICE_MEMORY_INDEX << PTE_ATTR_INDEX_SHIFT | \
    115186            PTE_L012_TYPE_BLOCK << PTE_TYPE_SHIFT | \
    116187            1 << PTE_PRESENT_SHIFT)
    117         lsr x4, x20, #FRAME_WIDTH
    118         orr x3, x3, x4, lsl #PTE_OUTPUT_ADDRESS_SHIFT
    119         str x3, [x2]
     188        lsr x4, x23, #FRAME_WIDTH
     189        orr x3, x3, x4, lsl #PTE_OUTPUT_ADDRESS_SHIFT
     190        str x3, [x2]
     191
     192        /* Flush the data cache of page tables. */
     193        adrp x27, lower_page_table_level0
     194        mov x28, #4096
     195        dcache_flush x27 x28 x29 x30
     196
     197        adrp x27, lower_page_table_level1
     198        mov x28, #4096
     199        dcache_flush x27 x28 x29 x30
     200
     201        adrp x27, upper_page_table_level0
     202        mov x28, #4096
     203        dcache_flush x27 x28 x29 x30
     204
     205        adrp x27, upper_page_table_level1
     206        mov x28, #4096
     207        dcache_flush x27 x28 x29 x30
    120208
    121209        /* Make sure there are not any stale TLB entries. */
     
    271359lower_page_table_level0:
    272360        .space 4096
     361
    273362lower_page_table_level1:
    274363        .space 4096
     364
    275365upper_page_table_level0:
    276366        .space 4096
     367
    277368upper_page_table_level1:
    278369        .space 4096
  • meson/arch/arm64/meson.build

    r95b7d4df r06f10ac  
    3232arch_uspace_link_args = [ '-nostdlib', '-lgcc' ]
    3333
    34 
    3534# UEFI binaries should be relocatable, the EFI boot service LoadImage() will
    3635# rebase the boot file using the .reloc information in the image if it cannot
     
    4645arch_boot_link_args = [ '-Wl,-shared', '-Wl,--no-gc-sections' ]
    4746
    48 
    4947if MACHINE == 'virt'
    5048        rd_essential += [
     
    5452        ]
    5553endif
     54
     55if MACHINE == 'hikey960'
     56        rd_essential += [
     57                'drv/char/pl011',
     58                'drv/intctl/gicv2',
     59                'drv/platform/hikey960',
     60        ]
     61endif
  • tools/ew.py

    r95b7d4df r06f10ac  
    144144                        return 'system-arm', '-M raspi1ap'
    145145        elif platform == 'arm64':
    146                 # Search for the EDK2 firmware image
    147                 default_paths = (
    148                         '/usr/local/qemu-efi-aarch64/QEMU_EFI.fd', # Custom
    149                         '/usr/share/edk2/aarch64/QEMU_EFI.fd',     # Fedora
    150                         '/usr/share/qemu-efi-aarch64/QEMU_EFI.fd', # Ubuntu
    151                 )
    152                 extra_info = ("Pre-compiled binary can be obtained from "
    153                     "http://snapshots.linaro.org/components/kernel/leg-virt-tianocore-edk2-upstream/latest/QEMU-AARCH64/RELEASE_GCC5/QEMU_EFI.fd.\n")
    154                 efi_path = find_firmware(
    155                     "EDK2", 'EW_QEMU_EFI_AARCH64', default_paths, extra_info)
    156                 if efi_path is None:
    157                         raise Exception
    158 
    159                 return 'system-aarch64', \
    160                     '-M virt -cpu cortex-a57 -m 1024 -bios %s' % efi_path
     146                if machine == 'virt':
     147                        # Search for the EDK2 firmware image
     148                        default_paths = (
     149                                '/usr/local/qemu-efi-aarch64/QEMU_EFI.fd', # Custom
     150                                '/usr/share/edk2/aarch64/QEMU_EFI.fd',     # Fedora
     151                                '/usr/share/qemu-efi-aarch64/QEMU_EFI.fd', # Ubuntu
     152                        )
     153                        extra_info = ("Pre-compiled binary can be obtained from "
     154                            "http://snapshots.linaro.org/components/kernel/leg-virt-tianocore-edk2-upstream/latest/QEMU-AARCH64/RELEASE_GCC5/QEMU_EFI.fd.\n")
     155                        efi_path = find_firmware(
     156                            "EDK2", 'EW_QEMU_EFI_AARCH64', default_paths, extra_info)
     157                        if efi_path is None:
     158                                raise Exception
     159
     160                        return 'system-aarch64', \
     161                            '-M virt -cpu cortex-a57 -m 1024 -bios %s' % efi_path
    161162        elif platform == 'ia32':
    162163                return 'system-i386', pc_options(32)
  • uspace/drv/meson.build

    r95b7d4df r06f10ac  
    7878        'platform/amdm37x',
    7979        'platform/arm64virt',
     80        'platform/hikey960',
    8081        'platform/icp',
    8182        'platform/mac',
  • uspace/srv/hid/input/input.c

    r95b7d4df r06f10ac  
    641641        kbd_add_dev(&chardev_port, &stty_ctl);
    642642#endif
     643#if defined(UARCH_arm64) && defined(MACHINE_hikey960)
     644        kbd_add_dev(&chardev_port, &stty_ctl);
     645#endif
    643646        /* Silence warning on abs32le about kbd_add_dev() being unused */
    644647        (void) kbd_add_dev;
  • uspace/srv/hid/output/port/chardev.c

    r95b7d4df r06f10ac  
    218218#elif defined(UARCH_arm64) && defined(MACHINE_virt)
    219219                /* OK */
     220#elif defined(UARCH_arm64) && defined(MACHINE_hikey960)
     221                /* OK */
    220222#else
    221223                return EOK;
Note: See TracChangeset for help on using the changeset viewer.