[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v5 11/25] arm: entry.S and head.S



From: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>

Low level assembly routines, including entry.S and head.S.
Also the linker script and a collection of dummy functions that we plan
to reduce to zero as soon as possible.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Signed-off-by: Tim Deegan <Tim.Deegan@xxxxxxxxxx>
---
 xen/arch/arm/asm-offsets.c      |   76 ++++++++++
 xen/arch/arm/dummy.S            |   72 ++++++++++
 xen/arch/arm/entry.S            |  107 ++++++++++++++
 xen/arch/arm/head.S             |  298 +++++++++++++++++++++++++++++++++++++++
 xen/arch/arm/xen.lds.S          |  141 ++++++++++++++++++
 xen/include/asm-arm/asm_defns.h |   18 +++
 6 files changed, 712 insertions(+), 0 deletions(-)
 create mode 100644 xen/arch/arm/asm-offsets.c
 create mode 100644 xen/arch/arm/dummy.S
 create mode 100644 xen/arch/arm/entry.S
 create mode 100644 xen/arch/arm/head.S
 create mode 100644 xen/arch/arm/xen.lds.S
 create mode 100644 xen/include/asm-arm/asm_defns.h

diff --git a/xen/arch/arm/asm-offsets.c b/xen/arch/arm/asm-offsets.c
new file mode 100644
index 0000000..ee5d5d4
--- /dev/null
+++ b/xen/arch/arm/asm-offsets.c
@@ -0,0 +1,76 @@
+/*
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed
+ * to extract and format the required data.
+ */
+#define COMPILE_OFFSETS
+
+#include <xen/config.h>
+#include <xen/types.h>
+#include <public/xen.h>
+#include <asm/current.h>
+
+#define DEFINE(_sym, _val) \
+    __asm__ __volatile__ ( "\n->" #_sym " %0 " #_val : : "i" (_val) )
+#define BLANK() \
+    __asm__ __volatile__ ( "\n->" : : )
+#define OFFSET(_sym, _str, _mem) \
+    DEFINE(_sym, offsetof(_str, _mem));
+
+/* base-2 logarithm */
+#define __L2(_x)  (((_x) & 0x00000002) ?   1 : 0)
+#define __L4(_x)  (((_x) & 0x0000000c) ? ( 2 + __L2( (_x)>> 2)) : __L2( _x))
+#define __L8(_x)  (((_x) & 0x000000f0) ? ( 4 + __L4( (_x)>> 4)) : __L4( _x))
+#define __L16(_x) (((_x) & 0x0000ff00) ? ( 8 + __L8( (_x)>> 8)) : __L8( _x))
+#define LOG_2(_x) (((_x) & 0xffff0000) ? (16 + __L16((_x)>>16)) : __L16(_x))
+
+void __dummy__(void)
+{
+   OFFSET(UREGS_sp, struct cpu_user_regs, sp);
+   OFFSET(UREGS_lr, struct cpu_user_regs, lr);
+   OFFSET(UREGS_pc, struct cpu_user_regs, pc);
+   OFFSET(UREGS_cpsr, struct cpu_user_regs, cpsr);
+
+   OFFSET(UREGS_LR_usr, struct cpu_user_regs, lr_usr);
+   OFFSET(UREGS_SP_usr, struct cpu_user_regs, sp_usr);
+
+   OFFSET(UREGS_SP_svc, struct cpu_user_regs, sp_svc);
+   OFFSET(UREGS_LR_svc, struct cpu_user_regs, lr_svc);
+   OFFSET(UREGS_SPSR_svc, struct cpu_user_regs, spsr_svc);
+
+   OFFSET(UREGS_SP_abt, struct cpu_user_regs, sp_abt);
+   OFFSET(UREGS_LR_abt, struct cpu_user_regs, lr_abt);
+   OFFSET(UREGS_SPSR_abt, struct cpu_user_regs, spsr_abt);
+
+   OFFSET(UREGS_SP_und, struct cpu_user_regs, sp_und);
+   OFFSET(UREGS_LR_und, struct cpu_user_regs, lr_und);
+   OFFSET(UREGS_SPSR_und, struct cpu_user_regs, spsr_und);
+
+   OFFSET(UREGS_SP_irq, struct cpu_user_regs, sp_irq);
+   OFFSET(UREGS_LR_irq, struct cpu_user_regs, lr_irq);
+   OFFSET(UREGS_SPSR_irq, struct cpu_user_regs, spsr_irq);
+
+   OFFSET(UREGS_SP_fiq, struct cpu_user_regs, sp_fiq);
+   OFFSET(UREGS_LR_fiq, struct cpu_user_regs, lr_fiq);
+   OFFSET(UREGS_SPSR_fiq, struct cpu_user_regs, spsr_fiq);
+
+   OFFSET(UREGS_R8_fiq, struct cpu_user_regs, r8_fiq);
+   OFFSET(UREGS_R9_fiq, struct cpu_user_regs, r9_fiq);
+   OFFSET(UREGS_R10_fiq, struct cpu_user_regs, r10_fiq);
+   OFFSET(UREGS_R11_fiq, struct cpu_user_regs, r11_fiq);
+   OFFSET(UREGS_R12_fiq, struct cpu_user_regs, r12_fiq);
+
+   OFFSET(UREGS_kernel_sizeof, struct cpu_user_regs, cpsr);
+   DEFINE(UREGS_user_sizeof, sizeof(struct cpu_user_regs));
+   BLANK();
+
+   DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info));
+}
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/dummy.S b/xen/arch/arm/dummy.S
new file mode 100644
index 0000000..5bc4f21
--- /dev/null
+++ b/xen/arch/arm/dummy.S
@@ -0,0 +1,72 @@
+/* Nothing is mapped at 1G, for the moment */
+#define DUMMY(x) \
+       .globl x; \
+x:     .word 0xe7f000f0
+/* x:  mov r0, #0x40000000 ; str r0, [r0]; b x */
+
+#define  NOP(x) \
+       .globl x; \
+x:     mov pc, lr
+       
+DUMMY(alloc_pirq_struct);
+DUMMY(alloc_vcpu_guest_context);
+DUMMY(arch_do_domctl);
+DUMMY(arch_do_sysctl);
+DUMMY(arch_do_vcpu_op);
+DUMMY(arch_get_info_guest);
+DUMMY(arch_get_xen_caps);
+DUMMY(arch_memory_op);
+DUMMY(arch_set_info_guest);
+DUMMY(arch_vcpu_reset);
+DUMMY(create_grant_host_mapping);
+DUMMY(__cpu_die);
+DUMMY(__cpu_disable);
+DUMMY(__cpu_up);
+DUMMY(do_get_pm_info);
+DUMMY(domain_get_maximum_gpfn);
+DUMMY(domain_relinquish_resources);
+DUMMY(domain_set_time_offset);
+DUMMY(dom_cow);
+DUMMY(donate_page);
+DUMMY(do_pm_op);
+DUMMY(flush_tlb_mask);
+DUMMY(free_vcpu_guest_context);
+DUMMY(get_page);
+DUMMY(get_page_type);
+DUMMY(gmfn_to_mfn);
+DUMMY(gnttab_clear_flag);
+DUMMY(gnttab_host_mapping_get_page_type);
+DUMMY(gnttab_mark_dirty);
+DUMMY(hypercall_create_continuation);
+DUMMY(iommu_map_page);
+DUMMY(iommu_unmap_page);
+DUMMY(is_iomem_page);
+DUMMY(local_event_delivery_enable);
+DUMMY(local_events_need_delivery);
+DUMMY(machine_to_phys_mapping_valid);
+DUMMY(max_page);
+DUMMY(node_online_map);
+DUMMY(nr_irqs_gsi);
+DUMMY(p2m_pod_decrease_reservation);
+DUMMY(guest_physmap_mark_populate_on_demand);
+DUMMY(page_get_owner_and_reference);
+DUMMY(page_is_ram_type);
+DUMMY(per_cpu__cpu_core_mask);
+DUMMY(per_cpu__cpu_sibling_mask);
+DUMMY(__per_cpu_offset);
+DUMMY(pirq_guest_bind);
+DUMMY(pirq_guest_unbind);
+DUMMY(pirq_set_affinity);
+DUMMY(put_page);
+DUMMY(put_page_type);
+DUMMY(replace_grant_host_mapping);
+DUMMY(send_timer_event);
+DUMMY(share_xen_page_with_privileged_guests);
+DUMMY(smp_send_state_dump);
+DUMMY(steal_page);
+DUMMY(sync_vcpu_execstate);
+DUMMY(__udelay);
+NOP(update_vcpu_system_time);
+DUMMY(vcpu_mark_events_pending);
+DUMMY(vcpu_show_execution_state);
+DUMMY(wallclock_time);
diff --git a/xen/arch/arm/entry.S b/xen/arch/arm/entry.S
new file mode 100644
index 0000000..16a8f36
--- /dev/null
+++ b/xen/arch/arm/entry.S
@@ -0,0 +1,107 @@
+#include <xen/config.h>
+#include <asm/asm_defns.h>
+
+#define SAVE_ONE_BANKED(reg)   mrs r11, reg; str r11, [sp, #UREGS_##reg]
+#define RESTORE_ONE_BANKED(reg)        ldr r11, [sp, #UREGS_##reg]; msr reg, 
r11
+
+#define SAVE_BANKED(mode) \
+       SAVE_ONE_BANKED(SP_##mode) ; SAVE_ONE_BANKED(LR_##mode) ; 
SAVE_ONE_BANKED(SPSR_##mode)
+
+#define RESTORE_BANKED(mode) \
+       RESTORE_ONE_BANKED(SP_##mode) ; RESTORE_ONE_BANKED(LR_##mode) ; 
RESTORE_ONE_BANKED(SPSR_##mode)
+
+#define SAVE_ALL                                                               
                        \
+       sub sp, #(UREGS_R8_fiq - UREGS_sp); /* SP, LR, SPSR, PC */              
                        \
+       push {r0-r12}; /* Save R0-R12 */                                        
                        \
+                                                                               
                        \
+       mrs r11, ELR_hyp;               /* ELR_hyp is return address. */        
                        \
+       str r11, [sp, #UREGS_pc];                                               
                        \
+                                                                               
                        \
+       str lr, [sp, #UREGS_lr];                                                
                        \
+                                                                               
                        \
+       add r11, sp, #UREGS_kernel_sizeof+4;                                    
                        \
+       str r11, [sp, #UREGS_sp];                                               
                        \
+                                                                               
                        \
+       mrs r11, SPSR_hyp;                                                      
                        \
+       str r11, [sp, #UREGS_cpsr];                                             
                        \
+       and r11, #PSR_MODE_MASK;                                                
                        \
+       cmp r11, #PSR_MODE_HYP;                                                 
                        \
+       blne save_guest_regs
+
+save_guest_regs:
+       ldr r11, [sp, #UREGS_lr]
+       str r11, [sp, #UREGS_LR_usr]
+       ldr r11, =0xffffffff  /* Clobber SP which is only valid for hypervisor 
frames. */
+       str r11, [sp, #UREGS_sp]
+       SAVE_ONE_BANKED(SP_usr)
+       SAVE_BANKED(svc)
+       SAVE_BANKED(abt)
+       SAVE_BANKED(und)
+       SAVE_BANKED(irq)
+       SAVE_BANKED(fiq)
+       SAVE_ONE_BANKED(R8_fiq); SAVE_ONE_BANKED(R9_fiq); 
SAVE_ONE_BANKED(R10_fiq)
+       SAVE_ONE_BANKED(R11_fiq); SAVE_ONE_BANKED(R12_fiq);
+       mov pc, lr
+
+#define DEFINE_TRAP_ENTRY(trap)                                                
                                \
+       ALIGN;                                                                  
                        \
+trap_##trap:                                                                   
                        \
+       SAVE_ALL;                                                               
                        \
+       adr lr, return_from_trap;                                               
                        \
+       mov r0, sp;                                                             
                        \
+       mov r11, sp;                                                            
                        \
+       bic sp, #7; /* Align the stack pointer (noop on guest trap) */          
                        \
+       b do_trap_##trap
+
+.globl hyp_traps_vector
+       .align 5
+hyp_traps_vector:
+       .word 0                         /* 0x00 - Reset */
+       b trap_undefined_instruction    /* 0x04 - Undefined Instruction */
+       b trap_supervisor_call          /* 0x08 - Supervisor Call */
+       b trap_prefetch_abort           /* 0x0c - Prefetch Abort */
+       b trap_data_abort               /* 0x10 - Data Abort */
+       b trap_hypervisor               /* 0x14 - Hypervisor */
+       b trap_irq                      /* 0x18 - IRQ */
+       b trap_fiq                      /* 0x1c - FIQ */
+
+DEFINE_TRAP_ENTRY(undefined_instruction)
+DEFINE_TRAP_ENTRY(supervisor_call)
+DEFINE_TRAP_ENTRY(prefetch_abort)
+DEFINE_TRAP_ENTRY(data_abort)
+DEFINE_TRAP_ENTRY(hypervisor)
+DEFINE_TRAP_ENTRY(irq)
+DEFINE_TRAP_ENTRY(fiq)
+
+ENTRY(return_from_trap)
+       ldr r11, [sp, #UREGS_cpsr]
+       and r11, #PSR_MODE_MASK
+       cmp r11, #PSR_MODE_HYP
+       beq return_to_hypervisor
+
+ENTRY(return_to_guest)
+       mov r11, sp
+       bic sp, #7 /* Align the stack pointer */
+       bl leave_hypervisor_tail
+       ldr r11, [sp, #UREGS_pc]
+       msr ELR_hyp, r11
+       ldr r11, [sp, #UREGS_cpsr]
+       msr SPSR_hyp, r11
+       RESTORE_ONE_BANKED(SP_usr)
+       RESTORE_BANKED(svc)
+       RESTORE_BANKED(abt)
+       RESTORE_BANKED(und)
+       RESTORE_BANKED(irq)
+       RESTORE_BANKED(fiq)
+       RESTORE_ONE_BANKED(R8_fiq); RESTORE_ONE_BANKED(R9_fiq); 
RESTORE_ONE_BANKED(R10_fiq)
+       RESTORE_ONE_BANKED(R11_fiq); RESTORE_ONE_BANKED(R12_fiq);
+       ldr lr, [sp, #UREGS_LR_usr]
+       pop {r0-r12}
+       add sp, #(UREGS_R8_fiq - UREGS_sp); /* SP, LR, SPSR, PC */
+       eret
+
+ENTRY(return_to_hypervisor)
+       ldr lr, [sp, #UREGS_lr]
+       pop {r0-r12}
+       add sp, #(UREGS_R8_fiq - UREGS_sp); /* SP, LR, SPSR, PC */
+       eret
diff --git a/xen/arch/arm/head.S b/xen/arch/arm/head.S
new file mode 100644
index 0000000..b98c921
--- /dev/null
+++ b/xen/arch/arm/head.S
@@ -0,0 +1,298 @@
+/*
+ * xen/arch/arm/head.S
+ *
+ * Start-of-day code for an ARMv7-A with virt extensions.
+ *
+ * Tim Deegan <tim@xxxxxxx>
+ * Copyright (c) 2011 Citrix Systems.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <asm/config.h>
+#include <asm/page.h>
+#include <asm/asm_defns.h>
+
+
+/* Macro to print a string to the UART, if there is one.
+ * Clobbers r0-r3. */
+#ifdef EARLY_UART_ADDRESS
+#define PRINT(_s)       \
+       adr   r0, 98f ; \
+       bl    puts    ; \
+       b     99f     ; \
+98:    .asciz _s     ; \
+       .align 2      ; \
+99:
+#else
+#define PRINT(s)
+#endif
+
+       .arm
+
+       /* This must be the very first address in the loaded image.
+        * It should be linked at XEN_VIRT_START, and loaded at any
+        * 2MB-aligned address.  All of text+data+bss must fit in 2MB,
+        * or the initial pagetable code below will need adjustment. */
+       .global start
+start:
+       cpsid aif                    /* Disable all interrupts */
+
+       /* Save the bootloader arguments in less-clobberable registers */
+       mov   r7, r1                 /* r7 := ARM-linux machine type */
+       mov   r8, r2                 /* r8 := ATAG base address */
+
+       /* Find out where we are */
+       ldr   r0, =start
+       adr   r9, start              /* r9  := paddr (start) */
+       sub   r10, r9, r0            /* r10 := phys-offset */
+
+#ifdef EARLY_UART_ADDRESS
+       /* Say hello */
+       ldr   r11, =EARLY_UART_ADDRESS  /* r11 := UART base address */
+       bl    init_uart
+#endif
+
+       /* Check that this CPU has Hyp mode */
+       mrc   CP32(r0, ID_PFR1)
+       and   r0, r0, #0xf000        /* Bits 12-15 define virt extensions */
+       teq   r0, #0x1000            /* Must == 0x1 or may be incompatible */
+       beq   1f
+       bl    putn
+       PRINT("- CPU doesn't support the virtualization extensions -\r\n")
+       b     fail
+1:
+       /* Check if we're already in it */
+       mrs   r0, cpsr
+       and   r0, r0, #0x1f          /* Mode is in the low 5 bits of CPSR */
+       teq   r0, #0x1a              /* Hyp Mode? */
+       bne   1f
+       PRINT("- Started in Hyp mode -\r\n")
+       b     hyp
+1:
+       /* Otherwise, it must have been Secure Supervisor mode */
+       mrc   CP32(r0, SCR)
+       tst   r0, #0x1               /* Not-Secure bit set? */
+       beq   1f
+       PRINT("- CPU is not in Hyp mode or Secure state -\r\n")
+       b     fail
+1:
+       /* OK, we're in Secure state. */
+       PRINT("- Started in Secure state -\r\n- Entering Hyp mode -\r\n")
+
+       /* Dance into Hyp mode */
+       cpsid aif, #0x16             /* Enter Monitor mode */
+       mrc   CP32(r0, SCR)
+       orr   r0, r0, #0x100         /* Set HCE */
+       orr   r0, r0, #0xb1          /* Set SCD, AW, FW and NS */
+       bic   r0, r0, #0xe           /* Clear EA, FIQ and IRQ */
+       mcr   CP32(r0, SCR)
+       /* Ugly: the system timer's frequency register is only
+        * programmable in Secure state.  Since we don't know where its
+        * memory-mapped control registers live, we can't find out the
+        * right frequency.  Use the VE model's default frequency here. */
+       ldr   r0, =0x5f5e100         /* 100 MHz */
+       mcr   CP32(r0, CNTFRQ)
+       ldr   r0, =0x40c00           /* SMP, c11, c10 in non-secure mode */
+       mcr   CP32(r0, NSACR)
+       /* Continuing ugliness: Set up the GIC so NS state owns interrupts */
+       mov   r0, #GIC_BASE_ADDRESS
+       add   r0, r0, #GIC_DR_OFFSET
+       mov   r1, #0
+       str   r1, [r0]               /* Disable delivery in the distributor */
+       add   r0, r0, #0x80          /* GICD_IGROUP0 */
+       mov   r2, #0xffffffff        /* All interrupts to group 1 */
+       str   r2, [r0]
+       str   r2, [r0, #4]
+       str   r2, [r0, #8]
+       /* Must drop priority mask below 0x80 before entering NS state */
+       mov   r0, #GIC_BASE_ADDRESS
+       add   r0, r0, #GIC_CR_OFFSET
+       ldr   r1, =0xff
+       str   r1, [r0, #0x4]         /* -> GICC_PMR */
+       /* Reset a few config registers */
+       mov   r0, #0
+       mcr   CP32(r0, FCSEIDR)
+       mcr   CP32(r0, CONTEXTIDR)
+       /* FIXME: ought to reset some other NS control regs here */
+       adr   r1, 1f
+       adr   r0, hyp                /* Store paddr (hyp entry point) */
+       str   r0, [r1]               /* where we can use it for RFE */
+       isb                          /* Ensure we see the stored target address 
*/
+       rfeia r1                     /* Enter Hyp mode */
+
+1:     .word 0                      /* PC to enter Hyp mode at */
+       .word 0x000001da             /* CPSR: LE, Abort/IRQ/FIQ off, Hyp */
+
+hyp:
+       PRINT("- Setting up control registers -\r\n")
+
+       /* Set up memory attribute type tables */
+       ldr   r0, =MAIR0VAL
+       ldr   r1, =MAIR1VAL
+       mcr   CP32(r0, MAIR0)
+       mcr   CP32(r1, MAIR1)
+       mcr   CP32(r0, HMAIR0)
+       mcr   CP32(r1, HMAIR1)
+
+       /* Set up the HTCR:
+        * PT walks use Outer-Shareable accesses,
+        * PT walks are write-back, no-write-allocate in both cache levels,
+        * Full 32-bit address space goes through this table. */
+       ldr   r0, =0x80002500
+       mcr   CP32(r0, HTCR)
+
+       /* Set up the HSCTLR:
+        * Exceptions in LE ARM,
+        * Low-latency IRQs disabled,
+        * Write-implies-XN disabled (for now),
+        * I-cache and d-cache enabled,
+        * Alignment checking enabled,
+        * MMU translation disabled (for now). */
+       ldr   r0, =(HSCTLR_BASE|SCTLR_A|SCTLR_C)
+       mcr   CP32(r0, HSCTLR)
+
+       /* Write Xen's PT's paddr into the HTTBR */
+       ldr   r4, =xen_pgtable
+       add   r4, r4, r10            /* r4 := paddr (xen_pagetable) */
+       mov   r5, #0                 /* r4:r5 is paddr (xen_pagetable) */
+       mcrr  CP64(r4, r5, HTTBR)
+
+       /* Build the baseline idle pagetable's first-level entries */
+       ldr   r1, =xen_second
+       add   r1, r1, r10            /* r1 := paddr (xen_second) */
+       mov   r3, #0x0
+       orr   r2, r1, #0xe00         /* r2:r3 := table map of xen_second */
+       orr   r2, r2, #0x07f         /* (+ rights for linear PT) */
+       strd  r2, r3, [r4, #0]       /* Map it in slot 0 */
+       add   r2, r2, #0x1000
+       strd  r2, r3, [r4, #8]       /* Map 2nd page in slot 1 */
+       add   r2, r2, #0x1000
+       strd  r2, r3, [r4, #16]      /* Map 3rd page in slot 2 */
+       add   r2, r2, #0x1000
+       strd  r2, r3, [r4, #24]      /* Map 4th page in slot 3 */
+
+       /* Now set up the second-level entries */
+       orr   r2, r9, #0xe00
+       orr   r2, r2, #0x07d         /* r2:r3 := 2MB normal map of Xen */
+       mov   r4, r9, lsr #18        /* Slot for paddr(start) */
+       strd  r2, r3, [r1, r4]       /* Map Xen there */
+       ldr   r4, =start
+       lsr   r4, #18                /* Slot for vaddr(start) */
+       strd  r2, r3, [r1, r4]       /* Map Xen there too */
+#ifdef EARLY_UART_ADDRESS
+       ldr   r3, =(1<<(54-32))      /* NS for device mapping */
+       lsr   r2, r11, #21
+       lsl   r2, r2, #21            /* 2MB-aligned paddr of UART */
+       orr   r2, r2, #0xe00
+       orr   r2, r2, #0x071         /* r2:r3 := 2MB dev map including UART */
+       add   r4, r4, #8
+       strd  r2, r3, [r1, r4]       /* Map it in the fixmap's slot */
+#endif
+
+       PRINT("- Turning on paging -\r\n")
+
+       ldr   r1, =paging            /* Explicit vaddr, not RIP-relative */
+       mrc   CP32(r0, HSCTLR)
+       orr   r0, r0, #0x1           /* Add in the MMU enable bit */
+       dsb                          /* Flush PTE writes and finish reads */
+       mcr   CP32(r0, HSCTLR)       /* now paging is enabled */
+       isb                          /* Now, flush the icache */
+       mov   pc, r1                 /* Get a proper vaddr into PC */
+paging:
+
+#ifdef EARLY_UART_ADDRESS
+       /* Recover the UART address in the new address space */
+       lsl   r11, #11
+       lsr   r11, #11               /* UART base's offset from 2MB base */
+       adr   r0, start
+       add   r0, r0, #0x200000      /* vaddr of the fixmap's 2MB slot */
+       add   r11, r11, r0           /* r11 := vaddr (UART base address) */
+#endif
+
+       PRINT("- Entering C -\r\n")
+
+       ldr   sp, =init_stack        /* Supply a stack */
+       add   sp, #STACK_SIZE        /* (which grows down from the top). */
+       sub   sp, #CPUINFO_sizeof    /* Make room for CPU save record */
+       mov   r0, r10                /* Marshal args: - phys_offset */
+       mov   r1, r7                 /*               - machine type */
+       mov   r2, r8                 /*               - ATAG address */
+       b     start_xen              /* and disappear into the land of C */
+
+/* Fail-stop
+ * r0: string explaining why */
+fail:  PRINT("- Boot failed -\r\n")
+1:     wfe
+       b     1b
+
+#ifdef EARLY_UART_ADDRESS
+
+/* Bring up the UART. Specific to the PL011 UART.
+ * Clobbers r0-r2 */
+init_uart:
+       mov   r1, #0x0
+       str   r1, [r11, #0x24]       /* -> UARTIBRD (Baud divisor fraction) */
+       mov   r1, #0x4               /* 7.3728MHz / 0x4 == 16 * 115200 */
+       str   r1, [r11, #0x24]       /* -> UARTIBRD (Baud divisor integer) */
+       mov   r1, #0x60              /* 8n1 */
+       str   r1, [r11, #0x24]       /* -> UARTLCR_H (Line control) */
+       ldr   r1, =0x00000301        /* RXE | TXE | UARTEN */
+       str   r1, [r11, #0x30]       /* -> UARTCR (Control Register) */
+       adr   r0, 1f
+       b     puts
+1:     .asciz "- UART enabled -\r\n"
+       .align 4
+
+/* Print early debug messages.  Specific to the PL011 UART.
+ * r0: Nul-terminated string to print.
+ * Clobbers r0-r2 */
+puts:
+       ldr   r2, [r11, #0x18]       /* <- UARTFR (Flag register) */
+       tst   r2, #0x8               /* Check BUSY bit */
+       bne   puts                   /* Wait for the UART to be ready */
+       ldrb  r2, [r0], #1           /* Load next char */
+       teq   r2, #0                 /* Exit on nul*/
+       moveq pc, lr
+       str   r2, [r11]              /* -> UARTDR (Data Register) */
+       b     puts
+
+/* Print a 32-bit number in hex.  Specific to the PL011 UART.
+ * r0: Number to print.
+ * clobbers r0-r3 */
+putn:
+       adr   r1, hex
+       mov   r3, #8
+1:     ldr   r2, [r11, #0x18]       /* <- UARTFR (Flag register) */
+       tst   r2, #0x8               /* Check BUSY bit */
+       bne   1b                     /* Wait for the UART to be ready */
+       and   r2, r0, #0xf0000000    /* Mask off the top nybble */
+       ldrb  r2, [r1, r2, lsr #28]  /* Convert to a char */
+       str   r2, [r11]              /* -> UARTDR (Data Register) */
+       lsl   r0, #4                 /* Roll it through one nybble at a time */
+       subs  r3, r3, #1
+       bne   1b
+       adr   r0, crlf               /* Finish with a newline */
+       b     puts
+
+crlf:  .asciz "\r\n"
+hex:   .ascii "0123456789abcdef"
+       .align 2
+
+#else  /* EARLY_UART_ADDRESS */
+
+init_uart:
+.global early_puts
+early_puts:
+puts:
+putn:  mov   pc, lr
+
+#endif /* EARLY_UART_ADDRESS */
diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S
new file mode 100644
index 0000000..5a62e2c
--- /dev/null
+++ b/xen/arch/arm/xen.lds.S
@@ -0,0 +1,141 @@
+/* Excerpts written by Martin Mares <mj@xxxxxxxxxxxxxxxxxxxxxxxx> */
+/* Modified for i386/x86-64 Xen by Keir Fraser */
+/* Modified for ARM Xen by Ian Campbell */
+
+#include <xen/config.h>
+#include <xen/cache.h>
+#include <asm/page.h>
+#include <asm/percpu.h>
+#undef ENTRY
+#undef ALIGN
+
+ENTRY(start)
+
+OUTPUT_ARCH(arm)
+
+PHDRS
+{
+  text PT_LOAD /* XXX should be AT ( XEN_PHYS_START ) */ ;
+}
+SECTIONS
+{
+  . = XEN_VIRT_START;
+  _start = .;
+  .text : /* XXX should be AT ( XEN_PHYS_START ) */ {
+        _stext = .;            /* Text section */
+       *(.text)
+       *(.fixup)
+       *(.gnu.warning)
+       _etext = .;             /* End of text section */
+  } :text = 0x9090
+
+  . = ALIGN(PAGE_SIZE);
+  .rodata : {
+        _srodata = .;          /* Read-only data */
+       *(.rodata)
+       *(.rodata.*)
+        _erodata = .;          /* End of read-only data */
+  } :text
+
+  .data : {                    /* Data */
+       . = ALIGN(PAGE_SIZE);
+       *(.data.page_aligned)
+       *(.data)
+       *(.data.rel)
+       *(.data.rel.*)
+       CONSTRUCTORS
+  } :text
+
+  . = ALIGN(SMP_CACHE_BYTES);
+  .data.read_mostly : {
+       /* Exception table */
+       __start___ex_table = .;
+       *(.ex_table)
+       __stop___ex_table = .;
+
+       /* Pre-exception table */
+       __start___pre_ex_table = .;
+       *(.ex_table.pre)
+       __stop___pre_ex_table = .;
+
+       *(.data.read_mostly)
+       *(.data.rel.ro)
+       *(.data.rel.ro.*)
+  } :text
+
+#ifdef LOCK_PROFILE
+  . = ALIGN(32);
+  __lock_profile_start = .;
+  .lockprofile.data : { *(.lockprofile.data) } :text
+  __lock_profile_end = .;
+#endif
+
+  . = ALIGN(PAGE_SIZE);             /* Init code and data */
+  __init_begin = .;
+  .init.text : {
+       _sinittext = .;
+       *(.init.text)
+       _einittext = .;
+  } :text
+  . = ALIGN(PAGE_SIZE);
+  .init.data : {
+       *(.init.rodata)
+       *(.init.rodata.str*)
+       *(.init.data)
+       *(.init.data.rel)
+       *(.init.data.rel.*)
+  } :text
+  . = ALIGN(32);
+  .init.setup : {
+       __setup_start = .;
+       *(.init.setup)
+       __setup_end = .;
+  } :text
+  .initcall.init : {
+       __initcall_start = .;
+       *(.initcallpresmp.init)
+       __presmp_initcall_end = .;
+       *(.initcall1.init)
+       __initcall_end = .;
+  } :text
+  .xsm_initcall.init : {
+       __xsm_initcall_start = .;
+       *(.xsm_initcall.init)
+       __xsm_initcall_end = .;
+  } :text
+  . = ALIGN(STACK_SIZE);
+  __init_end = .;
+
+  .bss : {                     /* BSS */
+       __bss_start = .;
+       *(.bss.stack_aligned)
+       . = ALIGN(PAGE_SIZE);
+       *(.bss.page_aligned)
+       *(.bss)
+       . = ALIGN(SMP_CACHE_BYTES);
+       __per_cpu_start = .;
+       *(.bss.percpu)
+       . = ALIGN(SMP_CACHE_BYTES);
+       *(.bss.percpu.read_mostly)
+       . = ALIGN(SMP_CACHE_BYTES);
+       __per_cpu_data_end = .;
+  } :text
+  _end = . ;
+
+  /* Sections to be discarded */
+  /DISCARD/ : {
+       *(.exit.text)
+       *(.exit.data)
+       *(.exitcall.exit)
+       *(.eh_frame)
+  }
+
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment 0 : { *(.comment) }
+}
diff --git a/xen/include/asm-arm/asm_defns.h b/xen/include/asm-arm/asm_defns.h
new file mode 100644
index 0000000..c59fb6c
--- /dev/null
+++ b/xen/include/asm-arm/asm_defns.h
@@ -0,0 +1,18 @@
+#ifndef __ARM_ASM_DEFNS_H__
+#define __ARM_ASM_DEFNS_H__
+
+#ifndef COMPILE_OFFSETS
+/* NB. Auto-generated from arch/.../asm-offsets.c */
+#include <asm/asm-offsets.h>
+#endif
+#include <asm/processor.h>
+
+#endif /* __ARM_ASM_DEFNS_H__ */
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
1.7.2.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.