--- linuz/arch/mips/brcm-boards/bcm947xx/prom.c 2004-12-03 05:56:20.000000000 +0300 +++ linux/arch/mips/brcm-boards/bcm947xx/prom.c 2006-11-10 17:27:58.312563984 +0300 @@ -1,15 +1,22 @@ /* * Early initialization code for BCM94710 boards * - * Copyright 2004, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * Copyright (C) 2004 Broadcom Corporation + * + * 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. * - * $Id$ */ #include @@ -18,24 +25,39 @@ #include #include -void __init -prom_init(int argc, const char **argv) +void __init prom_init(int argc, char **argv, char **envp, int *prom_vec) { - unsigned long mem; + unsigned long mem, before, offset; - mips_machgroup = MACH_GROUP_BRCM; - mips_machtype = MACH_BCM947XX; + mips_machgroup = MACH_GROUP_BRCM; + mips_machtype = MACH_BCM947XX; - /* Figure out memory size by finding aliases */ - for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) { - if (*(unsigned long *)((unsigned long)(prom_init) + mem) == - *(unsigned long *)(prom_init)) + /* Figure out memory size by finding aliases. + * + * We assume that there will be no more than 128 MB of memory, + * and that the memory size will be a multiple of 1 MB. + * + * We set 'before' to be the amount of memory (in MB) before this + * function, i.e. one MB less than the number of MB of memory that we + * *know* we have. And we set 'offset' to be the address of 'prominit' + * minus 'before', so that KSEG0 or KSEG1 base + offset < 1 MB. + * This prevents us from overrunning 128 MB and causing a bus error. + */ + before = ((unsigned long) &prom_init) & (127 << 20); + offset = ((unsigned long) &prom_init) - before; + for (mem = before + (1 << 20); mem < (128 << 20); mem += (1 << 20)) + if (*(unsigned long *)(offset + mem) == + *(unsigned long *)(prom_init)) { + /* + * We may already be well past the end of memory at + * this point, so we'll have to compensate for it. + */ + mem -= before; break; - } + } add_memory_region(0, mem, BOOT_MEM_RAM); } -void __init -prom_free_prom_memory(void) +void __init prom_free_prom_memory(void) { }