diff --git a/[refs] b/[refs] index e2f2ab75acd9..0efcd4a959de 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: e851b58cb77b47a5c14267723bd6b76655d21840 +refs/heads/master: 4a8992271c843cb5bcd3321bf6a02eb251280b1d diff --git a/trunk/arch/arm64/include/asm/Kbuild b/trunk/arch/arm64/include/asm/Kbuild index e5fe4f99fe10..a13a4a493d56 100644 --- a/trunk/arch/arm64/include/asm/Kbuild +++ b/trunk/arch/arm64/include/asm/Kbuild @@ -39,7 +39,6 @@ generic-y += shmbuf.h generic-y += sizes.h generic-y += socket.h generic-y += sockios.h -generic-y += string.h generic-y += switch_to.h generic-y += swab.h generic-y += termbits.h diff --git a/trunk/arch/arm64/include/asm/cputype.h b/trunk/arch/arm64/include/asm/cputype.h index cf2749488cd4..ef54125e6c1e 100644 --- a/trunk/arch/arm64/include/asm/cputype.h +++ b/trunk/arch/arm64/include/asm/cputype.h @@ -17,7 +17,6 @@ #define __ASM_CPUTYPE_H #define ID_MIDR_EL1 "midr_el1" -#define ID_MPIDR_EL1 "mpidr_el1" #define ID_CTR_EL0 "ctr_el0" #define ID_AA64PFR0_EL1 "id_aa64pfr0_el1" @@ -26,24 +25,12 @@ #define ID_AA64ISAR0_EL1 "id_aa64isar0_el1" #define ID_AA64MMFR0_EL1 "id_aa64mmfr0_el1" -#define INVALID_HWID ULONG_MAX - -#define MPIDR_HWID_BITMASK 0xff00ffffff - #define read_cpuid(reg) ({ \ u64 __val; \ asm("mrs %0, " reg : "=r" (__val)); \ __val; \ }) -#define ARM_CPU_IMP_ARM 0x41 - -#define ARM_CPU_PART_AEM_V8 0xD0F0 -#define ARM_CPU_PART_FOUNDATION 0xD000 -#define ARM_CPU_PART_CORTEX_A57 0xD070 - -#ifndef __ASSEMBLY__ - /* * The CPU ID never changes at run time, so we might as well tell the * compiler that it's constant. Use this function to read the CPU ID @@ -54,26 +41,9 @@ static inline u32 __attribute_const__ read_cpuid_id(void) return read_cpuid(ID_MIDR_EL1); } -static inline u64 __attribute_const__ read_cpuid_mpidr(void) -{ - return read_cpuid(ID_MPIDR_EL1); -} - -static inline unsigned int __attribute_const__ read_cpuid_implementor(void) -{ - return (read_cpuid_id() & 0xFF000000) >> 24; -} - -static inline unsigned int __attribute_const__ read_cpuid_part_number(void) -{ - return (read_cpuid_id() & 0xFFF0); -} - static inline u32 __attribute_const__ read_cpuid_cachetype(void) { return read_cpuid(ID_CTR_EL0); } -#endif /* __ASSEMBLY__ */ - #endif diff --git a/trunk/arch/arm64/include/asm/exception.h b/trunk/arch/arm64/include/asm/exception.h index 0303705fcad6..ac63519b7b90 100644 --- a/trunk/arch/arm64/include/asm/exception.h +++ b/trunk/arch/arm64/include/asm/exception.h @@ -19,6 +19,5 @@ #define __ASM_EXCEPTION_H #define __exception __attribute__((section(".exception.text"))) -#define __exception_irq_entry __exception #endif /* __ASM_EXCEPTION_H */ diff --git a/trunk/arch/arm64/include/asm/hardirq.h b/trunk/arch/arm64/include/asm/hardirq.h index 990c051e7829..507546353d62 100644 --- a/trunk/arch/arm64/include/asm/hardirq.h +++ b/trunk/arch/arm64/include/asm/hardirq.h @@ -49,9 +49,4 @@ static inline void ack_bad_irq(unsigned int irq) extern void handle_IRQ(unsigned int, struct pt_regs *); -/* - * No arch-specific IRQ flags. - */ -#define set_irq_flags(irq, flags) - #endif /* __ASM_HARDIRQ_H */ diff --git a/trunk/arch/arm64/include/asm/irq.h b/trunk/arch/arm64/include/asm/irq.h index 0332fc077f6e..a4e1cad3202a 100644 --- a/trunk/arch/arm64/include/asm/irq.h +++ b/trunk/arch/arm64/include/asm/irq.h @@ -4,6 +4,5 @@ #include extern void (*handle_arch_irq)(struct pt_regs *); -extern void set_handle_irq(void (*handle_irq)(struct pt_regs *)); #endif diff --git a/trunk/arch/arm64/include/asm/smp_plat.h b/trunk/arch/arm64/include/asm/string.h similarity index 55% rename from trunk/arch/arm64/include/asm/smp_plat.h rename to trunk/arch/arm64/include/asm/string.h index ed43a0d2b1b2..be8a644f306a 100644 --- a/trunk/arch/arm64/include/asm/smp_plat.h +++ b/trunk/arch/arm64/include/asm/string.h @@ -1,9 +1,7 @@ /* - * Definitions specific to SMP platforms. - * * Copyright (C) 2013 ARM Ltd. * - * This program is free software: you can redistribute it and/or modify + * 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. * @@ -15,16 +13,19 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ +#ifndef __ASM_STRING_H +#define __ASM_STRING_H -#ifndef __ASM_SMP_PLAT_H -#define __ASM_SMP_PLAT_H +#define __HAVE_ARCH_MEMCPY +extern void *memcpy(void *, const void *, __kernel_size_t); -#include +#define __HAVE_ARCH_MEMMOVE +extern void *memmove(void *, const void *, __kernel_size_t); -/* - * Logical CPU mapping. - */ -extern u64 __cpu_logical_map[NR_CPUS]; -#define cpu_logical_map(cpu) __cpu_logical_map[cpu] +#define __HAVE_ARCH_MEMCHR +extern void *memchr(const void *, int, __kernel_size_t); + +#define __HAVE_ARCH_MEMSET +extern void *memset(void *, int, __kernel_size_t); -#endif /* __ASM_SMP_PLAT_H */ +#endif diff --git a/trunk/arch/arm64/kernel/arm64ksyms.c b/trunk/arch/arm64/kernel/arm64ksyms.c index aa3e948f7885..d7f7b17c414e 100644 --- a/trunk/arch/arm64/kernel/arm64ksyms.c +++ b/trunk/arch/arm64/kernel/arm64ksyms.c @@ -46,3 +46,9 @@ EXPORT_SYMBOL(__atomic_hash); /* physical memory */ EXPORT_SYMBOL(memstart_addr); + + /* string / mem functions */ +EXPORT_SYMBOL(memset); +EXPORT_SYMBOL(memcpy); +EXPORT_SYMBOL(memmove); +EXPORT_SYMBOL(memchr); diff --git a/trunk/arch/arm64/kernel/early_printk.c b/trunk/arch/arm64/kernel/early_printk.c index ac974f48a7a2..7e320a2edb9b 100644 --- a/trunk/arch/arm64/kernel/early_printk.c +++ b/trunk/arch/arm64/kernel/early_printk.c @@ -24,7 +24,6 @@ #include #include -#include static void __iomem *early_base; static void (*printch)(char ch); @@ -41,37 +40,6 @@ static void pl011_printch(char ch) ; } -/* - * Semihosting-based debug console - */ -static void smh_printch(char ch) -{ - asm volatile("mov x1, %0\n" - "mov x0, #3\n" - "hlt 0xf000\n" - : : "r" (&ch) : "x0", "x1", "memory"); -} - -/* - * 8250/16550 (8-bit aligned registers) single character TX. - */ -static void uart8250_8bit_printch(char ch) -{ - while (!(readb_relaxed(early_base + UART_LSR) & UART_LSR_THRE)) - ; - writeb_relaxed(ch, early_base + UART_TX); -} - -/* - * 8250/16550 (32-bit aligned registers) single character TX. - */ -static void uart8250_32bit_printch(char ch) -{ - while (!(readl_relaxed(early_base + (UART_LSR << 2)) & UART_LSR_THRE)) - ; - writel_relaxed(ch, early_base + (UART_TX << 2)); -} - struct earlycon_match { const char *name; void (*printch)(char ch); @@ -79,9 +47,6 @@ struct earlycon_match { static const struct earlycon_match earlycon_match[] __initconst = { { .name = "pl011", .printch = pl011_printch, }, - { .name = "smh", .printch = smh_printch, }, - { .name = "uart8250-8bit", .printch = uart8250_8bit_printch, }, - { .name = "uart8250-32bit", .printch = uart8250_32bit_printch, }, {} }; diff --git a/trunk/arch/arm64/kernel/head.S b/trunk/arch/arm64/kernel/head.S index 53dcae49e729..0a0a49756826 100644 --- a/trunk/arch/arm64/kernel/head.S +++ b/trunk/arch/arm64/kernel/head.S @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -230,8 +229,7 @@ ENTRY(secondary_holding_pen) bl __calc_phys_offset // x24=phys offset bl el2_setup // Drop to EL1 mrs x0, mpidr_el1 - ldr x1, =MPIDR_HWID_BITMASK - and x0, x0, x1 + and x0, x0, #15 // CPU number adr x1, 1b ldp x2, x3, [x1] sub x1, x1, x2 diff --git a/trunk/arch/arm64/kernel/irq.c b/trunk/arch/arm64/kernel/irq.c index ecb3354292ed..0373c6609eaf 100644 --- a/trunk/arch/arm64/kernel/irq.c +++ b/trunk/arch/arm64/kernel/irq.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -67,17 +67,18 @@ void handle_IRQ(unsigned int irq, struct pt_regs *regs) set_irq_regs(old_regs); } -void __init set_handle_irq(void (*handle_irq)(struct pt_regs *)) -{ - if (handle_arch_irq) - return; - - handle_arch_irq = handle_irq; -} +/* + * Interrupt controllers supported by the kernel. + */ +static const struct of_device_id intctrl_of_match[] __initconst = { + /* IRQ controllers { .compatible, .data } info to go here */ + {} +}; void __init init_IRQ(void) { - irqchip_init(); + of_irq_init(intctrl_of_match); + if (!handle_arch_irq) panic("No interrupt controller found."); } diff --git a/trunk/arch/arm64/kernel/setup.c b/trunk/arch/arm64/kernel/setup.c index 6a9a53292590..113db863f832 100644 --- a/trunk/arch/arm64/kernel/setup.c +++ b/trunk/arch/arm64/kernel/setup.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -47,7 +46,6 @@ #include #include #include -#include #include #include #include @@ -242,8 +240,6 @@ static void __init request_standard_resources(void) } } -u64 __cpu_logical_map[NR_CPUS] = { [0 ... NR_CPUS-1] = INVALID_HWID }; - void __init setup_arch(char **cmdline_p) { setup_processor(); @@ -268,7 +264,6 @@ void __init setup_arch(char **cmdline_p) psci_init(); - cpu_logical_map(0) = read_cpuid_mpidr() & MPIDR_HWID_BITMASK; #ifdef CONFIG_SMP smp_init_cpus(); #endif @@ -282,13 +277,6 @@ void __init setup_arch(char **cmdline_p) #endif } -static int __init arm64_of_clk_init(void) -{ - of_clk_init(NULL); - return 0; -} -arch_initcall(arm64_of_clk_init); - static DEFINE_PER_CPU(struct cpu, cpu_data); static int __init topology_init(void) diff --git a/trunk/arch/arm64/kernel/smp.c b/trunk/arch/arm64/kernel/smp.c index d4dcc6515253..bdd34597254b 100644 --- a/trunk/arch/arm64/kernel/smp.c +++ b/trunk/arch/arm64/kernel/smp.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -54,7 +53,7 @@ * where to place its SVC stack */ struct secondary_data secondary_data; -volatile unsigned long secondary_holding_pen_release = INVALID_HWID; +volatile unsigned long secondary_holding_pen_release = -1; enum ipi_msg_type { IPI_RESCHEDULE, @@ -71,7 +70,7 @@ static DEFINE_RAW_SPINLOCK(boot_lock); * in coherency or not. This is necessary for the hotplug code to work * reliably. */ -static void __cpuinit write_pen_release(u64 val) +static void __cpuinit write_pen_release(int val) { void *start = (void *)&secondary_holding_pen_release; unsigned long size = sizeof(secondary_holding_pen_release); @@ -97,7 +96,7 @@ static int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) /* * Update the pen release flag. */ - write_pen_release(cpu_logical_map(cpu)); + write_pen_release(cpu); /* * Send an event, causing the secondaries to read pen_release. @@ -106,7 +105,7 @@ static int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { - if (secondary_holding_pen_release == INVALID_HWID) + if (secondary_holding_pen_release == -1UL) break; udelay(10); } @@ -117,7 +116,7 @@ static int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) */ raw_spin_unlock(&boot_lock); - return secondary_holding_pen_release != INVALID_HWID ? -ENOSYS : 0; + return secondary_holding_pen_release != -1 ? -ENOSYS : 0; } static DECLARE_COMPLETION(cpu_running); @@ -191,7 +190,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void) * Let the primary processor know we're out of the * pen, then head off into the C entry point */ - write_pen_release(INVALID_HWID); + write_pen_release(-1); /* * Synchronise with the boot thread. @@ -258,77 +257,15 @@ static const struct smp_enable_ops * __init smp_get_enable_ops(const char *name) } /* - * Enumerate the possible CPU set from the device tree and build the - * cpu logical map array containing MPIDR values related to logical - * cpus. Assumes that cpu_logical_map(0) has already been initialized. + * Enumerate the possible CPU set from the device tree. */ void __init smp_init_cpus(void) { const char *enable_method; struct device_node *dn = NULL; - int i, cpu = 1; - bool bootcpu_valid = false; + int cpu = 0; while ((dn = of_find_node_by_type(dn, "cpu"))) { - u64 hwid; - - /* - * A cpu node with missing "reg" property is - * considered invalid to build a cpu_logical_map - * entry. - */ - if (of_property_read_u64(dn, "reg", &hwid)) { - pr_err("%s: missing reg property\n", dn->full_name); - goto next; - } - - /* - * Non affinity bits must be set to 0 in the DT - */ - if (hwid & ~MPIDR_HWID_BITMASK) { - pr_err("%s: invalid reg property\n", dn->full_name); - goto next; - } - - /* - * Duplicate MPIDRs are a recipe for disaster. Scan - * all initialized entries and check for - * duplicates. If any is found just ignore the cpu. - * cpu_logical_map was initialized to INVALID_HWID to - * avoid matching valid MPIDR values. - */ - for (i = 1; (i < cpu) && (i < NR_CPUS); i++) { - if (cpu_logical_map(i) == hwid) { - pr_err("%s: duplicate cpu reg properties in the DT\n", - dn->full_name); - goto next; - } - } - - /* - * The numbering scheme requires that the boot CPU - * must be assigned logical id 0. Record it so that - * the logical map built from DT is validated and can - * be used. - */ - if (hwid == cpu_logical_map(0)) { - if (bootcpu_valid) { - pr_err("%s: duplicate boot cpu reg property in DT\n", - dn->full_name); - goto next; - } - - bootcpu_valid = true; - - /* - * cpu_logical_map has already been - * initialized and the boot cpu doesn't need - * the enable-method so continue without - * incrementing cpu. - */ - continue; - } - if (cpu >= NR_CPUS) goto next; @@ -337,24 +274,22 @@ void __init smp_init_cpus(void) */ enable_method = of_get_property(dn, "enable-method", NULL); if (!enable_method) { - pr_err("%s: missing enable-method property\n", - dn->full_name); + pr_err("CPU %d: missing enable-method property\n", cpu); goto next; } smp_enable_ops[cpu] = smp_get_enable_ops(enable_method); if (!smp_enable_ops[cpu]) { - pr_err("%s: invalid enable-method property: %s\n", - dn->full_name, enable_method); + pr_err("CPU %d: invalid enable-method property: %s\n", + cpu, enable_method); goto next; } if (smp_enable_ops[cpu]->init_cpu(dn, cpu)) goto next; - pr_debug("cpu logical map 0x%llx\n", hwid); - cpu_logical_map(cpu) = hwid; + set_cpu_possible(cpu, true); next: cpu++; } @@ -363,19 +298,6 @@ void __init smp_init_cpus(void) if (cpu > NR_CPUS) pr_warning("no. of cores (%d) greater than configured maximum of %d - clipping\n", cpu, NR_CPUS); - - if (!bootcpu_valid) { - pr_err("DT missing boot CPU MPIDR, not enabling secondaries\n"); - return; - } - - /* - * All the cpus that made it to the cpu_logical_map have been - * validated so set them as possible cpus. - */ - for (i = 0; i < NR_CPUS; i++) - if (cpu_logical_map(i) != INVALID_HWID) - set_cpu_possible(i, true); } void __init smp_prepare_cpus(unsigned int max_cpus) diff --git a/trunk/arch/arm64/kernel/smp_psci.c b/trunk/arch/arm64/kernel/smp_psci.c index 0c533301be77..112091684c22 100644 --- a/trunk/arch/arm64/kernel/smp_psci.c +++ b/trunk/arch/arm64/kernel/smp_psci.c @@ -21,7 +21,6 @@ #include #include -#include static int __init smp_psci_init_cpu(struct device_node *dn, int cpu) { @@ -37,7 +36,7 @@ static int __init smp_psci_prepare_cpu(int cpu) return -ENODEV; } - err = psci_ops.cpu_on(cpu_logical_map(cpu), __pa(secondary_holding_pen)); + err = psci_ops.cpu_on(cpu, __pa(secondary_holding_pen)); if (err) { pr_err("psci: failed to boot CPU%d (%d)\n", cpu, err); return err; @@ -48,6 +47,6 @@ static int __init smp_psci_prepare_cpu(int cpu) const struct smp_enable_ops smp_psci_ops __initconst = { .name = "psci", - .init_cpu = smp_psci_init_cpu, + .init_cpu = smp_psci_init_cpu, .prepare_cpu = smp_psci_prepare_cpu, }; diff --git a/trunk/arch/arm64/lib/Makefile b/trunk/arch/arm64/lib/Makefile index 2fb7f6092aae..2fce1398aa24 100644 --- a/trunk/arch/arm64/lib/Makefile +++ b/trunk/arch/arm64/lib/Makefile @@ -1,4 +1,5 @@ lib-y := bitops.o delay.o \ strncpy_from_user.o strnlen_user.o clear_user.o \ copy_from_user.o copy_to_user.o copy_in_user.o \ - copy_page.o clear_page.o + copy_page.o clear_page.o \ + memchr.o memcpy.o memmove.o memset.o diff --git a/trunk/arch/arm64/lib/memchr.S b/trunk/arch/arm64/lib/memchr.S new file mode 100644 index 000000000000..8636b7549163 --- /dev/null +++ b/trunk/arch/arm64/lib/memchr.S @@ -0,0 +1,44 @@ +/* + * Based on arch/arm/lib/memchr.S + * + * Copyright (C) 1995-2000 Russell King + * Copyright (C) 2013 ARM Ltd. + * + * 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 . + */ + +#include +#include + +/* + * Find a character in an area of memory. + * + * Parameters: + * x0 - buf + * x1 - c + * x2 - n + * Returns: + * x0 - address of first occurrence of 'c' or 0 + */ +ENTRY(memchr) + and w1, w1, #0xff +1: subs x2, x2, #1 + b.mi 2f + ldrb w3, [x0], #1 + cmp w3, w1 + b.ne 1b + sub x0, x0, #1 + ret +2: mov x0, #0 + ret +ENDPROC(memchr) diff --git a/trunk/arch/arm64/lib/memcpy.S b/trunk/arch/arm64/lib/memcpy.S new file mode 100644 index 000000000000..27b5003609b6 --- /dev/null +++ b/trunk/arch/arm64/lib/memcpy.S @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2013 ARM Ltd. + * + * 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 . + */ + +#include +#include + +/* + * Copy a buffer from src to dest (alignment handled by the hardware) + * + * Parameters: + * x0 - dest + * x1 - src + * x2 - n + * Returns: + * x0 - dest + */ +ENTRY(memcpy) + mov x4, x0 + subs x2, x2, #8 + b.mi 2f +1: ldr x3, [x1], #8 + subs x2, x2, #8 + str x3, [x4], #8 + b.pl 1b +2: adds x2, x2, #4 + b.mi 3f + ldr w3, [x1], #4 + sub x2, x2, #4 + str w3, [x4], #4 +3: adds x2, x2, #2 + b.mi 4f + ldrh w3, [x1], #2 + sub x2, x2, #2 + strh w3, [x4], #2 +4: adds x2, x2, #1 + b.mi 5f + ldrb w3, [x1] + strb w3, [x4] +5: ret +ENDPROC(memcpy) diff --git a/trunk/arch/arm64/lib/memmove.S b/trunk/arch/arm64/lib/memmove.S new file mode 100644 index 000000000000..b79fdfa42d39 --- /dev/null +++ b/trunk/arch/arm64/lib/memmove.S @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2013 ARM Ltd. + * + * 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 . + */ + +#include +#include + +/* + * Move a buffer from src to test (alignment handled by the hardware). + * If dest <= src, call memcpy, otherwise copy in reverse order. + * + * Parameters: + * x0 - dest + * x1 - src + * x2 - n + * Returns: + * x0 - dest + */ +ENTRY(memmove) + cmp x0, x1 + b.ls memcpy + add x4, x0, x2 + add x1, x1, x2 + subs x2, x2, #8 + b.mi 2f +1: ldr x3, [x1, #-8]! + subs x2, x2, #8 + str x3, [x4, #-8]! + b.pl 1b +2: adds x2, x2, #4 + b.mi 3f + ldr w3, [x1, #-4]! + sub x2, x2, #4 + str w3, [x4, #-4]! +3: adds x2, x2, #2 + b.mi 4f + ldrh w3, [x1, #-2]! + sub x2, x2, #2 + strh w3, [x4, #-2]! +4: adds x2, x2, #1 + b.mi 5f + ldrb w3, [x1, #-1] + strb w3, [x4, #-1] +5: ret +ENDPROC(memmove) diff --git a/trunk/arch/arm64/lib/memset.S b/trunk/arch/arm64/lib/memset.S new file mode 100644 index 000000000000..87e4a68fbbbc --- /dev/null +++ b/trunk/arch/arm64/lib/memset.S @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2013 ARM Ltd. + * + * 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 . + */ + +#include +#include + +/* + * Fill in the buffer with character c (alignment handled by the hardware) + * + * Parameters: + * x0 - buf + * x1 - c + * x2 - n + * Returns: + * x0 - buf + */ +ENTRY(memset) + mov x4, x0 + and w1, w1, #0xff + orr w1, w1, w1, lsl #8 + orr w1, w1, w1, lsl #16 + orr x1, x1, x1, lsl #32 + subs x2, x2, #8 + b.mi 2f +1: str x1, [x4], #8 + subs x2, x2, #8 + b.pl 1b +2: adds x2, x2, #4 + b.mi 3f + sub x2, x2, #4 + str w1, [x4], #4 +3: adds x2, x2, #2 + b.mi 4f + sub x2, x2, #2 + strh w1, [x4], #2 +4: adds x2, x2, #1 + b.mi 5f + strb w1, [x4] +5: ret +ENDPROC(memset)