Signed-off-by: Daniel Hellstrom <dan...@gaisler.com> --- arch/sparc/cpu/leon3/Makefile | 2 +- arch/sparc/cpu/leon3/cpu.c | 10 ++- arch/sparc/cpu/leon3/cpu_mp.c | 87 +++++++++++++++ arch/sparc/cpu/leon3/prom.c | 32 +++--- arch/sparc/cpu/leon3/start.S | 70 ++++++++++++ arch/sparc/include/asm/boot_mp.h | 70 ++++++++++++ arch/sparc/lib/Makefile | 2 +- arch/sparc/lib/boot_mp.c | 177 +++++++++++++++++++++++++++++++ arch/sparc/lib/bootm.c | 57 ++++++++-- board/gaisler/gr_cpci_ax2000/u-boot.lds | 7 ++ board/gaisler/gr_ep2s60/u-boot.lds | 7 ++ board/gaisler/gr_xc3s_1500/u-boot.lds | 7 ++ board/gaisler/grsim/u-boot.lds | 7 ++ include/configs/gr_cpci_ax2000.h | 12 ++- include/configs/gr_ep2s60.h | 12 ++- include/configs/gr_xc3s_1500.h | 14 ++- include/configs/grsim.h | 12 ++- 17 files changed, 547 insertions(+), 38 deletions(-) create mode 100644 arch/sparc/cpu/leon3/cpu_mp.c create mode 100644 arch/sparc/include/asm/boot_mp.h create mode 100644 arch/sparc/lib/boot_mp.c
diff --git a/arch/sparc/cpu/leon3/Makefile b/arch/sparc/cpu/leon3/Makefile index f1bb808..4d36061 100644 --- a/arch/sparc/cpu/leon3/Makefile +++ b/arch/sparc/cpu/leon3/Makefile @@ -28,7 +28,7 @@ LIB = $(obj)lib$(CPU).a START = start.o SOBJS = ambapp_low.o ambapp_low_c.o memcfg_low.o COBJS = cpu_init.o serial.o cpu.o ambapp.o interrupts.o prom.o usb_uhci.o \ - memcfg.o + memcfg.o cpu_mp.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/arch/sparc/cpu/leon3/cpu.c b/arch/sparc/cpu/leon3/cpu.c index 5cc9513..13d3dd7 100644 --- a/arch/sparc/cpu/leon3/cpu.c +++ b/arch/sparc/cpu/leon3/cpu.c @@ -83,8 +83,14 @@ int checkcpu(void) /* ------------------------------------------------------------------------- */ -void cpu_reset(void) +int cpu_reset(int nr) { + if ( nr > 0 ) { + puts(" CPU[N] RESET NOT SUPPORTED BY ARCHITECTURE (N>0), " + "SYSTEM RESET IS POSSIBLE."); + return -1; + } + /* Interrupts off */ disable_interrupts(); @@ -94,7 +100,7 @@ void cpu_reset(void) int do_reset(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { - cpu_reset(); + cpu_reset(0); return 1; diff --git a/arch/sparc/cpu/leon3/cpu_mp.c b/arch/sparc/cpu/leon3/cpu_mp.c new file mode 100644 index 0000000..9074149 --- /dev/null +++ b/arch/sparc/cpu/leon3/cpu_mp.c @@ -0,0 +1,87 @@ +/* Interface implementation for cmd_mp.c on multi processor LEON + * CPUs + * + * (C) Copyright 2010 + * Daniel Hellstrom, Gaisler Research, dan...@gaisler.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <config.h> + +#ifdef CONFIG_MP + +#include <grlib/irqmp.h> + +extern int leon_cpu_cnt; +extern ambapp_dev_irqmp *irqmp; + +int cpu_numcores(void) +{ + return leon_cpu_cnt; +} + +int cpu_status(int nr) +{ + printf("LEON CPUs available: %d\n", leon_cpu_cnt); + + return 0; +} + +int cpu_disable(int nr) +{ + printf("LEON CPU disable not available\n"); + + return 0; +} + +int cpu_release(int nr, int argc, char *argv[]) +{ + unsigned int ep, stack, arg0, arg1; + + /* Get entry point, stack and argument */ + if ( argc < 2 ) { + printf( " At least 5 arguments must be given.\n" + " Argument 4 is entry point\n" + " Argument 5 is stack\n" + " Argument 6-7 is kernel arg 0 and 1 (OPTIONAL)\n"); + return -1; + } + ep = simple_strtoul(argv[0], NULL, 16); + stack = simple_strtoul(argv[1], NULL, 16); + arg0 = arg1 = 0; + + if ( argc > 2 ) { + arg0 = simple_strtoul(argv[2], NULL, 16); + } + if ( argc > 3 ) { + arg1 = simple_strtoul(argv[3], NULL, 16); + } + + /* Register CPU start up options into MP table */ + boot_mp_cpu_setup(nr, ep, stack, (void *)arg0, (void *)arg1); + + /* Release CPU by writing to IRQ controller MP register */ + irqmp->mstatus = (1<<nr); + + return 0; +} + +#endif diff --git a/arch/sparc/cpu/leon3/prom.c b/arch/sparc/cpu/leon3/prom.c index e0a69af..eb7350b 100644 --- a/arch/sparc/cpu/leon3/prom.c +++ b/arch/sparc/cpu/leon3/prom.c @@ -31,6 +31,7 @@ #include <asm/processor.h> #include <asm/irq.h> #include <asm/leon.h> +#include <asm/boot_mp.h> #include <ambapp.h> #include <grlib/apbuart.h> #include <grlib/irqmp.h> @@ -931,21 +932,9 @@ void leon_prom_init(struct leon_prom_info *pspi) /* Set the pointer to the Console UART in romvec */ pspi->reloc_funcs.leon3_apbuart = leon3_apbuart; - { - int j = 1; -#ifdef CONFIG_SMP - ambapp_dev_irqmp *b; - b = (ambapp_dev_irqmp *) leon3_getapbbase(VENDOR_GAISLER, - GAISLER_IRQMP); - if (b) { - j = 1 + ((LEON3_BYPASS_LOAD_PA(&(b->mpstatus)) - >> LEON3_IRQMPSTATUS_CPUNR) & 0xf); - } -#endif #undef nodes - pspi->nodes[2 + j].level = -1; - pspi->nodes[2 + j].properties = __va(spi.root_properties + 3); - } + pspi->nodes[2 + leon_cpu_cnt].level = -1; + pspi->nodes[2 + leon_cpu_cnt].properties = __va(spi.root_properties + 3); /* Set Ethernet MAC address from environment */ if ((addr_str = getenv("ethaddr")) != NULL) { @@ -1024,7 +1013,7 @@ void prepare_bootargs(char *bootargs) } } -void srmmu_init_cpu(unsigned int entry) +void srmmu_init(unsigned int entry) { sparc_srmmu_setup *psrmmu_tables = (void *) ((((unsigned int)&srmmu_tables) & PROM_SIZE_MASK) + @@ -1079,6 +1068,19 @@ void srmmu_init_cpu(unsigned int entry) /* convert rom vec pointer to virtual address */ kernel_arg_promvec = (struct linux_romvec *) (((unsigned int)kernel_arg_promvec & 0x0fffffff) | 0xf0000000); +} + +#ifdef CONFIG_MP +/* This function must be located in the MP or PROM part of the application because + * it will be called from CPU1, CPU2 ... after CPU0 has made it into the kernel + * and started the other CPUs + */ +void MP_TEXT boot_mp_linux_cpu_preinit(int cpu) +#else +void boot_mp_linux_cpu_preinit(int cpu) +#endif +{ + sparc_srmmu_setup *psrmmu_tables = (void *)CONFIG_SYS_PROM_OFFSET; /* Set Context pointer to point to context table * 256 contexts supported. diff --git a/arch/sparc/cpu/leon3/start.S b/arch/sparc/cpu/leon3/start.S index a9c49d9..050f604 100644 --- a/arch/sparc/cpu/leon3/start.S +++ b/arch/sparc/cpu/leon3/start.S @@ -27,6 +27,7 @@ #include <asm/psr.h> #include <asm/stack.h> #include <asm/leon.h> +#include <asm/boot_mp.h> #include <timestamp.h> #include <version.h> #include <ambapp.h> @@ -258,6 +259,20 @@ wininit: set WIM_INIT, %g3 mov %g3, %wim +#ifdef CONFIG_MP +/* In a multi CPU system (and the slave CPUs have been started) the slaves + * have a special boot up sequence. It is expected that CPU0 has already run + * u-boot and it has loaded an OS which now have activated one or more slave + * CPUs. + */ +multi_cpu_detect: + rd %asr17, %g3 + srl %g3, 28, %g3 + cmp %g3, %g0 + bne slave_cpu_init + nop +#endif + stackp: set CONFIG_SYS_INIT_SP_OFFSET, %fp andn %fp, 0x0f, %fp @@ -386,6 +401,23 @@ prom_relocate_loop: bne prom_relocate_loop inc 16,%g4 +#ifdef CONFIG_MP +mp_relocate: + set __mp_start, %g2 + set __mp_end, %g3 + set CONFIG_SYS_MP_OFFSET, %g4 + +mp_relocate_loop: + ldd [%g2],%l0 + ldd [%g2+8],%l2 + std %l0,[%g4] + std %l2,[%g4+8] + inc 16,%g2 + subcc %g3,%g2,%g0 + bne mp_relocate_loop + inc 16,%g4 +#endif + /* Trap table has been moved, lets tell CPU about * the new trap table address */ @@ -651,3 +683,41 @@ _reset_reloc: set start, %l0 call %l0 nop + +#ifdef CONFIG_MP +/* Slave CPUs reach here */ +slave_cpu_init: + + /* Get Index into cpu slave struct */ + sll %g3, 4, %i0 + + set (CONFIG_SYS_MP_OFFSET+0x4), %o1 /* cpu_table is mp_data+0x4 */ + add %i0, %o1, %i0 + + /* Setup Stack Pointer from config */ + ld [%i0 + BOOT_MP_CPU_STACK], %fp + andn %fp, 0x0f, %fp + sub %fp, 64, %sp + + /* Call OS-dependent CPU init routine */ + set CONFIG_SYS_MP_OFFSET, %o1 /* cpu_table is mp_data+0x0 */ + ld [%o1], %o1 + cmp %o1, 0 + beq slave_cpu_boot_kernel + nop + call %o1 + clr %o0 + + /* Call Kernel */ +slave_cpu_boot_kernel: + ld [%i0 + BOOT_MP_CPU_ARG0], %o0 /* ARG0 */ + ld [%i0 + BOOT_MP_CPU_ARG1], %o1 /* ARG1 */ + ld [%i0 + BOOT_MP_CPU_EP], %o3 /* ENTRY POINT */ + call %o3 + clr %o2 + +dead_slave: + /* Kernel Failed or no support for MP */ + ta 0x1 + nop +#endif diff --git a/arch/sparc/include/asm/boot_mp.h b/arch/sparc/include/asm/boot_mp.h new file mode 100644 index 0000000..e033b9c --- /dev/null +++ b/arch/sparc/include/asm/boot_mp.h @@ -0,0 +1,70 @@ +/* Multiprocessor boot setup functions. + * + * (C) Copyright 2010 + * Daniel Hellstrom, Gaisler Research, dan...@gaisler.com. + * + * 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, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#ifndef __ASM_SPARC_BOOT_MP_H__ +#define __ASM_SPARC_BOOT_MP_H__ + +#define MP_TEXT __attribute__ ((__section__ (".mp.text"))) +#define MP_DATA __attribute__ ((__section__ (".mp.data"))) + +#define BOOT_MP_CPU_EP 0x00 +#define BOOT_MP_CPU_STACK 0x04 +#define BOOT_MP_CPU_ARG0 0x08 +#define BOOT_MP_CPU_ARG1 0x0C + +#ifndef __ASSEMBLER__ + +/* Allow for arch specific CPU initialization before RTEMS boot */ +extern void boot_mp_rtems_cpu_preinit(int cpu); + +/* Allow for arch specific CPU initialization before VxWorks boot */ +extern void boot_mp_vxworks_cpu_preinit(int cpu); + +/* Allow for arch specific CPU initialization before Linux boot */ +extern void boot_mp_linux_cpu_preinit(int cpu); + +struct boot_mp_cpu { + unsigned int entry_point; + unsigned int stack; + void *arg0; + void *arg1; +}; + +/* All CPU entry points and stacks */ +extern struct boot_mp_cpu boot_mp_cpu_table[]; + +extern void boot_mp_os_setup(int os); + +extern void boot_mp_cpu_setup( + int cpu, + unsigned int entry_point, + unsigned int stack, + void *arg0, + void *arg1 + ); + +/* Init a CPU before entering the kernel */ +extern void boot_mp_cpu_preinit(int cpu); + +#endif + +#endif diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index 040ca10..3860fdc 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile @@ -27,7 +27,7 @@ LIB = $(obj)lib$(ARCH).a SOBJS = -COBJS = board.o cache.o interrupts.o time.o bootm.o +COBJS = board.o cache.o interrupts.o time.o bootm.o boot_mp.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/arch/sparc/lib/boot_mp.c b/arch/sparc/lib/boot_mp.c new file mode 100644 index 0000000..3b4dcd0 --- /dev/null +++ b/arch/sparc/lib/boot_mp.c @@ -0,0 +1,177 @@ +/* SPARC Multi-Processor initialization + * + * (C) Copyright 2010 + * Daniel Hellstrom, Aeroflex Gaisler, dan...@gaisler.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/boot_mp.h> +#include <config.h> + +#ifdef CONFIG_MP + +#ifndef CONFIG_MP_MAX_CPUS + #error CONFIG_MP_MAX_CPUS must be defined +#endif + +typedef int (*cpu_preinit_func) (int cpu); + +/* Structure of all MP DATA section */ +struct boot_mp_data { + /* Function called for each CPU before entering kernel */ + cpu_preinit_func func; + + /* All CPU entry points and so on */ + struct boot_mp_cpu cpu_table[CONFIG_MP_MAX_CPUS]; + + /* OS to boot */ + int os; +}; + +struct boot_mp_data MP_DATA mp_data; + +/* Allow for specific RTEMS CPU initialization before RTEMS AMP boot */ +void MP_TEXT __boot_mp_rtems_cpu_preinit(int cpu) +{ + +} +void boot_mp_rtems_cpu_preinit(int cpu) + __attribute__((weak, alias("__boot_mp_rtems_cpu_preinit"))); + +/* Allow for specific VxWorks CPU initialization before slave CPUs boot */ +void MP_TEXT __boot_mp_vxworks_cpu_preinit(int cpu) +{ + +} +void boot_mp_vxworks_cpu_preinit(int cpu) + __attribute__((weak, alias("__boot_mp_vxworks_cpu_preinit"))); + +/* Allow for specific Linux CPU initialization before slave CPUs boot */ +void MP_TEXT __boot_mp_linux_cpu_preinit(int cpu) +{ + +} +void boot_mp_linux_cpu_preinit(int cpu) + __attribute__((weak, alias("__boot_mp_linux_cpu_preinit"))); + +static cpu_preinit_func os_cpu_preinit[] = +{ + [IH_OS_LINUX] = boot_mp_linux_cpu_preinit, + [IH_OS_RTEMS] = boot_mp_rtems_cpu_preinit, + [IH_OS_VXWORKS] = boot_mp_vxworks_cpu_preinit, +}; + +void boot_mp_os_setup(int os) +{ + struct boot_mp_data *mpd = (void *)CONFIG_SYS_MP_OFFSET; + unsigned int func; + + mpd->os = os; + + func = (unsigned int)os_cpu_preinit[os]; + if ( func == 0 ) { + /* We assume that the OS booting does not support MP and will + * therefore not start the other CPUs. + */ + mpd->func = 0; + } else { + mpd->func = CONFIG_SYS_MP_OFFSET + (func & (CONFIG_SYS_MP_SIZE-1)); + } + + debug("boot_mp_os_setup: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", + os, + os_cpu_preinit, + &os_cpu_preinit[os], + (unsigned int)os_cpu_preinit[os], + CONFIG_SYS_MP_SIZE, + ((unsigned int)os_cpu_preinit[os] & (CONFIG_SYS_MP_SIZE-1)) + ); +} + +void boot_mp_cpu_setup( + int cpu, + unsigned int entry_point, + unsigned int stack, + void *arg0, + void *arg1 + ) +{ + struct boot_mp_data *mpd = (void *)CONFIG_SYS_MP_OFFSET; + + if ( cpu >= CONFIG_MP_MAX_CPUS ) + return; + + mpd->cpu_table[cpu].entry_point = entry_point; + mpd->cpu_table[cpu].stack = stack; + mpd->cpu_table[cpu].arg0 = arg0; + mpd->cpu_table[cpu].arg1 = arg1; + + debug("boot_mp_cpu_setup(%d): ep=0x%x stack=0x%x, arg=[0x%x,0x%x]\n", + cpu, entry_point, stack, arg0, arg1); +} + +/* In a RTEMS AMP system all CPUs have different entry points and stacks, + * the addresses are taken from the environment variables: + * cpu0_entry and cpu0_stack + */ +void boot_mp_rtems_setup(void) +{ + char *str; + char env_str[16]; + int cpu; + unsigned int entry, stack; + + for(cpu=0; cpu<CONFIG_MP_MAX_CPUS; cpu++) { + + entry = 0; + stack = 0; + + strcpy(env_str, "cpuX_entry"); + env_str[3] = '0' + cpu; + if ( (str = getenv(env_str)) != NULL ) { + entry = simple_strtoul(str, NULL, 16); + } + + strcpy(env_str, "cpuX_stack"); + env_str[3] = '0' + cpu; + if ( (str = getenv(env_str)) != NULL ) { + stack = simple_strtoul(str, NULL, 16); + } + + boot_mp_cpu_setup( + cpu, + (unsigned int)entry, + (unsigned int)stack, + NULL, + NULL); + } +} + +/* Prepare boot, called from bootm */ +void arch_preboot_os(int os) +{ + boot_mp_os_setup(os); + + if ( os == IH_OS_RTEMS ) + boot_mp_rtems_setup(); +} + +#endif diff --git a/arch/sparc/lib/bootm.c b/arch/sparc/lib/bootm.c index f517325..3d25bf7 100644 --- a/arch/sparc/lib/bootm.c +++ b/arch/sparc/lib/bootm.c @@ -28,11 +28,12 @@ #include <asm/prom.h> #include <asm/cache.h> #include <image.h> +#include <asm/boot_mp.h> #define PRINT_KERNEL_HEADER extern image_header_t header; -extern void srmmu_init_cpu(unsigned int entry); +extern void srmmu_init(unsigned int entry); extern void prepare_bootargs(char *bootargs); /* sparc kernel argument (the ROM vector) */ @@ -43,7 +44,8 @@ struct linux_romvec *kernel_arg_promvec; #define RAMDISK_IMAGE_START_MASK 0x07FF #define RAMDISK_PROMPT_FLAG 0x8000 #define RAMDISK_LOAD_FLAG 0x4000 -struct __attribute__ ((packed)) { +/* Linux Single CPU Header */ +struct linux_up_hdr { char traptable[PAGE_SIZE]; char swapper_pg_dir[PAGE_SIZE]; char pg0[PAGE_SIZE]; @@ -73,7 +75,13 @@ struct __attribute__ ((packed)) { unsigned int end; } ver_0203; } hdr_input; -} *linux_hdr; +} __attribute__ ((packed)) ; + +/* Linux SMP Header */ +struct linux_smp_hdr { + char traptable[3][PAGE_SIZE]; + struct linux_up_hdr single_hdr; +} __attribute__ ((packed)); /* temporary initrd image holder */ image_header_t ihdr; @@ -98,23 +106,34 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t * images) void (*kernel) (struct linux_romvec *, void *); struct lmb *lmb = &images->lmb; int ret; + int i; + struct linux_up_hdr *linux_hdr; + struct linux_smp_hdr *linux_smp_hdr; if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) return 1; - /* Get virtual address of kernel start */ - linux_hdr = (void *)images->os.load; - - /* */ + /* Kernel Entry Point */ kernel = (void (*)(struct linux_romvec *, void *))images->ep; + /* Get virtual address of kernel start */ + linux_hdr = (struct linux_up_hdr *)images->os.load; + /* check for a SPARC kernel */ if ((linux_hdr->hdr[0] != 'H') || (linux_hdr->hdr[1] != 'd') || (linux_hdr->hdr[2] != 'r') || (linux_hdr->hdr[3] != 'S')) { - puts("Error reading header of SPARC Linux kernel, aborting\n"); - goto error; + /* Not a valid Linux Header, check if Linux SMP header */ + linux_smp_hdr = (struct linux_smp_hdr *)images->os.load; + linux_hdr = (struct linux_up_hdr *)&linux_smp_hdr->single_hdr; + if ((linux_hdr->hdr[0] != 'H') || + (linux_hdr->hdr[1] != 'd') || + (linux_hdr->hdr[2] != 'r') || (linux_hdr->hdr[3] != 'S')) { + puts("Error reading header of SPARC Linux kernel, aborting\n"); + goto error; + } } + #ifdef PRINT_KERNEL_HEADER printf("## Found SPARC Linux kernel %d.%d.%d ...\n", linux_hdr->linuxver_major, @@ -164,8 +183,24 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t * images) bootargs = getenv("bootargs"); prepare_bootargs(bootargs); - /* turn on mmu & setup context table & page table for process 0 (kernel) */ - srmmu_init_cpu((unsigned int)kernel); + /* Init MMU table of SRMMU and more */ + srmmu_init((unsigned int)kernel); + +#ifdef CONFIG_MP + for(i=0; i<CONFIG_MP_MAX_CPUS; i++) { + boot_mp_cpu_setup( + i, + (unsigned int)kernel, + (unsigned int)CONFIG_SYS_INIT_SP_OFFSET, + kernel_arg_promvec, + NULL); + } +#endif + + /* turn on mmu & setup context table & page table for process 0 (kernel). + * This function is later called by each CPU in a multiprocessor system. + */ + boot_mp_linux_cpu_preinit(0); /* Enter SPARC Linux kernel * From now on the only code in u-boot that will be diff --git a/board/gaisler/gr_cpci_ax2000/u-boot.lds b/board/gaisler/gr_cpci_ax2000/u-boot.lds index 2282682..4f116a1 100644 --- a/board/gaisler/gr_cpci_ax2000/u-boot.lds +++ b/board/gaisler/gr_cpci_ax2000/u-boot.lds @@ -72,6 +72,13 @@ SECTIONS *(.prom.text) . = ALIGN(16); __prom_end = .; + /* Align MP section to the same as the MAX size of the MP section */ + . = ALIGN(512); + __mp_start = .; + *(.mp.data) + *(.mp.text) + . = ALIGN(16); + __mp_end = .; *(.text) *(.fixup) *(.gnu.warning) diff --git a/board/gaisler/gr_ep2s60/u-boot.lds b/board/gaisler/gr_ep2s60/u-boot.lds index 0ca2651..7c2d82c 100644 --- a/board/gaisler/gr_ep2s60/u-boot.lds +++ b/board/gaisler/gr_ep2s60/u-boot.lds @@ -72,6 +72,13 @@ SECTIONS *(.prom.text) . = ALIGN(16); __prom_end = .; + /* Align MP section to the same as the MAX size of the MP section */ + . = ALIGN(512); + __mp_start = .; + *(.mp.data) + *(.mp.text) + . = ALIGN(16); + __mp_end = .; *(.text) *(.fixup) *(.gnu.warning) diff --git a/board/gaisler/gr_xc3s_1500/u-boot.lds b/board/gaisler/gr_xc3s_1500/u-boot.lds index 67222ac..769df44 100644 --- a/board/gaisler/gr_xc3s_1500/u-boot.lds +++ b/board/gaisler/gr_xc3s_1500/u-boot.lds @@ -72,6 +72,13 @@ SECTIONS *(.prom.text) . = ALIGN(16); __prom_end = .; + /* Align MP section to the same as the MAX size of the MP section */ + . = ALIGN(512); + __mp_start = .; + *(.mp.data) + *(.mp.text) + . = ALIGN(16); + __mp_end = .; *(.text) *(.fixup) *(.gnu.warning) diff --git a/board/gaisler/grsim/u-boot.lds b/board/gaisler/grsim/u-boot.lds index 681fd8d..c25d533 100644 --- a/board/gaisler/grsim/u-boot.lds +++ b/board/gaisler/grsim/u-boot.lds @@ -71,6 +71,13 @@ SECTIONS *(.prom.text) . = ALIGN(16); __prom_end = .; + /* Align MP section to the same as the MAX size of the MP section */ + . = ALIGN(512); + __mp_start = .; + *(.mp.data) + *(.mp.text) + . = ALIGN(16); + __mp_end = .; *(.text) *(.fixup) *(.gnu.warning) diff --git a/include/configs/gr_cpci_ax2000.h b/include/configs/gr_cpci_ax2000.h index b9d45dd..a6d669d 100644 --- a/include/configs/gr_cpci_ax2000.h +++ b/include/configs/gr_cpci_ax2000.h @@ -264,8 +264,16 @@ #define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ #define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_RAM_END - CONFIG_SYS_GBL_DATA_SIZE) -#define CONFIG_SYS_PROM_SIZE (8192-CONFIG_SYS_GBL_DATA_SIZE) -#define CONFIG_SYS_PROM_OFFSET (CONFIG_SYS_GBL_DATA_OFFSET-CONFIG_SYS_PROM_SIZE) +#ifdef CONFIG_MP +#define CONFIG_SYS_MP_SIZE 512 +#define CONFIG_SYS_MP_OFFSET (CONFIG_SYS_GBL_DATA_OFFSET-CONFIG_SYS_MP_SIZE) +#else +#define CONFIG_SYS_MP_SIZE 0 +#define CONFIG_SYS_MP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET +#endif + +#define CONFIG_SYS_PROM_SIZE (8192-CONFIG_SYS_MP_SIZE-CONFIG_SYS_GBL_DATA_SIZE) +#define CONFIG_SYS_PROM_OFFSET (CONFIG_SYS_MP_OFFSET-CONFIG_SYS_PROM_SIZE) #define CONFIG_SYS_INIT_SP_OFFSET (CONFIG_SYS_PROM_OFFSET-32) #define CONFIG_SYS_STACK_SIZE (0x10000-32) diff --git a/include/configs/gr_ep2s60.h b/include/configs/gr_ep2s60.h index 6edb92c..10afca2 100644 --- a/include/configs/gr_ep2s60.h +++ b/include/configs/gr_ep2s60.h @@ -232,8 +232,16 @@ #define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ #define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_SDRAM_END - CONFIG_SYS_GBL_DATA_SIZE) -#define CONFIG_SYS_PROM_SIZE (8192-CONFIG_SYS_GBL_DATA_SIZE) -#define CONFIG_SYS_PROM_OFFSET (CONFIG_SYS_GBL_DATA_OFFSET-CONFIG_SYS_PROM_SIZE) +#ifdef CONFIG_MP +#define CONFIG_SYS_MP_SIZE 512 +#define CONFIG_SYS_MP_OFFSET (CONFIG_SYS_GBL_DATA_OFFSET-CONFIG_SYS_MP_SIZE) +#else +#define CONFIG_SYS_MP_SIZE 0 +#define CONFIG_SYS_MP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET +#endif + +#define CONFIG_SYS_PROM_SIZE (8192-CONFIG_SYS_MP_SIZE-CONFIG_SYS_GBL_DATA_SIZE) +#define CONFIG_SYS_PROM_OFFSET (CONFIG_SYS_MP_OFFSET-CONFIG_SYS_PROM_SIZE) #define CONFIG_SYS_INIT_SP_OFFSET (CONFIG_SYS_PROM_OFFSET-32) #define CONFIG_SYS_STACK_SIZE (0x10000-32) diff --git a/include/configs/gr_xc3s_1500.h b/include/configs/gr_xc3s_1500.h index 1f9dd4a..b57640a 100644 --- a/include/configs/gr_xc3s_1500.h +++ b/include/configs/gr_xc3s_1500.h @@ -54,6 +54,8 @@ #define CONFIG_DOS_PARTITION #define CONFIG_MAC_PARTITION #define CONFIG_ISO_PARTITION +#define CONFIG_MP +#define CONFIG_MP_MAX_CPUS 4 /* * Supported commands @@ -209,8 +211,16 @@ #define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ #define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_RAM_END - CONFIG_SYS_GBL_DATA_SIZE) -#define CONFIG_SYS_PROM_SIZE (8192-CONFIG_SYS_GBL_DATA_SIZE) -#define CONFIG_SYS_PROM_OFFSET (CONFIG_SYS_GBL_DATA_OFFSET-CONFIG_SYS_PROM_SIZE) +#ifdef CONFIG_MP +#define CONFIG_SYS_MP_SIZE 512 +#define CONFIG_SYS_MP_OFFSET (CONFIG_SYS_GBL_DATA_OFFSET-CONFIG_SYS_MP_SIZE) +#else +#define CONFIG_SYS_MP_SIZE 0 +#define CONFIG_SYS_MP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET +#endif + +#define CONFIG_SYS_PROM_SIZE (8192-CONFIG_SYS_MP_SIZE-CONFIG_SYS_GBL_DATA_SIZE) +#define CONFIG_SYS_PROM_OFFSET (CONFIG_SYS_MP_OFFSET-CONFIG_SYS_PROM_SIZE) #define CONFIG_SYS_INIT_SP_OFFSET (CONFIG_SYS_PROM_OFFSET-32) #define CONFIG_SYS_STACK_SIZE (0x10000-32) diff --git a/include/configs/grsim.h b/include/configs/grsim.h index f815672..9e177e6 100644 --- a/include/configs/grsim.h +++ b/include/configs/grsim.h @@ -234,8 +234,16 @@ #define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes reserved for initial data */ #define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_RAM_END - CONFIG_SYS_GBL_DATA_SIZE) -#define CONFIG_SYS_PROM_SIZE (8192-CONFIG_SYS_GBL_DATA_SIZE) -#define CONFIG_SYS_PROM_OFFSET (CONFIG_SYS_GBL_DATA_OFFSET-CONFIG_SYS_PROM_SIZE) +#ifdef CONFIG_MP +#define CONFIG_SYS_MP_SIZE 512 +#define CONFIG_SYS_MP_OFFSET (CONFIG_SYS_GBL_DATA_OFFSET-CONFIG_SYS_MP_SIZE) +#else +#define CONFIG_SYS_MP_SIZE 0 +#define CONFIG_SYS_MP_OFFSET CONFIG_SYS_GBL_DATA_OFFSET +#endif + +#define CONFIG_SYS_PROM_SIZE (8192-CONFIG_SYS_MP_SIZE-CONFIG_SYS_GBL_DATA_SIZE) +#define CONFIG_SYS_PROM_OFFSET (CONFIG_SYS_MP_OFFSET-CONFIG_SYS_PROM_SIZE) #define CONFIG_SYS_INIT_SP_OFFSET (CONFIG_SYS_PROM_OFFSET-32) #define CONFIG_SYS_STACK_SIZE (0x10000-32) -- 1.5.4 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot