* [PATCH 2/6] clk: sunxi-ng: set the parent rate when adjustin CPUX clock on A33
From: Maxime Ripard @ 2016-12-14 9:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <306991481662454@web33j.yandex.ru>
On Wed, Dec 14, 2016 at 04:54:14AM +0800, Icenowy Zheng wrote:
>
>
> 13.12.2016, 23:44, "Maxime Ripard" <maxime.ripard@free-electrons.com>:
> > On Tue, Dec 13, 2016 at 11:22:48PM +0800, Icenowy Zheng wrote:
> >> ?The CPUX clock on A33, which is for the Cortex-A7 cores, is designed to
> >> ?be changeable by changing the rate of PLL_CPUX.
> >>
> >> ?Add CLK_SET_RATE_PARENT flag to this clock.
> >>
> >> ?Signed-off-by: Icenowy Zheng <icenowy@aosc.xyz>
> >
> > Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>
> Excuse me, have you merged this patch?
Yes, sorry, that's what I meant :)
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161214/f4ba7e80/attachment.sig>
^ permalink raw reply
* [PATCH 1/2] arm64: Add enable/disable d-cache support for purgatory
From: Pratyush Anand @ 2016-12-14 9:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5838834D.90205@arm.com>
Hi James,
Thanks a lot for your review. Its helpful.
On Saturday 26 November 2016 12:00 AM, James Morse wrote:
> Hi Pratyush,
>
> (CC: Mark, mismatched memory attributes in paragraph 3?)
>
> On 22/11/16 04:32, Pratyush Anand wrote:
>> This patch adds support to enable/disable d-cache, which can be used for
>> faster purgatory sha256 verification.
>
> (I'm not clear why we want the sha256, but that is being discussed elsewhere on
> the thread)
>
>
>> We are supporting only 4K and 64K page sizes. This code will not work if a
>> hardware is not supporting at least one of these page sizes. Therefore,
>> D-cache is disabled by default and enabled only when "enable-dcache" is
>> passed to the kexec().
>
> I don't think the maybe-4K/maybe-64K/maybe-neither logic is needed. It would be
> a lot simpler to only support one page size, which should be 4K as that is what
> UEFI requires. (If there are CPUs that only support one size, I bet its 4K!)
Ok.. So, I will implement a new version after considering that 4K will
always be supported. If 4K is not supported by hw(which is very
unlikely) then there would be no d-cache enabling feature.
>
> I would go as far as to generate the page tables at 'kexec -l' time, and only if
Ok..So you mean that I create a new section which will have page table
entries mapping physicalmemory represented by remaining section, and
then purgatory can just enable mmu with page table from that section,
right? Seems doable. can do that.
> '/sys/firmware/efi' exists to indicate we booted via UEFI. (and therefore must
> support 4K pages). This would keep the purgatory code as simple as possible.
What about reading ID_AA64MMFR0_EL1 instead of /sys/firmware/efi? That
can also tell us that whether 4K is supported or not?
>
> I don't think the performance difference between 4K and 64K page sizes will be
> measurable, is purgatory really performance sensitive code?
I agree, implementing only 4K will make it very simple.
>
>
>> Since this is an identity mapped system, so VA_BITS will be same as max PA
>> bits supported. If VA_BITS <= 42 for 64K and <= 39 for 4K then only one
>> level of page table will be there with block descriptor entries.
>> Otherwise, For 4K mapping, TTBR points to level 0 lookups, which will have
>> only table entries pointing to a level 1 lookup. Level 1 will have only
>> block entries which will map 1GB block. For 64K mapping, TTBR points to
>> level 1 lookups, which will have only table entries pointing to a level 2
>> lookup. Level 2 will have only block entries which will map 512MB block. If
>
> This is more complexity to pick a VA size. Why not always use the maximum 48bit
> VA? The cost is negligible compared to having simpler (easier to review!)
> purgatory code.
>
> By always using 1GB blocks you may be creating aliases with mismatched attributes:
> * If kdump only reserves 128MB, your 1GB mapping will alias whatever else was
> in the same 1GB of address space. This could be a reserved region with some
> other memory attributes.
> * With kdump, we may have failed to park the other CPUs if they are executing
> with interrupts masked and haven't yet handled the smp_send_stop() IPI.
> * One of these other CPUs could be reading/writing in this area as it doesn't
> belong to the kdump reserved area, just happens to be in the same 1GB.
>
> I need to dig through the ARM-ARM to find out what happens next, but I'm pretty
> sure this is well into the "don't do that" territory.
>
>
> It would be much better to force the memory areas to be a multiple of 2MB and
> 2MB aligned, which will allow you to use 2M section mappings for memory, (but
> not the uart). This way we only map regions we had reserved and know are memory.
OK. So, 48 bit VA, 4K page size, 3 level page table with entries in 3rd
level representing 2M block size.
>
>
>> UART base address and RAM addresses are not at least 1GB and 512MB apart
>> for 4K and 64K respectively, then mapping result could be unpredictable. In
>> that case we need to support one more level of granularity, but until
>> someone needs that keep it like this only.
>>
>> We can not allocate dynamic memory in purgatory. Therefore we keep page
>> table allocation size fixed as (3 * MAX_PAGE_SIZE). (page_table) points to
>> first level (having only table entries) and (page_table + MAX_PAGE_SIZE)
>> points to table at next level (having block entries). If index for RAM
>> area and UART area in first table is not same, then we will need another
>> next level table which will be located at (page_table + 2 * MAX_PAGE_SIZE).
>
>
>> diff --git a/purgatory/arch/arm64/cache-asm.S b/purgatory/arch/arm64/cache-asm.S
>> new file mode 100644
>> index 000000000000..bef97ef48888
>> --- /dev/null
>> +++ b/purgatory/arch/arm64/cache-asm.S
>> @@ -0,0 +1,186 @@
>> +/*
>> + * Some of the routines have been copied from Linux Kernel, therefore
>> + * copying the license as well.
>> + *
>> + * Copyright (C) 2001 Deep Blue Solutions Ltd.
>> + * Copyright (C) 2012 ARM Ltd.
>> + * Copyright (C) 2015 Pratyush Anand <panand@redhat.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include "cache.h"
>> +
>> +/*
>> + * dcache_line_size - get the minimum D-cache line size from the CTR register.
>> + */
>> + .macro dcache_line_size, reg, tmp
>> + mrs \tmp, ctr_el0 // read CTR
>> + ubfm \tmp, \tmp, #16, #19 // cache line size encoding
>> + mov \reg, #4 // bytes per word
>> + lsl \reg, \reg, \tmp // actual cache line size
>> + .endm
>> +
>> +/*
>> + * inval_cache_range(start, end)
>> + * - x0 - start - start address of region
>> + * - x1 - end - end address of region
>> + */
>> +.globl inval_cache_range
>> +inval_cache_range:
>> + dcache_line_size x2, x3
>> + sub x3, x2, #1
>> + tst x1, x3 // end cache line aligned?
>> + bic x1, x1, x3
>> + b.eq 1f
>> + dc civac, x1 // clean & invalidate D / U line
>> +1: tst x0, x3 // start cache line aligned?
>> + bic x0, x0, x3
>> + b.eq 2f
>> + dc civac, x0 // clean & invalidate D / U line
>> + b 3f
>> +2: dc ivac, x0 // invalidate D / U line
>> +3: add x0, x0, x2
>> + cmp x0, x1
>> + b.lo 2b
>> + dsb sy
>> + ret
>> +/*
>> + * flush_dcache_range(start, end)
>> + * - x0 - start - start address of region
>> + * - x1 - end - end address of region
>> + *
>> + */
>> +.globl flush_dcache_range
>> +flush_dcache_range:
>> + dcache_line_size x2, x3
>> + sub x3, x2, #1
>> + bic x0, x0, x3
>> +1: dc civac, x0 // clean & invalidate D line / unified line
>> + add x0, x0, x2
>> + cmp x0, x1
>> + b.lo 1b
>> + dsb sy
>> + ret
>> +
>> +/*
>> + * invalidate_tlbs_el1()
>> + */
>> +.globl invalidate_tlbs_el1
>> +invalidate_tlbs_el1:
>> + dsb nshst
>> + tlbi vmalle1
>> + dsb nsh
>> + isb
>> + ret
>> +
>> +/*
>> + * invalidate_tlbs_el2()
>> + */
>> +.globl invalidate_tlbs_el2
>> +invalidate_tlbs_el2:
>> + dsb nshst
>> + tlbi alle2
>> + dsb nsh
>> + isb
>> + ret
>> +
>> +/*
>> + * get_mm_feature_reg0_val - Get information about supported MM
>> + * features
>> + */
>> +.globl get_mm_feature_reg0_val
>> +get_mm_feature_reg0_val:
>> + mrs x0, ID_AA64MMFR0_EL1
>> + ret
>> +
>> +/*
>> + * get_current_el - Get information about current exception level
>> + */
>> +.globl get_current_el
>> +get_current_el:
>> + mrs x0, CurrentEL
>> + lsr x0, x0, #2
>> + ret
>> +
>> +/*
>> + * invalidate_icache - Invalidate I-cache
>> + */
>> +.globl invalidate_icache
>> +invalidate_icache:
>> + ic iallu
>> + dsb nsh
>> + isb
>> + ret
>> +
>> +/*
>> + * set_mair_tcr_ttbr_sctlr_el1(page_table, tcr_flags) - sets MAIR, TCR , TTBR and SCTLR registers
>> + * x0 - page_table - Page Table Base
>> + * x1 - tcr_flags - TCR Flags to be set
>> + */
>> +.globl set_mair_tcr_ttbr_sctlr_el1
>> +set_mair_tcr_ttbr_sctlr_el1:
>> + ldr x2, =MEMORY_ATTRIBUTES
>> + msr mair_el1, x2
>> + msr tcr_el1, x1
>> + msr ttbr0_el1, x0
>> + isb
>> + mrs x0, sctlr_el1
>> + ldr x3, =SCTLR_ELx_FLAGS
>> + orr x0, x0, x3
>> + msr sctlr_el1, x0
>> + isb
>> + ret
>> +
>> +/*
>> + * set_mair_tcr_ttbr_sctlr_el2(page_table, tcr_flags) - sets MAIR, TCR , TTBR and SCTLR registers
>> + * x0 - page_table - Page Table Base
>> + * x1 - tcr_flags - TCR Flags to be set
>> + */
>> +.globl set_mair_tcr_ttbr_sctlr_el2
>> +set_mair_tcr_ttbr_sctlr_el2:
>> + ldr x2, =MEMORY_ATTRIBUTES
>> + msr mair_el2, x2
>> + msr tcr_el2, x1
>> + msr ttbr0_el2, x0
>> + isb
>> + mrs x0, sctlr_el2
>> + ldr x3, =SCTLR_ELx_FLAGS
>> + orr x0, x0, x3
>> + msr sctlr_el2, x0
>> + isb
>> + ret
>> +
>> +/*
>> + * reset_sctlr_el1 - disables cache and mmu
>> + */
>> +.globl reset_sctlr_el1
>> +reset_sctlr_el1:
>> + mrs x0, sctlr_el1
>> + bic x0, x0, #SCTLR_ELx_C
>> + bic x0, x0, #SCTLR_ELx_M
>> + msr sctlr_el1, x0
>> + isb
>> + ret
>> +
>> +/*
>> + * reset_sctlr_el2 - disables cache and mmu
>> + */
>> +.globl reset_sctlr_el2
>> +reset_sctlr_el2:
>> + mrs x0, sctlr_el2
>> + bic x0, x0, #SCTLR_ELx_C
>> + bic x0, x0, #SCTLR_ELx_M
>> + msr sctlr_el2, x0
>> + isb
>> + ret
>> diff --git a/purgatory/arch/arm64/cache.c b/purgatory/arch/arm64/cache.c
>> new file mode 100644
>> index 000000000000..3c7e058ccf11
>> --- /dev/null
>> +++ b/purgatory/arch/arm64/cache.c
>> @@ -0,0 +1,330 @@
>> +/*
>> + * Copyright (C) 2015 Pratyush Anand <panand@redhat.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +/* We are supporting only 4K and 64K page sizes. This code will not work if
>> + * a hardware is not supporting at least one of these page sizes.
>> + * Therefore, D-cache is disabled by default and enabled only when
>> + * "enable-dcache" is passed to the kexec().
>> + * Since this is an identity mapped system, so VA_BITS will be same as max
>> + * PA bits supported. If VA_BITS <= 42 for 64K and <= 39 for 4K then only
>> + * one level of page table will be there with block descriptor entries.
>> + * Otherwise, For 4K mapping, TTBR points to level 0 lookups, which will
>> + * have only table entries pointing to a level 1 lookup. Level 1 will have
>> + * only block entries which will map 1GB block.For 64K mapping, TTBR points
>> + * to level 1 lookups, which will have only table entries pointing to a
>> + * level 2 lookup. Level 2 will have only block entries which will map
>> + * 512MB block. If UART base address and RAM addresses are not at least 1GB
>> + * and 512MB apart for 4K and 64K respectively, then mapping result could
>> + * be unpredictable. In that case we need to support one more level of
>> + * granularity, but until someone needs that keep it like this only.
>> + * We can not allocate dynamic memory in purgatory. Therefore we keep page
>> + * table allocation size fixed as (3 * MAX_PAGE_SIZE). (page_table) points
>> + * to first level (having only table entries) and (page_table +
>> + * MAX_PAGE_SIZE) points to table at next level (having block entries). If
>> + * index for RAM area and UART area in first table is not same, then we
>> + * will need another next level table which will be located at (page_table
>> + * + 2 * MAX_PAGE_SIZE).
>> + */
>> +
>> +#include <stdint.h>
>> +#include <string.h>
>> +#include <purgatory.h>
>> +#include "cache.h"
>> +
>> +static uint64_t page_shift;
>> +static uint64_t pgtable_level;
>> +static uint64_t va_bits;
>> +
>> +static uint64_t page_table[PAGE_TABLE_SIZE / sizeof(uint64_t)] __attribute__ ((aligned (MAX_PAGE_SIZE))) = { };
>> +static uint64_t page_table_used;
>> +
>> +#define PAGE_SIZE (1 << page_shift)
>> +/*
>> + * is_4k_page_supported - return true if 4k page is supported else
>> + * false
>> + */
>> +static int is_4k_page_supported(void)
>> +{
>> + return ((get_mm_feature_reg0_val() & ID_AA64MMFR0_TGRAN4_MASK) ==
>> + ID_AA64MMFR0_TGRAN4_SUPPORTED);
>> +}
>> +
>> +/*
>> + * is_64k_page_supported - return true if 64k page is supported else
>> + * false
>> + */
>> +static int is_64k_page_supported(void)
>> +{
>> + return ((get_mm_feature_reg0_val() & ID_AA64MMFR0_TGRAN64_MASK) ==
>> + ID_AA64MMFR0_TGRAN64_SUPPORTED);
>> +}
>> +
>> +/*
>> + * get_ips_bits - return supported IPS bits
>> + */
>> +static uint64_t get_ips_bits(void)
>> +{
>> + return ((get_mm_feature_reg0_val() & ID_AA64MMFR0_PARANGE_MASK) >>
>> + ID_AA64MMFR0_PARANGE_SHIFT);
>> +}
>> +
>> +/*
>> + * get_va_bits - return supported VA bits (For identity mapping VA = PA)
>> + */
>> +static uint64_t get_va_bits(void)
>> +{
>> + uint64_t ips = get_ips_bits();
>> +
>> + switch(ips) {
>> + case ID_AA64MMFR0_PARANGE_48:
>> + return 48;
>> + case ID_AA64MMFR0_PARANGE_44:
>> + return 44;
>> + case ID_AA64MMFR0_PARANGE_42:
>> + return 42;
>> + case ID_AA64MMFR0_PARANGE_40:
>> + return 40;
>> + case ID_AA64MMFR0_PARANGE_36:
>> + return 36;
>> + default:
>> + return 32;
>> + }
>> +}
>> +
>> +/*
>> + * get_section_shift - get block shift for supported page size
>> + */
>> +static uint64_t get_section_shift(void)
>> +{
>> + if (page_shift == 16)
>> + return 29;
>> + else if(page_shift == 12)
>> + return 30;
>> + else
>> + return 0;
>> +}
>> +
>> +/*
>> + * get_section_mask - get section mask for supported page size
>> + */
>> +static uint64_t get_section_mask(void)
>> +{
>> + if (page_shift == 16)
>> + return 0x1FFF;
>> + else if(page_shift == 12)
>> + return 0x1FF;
>> + else
>> + return 0;
>> +}
>> +
>> +/*
>> + * get_pgdir_shift - get pgdir shift for supported page size
>> + */
>> +static uint64_t get_pgdir_shift(void)
>> +{
>> + if (page_shift == 16)
>> + return 42;
>> + else if(page_shift == 12)
>> + return 39;
>> + else
>> + return 0;
>> +}
>> +
>> +/*
>> + * init_page_table - Initializes page table locations
>> + */
>> +
>> +static void init_page_table(void)
>> +{
>> + /*
>> + * Invalidate the page tables to avoid potential dirty cache lines
>> + * being evicted.
>> + */
>
> How do these lines get dirty? arm64_relocate_new_kernel() invalidated these
> pages to PoC before it copied the data. If they were speculatively fetched (I
> don't know the rules of when/how that happens) they may be wrong, but will be
> clean and not written back. If we change them in purgatory, you invalidate again
> from enable_mmu_dcache(). I don't think this is needed.
>
Had taken it from kernel arch/arm64/kernel/head.S.
But anyway, since this part will go to kexec code as you suggested, so
we will not need
it there for sure.
>
>> + inval_cache_range((uint64_t)page_table,
>> + (uint64_t)page_table + PAGE_TABLE_SIZE);
>> + memset(page_table, 0, PAGE_TABLE_SIZE);
>> +}
>> +/*
>> + * create_identity_mapping(start, end, flags)
>> + * start - start address
>> + * end - end address
>> + * flags - MMU Flags for Normal or Device type memory
>> + */
>> +static void create_identity_mapping(uint64_t start, uint64_t end,
>> + uint64_t flags)
>> +{
>> + uint32_t sec_shift, pgdir_shift, sec_mask;
>> + uint64_t desc, s1, e1, s2, e2;
>> + uint64_t *table2;
>> +
>> + s1 = start;
>> + e1 = end - 1;
>> +
>> + sec_shift = get_section_shift();
>> + if (pgtable_level == 1) {
>> + s1 >>= sec_shift;
>> + e1 >>= sec_shift;
>> + do {
>> + desc = s1 << sec_shift;
>> + desc |= flags;
>> + page_table[s1] = desc;
>> + s1++;
>> + } while (s1 <= e1);
>> + } else {
>> + pgdir_shift = get_pgdir_shift();
>> + sec_mask = get_section_mask();
>> + s1 >>= pgdir_shift;
>> + e1 >>= pgdir_shift;
>> + do {
>> + /*
>> + * If there is no table entry then write a new
>> + * entry else, use old entry
>> + */
>> + if (!page_table[s1]) {
>> + table2 = &page_table[(++page_table_used *
>> + MAX_PAGE_SIZE) /
>> + sizeof(uint64_t)];
>> + desc = (uint64_t)table2 | PMD_TYPE_TABLE;
>> + page_table[s1] = desc;
>> + } else {
>> + table2 = (uint64_t *)(page_table[s1] &
>> + ~PMD_TYPE_MASK);
>> + }
>> + s1++;
>> + s2 = start >> sec_shift;
>> + s2 &= sec_mask;
>> + e2 = (end - 1) >> sec_shift;
>> + e2 &= sec_mask;
>> + do {
>> + desc = s2 << sec_shift;
>> + desc |= flags;
>> + table2[s2] = desc;
>> + s2++;
>> + } while (s2 <= e2);
>> + } while (s1 <= e1);
>> + }
>> +}
>
> (I will need to come back to this ... it looks pretty complicated. If you mimic
> Linux's p?d/pte macros it will be more familiar and easier to read.)
Ok, will try to take definitions from head.S, as far as possible.
>
>
>> +
>> +/*
>> + * enable_mmu_dcache: Enable mmu and D-cache in sctlr_el1
>> + */
>> +static void enable_mmu_dcache(void)
>> +{
>> + uint64_t tcr_flags = TCR_FLAGS | TCR_T0SZ(va_bits);
>> +
>> + switch(page_shift) {
>> + case 16:
>> + tcr_flags |= TCR_TG0_64K;
>> + break;
>> + case 12:
>> + tcr_flags |= TCR_TG0_4K;
>> + break;
>> + default:
>> + printf("page shift not supported\n");
>> + return;
>> + }
>> + /*
>> + * Since the page tables have been populated with non-cacheable
>> + * accesses (MMU disabled), invalidate the page tables to remove
>> + * any speculatively loaded cache lines.
>> + */
>> + inval_cache_range((uint64_t)page_table,
>> + (uint64_t)page_table + PAGE_TABLE_SIZE);
>> +
>> + switch(get_current_el()) {
>> + case 2:
>> + invalidate_tlbs_el2();
>> + tcr_flags |= (get_ips_bits() << TCR_PS_EL2_SHIFT);
>> + set_mair_tcr_ttbr_sctlr_el2((uint64_t)page_table, tcr_flags);
>> + break;
>> + case 1:
>> + invalidate_tlbs_el1();
>> + tcr_flags |= (get_ips_bits() << TCR_IPS_EL1_SHIFT);
>> + set_mair_tcr_ttbr_sctlr_el1((uint64_t)page_table, tcr_flags);
>> + break;
>> + default:
>> + return;
>> + }
>
>> + invalidate_icache();
>
> What is this protecting against? We have executed instructions between here and
> setting the I+M bits in set_mair_tcr_ttbr_sctlr_el1(). (so it may be too late)
>
> arm64_relocate_new_kernel() already did 'ic iallu' before it branched into the
> purgatory code. No executable code has been changed or moved since then, so I
> don't think this is necessary.
OK.
>
>
>> +}
>> +
>> +/*
>> + * enable_dcache: Enable D-cache and set appropriate attributes
>> + * ram_start - Start address of RAM
>> + * ram_end - End address of RAM
>> + * uart_base - Base address of uart
>> + */
>> +int enable_dcache(uint64_t ram_start, uint64_t ram_end, uint64_t uart_base)
>> +{
>> + va_bits = get_va_bits();
>> +
>> + page_table_used = 0;
>> + if (is_64k_page_supported()) {
>> + page_shift = 16;
>> + if (va_bits <= 42)
>> + pgtable_level = 1;
>> + else
>> + pgtable_level = 2;
>> + } else if (is_4k_page_supported()) {
>> + page_shift = 12;
>> + if (va_bits <= 39)
>> + pgtable_level = 1;
>> + else
>> + pgtable_level = 2;
>> + } else {
>> + printf("Valid Page Granule not supported by hardware\n");
>> + return -1;
>> + }
>> + init_page_table();
>> + create_identity_mapping(ram_start, ram_end, MM_MMUFLAGS_NORMAL);
>> + printf("Normal identity mapping created from %lx to %lx\n",
>> + ram_start, ram_end);
>> + if (uart_base) {
>> + create_identity_mapping((uint64_t)uart_base,
>> + (uint64_t)uart_base + PAGE_SIZE,
>> + MM_MMUFLAGS_DEVICE);
>> + printf("Device identity mapping created from %lx to %lx\n",
>> + (uint64_t)uart_base,
>> + (uint64_t)uart_base + PAGE_SIZE);
>> + }
>> + enable_mmu_dcache();
>> + printf("Cache Enabled\n");
>> +
>> + return 0;
>> +}
>> +
>> +/*
>> + * disable_dcache: Disable D-cache and flush RAM locations
>> + * ram_start - Start address of RAM
>> + * ram_end - End address of RAM
>> + */
>> +void disable_dcache(uint64_t ram_start, uint64_t ram_end)
>> +{
>> + switch(get_current_el()) {
>> + case 2:
>> + reset_sctlr_el2();
>> + break;
>> + case 1:
>> + reset_sctlr_el1();
>
> You have C code running between disabling the MMU and cleaning the cache. The
> compiler is allowed to move data on and off the stack in here, but after
> disabling the MMU it will see whatever was on the stack before we turned the MMU
> on. Any data written at the beginning of this function is left in the caches.
>
> I'm afraid this sort of stuff needs to be done in assembly!
All these routines are self coded in assembly even though they are called
from C, so should be safe I think. Anyway, I can keep all of them in
assembly as well.
>
>
>> + break;
>> + default:
>> + return;
>> + }
>> + invalidate_icache();
>> + flush_dcache_range(ram_start, ram_end);
>> + printf("Cache Disabled\n");
>> +}
>> diff --git a/purgatory/arch/arm64/cache.h b/purgatory/arch/arm64/cache.h
>> new file mode 100644
>> index 000000000000..c988020566e3
>> --- /dev/null
>> +++ b/purgatory/arch/arm64/cache.h
>> @@ -0,0 +1,79 @@
>> +#ifndef __CACHE_H__
>> +#define __CACHE_H__
>> +
>> +#define MT_DEVICE_NGNRNE 0
>> +#define MT_DEVICE_NGNRE 1
>> +#define MT_DEVICE_GRE 2
>> +#define MT_NORMAL_NC 3
>> +#define MT_NORMAL 4
>
> You only use two of these. I guess this is so the MAIR value matches the kernel?
OK, can remove others. Yes, they are matching with kernel.
>
>
>> +
>> +#ifndef __ASSEMBLER__
>> +
>> +#define MAX_PAGE_SIZE 0x10000
>> +#define PAGE_TABLE_SIZE (3 * MAX_PAGE_SIZE)
>> +#define ID_AA64MMFR0_TGRAN64_SHIFT 24
>> +#define ID_AA64MMFR0_TGRAN4_SHIFT 28
>> +#define ID_AA64MMFR0_TGRAN64_MASK (0xFUL << ID_AA64MMFR0_TGRAN64_SHIFT)
>> +#define ID_AA64MMFR0_TGRAN4_MASK (0xFUL << ID_AA64MMFR0_TGRAN4_SHIFT)
>> +#define ID_AA64MMFR0_TGRAN64_SUPPORTED 0x0
>> +#define ID_AA64MMFR0_TGRAN4_SUPPORTED 0x0
>> +#define ID_AA64MMFR0_PARANGE_SHIFT 0
>> +#define ID_AA64MMFR0_PARANGE_MASK (0xFUL << ID_AA64MMFR0_PARANGE_SHIFT)
>> +#define ID_AA64MMFR0_PARANGE_48 0x5
>> +#define ID_AA64MMFR0_PARANGE_44 0x4
>> +#define ID_AA64MMFR0_PARANGE_42 0x3
>> +#define ID_AA64MMFR0_PARANGE_40 0x2
>> +#define ID_AA64MMFR0_PARANGE_36 0x1
>> +#define ID_AA64MMFR0_PARANGE_32 0x0
>> +
>> +#define TCR_TG0_64K (1UL << 14)
>> +#define TCR_TG0_4K (0UL << 14)
>> +#define TCR_SHARED_NONE (0UL << 12)
>> +#define TCR_ORGN_WBWA (1UL << 10)
>> +#define TCR_IRGN_WBWA (1UL << 8)
>> +#define TCR_IPS_EL1_SHIFT 32
>> +#define TCR_PS_EL2_SHIFT 16
>> +#define TCR_T0SZ(x) ((unsigned long)(64 - (x)) << 0)
>> +#define TCR_FLAGS (TCR_SHARED_NONE | TCR_ORGN_WBWA | TCR_IRGN_WBWA)
>> +
>> +#define PMD_TYPE_SECT (1UL << 0)
>> +#define PMD_TYPE_TABLE (3UL << 0)
>> +#define PMD_TYPE_MASK 0x3
>> +#define PMD_SECT_AF (1UL << 10)
>> +#define PMD_ATTRINDX(t) ((unsigned long)(t) << 2)
>> +#define PMD_FLAGS_NORMAL (PMD_TYPE_SECT | PMD_SECT_AF)
>> +#define PMD_SECT_PXN (1UL << 53)
>> +#define PMD_SECT_UXN (1UL << 54)
>> +#define PMD_FLAGS_DEVICE (PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_PXN | PMD_SECT_UXN)
>> +#define MM_MMUFLAGS_NORMAL PMD_ATTRINDX(MT_NORMAL) | PMD_FLAGS_NORMAL
>> +#define MM_MMUFLAGS_DEVICE PMD_ATTRINDX(MT_DEVICE_NGNRE) | PMD_FLAGS_DEVICE
>> +
>> +void disable_dcache(uint64_t ram_start, uint64_t ram_end);
>> +int enable_dcache(uint64_t ram_start, uint64_t ram_end, uint64_t uart_base);
>> +uint64_t get_mm_feature_reg0_val(void);
>> +void inval_cache_range(uint64_t start, uint64_t end);
>> +void flush_dcache_range(uint64_t start, uint64_t end);
>> +uint64_t get_current_el(void);
>> +void set_mair_tcr_ttbr_sctlr_el1(uint64_t page_table, uint64_t tcr_flags);
>> +void set_mair_tcr_ttbr_sctlr_el2(uint64_t page_table, uint64_t tcr_flags);
>> +void invalidate_tlbs_el1(void);
>> +void invalidate_tlbs_el2(void);
>> +void invalidate_icache(void);
>> +void reset_sctlr_el1(void);
>> +void reset_sctlr_el2(void);
>> +#else
>> +#define MEMORY_ATTRIBUTES ((0x00 << (MT_DEVICE_NGNRNE*8)) | \
>> + (0x04 << (MT_DEVICE_NGNRE*8)) | \
>> + (0x0C << (MT_DEVICE_GRE*8)) | \
>> + (0x44 << (MT_NORMAL_NC*8)) | \
>> + (0xFF << (MT_NORMAL*8)))
>
> Again, you only use two of these.
OK, will remove others.
>
>
>> +/* Common SCTLR_ELx flags. */
>> +#define SCTLR_ELx_I (1 << 12)
>> +#define SCTLR_ELx_C (1 << 2)
>> +#define SCTLR_ELx_M (1 << 0)
>> +
>> +#define SCTLR_ELx_FLAGS (SCTLR_ELx_M | SCTLR_ELx_C | SCTLR_ELx_I)
>> +
>> +#endif
>> +#endif
>>
~Pratyush
^ permalink raw reply
* [PATCH 09/18] arm64: introduce binfmt_elf32.c
From: Yury Norov @ 2016-12-14 9:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161205151018.GD14429@e104818-lin.cambridge.arm.com>
On Mon, Dec 05, 2016 at 03:10:19PM +0000, Catalin Marinas wrote:
> On Fri, Oct 21, 2016 at 11:33:08PM +0300, Yury Norov wrote:
> > As we support more than one compat formats, it looks more reasonable
> > to not use fs/compat_binfmt.c. Custom binfmt_elf32.c allows to move aarch32
> > specific definitions there and make code more maintainable and readable.
>
> Can you remind me why we need this patch (rather than using the default
> fs/compat_binfmt_elf.c which you include here anyway)?
https://patchwork.kernel.org/patch/8756121/
This is mostly to avoid runtime checks and hide some re-definitions
for aarch32 from ilp32, to avoid re-re-definition.
>
> > --- /dev/null
> > +++ b/arch/arm64/kernel/binfmt_elf32.c
> > @@ -0,0 +1,31 @@
> > +/*
> > + * Support for AArch32 Linux ELF binaries.
> > + */
> > +
> > +/* AArch32 EABI. */
> > +#define EF_ARM_EABI_MASK 0xff000000
> > +
> > +#define compat_start_thread compat_start_thread
> > +#define COMPAT_SET_PERSONALITY(ex) \
> > +do { \
> > + clear_thread_flag(TIF_32BIT_AARCH64); \
> > + set_thread_flag(TIF_32BIT); \
> > +} while (0)
>
> You introduce this here but it seems to still be present in asm/elf.h.
Hmm... Maybe chunk that delete it from asm/elf.h was dropped at some
rebase. Thank you for the catch. I'll check it again.
Yury
^ permalink raw reply
* [PATCH v2] arm64: mm: Fix NOMAP page initialization
From: Robert Richter @ 2016-12-14 9:42 UTC (permalink / raw)
To: linux-arm-kernel
On ThunderX systems with certain memory configurations we see the
following BUG_ON():
kernel BUG at mm/page_alloc.c:1848!
This happens for some configs with 64k page size enabled. The BUG_ON()
checks if start and end page of a memmap range belongs to the same
zone.
The BUG_ON() check fails if a memory zone contains NOMAP regions. In
this case the node information of those pages is not initialized. This
causes an inconsistency of the page links with wrong zone and node
information for that pages. NOMAP pages from node 1 still point to the
mem zone from node 0 and have the wrong nid assigned.
The reason for the mis-configuration is a change in pfn_valid() which
reports pages marked NOMAP as invalid:
68709f45385a arm64: only consider memblocks with NOMAP cleared for linear mapping
This causes pages marked as nomap being no longer reassigned to the
new zone in memmap_init_zone() by calling __init_single_pfn().
Fixing this by implementing an arm64 specific early_pfn_valid(). This
causes all pages of sections with memory including NOMAP ranges to be
initialized by __init_single_page() and ensures consistency of page
links to zone, node and section.
The HAVE_ARCH_PFN_VALID config option now requires an explicit
definiton of early_pfn_valid() in the same way as pfn_valid(). This
allows a customized implementation of early_pfn_valid() which
redirects to pfn_present() for arm64.
v2:
* Use pfn_present() instead of memblock_is_memory() to support also
non-memory NOMAP holes
Signed-off-by: Robert Richter <rrichter@cavium.com>
---
arch/arm/include/asm/page.h | 1 +
arch/arm64/include/asm/page.h | 2 ++
arch/arm64/mm/init.c | 12 ++++++++++++
include/linux/mmzone.h | 5 ++++-
4 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index 4355f0ec44d6..79761bd55f94 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -158,6 +158,7 @@ typedef struct page *pgtable_t;
#ifdef CONFIG_HAVE_ARCH_PFN_VALID
extern int pfn_valid(unsigned long);
+#define early_pfn_valid(pfn) pfn_valid(pfn)
#endif
#include <asm/memory.h>
diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
index 8472c6def5ef..17ceb7435ded 100644
--- a/arch/arm64/include/asm/page.h
+++ b/arch/arm64/include/asm/page.h
@@ -49,6 +49,8 @@ typedef struct page *pgtable_t;
#ifdef CONFIG_HAVE_ARCH_PFN_VALID
extern int pfn_valid(unsigned long);
+extern int early_pfn_valid(unsigned long);
+#define early_pfn_valid early_pfn_valid
#endif
#include <asm/memory.h>
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 212c4d1e2f26..bf1f5db11428 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -145,11 +145,23 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
#endif /* CONFIG_NUMA */
#ifdef CONFIG_HAVE_ARCH_PFN_VALID
+
int pfn_valid(unsigned long pfn)
{
return memblock_is_map_memory(pfn << PAGE_SHIFT);
}
EXPORT_SYMBOL(pfn_valid);
+
+/*
+ * We use pfn_present() here to make sure all pages of a section
+ * including NOMAP pages are initialized with __init_single_page().
+ */
+int early_pfn_valid(unsigned long pfn)
+{
+ return pfn_present(pfn);
+}
+EXPORT_SYMBOL(early_pfn_valid);
+
#endif
#ifndef CONFIG_SPARSEMEM
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 0f088f3a2fed..bedcf8a95881 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -1170,12 +1170,16 @@ static inline struct mem_section *__pfn_to_section(unsigned long pfn)
}
#ifndef CONFIG_HAVE_ARCH_PFN_VALID
+
static inline int pfn_valid(unsigned long pfn)
{
if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS)
return 0;
return valid_section(__nr_to_section(pfn_to_section_nr(pfn)));
}
+
+#define early_pfn_valid(pfn) pfn_valid(pfn)
+
#endif
static inline int pfn_present(unsigned long pfn)
@@ -1200,7 +1204,6 @@ static inline int pfn_present(unsigned long pfn)
#define pfn_to_nid(pfn) (0)
#endif
-#define early_pfn_valid(pfn) pfn_valid(pfn)
void sparse_init(void);
#else
#define sparse_init() do {} while (0)
--
2.1.4
^ permalink raw reply related
* [PATCH] arm/dts: ls1021a: Add dma-coherent property to usb3 node
From: Jerry Huang @ 2016-12-14 9:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1479885324-5468-1-git-send-email-jerry.huang@nxp.com>
> -----Original Message-----
> From: Changming Huang [mailto:jerry.huang at nxp.com]
> Sent: Wednesday, November 23, 2016 3:15 PM
> To: robh+dt at kernel.org; mark.rutland at arm.com; linux at armlinux.org.uk
> Cc: devicetree at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> kernel at vger.kernel.org; Jerry Huang <jerry.huang@nxp.com>; Rajesh
> Bhagat <rajesh.bhagat@nxp.com>
> Subject: [PATCH] arm/dts: ls1021a: Add dma-coherent property to usb3 node
>
> This sets dma ops as coherent for usb 3.0 platform device
>
> Signed-off-by: Changming Huang <jerry.huang@nxp.com>
> Signed-off-by: Rajesh Bhagat <rajesh.bhagat@nxp.com>
> ---
> arch/arm/boot/dts/ls1021a.dtsi | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
> index 368e219..81fb4d9 100644
> --- a/arch/arm/boot/dts/ls1021a.dtsi
> +++ b/arch/arm/boot/dts/ls1021a.dtsi
> @@ -627,6 +627,7 @@
> dr_mode = "host";
> snps,quirk-frame-length-adjustment = <0x20>;
> snps,dis_rxdet_inp3_quirk;
> + dma-coherent;
> };
>
> pcie at 3400000 {
> --
How about this property for usb? Any comment for it?
^ permalink raw reply
* [PATCH] arm64: mm: Fix NOMAP page initialization
From: Robert Richter @ 2016-12-14 9:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <9168b603-04aa-4302-3197-00f17fb336bd@huawei.com>
On 12.12.16 17:53:02, Yisheng Xie wrote:
> It seems that memblock_is_memory() is also too strict for early_pfn_valid,
> so what about this patch, which use common pfn_valid as early_pfn_valid
> when CONFIG_HAVE_ARCH_PFN_VALID=y:
> ------------
> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
> index 0f088f3..9d596f3 100644
> --- a/include/linux/mmzone.h
> +++ b/include/linux/mmzone.h
> @@ -1200,7 +1200,17 @@ static inline int pfn_present(unsigned long pfn)
> #define pfn_to_nid(pfn) (0)
> #endif
>
> +#ifdef CONFIG_HAVE_ARCH_PFN_VALID
> +static inline int early_pfn_valid(unsigned long pfn)
> +{
> + if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS)
> + return 0;
> + return valid_section(__nr_to_section(pfn_to_section_nr(pfn)));
> +}
I sent a V2 patch that uses pfn_present(). This only initilizes
sections with memory.
-Robert
> +#define early_pfn_valid early_pfn_valid
> +#else
> #define early_pfn_valid(pfn) pfn_valid(pfn)
> +#endif
> void sparse_init(void);
> #else
> #define sparse_init() do {} while (0)
>
>
>
^ permalink raw reply
* [RFT PATCH] ARM64: dts: meson-gxbb: Add reserved memory zone and usable memory range
From: Neil Armstrong @ 2016-12-14 9:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <09bb78ed-c8ec-d21f-d464-16e55c481d4e@gmx.de>
On 12/12/2016 10:22 PM, Heinrich Schuchardt wrote:
> On 12/12/2016 11:18 AM, Neil Armstrong wrote:
>> The Amlogic Meson GXBB secure monitor uses part of the memory space, this
>> patch adds these reserved zones and redefines the usable memory range for
>> each boards.
>>
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>> arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi | 2 +-
>> arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 21 +++++++++++++++++++++
>> .../boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts | 2 +-
>> arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 2 +-
>> arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi | 2 +-
>> .../boot/dts/amlogic/meson-gxbb-vega-s95-meta.dts | 2 +-
>> .../boot/dts/amlogic/meson-gxbb-vega-s95-pro.dts | 2 +-
>> .../boot/dts/amlogic/meson-gxbb-vega-s95-telos.dts | 2 +-
>> .../boot/dts/amlogic/meson-gxl-nexbox-a95x.dts | 2 +-
>> .../arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts | 2 +-
>> arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts | 2 +-
>> 11 files changed, 31 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
>> index 7a078be..ac40b2d 100644
>> --- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
>> +++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
>> @@ -56,7 +56,7 @@
>>
>> memory at 0 {
>> device_type = "memory";
>> - reg = <0x0 0x0 0x0 0x80000000>;
>> + reg = <0x0 0x1000000 0x0 0x7f000000>;
>> };
>>
>> vddio_boot: regulator-vddio_boot {
>> diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
>> index fc033c0..e085588 100644
>> --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
>> +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
>> @@ -55,6 +55,27 @@
>> #address-cells = <2>;
>> #size-cells = <2>;
>>
>> + reserved-memory {
>> + #address-cells = <2>;
>> + #size-cells = <2>;
>> + ranges;
>> +
>> + secos: secos {
>> + reg = <0x0 0x05300000 0x0 0x2000000>;
>> + no-map;
>> + };
>
> Hello Neil,
>
> In
> https://github.com/hardkernel/linux/blob/odroidc2-3.14.y/arch/arm64/boot/dts/meson64_odroidc2.dts
> the secos region does not exist. In linux-next I find no reference to
> the secos label. Where is the consumer of the region defined?
>
>> +
>> + pstore: pstore {
>> + reg = <0x0 0x07300000 0x0 0x100000>;
>> + no-map;
>> + };
>
> In
> https://github.com/hardkernel/linux/blob/odroidc2-3.14.y/arch/arm64/boot/dts/amlogic/gxbb_skt.dts
> and other files pstore uses a different position
> (reg = <0x0 0x20000000 0x0 0x100000>;).
> Why are we moving this?
> Should this region be marked
> compatible = "ramoops"; ?
> Cf. Documentation/devicetree/bindings/reserved-memory/ramoops.txt.
>
> It would be nice if you could add a short description of each reserved
> area to the commit message.
>
> Regards
>
> Heinrich Schuchardt
>
>> +
>> + secmon: secmon {
>> + reg = <0x0 0x10000000 0x0 0x200000>;
>> + no-map;
>> + };
>> + };
>> +
>> cpus {
>> #address-cells = <0x2>;
>> #size-cells = <0x0>;
>
>
Hi Heinrich,
Thanks for testing and for the report,
we are still struggling into finding what are these zones and how to label them correctly.
We need to identify the zones on all boards, the patch I provided works on a non-odroid-c2 and gxm and gxl boards.
Neil
^ permalink raw reply
* [PATCH v7 4/5] ARM: dts: da850-lcdk: add the vga-bridge node
From: Tomi Valkeinen @ 2016-12-14 9:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481623759-12786-5-git-send-email-bgolaszewski@baylibre.com>
On 13/12/16 12:09, Bartosz Golaszewski wrote:
> Add the vga-bridge node to the board DT together with corresponding
> ports and vga connector. This allows to retrieve the edid info from
> the display automatically.
>
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> arch/arm/boot/dts/da850-lcdk.dts | 51 ++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 51 insertions(+)
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Tomi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161214/d7838da1/attachment.sig>
^ permalink raw reply
* [PATCH v7 1/5] ARM: dts: da850: rename the display node label
From: Tomi Valkeinen @ 2016-12-14 9:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481623759-12786-2-git-send-email-bgolaszewski@baylibre.com>
On 13/12/16 12:09, Bartosz Golaszewski wrote:
> The tilcdc node name is 'display' as per the ePAPR 1.1 recommendation.
> The label is also 'display', but change it to 'lcdc' to make it clear
> what the underlying hardware is.
>
> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
> ---
> arch/arm/boot/dts/da850.dtsi | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
> index 104155d..6b0ef3d 100644
> --- a/arch/arm/boot/dts/da850.dtsi
> +++ b/arch/arm/boot/dts/da850.dtsi
> @@ -458,7 +458,7 @@
> dma-names = "tx", "rx";
> };
>
> - display: display at 213000 {
> + lcdc: display at 213000 {
> compatible = "ti,da850-tilcdc";
> reg = <0x213000 0x1000>;
> interrupts = <52>;
>
Reviewed-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Tomi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20161214/c170611c/attachment-0001.sig>
^ permalink raw reply
* [PATCH 0/3] Add and export clk-480m clocks for ehci and ohci on RK3399
From: Xing Zheng @ 2016-12-14 10:11 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
This patches would like to fix the USB suspend block without
the clk-480m clock. Let's add and export them to control them.
Thanks.
William wu (1):
arm64: dts: rockchip: add clk-480m for ehci and ohci of rk3399
Xing Zheng (2):
clk: rockchip: rk3399: add USBPHYx_480M_SRC clock IDs
clk: rockchip: rk3399: export 480M_SRC clocks id for usbphy0/usbphy1
arch/arm64/boot/dts/rockchip/rk3399.dtsi | 28 ++++++++++++++++++++--------
drivers/clk/rockchip/clk-rk3399.c | 4 ++--
include/dt-bindings/clock/rk3399-cru.h | 2 ++
3 files changed, 24 insertions(+), 10 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH 2/3] clk: rockchip: rk3399: export 480M_SRC clocks id for usbphy0/usbphy1
From: Xing Zheng @ 2016-12-14 10:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481710301-1454-1-git-send-email-zhengxing@rock-chips.com>
This patch exports USBPHYx_480M_SRC clocks for usbphy.
Signed-off-by: Xing Zheng <zhengxing@rock-chips.com>
---
drivers/clk/rockchip/clk-rk3399.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/rockchip/clk-rk3399.c b/drivers/clk/rockchip/clk-rk3399.c
index 3490887..cf2af4c 100644
--- a/drivers/clk/rockchip/clk-rk3399.c
+++ b/drivers/clk/rockchip/clk-rk3399.c
@@ -411,9 +411,9 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
GATE(SCLK_USB2PHY1_REF, "clk_usb2phy1_ref", "xin24m", CLK_IGNORE_UNUSED,
RK3399_CLKGATE_CON(6), 6, GFLAGS),
- GATE(0, "clk_usbphy0_480m_src", "clk_usbphy0_480m", 0,
+ GATE(SCLK_USBPHY0_480M_SRC, "clk_usbphy0_480m_src", "clk_usbphy0_480m", 0,
RK3399_CLKGATE_CON(13), 12, GFLAGS),
- GATE(0, "clk_usbphy1_480m_src", "clk_usbphy1_480m", 0,
+ GATE(SCLK_USBPHY1_480M_SRC, "clk_usbphy1_480m_src", "clk_usbphy1_480m", 0,
RK3399_CLKGATE_CON(13), 12, GFLAGS),
MUX(0, "clk_usbphy_480m", mux_usbphy_480m_p, 0,
RK3399_CLKSEL_CON(14), 6, 1, MFLAGS),
--
2.7.4
^ permalink raw reply related
* [PATCH 3/3] arm64: dts: rockchip: add clk-480m for ehci and ohci of rk3399
From: Xing Zheng @ 2016-12-14 10:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481710301-1454-1-git-send-email-zhengxing@rock-chips.com>
From: William wu <wulf@rock-chips.com>
We found that the suspend process was blocked when it run into
ehci/ohci module due to clk-480m of usb2-phy was disabled.
The root cause is that usb2-phy suspended earlier than ehci/ohci
(usb2-phy will be auto suspended if no devices plug-in). and the
clk-480m provided by it was disabled if no module used. However,
some suspend process related ehci/ohci are base on this clock,
so we should refer it into ehci/ohci driver to prevent this case.
Signed-off-by: William wu <wulf@rock-chips.com>
Signed-off-by: Xing Zheng <zhengxing@rock-chips.com>
---
arch/arm64/boot/dts/rockchip/rk3399.dtsi | 28 ++++++++++++++++++++--------
1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3399.dtsi b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
index b65c193..228c764 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399.dtsi
@@ -315,8 +315,10 @@
compatible = "generic-ehci";
reg = <0x0 0xfe380000 0x0 0x20000>;
interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST0_ARB>;
- clock-names = "hclk_host0", "hclk_host0_arb";
+ clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST0_ARB>,
+ <&cru SCLK_USBPHY0_480M_SRC>;
+ clock-names = "hclk_host0", "hclk_host0_arb",
+ "usbphy0_480m";
phys = <&u2phy0_host>;
phy-names = "usb";
status = "disabled";
@@ -326,8 +328,12 @@
compatible = "generic-ohci";
reg = <0x0 0xfe3a0000 0x0 0x20000>;
interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST0_ARB>;
- clock-names = "hclk_host0", "hclk_host0_arb";
+ clocks = <&cru HCLK_HOST0>, <&cru HCLK_HOST0_ARB>,
+ <&cru SCLK_USBPHY0_480M_SRC>;
+ clock-names = "hclk_host0", "hclk_host0_arb",
+ "usbphy0_480m";
+ phys = <&u2phy0_host>;
+ phy-names = "usb";
status = "disabled";
};
@@ -335,8 +341,10 @@
compatible = "generic-ehci";
reg = <0x0 0xfe3c0000 0x0 0x20000>;
interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST1_ARB>;
- clock-names = "hclk_host1", "hclk_host1_arb";
+ clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST1_ARB>,
+ <&cru SCLK_USBPHY1_480M_SRC>;
+ clock-names = "hclk_host1", "hclk_host1_arb",
+ "usbphy1_480m";
phys = <&u2phy1_host>;
phy-names = "usb";
status = "disabled";
@@ -346,8 +354,12 @@
compatible = "generic-ohci";
reg = <0x0 0xfe3e0000 0x0 0x20000>;
interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH 0>;
- clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST1_ARB>;
- clock-names = "hclk_host1", "hclk_host1_arb";
+ clocks = <&cru HCLK_HOST1>, <&cru HCLK_HOST1_ARB>,
+ <&cru SCLK_USBPHY1_480M_SRC>;
+ clock-names = "hclk_host1", "hclk_host1_arb",
+ "usbphy1_480m";
+ phys = <&u2phy1_host>;
+ phy-names = "usb";
status = "disabled";
};
--
2.7.4
^ permalink raw reply related
* [PATCH 1/2] arm64: Add enable/disable d-cache support for purgatory
From: Pratyush Anand @ 2016-12-14 10:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <d8f354da-1e61-feaf-f76a-18e90361e98b@redhat.com>
On Wednesday 14 December 2016 03:08 PM, Pratyush Anand wrote:
>
>>
>> I would go as far as to generate the page tables at 'kexec -l' time,
>> and only if
>
> Ok..So you mean that I create a new section which will have page table
> entries mapping physicalmemory represented by remaining section, and
> then purgatory can just enable mmu with page table from that section,
> right? Seems doable. can do that.
I see a problem here. If we create page table as a new segment then,
how can we verify in purgatory that sha for page table is correct? We
need page table before sha verification start,and we can not rely the
page table created by first kernel until it's sha is verified. So a
chicken-egg problem.
I think, creating page table will just take fraction of second and
should be good even in purgatory, What do you say?
~Pratyush
^ permalink raw reply
* [RFC v2 PATCH 0/3] Fix dma_alloc_coherent() and friends for NOMMU
From: Vladimir Murzin @ 2016-12-14 10:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <552e7994-31ee-9ec8-4acd-8f37d1a157a4@arm.com>
On 13/12/16 18:32, Robin Murphy wrote:
> On 13/12/16 15:02, Vladimir Murzin wrote:
>> On 13/12/16 14:25, Robin Murphy wrote:
>>> On 13/12/16 14:14, Vladimir Murzin wrote:
>>>> On 13/12/16 14:07, Russell King - ARM Linux wrote:
>>>>> On Tue, Dec 13, 2016 at 01:45:01PM +0000, Vladimir Murzin wrote:
>>>>>> This patch set is trying to address the issue by providing region of
>>>>>> memory suitable for consistent DMA operations. It is supposed that such
>>>>>> region is marked by MPU as non-cacheable. Since we have MPU support in
>>>>>> Linux for R-class only and M-class setting MPU in bootloader, proposed
>>>>>> interface to advertise such memory is via "memdma=size at start" command
>>>>>> line option, to avoid clashing with normal memory (which usually comes
>>>>>> from dts) it'd be safer to use it together with "mem=" command line
>>>>>> option. Meanwhile, I'm open to suggestions for the better way telling
>>>>>> Linux of such memory.
>>>>>
>>>>> For those nommu systems where the MPU is not used, how do they allocate
>>>>> DMA memory without setting aside a chunk of memory?
>>>>>
>>>>> >From what I understand of the current nommu code, it would just use
>>>>> the normal page allocator for DMA memory allocation, so now requiring
>>>>> everything to fit the "nommu has mpu" case seems like it's going to
>>>>> break older nommu.
>>>>>
>>>>
>>>> Probably, it'd be better if we just fallback to dma-noop operations if there
>>>> is no dma region, i.e. assume that platform is coherent. We still need a way
>>>> to tell user that absence of such region can be reason of broken DMA.
>>>
>>> As I mentioned internally, I think it would be worth trying to use CMA
>>> for this, because dma_map_ops are already wired to try that first, and
>>> from what I can see it seems already set up to do precisely this via a
>>> "shared-dma-pool" reserved memory region (see rmem_cma_setup() in
>>> drivers/base/dma-contiguous.c) - mandating that for cached v7-M systems
>>> whilst letting cache-less/non-MPU systems automatically fall back to the
>>> normal page allocator in its absence would seem to solve all 3 cases.
>>
>> Unfortunately,
>>
>> config DMA_CMA
>> bool "DMA Contiguous Memory Allocator"
>> depends on HAVE_DMA_CONTIGUOUS && CMA
>> help
>> ...
>> config CMA
>> bool "Contiguous Memory Allocator"
>> depends on HAVE_MEMBLOCK && MMU
>> select MIGRATION
>>
>> and it blows up if I remove dependecy on MMU :(
>
> Ah yes, fair enough.
>
>> Another option would be drivers/base/dma-coherent.c, but, IIUC, in this case
>> memory is reserved per device exclusively, so I'm in doubt if tiny M-class can
>> afford that...
>
> I think as usual I managed to conflate the two - it was actually
> dma_alloc_from_coherent() I had in mind when I mentioned dma_map_ops. It
> does seem from 7bfa5ab6fa1b that dma-coherent *can* handle multiple
> devices per region, so it wouldn't appear to be too hard to implement a
> default coherent region (possibly specific to ARM_MPU) for all devices
> in a similar manner to the default contiguous region. Either way I do
> still think a reserved memory region in the DT is nicer and probably
> more robust than the command line parameter.
Ok, I'll look at this option in detail.
Thanks
Vladimir
>
> Robin.
>
>>> Other than the allocator issue, though, the rest of the refactoring does
>>> look nice.
>>
>> Thanks for going through it!
>>
>> Cheers
>> Vladimir
>
>
^ permalink raw reply
* [PATCH 1/2] ARM: hyp-stub: improve ABI
From: Russell King @ 2016-12-14 10:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161213113044.GC19985@leverpostej>
Improve the hyp-stub ABI to allow it to do more than just get/set the
vectors. We follow the example in ARM64, where r0 is used as an opcode
with the other registers as an argument.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
arch/arm/kernel/hyp-stub.S | 27 ++++++++++++++++++++++-----
1 file changed, 22 insertions(+), 5 deletions(-)
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index 15d073ae5da2..f3e9ba5fb642 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -22,6 +22,9 @@
#include <asm/assembler.h>
#include <asm/virt.h>
+#define HVC_GET_VECTORS 0
+#define HVC_SET_VECTORS 1
+
#ifndef ZIMAGE
/*
* For the kernel proper, we need to find out the CPU boot mode long after
@@ -202,9 +205,19 @@ ARM_BE8(orr r7, r7, #(1 << 25)) @ HSCTLR.EE
ENDPROC(__hyp_stub_install_secondary)
__hyp_stub_do_trap:
- cmp r0, #-1
- mrceq p15, 4, r0, c12, c0, 0 @ get HVBAR
- mcrne p15, 4, r0, c12, c0, 0 @ set HVBAR
+ teq r0, #HVC_GET_VECTORS
+ bne 1f
+ mrc p15, 4, r0, c12, c0, 0 @ get HVBAR
+ b __hyp_stub_exit
+
+1: teq r0, #HVC_SET_VECTORS
+ bne 1f
+ mcr p15, 4, r1, c12, c0, 0 @ set HVBAR
+ b __hyp_stub_exit
+
+1: mov r0, #-1
+
+__hyp_stub_exit:
__ERET
ENDPROC(__hyp_stub_do_trap)
@@ -231,10 +244,14 @@ ENDPROC(__hyp_stub_do_trap)
* initialisation entry point.
*/
ENTRY(__hyp_get_vectors)
- mov r0, #-1
+ mov r0, #HVC_GET_VECTORS
+ __HVC(0)
+ ret lr
ENDPROC(__hyp_get_vectors)
- @ fall through
+
ENTRY(__hyp_set_vectors)
+ mov r1, r0
+ mov r0, #HVC_SET_VECTORS
__HVC(0)
ret lr
ENDPROC(__hyp_set_vectors)
--
2.7.4
^ permalink raw reply related
* [PATCH 2/2] ARM: soft-reboot into same mode that we entered the kernel
From: Russell King @ 2016-12-14 10:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161213113044.GC19985@leverpostej>
When we soft-reboot (eg, kexec) from one kernel into the next, we need
to ensure that we enter the new kernel in the same processor mode as
when we were entered, so that (eg) the new kernel can install its own
hypervisor - the old kernel's hypervisor will have been overwritten.
In order to do this, we need to pass a flag to cpu_reset() so it knows
what to do, and we need to modify the kernel's own hypervisor stub to
allow it to handle a soft-reboot.
As we are always guaranteed to install our own hypervisor if we're
entered in HYP32 mode, and KVM will have moved itself out of the way
on kexec/normal reboot, we can assume that our hypervisor is in place
when we want to kexec, so changing our hypervisor API should not be a
problem.
Tested-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
arch/arm/include/asm/proc-fns.h | 4 ++--
arch/arm/kernel/hyp-stub.S | 13 +++++++++++++
arch/arm/kernel/reboot.c | 7 +++++--
arch/arm/mm/proc-v7.S | 12 ++++++++----
4 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 8877ad5ffe10..f2e1af45bd6f 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -43,7 +43,7 @@ extern struct processor {
/*
* Special stuff for a reset
*/
- void (*reset)(unsigned long addr) __attribute__((noreturn));
+ void (*reset)(unsigned long addr, bool hvc) __attribute__((noreturn));
/*
* Idle the processor
*/
@@ -88,7 +88,7 @@ extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte);
#else
extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
#endif
-extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
+extern void cpu_reset(unsigned long addr, bool hvc) __attribute__((noreturn));
/* These three are private to arch/arm/kernel/suspend.c */
extern void cpu_do_suspend(void *);
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index f3e9ba5fb642..82915231c6f8 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -24,6 +24,7 @@
#define HVC_GET_VECTORS 0
#define HVC_SET_VECTORS 1
+#define HVC_SOFT_RESTART 2
#ifndef ZIMAGE
/*
@@ -215,6 +216,10 @@ ENDPROC(__hyp_stub_install_secondary)
mcr p15, 4, r1, c12, c0, 0 @ set HVBAR
b __hyp_stub_exit
+1: teq r0, #HVC_SOFT_RESTART
+ bne 1f
+ bx r3
+
1: mov r0, #-1
__hyp_stub_exit:
@@ -256,6 +261,14 @@ ENTRY(__hyp_set_vectors)
ret lr
ENDPROC(__hyp_set_vectors)
+ENTRY(__hyp_soft_restart)
+ mov r3, r0
+ mov r0, #HVC_SOFT_RESTART
+ __HVC(0)
+ mov r0, r3
+ ret lr
+ENDPROC(__hyp_soft_restart)
+
#ifndef ZIMAGE
.align 2
.L__boot_cpu_mode_offset:
diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c
index 3fa867a2aae6..3b2aa9a9fe26 100644
--- a/arch/arm/kernel/reboot.c
+++ b/arch/arm/kernel/reboot.c
@@ -12,10 +12,11 @@
#include <asm/cacheflush.h>
#include <asm/idmap.h>
+#include <asm/virt.h>
#include "reboot.h"
-typedef void (*phys_reset_t)(unsigned long);
+typedef void (*phys_reset_t)(unsigned long, bool);
/*
* Function pointers to optional machine specific functions
@@ -51,7 +52,9 @@ static void __soft_restart(void *addr)
/* Switch to the identity mapping. */
phys_reset = (phys_reset_t)virt_to_idmap(cpu_reset);
- phys_reset((unsigned long)addr);
+
+ /* original stub should be restored by kvm */
+ phys_reset((unsigned long)addr, is_hyp_mode_available());
/* Should never get here. */
BUG();
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index d00d52c9de3e..1846ca4255d0 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -53,11 +53,15 @@ ENDPROC(cpu_v7_proc_fin)
.align 5
.pushsection .idmap.text, "ax"
ENTRY(cpu_v7_reset)
- mrc p15, 0, r1, c1, c0, 0 @ ctrl register
- bic r1, r1, #0x1 @ ...............m
- THUMB( bic r1, r1, #1 << 30 ) @ SCTLR.TE (Thumb exceptions)
- mcr p15, 0, r1, c1, c0, 0 @ disable MMU
+ mrc p15, 0, r2, c1, c0, 0 @ ctrl register
+ bic r2, r2, #0x1 @ ...............m
+ THUMB( bic r2, r2, #1 << 30 ) @ SCTLR.TE (Thumb exceptions)
+ mcr p15, 0, r2, c1, c0, 0 @ disable MMU
isb
+#ifdef CONFIG_ARM_VIRT_EXT
+ teq r1, #0
+ bne __hyp_soft_restart
+#endif
bx r0
ENDPROC(cpu_v7_reset)
.popsection
--
2.7.4
^ permalink raw reply related
* [PATCH] ARM: dts: dra72-evm-tps65917: Add voltage supplies to usb_phy, mmc, dss
From: Roger Quadros @ 2016-12-14 11:00 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161214085703.506-1-lokeshvutla@ti.com>
Lokesh,
On 14/12/16 10:57, Lokesh Vutla wrote:
> Commit 5d080aa30681 ("ARM: dts: dra72: Add separate dtsi for tps65917")
> added a separate dtsi for dra72-evm-tps65917 moving all the voltage supplies
> to this file. But it missed adding voltage supplies to usb_phy, mmc,
> dss and deleted from dra72-evm-common.dtsi. Adding the voltage supply
> phandles to these nodes in dra72-evm-tps65917.dtsi
>
> Fixes: 5d080aa30681 ("ARM: dts: dra72: Add separate dtsi for tps65917")
> Reported-by: Carlos Hernandez <ceh@ti.com>
> Signed-off-by: Roger Quadros <rogerq@ti.com>
> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
> ---
> Logs:
> - DRA72-evm revC: http://pastebin.ubuntu.com/23627665/
> - DRA72-evm revB: http://pastebin.ubuntu.com/23627658/
> arch/arm/boot/dts/dra72-evm-tps65917.dtsi | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/arch/arm/boot/dts/dra72-evm-tps65917.dtsi b/arch/arm/boot/dts/dra72-evm-tps65917.dtsi
> index ee6dac44edf1..e6df676886c0 100644
> --- a/arch/arm/boot/dts/dra72-evm-tps65917.dtsi
> +++ b/arch/arm/boot/dts/dra72-evm-tps65917.dtsi
> @@ -132,3 +132,19 @@
> ti,palmas-long-press-seconds = <6>;
> };
> };
> +
> +&usb2_phy1 {
> + phy-supply = <&ldo4_reg>;
> +};
> +
> +&usb2_phy2 {
> + phy-supply = <&ldo4_reg>;
> +};
> +
> +&dss {
> + vdda_video-supply = <&ldo5_reg>;
> +};
> +
> +&mmc1 {
> + vmmc_aux-supply = <&ldo1_reg>;
> +};
>
Are you sure that all future users of dra72-evm-tps65917.dtsi will use this same configuration?
If not I'd rather put this in the board dts files.
cheers,
-roger
^ permalink raw reply
* [PATCH linux v1 4/4] arm: dts: Add dt-binding to support seven segment display on zaius
From: Russell King - ARM Linux @ 2016-12-14 11:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <10697525.O7CkPN6Gfl@wuerfel>
On Wed, Dec 14, 2016 at 10:00:46AM +0100, Arnd Bergmann wrote:
> On Wednesday, December 14, 2016 9:55:47 AM CET Arnd Bergmann wrote:
> > According to your introductory mail, the interface is assumed to be
> > a 74HC164. Should we use that ID in the compatible string?
> >
> > We can always add other strings later if we want to support multiple
> > wire formats.
>
> Actually, looking up 74hc164, that seems to be a gpio expander,
> so maybe a more flexible way to do the same is to put a driver
> for the expander into drivers/gpio/ and have the main driver
> access the outputs of that using the gpiolib interface.
There already is - drivers/gpio/gpio-74x164.c
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [PATCH 1/2] arm64: Add enable/disable d-cache support for purgatory
From: James Morse @ 2016-12-14 11:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <d8f354da-1e61-feaf-f76a-18e90361e98b@redhat.com>
Hi Pratyush,
On 14/12/16 09:38, Pratyush Anand wrote:
> On Saturday 26 November 2016 12:00 AM, James Morse wrote:
>> On 22/11/16 04:32, Pratyush Anand wrote:
>>> This patch adds support to enable/disable d-cache, which can be used for
>>> faster purgatory sha256 verification.
>>
>> (I'm not clear why we want the sha256, but that is being discussed elsewhere on
>> the thread)
>>
>>
>>> We are supporting only 4K and 64K page sizes. This code will not work if a
>>> hardware is not supporting at least one of these page sizes. Therefore,
>>> D-cache is disabled by default and enabled only when "enable-dcache" is
>>> passed to the kexec().
>>
>> I don't think the maybe-4K/maybe-64K/maybe-neither logic is needed. It would be
>> a lot simpler to only support one page size, which should be 4K as that is what
>> UEFI requires. (If there are CPUs that only support one size, I bet its 4K!)
>
> Ok.. So, I will implement a new version after considering that 4K will always be
> supported. If 4K is not supported by hw(which is very unlikely) then there would
> be no d-cache enabling feature.
Sounds good tom me. I think its important to keep the purgatory code as small
and as simple as possible as its very hard to debug. If we do get bug reports
they are likely to be 'it didn't nothing', with no further details. If it only
fails on some platform we don't have access to its basically impossible.
>> I would go as far as to generate the page tables at 'kexec -l' time, and only if
>
> Ok..So you mean that I create a new section which will have page table entries
> mapping physicalmemory represented by remaining section, and then purgatory can
> just enable mmu with page table from that section, right? Seems doable. can do
> that.
>
>> '/sys/firmware/efi' exists to indicate we booted via UEFI. (and therefore must
>> support 4K pages). This would keep the purgatory code as simple as possible.
>
> What about reading ID_AA64MMFR0_EL1 instead of /sys/firmware/efi? That can also
> tell us that whether 4K is supported or not?
If you're doing it at EL1/EL2 in the purgatory code, sure. But if you generate
the page tables at 'kexec -l' time you can't read this register from EL0 so you
need another way to guess if 4K pages are supported (or just assume they are and
test that register once you're in purgatory).
I was looking for some way to print a message at 'kexec -l' time that the sha256
would be slow as 4K wasn't supported. (a message printed at any other time won't
get seen).
>>> +/*
>>> + * disable_dcache: Disable D-cache and flush RAM locations
>>> + * ram_start - Start address of RAM
>>> + * ram_end - End address of RAM
>>> + */
>>> +void disable_dcache(uint64_t ram_start, uint64_t ram_end)
>>> +{
>>> + switch(get_current_el()) {
>>> + case 2:
>>> + reset_sctlr_el2();
>>> + break;
>>> + case 1:
>>> + reset_sctlr_el1();
>>
>> You have C code running between disabling the MMU and cleaning the cache. The
>> compiler is allowed to move data on and off the stack in here, but after
>> disabling the MMU it will see whatever was on the stack before we turned the MMU
>> on. Any data written at the beginning of this function is left in the caches.
>>
>> I'm afraid this sort of stuff needs to be done in assembly!
>
> All these routines are self coded in assembly even though they are called
> from C, so should be safe I think. Anyway, I can keep all of them in
> assembly as well.
You can't tell the compiler that the stack data is inaccessible until the dcache
clean call completes. Some future version may do really crazy things in here.
You can decompile what your compiler version produces to check it doesn't
load/store to the stack, but that doesn't mean my compiler version does the
same. This is the kind of thing that is extremely difficult to debug, its best
not to take the risk.
Thanks,
James
^ permalink raw reply
* [PATCH 1/2] arm64: Add enable/disable d-cache support for purgatory
From: James Morse @ 2016-12-14 11:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <9a79b666-7990-2a23-2d74-52b3317ce272@redhat.com>
Hi Pratyush,
On 14/12/16 10:12, Pratyush Anand wrote:
> On Wednesday 14 December 2016 03:08 PM, Pratyush Anand wrote:
>>> I would go as far as to generate the page tables at 'kexec -l' time,
>>> and only if
>>
>> Ok..So you mean that I create a new section which will have page table
>> entries mapping physicalmemory represented by remaining section, and
>> then purgatory can just enable mmu with page table from that section,
>> right? Seems doable. can do that.
>
> I see a problem here. If we create page table as a new segment then, how can we
> verify in purgatory that sha for page table is correct? We need page table
> before sha verification start,and we can not rely the page table created by
> first kernel until it's sha is verified. So a chicken-egg problem.
There is more than one of those! What happens if your sha256 calculation code is
corrupted? You have to run it before you know. The same goes for all the
purgatory code.
This is why I think its better to do this in the kernel before we exit to
purgatory, but obviously that doesn't work for kdump.
> I think, creating page table will just take fraction of second and should be
> good even in purgatory, What do you say?
If it's for kdump its best-effort. I think its easier/simpler to generate and
debug them at 'kexec -l' time, but if you're worried about the increased area
that could be corrupted then do it in purgatory.
Thanks,
James
^ permalink raw reply
* [PATCH v7] arm64: fpsimd: improve stacking logic in non-interruptible context
From: Ard Biesheuvel @ 2016-12-14 11:20 UTC (permalink / raw)
To: linux-arm-kernel
Currently, we allow kernel mode NEON in softirq or hardirq context by
stacking and unstacking a slice of the NEON register file for each call
to kernel_neon_begin() and kernel_neon_end(), respectively.
Given that
a) a CPU typically spends most of its time in userland, during which time
no kernel mode NEON in process context is in progress,
b) a CPU spends most of its time in the kernel doing other things than
kernel mode NEON when it gets interrupted to perform kernel mode NEON
in softirq context
the stacking and subsequent unstacking is only necessary if we are
interrupting a thread while it is performing kernel mode NEON in process
context, which means that in all other cases, we can simply preserve the
userland FP/SIMD state once, and only restore it upon return to userland,
even if we are being invoked from softirq or hardirq context.
However, with support being added to teh arm64 kernel for Scalable Vector
Extensions (SVE), which shares the bottom 128 bits of each FP/SIMD register,
but could scale up to 2048 bits per register, the nested stacking and
unstacking that occurs in interrupt context is no longer sufficient, given
that the register contents will be truncated to 128 bits upon restore, unless
we add support for stacking/unstacking the entire SVE state, which does not
sound that appealing.
This means that the FP/SIMD save state operation that encounters the
userland state first *has* to be able to run to completion (since any
interruption could truncate the contents of the registers, which would
result in corrupted state to be restored once the interrupted context is
allowed to resume preserving the state)
Since executing all code involving the FP/SIMD state with interrupts
disabled is undesirable, let's ban kernel mode NEON in hardirq context
altogether. This is a small price to pay, given that the primary use
case of kernel mode NEON, crypto, can deal with this quite easily (and
simply falls back to generic scalar algorithms whose worse performance
should not matter in hardirq context anyway)
With hardirq context removed from the equation, we can modify the FP/SIMD
state manipulation code to execute with softirqs disable. This allows the
critical sections to complete without the risk of having the register
contents getting corrupted half way through.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
v7:
- ban kernel mode NEON in hardirq context, and execute all FP/SIMD state
manipulations with softirqs disabled
v6:
- use a spinlock instead of disabling interrupts
v5:
- perform the test-and-set and the fpsimd_save_state with interrupts disabled,
to prevent nested kernel_neon_begin()/_end() pairs to clobber the state
while it is being preserved
v4:
- use this_cpu_inc/dec, which give sufficient guarantees regarding
concurrency, but do not imply SMP barriers, which are not needed here
v3:
- avoid corruption by concurrent invocations of kernel_neon_begin()/_end()
v2:
- BUG() on unexpected values of the nesting level
- relax the BUG() on num_regs>32 to a WARN, given that nothing actually
breaks in that case
arch/arm64/include/asm/Kbuild | 1 -
arch/arm64/include/asm/simd.h | 16 ++++
arch/arm64/kernel/fpsimd.c | 77 ++++++++++++++------
3 files changed, 72 insertions(+), 22 deletions(-)
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index 44e1d7f10add..39ca0409e157 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -33,7 +33,6 @@ generic-y += segment.h
generic-y += sembuf.h
generic-y += serial.h
generic-y += shmbuf.h
-generic-y += simd.h
generic-y += sizes.h
generic-y += socket.h
generic-y += sockios.h
diff --git a/arch/arm64/include/asm/simd.h b/arch/arm64/include/asm/simd.h
new file mode 100644
index 000000000000..142eca29125a
--- /dev/null
+++ b/arch/arm64/include/asm/simd.h
@@ -0,0 +1,16 @@
+
+#include <linux/hardirq.h>
+
+/*
+ * may_use_simd - whether it is allowable at this time to issue SIMD
+ * instructions or access the SIMD register file
+ *
+ * On arm64, we allow kernel mode NEON in softirq context but not in hardirq
+ * context, due to the fact that the NEON register file may be shared with SVE,
+ * whose state may too large to preserve/restore efficiently at each invocation
+ * of kernel_neon_begin()/_end() in hardirq context.
+ */
+static __must_check inline bool may_use_simd(void)
+{
+ return !in_irq();
+}
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 394c61db5566..97344c94acae 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -127,6 +127,8 @@ void do_fpsimd_exc(unsigned int esr, struct pt_regs *regs)
void fpsimd_thread_switch(struct task_struct *next)
{
+ BUG_ON(!irqs_disabled());
+
/*
* Save the current FPSIMD state to memory, but only if whatever is in
* the registers is in fact the most recent userland FPSIMD state of
@@ -169,8 +171,10 @@ void fpsimd_flush_thread(void)
void fpsimd_preserve_current_state(void)
{
preempt_disable();
+ local_bh_disable();
if (!test_thread_flag(TIF_FOREIGN_FPSTATE))
fpsimd_save_state(¤t->thread.fpsimd_state);
+ local_bh_enable();
preempt_enable();
}
@@ -182,6 +186,7 @@ void fpsimd_preserve_current_state(void)
void fpsimd_restore_current_state(void)
{
preempt_disable();
+ local_bh_disable();
if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) {
struct fpsimd_state *st = ¤t->thread.fpsimd_state;
@@ -189,6 +194,7 @@ void fpsimd_restore_current_state(void)
this_cpu_write(fpsimd_last_state, st);
st->cpu = smp_processor_id();
}
+ local_bh_enable();
preempt_enable();
}
@@ -200,6 +206,7 @@ void fpsimd_restore_current_state(void)
void fpsimd_update_current_state(struct fpsimd_state *state)
{
preempt_disable();
+ local_bh_disable();
fpsimd_load_state(state);
if (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) {
struct fpsimd_state *st = ¤t->thread.fpsimd_state;
@@ -207,6 +214,7 @@ void fpsimd_update_current_state(struct fpsimd_state *state)
this_cpu_write(fpsimd_last_state, st);
st->cpu = smp_processor_id();
}
+ local_bh_enable();
preempt_enable();
}
@@ -220,45 +228,68 @@ void fpsimd_flush_task_state(struct task_struct *t)
#ifdef CONFIG_KERNEL_MODE_NEON
-static DEFINE_PER_CPU(struct fpsimd_partial_state, hardirq_fpsimdstate);
-static DEFINE_PER_CPU(struct fpsimd_partial_state, softirq_fpsimdstate);
+static DEFINE_PER_CPU(struct fpsimd_partial_state, nested_fpsimdstate);
+static DEFINE_PER_CPU(int, kernel_neon_nesting_level);
/*
* Kernel-side NEON support functions
*/
void kernel_neon_begin_partial(u32 num_regs)
{
- if (in_interrupt()) {
- struct fpsimd_partial_state *s = this_cpu_ptr(
- in_irq() ? &hardirq_fpsimdstate : &softirq_fpsimdstate);
+ int level;
- BUG_ON(num_regs > 32);
- fpsimd_save_partial_state(s, roundup(num_regs, 2));
- } else {
+ /*
+ * We don't allow kernel mode NEON in hard IRQ context because we'd
+ * have to assume that any sequence involving preserve/restore of the
+ * FP/SIMD register file could be interrupted by nested use of the NEON.
+ *
+ * On SVE capable hardware, that would necessitate executing all
+ * manipulation of the preserved FP/SIMD state with interrupts disabled,
+ * unless we preserve/restore the *entire* SVE state in interrupt
+ * context as well.
+ */
+ BUG_ON(in_irq());
+
+ preempt_disable();
+ if (current->mm && !test_thread_flag(TIF_FOREIGN_FPSTATE)) {
/*
* Save the userland FPSIMD state if we have one and if we
* haven't done so already. Clear fpsimd_last_state to indicate
* that there is no longer userland FPSIMD state in the
* registers.
*/
- preempt_disable();
- if (current->mm &&
- !test_and_set_thread_flag(TIF_FOREIGN_FPSTATE))
+ local_bh_disable();
+ if (!test_and_set_thread_flag(TIF_FOREIGN_FPSTATE))
fpsimd_save_state(¤t->thread.fpsimd_state);
- this_cpu_write(fpsimd_last_state, NULL);
+ local_bh_enable();
+ }
+ this_cpu_write(fpsimd_last_state, NULL);
+
+ level = this_cpu_inc_return(kernel_neon_nesting_level);
+ BUG_ON(level > 2);
+
+ if (level > 1) {
+ WARN_ON_ONCE(num_regs > 32);
+ num_regs = max(roundup(num_regs, 2), 32U);
+
+ fpsimd_save_partial_state(this_cpu_ptr(&nested_fpsimdstate),
+ num_regs);
}
}
EXPORT_SYMBOL(kernel_neon_begin_partial);
void kernel_neon_end(void)
{
- if (in_interrupt()) {
- struct fpsimd_partial_state *s = this_cpu_ptr(
- in_irq() ? &hardirq_fpsimdstate : &softirq_fpsimdstate);
- fpsimd_load_partial_state(s);
- } else {
- preempt_enable();
- }
+ int level;
+
+ level = this_cpu_read(kernel_neon_nesting_level);
+ BUG_ON(level < 1);
+
+ if (level > 1)
+ fpsimd_load_partial_state(this_cpu_ptr(&nested_fpsimdstate));
+
+ this_cpu_dec(kernel_neon_nesting_level);
+ preempt_enable();
}
EXPORT_SYMBOL(kernel_neon_end);
@@ -270,8 +301,12 @@ static int fpsimd_cpu_pm_notifier(struct notifier_block *self,
{
switch (cmd) {
case CPU_PM_ENTER:
- if (current->mm && !test_thread_flag(TIF_FOREIGN_FPSTATE))
- fpsimd_save_state(¤t->thread.fpsimd_state);
+ if (current->mm) {
+ local_bh_disable();
+ if (!test_thread_flag(TIF_FOREIGN_FPSTATE))
+ fpsimd_save_state(¤t->thread.fpsimd_state);
+ local_bh_enable();
+ }
this_cpu_write(fpsimd_last_state, NULL);
break;
case CPU_PM_EXIT:
--
2.7.4
^ permalink raw reply related
* [PATCH 1/2] arm64: Add enable/disable d-cache support for purgatory
From: Mark Rutland @ 2016-12-14 11:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <585129F7.6070704@arm.com>
On Wed, Dec 14, 2016 at 11:16:07AM +0000, James Morse wrote:
> Hi Pratyush,
> On 14/12/16 09:38, Pratyush Anand wrote:
> > On Saturday 26 November 2016 12:00 AM, James Morse wrote:
> >> On 22/11/16 04:32, Pratyush Anand wrote:
> >>> +/*
> >>> + * disable_dcache: Disable D-cache and flush RAM locations
> >>> + * ram_start - Start address of RAM
> >>> + * ram_end - End address of RAM
> >>> + */
> >>> +void disable_dcache(uint64_t ram_start, uint64_t ram_end)
> >>> +{
> >>> + switch(get_current_el()) {
> >>> + case 2:
> >>> + reset_sctlr_el2();
> >>> + break;
> >>> + case 1:
> >>> + reset_sctlr_el1();
> >>
> >> You have C code running between disabling the MMU and cleaning the cache. The
> >> compiler is allowed to move data on and off the stack in here, but after
> >> disabling the MMU it will see whatever was on the stack before we turned the MMU
> >> on. Any data written at the beginning of this function is left in the caches.
> >>
> >> I'm afraid this sort of stuff needs to be done in assembly!
> >
> > All these routines are self coded in assembly even though they are called
> > from C, so should be safe I think. Anyway, I can keep all of them in
> > assembly as well.
>
> You can't tell the compiler that the stack data is inaccessible until the dcache
> clean call completes. Some future version may do really crazy things in here.
> You can decompile what your compiler version produces to check it doesn't
> load/store to the stack, but that doesn't mean my compiler version does the
> same. This is the kind of thing that is extremely difficult to debug, its best
> not to take the risk.
FWIW, I completely agree.
We've been bitten in the past; see commit 5e051531447259e5 ("arm64:
convert part of soft_restart() to assembly") for an example.
Thanks,
Mark.
^ permalink raw reply
* [PATCH 1/2] arm64: Add enable/disable d-cache support for purgatory
From: Mark Rutland @ 2016-12-14 11:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <58512A01.70101@arm.com>
On Wed, Dec 14, 2016 at 11:16:17AM +0000, James Morse wrote:
> Hi Pratyush,
>
> On 14/12/16 10:12, Pratyush Anand wrote:
> > On Wednesday 14 December 2016 03:08 PM, Pratyush Anand wrote:
> >>> I would go as far as to generate the page tables at 'kexec -l' time,
> >>> and only if
> >>
> >> Ok..So you mean that I create a new section which will have page table
> >> entries mapping physicalmemory represented by remaining section, and
> >> then purgatory can just enable mmu with page table from that section,
> >> right? Seems doable. can do that.
> >
> > I see a problem here. If we create page table as a new segment then, how can we
> > verify in purgatory that sha for page table is correct? We need page table
> > before sha verification start,and we can not rely the page table created by
> > first kernel until it's sha is verified. So a chicken-egg problem.
>
> There is more than one of those! What happens if your sha256 calculation code is
> corrupted? You have to run it before you know. The same goes for all the
> purgatory code.
>
> This is why I think its better to do this in the kernel before we exit to
> purgatory, but obviously that doesn't work for kdump.
I see in an earlier message that the need for sha256 was being discussed
in another thread. Do either of you happen to have a pointer to that.
To me, it seems like it doesn't come with much benefit for the kdump
case given that's best-effort anyway, and as above the verification code
could have been be corrupted. In the non-kdump case it's not strictly
necessary and seems like a debugging aid rather than a necessary piece
of functionality -- if that's the case, a 20 second delay isn't the end
of the world...
Thanks,
Mark.
^ permalink raw reply
* [PATCH linux v1 4/4] arm: dts: Add dt-binding to support seven segment display on zaius
From: Russell King - ARM Linux @ 2016-12-14 11:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161214110635.GB14217@n2100.armlinux.org.uk>
On Wed, Dec 14, 2016 at 11:06:35AM +0000, Russell King - ARM Linux wrote:
> On Wed, Dec 14, 2016 at 10:00:46AM +0100, Arnd Bergmann wrote:
> > On Wednesday, December 14, 2016 9:55:47 AM CET Arnd Bergmann wrote:
> > > According to your introductory mail, the interface is assumed to be
> > > a 74HC164. Should we use that ID in the compatible string?
> > >
> > > We can always add other strings later if we want to support multiple
> > > wire formats.
> >
> > Actually, looking up 74hc164, that seems to be a gpio expander,
> > so maybe a more flexible way to do the same is to put a driver
> > for the expander into drivers/gpio/ and have the main driver
> > access the outputs of that using the gpiolib interface.
>
> There already is - drivers/gpio/gpio-74x164.c
Looking at this more, it's a SPI driver, presumably because the first
case where it appeared was on a SPI bus.
However, it's not a SPI device as such, it's a piece of standard,
general purpose logic that's been around for many years, pre-dating
the SPI bus.
Now, as for DT, we have this "DT represents the hardware, not the
implementation" edict, which now brings up an interesting problem.
If we want to use this driver in its existing form, we need to:
- declare in DT a spi-gpio driver to provide a SPI bus on the GPIO
pins connected to the 74HC164.
- attach the 74HC164 to the SPI bus.
The problem with that is it's not representative of the hardware -
what we're saying is that we want to reuse our existing implementation
and make DT conform to the implementation. At that point, we might as
well scrap our "DT is implementation independent" edict above.
What if, tomorrow, we end up with 74HC164 connected to via a different
method?
I think a much more sensible approach would be to turn the GPIO side
of the 74x164 driver into a library, which can be re-used by multiple
bus-specific drivers - one for SPI which allows it to be used in its
current form, one for our platform bus which takes the GPIO lines for
the data, clock and clear signals.
I also don't see why they shouldn't use the same compatible - they're
the same _device_ at the end of the day, just wired up differently.
It makes the binding documentation a little fun wrt what are required
and optional properties, but nothing that shouldn't be too difficult.
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up
according to speedtest.net.
^ permalink raw reply
* [PATCH 1/2] ARM: hyp-stub: improve ABI
From: Mark Rutland @ 2016-12-14 11:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <E1cH74w-0003ke-Qp@rmk-PC.armlinux.org.uk>
On Wed, Dec 14, 2016 at 10:46:30AM +0000, Russell King wrote:
> Improve the hyp-stub ABI to allow it to do more than just get/set the
> vectors. We follow the example in ARM64, where r0 is used as an opcode
> with the other registers as an argument.
>
> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
This looks good to me, though I'd suggest s/ABI/calling convention/, as
this isn't strictly speaking an ABI. So FWIW:
Acked-by: Mark Rutland <mark.rutland@arm.com>
Thanks,
Mark.
> ---
> arch/arm/kernel/hyp-stub.S | 27 ++++++++++++++++++++++-----
> 1 file changed, 22 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
> index 15d073ae5da2..f3e9ba5fb642 100644
> --- a/arch/arm/kernel/hyp-stub.S
> +++ b/arch/arm/kernel/hyp-stub.S
> @@ -22,6 +22,9 @@
> #include <asm/assembler.h>
> #include <asm/virt.h>
>
> +#define HVC_GET_VECTORS 0
> +#define HVC_SET_VECTORS 1
> +
> #ifndef ZIMAGE
> /*
> * For the kernel proper, we need to find out the CPU boot mode long after
> @@ -202,9 +205,19 @@ ARM_BE8(orr r7, r7, #(1 << 25)) @ HSCTLR.EE
> ENDPROC(__hyp_stub_install_secondary)
>
> __hyp_stub_do_trap:
> - cmp r0, #-1
> - mrceq p15, 4, r0, c12, c0, 0 @ get HVBAR
> - mcrne p15, 4, r0, c12, c0, 0 @ set HVBAR
> + teq r0, #HVC_GET_VECTORS
> + bne 1f
> + mrc p15, 4, r0, c12, c0, 0 @ get HVBAR
> + b __hyp_stub_exit
> +
> +1: teq r0, #HVC_SET_VECTORS
> + bne 1f
> + mcr p15, 4, r1, c12, c0, 0 @ set HVBAR
> + b __hyp_stub_exit
> +
> +1: mov r0, #-1
> +
> +__hyp_stub_exit:
> __ERET
> ENDPROC(__hyp_stub_do_trap)
>
> @@ -231,10 +244,14 @@ ENDPROC(__hyp_stub_do_trap)
> * initialisation entry point.
> */
> ENTRY(__hyp_get_vectors)
> - mov r0, #-1
> + mov r0, #HVC_GET_VECTORS
> + __HVC(0)
> + ret lr
> ENDPROC(__hyp_get_vectors)
> - @ fall through
> +
> ENTRY(__hyp_set_vectors)
> + mov r1, r0
> + mov r0, #HVC_SET_VECTORS
> __HVC(0)
> ret lr
> ENDPROC(__hyp_set_vectors)
> --
> 2.7.4
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox