Mailing List Archive

[PATCH 04/14] arm: implement xen init code
arm: implement xen init code

xen/arch/arm/xen/cpu.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
xen/arch/arm/xen/setup.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 167 insertions(+), 18 deletions(-)

Signed-off-by: Jaemin Ryu <jm77.ryu@samsung.com>

diff -r fb0815ba40a1 xen/arch/arm/xen/cpu.c
--- a/xen/arch/arm/xen/cpu.c Fri Feb 03 16:26:49 2012 +0900
+++ b/xen/arch/arm/xen/cpu.c Fri Feb 03 17:28:15 2012 +0900
@@ -28,6 +28,11 @@
#include <xen/sched.h>
#include <xen/preempt.h>
#include <xen/percpu.h>
+#include <asm/mmu.h>
+#include <asm/current.h>
+#include <asm/delay.h>
+#include <asm/processor.h>
+#include <asm/delay.h>

cpumask_t cpu_online_map;
cpumask_t cpu_present_map;
@@ -46,7 +51,12 @@ DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t

int __cpu_up(unsigned int cpu)
{
- NOT_YET();
+ int ret = 0;
+
+ while(!cpu_online(cpu)) {
+ cpu_relax();
+ process_pending_softirqs();
+ }

return 0;
}
@@ -63,35 +73,93 @@ void __cpu_die(unsigned int cpu)

void set_cpu_sibling_map(unsigned int cpu)
{
- NOT_YET();
+ unsigned int i;
+
+ for_each_present_cpu(i) {
+ cpumask_set_cpu(i, &per_cpu(cpu_sibling_mask, cpu));
+ cpumask_set_cpu(cpu, &per_cpu(cpu_sibling_mask, i));
+
+ cpumask_set_cpu(i, &per_cpu(cpu_core_mask, cpu));
+ cpumask_set_cpu(cpu, &per_cpu(cpu_core_mask, i));
+ }
}

void smp_prepare_cpus(unsigned int max_cpus)
{
- NOT_YET();
+ set_cpu_sibling_map(0);
}

void smp_prepare_boot_cpu(void)
{
- NOT_YET();
+ int cpu = smp_processor_id();
+
+ cpumask_set_cpu(cpu, &cpu_online_map);
+ cpumask_set_cpu(cpu, &cpu_present_map);
+ cpumask_set_cpu(cpu, &cpu_possible_map);
+
+ cpu_info_init(get_cpu_info());
}

asmlinkage void start_xen_on_slave_cpu(void)
{
- NOT_YET();
+ unsigned int cpu;
+ struct vcpu *v;
+
+ cpu = smp_processor_id();
+
+ /* idle vcpu is allocated by scheduler_init() */
+ v = idle_vcpu[cpu];
+ set_current(idle_vcpu[cpu]);
+
+ set_cpu_sibling_map(cpu);
+
+ notify_cpu_starting(cpu);
+ wmb();
+
+ cpumask_set_cpu(cpu, &cpu_online_map);
+ wmb();
+
+ local_irq_enable();
+ local_fiq_enable();
+
+ startup_cpu_idle_loop();
}

void smp_send_event_check_mask(const cpumask_t *mask)
{
- NOT_YET();
+ int cpu;
+ unsigned long map = 0;
+
+ for_each_cpu(cpu, mask) {
+ map |= 1 << cpu;
+ }
+
+ /* Trigger remote CPU */
}

void smp_call_function(void (*f)(void *param), void *param, int wait)
{
- NOT_YET();
}

void smp_send_state_dump(unsigned int cpu)
{
- NOT_YET();
}
+
+void cpu_topology_init(unsigned int cpus)
+{
+ int i;
+
+ if (cpus == 0) {
+ cpus = 1;
+ }
+
+ if (cpus > MAX_PHYS_CPUS) {
+ cpus = MAX_PHYS_CPUS;
+ }
+
+ for (i = 0; i < cpus; i++) {
+ cpumask_set_cpu(i, &cpu_possible_map);
+ cpumask_set_cpu(i, &cpu_present_map);
+ }
+}
+
diff -r fb0815ba40a1 xen/arch/arm/xen/setup.c
--- a/xen/arch/arm/xen/setup.c Fri Feb 03 16:26:49 2012 +0900
+++ b/xen/arch/arm/xen/setup.c Fri Feb 03 17:28:15 2012 +0900
@@ -30,35 +30,116 @@
#include <xen/preempt.h>
#include <public/version.h>
#include <public/sched.h>
-
+#include <asm/mmu.h>

struct domain _dom_xen = {
- .refcnt = ATOMIC_INIT(1),
- .domain_id = DOMID_XEN,
- .domain_lock = SPIN_LOCK_UNLOCKED,
+ .refcnt = ATOMIC_INIT(1),
+ .domain_id = DOMID_XEN,
+ .domain_lock = SPIN_LOCK_UNLOCKED,
};

struct domain _dom_io = {
- .refcnt = ATOMIC_INIT(1),
- .domain_id = DOMID_IO,
- .domain_lock = SPIN_LOCK_UNLOCKED,
+ .refcnt = ATOMIC_INIT(1),
+ .domain_id = DOMID_IO,
+ .domain_lock = SPIN_LOCK_UNLOCKED,
};

struct domain _dom_cow = {
- .refcnt = ATOMIC_INIT(1),
- .domain_id = DOMID_COW,
- .domain_lock = SPIN_LOCK_UNLOCKED,
+ .refcnt = ATOMIC_INIT(1),
+ .domain_id = DOMID_COW,
+ .domain_lock = SPIN_LOCK_UNLOCKED,
};

struct domain *dom_xen = &_dom_xen;
struct domain *dom_io = &_dom_io;
struct domain *dom_cow = &_dom_cow;

+/* maxcpus: maximum number of CPUs to be activated */
+static unsigned int max_cpus = NR_CPUS;
+integer_param("maxcpus", max_cpus);
+
+/* Default domain size = 64MB */
+static unsigned int dom0_size = 256 * 1024 * 1024;
+integer_param("dom0_size", dom0_size);
+
+//static unsigned long dom0_image_start = 0x40B00000UL;
+static unsigned long dom0_image_start = 0x00B00000UL;
+integer_param("image_start", dom0_image_start);
+
+//static unsigned long dom0_image_size = 0xA00000UL;
+static unsigned long dom0_image_size = 0xA00000UL;
+integer_param("image_length", dom0_image_size);
+
void arch_get_xen_caps(xen_capabilities_info_t *info)
{
}

+static void idle_domain_init(void)
+{
+ struct vcpu *v;
+
+ scheduler_init();
+
+ /* idle vcpu is allocated by scheduler_init() */
+ v = idle_vcpu[0];
+
+ set_current_vcpu(v);
+}
+
asmlinkage void start_xen(void)
{
+ unsigned int i;
+
+ smp_prepare_boot_cpu();
+
+ softirq_init();
+
+ tasklet_subsys_init();
+
+ timer_init();
+
+ idle_domain_init();
+
+ rcu_init();
+
+ local_irq_enable();
+
+ smp_prepare_cpus(max_cpus);
+
+ do_presmp_initcalls();
+
+ timekeeping_init();
+
+ for_each_present_cpu(i) {
+ if (num_online_cpus() < max_cpus && !cpu_online(i)) {
+ int ret = cpu_up(i);
+
+ if (ret != 0) {
+ printk("Fail to bring up CPU %u (error %d)\n", i, ret);
+ }
+ }
+ }
+
+ printk("Brought up %ld CPUs\n", (long)num_online_cpus());
+
+ do_initcalls();
+
+ dom0 = domain_create(0, 0, 0);
+ if (dom0 == NULL) {
+ panic("Domain creation failed\n");
+ }
+
+
+ if (domain_construct(dom0,
+ dom0_image_start,
+ dom0_image_size,
+ dom0_size,
+ max_cpus)) {
+ PANIC("Domain construction failed\n");
+ }
+
+ domain_unpause_by_systemcontroller(dom0);
+
+ startup_cpu_idle_loop();
}