LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* " Problem in copying files into /mnt/jffs2 directory "
From: nreddy @ 2005-10-06  9:17 UTC (permalink / raw)
  To: linuxppc-embedded; +Cc: u-boot-users

Hi All,

I am working on PPC405ep (walnut board) board which has 4MB AMD flash and
working fine .
Recently we have increased FLASH size to 8MB and modified Flash drivers
accordingly.
I have taken some help from uboot users.
Thanks for giving such kind of invaluable help.

Now the system is up and running well, but i get into some other problem
like when copying files to /mnt/jffs2 directory it is taking so much extra
time to copy files.
But when i was using 4MB flash it was taking 1/4 of this time.

Can some one throw a lite on this.

Thanks & Regards,
--Nagi

^ permalink raw reply

* Re: kernel.org's kernel: building and root file system
From: Johannes Geissel @ 2005-10-06  5:57 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <OFAF025B3B.4E7DEDE8-ON48257092.0018E543@uk.marconicomms.com>

Am Donnerstag, 6. Oktober 2005 06:53 schrieb KokHow Teh:
> Hi;
>       I am new to this and I have some questions of "what's next?" after
> having downloaded the latest kernel from kernel.org:
>
> (1)   Since I am going to build the kernel for PPC platform and
> architecture, running `make xconfig` won't bring up the right set of
> configurations for your target but the default which is a generic X86
> architecture and platform. What is the usual step so that I will have the
> configuration set for my target? I think of 2:
>
>       (i) copy arch/ppc/configs/<foo>_defconfig to $SRC_BASE/.config; `make
> xconfig`
Don't copy anything, just do a make <foo>_config. Before that you have 
to do export CROSS_COMPILE=ppc_xxx-

>       (ii) `make xconfig`; and inside the X-window, open the
> arch/ppc/configs/<foo>_defconfig and save it for your architecture.
>
>       I tried (ii) but after having opened the <foo>_defconfig, it is not
> reflected at all in the X-window. It is still showing the default
> configurations.
>
> (2)   Ok, you have the kernel running on your PPC target. How about the
> root file system? Where and how can I have/build a generic root file system
> that works with kernels running from kernel.org?
>
> (3)   Toolchain. What cross-toolchain is generally used to build the kernel
> for your target? For PPC, I come across this
> http://penguinppc.org/dev/crosstool.php... Is that popularly used to build
> kernel from kernel.org for PPC architecture and platform?
I'm using ELDK from www.denx.de and also a linuxppc_2_4_devel kernel
from there.

>
>       Thanks for any comment and insight.
>
> Regards,
> TEH
>
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded

^ permalink raw reply

* Re: kernel.org's kernel: building and root file system
From: Wolfgang Denk @ 2005-10-06  7:26 UTC (permalink / raw)
  To: KokHow Teh; +Cc: linuxppc-embedded list <linuxppc-embedded
In-Reply-To: <OFAF025B3B.4E7DEDE8-ON48257092.0018E543@uk.marconicomms.com>

In message <OFAF025B3B.4E7DEDE8-ON48257092.0018E543@uk.marconicomms.com> you wrote:
> 
>       I am new to this and I have some questions of "what's next?" after
> having downloaded the latest kernel from kernel.org:

Have a look at the DULG - http://www.denx.de/twiki/bin/view/DULG/Manual

It covers most of your questions.

Best regards,

Wolfgang Denk

-- 
Software Engineering:  Embedded and Realtime Systems,  Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Harrison's Postulate:
	For every action, there is an equal and opposite criticism.

^ permalink raw reply

* kernel.org's kernel: building and root file system
From: KokHow Teh @ 2005-10-06  4:53 UTC (permalink / raw)
  To: Vitaly Bordug <vbordug; +Cc: linuxppc-embedded list <linuxppc-embedded


Hi;
      I am new to this and I have some questions of "what's next?" after
having downloaded the latest kernel from kernel.org:

(1)   Since I am going to build the kernel for PPC platform and
architecture, running `make xconfig` won't bring up the right set of
configurations for your target but the default which is a generic X86
architecture and platform. What is the usual step so that I will have the
configuration set for my target? I think of 2:

      (i) copy arch/ppc/configs/<foo>_defconfig to $SRC_BASE/.config; `make
xconfig`
      (ii) `make xconfig`; and inside the X-window, open the
arch/ppc/configs/<foo>_defconfig and save it for your architecture.

      I tried (ii) but after having opened the <foo>_defconfig, it is not
reflected at all in the X-window. It is still showing the default
configurations.

(2)   Ok, you have the kernel running on your PPC target. How about the
root file system? Where and how can I have/build a generic root file system
that works with kernels running from kernel.org?

(3)   Toolchain. What cross-toolchain is generally used to build the kernel
for your target? For PPC, I come across this
http://penguinppc.org/dev/crosstool.php... Is that popularly used to build
kernel from kernel.org for PPC architecture and platform?

      Thanks for any comment and insight.

Regards,
TEH

^ permalink raw reply

* problems with dma_alloc_coherent and consistent_alloc
From: Earl Olsen @ 2005-10-05 21:21 UTC (permalink / raw)
  To: linuxppc-embedded

[-- Attachment #1: Type: text/plain, Size: 1740 bytes --]


(Sorry, I had trouble outlook and messed up the subject line)

We are using a PPC 750 with 512m of RAM.  

1) When we try to allocate memory using consistent_alloc we get a 
failure with get_pteptr - there is no pte.  

2) When we try using dma_alloc_coherent the system locks up when
we try to access that memory.

I'm guessing these problems stem from the memory being allocated
is from the 384 bytes of RAM that gets handed over to BATs 2 AND 3,
not the remaining memory handled by the page table.

In the first case, pages are allocated, but since if came from the
BAT region, will not have a page table mapping.

In the second case, if dma_alloc_init gets memory from the BAT
region, then we have the BAT and page management mechanisms
both trying to control the memory.

Does this sound like a good theory?  Has anybody encountered
this problem before?

Thanks

--
Earl Olsen
Senior Software Engineer
Dilithium Networks, Inc.
TEL:+1 707-792-3925
earl.olsen@dilithiumnetworks.com
www.dilithiumnetworks.com

Communications for a Borderless World

This electronic message from Dilithium Networks contains information
which may be privileged or confidential. It is intended to be for the
use of the recipient(s) named above. If you are not the intended
recipient please return the message to the sender by replying to it and
then delete the message from your computer. Dilithium Networks shall not
be held liable to any person resulting from the use of any information
contained in this e-mail and shall not be liable to any person who acts
or omits to do anything in reliance upon it. Dilithium Networks does not
accept responsibility for changes made to this message after it was
sent.


[-- Attachment #2: Type: text/html, Size: 3527 bytes --]

^ permalink raw reply

* We are using a PPC 750 with 512m of RAM.
From: Earl Olsen @ 2005-10-05 21:18 UTC (permalink / raw)
  To: linuxppc-embedded

[-- Attachment #1: Type: text/plain, Size: 1675 bytes --]


We are using a PPC 750 with 512m of RAM.  

1) When we try to allocate memory using consistent_alloc we get a 
failure with get_pteptr - there is no pte.  

2) When we try using dma_alloc_coherent the system locks up when
we try to access that memory.

I'm guessing these problems stem from the memory being allocated
is from the 384 bytes of RAM that gets handed over to BATs 2 AND 3,
not the remaining memory handled by the page table.

In the first case, pages are allocated, but since if came from the
BAT region, will not have a page table mapping.

In the second case, if dma_alloc_init gets memory from the BAT
region, then we have the BAT and page management mechanisms
both trying to control the memory.

Does this sound like a good theory?  Has anybody encountered
this problem before?

Thanks

--
Earl Olsen
Senior Software Engineer
Dilithium Networks, Inc.
TEL:+1 707-792-3925
earl.olsen@dilithiumnetworks.com
www.dilithiumnetworks.com

Communications for a Borderless World

This electronic message from Dilithium Networks contains information
which may be privileged or confidential. It is intended to be for the
use of the recipient(s) named above. If you are not the intended
recipient please return the message to the sender by replying to it and
then delete the message from your computer. Dilithium Networks shall not
be held liable to any person resulting from the use of any information
contained in this e-mail and shall not be liable to any person who acts
or omits to do anything in reliance upon it. Dilithium Networks does not
accept responsibility for changes made to this message after it was
sent.


[-- Attachment #2: Type: text/html, Size: 3402 bytes --]

^ permalink raw reply

* [PATCH] powerpc: improved byte swapping functions
From: Gabriel Paubert @ 2005-10-05 18:20 UTC (permalink / raw)
  To: Becky Bruce; +Cc: linuxppc64-dev, linuxppc-dev
In-Reply-To: <20050927211534.GA32173@iram.es>


From: Gabriel Paubert <paubert@iram.es>

The previous versions of ___arch__swab16 and ___arch__swab32 were
not optimal. In most cases the code can be made shorter and faster
with this patch.

Signed-off-by: Gabriel Paubert <paubert@iram.es>

---

Additional notes: 

1) for ___arch__swab16, the trick is to let the compiler 
generate a single rlwinm instruction for the final right 
shift and cast. 

2) For ___arch_swab32, the rotated value passed as a parameter 
already has 2 bytes at the right place, so only 2 rlwimi 
instructions are necessary to complete the byte swap.

3) edit if you don't like the formatting of the result.

4) I've been reading the thread about how to format patches
and I hope that I got it right. But I believe that the
diffstat output is overkill for such a small patch.

	Regards,
	Gabriel

diff --git a/include/asm-powerpc/byteorder.h b/include/asm-powerpc/byteorder.h
--- a/include/asm-powerpc/byteorder.h
+++ b/include/asm-powerpc/byteorder.h
@@ -42,23 +42,22 @@ static __inline__ void st_le32(volatile 
 
 static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value)
 {
-	__u16 result;
+	__u32 tmp;
 
-	__asm__("rlwimi %0,%1,8,16,23"
-	    : "=r" (result)
-	    : "r" (value), "0" (value >> 8));
-	return result;
+	__asm__("rlwimi %0,%0,16,8,15"
+		: "=r" (tmp) : "0" (value));
+	return (__u16)(tmp>>8);
 }
 
 static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value)
 {
 	__u32 result;
 
-	__asm__("rlwimi %0,%1,24,16,23\n\t"
-	    "rlwimi %0,%1,8,8,15\n\t"
-	    "rlwimi %0,%1,24,0,7"
+	__asm__(
+"	rlwimi %0,%1,24,16,23\n"
+"	rlwimi %0,%1,24,0,7\n"
 	    : "=r" (result)
-	    : "r" (value), "0" (value >> 24));
+	    : "r" (value), "0" ((value >> 24)|(value<<8)));
 	return result;
 }
 

^ permalink raw reply

* Re: serial console
From: Vitaly Bordug @ 2005-10-05 12:23 UTC (permalink / raw)
  To: KokHow Teh; +Cc: david.jander, linuxppc-embedded list
In-Reply-To: <OF0BB1D8FC.27908478-ON48257091.000E28F8@uk.marconicomms.com>

KokHow Teh wrote:
> Hi;
>       I have tried with 4 types of command lines with my linux kernel with
> devfs and serial device compiled in and none gives me the desired results:
> 
> (1)   console=tts/0,115200n8 OR console=ttyCPM0,115200n8
> 
>       no serial console output at all during boot time but it gives me
> login prompt at the end.
> 
> (2)   without "console=" OR console=ttyS0,115200n8
> 
>       serial console output fine during bootup but only until the point
> when it prints out "Freeing unused kernel memory: 232k init 4k prep". After
> that, the serial console output is garbled. No login prompt.
> 
>       So this has not solved my problem. I need more advice. Here are some
> more questions and observations:
> 
> (1)   David Jander's comment:
> 
> I don't know exactly what I am talking about right now, but the string
> "tts/0"
> in the console-line sounds suspicious to me. AFAIK when using devfs still
> device names on the kernel-commandline have to be old-style.
> Just a guess: try using "console=ttyS0,115200n8" and see if this helps.
> 
>       Is it confirmed that kernel-commandline has to be old-style even
> though the kernel is using devfs?
> 
> (2)   Vitaly Bordug's suggestion of using "console=ttyCPM0". May I know
> where is ttyCPM0 defined and how is it bound to the serial console device
> driver in the source?
> 
Ummm.. The driver itself is in drivers/serial/cpm_uart. It does have the 
different major than ordinary ttyS... This relates to the 2.6.x kernel 
of course. I could suggest you to try the latest kernel.org release, in 
which you board is known to work fine.

>       Thanks for any input and pointer.
> 
> Regards,
> TEH
> 
> 
> 


-- 
Sincerely,
Vitaly

^ permalink raw reply

* Re: serial console
From: David Jander @ 2005-10-05  9:16 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <43429CBA.6050906@ru.mvista.com>

On Tuesday 04 October 2005 17:16, Vitaly Bordug wrote:
> Yes, but PQ2FADS use cpm_uart and hence the commandline should be
> console=ttyCPM0,115200

You are totally right. I did that same mistake once in the past and again now. 
Shame on me ;-)
Now that I remeber, this might give trouble if you happen to use a normal uart 
(16550 or similar) also, and devfs. I had to slightly hack serial.c in my 
version of the kernel for this combination to work. I don't remeber right now 
exactly what I did, but it had to do with "SERIAL_DEV_OFFSET" and major/minor 
numbers ;-)
Anyway, I don't think your board has this combination.

Greetings,

-- 
David Jander

^ permalink raw reply

* [PATCH] ppc: Fix timekeeping with HZ=250 on some Mac models
From: Benjamin Herrenschmidt @ 2005-10-05  7:43 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linuxppc-dev list

Older Macs which uses the VIA chip timers to calibrate the timebase used
some code that wouldn't work if HZ wasn't divisible by 100... This fixes
it at least for 250. Not totally perfect but should be enough for now
(so it at least works with the default value which is now 250). There is
still a potential issue with the core using CLOCK_TICK_RATE to maintain
xtime and CLOCK_TICK_RATE value on ppc32 is pure crap, but that is a
different problem, this patch at least brings us back to our previous
situation.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Index: linux-work/arch/ppc/platforms/pmac_time.c
===================================================================
--- linux-work.orig/arch/ppc/platforms/pmac_time.c	2005-09-22 14:06:18.000000000 +1000
+++ linux-work/arch/ppc/platforms/pmac_time.c	2005-10-05 08:14:17.000000000 +1000
@@ -195,7 +195,7 @@
 		;
 	dend = get_dec();
 
-	tb_ticks_per_jiffy = (dstart - dend) / (6 * (HZ/100));
+	tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100);
 	tb_to_us = mulhwu_scale_factor(dstart - dend, 60000);
 
 	printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n",

^ permalink raw reply

* Re: clock skew on B/W G3
From: Marc @ 2005-10-05  6:34 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <1128464094.6417.31.camel@gaston>


Hi Ben,=20

Le Mittwoch 05 Oktober 2005 00:14, Benjamin Herrenschmidt a =C3=A9crit :
> The problem is indeed in via_calibrate_decr(). This routine works on
> HZ/100 so it will not do any good with HZ not beeing a multiple of 100.
>
> Can you test this patch ?

I can confirm that this patch solves the timer skew on my mac.

Thanks!

>
> Index: linux-work/arch/ppc/platforms/pmac_time.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> --- linux-work.orig/arch/ppc/platforms/pmac_time.c	2005-09-22
> 14:06:18.000000000 +1000 +++
> linux-work/arch/ppc/platforms/pmac_time.c	2005-10-05 08:14:17.000000000
> +1000 @@ -195,7 +195,7 @@
>  		;
>  	dend =3D get_dec();
>
> -	tb_ticks_per_jiffy =3D (dstart - dend) / (6 * (HZ/100));
> +	tb_ticks_per_jiffy =3D (dstart - dend) / ((6 * HZ)/100);
>  	tb_to_us =3D mulhwu_scale_factor(dstart - dend, 60000);
>
>  	printk(KERN_INFO "via_calibrate_decr: ticks per jiffy =3D %u (%u ticks)=
\n",
>
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply

* Re: PATCH powerpc Move LMB from ppc64 to powerpc
From: Kumar Gala @ 2005-10-05  5:17 UTC (permalink / raw)
  To: Loeliger Jon-LOELIGER; +Cc: linuxppc-dev, linuxppc64-dev
In-Reply-To: <1128463190.22452.29.camel@cashmere.sps.mot.com>

Jon,

Look good.  As your removing the use of mem_pieces from arch/powerpc,  
we should see if the LMB data structures can always have 64-bit  
addresses.  The reason for this is to handle the > 32-bit address  
case on ppc32.  Anyways, something to keep in the back of your mind  
while looking at this code.

- kumar

On Oct 4, 2005, at 4:59 PM, Loeliger Jon-LOELIGER wrote:

> Move the LMB code from ppc64 to powerpc.
> Only compile ppc32's tlb.c code on "standard" mmu machines.
>
> Signed-off-by: Jon Loeliger <jdl@freescale.com>
> ---
>
>  arch/powerpc/mm/Makefile   |    8 +
>  arch/powerpc/mm/lmb.c      |  303
> ++++++++++++++++++++++++++++++++++++++++++++
>  arch/ppc64/kernel/Makefile |    1
>  arch/ppc64/kernel/lmb.c    |  299
> -------------------------------------------
>  include/asm-powerpc/lmb.h  |   78 +++++++++++
>  include/asm-ppc/page.h     |    6 +
>  6 files changed, 391 insertions(+), 304 deletions(-)
>
>
> diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
> --- a/arch/powerpc/mm/Makefile
> +++ b/arch/powerpc/mm/Makefile
> @@ -2,11 +2,11 @@
>  # Makefile for the linux ppc-specific parts of the memory manager.
>  #
>
> -obj-y                := fault.o mem.o
> -obj-$(CONFIG_PPC32)        += init.o pgtable.o mmu_context.o \
> -                   mem_pieces.o tlb.o
> +obj-y                := fault.o lmb.o mem.o
> +
> +obj-$(CONFIG_PPC32)        += init.o pgtable.o mmu_context.o
> mem_pieces.o
>  obj-$(CONFIG_PPC64)        += init64.o pgtable64.o mmu_context64.o
> -obj-$(CONFIG_PPC_STD_MMU_32)    += ppc_mmu.o hash_32.o
> +obj-$(CONFIG_PPC_STD_MMU_32)    += ppc_mmu.o hash_32.o tlb.o
>  obj-$(CONFIG_40x)        += 4xx_mmu.o
>  obj-$(CONFIG_44x)        += 44x_mmu.o
>  obj-$(CONFIG_FSL_BOOKE)        += fsl_booke_mmu.o
> diff --git a/arch/powerpc/mm/lmb.c b/arch/powerpc/mm/lmb.c
> new file mode 100644
> --- /dev/null
> +++ b/arch/powerpc/mm/lmb.c
> @@ -0,0 +1,303 @@
> +/*
> + * Procedures for interfacing to Open Firmware.
> + *
> + * Peter Bergner, IBM Corp.    June 2001.
> + * Copyright (C) 2001 Peter Bergner.
> + *
> + *      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.
> + */
> +
> +#include <linux/config.h>
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/bitops.h>
> +#include <asm/types.h>
> +#include <asm/page.h>
> +#include <asm/prom.h>
> +#include <asm/lmb.h>
> +
> +struct lmb lmb;
> +
> +#undef DEBUG
> +
> +void lmb_dump_all(void)
> +{
> +#ifdef DEBUG
> +    unsigned long i;
> +
> +    udbg_printf("lmb_dump_all:\n");
> +    udbg_printf("    memory.cnt          = 0x%lx\n",
> +            lmb.memory.cnt);
> +    udbg_printf("    memory.size          = 0x%lx\n",
> +            lmb.memory.size);
> +    for (i=0; i < lmb.memory.cnt ;i++) {
> +        udbg_printf("    memory.region[0x%x].base       =
> 0x%lx\n",
> +                i, lmb.memory.region[i].base);
> +        udbg_printf("              .size     = 0x%lx\n",
> +                lmb.memory.region[i].size);
> +    }
> +
> +    udbg_printf("\n    reserved.cnt      = 0x%lx\n",
> +            lmb.reserved.cnt);
> +    udbg_printf("    reserved.size      = 0x%lx\n",
> +            lmb.reserved.size);
> +    for (i=0; i < lmb.reserved.cnt ;i++) {
> +        udbg_printf("    reserved.region[0x%x].base       =
> 0x%lx\n",
> +                i, lmb.reserved.region[i].base);
> +        udbg_printf("              .size     = 0x%lx\n",
> +                lmb.reserved.region[i].size);
> +    }
> +#endif /* DEBUG */
> +}
> +
> +static unsigned long __init
> +lmb_addrs_overlap(unsigned long base1, unsigned long size1,
> +                  unsigned long base2, unsigned long size2)
> +{
> +    return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
> +}
> +
> +static long __init
> +lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
> +           unsigned long base2, unsigned long size2)
> +{
> +    if (base2 == base1 + size1)
> +        return 1;
> +    else if (base1 == base2 + size2)
> +        return -1;
> +
> +    return 0;
> +}
> +
> +static long __init
> +lmb_regions_adjacent(struct lmb_region *rgn,
> +             unsigned long r1, unsigned long r2)
> +{
> +    unsigned long base1 = rgn->region[r1].base;
> +    unsigned long size1 = rgn->region[r1].size;
> +    unsigned long base2 = rgn->region[r2].base;
> +    unsigned long size2 = rgn->region[r2].size;
> +
> +    return lmb_addrs_adjacent(base1, size1, base2, size2);
> +}
> +
> +/* Assumption: base addr of region 1 < base addr of region 2 */
> +static void __init
> +lmb_coalesce_regions(struct lmb_region *rgn,
> +             unsigned long r1, unsigned long r2)
> +{
> +    unsigned long i;
> +
> +    rgn->region[r1].size += rgn->region[r2].size;
> +    for (i=r2; i < rgn->cnt-1; i++) {
> +        rgn->region[i].base = rgn->region[i+1].base;
> +        rgn->region[i].size = rgn->region[i+1].size;
> +    }
> +    rgn->cnt--;
> +}
> +
> +/* This routine called with relocation disabled. */
> +void __init
> +lmb_init(void)
> +{
> +    /* Create a dummy zero size LMB which will get coalesced away
> later.
> +     * This simplifies the lmb_add() code below...
> +     */
> +    lmb.memory.region[0].base = 0;
> +    lmb.memory.region[0].size = 0;
> +    lmb.memory.cnt = 1;
> +
> +    /* Ditto. */
> +    lmb.reserved.region[0].base = 0;
> +    lmb.reserved.region[0].size = 0;
> +    lmb.reserved.cnt = 1;
> +}
> +
> +/* This routine called with relocation disabled. */
> +void __init
> +lmb_analyze(void)
> +{
> +    int i;
> +
> +    lmb.memory.size = 0;
> +
> +    for (i = 0; i < lmb.memory.cnt; i++)
> +        lmb.memory.size += lmb.memory.region[i].size;
> +}
> +
> +/* This routine called with relocation disabled. */
> +static long __init
> +lmb_add_region(struct lmb_region *rgn, unsigned long base, unsigned
> long size)
> +{
> +    unsigned long i, coalesced = 0;
> +    long adjacent;
> +
> +    /* First try and coalesce this LMB with another. */
> +    for (i=0; i < rgn->cnt; i++) {
> +        unsigned long rgnbase = rgn->region[i].base;
> +        unsigned long rgnsize = rgn->region[i].size;
> +
> +        adjacent =
> lmb_addrs_adjacent(base,size,rgnbase,rgnsize);
> +        if ( adjacent > 0 ) {
> +            rgn->region[i].base -= size;
> +            rgn->region[i].size += size;
> +            coalesced++;
> +            break;
> +        }
> +        else if ( adjacent < 0 ) {
> +            rgn->region[i].size += size;
> +            coalesced++;
> +            break;
> +        }
> +    }
> +
> +    if ((i < rgn->cnt-1) && lmb_regions_adjacent(rgn, i, i+1) ) {
> +        lmb_coalesce_regions(rgn, i, i+1);
> +        coalesced++;
> +    }
> +
> +    if ( coalesced ) {
> +        return coalesced;
> +    } else if ( rgn->cnt >= MAX_LMB_REGIONS ) {
> +        return -1;
> +    }
> +
> +    /* Couldn't coalesce the LMB, so add it to the sorted table. */
> +    for (i=rgn->cnt-1; i >= 0; i--) {
> +        if (base < rgn->region[i].base) {
> +            rgn->region[i+1].base = rgn->region[i].base;
> +            rgn->region[i+1].size = rgn->region[i].size;
> +        }  else {
> +            rgn->region[i+1].base = base;
> +            rgn->region[i+1].size = size;
> +            break;
> +        }
> +    }
> +    rgn->cnt++;
> +
> +    return 0;
> +}
> +
> +/* This routine called with relocation disabled. */
> +long __init
> +lmb_add(unsigned long base, unsigned long size)
> +{
> +    struct lmb_region *_rgn = &(lmb.memory);
> +
> +    /* On pSeries LPAR systems, the first LMB is our RMO region. */
> +    if ( base == 0 )
> +        lmb.rmo_size = size;
> +
> +    return lmb_add_region(_rgn, base, size);
> +
> +}
> +
> +long __init
> +lmb_reserve(unsigned long base, unsigned long size)
> +{
> +    struct lmb_region *_rgn = &(lmb.reserved);
> +
> +    return lmb_add_region(_rgn, base, size);
> +}
> +
> +long __init
> +lmb_overlaps_region(struct lmb_region *rgn,
> +            unsigned long base, unsigned long size)
> +{
> +    unsigned long i;
> +
> +    for (i=0; i < rgn->cnt; i++) {
> +        unsigned long rgnbase = rgn->region[i].base;
> +        unsigned long rgnsize = rgn->region[i].size;
> +        if ( lmb_addrs_overlap(base,size,rgnbase,rgnsize) ) {
> +            break;
> +        }
> +    }
> +
> +    return (i < rgn->cnt) ? i : -1;
> +}
> +
> +unsigned long __init
> +lmb_alloc(unsigned long size, unsigned long align)
> +{
> +    return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE);
> +}
> +
> +unsigned long __init
> +lmb_alloc_base(unsigned long size, unsigned long align, unsigned long
> max_addr)
> +{
> +    long i, j;
> +    unsigned long base = 0;
> +
> +    for (i=lmb.memory.cnt-1; i >= 0; i--) {
> +        unsigned long lmbbase = lmb.memory.region[i].base;
> +        unsigned long lmbsize = lmb.memory.region[i].size;
> +
> +        if ( max_addr == LMB_ALLOC_ANYWHERE )
> +            base = _ALIGN_DOWN(lmbbase+lmbsize-size, align);
> +        else if ( lmbbase < max_addr )
> +            base =
> _ALIGN_DOWN(min(lmbbase+lmbsize,max_addr)-size,
> +                       align);
> +        else
> +            continue;
> +
> +        while ( (lmbbase <= base) &&
> +            ((j =
> lmb_overlaps_region(&lmb.reserved,base,size)) >= 0) ) {
> +            base =
> _ALIGN_DOWN(lmb.reserved.region[j].base-size,
> +                       align);
> +        }
> +
> +        if ( (base != 0) && (lmbbase <= base) )
> +            break;
> +    }
> +
> +    if ( i < 0 )
> +        return 0;
> +
> +    lmb_add_region(&lmb.reserved, base, size);
> +
> +    return base;
> +}
> +
> +/* You must call lmb_analyze() before this. */
> +unsigned long __init
> +lmb_phys_mem_size(void)
> +{
> +    return lmb.memory.size;
> +}
> +
> +unsigned long __init
> +lmb_end_of_DRAM(void)
> +{
> +    int idx = lmb.memory.cnt - 1;
> +
> +    return (lmb.memory.region[idx].base +
> lmb.memory.region[idx].size);
> +}
> +
> +/*
> + * Truncate the lmb list to memory_limit if it's set
> + * You must call lmb_analyze() after this.
> + */
> +void __init lmb_enforce_memory_limit(void)
> +{
> +    extern unsigned long memory_limit;
> +    unsigned long i, limit;
> +
> +    if (! memory_limit)
> +        return;
> +
> +    limit = memory_limit;
> +    for (i = 0; i < lmb.memory.cnt; i++) {
> +        if (limit > lmb.memory.region[i].size) {
> +            limit -= lmb.memory.region[i].size;
> +            continue;
> +        }
> +
> +        lmb.memory.region[i].size = limit;
> +        lmb.memory.cnt = i + 1;
> +        break;
> +    }
> +}
> diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
> --- a/arch/ppc64/kernel/Makefile
> +++ b/arch/ppc64/kernel/Makefile
> @@ -76,3 +76,4 @@ endif
>
>  # These are here while we do the architecture merge
>  vecemu-y            += ../../powerpc/kernel/vecemu.o
> +lmb-y                += ../../powerpc/mm/lmb.o
> diff --git a/arch/ppc64/kernel/lmb.c b/arch/ppc64/kernel/lmb.c
> deleted file mode 100644
> --- a/arch/ppc64/kernel/lmb.c
> +++ /dev/null
> @@ -1,299 +0,0 @@
> -/*
> - * Procedures for interfacing to Open Firmware.
> - *
> - * Peter Bergner, IBM Corp.    June 2001.
> - * Copyright (C) 2001 Peter Bergner.
> - *
> - *      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.
> - */
> -
> -#include <linux/config.h>
> -#include <linux/kernel.h>
> -#include <linux/init.h>
> -#include <linux/bitops.h>
> -#include <asm/types.h>
> -#include <asm/page.h>
> -#include <asm/prom.h>
> -#include <asm/lmb.h>
> -#include <asm/abs_addr.h>
> -
> -struct lmb lmb;
> -
> -#undef DEBUG
> -
> -void lmb_dump_all(void)
> -{
> -#ifdef DEBUG
> -    unsigned long i;
> -
> -    udbg_printf("lmb_dump_all:\n");
> -    udbg_printf("    memory.cnt          = 0x%lx\n",
> -            lmb.memory.cnt);
> -    udbg_printf("    memory.size          = 0x%lx\n",
> -            lmb.memory.size);
> -    for (i=0; i < lmb.memory.cnt ;i++) {
> -        udbg_printf("    memory.region[0x%x].base       =
> 0x%lx\n",
> -                i, lmb.memory.region[i].base);
> -        udbg_printf("              .size     = 0x%lx\n",
> -                lmb.memory.region[i].size);
> -    }
> -
> -    udbg_printf("\n    reserved.cnt      = 0x%lx\n",
> -            lmb.reserved.cnt);
> -    udbg_printf("    reserved.size      = 0x%lx\n",
> -            lmb.reserved.size);
> -    for (i=0; i < lmb.reserved.cnt ;i++) {
> -        udbg_printf("    reserved.region[0x%x].base       =
> 0x%lx\n",
> -                i, lmb.reserved.region[i].base);
> -        udbg_printf("              .size     = 0x%lx\n",
> -                lmb.reserved.region[i].size);
> -    }
> -#endif /* DEBUG */
> -}
> -
> -static unsigned long __init
> -lmb_addrs_overlap(unsigned long base1, unsigned long size1,
> -                  unsigned long base2, unsigned long size2)
> -{
> -    return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
> -}
> -
> -static long __init
> -lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
> -           unsigned long base2, unsigned long size2)
> -{
> -    if (base2 == base1 + size1)
> -        return 1;
> -    else if (base1 == base2 + size2)
> -        return -1;
> -
> -    return 0;
> -}
> -
> -static long __init
> -lmb_regions_adjacent(struct lmb_region *rgn, unsigned long r1,  
> unsigned
> long r2)
> -{
> -    unsigned long base1 = rgn->region[r1].base;
> -    unsigned long size1 = rgn->region[r1].size;
> -    unsigned long base2 = rgn->region[r2].base;
> -    unsigned long size2 = rgn->region[r2].size;
> -
> -    return lmb_addrs_adjacent(base1, size1, base2, size2);
> -}
> -
> -/* Assumption: base addr of region 1 < base addr of region 2 */
> -static void __init
> -lmb_coalesce_regions(struct lmb_region *rgn, unsigned long r1,  
> unsigned
> long r2)
> -{
> -    unsigned long i;
> -
> -    rgn->region[r1].size += rgn->region[r2].size;
> -    for (i=r2; i < rgn->cnt-1; i++) {
> -        rgn->region[i].base = rgn->region[i+1].base;
> -        rgn->region[i].size = rgn->region[i+1].size;
> -    }
> -    rgn->cnt--;
> -}
> -
> -/* This routine called with relocation disabled. */
> -void __init
> -lmb_init(void)
> -{
> -    /* Create a dummy zero size LMB which will get coalesced away
> later.
> -     * This simplifies the lmb_add() code below...
> -     */
> -    lmb.memory.region[0].base = 0;
> -    lmb.memory.region[0].size = 0;
> -    lmb.memory.cnt = 1;
> -
> -    /* Ditto. */
> -    lmb.reserved.region[0].base = 0;
> -    lmb.reserved.region[0].size = 0;
> -    lmb.reserved.cnt = 1;
> -}
> -
> -/* This routine called with relocation disabled. */
> -void __init
> -lmb_analyze(void)
> -{
> -    int i;
> -
> -    lmb.memory.size = 0;
> -
> -    for (i = 0; i < lmb.memory.cnt; i++)
> -        lmb.memory.size += lmb.memory.region[i].size;
> -}
> -
> -/* This routine called with relocation disabled. */
> -static long __init
> -lmb_add_region(struct lmb_region *rgn, unsigned long base, unsigned
> long size)
> -{
> -    unsigned long i, coalesced = 0;
> -    long adjacent;
> -
> -    /* First try and coalesce this LMB with another. */
> -    for (i=0; i < rgn->cnt; i++) {
> -        unsigned long rgnbase = rgn->region[i].base;
> -        unsigned long rgnsize = rgn->region[i].size;
> -
> -        adjacent =
> lmb_addrs_adjacent(base,size,rgnbase,rgnsize);
> -        if ( adjacent > 0 ) {
> -            rgn->region[i].base -= size;
> -            rgn->region[i].size += size;
> -            coalesced++;
> -            break;
> -        }
> -        else if ( adjacent < 0 ) {
> -            rgn->region[i].size += size;
> -            coalesced++;
> -            break;
> -        }
> -    }
> -
> -    if ((i < rgn->cnt-1) && lmb_regions_adjacent(rgn, i, i+1) ) {
> -        lmb_coalesce_regions(rgn, i, i+1);
> -        coalesced++;
> -    }
> -
> -    if ( coalesced ) {
> -        return coalesced;
> -    } else if ( rgn->cnt >= MAX_LMB_REGIONS ) {
> -        return -1;
> -    }
> -
> -    /* Couldn't coalesce the LMB, so add it to the sorted table. */
> -    for (i=rgn->cnt-1; i >= 0; i--) {
> -        if (base < rgn->region[i].base) {
> -            rgn->region[i+1].base = rgn->region[i].base;
> -            rgn->region[i+1].size = rgn->region[i].size;
> -        }  else {
> -            rgn->region[i+1].base = base;
> -            rgn->region[i+1].size = size;
> -            break;
> -        }
> -    }
> -    rgn->cnt++;
> -
> -    return 0;
> -}
> -
> -/* This routine called with relocation disabled. */
> -long __init
> -lmb_add(unsigned long base, unsigned long size)
> -{
> -    struct lmb_region *_rgn = &(lmb.memory);
> -
> -    /* On pSeries LPAR systems, the first LMB is our RMO region. */
> -    if ( base == 0 )
> -        lmb.rmo_size = size;
> -
> -    return lmb_add_region(_rgn, base, size);
> -
> -}
> -
> -long __init
> -lmb_reserve(unsigned long base, unsigned long size)
> -{
> -    struct lmb_region *_rgn = &(lmb.reserved);
> -
> -    return lmb_add_region(_rgn, base, size);
> -}
> -
> -long __init
> -lmb_overlaps_region(struct lmb_region *rgn, unsigned long base,
> unsigned long size)
> -{
> -    unsigned long i;
> -
> -    for (i=0; i < rgn->cnt; i++) {
> -        unsigned long rgnbase = rgn->region[i].base;
> -        unsigned long rgnsize = rgn->region[i].size;
> -        if ( lmb_addrs_overlap(base,size,rgnbase,rgnsize) ) {
> -            break;
> -        }
> -    }
> -
> -    return (i < rgn->cnt) ? i : -1;
> -}
> -
> -unsigned long __init
> -lmb_alloc(unsigned long size, unsigned long align)
> -{
> -    return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE);
> -}
> -
> -unsigned long __init
> -lmb_alloc_base(unsigned long size, unsigned long align, unsigned long
> max_addr)
> -{
> -    long i, j;
> -    unsigned long base = 0;
> -
> -    for (i=lmb.memory.cnt-1; i >= 0; i--) {
> -        unsigned long lmbbase = lmb.memory.region[i].base;
> -        unsigned long lmbsize = lmb.memory.region[i].size;
> -
> -        if ( max_addr == LMB_ALLOC_ANYWHERE )
> -            base = _ALIGN_DOWN(lmbbase+lmbsize-size, align);
> -        else if ( lmbbase < max_addr )
> -            base =
> _ALIGN_DOWN(min(lmbbase+lmbsize,max_addr)-size, align);
> -        else
> -            continue;
> -
> -        while ( (lmbbase <= base) &&
> -            ((j =
> lmb_overlaps_region(&lmb.reserved,base,size)) >= 0) ) {
> -            base =
> _ALIGN_DOWN(lmb.reserved.region[j].base-size, align);
> -        }
> -
> -        if ( (base != 0) && (lmbbase <= base) )
> -            break;
> -    }
> -
> -    if ( i < 0 )
> -        return 0;
> -
> -    lmb_add_region(&lmb.reserved, base, size);
> -
> -    return base;
> -}
> -
> -/* You must call lmb_analyze() before this. */
> -unsigned long __init
> -lmb_phys_mem_size(void)
> -{
> -    return lmb.memory.size;
> -}
> -
> -unsigned long __init
> -lmb_end_of_DRAM(void)
> -{
> -    int idx = lmb.memory.cnt - 1;
> -
> -    return (lmb.memory.region[idx].base +
> lmb.memory.region[idx].size);
> -}
> -
> -/*
> - * Truncate the lmb list to memory_limit if it's set
> - * You must call lmb_analyze() after this.
> - */
> -void __init lmb_enforce_memory_limit(void)
> -{
> -    extern unsigned long memory_limit;
> -    unsigned long i, limit;
> -
> -    if (! memory_limit)
> -        return;
> -
> -    limit = memory_limit;
> -    for (i = 0; i < lmb.memory.cnt; i++) {
> -        if (limit > lmb.memory.region[i].size) {
> -            limit -= lmb.memory.region[i].size;
> -            continue;
> -        }
> -
> -        lmb.memory.region[i].size = limit;
> -        lmb.memory.cnt = i + 1;
> -        break;
> -    }
> -}
> diff --git a/include/asm-powerpc/lmb.h b/include/asm-powerpc/lmb.h
> new file mode 100644
> --- /dev/null
> +++ b/include/asm-powerpc/lmb.h
> @@ -0,0 +1,78 @@
> +#ifndef _ASM_POWERPC_LMB_H
> +#define _ASM_POWERPC_LMB_H
> +
> +/*
> + * Low-level Memory Block management.
> + *
> + * Copyright (C) 2001 Peter Bergner, IBM Corp.
> + */
> +
> +#include <linux/init.h>
> +#include <asm/prom.h>
> +
> +#define MAX_LMB_REGIONS 128
> +
> +#define LMB_ALLOC_ANYWHERE    0
> +
> +struct lmb_block {
> +    unsigned long base;
> +    unsigned long size;
> +};
> +
> +struct lmb_region {
> +    unsigned long cnt;
> +    unsigned long size;
> +    struct lmb_block region[MAX_LMB_REGIONS+1];
> +};
> +
> +struct lmb {
> +    unsigned long debug;
> +    unsigned long rmo_size;
> +    struct lmb_region memory;
> +    struct lmb_region reserved;
> +};
> +
> +extern struct lmb lmb;
> +
> +extern void __init lmb_init(void);
> +extern void __init lmb_analyze(void);
> +extern long __init lmb_add(unsigned long, unsigned long);
> +extern long __init lmb_reserve(unsigned long, unsigned long);
> +extern unsigned long __init lmb_alloc(unsigned long, unsigned long);
> +extern unsigned long __init lmb_alloc_base(unsigned long, unsigned
> long,
> +                       unsigned long);
> +extern unsigned long __init lmb_phys_mem_size(void);
> +extern unsigned long __init lmb_end_of_DRAM(void);
> +extern unsigned long __init lmb_abs_to_phys(unsigned long);
> +extern void __init lmb_enforce_memory_limit(void);
> +
> +extern void lmb_dump_all(void);
> +
> +extern unsigned long io_hole_start;
> +
> +static inline unsigned long
> +lmb_size_bytes(struct lmb_region *type, unsigned long region_nr)
> +{
> +    return type->region[region_nr].size;
> +}
> +
> +static inline unsigned long
> +lmb_size_pages(struct lmb_region *type, unsigned long region_nr)
> +{
> +    return lmb_size_bytes(type, region_nr) >> PAGE_SHIFT;
> +}
> +
> +static inline unsigned long
> +lmb_start_pfn(struct lmb_region *type, unsigned long region_nr)
> +{
> +    return type->region[region_nr].base >> PAGE_SHIFT;
> +}
> +
> +static inline unsigned long
> +lmb_end_pfn(struct lmb_region *type, unsigned long region_nr)
> +{
> +    return lmb_start_pfn(type, region_nr) +
> +           lmb_size_pages(type, region_nr);
> +}
> +
> +#endif    /* _ASM_POWERPC_LMB_H */
> diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h
> --- a/include/asm-ppc/page.h
> +++ b/include/asm-ppc/page.h
> @@ -77,8 +77,12 @@ typedef unsigned long pgprot_t;
>  #endif
>
>
> +/* align addr on a size boundary - adjust address up/down if  
> needed */
> +#define _ALIGN_UP(addr,size)    (((addr)+((size)-1))&(~((size)-1)))
> +#define _ALIGN_DOWN(addr,size)    ((addr)&(~((size)-1)))
> +
>  /* align addr on a size boundary - adjust address up if needed --  
> Cort
> */
> -#define _ALIGN(addr,size)    (((addr)+(size)-1)&(~((size)-1)))
> +#define _ALIGN(addr,size)    _ALIGN_UP(addr,size)
>
>  /* to align the pointer to the (next) page boundary */
>  #define PAGE_ALIGN(addr)    (((addr)+PAGE_SIZE-1)&PAGE_MASK)
>
>
> _______________________________________________
> Linuxppc64-dev mailing list
> Linuxppc64-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc64-dev
>

^ permalink raw reply

* Re: Available user-level tool for I2C device?
From: Sam Song @ 2005-10-05  3:33 UTC (permalink / raw)
  To: Yuli Barcohen; +Cc: Jonathan Masel, linuxppc-embedded
In-Reply-To: <17215.59283.623355.83952@astp0002.localdomain>

Yuli Barcohen <yuli@arabellasw.com> wrote:
> so the same tool works for both I2C and SPI. I
> attached to this mail the
> source, brief documentation, and some examples.

Greatly appreciate! This utility is on the top of
what I expected and thought. 

Sam


		
___________________________________________________________ 
雅虎邮箱超强增值服务-2G超大空间、pop3收信、无限量邮件提醒 
http://cn.mail.yahoo.com

^ permalink raw reply

* Re: serial console
From: KokHow Teh @ 2005-10-05  2:36 UTC (permalink / raw)
  To: Vitaly Bordug, david.jander, linuxppc-embedded list


Hi;
      I have tried with 4 types of command lines with my linux kernel with
devfs and serial device compiled in and none gives me the desired results:

(1)   console=tts/0,115200n8 OR console=ttyCPM0,115200n8

      no serial console output at all during boot time but it gives me
login prompt at the end.

(2)   without "console=" OR console=ttyS0,115200n8

      serial console output fine during bootup but only until the point
when it prints out "Freeing unused kernel memory: 232k init 4k prep". After
that, the serial console output is garbled. No login prompt.

      So this has not solved my problem. I need more advice. Here are some
more questions and observations:

(1)   David Jander's comment:

I don't know exactly what I am talking about right now, but the string
"tts/0"
in the console-line sounds suspicious to me. AFAIK when using devfs still
device names on the kernel-commandline have to be old-style.
Just a guess: try using "console=ttyS0,115200n8" and see if this helps.

      Is it confirmed that kernel-commandline has to be old-style even
though the kernel is using devfs?

(2)   Vitaly Bordug's suggestion of using "console=ttyCPM0". May I know
where is ttyCPM0 defined and how is it bound to the serial console device
driver in the source?

      Thanks for any input and pointer.

Regards,
TEH

^ permalink raw reply

* Re: serial console
From: KokHow Teh @ 2005-10-05  2:32 UTC (permalink / raw)
  To: Vitaly Bordug, david.jander; +Cc: linuxppc-embedded list


Hi;
      I have tried with 4 types of command lines with my linux kernel with
devfs and serial device compiled in and none gives me the desired results:

(1)   console=tts/0,115200n8 OR console=ttyCPM0,115200n8

      no serial console output at all during boot time but it gives me
login prompt at the end.

(2)   without "console=" OR console=ttyS0,115200n8

      serial console output fine during bootup but only until the point
when it prints out "Freeing unused kernel memory: 232k init 4k prep". After
that, the serial console output is garbled.

      So this has not solved my problem. I need more advice. Here are some
more questions and observations:

(1)   David Jander's comment:

I don't know exactly what I am talking about right now, but the string
"tts/0"
in the console-line sounds suspicious to me. AFAIK when using devfs still
device names on the kernel-commandline have to be old-style.
Just a guess: try using "console=ttyS0,115200n8" and see if this helps.

      Is it confirmed that kernel-commandline has to be old-style even
though the kernel is using devfs?

(2)   Vitaly Bordug's suggestion of using "console=ttyCPM0". May I know
where is ttyCPM0 defined and how is it bound to the serial console device
driver in the source?

      Thanks for any input and pointer.

Regards,
TEH



Vitaly Bordug <vbordug@ru.mvista.com> on 10/04/2005 11:16:10 PM

To:    KokHow.Teh@marconi.com
cc:    linuxppc-embedded list <linuxppc-embedded@ozlabs.org>

Subject:    Re: serial console



> On Tuesday 04 October 2005 08:54, KokHow Teh wrote:
>
>>Hi;
>>      I have debian linux running on my PQ2FADS-ZU with devfs and serial
>>driver compiled in. I have read Documentation/serial-console.txt and I
have
>>tried both passing "console=" option as well as without passing that to
the
>>kernel and both don't give me the expected results.
>>      When I pass "console=tts/0,115200n8" to the kernel, I don't get any
>>console output until the login prompt which I set to 115200 in
>>/etc/inittab. When I don't pass "console=" option to the kernel, I get
>>console output all the way until "Freeing unused kernel memory:" and the
>>console output is garbled and I don't see any login prompt. Here is the
>>/dev/* content:
>
>
> I don't know exactly what I am talking about right now, but the string
"tts/0"
> in the console-line sounds suspicious to me. AFAIK when using devfs still
> device names on the kernel-commandline have to be old-style.
> Just a guess: try using "console=ttyS0,115200n8" and see if this helps.
>
Yes, but PQ2FADS use cpm_uart and hence the commandline should be
console=ttyCPM0,115200

> Greetings,
>


--
Sincerely,
Vitaly

^ permalink raw reply

* Re: clock skew on B/W G3
From: Benjamin Herrenschmidt @ 2005-10-04 22:14 UTC (permalink / raw)
  To: Marc; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <200510040814.07188.marvin24@gmx.de>

On Tue, 2005-10-04 at 08:14 +0200, Marc wrote:
> Hi,
> 
> given that this option causes problems on non i386 systems, may I propose to 
> mark CONFIG_HZ as broken on these architectures and/or use a default value of 
> 1000 ? I guess this issue can't be fixed in a sane way until 2.6.14 is out.

The problem is indeed in via_calibrate_decr(). This routine works on
HZ/100 so it will not do any good with HZ not beeing a multiple of 100.

Can you test this patch ?

Index: linux-work/arch/ppc/platforms/pmac_time.c
===================================================================
--- linux-work.orig/arch/ppc/platforms/pmac_time.c	2005-09-22 14:06:18.000000000 +1000
+++ linux-work/arch/ppc/platforms/pmac_time.c	2005-10-05 08:14:17.000000000 +1000
@@ -195,7 +195,7 @@
 		;
 	dend = get_dec();
 
-	tb_ticks_per_jiffy = (dstart - dend) / (6 * (HZ/100));
+	tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100);
 	tb_to_us = mulhwu_scale_factor(dstart - dend, 60000);
 
 	printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n",

^ permalink raw reply

* Re: clock skew on B/W G3
From: Benjamin Herrenschmidt @ 2005-10-04 22:10 UTC (permalink / raw)
  To: Marc; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <200510040814.07188.marvin24@gmx.de>

On Tue, 2005-10-04 at 08:14 +0200, Marc wrote:
> Hi,
> 
> given that this option causes problems on non i386 systems, may I propose to 
> mark CONFIG_HZ as broken on these architectures and/or use a default value of 
> 1000 ? I guess this issue can't be fixed in a sane way until 2.6.14 is out.

No, it should work fine, there is something else broken on this G3

Ben.

^ permalink raw reply

* PATCH powerpc Move LMB from ppc64 to powerpc
From: Jon Loeliger @ 2005-10-04 21:59 UTC (permalink / raw)
  To: linuxppc-dev@ozlabs.org, linuxppc64-dev

Move the LMB code from ppc64 to powerpc.
Only compile ppc32's tlb.c code on "standard" mmu machines.

Signed-off-by: Jon Loeliger <jdl@freescale.com>
---

 arch/powerpc/mm/Makefile   |    8 +
 arch/powerpc/mm/lmb.c      |  303 ++++++++++++++++++++++++++++++++++++++++++++
 arch/ppc64/kernel/Makefile |    1 
 arch/ppc64/kernel/lmb.c    |  299 -------------------------------------------
 include/asm-powerpc/lmb.h  |   78 +++++++++++
 include/asm-ppc/page.h     |    6 +
 6 files changed, 391 insertions(+), 304 deletions(-)


diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -2,11 +2,11 @@
 # Makefile for the linux ppc-specific parts of the memory manager.
 #
 
-obj-y				:= fault.o mem.o
-obj-$(CONFIG_PPC32)		+= init.o pgtable.o mmu_context.o \
-				   mem_pieces.o tlb.o
+obj-y				:= fault.o lmb.o mem.o
+
+obj-$(CONFIG_PPC32)		+= init.o pgtable.o mmu_context.o mem_pieces.o
 obj-$(CONFIG_PPC64)		+= init64.o pgtable64.o mmu_context64.o
-obj-$(CONFIG_PPC_STD_MMU_32)	+= ppc_mmu.o hash_32.o
+obj-$(CONFIG_PPC_STD_MMU_32)	+= ppc_mmu.o hash_32.o tlb.o
 obj-$(CONFIG_40x)		+= 4xx_mmu.o
 obj-$(CONFIG_44x)		+= 44x_mmu.o
 obj-$(CONFIG_FSL_BOOKE)		+= fsl_booke_mmu.o
diff --git a/arch/powerpc/mm/lmb.c b/arch/powerpc/mm/lmb.c
new file mode 100644
--- /dev/null
+++ b/arch/powerpc/mm/lmb.c
@@ -0,0 +1,303 @@
+/*
+ * Procedures for interfacing to Open Firmware.
+ *
+ * Peter Bergner, IBM Corp.	June 2001.
+ * Copyright (C) 2001 Peter Bergner.
+ * 
+ *      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.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <asm/types.h>
+#include <asm/page.h>
+#include <asm/prom.h>
+#include <asm/lmb.h>
+
+struct lmb lmb;
+
+#undef DEBUG
+
+void lmb_dump_all(void)
+{
+#ifdef DEBUG
+	unsigned long i;
+
+	udbg_printf("lmb_dump_all:\n");
+	udbg_printf("    memory.cnt		  = 0x%lx\n",
+		    lmb.memory.cnt);
+	udbg_printf("    memory.size		  = 0x%lx\n",
+		    lmb.memory.size);
+	for (i=0; i < lmb.memory.cnt ;i++) {
+		udbg_printf("    memory.region[0x%x].base       = 0x%lx\n",
+			    i, lmb.memory.region[i].base);
+		udbg_printf("		      .size     = 0x%lx\n",
+			    lmb.memory.region[i].size);
+	}
+
+	udbg_printf("\n    reserved.cnt	  = 0x%lx\n",
+		    lmb.reserved.cnt);
+	udbg_printf("    reserved.size	  = 0x%lx\n",
+		    lmb.reserved.size);
+	for (i=0; i < lmb.reserved.cnt ;i++) {
+		udbg_printf("    reserved.region[0x%x].base       = 0x%lx\n",
+			    i, lmb.reserved.region[i].base);
+		udbg_printf("		      .size     = 0x%lx\n",
+			    lmb.reserved.region[i].size);
+	}
+#endif /* DEBUG */
+}
+
+static unsigned long __init
+lmb_addrs_overlap(unsigned long base1, unsigned long size1,
+                  unsigned long base2, unsigned long size2)
+{
+	return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
+}
+
+static long __init
+lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
+		   unsigned long base2, unsigned long size2)
+{
+	if (base2 == base1 + size1)
+		return 1;
+	else if (base1 == base2 + size2)
+		return -1;
+
+	return 0;
+}
+
+static long __init
+lmb_regions_adjacent(struct lmb_region *rgn,
+		     unsigned long r1, unsigned long r2)
+{
+	unsigned long base1 = rgn->region[r1].base;
+	unsigned long size1 = rgn->region[r1].size;
+	unsigned long base2 = rgn->region[r2].base;
+	unsigned long size2 = rgn->region[r2].size;
+
+	return lmb_addrs_adjacent(base1, size1, base2, size2);
+}
+
+/* Assumption: base addr of region 1 < base addr of region 2 */
+static void __init
+lmb_coalesce_regions(struct lmb_region *rgn,
+		     unsigned long r1, unsigned long r2)
+{
+	unsigned long i;
+
+	rgn->region[r1].size += rgn->region[r2].size;
+	for (i=r2; i < rgn->cnt-1; i++) {
+		rgn->region[i].base = rgn->region[i+1].base;
+		rgn->region[i].size = rgn->region[i+1].size;
+	}
+	rgn->cnt--;
+}
+
+/* This routine called with relocation disabled. */
+void __init
+lmb_init(void)
+{
+	/* Create a dummy zero size LMB which will get coalesced away later.
+	 * This simplifies the lmb_add() code below...
+	 */
+	lmb.memory.region[0].base = 0;
+	lmb.memory.region[0].size = 0;
+	lmb.memory.cnt = 1;
+
+	/* Ditto. */
+	lmb.reserved.region[0].base = 0;
+	lmb.reserved.region[0].size = 0;
+	lmb.reserved.cnt = 1;
+}
+
+/* This routine called with relocation disabled. */
+void __init
+lmb_analyze(void)
+{
+	int i;
+
+	lmb.memory.size = 0;
+
+	for (i = 0; i < lmb.memory.cnt; i++)
+		lmb.memory.size += lmb.memory.region[i].size;
+}
+
+/* This routine called with relocation disabled. */
+static long __init
+lmb_add_region(struct lmb_region *rgn, unsigned long base, unsigned long size)
+{
+	unsigned long i, coalesced = 0;
+	long adjacent;
+
+	/* First try and coalesce this LMB with another. */
+	for (i=0; i < rgn->cnt; i++) {
+		unsigned long rgnbase = rgn->region[i].base;
+		unsigned long rgnsize = rgn->region[i].size;
+
+		adjacent = lmb_addrs_adjacent(base,size,rgnbase,rgnsize);
+		if ( adjacent > 0 ) {
+			rgn->region[i].base -= size;
+			rgn->region[i].size += size;
+			coalesced++;
+			break;
+		}
+		else if ( adjacent < 0 ) {
+			rgn->region[i].size += size;
+			coalesced++;
+			break;
+		}
+	}
+
+	if ((i < rgn->cnt-1) && lmb_regions_adjacent(rgn, i, i+1) ) {
+		lmb_coalesce_regions(rgn, i, i+1);
+		coalesced++;
+	}
+
+	if ( coalesced ) {
+		return coalesced;
+	} else if ( rgn->cnt >= MAX_LMB_REGIONS ) {
+		return -1;
+	}
+
+	/* Couldn't coalesce the LMB, so add it to the sorted table. */
+	for (i=rgn->cnt-1; i >= 0; i--) {
+		if (base < rgn->region[i].base) {
+			rgn->region[i+1].base = rgn->region[i].base;
+			rgn->region[i+1].size = rgn->region[i].size;
+		}  else {
+			rgn->region[i+1].base = base;
+			rgn->region[i+1].size = size;
+			break;
+		}
+	}
+	rgn->cnt++;
+
+	return 0;
+}
+
+/* This routine called with relocation disabled. */
+long __init
+lmb_add(unsigned long base, unsigned long size)
+{
+	struct lmb_region *_rgn = &(lmb.memory);
+
+	/* On pSeries LPAR systems, the first LMB is our RMO region. */
+	if ( base == 0 )
+		lmb.rmo_size = size;
+
+	return lmb_add_region(_rgn, base, size);
+
+}
+
+long __init
+lmb_reserve(unsigned long base, unsigned long size)
+{
+	struct lmb_region *_rgn = &(lmb.reserved);
+
+	return lmb_add_region(_rgn, base, size);
+}
+
+long __init
+lmb_overlaps_region(struct lmb_region *rgn,
+		    unsigned long base, unsigned long size)
+{
+	unsigned long i;
+
+	for (i=0; i < rgn->cnt; i++) {
+		unsigned long rgnbase = rgn->region[i].base;
+		unsigned long rgnsize = rgn->region[i].size;
+		if ( lmb_addrs_overlap(base,size,rgnbase,rgnsize) ) {
+			break;
+		}
+	}
+
+	return (i < rgn->cnt) ? i : -1;
+}
+
+unsigned long __init
+lmb_alloc(unsigned long size, unsigned long align)
+{
+	return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE);
+}
+
+unsigned long __init
+lmb_alloc_base(unsigned long size, unsigned long align, unsigned long max_addr)
+{
+	long i, j;
+	unsigned long base = 0;
+
+	for (i=lmb.memory.cnt-1; i >= 0; i--) {
+		unsigned long lmbbase = lmb.memory.region[i].base;
+		unsigned long lmbsize = lmb.memory.region[i].size;
+
+		if ( max_addr == LMB_ALLOC_ANYWHERE )
+			base = _ALIGN_DOWN(lmbbase+lmbsize-size, align);
+		else if ( lmbbase < max_addr )
+			base = _ALIGN_DOWN(min(lmbbase+lmbsize,max_addr)-size,
+					   align);
+		else
+			continue;
+
+		while ( (lmbbase <= base) &&
+			((j = lmb_overlaps_region(&lmb.reserved,base,size)) >= 0) ) {
+			base = _ALIGN_DOWN(lmb.reserved.region[j].base-size,
+					   align);
+		}
+
+		if ( (base != 0) && (lmbbase <= base) )
+			break;
+	}
+
+	if ( i < 0 )
+		return 0;
+
+	lmb_add_region(&lmb.reserved, base, size);
+
+	return base;
+}
+
+/* You must call lmb_analyze() before this. */
+unsigned long __init
+lmb_phys_mem_size(void)
+{
+	return lmb.memory.size;
+}
+
+unsigned long __init
+lmb_end_of_DRAM(void)
+{
+	int idx = lmb.memory.cnt - 1;
+
+	return (lmb.memory.region[idx].base + lmb.memory.region[idx].size);
+}
+
+/*
+ * Truncate the lmb list to memory_limit if it's set
+ * You must call lmb_analyze() after this.
+ */
+void __init lmb_enforce_memory_limit(void)
+{
+	extern unsigned long memory_limit;
+	unsigned long i, limit;
+
+	if (! memory_limit)
+		return;
+
+	limit = memory_limit;
+	for (i = 0; i < lmb.memory.cnt; i++) {
+		if (limit > lmb.memory.region[i].size) {
+			limit -= lmb.memory.region[i].size;
+			continue;
+		}
+
+		lmb.memory.region[i].size = limit;
+		lmb.memory.cnt = i + 1;
+		break;
+	}
+}
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile
--- a/arch/ppc64/kernel/Makefile
+++ b/arch/ppc64/kernel/Makefile
@@ -76,3 +76,4 @@ endif
 
 # These are here while we do the architecture merge
 vecemu-y			+= ../../powerpc/kernel/vecemu.o
+lmb-y				+= ../../powerpc/mm/lmb.o
diff --git a/arch/ppc64/kernel/lmb.c b/arch/ppc64/kernel/lmb.c
deleted file mode 100644
--- a/arch/ppc64/kernel/lmb.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Procedures for interfacing to Open Firmware.
- *
- * Peter Bergner, IBM Corp.	June 2001.
- * Copyright (C) 2001 Peter Bergner.
- * 
- *      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.
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-#include <asm/types.h>
-#include <asm/page.h>
-#include <asm/prom.h>
-#include <asm/lmb.h>
-#include <asm/abs_addr.h>
-
-struct lmb lmb;
-
-#undef DEBUG
-
-void lmb_dump_all(void)
-{
-#ifdef DEBUG
-	unsigned long i;
-
-	udbg_printf("lmb_dump_all:\n");
-	udbg_printf("    memory.cnt		  = 0x%lx\n",
-		    lmb.memory.cnt);
-	udbg_printf("    memory.size		  = 0x%lx\n",
-		    lmb.memory.size);
-	for (i=0; i < lmb.memory.cnt ;i++) {
-		udbg_printf("    memory.region[0x%x].base       = 0x%lx\n",
-			    i, lmb.memory.region[i].base);
-		udbg_printf("		      .size     = 0x%lx\n",
-			    lmb.memory.region[i].size);
-	}
-
-	udbg_printf("\n    reserved.cnt	  = 0x%lx\n",
-		    lmb.reserved.cnt);
-	udbg_printf("    reserved.size	  = 0x%lx\n",
-		    lmb.reserved.size);
-	for (i=0; i < lmb.reserved.cnt ;i++) {
-		udbg_printf("    reserved.region[0x%x].base       = 0x%lx\n",
-			    i, lmb.reserved.region[i].base);
-		udbg_printf("		      .size     = 0x%lx\n",
-			    lmb.reserved.region[i].size);
-	}
-#endif /* DEBUG */
-}
-
-static unsigned long __init
-lmb_addrs_overlap(unsigned long base1, unsigned long size1,
-                  unsigned long base2, unsigned long size2)
-{
-	return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
-}
-
-static long __init
-lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
-		   unsigned long base2, unsigned long size2)
-{
-	if (base2 == base1 + size1)
-		return 1;
-	else if (base1 == base2 + size2)
-		return -1;
-
-	return 0;
-}
-
-static long __init
-lmb_regions_adjacent(struct lmb_region *rgn, unsigned long r1, unsigned long r2)
-{
-	unsigned long base1 = rgn->region[r1].base;
-	unsigned long size1 = rgn->region[r1].size;
-	unsigned long base2 = rgn->region[r2].base;
-	unsigned long size2 = rgn->region[r2].size;
-
-	return lmb_addrs_adjacent(base1, size1, base2, size2);
-}
-
-/* Assumption: base addr of region 1 < base addr of region 2 */
-static void __init
-lmb_coalesce_regions(struct lmb_region *rgn, unsigned long r1, unsigned long r2)
-{
-	unsigned long i;
-
-	rgn->region[r1].size += rgn->region[r2].size;
-	for (i=r2; i < rgn->cnt-1; i++) {
-		rgn->region[i].base = rgn->region[i+1].base;
-		rgn->region[i].size = rgn->region[i+1].size;
-	}
-	rgn->cnt--;
-}
-
-/* This routine called with relocation disabled. */
-void __init
-lmb_init(void)
-{
-	/* Create a dummy zero size LMB which will get coalesced away later.
-	 * This simplifies the lmb_add() code below...
-	 */
-	lmb.memory.region[0].base = 0;
-	lmb.memory.region[0].size = 0;
-	lmb.memory.cnt = 1;
-
-	/* Ditto. */
-	lmb.reserved.region[0].base = 0;
-	lmb.reserved.region[0].size = 0;
-	lmb.reserved.cnt = 1;
-}
-
-/* This routine called with relocation disabled. */
-void __init
-lmb_analyze(void)
-{
-	int i;
-
-	lmb.memory.size = 0;
-
-	for (i = 0; i < lmb.memory.cnt; i++)
-		lmb.memory.size += lmb.memory.region[i].size;
-}
-
-/* This routine called with relocation disabled. */
-static long __init
-lmb_add_region(struct lmb_region *rgn, unsigned long base, unsigned long size)
-{
-	unsigned long i, coalesced = 0;
-	long adjacent;
-
-	/* First try and coalesce this LMB with another. */
-	for (i=0; i < rgn->cnt; i++) {
-		unsigned long rgnbase = rgn->region[i].base;
-		unsigned long rgnsize = rgn->region[i].size;
-
-		adjacent = lmb_addrs_adjacent(base,size,rgnbase,rgnsize);
-		if ( adjacent > 0 ) {
-			rgn->region[i].base -= size;
-			rgn->region[i].size += size;
-			coalesced++;
-			break;
-		}
-		else if ( adjacent < 0 ) {
-			rgn->region[i].size += size;
-			coalesced++;
-			break;
-		}
-	}
-
-	if ((i < rgn->cnt-1) && lmb_regions_adjacent(rgn, i, i+1) ) {
-		lmb_coalesce_regions(rgn, i, i+1);
-		coalesced++;
-	}
-
-	if ( coalesced ) {
-		return coalesced;
-	} else if ( rgn->cnt >= MAX_LMB_REGIONS ) {
-		return -1;
-	}
-
-	/* Couldn't coalesce the LMB, so add it to the sorted table. */
-	for (i=rgn->cnt-1; i >= 0; i--) {
-		if (base < rgn->region[i].base) {
-			rgn->region[i+1].base = rgn->region[i].base;
-			rgn->region[i+1].size = rgn->region[i].size;
-		}  else {
-			rgn->region[i+1].base = base;
-			rgn->region[i+1].size = size;
-			break;
-		}
-	}
-	rgn->cnt++;
-
-	return 0;
-}
-
-/* This routine called with relocation disabled. */
-long __init
-lmb_add(unsigned long base, unsigned long size)
-{
-	struct lmb_region *_rgn = &(lmb.memory);
-
-	/* On pSeries LPAR systems, the first LMB is our RMO region. */
-	if ( base == 0 )
-		lmb.rmo_size = size;
-
-	return lmb_add_region(_rgn, base, size);
-
-}
-
-long __init
-lmb_reserve(unsigned long base, unsigned long size)
-{
-	struct lmb_region *_rgn = &(lmb.reserved);
-
-	return lmb_add_region(_rgn, base, size);
-}
-
-long __init
-lmb_overlaps_region(struct lmb_region *rgn, unsigned long base, unsigned long size)
-{
-	unsigned long i;
-
-	for (i=0; i < rgn->cnt; i++) {
-		unsigned long rgnbase = rgn->region[i].base;
-		unsigned long rgnsize = rgn->region[i].size;
-		if ( lmb_addrs_overlap(base,size,rgnbase,rgnsize) ) {
-			break;
-		}
-	}
-
-	return (i < rgn->cnt) ? i : -1;
-}
-
-unsigned long __init
-lmb_alloc(unsigned long size, unsigned long align)
-{
-	return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE);
-}
-
-unsigned long __init
-lmb_alloc_base(unsigned long size, unsigned long align, unsigned long max_addr)
-{
-	long i, j;
-	unsigned long base = 0;
-
-	for (i=lmb.memory.cnt-1; i >= 0; i--) {
-		unsigned long lmbbase = lmb.memory.region[i].base;
-		unsigned long lmbsize = lmb.memory.region[i].size;
-
-		if ( max_addr == LMB_ALLOC_ANYWHERE )
-			base = _ALIGN_DOWN(lmbbase+lmbsize-size, align);
-		else if ( lmbbase < max_addr )
-			base = _ALIGN_DOWN(min(lmbbase+lmbsize,max_addr)-size, align);
-		else
-			continue;
-
-		while ( (lmbbase <= base) &&
-			((j = lmb_overlaps_region(&lmb.reserved,base,size)) >= 0) ) {
-			base = _ALIGN_DOWN(lmb.reserved.region[j].base-size, align);
-		}
-
-		if ( (base != 0) && (lmbbase <= base) )
-			break;
-	}
-
-	if ( i < 0 )
-		return 0;
-
-	lmb_add_region(&lmb.reserved, base, size);
-
-	return base;
-}
-
-/* You must call lmb_analyze() before this. */
-unsigned long __init
-lmb_phys_mem_size(void)
-{
-	return lmb.memory.size;
-}
-
-unsigned long __init
-lmb_end_of_DRAM(void)
-{
-	int idx = lmb.memory.cnt - 1;
-
-	return (lmb.memory.region[idx].base + lmb.memory.region[idx].size);
-}
-
-/*
- * Truncate the lmb list to memory_limit if it's set
- * You must call lmb_analyze() after this.
- */
-void __init lmb_enforce_memory_limit(void)
-{
-	extern unsigned long memory_limit;
-	unsigned long i, limit;
-
-	if (! memory_limit)
-		return;
-
-	limit = memory_limit;
-	for (i = 0; i < lmb.memory.cnt; i++) {
-		if (limit > lmb.memory.region[i].size) {
-			limit -= lmb.memory.region[i].size;
-			continue;
-		}
-
-		lmb.memory.region[i].size = limit;
-		lmb.memory.cnt = i + 1;
-		break;
-	}
-}
diff --git a/include/asm-powerpc/lmb.h b/include/asm-powerpc/lmb.h
new file mode 100644
--- /dev/null
+++ b/include/asm-powerpc/lmb.h
@@ -0,0 +1,78 @@
+#ifndef _ASM_POWERPC_LMB_H
+#define _ASM_POWERPC_LMB_H
+
+/*
+ * Low-level Memory Block management.
+ *
+ * Copyright (C) 2001 Peter Bergner, IBM Corp.
+ */
+
+#include <linux/init.h>
+#include <asm/prom.h>
+
+#define MAX_LMB_REGIONS 128
+
+#define LMB_ALLOC_ANYWHERE	0
+
+struct lmb_block {
+	unsigned long base;
+	unsigned long size;
+};
+
+struct lmb_region {
+	unsigned long cnt;
+	unsigned long size;
+	struct lmb_block region[MAX_LMB_REGIONS+1];
+};
+
+struct lmb {
+	unsigned long debug;
+	unsigned long rmo_size;
+	struct lmb_region memory;
+	struct lmb_region reserved;
+};
+
+extern struct lmb lmb;
+
+extern void __init lmb_init(void);
+extern void __init lmb_analyze(void);
+extern long __init lmb_add(unsigned long, unsigned long);
+extern long __init lmb_reserve(unsigned long, unsigned long);
+extern unsigned long __init lmb_alloc(unsigned long, unsigned long);
+extern unsigned long __init lmb_alloc_base(unsigned long, unsigned long,
+					   unsigned long);
+extern unsigned long __init lmb_phys_mem_size(void);
+extern unsigned long __init lmb_end_of_DRAM(void);
+extern unsigned long __init lmb_abs_to_phys(unsigned long);
+extern void __init lmb_enforce_memory_limit(void);
+
+extern void lmb_dump_all(void);
+
+extern unsigned long io_hole_start;
+
+static inline unsigned long
+lmb_size_bytes(struct lmb_region *type, unsigned long region_nr)
+{
+	return type->region[region_nr].size;
+}
+
+static inline unsigned long
+lmb_size_pages(struct lmb_region *type, unsigned long region_nr)
+{
+	return lmb_size_bytes(type, region_nr) >> PAGE_SHIFT;
+}
+
+static inline unsigned long
+lmb_start_pfn(struct lmb_region *type, unsigned long region_nr)
+{
+	return type->region[region_nr].base >> PAGE_SHIFT;
+}
+
+static inline unsigned long
+lmb_end_pfn(struct lmb_region *type, unsigned long region_nr)
+{
+	return lmb_start_pfn(type, region_nr) +
+	       lmb_size_pages(type, region_nr);
+}
+
+#endif	/* _ASM_POWERPC_LMB_H */
diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h
--- a/include/asm-ppc/page.h
+++ b/include/asm-ppc/page.h
@@ -77,8 +77,12 @@ typedef unsigned long pgprot_t;
 #endif
 
 
+/* align addr on a size boundary - adjust address up/down if needed */
+#define _ALIGN_UP(addr,size)	(((addr)+((size)-1))&(~((size)-1)))
+#define _ALIGN_DOWN(addr,size)	((addr)&(~((size)-1)))
+
 /* align addr on a size boundary - adjust address up if needed -- Cort */
-#define _ALIGN(addr,size)	(((addr)+(size)-1)&(~((size)-1)))
+#define _ALIGN(addr,size)	_ALIGN_UP(addr,size)
 
 /* to align the pointer to the (next) page boundary */
 #define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)

^ permalink raw reply

* Re: clock skew on B/W G3
From: George Anzinger @ 2005-10-04 19:14 UTC (permalink / raw)
  To: Rune Torgersen; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <DCEAAC0833DD314AB0B58112AD99B93B859479@ismail.innsys.innovsys.com>

Rune Torgersen wrote:
>  
> 
> 
>>-----Original Message-----
>>From: Paul Mackerras [mailto:paulus@samba.org] 
>>Sent: Tuesday, October 04, 2005 07:49
>>Subject: RE: clock skew on B/W G3
>>
>>I do not believe CLOCK_TICK_RATE affects timekeeping at all on ppc or
>>ppc64 machines, but I could be wrong.  Can you show us where and how
>>CLOCK_TICK_RATE affects things?
> 
> 
> I looked very closely at htis thing earlier this summer because of an
> embedded board that drifted quite severly (15sec a day) with a very
> accureate BITS clock as clock source.
> 
> Here goes:
> In arch/ppc/kernel/time.c
> timer_interrupt() gets called every decrementer timeout (about every
> 1/CONFIG_HZ seconds, accuracy depends on how easily your decrementer
> cliock can be divided by CONFIG_HZ)
> this calls do_timer() to do the timer increment.
> 
> do_timer is in kernel/timer.c and calls update_times().
> update_times() calls update_wall_time() which in turns calls
> update_wall_time_one_tick()
> 
> update_wall_time_one_tick()uses tick_nsec to increment xtime.
> 
> tick_nsec is defined as: (kernel/timer.c:561)
> unsigned long tick_nsec = TICK_NSEC;
> 
> TICK_NSEC is defined as: (include/linux/jiffies.h:64)
> #define TICK_NSEC (SH_DIV (1000000UL * 1000, ACTHZ, 8))
> 
> ACTHZ is defined as: (include/linux/jiffies.h:61)
> #define ACTHZ (SH_DIV (CLOCK_TICK_RATE, LATCH, 8))
> 
> LATCH is defined as: (include/linux/jiffies.h:46)
> #define LATCH  ((CLOCK_TICK_RATE + HZ/2) / HZ)
> 
> which means that tick_nsec depends on CLOCK_TICK_RATE to get its value.
> 
> defined as:
> #define CLOCK_TICK_RATE	1193180 /* Underlying HZ */

But this is defined in include/asm/???.h  so you should be able to set something more to your liking 
(or rather to your archs liking).  It is true that it SHOULD be defined as it is used to define 
TICK_NSEC which is used to define the jiffies<-->timeval/timespec conversions which would be VERY 
slow it it were a variable.

George
-- 

> 
> this clock is completely wrong for most/all ppc. 
> It happens to generate a tick_nsec of 999848 which is close enough to
> 1000000 that most people does not notice.
> (tick_nsec is number of nsec per timer tick)
> 
> When HZ is 250, TICK_NSEC becomes 4000250.
> While this might not completely explain a 20% change in clock sped, it
> it clearly not acurate either.
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 

-- 
George Anzinger   george@mvista.com
HRT (High-res-timers):  http://sourceforge.net/projects/high-res-timers/

^ permalink raw reply

* RE: clock skew on B/W G3
From: Rune Torgersen @ 2005-10-04 19:22 UTC (permalink / raw)
  To: george; +Cc: linuxppc-dev, linux-kernel

=20

> From: George Anzinger [mailto:george@mvista.com]=20
> But this is defined in include/asm/???.h  so you should be=20
> able to set something more to your liking=20
> (or rather to your archs liking).  It is true that it SHOULD=20
> be defined as it is used to define=20
> TICK_NSEC which is used to define the=20
> jiffies<-->timeval/timespec conversions which would be VERY=20
> slow it it were a variable.

Just make them variables, and compute them ONCE during boot.
ppc calls calibrate_decr() before enabling the timer interrupt anyways.

time_nsec is easy.=20
in a platfrom specific file do (very simplified):

extern unsigned long time_nsec;

void platform_specific_calibrate_decr()
{
	time_nsec =3D REAL_TIME_NSEC;
}

This (of course) will do nothing about LATCH and ACTHZ that might be
used other places.

^ permalink raw reply

* Re: CPM2 early console
From: Dan Malek @ 2005-10-04 16:04 UTC (permalink / raw)
  To: Kalle Pokki; +Cc: linuxppc-embedded
In-Reply-To: <43423996.7090403@iki.fi>


On Oct 4, 2005, at 1:13 AM, Kalle Pokki wrote:

> ...... This errata should probably be included in the Linux kernel, 
> since it really depends on it.

Everything depends on that, and it should be done in the boot rom as
part of the processor initialization after reset.

Thanks.

	-- Dan

^ permalink raw reply

* Re: serial console
From: Vitaly Bordug @ 2005-10-04 15:16 UTC (permalink / raw)
  To: KokHow.Teh; +Cc: linuxppc-embedded list
In-Reply-To: <200510041711.34388.david.jander@protonic.nl>


> On Tuesday 04 October 2005 08:54, KokHow Teh wrote:
> 
>>Hi;
>>      I have debian linux running on my PQ2FADS-ZU with devfs and serial
>>driver compiled in. I have read Documentation/serial-console.txt and I have
>>tried both passing "console=" option as well as without passing that to the
>>kernel and both don't give me the expected results.
>>      When I pass "console=tts/0,115200n8" to the kernel, I don't get any
>>console output until the login prompt which I set to 115200 in
>>/etc/inittab. When I don't pass "console=" option to the kernel, I get
>>console output all the way until "Freeing unused kernel memory:" and the
>>console output is garbled and I don't see any login prompt. Here is the
>>/dev/* content:
> 
> 
> I don't know exactly what I am talking about right now, but the string "tts/0" 
> in the console-line sounds suspicious to me. AFAIK when using devfs still 
> device names on the kernel-commandline have to be old-style.
> Just a guess: try using "console=ttyS0,115200n8" and see if this helps.
> 
Yes, but PQ2FADS use cpm_uart and hence the commandline should be
console=ttyCPM0,115200

> Greetings,
> 


-- 
Sincerely,
Vitaly

^ permalink raw reply

* RE: clock skew on B/W G3
From: Rune Torgersen @ 2005-10-04 15:15 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev, linux-kernel

=20

> -----Original Message-----
> From: Paul Mackerras [mailto:paulus@samba.org]=20
> Sent: Tuesday, October 04, 2005 07:49
> Subject: RE: clock skew on B/W G3
>
> I do not believe CLOCK_TICK_RATE affects timekeeping at all on ppc or
> ppc64 machines, but I could be wrong.  Can you show us where and how
> CLOCK_TICK_RATE affects things?

I looked very closely at htis thing earlier this summer because of an
embedded board that drifted quite severly (15sec a day) with a very
accureate BITS clock as clock source.

Here goes:
In arch/ppc/kernel/time.c
timer_interrupt() gets called every decrementer timeout (about every
1/CONFIG_HZ seconds, accuracy depends on how easily your decrementer
cliock can be divided by CONFIG_HZ)
this calls do_timer() to do the timer increment.

do_timer is in kernel/timer.c and calls update_times().
update_times() calls update_wall_time() which in turns calls
update_wall_time_one_tick()

update_wall_time_one_tick()uses tick_nsec to increment xtime.

tick_nsec is defined as: (kernel/timer.c:561)
unsigned long tick_nsec =3D TICK_NSEC;

TICK_NSEC is defined as: (include/linux/jiffies.h:64)
#define TICK_NSEC (SH_DIV (1000000UL * 1000, ACTHZ, 8))

ACTHZ is defined as: (include/linux/jiffies.h:61)
#define ACTHZ (SH_DIV (CLOCK_TICK_RATE, LATCH, 8))

LATCH is defined as: (include/linux/jiffies.h:46)
#define LATCH  ((CLOCK_TICK_RATE + HZ/2) / HZ)

which means that tick_nsec depends on CLOCK_TICK_RATE to get its value.

defined as:
#define CLOCK_TICK_RATE	1193180 /* Underlying HZ */

this clock is completely wrong for most/all ppc.=20
It happens to generate a tick_nsec of 999848 which is close enough to
1000000 that most people does not notice.
(tick_nsec is number of nsec per timer tick)

When HZ is 250, TICK_NSEC becomes 4000250.
While this might not completely explain a 20% change in clock sped, it
it clearly not acurate either.

^ permalink raw reply

* Re: serial console
From: David Jander @ 2005-10-04 15:11 UTC (permalink / raw)
  To: linuxppc-embedded
In-Reply-To: <OF3208D35D.AA3CBB6C-ON48257090.0019F4B3@uk.marconicomms.com>

On Tuesday 04 October 2005 08:54, KokHow Teh wrote:
> Hi;
>       I have debian linux running on my PQ2FADS-ZU with devfs and serial
> driver compiled in. I have read Documentation/serial-console.txt and I have
> tried both passing "console=" option as well as without passing that to the
> kernel and both don't give me the expected results.
>       When I pass "console=tts/0,115200n8" to the kernel, I don't get any
> console output until the login prompt which I set to 115200 in
> /etc/inittab. When I don't pass "console=" option to the kernel, I get
> console output all the way until "Freeing unused kernel memory:" and the
> console output is garbled and I don't see any login prompt. Here is the
> /dev/* content:

I don't know exactly what I am talking about right now, but the string "tts/0" 
in the console-line sounds suspicious to me. AFAIK when using devfs still 
device names on the kernel-commandline have to be old-style.
Just a guess: try using "console=ttyS0,115200n8" and see if this helps.

Greetings,

-- 
David Jander

^ permalink raw reply

* RE: clock skew on B/W G3
From: Paul Mackerras @ 2005-10-04 12:48 UTC (permalink / raw)
  To: Rune Torgersen; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <DCEAAC0833DD314AB0B58112AD99B93B859476@ismail.innsys.innovsys.com>

Rune Torgersen writes:

> CONFIG_HZ is not broken, but the whole clock configuration is.
> (I poseded something about it for 8260 earlier this summer)
> 
> Basic problem is that CLOCK_TICK_RATE which is used for setting up the
> variables used for advancing the clock, is hardcoded to a value that
> only makes sence for an i386. (it is default set at 1193180Hz which
> happens to be the timer clock for timer1 on an i386 machine)

I do not believe CLOCK_TICK_RATE affects timekeeping at all on ppc or
ppc64 machines, but I could be wrong.  Can you show us where and how
CLOCK_TICK_RATE affects things?

Paul.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox