aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux
Commit message (Expand)AuthorAgeFilesLines
* Update S100 profile (#2587)Florian Fainelli2007-10-291-1/+2
* Resync kernel config, put back yellow led registration (#2607)Florian Fainelli2007-10-292-2/+8
* Initial OLPC targetJens Muecke2007-10-2814-0/+19750
* fixed typo in generic squashfs split patch ... shame on you :)John Crispin2007-10-271-1/+1
* reduce wasted flash space by ~56K on Edimax devices, thanks to Bernhard Held ...Gabor Juhos2007-10-262-9/+5
* Fix another wrong shitfingFlorian Fainelli2007-10-251-1/+1
* Wrong bit shifting for the cfrdy function, will always return cf-mips busyFlorian Fainelli2007-10-251-1/+1
* Fix the r8169 kernel module (#2554)Florian Fainelli2007-10-241-3/+0
* The build system actually changed the routerboard kernel (#2584)Florian Fainelli2007-10-241-1/+5
* silence a bogus preinit messageFelix Fietkau2007-10-241-1/+1
* The watchdog driver is now a platform device driver and reads its gpio line w...Florian Fainelli2007-10-241-0/+104
* minor cleanupsGabor Juhos2007-10-248-228/+135
* ar7_gpio: remove unneeded checks and volatileMatteo Croce2007-10-231-14/+2
* fix flash driver, it should work on RB150 as wellGabor Juhos2007-10-233-6/+16
* ar7: fix eva image generationEugene Konev2007-10-231-1/+1
* The RB513 CF driver is now a module, enable it by default for the RB1xx profi...Florian Fainelli2007-10-236-6/+22
* We are now at .23.1Florian Fainelli2007-10-238-8/+8
* Add ps3 targetFelix Fietkau2007-10-234-0/+1169
* Add udev initilisationFelix Fietkau2007-10-231-0/+14
* only do hotplug2 init if hotplug2 is presentFelix Fietkau2007-10-231-2/+3
* Allow targets to specify extra initramfs source filesFelix Fietkau2007-10-231-0/+9
* don't replace powerpc arch with ppcFelix Fietkau2007-10-232-0/+2
* Add preliminary support for the Routerboard 153 CF slot (#2550)Florian Fainelli2007-10-229-2/+1079
* Resync kernel config, make kernel.{flash,ram}.srec availableFlorian Fainelli2007-10-222-7/+2
* ar7: add eva image generation (thanks Axel Gembe)Eugene Konev2007-10-221-0/+7
* fix b0rked atheros kernelconfigJohn Crispin2007-10-211-27/+13
* refreshed madwifi patchesJohn Crispin2007-10-201-0/+1
* reorganize subtargets, sort subtargets below top level targetsFelix Fietkau2007-10-206-9/+8
* make morse LED trigger available as a package, and fix it to compile with 2.6.23Gabor Juhos2007-10-201-22/+93
* add LEDs trigger for switch port states, thanks to Bernhard Held (closes: #2153)Gabor Juhos2007-10-204-0/+177
* fix typos in the switch driver, thanks to Bernhard Held (closes: #2573)Gabor Juhos2007-10-201-2/+2
* add patch for gpio-leds to support special brightness values, thanks to Bernh...Gabor Juhos2007-10-201-0/+29
* fritzbox leds detection (thanks Axel Gembe)Eugene Konev2007-10-191-4/+27
* fixed missing symbols in atheros kernel configJohn Crispin2007-10-181-19/+26
* don't dispatch spurious irq0 eventsFelix Fietkau2007-10-182-4/+0
* add kernel config option to disabling common PCI quirks, resync kernel configGabor Juhos2007-10-183-15/+52
* add ids for Edimax BR-6104Wg boardsGabor Juhos2007-10-185-10/+55
* fix initcall level in i2c-gpio-custom driver if not built as a moduleGabor Juhos2007-10-171-3/+10
* switch driver cleanup, 4th phaseGabor Juhos2007-10-175-154/+227
* added rtl8169, from #2554John Crispin2007-10-161-0/+3
* switch driver cleanup, 3rd phaseGabor Juhos2007-10-161-160/+214
* Fix tx error handling (#2552). Make rx ring size actually configurable throug...Eugene Konev2007-10-161-18/+11
* resync avr32 with 2.6.23.atmel.1Imre Kaloz2007-10-163-5609/+6103
* switch driver cleanup, 2nd phaseGabor Juhos2007-10-161-147/+332
* Resync kernel config, do not enable the setup fileFlorian Fainelli2007-10-152-14/+1
* Typo on PCI idsFlorian Fainelli2007-10-152-3/+2
* Add the RDC PCI ids for a fancier PCI device table.Return the system name on ...Florian Fainelli2007-10-154-2/+34
* switch driver cleanup, 1st phaseGabor Juhos2007-10-153-418/+606
* Fix profile/image generation for dir450Florian Fainelli2007-10-142-3/+9
* fixed missing kernel option for x86John Crispin2007-10-141-4/+1
*/ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
/*
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 * Copyright (C) IBM Corp. 2005, 2006
 *
 * Authors: Jimi Xenidis <jimix@watson.ibm.com>
 */

#include <xen/config.h>
#include <xen/init.h>
#include <xen/lib.h>
#include <xen/cpumask.h>
#include <xen/sched.h>
#include <xen/multiboot.h>
#include <xen/serial.h>
#include <xen/softirq.h>
#include <xen/console.h>
#include <xen/trace.h>
#include <xen/mm.h>
#include <xen/domain.h>
#include <xen/gdbstub.h>
#include <xen/symbols.h>
#include <xen/keyhandler.h>
#include <acm/acm_hooks.h>
#include <public/version.h>
#include <asm/processor.h>
#include <asm/desc.h>
#include <asm/cache.h>
#include <asm/debugger.h>
#include <asm/delay.h>
#include <asm/percpu.h>
#include "exceptions.h"
#include "of-devtree.h"

#define DEBUG
unsigned long xenheap_phys_end;

/* opt_noht: If true, Hyperthreading is ignored. */
int opt_noht = 0;
boolean_param("noht", opt_noht);

int opt_earlygdb = 0;
boolean_param("earlygdb", opt_earlygdb);

/* opt_nosmp: If true, secondary processors are ignored. */
static int opt_nosmp = 0;
boolean_param("nosmp", opt_nosmp);

/* maxcpus: maximum number of CPUs to activate. */
static unsigned int max_cpus = NR_CPUS;
integer_param("maxcpus", max_cpus);

u32 tlbflush_clock = 1U;
DEFINE_PER_CPU(u32, tlbflush_time);

unsigned int watchdog_on;
unsigned long wait_init_idle;
ulong oftree;
ulong oftree_len;
ulong oftree_end;

cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly;
cpumask_t cpu_online_map; /* missing ifdef in schedule.c */
cpumask_t cpu_present_map;

/* XXX get this from ISA node in device tree */
ulong isa_io_base;
struct ns16550_defaults ns16550;

extern char __per_cpu_start[], __per_cpu_data_end[], __per_cpu_end[];
extern void idle_loop(void);

/* move us to a header file */
extern void initialize_keytable(void);

volatile struct processor_area * volatile global_cpu_table[NR_CPUS];

int is_kernel_text(unsigned long addr)
{
    if (addr >= (unsigned long) &_start &&
        addr <= (unsigned long) &_etext)
        return 1;
    return 0;
}

unsigned long kernel_text_end(void)
{
    return (unsigned long) &_etext;
}

void idle_loop(void)
{
    int cpu = smp_processor_id();

    for ( ; ; )
    {
        while (!softirq_pending(cpu)) {
            void sleep(void);
            page_scrub_schedule_work();
            sleep();
        }
        do_softirq();
    }
}

static void __init do_initcalls(void)
{
    initcall_t *call;
    for (call = &__initcall_start; call < &__initcall_end; call++) {
        (*call)();
    }
}

static void hw_probe_attn(unsigned char key, struct cpu_user_regs *regs)
{
    /* To continue the probe will step over the ATTN instruction.  The
     * NOP is there to make sure there is something sane to "step
     * over" to. */
    asm volatile(".long 0x00000200; nop");
}

static void percpu_init_areas(void)
{
    unsigned int i, data_size = __per_cpu_data_end - __per_cpu_start;

    BUG_ON(data_size > PERCPU_SIZE);

    for ( i = 1; i < NR_CPUS; i++ )
        memcpy(__per_cpu_start + (i << PERCPU_SHIFT),
               __per_cpu_start,
               data_size);
}

static void percpu_free_unused_areas(void)
{
    unsigned int i, first_unused;

    /* Find first unused CPU number. */
    for ( i = 0; i < NR_CPUS; i++ )
        if ( !cpu_online(i) )
            break;
    first_unused = i;

    /* Check that there are no holes in cpu_online_map. */
    for ( ; i < NR_CPUS; i++ )
        BUG_ON(cpu_online(i));

    init_xenheap_pages((ulong)__per_cpu_start + (first_unused << PERCPU_SHIFT),
                       (ulong)__per_cpu_end);
}

static void __init start_of_day(void)
{
    struct domain *idle_domain;

    init_IRQ();

    scheduler_init();

    /* create idle domain */
    idle_domain = domain_create(IDLE_DOMAIN_ID);
    if ((idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL))
        BUG();
    set_current(idle_domain->vcpu[0]);
    idle_vcpu[0] = current;

    /* for some reason we need to set our own bit in the thread map */
    cpu_set(0, cpu_sibling_map[0]);

    percpu_free_unused_areas();

    initialize_keytable();
    /* Register another key that will allow for the the Harware Probe
     * to be contacted, this works with RiscWatch probes and should
     * work with Chronos and FSPs */
    register_irq_keyhandler('^', hw_probe_attn,   "Trap to Hardware Probe");

    timer_init();
    serial_init_postirq();
    do_initcalls();
    schedulers_start();
}

void startup_cpu_idle_loop(void)
{
    struct vcpu *v = current;

    ASSERT(is_idle_vcpu(v));
    cpu_set(smp_processor_id(), v->domain->domain_dirty_cpumask);
    cpu_set(smp_processor_id(), v->vcpu_dirty_cpumask);

    /* Finally get off the boot stack. */
    reset_stack_and_jump(idle_loop);
}

static ulong free_xenheap(ulong start, ulong end)
{
    start = ALIGN_UP(start, PAGE_SIZE);
    end = ALIGN_DOWN(end, PAGE_SIZE);

    printk("%s: 0x%lx - 0x%lx\n", __func__, start, end);

    if (oftree <= end && oftree >= start) {
        printk("%s:     Go around the devtree: 0x%lx - 0x%lx\n",
                  __func__, oftree, oftree_end);
        init_xenheap_pages(start, ALIGN_DOWN(oftree, PAGE_SIZE));
        init_xenheap_pages(ALIGN_UP(oftree_end, PAGE_SIZE), end);
    } else {
        init_xenheap_pages(start, end);
    }
    return ALIGN_UP(end, PAGE_SIZE);
}

static void init_parea(int cpuid)
{
    /* Be careful not to shadow the global variable.  */
    volatile struct processor_area *pa;
    void *stack;

    pa = xmalloc(struct processor_area);
    if (pa == NULL)
        panic("%s: failed to allocate parea for cpu #%d\n", __func__, cpuid);

    stack = alloc_xenheap_pages(STACK_ORDER);
    if (stack == NULL)
        panic("%s: failed to allocate stack (order %d) for cpu #%d\n", 
              __func__, STACK_ORDER, cpuid);

    pa->whoami = cpuid;
    pa->hyp_stack_base = (void *)((ulong)stack + STACK_SIZE);

    /* This store has the effect of invoking secondary_cpu_init.  */
    global_cpu_table[cpuid] = pa;
    mb();
}

static int kick_secondary_cpus(int maxcpus)
{
    int cpuid;

    for_each_present_cpu(cpuid) {
        if (cpuid == 0)
            continue;
        if (cpuid >= maxcpus)
            break;
        init_parea(cpuid);
        cpu_set(cpuid, cpu_online_map);
    }

    return 0;
}

/* This is the first C code that secondary processors invoke.  */
int secondary_cpu_init(int cpuid, unsigned long r4);
int secondary_cpu_init(int cpuid, unsigned long r4)
{
    cpu_initialize(cpuid);
    while(1);
}

static void __init __start_xen(multiboot_info_t *mbi)
{
    char *cmdline;
    module_t *mod = (module_t *)((ulong)mbi->mods_addr);
    ulong heap_start;
    ulong eomem = 0;
    ulong heap_size = 0;
    ulong bytes = 0;
    ulong freemem;
    ulong dom0_start, dom0_len;
    ulong initrd_start, initrd_len;
    
    int i;

    memcpy(0, exception_vectors, exception_vectors_end - exception_vectors);
    synchronize_caches(0, exception_vectors_end - exception_vectors);

    ticks_per_usec = timebase_freq / 1000000ULL;

    /* Parse the command-line options. */
    if ((mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0))
        cmdline_parse(__va((ulong)mbi->cmdline));

    /* We initialise the serial devices very early so we can get debugging. */
    ns16550.io_base = 0x3f8;
    ns16550_init(0, &ns16550);
    ns16550.io_base = 0x2f8;
    ns16550_init(1, &ns16550);
    serial_init_preirq();

    init_console();
#ifdef CONSOLE_SYNC
    console_start_sync();
#endif

    /* Check that we have at least one Multiboot module. */
    if (!(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0)) {
        panic("FATAL ERROR: Require at least one Multiboot module.\n");
    }

    if (!(mbi->flags & MBI_MEMMAP)) {
        panic("FATAL ERROR: Bootloader provided no memory information.\n");
    }

    /* OF dev tree is the last module */
    oftree = mod[mbi->mods_count-1].mod_start;
    oftree_end = mod[mbi->mods_count-1].mod_end;
    oftree_len = oftree_end - oftree;

    /* remove it from consideration */
    mod[mbi->mods_count-1].mod_start = 0;
    mod[mbi->mods_count-1].mod_end = 0;
    --mbi->mods_count;

    printk("Physical RAM map:\n");

    /* lets find out how much memory there is */
    while (bytes < mbi->mmap_length) {
        u64 end;
        u64 addr;
        u64 size;

        memory_map_t *map = (memory_map_t *)((ulong)mbi->mmap_addr + bytes);
        addr = ((u64)map->base_addr_high << 32) | (u64)map->base_addr_low;
        size = ((u64)map->length_high << 32) | (u64)map->length_low;
        end = addr + size;

        printk(" %016lx - %016lx (usable)\n", addr, end);

        if (addr > eomem) {
            printk("found a hole skipping remainder of memory at:\n"
                   " %016lx and beyond\n", addr);
            break;
        }
        if (end > eomem) {
            eomem = end;
        }
        bytes += map->size + 4;
    }

    printk("System RAM: %luMB (%lukB)\n", eomem >> 20, eomem >> 10);

    /* top of memory */
    max_page = PFN_DOWN(ALIGN_DOWN(eomem, PAGE_SIZE));
    total_pages = max_page;

    /* Architecturally the first 4 pages are exception hendlers, we
     * will also be copying down some code there */
    heap_start = 4 << PAGE_SHIFT;
    if (oftree < (ulong)_start)
        heap_start = ALIGN_UP(oftree_end, PAGE_SIZE);

    heap_start = init_boot_allocator(heap_start);
    if (heap_start > (ulong)_start) {
        panic("space below _start (%p) is not enough memory "
              "for heap (0x%lx)\n", _start, heap_start);
    }

    /* we give the first RMA to the hypervisor */
    xenheap_phys_end = rma_size(cpu_rma_order());

    /* allow everything else to be allocated */
    init_boot_pages(xenheap_phys_end, eomem);
    init_frametable();
    end_boot_allocator();

    /* Add memory between the beginning of the heap and the beginning
     * of out text */
    free_xenheap(heap_start, (ulong)_start);
    freemem = ALIGN_UP((ulong)_end, PAGE_SIZE);

    for (i = 0; i < mbi->mods_count; i++) {
        u32 s;