summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAchin Gupta <achin.gupta@arm.com>2013-10-25 09:08:21 +0100
committerJames Morrissey <james.morrissey@arm.com>2013-10-25 09:37:16 +0100
commit4f6ad66ae9fcc8bcb3b0fcee10b7ab1ffcaf1a56 (patch)
tree475db5d74370cb62b02afab0900774955a59702f /lib
ARMv8 Trusted Firmware release v0.2
Diffstat (limited to 'lib')
-rw-r--r--lib/arch/aarch64/cache_helpers.S233
-rw-r--r--lib/arch/aarch64/misc_helpers.S274
-rw-r--r--lib/arch/aarch64/sysreg_helpers.S1154
-rw-r--r--lib/arch/aarch64/tlb_helpers.S111
-rw-r--r--lib/mmio.c41
-rw-r--r--lib/non-semihosting/ctype.h60
-rw-r--r--lib/non-semihosting/mem.c103
-rw-r--r--lib/non-semihosting/std.c106
-rw-r--r--lib/non-semihosting/strcmp.c49
-rw-r--r--lib/non-semihosting/string.c40
-rw-r--r--lib/non-semihosting/strlen.c46
-rw-r--r--lib/non-semihosting/strncmp.c52
-rw-r--r--lib/non-semihosting/strncpy.c62
-rw-r--r--lib/non-semihosting/strsep.c74
-rw-r--r--lib/non-semihosting/strtol.c146
-rw-r--r--lib/non-semihosting/strtoull.c117
-rw-r--r--lib/non-semihosting/subr_prf.c557
-rw-r--r--lib/semihosting/aarch64/semihosting_call.S37
-rw-r--r--lib/semihosting/semihosting.c234
-rw-r--r--lib/sync/locks/bakery/bakery_lock.c104
-rw-r--r--lib/sync/locks/exclusive/spinlock.S50
21 files changed, 3650 insertions, 0 deletions
diff --git a/lib/arch/aarch64/cache_helpers.S b/lib/arch/aarch64/cache_helpers.S
new file mode 100644
index 0000000..b8a5608
--- /dev/null
+++ b/lib/arch/aarch64/cache_helpers.S
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2013, ARM Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+#include <asm_macros.S>
+
+ .globl dcisw
+ .globl dccisw
+ .globl dccsw
+ .globl dccvac
+ .globl dcivac
+ .globl dccivac
+ .globl dccvau
+ .globl dczva
+ .globl flush_dcache_range
+ .globl inv_dcache_range
+ .globl dcsw_op_louis
+ .globl dcsw_op_all
+
+ .section .text, "ax"; .align 3
+
+dcisw:; .type dcisw, %function
+ dc isw, x0
+ dsb sy
+ isb
+ ret
+
+
+dccisw:; .type dccisw, %function
+ dc cisw, x0
+ dsb sy
+ isb
+ ret
+
+
+dccsw:; .type dccsw, %function
+ dc csw, x0
+ dsb sy
+ isb
+ ret
+
+
+dccvac:; .type dccvac, %function
+ dc cvac, x0
+ dsb sy
+ isb
+ ret
+
+
+dcivac:; .type dcivac, %function
+ dc ivac, x0
+ dsb sy
+ isb
+ ret
+
+
+dccivac:; .type dccivac, %function
+ dc civac, x0
+ dsb sy
+ isb
+ ret
+
+
+dccvau:; .type dccvau, %function
+ dc cvau, x0
+ dsb sy
+ isb
+ ret
+
+
+dczva:; .type dczva, %function
+ dc zva, x0
+ dsb sy
+ isb
+ ret
+
+
+ /* ------------------------------------------
+ * Clean+Invalidate from base address till
+ * size. 'x0' = addr, 'x1' = size
+ * ------------------------------------------
+ */
+flush_dcache_range:; .type flush_dcache_range, %function
+ dcache_line_size x2, x3
+ add x1, x0, x1
+ sub x3, x2, #1
+ bic x0, x0, x3
+flush_loop:
+ dc civac, x0
+ add x0, x0, x2
+ cmp x0, x1
+ b.lo flush_loop
+ dsb sy
+ ret
+
+
+ /* ------------------------------------------
+ * Invalidate from base address till
+ * size. 'x0' = addr, 'x1' = size
+ * ------------------------------------------
+ */
+inv_dcache_range:; .type inv_dcache_range, %function
+ dcache_line_size x2, x3
+ add x1, x0, x1
+ sub x3, x2, #1
+ bic x0, x0, x3
+inv_loop:
+ dc ivac, x0
+ add x0, x0, x2
+ cmp x0, x1
+ b.lo inv_loop
+ dsb sy
+ ret
+
+
+ /* ------------------------------------------
+ * Data cache operations by set/way to the
+ * level specified
+ * ------------------------------------------
+ * ----------------------------------
+ * Call this func with the clidr in
+ * x0, starting cache level in x10,
+ * last cache level in x3 & cm op in
+ * x14
+ * ----------------------------------
+ */
+dcsw_op:; .type dcsw_op, %function
+all_start_at_level:
+ add x2, x10, x10, lsr #1 // work out 3x current cache level
+ lsr x1, x0, x2 // extract cache type bits from clidr
+ and x1, x1, #7 // mask of the bits for current cache only
+ cmp x1, #2 // see what cache we have at this level
+ b.lt skip // skip if no cache, or just i-cache
+ msr csselr_el1, x10 // select current cache level in csselr
+ isb // isb to sych the new cssr&csidr
+ mrs x1, ccsidr_el1 // read the new ccsidr
+ and x2, x1, #7 // extract the length of the cache lines
+ add x2, x2, #4 // add 4 (line length offset)
+ mov x4, #0x3ff
+ and x4, x4, x1, lsr #3 // find maximum number on the way size
+ clz w5, w4 // find bit position of way size increment
+ mov x7, #0x7fff
+ and x7, x7, x1, lsr #13 // extract max number of the index size
+loop2:
+ mov x9, x4 // create working copy of max way size
+loop3:
+ lsl x6, x9, x5
+ orr x11, x10, x6 // factor way and cache number into x11
+ lsl x6, x7, x2
+ orr x11, x11, x6 // factor index number into x11
+ mov x12, x0
+ mov x13, x30 // lr
+ mov x0, x11
+ blr x14
+ mov x0, x12
+ mov x30, x13 // lr
+ subs x9, x9, #1 // decrement the way
+ b.ge loop3
+ subs x7, x7, #1 // decrement the index
+ b.ge loop2
+skip:
+ add x10, x10, #2 // increment cache number
+ cmp x3, x10
+ b.gt all_start_at_level
+finished:
+ mov x10, #0 // swith back to cache level 0
+ msr csselr_el1, x10 // select current cache level in csselr
+ dsb sy
+ isb
+ ret
+
+
+do_dcsw_op:; .type do_dcsw_op, %function
+ cbz x3, exit
+ cmp x0, #DCISW
+ b.eq dc_isw
+ cmp x0, #DCCISW
+ b.eq dc_cisw
+ cmp x0, #DCCSW
+ b.eq dc_csw
+dc_isw:
+ mov x0, x9
+ adr x14, dcisw
+ b dcsw_op
+dc_cisw:
+ mov x0, x9
+ adr x14, dccisw
+ b dcsw_op
+dc_csw:
+ mov x0, x9
+ adr x14, dccsw
+ b dcsw_op
+exit:
+ ret
+
+
+dcsw_op_louis:; .type dcsw_op_louis, %function
+ dsb sy
+ setup_dcsw_op_args x10, x3, x9, #LOUIS_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
+ b do_dcsw_op
+
+
+dcsw_op_all:; .type dcsw_op_all, %function
+ dsb sy
+ setup_dcsw_op_args x10, x3, x9, #LOC_SHIFT, #CLIDR_FIELD_WIDTH, #LEVEL_SHIFT
+ b do_dcsw_op
diff --git a/lib/arch/aarch64/misc_helpers.S b/lib/arch/aarch64/misc_helpers.S
new file mode 100644
index 0000000..8c1f740
--- /dev/null
+++ b/lib/arch/aarch64/misc_helpers.S
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2013, ARM Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+
+ .globl enable_irq
+ .globl disable_irq
+
+ .globl enable_fiq
+ .globl disable_fiq
+
+ .globl enable_serror
+ .globl disable_serror
+
+ .globl read_daif
+ .globl write_daif
+
+ .globl read_spsr
+ .globl read_spsr_el1
+ .globl read_spsr_el2
+ .globl read_spsr_el3
+
+ .globl write_spsr
+ .globl write_spsr_el1
+ .globl write_spsr_el2
+ .globl write_spsr_el3
+
+ .globl read_elr
+ .globl read_elr_el1
+ .globl read_elr_el2
+ .globl read_elr_el3
+
+ .globl write_elr
+ .globl write_elr_el1
+ .globl write_elr_el2
+ .globl write_elr_el3
+
+ .globl get_afflvl_shift
+ .globl mpidr_mask_lower_afflvls
+ .globl dsb
+ .globl isb
+ .globl sev
+ .globl wfe
+ .globl wfi
+ .globl eret
+ .globl smc
+
+
+ .section .text, "ax"
+
+get_afflvl_shift:; .type get_afflvl_shift, %function
+ cmp x0, #3
+ cinc x0, x0, eq
+ mov x1, #MPIDR_AFFLVL_SHIFT
+ lsl x0, x0, x1
+ ret
+
+mpidr_mask_lower_afflvls:; .type mpidr_mask_lower_afflvls, %function
+ cmp x1, #3
+ cinc x1, x1, eq
+ mov x2, #MPIDR_AFFLVL_SHIFT
+ lsl x2, x1, x2
+ lsr x0, x0, x2
+ lsl x0, x0, x2
+ ret
+
+ /* -----------------------------------------------------
+ * Asynchronous exception manipulation accessors
+ * -----------------------------------------------------
+ */
+enable_irq:; .type enable_irq, %function
+ msr daifclr, #DAIF_IRQ_BIT
+ ret
+
+
+enable_fiq:; .type enable_fiq, %function
+ msr daifclr, #DAIF_FIQ_BIT
+ ret
+
+
+enable_serror:; .type enable_serror, %function
+ msr daifclr, #DAIF_ABT_BIT
+ ret
+
+
+disable_irq:; .type disable_irq, %function
+ msr daifset, #DAIF_IRQ_BIT
+ ret
+
+
+disable_fiq:; .type disable_fiq, %function
+ msr daifset, #DAIF_FIQ_BIT
+ ret
+
+
+disable_serror:; .type disable_serror, %function
+ msr daifset, #DAIF_ABT_BIT
+ ret
+
+
+read_daif:; .type read_daif, %function
+ mrs x0, daif
+ ret
+
+
+write_daif:; .type write_daif, %function
+ msr daif, x0
+ ret
+
+
+read_spsr:; .type read_spsr, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq read_spsr_el1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq read_spsr_el2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq read_spsr_el3
+
+
+read_spsr_el1:; .type read_spsr_el1, %function
+ mrs x0, spsr_el1
+ ret
+
+
+read_spsr_el2:; .type read_spsr_el2, %function
+ mrs x0, spsr_el2
+ ret
+
+
+read_spsr_el3:; .type read_spsr_el3, %function
+ mrs x0, spsr_el3
+ ret
+
+
+write_spsr:; .type write_spsr, %function
+ mrs x1, CurrentEl
+ cmp x1, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq write_spsr_el1
+ cmp x1, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq write_spsr_el2
+ cmp x1, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq write_spsr_el3
+
+
+write_spsr_el1:; .type write_spsr_el1, %function
+ msr spsr_el1, x0
+ isb
+ ret
+
+
+write_spsr_el2:; .type write_spsr_el2, %function
+ msr spsr_el2, x0
+ isb
+ ret
+
+
+write_spsr_el3:; .type write_spsr_el3, %function
+ msr spsr_el3, x0
+ isb
+ ret
+
+
+read_elr:; .type read_elr, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq read_elr_el1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq read_elr_el2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq read_elr_el3
+
+
+read_elr_el1:; .type read_elr_el1, %function
+ mrs x0, elr_el1
+ ret
+
+
+read_elr_el2:; .type read_elr_el2, %function
+ mrs x0, elr_el2
+ ret
+
+
+read_elr_el3:; .type read_elr_el3, %function
+ mrs x0, elr_el3
+ ret
+
+
+write_elr:; .type write_elr, %function
+ mrs x1, CurrentEl
+ cmp x1, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq write_elr_el1
+ cmp x1, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq write_elr_el2
+ cmp x1, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq write_elr_el3
+
+
+write_elr_el1:; .type write_elr_el1, %function
+ msr elr_el1, x0
+ isb
+ ret
+
+
+write_elr_el2:; .type write_elr_el2, %function
+ msr elr_el2, x0
+ isb
+ ret
+
+
+write_elr_el3:; .type write_elr_el3, %function
+ msr elr_el3, x0
+ isb
+ ret
+
+
+dsb:; .type dsb, %function
+ dsb sy
+ ret
+
+
+isb:; .type isb, %function
+ isb
+ ret
+
+
+sev:; .type sev, %function
+ sev
+ ret
+
+
+wfe:; .type wfe, %function
+ wfe
+ ret
+
+
+wfi:; .type wfi, %function
+ wfi
+ ret
+
+
+eret:; .type eret, %function
+ eret
+
+
+smc:; .type smc, %function
+ smc #0
diff --git a/lib/arch/aarch64/sysreg_helpers.S b/lib/arch/aarch64/sysreg_helpers.S
new file mode 100644
index 0000000..e68192f
--- /dev/null
+++ b/lib/arch/aarch64/sysreg_helpers.S
@@ -0,0 +1,1154 @@
+/*
+ * Copyright (c) 2013, ARM Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+
+ .globl read_vbar
+ .globl read_vbar_el1
+ .globl read_vbar_el2
+ .globl read_vbar_el3
+ .globl write_vbar
+ .globl write_vbar_el1
+ .globl write_vbar_el2
+ .globl write_vbar_el3
+
+ .globl read_sctlr
+ .globl read_sctlr_el1
+ .globl read_sctlr_el2
+ .globl read_sctlr_el3
+ .globl write_sctlr
+ .globl write_sctlr_el1
+ .globl write_sctlr_el2
+ .globl write_sctlr_el3
+
+ .globl read_actlr
+ .globl read_actlr_el1
+ .globl read_actlr_el2
+ .globl read_actlr_el3
+ .globl write_actlr
+ .globl write_actlr_el1
+ .globl write_actlr_el2
+ .globl write_actlr_el3
+
+ .globl read_esr
+ .globl read_esr_el1
+ .globl read_esr_el2
+ .globl read_esr_el3
+ .globl write_esr
+ .globl write_esr_el1
+ .globl write_esr_el2
+ .globl write_esr_el3
+
+ .globl read_afsr0
+ .globl read_afsr0_el1
+ .globl read_afsr0_el2
+ .globl read_afsr0_el3
+ .globl write_afsr0
+ .globl write_afsr0_el1
+ .globl write_afsr0_el2
+ .globl write_afsr0_el3
+
+ .globl read_afsr1
+ .globl read_afsr1_el1
+ .globl read_afsr1_el2
+ .globl read_afsr1_el3
+ .globl write_afsr1
+ .globl write_afsr1_el1
+ .globl write_afsr1_el2
+ .globl write_afsr1_el3
+
+ .globl read_far
+ .globl read_far_el1
+ .globl read_far_el2
+ .globl read_far_el3
+ .globl write_far
+ .globl write_far_el1
+ .globl write_far_el2
+ .globl write_far_el3
+
+ .globl read_mair
+ .globl read_mair_el1
+ .globl read_mair_el2
+ .globl read_mair_el3
+ .globl write_mair
+ .globl write_mair_el1
+ .globl write_mair_el2
+ .globl write_mair_el3
+
+ .globl read_amair
+ .globl read_amair_el1
+ .globl read_amair_el2
+ .globl read_amair_el3
+ .globl write_amair
+ .globl write_amair_el1
+ .globl write_amair_el2
+ .globl write_amair_el3
+
+ .globl read_rvbar
+ .globl read_rvbar_el1
+ .globl read_rvbar_el2
+ .globl read_rvbar_el3
+
+ .globl read_rmr
+ .globl read_rmr_el1
+ .globl read_rmr_el2
+ .globl read_rmr_el3
+ .globl write_rmr
+ .globl write_rmr_el1
+ .globl write_rmr_el2
+ .globl write_rmr_el3
+
+ .globl read_tcr
+ .globl read_tcr_el1
+ .globl read_tcr_el2
+ .globl read_tcr_el3
+ .globl write_tcr
+ .globl write_tcr_el1
+ .globl write_tcr_el2
+ .globl write_tcr_el3
+
+ .globl read_cptr
+ .globl read_cptr_el2
+ .globl read_cptr_el3
+ .globl write_cptr
+ .globl write_cptr_el2
+ .globl write_cptr_el3
+
+ .globl read_ttbr0
+ .globl read_ttbr0_el1
+ .globl read_ttbr0_el2
+ .globl read_ttbr0_el3
+ .globl write_ttbr0
+ .globl write_ttbr0_el1
+ .globl write_ttbr0_el2
+ .globl write_ttbr0_el3
+
+ .globl read_ttbr1
+ .globl read_ttbr1_el1
+ .globl read_ttbr1_el2
+ .globl write_ttbr1
+ .globl write_ttbr1_el1
+ .globl write_ttbr1_el2
+
+ .globl read_cpacr
+ .globl write_cpacr
+
+ .globl read_cntfrq
+ .globl write_cntfrq
+
+ .globl read_cpuectlr
+ .globl write_cpuectlr
+
+ .globl read_cnthctl_el2
+ .globl write_cnthctl_el2
+
+ .globl read_cntfrq_el0
+ .globl write_cntfrq_el0
+
+ .globl read_scr
+ .globl write_scr
+
+ .globl read_hcr
+ .globl write_hcr
+
+ .globl read_midr
+ .globl read_mpidr
+
+ .globl read_current_el
+ .globl read_id_pfr1_el1
+ .globl read_id_aa64pfr0_el1
+
+#if SUPPORT_VFP
+ .globl enable_vfp
+ .globl read_fpexc
+ .globl write_fpexc
+#endif
+
+
+ .section .text, "ax"
+
+read_current_el:; .type read_current_el, %function
+ mrs x0, CurrentEl
+ ret
+
+
+read_id_pfr1_el1:; .type read_id_pfr1_el1, %function
+ mrs x0, id_pfr1_el1
+ ret
+
+
+read_id_aa64pfr0_el1:; .type read_id_aa64pfr0_el1, %function
+ mrs x0, id_aa64pfr0_el1
+ ret
+
+
+ /* -----------------------------------------------------
+ * VBAR accessors
+ * -----------------------------------------------------
+ */
+read_vbar:; .type read_vbar, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq read_vbar_el1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq read_vbar_el2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq read_vbar_el3
+
+
+read_vbar_el1:; .type read_vbar_el1, %function
+ mrs x0, vbar_el1
+ ret
+
+
+read_vbar_el2:; .type read_vbar_el2, %function
+ mrs x0, vbar_el2
+ ret
+
+
+read_vbar_el3:; .type read_vbar_el3, %function
+ mrs x0, vbar_el3
+ ret
+
+
+write_vbar:; .type write_vbar, %function
+ mrs x1, CurrentEl
+ cmp x1, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq write_vbar_el1
+ cmp x1, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq write_vbar_el2
+ cmp x1, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq write_vbar_el3
+
+
+write_vbar_el1:; .type write_vbar_el1, %function
+ msr vbar_el1, x0
+ isb
+ ret
+
+
+write_vbar_el2:; .type write_vbar_el2, %function
+ msr vbar_el2, x0
+ isb
+ ret
+
+
+write_vbar_el3:; .type write_vbar_el3, %function
+ msr vbar_el3, x0
+ isb
+ ret
+
+
+ /* -----------------------------------------------------
+ * AFSR0 accessors
+ * -----------------------------------------------------
+ */
+read_afsr0:; .type read_afsr0, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq read_afsr0_el1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq read_afsr0_el2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq read_afsr0_el3
+
+
+read_afsr0_el1:; .type read_afsr0_el1, %function
+ mrs x0, afsr0_el1
+ ret
+
+
+read_afsr0_el2:; .type read_afsr0_el2, %function
+ mrs x0, afsr0_el2
+ ret
+
+
+read_afsr0_el3:; .type read_afsr0_el3, %function
+ mrs x0, afsr0_el3
+ ret
+
+
+write_afsr0:; .type write_afsr0, %function
+ mrs x1, CurrentEl
+ cmp x1, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq write_afsr0_el1
+ cmp x1, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq write_afsr0_el2
+ cmp x1, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq write_afsr0_el3
+
+
+write_afsr0_el1:; .type write_afsr0_el1, %function
+ msr afsr0_el1, x0
+ isb
+ ret
+
+
+write_afsr0_el2:; .type write_afsr0_el2, %function
+ msr afsr0_el2, x0
+ isb
+ ret
+
+
+write_afsr0_el3:; .type write_afsr0_el3, %function
+ msr afsr0_el3, x0
+ isb
+ ret
+
+
+ /* -----------------------------------------------------
+ * FAR accessors
+ * -----------------------------------------------------
+ */
+read_far:; .type read_far, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq read_far_el1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq read_far_el2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq read_far_el3
+
+
+read_far_el1:; .type read_far_el1, %function
+ mrs x0, far_el1
+ ret
+
+
+read_far_el2:; .type read_far_el2, %function
+ mrs x0, far_el2
+ ret
+
+
+read_far_el3:; .type read_far_el3, %function
+ mrs x0, far_el3
+ ret
+
+
+write_far:; .type write_far, %function
+ mrs x1, CurrentEl
+ cmp x1, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq write_far_el1
+ cmp x1, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq write_far_el2
+ cmp x1, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq write_far_el3
+
+
+write_far_el1:; .type write_far_el1, %function
+ msr far_el1, x0
+ isb
+ ret
+
+
+write_far_el2:; .type write_far_el2, %function
+ msr far_el2, x0
+ isb
+ ret
+
+
+write_far_el3:; .type write_far_el3, %function
+ msr far_el3, x0
+ isb
+ ret
+
+
+ /* -----------------------------------------------------
+ * MAIR accessors
+ * -----------------------------------------------------
+ */
+read_mair:; .type read_mair, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq read_mair_el1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq read_mair_el2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq read_mair_el3
+
+
+read_mair_el1:; .type read_mair_el1, %function
+ mrs x0, mair_el1
+ ret
+
+
+read_mair_el2:; .type read_mair_el2, %function
+ mrs x0, mair_el2
+ ret
+
+
+read_mair_el3:; .type read_mair_el3, %function
+ mrs x0, mair_el3
+ ret
+
+
+write_mair:; .type write_mair, %function
+ mrs x1, CurrentEl
+ cmp x1, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq write_mair_el1
+ cmp x1, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq write_mair_el2
+ cmp x1, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq write_mair_el3
+
+
+write_mair_el1:; .type write_mair_el1, %function
+ msr mair_el1, x0
+ isb
+ ret
+
+
+write_mair_el2:; .type write_mair_el2, %function
+ msr mair_el2, x0
+ isb
+ ret
+
+
+write_mair_el3:; .type write_mair_el3, %function
+ msr mair_el3, x0
+ isb
+ ret
+
+
+ /* -----------------------------------------------------
+ * AMAIR accessors
+ * -----------------------------------------------------
+ */
+read_amair:; .type read_amair, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq read_amair_el1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq read_amair_el2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq read_amair_el3
+
+
+read_amair_el1:; .type read_amair_el1, %function
+ mrs x0, amair_el1
+ ret
+
+
+read_amair_el2:; .type read_amair_el2, %function
+ mrs x0, amair_el2
+ ret
+
+
+read_amair_el3:; .type read_amair_el3, %function
+ mrs x0, amair_el3
+ ret
+
+
+write_amair:; .type write_amair, %function
+ mrs x1, CurrentEl
+ cmp x1, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq write_amair_el1
+ cmp x1, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq write_amair_el2
+ cmp x1, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq write_amair_el3
+
+
+write_amair_el1:; .type write_amair_el1, %function
+ msr amair_el1, x0
+ isb
+ ret
+
+
+write_amair_el2:; .type write_amair_el2, %function
+ msr amair_el2, x0
+ isb
+ ret
+
+
+write_amair_el3:; .type write_amair_el3, %function
+ msr amair_el3, x0
+ isb
+ ret
+
+
+ /* -----------------------------------------------------
+ * RVBAR accessors
+ * -----------------------------------------------------
+ */
+read_rvbar:; .type read_rvbar, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq read_rvbar_el1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq read_rvbar_el2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq read_rvbar_el3
+
+
+read_rvbar_el1:; .type read_rvbar_el1, %function
+ mrs x0, rvbar_el1
+ ret
+
+
+read_rvbar_el2:; .type read_rvbar_el2, %function
+ mrs x0, rvbar_el2
+ ret
+
+
+read_rvbar_el3:; .type read_rvbar_el3, %function
+ mrs x0, rvbar_el3
+ ret
+
+
+ /* -----------------------------------------------------
+ * RMR accessors
+ * -----------------------------------------------------
+ */
+read_rmr:; .type read_rmr, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq read_rmr_el1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq read_rmr_el2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq read_rmr_el3
+
+
+read_rmr_el1:; .type read_rmr_el1, %function
+ mrs x0, rmr_el1
+ ret
+
+
+read_rmr_el2:; .type read_rmr_el2, %function
+ mrs x0, rmr_el2
+ ret
+
+
+read_rmr_el3:; .type read_rmr_el3, %function
+ mrs x0, rmr_el3
+ ret
+
+
+write_rmr:; .type write_rmr, %function
+ mrs x1, CurrentEl
+ cmp x1, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq write_rmr_el1
+ cmp x1, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq write_rmr_el2
+ cmp x1, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq write_rmr_el3
+
+
+write_rmr_el1:; .type write_rmr_el1, %function
+ msr rmr_el1, x0
+ isb
+ ret
+
+
+write_rmr_el2:; .type write_rmr_el2, %function
+ msr rmr_el2, x0
+ isb
+ ret
+
+
+write_rmr_el3:; .type write_rmr_el3, %function
+ msr rmr_el3, x0
+ isb
+ ret
+
+
+read_afsr1:; .type read_afsr1, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq read_afsr1_el1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq read_afsr1_el2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq read_afsr1_el3
+
+
+ /* -----------------------------------------------------
+ * AFSR1 accessors
+ * -----------------------------------------------------
+ */
+read_afsr1_el1:; .type read_afsr1_el1, %function
+ mrs x0, afsr1_el1
+ ret
+
+
+read_afsr1_el2:; .type read_afsr1_el2, %function
+ mrs x0, afsr1_el2
+ ret
+
+
+read_afsr1_el3:; .type read_afsr1_el3, %function
+ mrs x0, afsr1_el3
+ ret
+
+
+write_afsr1:; .type write_afsr1, %function
+ mrs x1, CurrentEl
+ cmp x1, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq write_afsr1_el1
+ cmp x1, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq write_afsr1_el2
+ cmp x1, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq write_afsr1_el3
+
+
+write_afsr1_el1:; .type write_afsr1_el1, %function
+ msr afsr1_el1, x0
+ isb
+ ret
+
+
+write_afsr1_el2:; .type write_afsr1_el2, %function
+ msr afsr1_el2, x0
+ isb
+ ret
+
+
+write_afsr1_el3:; .type write_afsr1_el3, %function
+ msr afsr1_el3, x0
+ isb
+ ret
+
+
+ /* -----------------------------------------------------
+ * SCTLR accessors
+ * -----------------------------------------------------
+ */
+read_sctlr:; .type read_sctlr, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq read_sctlr_el1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq read_sctlr_el2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq read_sctlr_el3
+
+
+read_sctlr_el1:; .type read_sctlr_el1, %function
+ mrs x0, sctlr_el1
+ ret
+
+
+read_sctlr_el2:; .type read_sctlr_el2, %function
+ mrs x0, sctlr_el2
+ ret
+
+
+read_sctlr_el3:; .type read_sctlr_el3, %function
+ mrs x0, sctlr_el3
+ ret
+
+
+write_sctlr:; .type write_sctlr, %function
+ mrs x1, CurrentEl
+ cmp x1, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq write_sctlr_el1
+ cmp x1, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq write_sctlr_el2
+ cmp x1, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq write_sctlr_el3
+
+
+write_sctlr_el1:; .type write_sctlr_el1, %function
+ msr sctlr_el1, x0
+ dsb sy
+ isb
+ ret
+
+
+write_sctlr_el2:; .type write_sctlr_el2, %function
+ msr sctlr_el2, x0
+ dsb sy
+ isb
+ ret
+
+
+write_sctlr_el3:; .type write_sctlr_el3, %function
+ msr sctlr_el3, x0
+ dsb sy
+ isb
+ ret
+
+
+ /* -----------------------------------------------------
+ * ACTLR accessors
+ * -----------------------------------------------------
+ */
+read_actlr:; .type read_actlr, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq read_actlr_el1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq read_actlr_el2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq read_actlr_el3
+
+
+read_actlr_el1:; .type read_actlr_el1, %function
+ mrs x0, actlr_el1
+ ret
+
+
+read_actlr_el2:; .type read_actlr_el2, %function
+ mrs x0, actlr_el2
+ ret
+
+
+read_actlr_el3:; .type read_actlr_el3, %function
+ mrs x0, actlr_el3
+ ret
+
+
+write_actlr:; .type write_actlr, %function
+ mrs x1, CurrentEl
+ cmp x1, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq write_actlr_el1
+ cmp x1, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq write_actlr_el2
+ cmp x1, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq write_actlr_el3
+
+
+write_actlr_el1:; .type write_actlr_el1, %function
+ msr actlr_el1, x0
+ dsb sy
+ isb
+ ret
+
+
+write_actlr_el2:; .type write_actlr_el2, %function
+ msr actlr_el2, x0
+ dsb sy
+ isb
+ ret
+
+
+write_actlr_el3:; .type write_actlr_el3, %function
+ msr actlr_el3, x0
+ dsb sy
+ isb
+ ret
+
+
+ /* -----------------------------------------------------
+ * ESR accessors
+ * -----------------------------------------------------
+ */
+read_esr:; .type read_esr, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq read_esr_el1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq read_esr_el2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq read_esr_el3
+
+
+read_esr_el1:; .type read_esr_el1, %function
+ mrs x0, esr_el1
+ ret
+
+
+read_esr_el2:; .type read_esr_el2, %function
+ mrs x0, esr_el2
+ ret
+
+
+read_esr_el3:; .type read_esr_el3, %function
+ mrs x0, esr_el3
+ ret
+
+
+write_esr:; .type write_esr, %function
+ mrs x1, CurrentEl
+ cmp x1, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq write_esr_el1
+ cmp x1, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq write_esr_el2
+ cmp x1, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq write_esr_el3
+
+
+write_esr_el1:; .type write_esr_el1, %function
+ msr esr_el1, x0
+ dsb sy
+ isb
+ ret
+
+
+write_esr_el2:; .type write_esr_el2, %function
+ msr esr_el2, x0
+ dsb sy
+ isb
+ ret
+
+
+write_esr_el3:; .type write_esr_el3, %function
+ msr esr_el3, x0
+ dsb sy
+ isb
+ ret
+
+
+ /* -----------------------------------------------------
+ * TCR accessors
+ * -----------------------------------------------------
+ */
+read_tcr:; .type read_tcr, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq read_tcr_el1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq read_tcr_el2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq read_tcr_el3
+
+
+read_tcr_el1:; .type read_tcr_el1, %function
+ mrs x0, tcr_el1
+ ret
+
+
+read_tcr_el2:; .type read_tcr_el2, %function
+ mrs x0, tcr_el2
+ ret
+
+
+read_tcr_el3:; .type read_tcr_el3, %function
+ mrs x0, tcr_el3
+ ret
+
+
+write_tcr:; .type write_tcr, %function
+ mrs x1, CurrentEl
+ cmp x1, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq write_tcr_el1
+ cmp x1, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq write_tcr_el2
+ cmp x1, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq write_tcr_el3
+
+
+write_tcr_el1:; .type write_tcr_el1, %function
+ msr tcr_el1, x0
+ dsb sy
+ isb
+ ret
+
+
+write_tcr_el2:; .type write_tcr_el2, %function
+ msr tcr_el2, x0
+ dsb sy
+ isb
+ ret
+
+
+write_tcr_el3:; .type write_tcr_el3, %function
+ msr tcr_el3, x0
+ dsb sy
+ isb
+ ret
+
+
+ /* -----------------------------------------------------
+ * CPTR accessors
+ * -----------------------------------------------------
+ */
+read_cptr:; .type read_cptr, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq read_cptr_el1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq read_cptr_el2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq read_cptr_el3
+
+
+read_cptr_el1:; .type read_cptr_el1, %function
+ b read_cptr_el1
+ ret
+
+
+read_cptr_el2:; .type read_cptr_el2, %function
+ mrs x0, cptr_el2
+ ret
+
+
+read_cptr_el3:; .type read_cptr_el3, %function
+ mrs x0, cptr_el3
+ ret
+
+
+write_cptr:; .type write_cptr, %function
+ mrs x1, CurrentEl
+ cmp x1, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq write_cptr_el1
+ cmp x1, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq write_cptr_el2
+ cmp x1, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq write_cptr_el3
+
+
+write_cptr_el1:; .type write_cptr_el1, %function
+ b write_cptr_el1
+
+
+write_cptr_el2:; .type write_cptr_el2, %function
+ msr cptr_el2, x0
+ dsb sy
+ isb
+ ret
+
+
+write_cptr_el3:; .type write_cptr_el3, %function
+ msr cptr_el3, x0
+ dsb sy
+ isb
+ ret
+
+
+ /* -----------------------------------------------------
+ * TTBR0 accessors
+ * -----------------------------------------------------
+ */
+read_ttbr0:; .type read_ttbr0, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq read_ttbr0_el1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq read_ttbr0_el2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq read_ttbr0_el3
+
+
+read_ttbr0_el1:; .type read_ttbr0_el1, %function
+ mrs x0, ttbr0_el1
+ ret
+
+
+read_ttbr0_el2:; .type read_ttbr0_el2, %function
+ mrs x0, ttbr0_el2
+ ret
+
+
+read_ttbr0_el3:; .type read_ttbr0_el3, %function
+ mrs x0, ttbr0_el3
+ ret
+
+
+write_ttbr0:; .type write_ttbr0, %function
+ mrs x1, CurrentEl
+ cmp x1, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq write_ttbr0_el1
+ cmp x1, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq write_ttbr0_el2
+ cmp x1, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq write_ttbr0_el3
+
+
+write_ttbr0_el1:; .type write_ttbr0_el1, %function
+ msr ttbr0_el1, x0
+ isb
+ ret
+
+
+write_ttbr0_el2:; .type write_ttbr0_el2, %function
+ msr ttbr0_el2, x0
+ isb
+ ret
+
+
+write_ttbr0_el3:; .type write_ttbr0_el3, %function
+ msr ttbr0_el3, x0
+ isb
+ ret
+
+
+ /* -----------------------------------------------------
+ * TTBR1 accessors
+ * -----------------------------------------------------
+ */
+read_ttbr1:; .type read_ttbr1, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq read_ttbr1_el1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq read_ttbr1_el2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq read_ttbr1_el3
+
+
+read_ttbr1_el1:; .type read_ttbr1_el1, %function
+ mrs x0, ttbr1_el1
+ ret
+
+
+read_ttbr1_el2:; .type read_ttbr1_el2, %function
+ b read_ttbr1_el2
+
+
+read_ttbr1_el3:; .type read_ttbr1_el3, %function
+ b read_ttbr1_el3
+
+
+write_ttbr1:; .type write_ttbr1, %function
+ mrs x1, CurrentEl
+ cmp x1, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq write_ttbr1_el1
+ cmp x1, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq write_ttbr1_el2
+ cmp x1, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq write_ttbr1_el3
+
+
+write_ttbr1_el1:; .type write_ttbr1_el1, %function
+ msr ttbr1_el1, x0
+ isb
+ ret
+
+
+write_ttbr1_el2:; .type write_ttbr1_el2, %function
+ b write_ttbr1_el2
+
+
+write_ttbr1_el3:; .type write_ttbr1_el3, %function
+ b write_ttbr1_el3
+
+
+read_hcr:; .type read_hcr, %function
+ mrs x0, hcr_el2
+ ret
+
+
+write_hcr:; .type write_hcr, %function
+ msr hcr_el2, x0
+ dsb sy
+ isb
+ ret
+
+
+read_cpacr:; .type read_cpacr, %function
+ mrs x0, cpacr_el1
+ ret
+
+
+write_cpacr:; .type write_cpacr, %function
+ msr cpacr_el1, x0
+ ret
+
+
+read_cntfrq_el0:; .type read_cntfrq_el0, %function
+ mrs x0, cntfrq_el0
+ ret
+
+
+write_cntfrq_el0:; .type write_cntfrq_el0, %function
+ msr cntfrq_el0, x0
+ ret
+
+
+read_cpuectlr:; .type read_cpuectlr, %function
+ mrs x0, CPUECTLR_EL1
+ ret
+
+
+write_cpuectlr:; .type write_cpuectlr, %function
+ msr CPUECTLR_EL1, x0
+ dsb sy
+ isb
+ ret
+
+
+read_cnthctl_el2:; .type read_cnthctl_el2, %function
+ mrs x0, cnthctl_el2
+ ret
+
+
+write_cnthctl_el2:; .type write_cnthctl_el2, %function
+ msr cnthctl_el2, x0
+ ret
+
+
+read_cntfrq:; .type read_cntfrq, %function
+ mrs x0, cntfrq_el0
+ ret
+
+
+write_cntfrq:; .type write_cntfrq, %function
+ msr cntfrq_el0, x0
+ ret
+
+
+write_scr:; .type write_scr, %function
+ msr scr_el3, x0
+ dsb sy
+ isb
+ ret
+
+
+read_scr:; .type read_scr, %function
+ mrs x0, scr_el3
+ ret
+
+
+read_midr:; .type read_midr, %function
+ mrs x0, midr_el1
+ ret
+
+
+read_mpidr:; .type read_mpidr, %function
+ mrs x0, mpidr_el1
+ ret
+
+
+#if SUPPORT_VFP
+enable_vfp:; .type enable_vfp, %function
+ mrs x0, cpacr_el1
+ orr x0, x0, #CPACR_VFP_BITS
+ msr cpacr_el1, x0
+ mrs x0, cptr_el3
+ mov x1, #AARCH64_CPTR_TFP
+ bic x0, x0, x1
+ msr cptr_el3, x0
+ ret
+
+
+ // int read_fpexc(void)
+read_fpexc:; .type read_fpexc, %function
+ b read_fpexc
+ ret
+
+
+ // void write_fpexc(int fpexc)
+write_fpexc:; .type write_fpexc, %function
+ b write_fpexc
+ ret
+
+#endif
diff --git a/lib/arch/aarch64/tlb_helpers.S b/lib/arch/aarch64/tlb_helpers.S
new file mode 100644
index 0000000..8377f2c
--- /dev/null
+++ b/lib/arch/aarch64/tlb_helpers.S
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2013, ARM Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch_helpers.h>
+
+ .globl tlbiall
+ .globl tlbiallis
+ .globl tlbialle1
+ .globl tlbialle1is
+ .globl tlbialle2
+ .globl tlbialle2is
+ .globl tlbialle3
+ .globl tlbialle3is
+ .globl tlbivmalle1
+
+
+ .section .text, "ax"
+
+tlbiall:; .type tlbiall, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq tlbialle1
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq tlbialle2
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq tlbialle3
+
+
+tlbiallis:; .type tlbiallis, %function
+ mrs x0, CurrentEl
+ cmp x0, #(MODE_EL1 << MODE_EL_SHIFT)
+ b.eq tlbialle1is
+ cmp x0, #(MODE_EL2 << MODE_EL_SHIFT)
+ b.eq tlbialle2is
+ cmp x0, #(MODE_EL3 << MODE_EL_SHIFT)
+ b.eq tlbialle3is
+
+
+tlbialle1:; .type tlbialle1, %function
+ tlbi alle1
+ dsb sy
+ isb
+ ret
+
+
+tlbialle1is:; .type tlbialle1is, %function
+ tlbi alle1is
+ dsb sy
+ isb
+ ret
+
+
+tlbialle2:; .type tlbialle2, %function
+ tlbi alle2
+ dsb sy
+ isb
+ ret
+
+
+tlbialle2is:; .type tlbialle2is, %function
+ tlbi alle2is
+ dsb sy
+ isb
+ ret
+
+
+tlbialle3:; .type tlbialle3, %function
+ tlbi alle3
+ dsb sy
+ isb
+ ret
+
+
+tlbialle3is:; .type tlbialle3is, %function
+ tlbi alle3is
+ dsb sy
+ isb
+ ret
+
+tlbivmalle1:; .type tlbivmalle1, %function
+ tlbi vmalle1
+ dsb sy
+ isb
+ ret
diff --git a/lib/mmio.c b/lib/mmio.c
new file mode 100644
index 0000000..bf35e36
--- /dev/null
+++ b/lib/mmio.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013, ARM Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+
+void mmio_write_32(uintptr_t addr, uint32_t value)
+{
+ *(volatile uint32_t*)addr = value;
+}
+
+unsigned mmio_read_32(uintptr_t addr)
+{
+ return *(volatile uint32_t*)addr;
+}
diff --git a/lib/non-semihosting/ctype.h b/lib/non-semihosting/ctype.h
new file mode 100644
index 0000000..88e7da1
--- /dev/null
+++ b/lib/non-semihosting/ctype.h
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 1982, 1988, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Portions copyright (c) 2009-2013, ARM Ltd. All rights reserved.
+ * ---------------------------------------------------------------
+ * File: include/lib/ctype.h
+ */
+
+#ifndef _SYS_CTYPE_H_
+#define _SYS_CTYPE_H_
+
+#define isspace(c) ((c) == ' ' || ((c) >= '\t' && (c) <= '\r'))
+#define isascii(c) (((c) & ~0x7f) == 0)
+#define isupper(c) ((c) >= 'A' && (c) <= 'Z')
+#define islower(c) ((c) >= 'a' && (c) <= 'z')
+#define isalpha(c) (isupper(c) || islower(c))
+#define isdigit(c) ((c) >= '0' && (c) <= '9')
+#define isxdigit(c) (isdigit(c) \
+ || ((c) >= 'A' && (c) <= 'F') \
+ || ((c) >= 'a' && (c) <= 'f'))
+#define isprint(c) ((c) >= ' ' && (c) <= '~')
+
+#define toupper(c) ((c) - 0x20 * (((c) >= 'a') && ((c) <= 'z')))
+#define tolower(c) ((c) + 0x20 * (((c) >= 'A') && ((c) <= 'Z')))
+
+#endif /* !_SYS_CTYPE_H_ */
diff --git a/lib/non-semihosting/mem.c b/lib/non-semihosting/mem.c
new file mode 100644
index 0000000..bca9ab5
--- /dev/null
+++ b/lib/non-semihosting/mem.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2013, ARM Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stddef.h> /* size_t */
+
+/*
+ * Fill @count bytes of memory pointed to by @dst with @val
+ */
+void *memset(void *dst, int val, size_t count)
+{
+ char *ptr = dst;
+
+ while (count--)
+ *ptr++ = val;
+
+ return dst;
+}
+
+/*
+ * Compare @len bytes of @s1 and @s2
+ */
+int memcmp(const void *s1, const void *s2, size_t len)
+{
+ const char *s = s1;
+ const char *d = s2;
+ char dc;
+ char sc;
+
+ while (len--) {
+ sc = *s++;
+ dc = *d++;
+ if (sc - dc)
+ return (sc - dc);
+ }
+
+ return 0;
+}
+
+
+/*
+ * Move @len bytes from @src to @dst
+ */
+void *memmove(void *dst, const void *src, size_t len)
+{
+ const char *s = src;
+ char *d = dst;
+
+ while (len--)
+ *d++ = *s++;
+ return d;
+}
+
+/*
+ * Copy @len bytes from @src to @dst
+ */
+void *memcpy(void *dst, const void *src, size_t len)
+{
+ return memmove(dst, src, len);
+}
+
+
+/*
+ * Scan @len bytes of @src for value @c
+ */
+void *memchr(const void *src, int c, size_t len)
+{
+ const char *s = src;
+
+ while (len--) {
+ if (*s == c)
+ return (void *) s;
+ s++;
+ }
+
+ return NULL;
+}
diff --git a/lib/non-semihosting/std.c b/lib/non-semihosting/std.c
new file mode 100644
index 0000000..ea91d5f
--- /dev/null
+++ b/lib/non-semihosting/std.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2013, ARM Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <console.h>
+
+#if defined (__GNUC__)
+
+#include <stdio.h>
+#include <stddef.h> /* size_t */
+#include <stdarg.h> /* va_list */
+
+// Code from VTB.
+#include "mem.c"
+
+// Make mem functions that will operate on DEV mem. "memset_io"?
+
+
+//Code from VTB
+#include "strlen.c"
+
+int puts(const char *s)
+{
+ int count = 0;
+ while(*s)
+ {
+ if (console_putc(*s++)) {
+ count++;
+ } else {
+ count = EOF; // -1 in stdio.h
+ break;
+ }
+ }
+ return count;
+}
+
+// From VTB
+#include "ctype.h"
+#include "subr_prf.c"
+
+ // Choose max of 128 chars for now.
+#define PRINT_BUFFER_SIZE 128
+int printf(const char *fmt, ...)
+{
+ va_list args;
+ va_start(args, fmt);
+ char buf[PRINT_BUFFER_SIZE];
+ vsnprintf(buf, sizeof(buf) - 1, fmt, args);
+ buf[PRINT_BUFFER_SIZE - 1] = '\0';
+ return puts(buf);
+}
+
+
+// I just made this up. Probably make it beter.
+void __assert_func (const char *file, int l, const char *func, const char *error)
+{
+ printf("ASSERT: %s <%d> : %s\n\r", func, l, error);
+ while(1);
+}
+
+extern void __assert_fail (const char *assertion, const char *file,
+ unsigned int line, const char *function)
+{
+ printf("ASSERT: %s <%d> : %s\n\r", function, line, assertion);
+ while(1);
+}
+
+
+// I just made this up. Probably make it beter.
+void abort (void)
+{
+ printf("ABORT\n\r");
+ while(1);
+}
+
+
+#else
+#error "No standard library binding defined."
+#endif
diff --git a/lib/non-semihosting/strcmp.c b/lib/non-semihosting/strcmp.c
new file mode 100644
index 0000000..e5921ba
--- /dev/null
+++ b/lib/non-semihosting/strcmp.c
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions copyright (c) 2009-2013, ARM Ltd. All rights reserved.
+ * ---------------------------------------------------------------
+ * File: lib/strcmp.c
+ */
+
+/*
+ * Compare strings.
+ */
+int
+strcmp(const char *s1, const char *s2)
+{
+ while (*s1 == *s2++)
+ if (*s1++ == '\0')
+ return (0);
+ return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1));
+}
diff --git a/lib/non-semihosting/string.c b/lib/non-semihosting/string.c
new file mode 100644
index 0000000..5bb01a1
--- /dev/null
+++ b/lib/non-semihosting/string.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, ARM Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "ctype.h"
+
+/* Return pointer to the first non-space character */
+const char *skip_spaces(const char *str)
+{
+ while (isspace(*str))
+ ++str;
+ return str;
+}
diff --git a/lib/non-semihosting/strlen.c b/lib/non-semihosting/strlen.c
new file mode 100644
index 0000000..5c1e7a6
--- /dev/null
+++ b/lib/non-semihosting/strlen.c
@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions copyright (c) 2009-2013, ARM Ltd. All rights reserved.
+ * ---------------------------------------------------------------
+ * File: lib/strlen.c
+ */
+
+#include <stddef.h>
+
+size_t
+strlen(str)
+ const char *str;
+{
+ register const char *s;
+
+ for (s = str; *s; ++s);
+ return(s - str);
+}
diff --git a/lib/non-semihosting/strncmp.c b/lib/non-semihosting/strncmp.c
new file mode 100644
index 0000000..984b7a0
--- /dev/null
+++ b/lib/non-semihosting/strncmp.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions copyright (c) 2009-2013, ARM Ltd. All rights reserved.
+ * ---------------------------------------------------------------
+ * File: lib/strncmp.c
+ */
+
+#include "types.h"
+
+int
+strncmp(const char *s1, const char *s2, size_t n)
+{
+
+ if (n == 0)
+ return (0);
+ do {
+ if (*s1 != *s2++)
+ return (*(const unsigned char *)s1 -
+ *(const unsigned char *)(s2 - 1));
+ if (*s1++ == '\0')
+ break;
+ } while (--n != 0);
+ return (0);
+}
diff --git a/lib/non-semihosting/strncpy.c b/lib/non-semihosting/strncpy.c
new file mode 100644
index 0000000..56a8a69
--- /dev/null
+++ b/lib/non-semihosting/strncpy.c
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions copyright (c) 2009-2013, ARM Ltd. All rights reserved.
+ * ---------------------------------------------------------------
+ * File: lib/strncpy.c
+ */
+
+#include "types.h"
+
+/*
+ * Copy src to dst, truncating or null-padding to always copy n bytes.
+ * Return dst.
+ */
+char *
+strncpy(char *dst, const char *src, size_t n)
+{
+ if (n != 0) {
+ char *d = dst;
+ const char *s = src;
+
+ do {
+ if ((*d++ = *s++) == '\0') {
+ /* NUL pad the remaining n-1 bytes */
+ while (--n != 0)
+ *d++ = '\0';
+ break;
+ }
+ } while (--n != 0);
+ }
+ return (dst);
+}
diff --git a/lib/non-semihosting/strsep.c b/lib/non-semihosting/strsep.c
new file mode 100644
index 0000000..1f80af4
--- /dev/null
+++ b/lib/non-semihosting/strsep.c
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions copyright (c) 2009-2013, ARM Ltd. All rights reserved.
+ * ---------------------------------------------------------------
+ * File: lib/strsep.c
+ */
+
+#include "types.h"
+
+/*
+ * Get next token from string *stringp, where tokens are possibly-empty
+ * strings separated by characters from delim.
+ *
+ * Writes NULs into the string at *stringp to end tokens.
+ * delim need not remain constant from call to call.
+ * On return, *stringp points past the last NUL written (if there might
+ * be further tokens), or is NULL (if there are definitely no more tokens).
+ *
+ * If *stringp is NULL, strsep returns NULL.
+ */
+char *
+strsep(char **stringp, const char *delim)
+{
+ char *s;
+ const char *spanp;
+ int c, sc;
+ char *tok;
+
+ if ((s = *stringp) == NULL)
+ return (NULL);
+ for (tok = s;;) {
+ c = *s++;
+ spanp = delim;
+ do {
+ if ((sc = *spanp++) == c) {
+ if (c == 0)
+ s = NULL;
+ else
+ s[-1] = 0;
+ *stringp = s;
+ return (tok);
+ }
+ } while (sc != 0);
+ }
+ /* NOTREACHED */
+}
diff --git a/lib/non-semihosting/strtol.c b/lib/non-semihosting/strtol.c
new file mode 100644
index 0000000..4a5a404
--- /dev/null
+++ b/lib/non-semihosting/strtol.c
@@ -0,0 +1,146 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * From: @(#)strtol.c 8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * Portions copyright (c) 2009-2013, ARM Ltd. All rights reserved.
+ * ---------------------------------------------------------------
+ * File: lib/strtol.c
+ */
+
+#include "types.h"
+#include "ctype.h"
+#include "limits.h"
+
+/*
+ * Convert a string to a long integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+static long
+bsd_strtol(nptr, endptr, base)
+ const char *nptr;
+ char **endptr;
+ int base;
+{
+ const char *s = nptr;
+ unsigned long acc;
+ unsigned char c;
+ unsigned long cutoff;
+ int neg = 0, any, cutlim;
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else if (c == '+')
+ c = *s++;
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for longs is
+ * [-2147483648..2147483647] and the input base is 10,
+ * cutoff will be set to 214748364 and cutlim to either
+ * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+ * a value > 214748364, or equal but the next digit is > 7 (or 8),
+ * the number is too big, and we will return a range error.
+ *
+ * Set any if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
+ cutlim = cutoff % (unsigned long)base;
+ cutoff /= (unsigned long)base;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (!isascii(c))
+ break;
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = neg ? LONG_MIN : LONG_MAX;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != 0)
+ *((const char **)endptr) = any ? s - 1 : nptr;
+ return (acc);
+}
+
+int strict_strtol(const char *str, unsigned int base, long *result)
+{
+ if (*str == '-')
+ *result = 0 - bsd_strtol(str + 1, NULL, base);
+ else
+ *result = bsd_strtol(str, NULL, base);
+ return 0;
+}
+
+int strict_strtoul(const char *str, unsigned int base, unsigned long *result)
+{
+ *result = bsd_strtol(str, NULL, base);
+ return 0;
+}
diff --git a/lib/non-semihosting/strtoull.c b/lib/non-semihosting/strtoull.c
new file mode 100644
index 0000000..e46ef4c
--- /dev/null
+++ b/lib/non-semihosting/strtoull.c
@@ -0,0 +1,117 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions copyright (c) 2009-2013, ARM Ltd. All rights reserved.
+ * ---------------------------------------------------------------
+ * File: lib/strtoull.c
+ */
+
+#include "types.h"
+#include "ctype.h"
+#include "limits.h"
+
+/*
+ * Convert a string to an unsigned long long integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+static unsigned long long
+bsd_strtoull(const char *nptr, char **endptr, int base)
+{
+ const char *s;
+ unsigned long long acc;
+ char c;
+ unsigned long long cutoff;
+ int neg, any, cutlim;
+
+ /*
+ * See strtoq for comments as to the logic used.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace((unsigned char)c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X') &&
+ ((s[1] >= '0' && s[1] <= '9') ||
+ (s[1] >= 'A' && s[1] <= 'F') ||
+ (s[1] >= 'a' && s[1] <= 'f'))) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ acc = any = 0;
+
+ cutoff = ULLONG_MAX / base;
+ cutlim = ULLONG_MAX % base;
+ for ( ; ; c = *s++) {
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'Z')
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= base;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = ULLONG_MAX;
+ } else if (neg)
+ acc = -acc;
+ if (endptr != NULL)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
+
+int strict_strtoull(const char *str, unsigned int base, long long *result)
+{
+ *result = bsd_strtoull(str, NULL, base);
+ return 0;
+}
diff --git a/lib/non-semihosting/subr_prf.c b/lib/non-semihosting/subr_prf.c
new file mode 100644
index 0000000..6e2a1ac
--- /dev/null
+++ b/lib/non-semihosting/subr_prf.c
@@ -0,0 +1,557 @@
+/*-
+ * Copyright (c) 1986, 1988, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
+ */
+
+/*
+ * Portions copyright (c) 2009-2013, ARM Ltd. All rights reserved.
+ * ---------------------------------------------------------------
+ * File: lib/subr_prf.c
+ */
+
+/*
+#include "types.h"
+#include "varargs.h"
+#include "ctype.h"
+#include "string.h"
+*/
+#include <stddef.h>
+#include <sys/types.h> /* For ssize_t */
+#include <stdint.h>
+#include <string.h>
+
+#include "ctype.h"
+
+typedef uint64_t uintmax_t;
+typedef int64_t intmax_t;
+typedef unsigned char u_char;
+typedef unsigned int u_int;
+typedef int64_t quad_t;
+typedef uint64_t u_quad_t;
+typedef unsigned long u_long;
+typedef unsigned short u_short;
+
+static inline int imax(int a, int b) { return (a > b ? a : b); }
+
+/*
+ * Note that stdarg.h and the ANSI style va_start macro is used for both
+ * ANSI and traditional C compilers.
+ */
+
+#define TOCONS 0x01
+#define TOTTY 0x02
+#define TOLOG 0x04
+
+/* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */
+#define MAXNBUF (sizeof(intmax_t) * 8 + 1)
+
+struct putchar_arg {
+ int flags;
+ int pri;
+ struct tty *tty;
+ char *p_bufr;
+ size_t n_bufr;
+ char *p_next;
+ size_t remain;
+};
+
+struct snprintf_arg {
+ char *str;
+ size_t remain;
+};
+
+extern int log_open;
+
+static char *ksprintn(char *nbuf, uintmax_t num, int base, int *len, int upper);
+static void snprintf_func(int ch, void *arg);
+static int kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap);
+
+int vsnprintf(char *str, size_t size, const char *format, va_list ap);
+
+static char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+#define hex2ascii(hex) (hex2ascii_data[hex])
+
+/*
+ * Scaled down version of sprintf(3).
+ */
+int
+sprintf(char *buf, const char *cfmt, ...)
+{
+ int retval;
+ va_list ap;
+
+ va_start(ap, cfmt);
+ retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
+ buf[retval] = '\0';
+ va_end(ap);
+ return (retval);
+}
+
+/*
+ * Scaled down version of vsprintf(3).
+ */
+int
+vsprintf(char *buf, const char *cfmt, va_list ap)
+{
+ int retval;
+
+ retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
+ buf[retval] = '\0';
+ return (retval);
+}
+
+/*
+ * Scaled down version of snprintf(3).
+ */
+int
+snprintf(char *str, size_t size, const char *format, ...)
+{
+ int retval;
+ va_list ap;
+
+ va_start(ap, format);
+ retval = vsnprintf(str, size, format, ap);
+ va_end(ap);
+ return(retval);
+}
+
+/*
+ * Scaled down version of vsnprintf(3).
+ */
+int
+vsnprintf(char *str, size_t size, const char *format, va_list ap)
+{
+ struct snprintf_arg info;
+ int retval;
+
+ info.str = str;
+ info.remain = size;
+ retval = kvprintf(format, snprintf_func, &info, 10, ap);
+ if (info.remain >= 1)
+ *info.str++ = '\0';
+ return (retval);
+}
+
+static void
+snprintf_func(int ch, void *arg)
+{
+ struct snprintf_arg *const info = arg;
+
+ if (info->remain >= 2) {
+ *info->str++ = ch;
+ info->remain--;
+ }
+}
+
+
+/*
+ * Kernel version which takes radix argument vsnprintf(3).
+ */
+int
+vsnrprintf(char *str, size_t size, int radix, const char *format, va_list ap)
+{
+ struct snprintf_arg info;
+ int retval;
+
+ info.str = str;
+ info.remain = size;
+ retval = kvprintf(format, snprintf_func, &info, radix, ap);
+ if (info.remain >= 1)
+ *info.str++ = '\0';
+ return (retval);
+}
+
+
+/*
+ * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
+ * order; return an optional length and a pointer to the last character
+ * written in the buffer (i.e., the first character of the string).
+ * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
+ */
+static char *
+ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
+{
+ char *p, c;
+
+ p = nbuf;
+ *p = '\0';
+ do {
+ c = hex2ascii(num % base);
+ *++p = upper ? toupper(c) : c;
+ } while (num /= base);
+ if (lenp)
+ *lenp = p - nbuf;
+ return (p);
+}
+
+/*
+ * Scaled down version of printf(3).
+ *
+ * Two additional formats:
+ *
+ * The format %b is supported to decode error registers.
+ * Its usage is:
+ *
+ * printf("reg=%b\n", regval, "<base><arg>*");
+ *
+ * where <base> is the output base expressed as a control character, e.g.
+ * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
+ * the first of which gives the bit number to be inspected (origin 1), and
+ * the next characters (up to a control character, i.e. a character <= 32),
+ * give the name of the register. Thus:
+ *
+ * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
+ *
+ * would produce output:
+ *
+ * reg=3<BITTWO,BITONE>
+ *
+ * XXX: %D -- Hexdump, takes pointer and separator string:
+ * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
+ * ("%*D", len, ptr, " " -> XX XX XX XX ...
+ */
+int
+kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap)
+{
+#define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; }
+ char nbuf[MAXNBUF];
+ char *d;
+ const char *p, *percent, *q;
+ u_char *up;
+ int ch, n;
+ uintmax_t num;
+ int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
+ int cflag, hflag, jflag, tflag, zflag;
+ int dwidth, upper;
+ char padc;
+ int stop = 0, retval = 0;
+
+ num = 0;
+ if (!func)
+ d = (char *) arg;
+ else
+ d = NULL;
+
+ if (fmt == NULL)
+ fmt = "(fmt null)\n";
+
+ if (radix < 2 || radix > 36)
+ radix = 10;
+
+ for (;;) {
+ padc = ' ';
+ width = 0;
+ while ((ch = (u_char)*fmt++) != '%' || stop) {
+ if (ch == '\0')
+ return (retval);
+ PCHAR(ch);
+ }
+ percent = fmt - 1;
+ qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
+ sign = 0; dot = 0; dwidth = 0; upper = 0;
+ cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
+reswitch: switch (ch = (u_char)*fmt++) {
+ case '.':
+ dot = 1;
+ goto reswitch;
+ case '#':
+ sharpflag = 1;
+ goto reswitch;
+ case '+':
+ sign = 1;
+ goto reswitch;
+ case '-':
+ ladjust = 1;
+ goto reswitch;
+ case '%':
+ PCHAR(ch);
+ break;
+ case '*':
+ if (!dot) {
+ width = va_arg(ap, int);
+ if (width < 0) {
+ ladjust = !ladjust;
+ width = -width;
+ }
+ } else {
+ dwidth = va_arg(ap, int);
+ }
+ goto reswitch;
+ case '0':
+ if (!dot) {
+ padc = '0';
+ goto reswitch;
+ }
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ for (n = 0;; ++fmt) {
+ n = n * 10 + ch - '0';
+ ch = *fmt;
+ if (ch < '0' || ch > '9')
+ break;
+ }
+ if (dot)
+ dwidth = n;
+ else
+ width = n;
+ goto reswitch;
+ case 'b':
+ num = (u_int)va_arg(ap, int);
+ p = va_arg(ap, char *);
+ for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
+ PCHAR(*q--);
+
+ if (num == 0)
+ break;
+
+ for (tmp = 0; *p;) {
+ n = *p++;
+ if (num & (1 << (n - 1))) {
+ PCHAR(tmp ? ',' : '<');
+ for (; (n = *p) > ' '; ++p)
+ PCHAR(n);
+ tmp = 1;
+ } else
+ for (; *p > ' '; ++p)
+ continue;
+ }
+ if (tmp)
+ PCHAR('>');
+ break;
+ case 'c':
+ PCHAR(va_arg(ap, int));
+ break;
+ case 'D':
+ up = va_arg(ap, u_char *);
+ p = va_arg(ap, char *);
+ if (!width)
+ width = 16;
+ while(width--) {
+ PCHAR(hex2ascii(*up >> 4));
+ PCHAR(hex2ascii(*up & 0x0f));
+ up++;
+ if (width)
+ for (q=p;*q;q++)
+ PCHAR(*q);
+ }
+ break;
+ case 'd':
+ case 'i':
+ base = 10;
+ sign = 1;
+ goto handle_sign;
+ case 'h':
+ if (hflag) {
+ hflag = 0;
+ cflag = 1;
+ } else
+ hflag = 1;
+ goto reswitch;
+ case 'j':
+ jflag = 1;
+ goto reswitch;
+ case 'l':
+ if (lflag) {
+ lflag = 0;
+ qflag = 1;
+ } else
+ lflag = 1;
+ goto reswitch;
+ case 'n':
+ if (jflag)
+ *(va_arg(ap, intmax_t *)) = retval;
+ else if (qflag)
+ *(va_arg(ap, quad_t *)) = retval;
+ else if (lflag)
+ *(va_arg(ap, long *)) = retval;
+ else if (zflag)
+ *(va_arg(ap, size_t *)) = retval;
+ else if (hflag)
+ *(va_arg(ap, short *)) = retval;
+ else if (cflag)
+ *(va_arg(ap, char *)) = retval;
+ else
+ *(va_arg(ap, int *)) = retval;
+ break;
+ case 'o':
+ base = 8;
+ goto handle_nosign;
+ case 'p':
+ base = 16;
+ sharpflag = (width == 0);
+ sign = 0;
+ num = (uintptr_t)va_arg(ap, void *);
+ goto number;
+ case 'q':
+ qflag = 1;
+ goto reswitch;
+ case 'r':
+ base = radix;
+ if (sign)
+ goto handle_sign;
+ goto handle_nosign;
+ case 's':
+ p = va_arg(ap, char *);
+ if (p == NULL)
+ p = "(null)";
+ if (!dot)
+ n = strlen (p);
+ else
+ for (n = 0; n < dwidth && p[n]; n++)
+ continue;
+
+ width -= n;
+
+ if (!ladjust && width > 0)
+ while (width--)
+ PCHAR(padc);
+ while (n--)
+ PCHAR(*p++);
+ if (ladjust && width > 0)
+ while (width--)
+ PCHAR(padc);
+ break;
+ case 't':
+ tflag = 1;
+ goto reswitch;
+ case 'u':
+ base = 10;
+ goto handle_nosign;
+ case 'X':
+ upper = 1;
+ case 'x':
+ base = 16;
+ goto handle_nosign;
+ case 'y':
+ base = 16;
+ sign = 1;
+ goto handle_sign;
+ case 'z':
+ zflag = 1;
+ goto reswitch;
+handle_nosign:
+ sign = 0;
+ if (jflag)
+ num = va_arg(ap, uintmax_t);
+ else if (qflag)
+ num = va_arg(ap, u_quad_t);
+ else if (tflag)
+ num = va_arg(ap, ptrdiff_t);
+ else if (lflag)
+ num = va_arg(ap, u_long);
+ else if (zflag)
+ num = va_arg(ap, size_t);
+ else if (hflag)
+ num = (u_short)va_arg(ap, int);
+ else if (cflag)
+ num = (u_char)va_arg(ap, int);
+ else
+ num = va_arg(ap, u_int);
+ goto number;
+handle_sign:
+ if (jflag)
+ num = va_arg(ap, intmax_t);
+ else if (qflag)
+ num = va_arg(ap, quad_t);
+ else if (tflag)
+ num = va_arg(ap, ptrdiff_t);
+ else if (lflag)
+ num = va_arg(ap, long);
+ else if (zflag)
+ num = va_arg(ap, ssize_t);
+ else if (hflag)
+ num = (short)va_arg(ap, int);
+ else if (cflag)
+ num = (char)va_arg(ap, int);
+ else
+ num = va_arg(ap, int);
+number:
+ if (sign && (intmax_t)num < 0) {
+ neg = 1;
+ num = -(intmax_t)num;
+ }
+ p = ksprintn(nbuf, num, base, &n, upper);
+ tmp = 0;
+ if (sharpflag && num != 0) {
+ if (base == 8)
+ tmp++;
+ else if (base == 16)
+ tmp += 2;
+ }
+ if (neg)
+ tmp++;
+
+ if (!ladjust && padc == '0')
+ dwidth = width - tmp;
+ width -= tmp + imax(dwidth, n);
+ dwidth -= n;
+ if (!ladjust)
+ while (width-- > 0)
+ PCHAR(' ');
+ if (neg)
+ PCHAR('-');
+ if (sharpflag && num != 0) {
+ if (base == 8) {
+ PCHAR('0');
+ } else if (base == 16) {
+ PCHAR('0');
+ PCHAR('x');
+ }
+ }
+ while (dwidth-- > 0)
+ PCHAR('0');
+
+ while (*p)
+ PCHAR(*p--);
+
+ if (ladjust)
+ while (width-- > 0)
+ PCHAR(' ');
+
+ break;
+ default:
+ while (percent < fmt)
+ PCHAR(*percent++);
+ /*
+ * Since we ignore an formatting argument it is no
+ * longer safe to obey the remaining formatting
+ * arguments as the arguments will no longer match
+ * the format specs.
+ */
+ stop = 1;
+ break;
+ }
+ }
+#undef PCHAR
+}
diff --git a/lib/semihosting/aarch64/semihosting_call.S b/lib/semihosting/aarch64/semihosting_call.S
new file mode 100644
index 0000000..cc72ec2
--- /dev/null
+++ b/lib/semihosting/aarch64/semihosting_call.S
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, ARM Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ .globl semihosting_call
+
+ .section .text, "ax"
+
+semihosting_call:; .type semihosting_call, %function
+ hlt #0xf000
+ ret
diff --git a/lib/semihosting/semihosting.c b/lib/semihosting/semihosting.c
new file mode 100644
index 0000000..558973a
--- /dev/null
+++ b/lib/semihosting/semihosting.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2013, ARM Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <semihosting.h>
+
+#ifndef SEMIHOSTING_SUPPORTED
+#define SEMIHOSTING_SUPPORTED 1
+#endif
+
+extern int semihosting_call(unsigned int operation,
+ void *system_block_address);
+
+typedef struct {
+ const char *file_name;
+ unsigned int mode;
+ unsigned int name_length;
+} smh_file_open_block;
+
+typedef struct {
+ int handle;
+ void *buffer;
+ unsigned int length;
+} smh_file_read_write_block;
+
+typedef struct {
+ int handle;
+ unsigned int location;
+} smh_file_seek_block;
+
+typedef struct {
+ char *command_line;
+ unsigned int command_length;
+} smh_system_block;
+
+int semihosting_connection_supported(void)
+{
+ return SEMIHOSTING_SUPPORTED;
+}
+
+int semihosting_file_open(const char *file_name, unsigned int mode)
+{
+ smh_file_open_block open_block;
+
+ open_block.file_name = file_name;
+ open_block.mode = mode;
+ open_block.name_length = strlen(file_name);
+
+ return semihosting_call(SEMIHOSTING_SYS_OPEN,
+ (void *) &open_block);
+}
+
+int semihosting_file_seek(int file_handle, unsigned int offset)
+{
+ smh_file_seek_block seek_block;
+ int result;
+
+ seek_block.handle = file_handle;
+ seek_block.location = offset;
+
+ result = semihosting_call(SEMIHOSTING_SYS_SEEK,
+ (void *) &seek_block);
+
+ if (result)
+ result = semihosting_call(SEMIHOSTING_SYS_ERRNO, 0);
+
+ return result;
+}
+
+int semihosting_file_read(int file_handle, int *length, void *buffer)
+{
+ smh_file_read_write_block read_block;
+ int result = -EINVAL;
+
+ if ((length == NULL) || (buffer == NULL))
+ return result;
+
+ read_block.handle = file_handle;
+ read_block.buffer = buffer;
+ read_block.length = *length;
+
+ result = semihosting_call(SEMIHOSTING_SYS_READ,
+ (void *) &read_block);
+
+ if (result == *length) {
+ return -EINVAL;
+ } else if (result < *length) {
+ *length -= result;
+ return 0;
+ } else
+ return result;
+}
+
+int semihosting_file_write(int file_handle, int *length, void *buffer)
+{
+ smh_file_read_write_block write_block;
+
+ if ((length == NULL) || (buffer == NULL))
+ return -EINVAL;
+
+ write_block.handle = file_handle;
+ write_block.buffer = buffer;
+ write_block.length = *length;
+
+ *length = semihosting_call(SEMIHOSTING_SYS_WRITE,
+ (void *) &write_block);
+
+ return *length;
+}
+
+int semihosting_file_close(int file_handle)
+{
+ return semihosting_call(SEMIHOSTING_SYS_CLOSE,
+ (void *) &file_handle);
+}
+
+int semihosting_file_length(int file_handle)
+{
+ return semihosting_call(SEMIHOSTING_SYS_FLEN,
+ (void *) &file_handle);
+}
+
+char semihosting_read_char(void)
+{
+ return semihosting_call(SEMIHOSTING_SYS_READC, NULL);
+}
+
+void semihosting_write_char(char character)
+{
+ semihosting_call(SEMIHOSTING_SYS_WRITEC, (void *) &character);
+}
+
+void semihosting_write_string(char *string)
+{
+ semihosting_call(SEMIHOSTING_SYS_WRITE0, (void *) string);
+}
+
+int semihosting_system(char *command_line)
+{
+ smh_system_block system_block;
+
+ system_block.command_line = command_line;
+ system_block.command_length = strlen(command_line);
+
+ return semihosting_call(SEMIHOSTING_SYS_SYSTEM,
+ (void *) &system_block);
+}
+
+int semihosting_get_flen(const char *file_name)
+{
+ int file_handle, length;
+
+ assert(semihosting_connection_supported());
+
+ file_handle = semihosting_file_open(file_name, FOPEN_MODE_RB);
+ if (file_handle == -1)
+ return file_handle;
+
+ /* Find the length of the file */
+ length = semihosting_file_length(file_handle);
+
+ return semihosting_file_close(file_handle) ? -1 : length;
+}
+
+int semihosting_download_file(const char *file_name,
+ int buf_size,
+ void *buf)
+{
+ int ret = -EINVAL, file_handle, length;
+
+ /* Null pointer check */
+ if (!buf)
+ return ret;
+
+ assert(semihosting_connection_supported());
+
+ file_handle = semihosting_file_open(file_name, FOPEN_MODE_RB);
+ if (file_handle == -1)
+ return ret;
+
+ /* Find the actual length of the file */
+ length = semihosting_file_length(file_handle);
+ if (length == -1)
+ goto semihosting_fail;
+
+ /* Signal error if we do not have enough space for the file */
+ if (length > buf_size)
+ goto semihosting_fail;
+
+ /*
+ * A successful read will return 0 in which case we pass back
+ * the actual number of bytes read. Else we pass a negative
+ * value indicating an error.
+ */
+ ret = semihosting_file_read(file_handle, &length, buf);
+ if (ret)
+ goto semihosting_fail;
+ else
+ ret = length;
+
+semihosting_fail:
+ semihosting_file_close(file_handle);
+ return ret;
+}
diff --git a/lib/sync/locks/bakery/bakery_lock.c b/lib/sync/locks/bakery/bakery_lock.c
new file mode 100644
index 0000000..d3c780c
--- /dev/null
+++ b/lib/sync/locks/bakery/bakery_lock.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2013, ARM Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include <bakery_lock.h>
+
+#define assert_bakery_entry_valid(entry, bakery) do { \
+ assert(bakery); \
+ assert(entry < BAKERY_LOCK_MAX_CPUS); \
+} while(0)
+
+void bakery_lock_init(bakery_lock * bakery)
+{
+ assert(bakery);
+ memset(bakery, 0, sizeof(*bakery));
+ bakery->owner = NO_OWNER;
+}
+
+void bakery_lock_get(unsigned long mpidr, bakery_lock * bakery)
+{
+ unsigned int i, max = 0, my_full_number, his_full_number, entry;
+
+ entry = platform_get_core_pos(mpidr);
+
+ assert_bakery_entry_valid(entry, bakery);
+
+ // Catch recursive attempts to take the lock under the same entry:
+ assert(bakery->owner != entry);
+
+ // Get a ticket
+ bakery->entering[entry] = 1;
+ for (i = 0; i < BAKERY_LOCK_MAX_CPUS; ++i) {
+ if (bakery->number[i] > max) {
+ max = bakery->number[i];
+ }
+ }
+ ++max;
+ bakery->number[entry] = max;
+ bakery->entering[entry] = 0;
+
+ // Wait for our turn
+ my_full_number = (max << 8) + entry;
+ for (i = 0; i < BAKERY_LOCK_MAX_CPUS; ++i) {
+ while (bakery->entering[i]) ; /* Wait */
+ do {
+ his_full_number = bakery->number[i];
+ if (his_full_number) {
+ his_full_number = (his_full_number << 8) + i;
+ }
+ }
+ while (his_full_number && (his_full_number < my_full_number));
+ }
+
+ bakery->owner = entry;
+}
+
+void bakery_lock_release(unsigned long mpidr, bakery_lock * bakery)
+{
+ unsigned int entry = platform_get_core_pos(mpidr);
+
+ assert_bakery_entry_valid(entry, bakery);
+ assert(bakery_lock_held(entry, bakery));
+
+ bakery->owner = NO_OWNER;
+ bakery->number[entry] = 0;
+}
+
+int bakery_lock_held(unsigned long mpidr, const bakery_lock * bakery)
+{
+ unsigned int entry = platform_get_core_pos(mpidr);
+
+ assert_bakery_entry_valid(entry, bakery);
+
+ return bakery->owner == entry;
+}
diff --git a/lib/sync/locks/exclusive/spinlock.S b/lib/sync/locks/exclusive/spinlock.S
new file mode 100644
index 0000000..4269d95
--- /dev/null
+++ b/lib/sync/locks/exclusive/spinlock.S
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013, ARM Limited. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ .globl spin_lock
+ .globl spin_unlock
+
+
+ .section .text, "ax";
+
+spin_lock:; .type spin_lock, %function
+ mov w2, #1
+ sevl
+l1: wfe
+l2: ldaxr w1, [x0]
+ cbnz w1, l1
+ stxr w1, w2, [x0]
+ cbnz w1, l2
+ ret
+
+
+spin_unlock:; .type spin_unlock, %function
+ stlr wzr, [x0]
+ ret