* (no subject)
From: FLAMENT David @ 2005-06-27 12:25 UTC (permalink / raw)
To: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 494 bytes --]
hello,
I use a EP8248 and I search a Kernel 2.6 for this board because I use a kernel 2.4.26 of arabella and the usb isn't supported in this version.
When I compile with USB option ( uhci, scsi + usb mastorage), there is this message "usb-ohci currently requires PCI-based controllers".
If you have a sugget, thank you.
--------------------------------
Flament David
d.flament@sofrel.com
Lacroix Sofrel, 1 rue plessis, 35770 Vern sur seiche (France)
(+33)2.99.04.84.23
[-- Attachment #2: Type: text/html, Size: 1677 bytes --]
^ permalink raw reply
* ppc405 kernel debugging
From: Xavier Grave @ 2005-06-27 14:23 UTC (permalink / raw)
To: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 1570 bytes --]
Hi,
I try to boot a linux kernel (2.6.12) on a custom hardware (memec ff1152
board). If I use the xmd tool to download the zImage.elf I have the
following messages :
loaded at: 00400000 0047813C
board data at: 00476124 0047613C
relocated to: 004051D4 004051EC
zimage at: 004059E5 00475A06
avail ram: 00479000 04000000
Linux/PPC load: console=ttyS0,9600 root=/dev/nfs ip=dhcp
Uncompressing Linux...done.
Now booting the kernel
closing serial
id mach(): done
MMU:enter
MMU:hw init
MMU:mapin
MMU:setio
ml300_map_io:enter
ml300_map_io:exit
MMU:exit
Starting with uboot I get (uImage) :
Filename 'ubootimage'.
Load address: 0x400000
Loading:
#################################################################
#########################
done
Bytes transferred = 458849 (70061 hex)
=> bootm 0x400000
## Booting image at 00400000 ...
Image Name: Linux-2.6.12-bitsim
Image Type: PowerPC Linux Kernel Image (gzip compressed)
Data Size: 458785 Bytes = 448 kB
Load Address: 00000000
Entry Point: 00000000
Verifying Checksum ... OK
Uncompressing Kernel Image ... OK
id mach(): done
MMU:enter
MMU:hw init
MMU:mapin
Does somebody know how to go further ?
In xilinx_ml300.c file, it seems that the following call is
start_kernel, but I don't know how to really debug at this point...
I had a try with print_char function but without much success...
I have a very small config file for the kernel, don't know to have a
smaller one...
kernel version : 2.6.12
gcc : 3.3.6
binutils : 2.14
Thanks in advance for any help...
xavier
[-- Attachment #2: config_kernel --]
[-- Type: text/plain, Size: 7801 bytes --]
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.12
# Mon Jun 27 12:53:17 2005
#
CONFIG_MMU=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_HAVE_DEC_LOCK=y
CONFIG_PPC=y
CONFIG_PPC32=y
CONFIG_GENERIC_NVRAM=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
#
CONFIG_LOCALVERSION="-bitsim"
# CONFIG_SWAP is not set
# CONFIG_SYSVIPC is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_SYSCTL is not set
# CONFIG_AUDIT is not set
# CONFIG_HOTPLUG is not set
# CONFIG_IKCONFIG is not set
CONFIG_EMBEDDED=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
# CONFIG_SHMEM is not set
CONFIG_CC_ALIGN_FUNCTIONS=0
CONFIG_CC_ALIGN_LABELS=0
CONFIG_CC_ALIGN_LOOPS=0
CONFIG_CC_ALIGN_JUMPS=0
CONFIG_TINY_SHMEM=y
CONFIG_BASE_SMALL=0
#
# Loadable module support
#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_OBSOLETE_MODPARM=y
CONFIG_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
#
# Processor
#
# CONFIG_6xx is not set
CONFIG_40x=y
# CONFIG_44x is not set
# CONFIG_POWER3 is not set
# CONFIG_POWER4 is not set
# CONFIG_8xx is not set
# CONFIG_E500 is not set
# CONFIG_MATH_EMULATION is not set
# CONFIG_CPU_FREQ is not set
CONFIG_4xx=y
#
# IBM 4xx options
#
# CONFIG_ASH is not set
# CONFIG_BUBINGA is not set
# CONFIG_CPCI405 is not set
# CONFIG_EP405 is not set
# CONFIG_OAK is not set
# CONFIG_REDWOOD_5 is not set
# CONFIG_REDWOOD_6 is not set
# CONFIG_SYCAMORE is not set
# CONFIG_WALNUT is not set
CONFIG_XILINX_ML300=y
CONFIG_IBM405_ERR77=y
CONFIG_IBM405_ERR51=y
CONFIG_XILINX_OCP=y
CONFIG_VIRTEX_II_PRO=y
CONFIG_EMBEDDEDBOOT=y
# CONFIG_PPC4xx_DMA is not set
CONFIG_PPC_GEN550=y
# CONFIG_PM is not set
CONFIG_UART0_TTYS0=y
# CONFIG_UART0_TTYS1 is not set
CONFIG_NOT_COHERENT_CACHE=y
#
# Platform options
#
# CONFIG_PC_KEYBOARD is not set
# CONFIG_SMP is not set
# CONFIG_PREEMPT is not set
# CONFIG_HIGHMEM is not set
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_CMDLINE_BOOL=y
CONFIG_CMDLINE="console=ttyS0,9600 root=/dev/nfs ip=dhcp"
CONFIG_ISA_DMA_API=y
#
# Bus options
#
# CONFIG_PCI is not set
# CONFIG_PCI_DOMAINS is not set
#
# PCCARD (PCMCIA/CardBus) support
#
# CONFIG_PCCARD is not set
#
# Advanced setup
#
# CONFIG_ADVANCED_OPTIONS is not set
#
# Default settings for advanced configuration options are used
#
CONFIG_HIGHMEM_START=0xfe000000
CONFIG_LOWMEM_SIZE=0x30000000
CONFIG_KERNEL_START=0xc0000000
CONFIG_TASK_SIZE=0x80000000
CONFIG_CONSISTENT_START=0xff100000
CONFIG_CONSISTENT_SIZE=0x00200000
CONFIG_BOOT_LOAD=0x00400000
#
# Device Drivers
#
#
# Generic Driver Options
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
CONFIG_DEBUG_DRIVER=y
#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
#
# Parallel port support
#
# CONFIG_PARPORT is not set
#
# Plug and Play support
#
#
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_RAM is not set
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_LBD is not set
# CONFIG_CDROM_PKTCDVD is not set
#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
# CONFIG_IOSCHED_AS is not set
CONFIG_IOSCHED_DEADLINE=y
# CONFIG_IOSCHED_CFQ is not set
#
# ATA/ATAPI/MFM/RLL support
#
# CONFIG_IDE is not set
#
# SCSI device support
#
# CONFIG_SCSI is not set
#
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set
#
# Fusion MPT device support
#
#
# IEEE 1394 (FireWire) support
#
#
# I2O device support
#
#
# Macintosh device drivers
#
#
# Networking support
#
# CONFIG_NET is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
#
# ISDN subsystem
#
#
# Telephony Support
#
# CONFIG_PHONE is not set
#
# Input device support
#
# CONFIG_INPUT is not set
#
# Hardware I/O ports
#
# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set
#
# Character devices
#
# CONFIG_VT is not set
# CONFIG_SERIAL_NONSTANDARD is not set
#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=4
# CONFIG_SERIAL_8250_EXTENDED is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
#
# IPMI
#
# CONFIG_IPMI_HANDLER is not set
#
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
# CONFIG_NVRAM is not set
# CONFIG_GEN_RTC is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
#
# Ftape, the floppy tape device driver
#
# CONFIG_AGP is not set
# CONFIG_DRM is not set
# CONFIG_RAW_DRIVER is not set
#
# TPM devices
#
#
# I2C support
#
# CONFIG_I2C is not set
#
# Dallas's 1-wire bus
#
# CONFIG_W1 is not set
#
# Misc devices
#
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
#
# Digital Video Broadcasting Devices
#
#
# Graphics support
#
# CONFIG_FB is not set
#
# Sound
#
# CONFIG_SOUND is not set
#
# USB support
#
# CONFIG_USB_ARCH_HAS_HCD is not set
# CONFIG_USB_ARCH_HAS_OHCI is not set
#
# USB Gadget Support
#
# CONFIG_USB_GADGET is not set
#
# MMC/SD Card support
#
# CONFIG_MMC is not set
#
# InfiniBand support
#
# CONFIG_INFINIBAND is not set
#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT3_FS is not set
# CONFIG_JBD is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
#
# XFS support
#
# CONFIG_XFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_QUOTA is not set
# CONFIG_DNOTIFY is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
# CONFIG_UDF_FS is not set
#
# DOS/FAT/NT Filesystems
#
# CONFIG_MSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_NTFS_FS is not set
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_SYSFS=y
# CONFIG_DEVFS_FS is not set
# CONFIG_DEVPTS_FS_XATTR is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
#
# Miscellaneous filesystems
#
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
#
# Native Language Support
#
# CONFIG_NLS is not set
#
# IBM 40x options
#
#
# Library routines
#
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC32 is not set
# CONFIG_LIBCRC32C is not set
#
# Profiling support
#
# CONFIG_PROFILING is not set
#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_MAGIC_SYSRQ is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_FS is not set
CONFIG_KGDB=y
CONFIG_KGDB_TTYS0=y
# CONFIG_KGDB_TTYS1 is not set
# CONFIG_KGDB_TTYS2 is not set
# CONFIG_KGDB_TTYS3 is not set
# CONFIG_XMON is not set
# CONFIG_BDI_SWITCH is not set
CONFIG_SERIAL_TEXT_DEBUG=y
CONFIG_PPC_OCP=y
#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
#
# Cryptographic options
#
# CONFIG_CRYPTO is not set
#
# Hardware crypto devices
#
^ permalink raw reply
* [PATCH] PPC32 mem_pieces interface cleanup
From: Jon Loeliger @ 2005-06-27 16:28 UTC (permalink / raw)
To: linuxppc-embedded@ozlabs.org
[-- Attachment #1: Type: text/plain, Size: 396 bytes --]
Guys,
As an initial step towards getting the OF Flat Dev tree
handled in the PPC32 tree, this patch cleans up some of
the interface parts of the very early mem_pieces manager
and adds some PPC64-LMB-like routines as well.
It has been built and booted on 85xx and pmac boards.
Thanks,
jdl
Signed-off-by: Jon Loeliger <jdl@freescale.com>
Signed-off-by: Kumar Gala <kumar.gala@freescale.com>
[-- Attachment #2: mem_pieces_cleanup.patch --]
[-- Type: text/x-patch, Size: 9638 bytes --]
Index: arch/ppc/mm/init.c
===================================================================
--- 413e8c09a51b5e4ee6850da2b7a65f9a9af0be9c/arch/ppc/mm/init.c (mode:100644)
+++ uncommitted/arch/ppc/mm/init.c (mode:100644)
@@ -316,7 +316,7 @@
if (init_bootmem_done) {
p = alloc_bootmem_pages(PAGE_SIZE);
} else {
- p = mem_pieces_find(PAGE_SIZE, PAGE_SIZE);
+ p = mem_pieces_find(&phys_avail, PAGE_SIZE, PAGE_SIZE);
}
return p;
}
@@ -495,10 +495,8 @@
* Initially, available physical memory is equivalent to all
* physical memory.
*/
-
- phys_avail.regions[0].address = PPC_MEMSTART;
- phys_avail.regions[0].size = total_memory;
- phys_avail.n_regions = 1;
+ mem_pieces_reset(&phys_avail);
+ mem_pieces_add(&phys_avail, PPC_MEMSTART, total_memory);
/*
* Map out the kernel text/data/bss from the available physical
Index: arch/ppc/mm/mem_pieces.c
===================================================================
--- 413e8c09a51b5e4ee6850da2b7a65f9a9af0be9c/arch/ppc/mm/mem_pieces.c (mode:100644)
+++ uncommitted/arch/ppc/mm/mem_pieces.c (mode:100644)
@@ -22,19 +22,105 @@
#include "mem_pieces.h"
-extern struct mem_pieces phys_avail;
-static void mem_pieces_print(struct mem_pieces *);
+static unsigned int __init mem_pieces_addrs_adjacent(unsigned int base1,
+ unsigned int size1,
+ unsigned int base2,
+ unsigned int size2);
+static int __init mem_pieces_regions_adjacent(struct mem_pieces *mp,
+ unsigned int r1,
+ unsigned int r2);
+static void __init mem_pieces_coalesce_regions(struct mem_pieces *mp,
+ unsigned int r1,
+ unsigned int r2);
+
+
+void __init
+mem_pieces_reset(struct mem_pieces *mp)
+{
+ /*
+ * Create a dummy zero size block which will get coalesced
+ * away later. This simplifies the mem_pieces_add() code below.
+ */
+ mp->regions[0].address = 0;
+ mp->regions[0].size = 0;
+ mp->n_regions = 1;
+}
+
+
+/*
+ * mem_pieces_add() -- Add a memory block to a sorted region table,
+ * merging adjacent blocks if possible.
+ * Returns 0 on straight add, >0 on coallsced, -1 on failure.
+ */
+
+int __init
+mem_pieces_add(struct mem_pieces *mp, unsigned int base, unsigned int size)
+{
+ unsigned int i;
+ unsigned int coalesced;
+
+ /*
+ * First try and coalesce this mem_piece with another.
+ */
+ coalesced = 0;
+ for (i = 0; i < mp->n_regions; i++) {
+ unsigned int rgnbase = mp->regions[i].address;
+ unsigned int rgnsize = mp->regions[i].size;
+ int adjacent = mem_pieces_addrs_adjacent(base, size,
+ rgnbase, rgnsize);
+ if (adjacent > 0) {
+ mp->regions[i].address -= size;
+ mp->regions[i].size += size;
+ coalesced++;
+ break;
+ } else if (adjacent < 0) {
+ mp->regions[i].size += size;
+ coalesced++;
+ break;
+ }
+ }
+
+ if ((i < mp->n_regions-1) && mem_pieces_regions_adjacent(mp, i, i+1)) {
+ mem_pieces_coalesce_regions(mp, i, i+1);
+ coalesced++;
+ }
+
+ if (coalesced) {
+ return coalesced;
+ } else if (mp->n_regions >= MEM_PIECES_MAX ) {
+ return -1;
+ }
+
+ /*
+ * Couldn't coalesce the new mem_piece, so add it to the sorted table.
+ */
+ for (i = mp->n_regions-1; i >= 0; i--) {
+ if (base < mp->regions[i].address) {
+ /* Shift up a slot. */
+ mp->regions[i+1].address = mp->regions[i].address;
+ mp->regions[i+1].size = mp->regions[i].size;
+ } else {
+ /* Insert in newly opened slot. */
+ mp->regions[i+1].address = base;
+ mp->regions[i+1].size = size;
+ break;
+ }
+ }
+ ++mp->n_regions;
+
+ return 0;
+}
+
/*
* Scan a region for a piece of a given size with the required alignment.
*/
void __init *
-mem_pieces_find(unsigned int size, unsigned int align)
+mem_pieces_find(struct mem_pieces *mp, unsigned int size, unsigned int align)
{
int i;
unsigned a, e;
- struct mem_pieces *mp = &phys_avail;
for (i = 0; i < mp->n_regions; ++i) {
a = mp->regions[i].address;
@@ -50,6 +136,7 @@
return NULL;
}
+
/*
* Remove some memory from an array of pieces
*/
@@ -59,7 +146,7 @@
{
int i, j;
unsigned int end, rs, re;
- struct reg_property *rp;
+ struct mem_pieces_property *rp;
end = start + size;
for (i = 0, rp = mp->regions; i < mp->n_regions; ++i, ++rp) {
@@ -109,17 +196,20 @@
}
}
-static void __init
+
+void __init
mem_pieces_print(struct mem_pieces *mp)
{
int i;
- for (i = 0; i < mp->n_regions; ++i)
+ for (i = 0; i < mp->n_regions; ++i) {
printk(" [%x, %x)", mp->regions[i].address,
mp->regions[i].address + mp->regions[i].size);
+ }
printk("\n");
}
+
void __init
mem_pieces_sort(struct mem_pieces *mp)
{
@@ -139,6 +229,7 @@
}
}
+
void __init
mem_pieces_coalesce(struct mem_pieces *mp)
{
@@ -161,3 +252,66 @@
}
mp->n_regions = d;
}
+
+
+unsigned int __init
+mem_pieces_get_phys_mem_size(struct mem_pieces *mp)
+{
+ int i;
+ unsigned int total = 0;
+
+ for (i = 0; i < mp->n_regions; i++) {
+ total += mp->regions[i].size;
+ }
+ return total;
+}
+
+
+static unsigned int __init
+mem_pieces_addrs_adjacent(unsigned int base1, unsigned int size1,
+ unsigned int base2, unsigned int size2)
+{
+ if (base2 == base1 + size1) {
+ return 1;
+ } else if (base1 == base2 + size2) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int __init
+mem_pieces_regions_adjacent(struct mem_pieces *mp,
+ unsigned int r1,
+ unsigned int r2)
+{
+ unsigned int base1 = mp->regions[r1].address;
+ unsigned int size1 = mp->regions[r1].size;
+ unsigned int base2 = mp->regions[r2].address;
+ unsigned int size2 = mp->regions[r2].size;
+
+ return mem_pieces_addrs_adjacent(base1, size1, base2, size2);
+}
+
+
+/*
+ * Coalesce block r2 into block r1.
+ * Assumes base addr of region 1 < base addr of region 2
+ */
+
+static void __init
+mem_pieces_coalesce_regions(struct mem_pieces *mp,
+ unsigned int r1,
+ unsigned int r2)
+{
+ unsigned int i;
+
+ mp->regions[r1].size += mp->regions[r2].size;
+ for (i = r2; i < mp->n_regions-1; i++) {
+ mp->regions[i].address = mp->regions[i+1].address;
+ mp->regions[i].size = mp->regions[i+1].size;
+ }
+ --mp->n_regions;
+
+}
Index: arch/ppc/mm/mem_pieces.h
===================================================================
--- 413e8c09a51b5e4ee6850da2b7a65f9a9af0be9c/arch/ppc/mm/mem_pieces.h (mode:100644)
+++ uncommitted/arch/ppc/mm/mem_pieces.h (mode:100644)
@@ -17,8 +17,6 @@
#ifndef __MEM_PIECES_H__
#define __MEM_PIECES_H__
-#include <asm/prom.h>
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -26,20 +24,34 @@
/* Type Definitions */
+struct mem_pieces_property {
+ unsigned int address;
+ unsigned int size;
+};
+
+
#define MEM_PIECES_MAX 32
struct mem_pieces {
int n_regions;
- struct reg_property regions[MEM_PIECES_MAX];
+ struct mem_pieces_property regions[MEM_PIECES_MAX];
};
/* Function Prototypes */
-extern void *mem_pieces_find(unsigned int size, unsigned int align);
-extern void mem_pieces_remove(struct mem_pieces *mp, unsigned int start,
+extern void mem_pieces_reset(struct mem_pieces *mp);
+extern int mem_pieces_add(struct mem_pieces *mp,
+ unsigned int base, unsigned int size);
+extern void *mem_pieces_find(struct mem_pieces *mp,
+ unsigned int size, unsigned int align);
+extern void mem_pieces_remove(struct mem_pieces *mp,
+ unsigned int start,
unsigned int size, int must_exist);
extern void mem_pieces_coalesce(struct mem_pieces *mp);
extern void mem_pieces_sort(struct mem_pieces *mp);
+extern unsigned int mem_pieces_get_phys_mem_size(struct mem_pieces *mp);
+extern void mem_pieces_print(struct mem_pieces *);
+
#ifdef __cplusplus
}
Index: arch/ppc/mm/ppc_mmu.c
===================================================================
--- 413e8c09a51b5e4ee6850da2b7a65f9a9af0be9c/arch/ppc/mm/ppc_mmu.c (mode:100644)
+++ uncommitted/arch/ppc/mm/ppc_mmu.c (mode:100644)
@@ -186,6 +186,7 @@
unsigned int hmask, mb, mb2;
unsigned int n_hpteg, lg_n_hpteg;
+ extern struct mem_pieces phys_avail;
extern unsigned int hash_page_patch_A[];
extern unsigned int hash_page_patch_B[], hash_page_patch_C[];
extern unsigned int hash_page[];
@@ -245,7 +246,7 @@
* Find some memory for the hash table.
*/
if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322);
- Hash = mem_pieces_find(Hash_size, Hash_size);
+ Hash = mem_pieces_find(&phys_avail, Hash_size, Hash_size);
cacheable_memzero(Hash, Hash_size);
_SDR1 = __pa(Hash) | SDR1_LOW_BITS;
#endif /* CONFIG_POWER4 */
Index: arch/ppc/platforms/pmac_setup.c
===================================================================
--- 413e8c09a51b5e4ee6850da2b7a65f9a9af0be9c/arch/ppc/platforms/pmac_setup.c (mode:100644)
+++ uncommitted/arch/ppc/platforms/pmac_setup.c (mode:100644)
@@ -575,7 +575,6 @@
static int __init
get_mem_prop(char *name, struct mem_pieces *mp)
{
- struct reg_property *rp;
int i, s;
unsigned int *ip;
int nac = prom_n_addr_cells(memory_node);
@@ -588,18 +587,16 @@
return 0;
}
s /= (nsc + nac) * 4;
- rp = mp->regions;
for (i = 0; i < s; ++i, ip += nac+nsc) {
+ unsigned int size;
if (nac >= 2 && ip[nac-2] != 0)
continue;
- rp->address = ip[nac-1];
if (nsc >= 2 && ip[nac+nsc-2] != 0)
- rp->size = ~0U;
+ size = ~0U;
else
- rp->size = ip[nac+nsc-1];
- ++rp;
+ size = ip[nac+nsc-1];
+ mem_pieces_add(mp, ip[nac-1], size);
}
- mp->n_regions = rp - mp->regions;
/* Make sure the pieces are sorted. */
mem_pieces_sort(mp);
@@ -620,6 +617,8 @@
unsigned long a, total;
struct mem_pieces phys_mem;
+ mem_pieces_reset(&phys_mem);
+
/*
* Find out where physical memory is, and check that it
* starts at 0 and is contiguous. It seems that RAM is
^ permalink raw reply
* [PATCH] 8xx: tlbie debugging aid (try #2)
From: Marcelo Tosatti @ 2005-06-27 14:28 UTC (permalink / raw)
To: Dan Malek; +Cc: linux-ppc-embedded
In-Reply-To: <f14f5f5aebd45879c39c6ce69f29c004@embeddededge.com>
On Sat, Jun 25, 2005 at 06:24:47PM -0400, Dan Malek wrote:
> We really want to see this generate an error. We shouldn't be
> calling this on any of the pinned spaces. In the case of initially
> mapping the kernel space, we should set up the page tables but
> not call this far down that we get here.
How about the following addressing your comments:
1) handles more than a single contiguous region by having a list_head (I thought of a
binary tree for storing the ranges but sounds like overkill at first given the
small amount of pinned regions).
2) implement as C code.
it yields
_tlbie on pinned range: c0000000-c1800000
Badness in _tlbie at arch/ppc/mm/pgtable.c:527
Call trace:
[c0005530] dump_stack+0x18/0x28
[c0003628] check_bug_trap+0x84/0xac
[c00037b0] ProgramCheckException+0x160/0x1a0
[c0002d50] ret_from_except_full+0x0/0x4c
[c000a91c] _tlbie+0x94/0xa0
[c902f018] alloc_init_module+0x18/0x40 [alloc]
[c002c4ac] sys_init_module+0x224/0x324
[c00026f0] ret_from_syscall+0x0/0x44
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -1296,6 +1296,11 @@ config BOOT_LOAD
config PIN_TLB
bool "Pinned Kernel TLBs (860 ONLY)"
depends on ADVANCED_OPTIONS && 8xx
+
+config DEBUG_PIN_TLBIE
+ bool "Check for overlapping TLB invalidates inside the pinned area"
+ depends on ADVANCED_OPTIONS && 8xx && PIN_TLB
+
endmenu
source "drivers/Kconfig"
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -494,7 +494,7 @@ _GLOBAL(_tlbia)
/*
* Flush MMU TLB for a particular address
*/
-_GLOBAL(_tlbie)
+_GLOBAL(__tlbie)
#if defined(CONFIG_40x)
tlbsx. r3, 0, r3
bne 10f
diff --git a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c
--- a/arch/ppc/mm/pgtable.c
+++ b/arch/ppc/mm/pgtable.c
@@ -32,6 +32,7 @@
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
#include <asm/io.h>
+#include <asm/tlb.h>
#include "mmu_decl.h"
@@ -469,3 +470,48 @@ exit:
return ret;
}
+#ifndef CONFIG_DEBUG_PIN_TLBIE
+
+void _tlbie(unsigned long address)
+{
+ __tlbie(address);
+}
+
+#else
+LIST_HEAD(pin_range_root);
+
+static struct pinned_range kernelbase = {
+ start: KERNELBASE,
+ end: KERNELBASE+0x1800000,
+};
+
+static struct pinned_range immr = {
+ start: IMMR,
+ end: IMMR+0x800000,
+};
+
+inline void register_pinned_entries(void)
+{
+ list_add(&kernelbase.pin_list, &pin_range_root);
+ list_add(&immr.pin_list, &pin_range_root);
+}
+
+void _tlbie(unsigned long address)
+{
+ struct list_head *l;
+ struct pinned_range *r;
+
+ list_for_each(l, &pin_range_root) {
+ r = list_entry(l, struct pinned_range, pin_list);
+
+ if (address < r->start)
+ continue;
+ if (address >= r->end)
+ continue;
+ printk("_tlbie on pinned range: %lx-%lx\n", r->start, r->end);
+ WARN_ON(1);
+ }
+
+ __tlbie(address);
+}
+#endif
diff --git a/include/asm-ppc/tlb.h b/include/asm-ppc/tlb.h
--- a/include/asm-ppc/tlb.h
+++ b/include/asm-ppc/tlb.h
@@ -18,6 +18,18 @@
#include <asm/page.h>
#include <asm/mmu.h>
+#ifdef CONFIG_DEBUG_PIN_TLBIE
+struct pinned_range {
+ unsigned long start, end;
+ struct list_head pin_list;
+};
+inline void register_pinned_entries(void);
+#else
+inline void register_pinned_entries(void)
+{
+ return;
+}
+#endif
#ifdef CONFIG_PPC_STD_MMU
/* Classic PPC with hash-table based MMU... */
diff --git a/include/asm-ppc/tlbflush.h b/include/asm-ppc/tlbflush.h
--- a/include/asm-ppc/tlbflush.h
+++ b/include/asm-ppc/tlbflush.h
@@ -13,9 +13,14 @@
#include <linux/config.h>
#include <linux/mm.h>
+extern void __tlbie(unsigned long address);
extern void _tlbie(unsigned long address);
extern void _tlbia(void);
+#ifdef CONFIG_DEBUG_PIN_TLBIE
+extern struct list_head pin_range_root;
+#endif
+
#if defined(CONFIG_4xx)
#ifndef CONFIG_44x
^ permalink raw reply
* Re: [PATCH] 8xx: map_page() skip pinned region and tlbie debugging aid
From: Marcelo Tosatti @ 2005-06-27 13:39 UTC (permalink / raw)
To: Dan Malek; +Cc: linux-ppc-embedded
In-Reply-To: <20050626143004.GA5198@logos.cnet>
On Sun, Jun 26, 2005 at 11:30:04AM -0300, Marcelo Tosatti wrote:
>
> Hi Dan,
>
> On Sat, Jun 25, 2005 at 06:24:47PM -0400, Dan Malek wrote:
> >
> > On Jun 25, 2005, at 10:53 AM, Marcelo Tosatti wrote:
> >
> > >Dan: I dont think ioremap() is an issue because it never works inside
> > >the
> > >kernel's static virtual address space (which is the only one we're
> > >interested
> > >in having pinned at the moment).
> >
> > Take a close look at the initialization code. I believe it also
> > pins the IMMR space, which is subject to ioremap().
>
> OK. Now that makes me think that the IMMR pinned entry is also always
> thrashed by the tlbie at map_page() :(
Bullshit, map_page()'s call for flush_HPTE() is conditioned by "mem_init_done",
and mapin_ram() is called before mem_init_done is set.
> The IMMR space is a 16kB window (correct?), so I wonder if it might
> be better to the use occupied pinned slot for another more accessed
> region (an 8MB one preferably!).
Thats still some food for thought...
^ permalink raw reply
* Re: [PATCH] 8xx: tlbie debugging aid (try #2)
From: Dan Malek @ 2005-06-27 20:18 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: linux-ppc-embedded
In-Reply-To: <20050627142803.GA9810@logos.cnet>
On Jun 27, 2005, at 10:28 AM, Marcelo Tosatti wrote:
> it yields
>
> _tlbie on pinned range: c0000000-c1800000
> Badness in _tlbie at arch/ppc/mm/pgtable.c:527
> Call trace:
> [c0005530] dump_stack+0x18/0x28
> [c0003628] check_bug_trap+0x84/0xac
> [c00037b0] ProgramCheckException+0x160/0x1a0
> [c0002d50] ret_from_except_full+0x0/0x4c
> [c000a91c] _tlbie+0x94/0xa0
> [c902f018] alloc_init_module+0x18/0x40 [alloc]
> [c002c4ac] sys_init_module+0x224/0x324
> [c00026f0] ret_from_syscall+0x0/0x44
How much real memory on your board?
We need to ensure VMALLOC_START is beyond
the pinned entries. We should make all of the code
much smarter to pin on the real space that is on
the board. For testing now, just make VMALLOC_OFFSET
32M, which will push the start to the 32M boundary
after the kernel.
Thanks.
-- Dan
^ permalink raw reply
* Re: [PATCH] 8xx: tlbie debugging aid (try #2)
From: Marcelo Tosatti @ 2005-06-27 14:56 UTC (permalink / raw)
To: Dan Malek; +Cc: linux-ppc-embedded
In-Reply-To: <014331894c585b85c6bb419d72110125@embeddededge.com>
Hi Dan,
On Mon, Jun 27, 2005 at 04:18:14PM -0400, Dan Malek wrote:
>
> On Jun 27, 2005, at 10:28 AM, Marcelo Tosatti wrote:
>
> >it yields
> >
> >_tlbie on pinned range: c0000000-c1800000
> >Badness in _tlbie at arch/ppc/mm/pgtable.c:527
> >Call trace:
> > [c0005530] dump_stack+0x18/0x28
> > [c0003628] check_bug_trap+0x84/0xac
> > [c00037b0] ProgramCheckException+0x160/0x1a0
> > [c0002d50] ret_from_except_full+0x0/0x4c
> > [c000a91c] _tlbie+0x94/0xa0
> > [c902f018] alloc_init_module+0x18/0x40 [alloc]
> > [c002c4ac] sys_init_module+0x224/0x324
> > [c00026f0] ret_from_syscall+0x0/0x44
Note: this was just a test module doing tlbie(0xc0000100)...
Hum, it should also print out the address in question...
> How much real memory on your board?
128M
> We need to ensure VMALLOC_START is beyond
> the pinned entries.
Right now VMALLOC_START is before the IMMR pinned space.
> We should make all of the code
> much smarter to pin on the real space that is on
> the board.
Oh! What are the side effects of such pinning as the
code is today?
The only issue I see with pinning virtual address translations
farther the the physical addresses (real space) is that we lose
some virtual space, but nothing more than that.
Is it only that?
> For testing now, just make VMALLOC_OFFSET
> 32M, which will push the start to the 32M boundary
> after the kernel.
For what purpose? Sorry I don't get you, please be more
verbose.
^ permalink raw reply
* Re: [PATCH] 8xx: map_page() skip pinned region and tlbie debugging aid
From: Dan Malek @ 2005-06-27 20:46 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: linux-ppc-embedded
In-Reply-To: <20050627133930.GA9109@logos.cnet>
On Jun 27, 2005, at 9:39 AM, Marcelo Tosatti wrote:
> Bullshit, map_page()'s call for flush_HPTE() is conditioned by
> "mem_init_done",
> and mapin_ram() is called before mem_init_done is set.
Excuse me?
>> The IMMR space is a 16kB window (correct?), so I wonder if it might
>> be better to the use occupied pinned slot for another more accessed
>> region (an 8MB one preferably!).
>
> Thats still some food for thought...
Actually, most 8xx systems map the IMMR, plus other external
devices (including flash memory), into a packed space at the top
of the address range. The 8M mapping catches the IMMR space,
but also many of these other devices subject to ioremap(). In
some systems, they trade off mapping the IMMR, or data pages,
to get an additional 8M of peripheral IO space.
The data space pinning is the big trade off right now. You can
pin 4 entries, or 32M of space. If you only have 16M of real
memory, the other two 8M entries can be used to cover IO space.
This is one (of a a few) advantages of using dynamic large
pages instead of pinned entries. You could map more 8M
spaces for IO. The problem is all of these have been custom
initialization and mapping code.
You see, this just keeps growing in features and complexity :-)
It would be nice for ioremap() to consider multiple, dynamic 8M
pages on 8xx like it does BATs on traditional PPC. It will do
this .... someday soon.
Perhaps I should go back and push some of this dynamic 8M
page stuff. It would eliminate the tlbie() problems, give us
more flexibility. Damn, not enough hours in a day ....
Thanks.
-- Dan
^ permalink raw reply
* Re: [PATCH] 8xx: tlbie debugging aid (try #2)
From: Dan Malek @ 2005-06-27 20:53 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: linux-ppc-embedded
In-Reply-To: <20050627145603.GB9810@logos.cnet>
On Jun 27, 2005, at 10:56 AM, Marcelo Tosatti wrote:
> Note: this was just a test module doing tlbie(0xc0000100)...
> Hum, it should also print out the address in question...
Oh, I see. I thought it was a bug with loading a module
in general, since it allocates from vmalloc() space.
>> How much real memory on your board?
>
> 128M
No problem.
>> We need to ensure VMALLOC_START is beyond
>> the pinned entries.
>
> Right now VMALLOC_START is before the IMMR pinned space.
Sorry, I wasn't clear :-) I meant we need to ensure VMALLOC_START
is beyond the pinned _data_ area.
> Oh! What are the side effects of such pinning as the
> code is today?
The code maps 24M of data space, plus 8M of IMMR (and anything
that follows). So, if you don't have enough real memory, you can
end up with both a pinned entry and vmalloc() trying to share the same
VM space, which is a bad thing. The problem depends on the amount
of real memory, plus the "offset" hole of the vmalloc() space.
> For what purpose? Sorry I don't get you, please be more
> verbose.
Just to prevent what I mentioned in the previous paragraph.
Since you have lots of real memory, this doesn't affect you.
Thanks.
-- Dan
^ permalink raw reply
* cpm_uart: use dpram for early console
From: Marcelo Tosatti @ 2005-06-27 15:28 UTC (permalink / raw)
To: Kumar Gala, Pantelis Antoniou, Dan Malek; +Cc: linux-ppc-embedded
Panto, Kumar,
Can something semantically equivalent to this be merged please.
m8xx_cpm_hostalloc() can't rely on using the coherent DMA allocator
early on boot because the VM is not fully up yet.
The current code relies on the "bootmem_page" allocated by
m8xx_cpm_reset(), which must be killed.
--- cpm_uart_cpm1.c.orig 2005-06-27 17:51:53.000000000 -0300
+++ cpm_uart_cpm1.c 2005-06-27 17:55:45.000000000 -0300
@@ -155,7 +155,7 @@
memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) +
L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize);
if (is_con) {
- mem_addr = (u8 *) m8xx_cpm_hostalloc(memsz);
+ mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8));
dma_addr = 0;
} else
mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr,
^ permalink raw reply
* Re: [PATCH] 8xx: map_page() skip pinned region and tlbie debugging aid
From: Benjamin Herrenschmidt @ 2005-06-28 6:30 UTC (permalink / raw)
To: Dan Malek; +Cc: linux-ppc-embedded
In-Reply-To: <f5d1cb54913dd31385d15fe1f2e5b12d@embeddededge.com>
>
> You see, this just keeps growing in features and complexity :-)
> It would be nice for ioremap() to consider multiple, dynamic 8M
> pages on 8xx like it does BATs on traditional PPC. It will do
> this .... someday soon.
You should consider 8Mb pages the way we do BATs yes, that is have
something like an array of those or use 2 PMD entries to represent them,
and then, have ioremap treat them like it does with BATs. Such 8Mb pages
could then be setup using io_block_mapping().
Note that I'll soon send the patch I told you about that makes the
virtual address picked by io_block_mapping() dynamic, so we no longer
have to do crappy assumptions all over the place :)
> Perhaps I should go back and push some of this dynamic 8M
> page stuff. It would eliminate the tlbie() problems, give us
> more flexibility. Damn, not enough hours in a day ....
Looks like a good idea though :)
Ben.
^ permalink raw reply
* Re: [PATCH] PPC32 mem_pieces interface cleanup
From: Benjamin Herrenschmidt @ 2005-06-28 6:30 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-embedded@ozlabs.org
In-Reply-To: <1119889730.25557.19.camel@cashmere.sps.mot.com>
On Mon, 2005-06-27 at 11:28 -0500, Jon Loeliger wrote:
> Guys,
>
> As an initial step towards getting the OF Flat Dev tree
> handled in the PPC32 tree, this patch cleans up some of
> the interface parts of the very early mem_pieces manager
> and adds some PPC64-LMB-like routines as well.
>
> It has been built and booted on 85xx and pmac boards.
Please make sure you CC linuxppc-dev on such patches or they'll be
missed by me and/or paulus most of the time :)
Ben.
^ permalink raw reply
* Re: [PATCH] ppc32: Remove CONFIG_PMAC_PBOOK
From: Segher Boessenkool @ 2005-06-28 7:43 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Andrew Morton, linuxppc-dev list, Linux Kernel list
In-Reply-To: <1119847159.5133.106.camel@gaston>
> This patch removes CONFIG_PMAC_PBOOK (PowerBook support). This is now
> split into CONFIG_PMAC_MEDIABAY for the actual hotswap bay that some
> powerbooks have, CONFIG_PM for power management related code, and just
> left out of any CONFIG_* option for some generally useful stuff that
> can
> be used on non-laptops as well.
Is there any real reason not to enable CONFIG_PM on all Macs?
Segher
^ permalink raw reply
* pb USB, EP8248
From: FLAMENT David @ 2005-06-28 7:52 UTC (permalink / raw)
To: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 294 bytes --]
Hello all,
I use a EP8248 and I need USB connection. When I compile with USB option in kernel, there is this message "usb-ohci currently requires PCI-bases controllers". (I use a 2.4.26 kernel Linux)
If you are a suggest or a idea, thank's for your answer .
David Flament
[-- Attachment #2: Type: text/html, Size: 1325 bytes --]
^ permalink raw reply
* Re: [PATCH] ppc32: Remove CONFIG_PMAC_PBOOK
From: Christoph Hellwig @ 2005-06-28 8:57 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Andrew Morton, linuxppc-dev list, Linux Kernel list
In-Reply-To: <1119847159.5133.106.camel@gaston>
On Mon, Jun 27, 2005 at 02:39:16PM +1000, Benjamin Herrenschmidt wrote:
> This patch removes CONFIG_PMAC_PBOOK (PowerBook support). This is now
> split into CONFIG_PMAC_MEDIABAY for the actual hotswap bay that some
> powerbooks have, CONFIG_PM for power management related code, and just
> left out of any CONFIG_* option for some generally useful stuff that can
> be used on non-laptops as well.
Can you clarify the CONFIG_PMAC_MEDIABAY for which powerbooks this
is needed exactly? AFAIK up to one of the G3 models, but you probably
know better :)
^ permalink raw reply
* GCC 3.3.1 unsigned long long issue on Powerpc 7xx
From: Srivatsan CR @ 2005-06-28 4:41 UTC (permalink / raw)
To: linuxppc-embedded; +Cc: Chandrasekhar C
[-- Attachment #1: Type: text/plain, Size: 798 bytes --]
Dear all,
We are using a third party software (support is not available :-( )
which uses unsigned long long in the code (both
kernel and user space).
We are trying to compile the same using the flag "-std=c99" (Changes
made to the CFLAGS option in Kernel and user
space Makefiles). For this we removed the -ansi option from CFLAGS
(both Kernel and user space Makefiles). The
compiler being used is GCC 3.3.1 on a 7xx platform.
Using the above mentioned method, user space code compiles properly but
the kernel code gives errors. Is there any
workaround to be done on the Kernel Makefile so that it compiles
without errors?
Requesting all your help to solve the issue. Thanks in advance for all
the help extended.
With Best Regards,
C.R.Srivatsan
[-- Attachment #2: Type: text/html, Size: 1610 bytes --]
^ permalink raw reply
* CPM2 reports CRC errors in FCC2 for good packets
From: Alex BASTOS @ 2005-06-28 13:59 UTC (permalink / raw)
To: linuxppc-embedded
Hi guys,
I am working with a MPC8248 custom board. On this, we have mixed
interfaces, with Ethernet on FCC1 working in Full Duplex 100Mbps,
and MII-generic on FCC2, working in Half-Duplex 100Mbps.
On FCC2, CPM2 reports CRC error for each received packet, but
ignoring it, packets arrive correctly. We have tested it with
a known packet (ARP broadcast) through both interfaces, and this
packet reports and CRC error on FCC2, but not in FCC1 ... but the
received packet is the same in both cases !!! (taken from buffer
pointed by RxBD):
# FCC2 : Generic-mii Half Duplex
# ARP Broadcast Packet received on board!!!
FF FF FF FF FF FF 00 10 5A A7 8A F3 08 06 00 01 08 00 06 04 00 01
00 10 5A A7 8A F3 0A 00 00 03 00 00 00 00 00 00 0A 00 00 01 00 00
00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 E7 E0 E9 46
... len: 64
CBD_SC = 1C84 (crc_error)
# FCC1 : ETHERNET Full Duplex
# ARP Broadcast Packet received on board!!!
FF FF FF FF FF FF 00 10 5A A7 8A F3 08 06 00 01 08 00 06 04 00 01
00 10 5A A7 8A F3 0A 00 00 03 00 00 00 00 00 00 0A 00 00 01 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E7 E0 E9 46
... len: 64
So, packet is received ok, but CRC error is reported.
Any idea? May it be a Hardware problem, even if packets are received
OK by the driver?
Thanks,
Alexandre BASTOS
^ permalink raw reply
* porting linux ppc on custom board, stuck in timer loop ?
From: Xavier Grave @ 2005-06-28 13:10 UTC (permalink / raw)
To: linuxppc-dev
Hi !
I still try to port linux ppc on our ppc405 based hardware, after a look
at xilinx_ml300.c file that gives the list of function calls I wait for
a call to start_kernel but I found that start_kernel is never reached...
In fact the code in head_4xx.S jumps to 0x00001000 which is Decrementer
exception :
bl machine_init
bl MMU_init
/* Go back to running unmapped so we can load up new values
* and change to using our exception vectors.
* On the 4xx, all we have to do is invalidate the TLB to clear
* the old 16M byte TLB mappings.
*/
lis r4,2f@h
ori r4,r4,2f@l
tophys(r4,r4) /* r4 seems to hold 0x00001000 */
lis r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@h
ori r3,r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@l
mtspr SPRN_SRR0,r4
mtspr SPRN_SRR1,r3
rfi
b . /* prevent prefetch past rfi */
the previous code jump to decrementer and the code after is never
reached... And so start_kernel also...
/* Load up the kernel context */
2:
sync /* Flush to memory before changing TLB */
tlbia
isync /* Flush shadow TLBs */
/* set up the PTE pointers for the Abatron bdiGDB.
*/
lis r6, swapper_pg_dir@h
ori r6, r6, swapper_pg_dir@l
lis r5, abatron_pteptrs@h
ori r5, r5, abatron_pteptrs@l
stw r5, 0xf0(r0) /* Must match your Abatron config file */
tophys(r5,r5)
stw r6, 0(r5)
/* Now turn on the MMU for real! */
lis r4,MSR_KERNEL@h
ori r4,r4,MSR_KERNEL@l
lis r3,start_kernel@h
ori r3,r3,start_kernel@l
mtspr SPRN_SRR0,r3
mtspr SPRN_SRR1,r4
rfi /* enable MMU and jump to start_kernel */
b . /* prevent prefetch past rfi */
Is this my hardware implementation that is incorrect ? Or I missed
something in my kernel configuration ?
Thanks in advance for any answer...
xavier
^ permalink raw reply
* [PATCH] 8xx: get_mmu_context() for (very) FEW_CONTEXTS and KERNEL_PREEMPT race/starvation issue
From: Guillaume Autran @ 2005-06-28 13:42 UTC (permalink / raw)
To: linux-ppc-embedded
In-Reply-To: <1119940208.5133.204.camel@gaston>
[-- Attachment #1: Type: text/plain, Size: 886 bytes --]
Hi,
I happen to notice a race condition in the mmu_context code for the 8xx
with very few context (16 MMU contexts) and kernel preemption enable. It
is hard to reproduce has it shows only when many processes are
created/destroy and the system is doing a lot of IRQ processing.
In short, one process is trying to steal a context that is in the
process of being freed (mm->context == NO_CONTEXT) but not completely
freed (nr_free_contexts == 0).
The steal_context() function does not do anything and the process stays
in the loop forever.
Anyway, I got a patch that fixes this part. Does not seem to affect
scheduling latency at all.
Comments are appreciated.
Guillaume.
--
=======================================
Guillaume Autran
Senior Software Engineer
MRV Communications, Inc.
Tel: (978) 952-4932 office
E-mail: gautran@mrv.com
=======================================
[-- Attachment #2: mmu_context.patch --]
[-- Type: text/plain, Size: 3222 bytes --]
diff -Nru --exclude=CVS linux-2.6.old/arch/ppc/mm/mmu_context.c linux-2.6/arch/ppc/mm/mmu_context.c
--- linux-2.6.old/arch/ppc/mm/mmu_context.c 2004-12-13 16:11:56.000000000 -0500
+++ linux-2.6/arch/ppc/mm/mmu_context.c 2005-06-28 09:08:13.000000000 -0400
@@ -31,9 +31,9 @@
#include <asm/tlbflush.h>
mm_context_t next_mmu_context;
+spinlock_t next_mmu_ctx_lock = SPIN_LOCK_UNLOCKED;
unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1];
#ifdef FEW_CONTEXTS
-atomic_t nr_free_contexts;
struct mm_struct *context_mm[LAST_CONTEXT+1];
void steal_context(void);
#endif /* FEW_CONTEXTS */
@@ -52,9 +52,6 @@
*/
context_map[0] = (1 << FIRST_CONTEXT) - 1;
next_mmu_context = FIRST_CONTEXT;
-#ifdef FEW_CONTEXTS
- atomic_set(&nr_free_contexts, LAST_CONTEXT - FIRST_CONTEXT + 1);
-#endif /* FEW_CONTEXTS */
}
#ifdef FEW_CONTEXTS
@@ -74,12 +71,21 @@
steal_context(void)
{
struct mm_struct *mm;
+ mm_context_t ctx = 0;
/* free up context `next_mmu_context' */
+ spin_lock(&next_mmu_ctx_lock);
+
/* if we shouldn't free context 0, don't... */
if (next_mmu_context < FIRST_CONTEXT)
next_mmu_context = FIRST_CONTEXT;
- mm = context_mm[next_mmu_context];
+
+ ctx = next_mmu_context;
+ next_mmu_context = (ctx + 1) & LAST_CONTEXT;
+
+ spin_unlock(&next_mmu_ctx_lock);
+
+ mm = context_mm[ctx];
flush_tlb_mm(mm);
destroy_context(mm);
}
diff -Nru --exclude=CVS linux-2.6.old/include/asm-ppc/mmu_context.h linux-2.6/include/asm-ppc/mmu_context.h
--- linux-2.6.old/include/asm-ppc/mmu_context.h 2004-12-13 16:11:21.000000000 -0500
+++ linux-2.6/include/asm-ppc/mmu_context.h 2005-06-28 09:08:13.000000000 -0400
@@ -100,6 +100,7 @@
* number to be free, but it usually will be.
*/
extern mm_context_t next_mmu_context;
+extern spinlock_t next_mmu_ctx_lock;
/*
* If we don't have sufficient contexts to give one to every task
@@ -108,7 +109,6 @@
*/
#if LAST_CONTEXT < 30000
#define FEW_CONTEXTS 1
-extern atomic_t nr_free_contexts;
extern struct mm_struct *context_mm[LAST_CONTEXT+1];
extern void steal_context(void);
#endif
@@ -119,24 +119,36 @@
static inline void get_mmu_context(struct mm_struct *mm)
{
mm_context_t ctx;
+ int flag;
if (mm->context != NO_CONTEXT)
return;
-#ifdef FEW_CONTEXTS
- while (atomic_dec_if_positive(&nr_free_contexts) < 0)
- steal_context();
-#endif
+
ctx = next_mmu_context;
+ flag = 0;
+
while (test_and_set_bit(ctx, context_map)) {
ctx = find_next_zero_bit(context_map, LAST_CONTEXT+1, ctx);
- if (ctx > LAST_CONTEXT)
+ if (ctx > LAST_CONTEXT) {
ctx = 0;
+#ifdef FEW_CONTEXTS
+ if( flag == 0 ) {
+ flag = 1;
+ } else {
+ ctx = next_mmu_context;
+ steal_context();
+ }
+#endif
+ }
}
+ spin_lock(&next_mmu_ctx_lock);
next_mmu_context = (ctx + 1) & LAST_CONTEXT;
mm->context = ctx;
#ifdef FEW_CONTEXTS
context_mm[ctx] = mm;
#endif
+ spin_unlock(&next_mmu_ctx_lock);
+
}
/*
@@ -150,11 +162,9 @@
static inline void destroy_context(struct mm_struct *mm)
{
if (mm->context != NO_CONTEXT) {
- clear_bit(mm->context, context_map);
+ mm_context_t ctx = mm->context;
mm->context = NO_CONTEXT;
-#ifdef FEW_CONTEXTS
- atomic_inc(&nr_free_contexts);
-#endif
+ clear_bit(ctx, context_map);
}
}
^ permalink raw reply
* Re: [PATCH] 8xx: map_page() skip pinned region and tlbie debugging aid
From: Dan Malek @ 2005-06-28 13:53 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linux-ppc-embedded
In-Reply-To: <1119940208.5133.204.camel@gaston>
On Jun 28, 2005, at 2:30 AM, Benjamin Herrenschmidt wrote:
> You should consider 8Mb pages the way we do BATs yes,
It's always been considered, just never fully implemented :-)
> Note that I'll soon send the patch I told you about that makes the
> virtual address picked by io_block_mapping() dynamic, so we no longer
> have to do crappy assumptions all over the place :)
Whatever, I'll never use it that way and no one else should either.
All of the io_block_mapping() calls should be used to set these 8M
mapped IO spaces, everyone should use ioremap() to map them,
and ioremap() has to be modified to find them for the 8xx.
Thanks.
-- Dan
^ permalink raw reply
* 2.6 support for MPC8541(e)
From: jbi130 @ 2005-06-28 14:03 UTC (permalink / raw)
To: linuxppc-embedded
I've recently received a GDA PCI-G8400 evaluation board with an
MPC8541E. It came with u-boot 1.1.2 and a 2.4.27 kernel.
Our hopes are to get a 2.6 kernel running on this device so it is in
sync with out MPC8248 based boards.
What is the status of the support for these chips? When I enable
CONFIG_SERIAL_TEXT_DEBUG I'm able to get some output, it seems to die
when initializing openpic. There also appears to be issues with the
serial console as I'm not getting printk output at all, and I think I
should be by the time start_kernel is entered.
My current 2.6.12 builds use the MPC8540_ADS configs as a base. The
2.4 that was received with the board does as well.
For now I'm not concerned with the 'E' part. My main job is to
actually add support for the security engine, but I'd like to get 2.6
up and running first. Yes, this is my first jump into machine
specific code..
Thanks.
^ permalink raw reply
* Re: 2.6 support for MPC8541(e)
From: Kumar Gala @ 2005-06-28 14:27 UTC (permalink / raw)
To: <jbi130@yahoo.com>; +Cc: linuxppc-embedded
In-Reply-To: <87zmtavasj.fsf@nimrod.unx.ca>
You probably need to port the platform code from 2.4 to 2.6 for this
board. I'm guessing you are running into some PCI config issue with
interrupts and the such.
Take a look at arch/ppc/platforms/85xx/* for examples of boards that
support 85xx processors.
- kumar
On Jun 28, 2005, at 9:03 AM, <jbi130@yahoo.com> <jbi130@yahoo.com>
wrote:
> I've recently received a GDA PCI-G8400 evaluation board with an
> MPC8541E. It came with u-boot 1.1.2 and a 2.4.27 kernel.
>
> Our hopes are to get a 2.6 kernel running on this device so it is in
> sync with out MPC8248 based boards.
>
> What is the status of the support for these chips? When I enable
> CONFIG_SERIAL_TEXT_DEBUG I'm able to get some output, it seems to die
> when initializing openpic. There also appears to be issues with the
> serial console as I'm not getting printk output at all, and I think I
> should be by the time start_kernel is entered.
>
> My current 2.6.12 builds use the MPC8540_ADS configs as a base. The
> 2.4 that was received with the board does as well.
>
> For now I'm not concerned with the 'E' part. My main job is to
> actually add support for the security engine, but I'd like to get 2.6
> up and running first. Yes, this is my first jump into machine
> specific code..
>
> Thanks.
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
^ permalink raw reply
* Re: porting linux ppc on custom board, stuck in timer loop ?
From: Xavier Grave @ 2005-06-28 15:01 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1119964226.28013.35.camel@ipnnarval>
montavista 2.4.20 kernel code from preview kit boot without any
problems... Thanks to them ! I'll have a look at the 2.6.12 kernel later
once my application run on my embedded board :-)
So sorry for the previous mail...
Le mardi 28 juin 2005 à 15:10 +0200, Xavier Grave a écrit :
> Hi !
>
> I still try to port linux ppc on our ppc405 based hardware, after a look
> at xilinx_ml300.c file that gives the list of function calls I wait for
> a call to start_kernel but I found that start_kernel is never reached...
> In fact the code in head_4xx.S jumps to 0x00001000 which is Decrementer
> exception :
>
> bl machine_init
> bl MMU_init
> /* Go back to running unmapped so we can load up new values
> * and change to using our exception vectors.
> * On the 4xx, all we have to do is invalidate the TLB to clear
> * the old 16M byte TLB mappings.
> */
> lis r4,2f@h
> ori r4,r4,2f@l
> tophys(r4,r4) /* r4 seems to hold 0x00001000 */
> lis r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@h
> ori r3,r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@l
> mtspr SPRN_SRR0,r4
> mtspr SPRN_SRR1,r3
> rfi
> b . /* prevent prefetch past rfi */
>
> the previous code jump to decrementer and the code after is never
> reached... And so start_kernel also...
>
> /* Load up the kernel context */
> 2:
> sync /* Flush to memory before changing TLB */
> tlbia
> isync /* Flush shadow TLBs */
> /* set up the PTE pointers for the Abatron bdiGDB.
> */
> lis r6, swapper_pg_dir@h
> ori r6, r6, swapper_pg_dir@l
> lis r5, abatron_pteptrs@h
> ori r5, r5, abatron_pteptrs@l
> stw r5, 0xf0(r0) /* Must match your Abatron config file */
> tophys(r5,r5)
> stw r6, 0(r5)
> /* Now turn on the MMU for real! */
> lis r4,MSR_KERNEL@h
> ori r4,r4,MSR_KERNEL@l
> lis r3,start_kernel@h
> ori r3,r3,start_kernel@l
> mtspr SPRN_SRR0,r3
> mtspr SPRN_SRR1,r4
> rfi /* enable MMU and jump to start_kernel */
> b . /* prevent prefetch past rfi */
>
> Is this my hardware implementation that is incorrect ? Or I missed
> something in my kernel configuration ?
>
> Thanks in advance for any answer...
>
> xavier
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
^ permalink raw reply
* Re: 2.6 support for MPC8541(e)
From: Clemens Koller @ 2005-06-28 16:06 UTC (permalink / raw)
To: Kumar Gala; +Cc: <jbi130@yahoo.com>, linuxppc-embedded
In-Reply-To: <A6920FBA-2DBF-4E09-9B8D-1612A4DA6AAD@freescale.com>
Hi!
I had to do the same for my MPC8540 board (Microsys PM854).
It's based on the MPC8540_ADS platform, too with
changes in PCI subsystem and Gigabit Ethernet (gianfar_phy).
Enable early serial and enjoy printk.
Try to find out, where it hangs.
Greets,
Clemens Koller
_______________________________
R&D Imaging Devices
Anagramm GmbH
Rupert-Mayer-Str. 45/1
81379 Muenchen
Germany
http://www.anagramm.de
Phone: +49-89-741518-50
Fax: +49-89-741518-19
Kumar Gala wrote:
> You probably need to port the platform code from 2.4 to 2.6 for this
> board. I'm guessing you are running into some PCI config issue with
> interrupts and the such.
>
> Take a look at arch/ppc/platforms/85xx/* for examples of boards that
> support 85xx processors.
>
> - kumar
>
> On Jun 28, 2005, at 9:03 AM, <jbi130@yahoo.com> <jbi130@yahoo.com> wrote:
>
>> I've recently received a GDA PCI-G8400 evaluation board with an
>> MPC8541E. It came with u-boot 1.1.2 and a 2.4.27 kernel.
>>
>> Our hopes are to get a 2.6 kernel running on this device so it is in
>> sync with out MPC8248 based boards.
>>
>> What is the status of the support for these chips? When I enable
>> CONFIG_SERIAL_TEXT_DEBUG I'm able to get some output, it seems to die
>> when initializing openpic. There also appears to be issues with the
>> serial console as I'm not getting printk output at all, and I think I
>> should be by the time start_kernel is entered.
>>
>> My current 2.6.12 builds use the MPC8540_ADS configs as a base. The
>> 2.4 that was received with the board does as well.
>>
>> For now I'm not concerned with the 'E' part. My main job is to
>> actually add support for the security engine, but I'd like to get 2.6
>> up and running first. Yes, this is my first jump into machine
>> specific code..
>>
>> Thanks.
>>
>> _______________________________________________
>> Linuxppc-embedded mailing list
>> Linuxppc-embedded@ozlabs.org
>> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>>
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
^ permalink raw reply
* [Fwd: [PATCH] PPC32 mem_pieces interface cleanup]
From: Jon Loeliger @ 2005-06-28 20:22 UTC (permalink / raw)
To: linuxppc-dev@ozlabs.org
Well, Ben suggested I send it here too...
And Kumar abused me too. Want to see my scar?
jdl
-----Forwarded Message-----
From: Jon Loeliger <jdl@freescale.com>
To: linuxppc-embedded@ozlabs.org <linuxppc-embedded@ozlabs.org>
Subject: [PATCH] PPC32 mem_pieces interface cleanup
Date: Mon, 27 Jun 2005 11:28:50 -0500
Guys,
As an initial step towards getting the OF Flat Dev tree
handled in the PPC32 tree, this patch cleans up some of
the interface parts of the very early mem_pieces manager
and adds some PPC64-LMB-like routines as well.
It has been built and booted on 85xx and pmac boards.
Thanks,
jdl
Signed-off-by: Jon Loeliger <jdl@freescale.com>
Signed-off-by: Kumar Gala <kumar.gala@freescale.com>
Index: arch/ppc/mm/init.c
===================================================================
--- 413e8c09a51b5e4ee6850da2b7a65f9a9af0be9c/arch/ppc/mm/init.c (mode:100644)
+++ uncommitted/arch/ppc/mm/init.c (mode:100644)
@@ -316,7 +316,7 @@
if (init_bootmem_done) {
p = alloc_bootmem_pages(PAGE_SIZE);
} else {
- p = mem_pieces_find(PAGE_SIZE, PAGE_SIZE);
+ p = mem_pieces_find(&phys_avail, PAGE_SIZE, PAGE_SIZE);
}
return p;
}
@@ -495,10 +495,8 @@
* Initially, available physical memory is equivalent to all
* physical memory.
*/
-
- phys_avail.regions[0].address = PPC_MEMSTART;
- phys_avail.regions[0].size = total_memory;
- phys_avail.n_regions = 1;
+ mem_pieces_reset(&phys_avail);
+ mem_pieces_add(&phys_avail, PPC_MEMSTART, total_memory);
/*
* Map out the kernel text/data/bss from the available physical
Index: arch/ppc/mm/mem_pieces.c
===================================================================
--- 413e8c09a51b5e4ee6850da2b7a65f9a9af0be9c/arch/ppc/mm/mem_pieces.c (mode:100644)
+++ uncommitted/arch/ppc/mm/mem_pieces.c (mode:100644)
@@ -22,19 +22,105 @@
#include "mem_pieces.h"
-extern struct mem_pieces phys_avail;
-static void mem_pieces_print(struct mem_pieces *);
+static unsigned int __init mem_pieces_addrs_adjacent(unsigned int base1,
+ unsigned int size1,
+ unsigned int base2,
+ unsigned int size2);
+static int __init mem_pieces_regions_adjacent(struct mem_pieces *mp,
+ unsigned int r1,
+ unsigned int r2);
+static void __init mem_pieces_coalesce_regions(struct mem_pieces *mp,
+ unsigned int r1,
+ unsigned int r2);
+
+
+void __init
+mem_pieces_reset(struct mem_pieces *mp)
+{
+ /*
+ * Create a dummy zero size block which will get coalesced
+ * away later. This simplifies the mem_pieces_add() code below.
+ */
+ mp->regions[0].address = 0;
+ mp->regions[0].size = 0;
+ mp->n_regions = 1;
+}
+
+
+/*
+ * mem_pieces_add() -- Add a memory block to a sorted region table,
+ * merging adjacent blocks if possible.
+ * Returns 0 on straight add, >0 on coallsced, -1 on failure.
+ */
+
+int __init
+mem_pieces_add(struct mem_pieces *mp, unsigned int base, unsigned int size)
+{
+ unsigned int i;
+ unsigned int coalesced;
+
+ /*
+ * First try and coalesce this mem_piece with another.
+ */
+ coalesced = 0;
+ for (i = 0; i < mp->n_regions; i++) {
+ unsigned int rgnbase = mp->regions[i].address;
+ unsigned int rgnsize = mp->regions[i].size;
+ int adjacent = mem_pieces_addrs_adjacent(base, size,
+ rgnbase, rgnsize);
+ if (adjacent > 0) {
+ mp->regions[i].address -= size;
+ mp->regions[i].size += size;
+ coalesced++;
+ break;
+ } else if (adjacent < 0) {
+ mp->regions[i].size += size;
+ coalesced++;
+ break;
+ }
+ }
+
+ if ((i < mp->n_regions-1) && mem_pieces_regions_adjacent(mp, i, i+1)) {
+ mem_pieces_coalesce_regions(mp, i, i+1);
+ coalesced++;
+ }
+
+ if (coalesced) {
+ return coalesced;
+ } else if (mp->n_regions >= MEM_PIECES_MAX ) {
+ return -1;
+ }
+
+ /*
+ * Couldn't coalesce the new mem_piece, so add it to the sorted table.
+ */
+ for (i = mp->n_regions-1; i >= 0; i--) {
+ if (base < mp->regions[i].address) {
+ /* Shift up a slot. */
+ mp->regions[i+1].address = mp->regions[i].address;
+ mp->regions[i+1].size = mp->regions[i].size;
+ } else {
+ /* Insert in newly opened slot. */
+ mp->regions[i+1].address = base;
+ mp->regions[i+1].size = size;
+ break;
+ }
+ }
+ ++mp->n_regions;
+
+ return 0;
+}
+
/*
* Scan a region for a piece of a given size with the required alignment.
*/
void __init *
-mem_pieces_find(unsigned int size, unsigned int align)
+mem_pieces_find(struct mem_pieces *mp, unsigned int size, unsigned int align)
{
int i;
unsigned a, e;
- struct mem_pieces *mp = &phys_avail;
for (i = 0; i < mp->n_regions; ++i) {
a = mp->regions[i].address;
@@ -50,6 +136,7 @@
return NULL;
}
+
/*
* Remove some memory from an array of pieces
*/
@@ -59,7 +146,7 @@
{
int i, j;
unsigned int end, rs, re;
- struct reg_property *rp;
+ struct mem_pieces_property *rp;
end = start + size;
for (i = 0, rp = mp->regions; i < mp->n_regions; ++i, ++rp) {
@@ -109,17 +196,20 @@
}
}
-static void __init
+
+void __init
mem_pieces_print(struct mem_pieces *mp)
{
int i;
- for (i = 0; i < mp->n_regions; ++i)
+ for (i = 0; i < mp->n_regions; ++i) {
printk(" [%x, %x)", mp->regions[i].address,
mp->regions[i].address + mp->regions[i].size);
+ }
printk("\n");
}
+
void __init
mem_pieces_sort(struct mem_pieces *mp)
{
@@ -139,6 +229,7 @@
}
}
+
void __init
mem_pieces_coalesce(struct mem_pieces *mp)
{
@@ -161,3 +252,66 @@
}
mp->n_regions = d;
}
+
+
+unsigned int __init
+mem_pieces_get_phys_mem_size(struct mem_pieces *mp)
+{
+ int i;
+ unsigned int total = 0;
+
+ for (i = 0; i < mp->n_regions; i++) {
+ total += mp->regions[i].size;
+ }
+ return total;
+}
+
+
+static unsigned int __init
+mem_pieces_addrs_adjacent(unsigned int base1, unsigned int size1,
+ unsigned int base2, unsigned int size2)
+{
+ if (base2 == base1 + size1) {
+ return 1;
+ } else if (base1 == base2 + size2) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int __init
+mem_pieces_regions_adjacent(struct mem_pieces *mp,
+ unsigned int r1,
+ unsigned int r2)
+{
+ unsigned int base1 = mp->regions[r1].address;
+ unsigned int size1 = mp->regions[r1].size;
+ unsigned int base2 = mp->regions[r2].address;
+ unsigned int size2 = mp->regions[r2].size;
+
+ return mem_pieces_addrs_adjacent(base1, size1, base2, size2);
+}
+
+
+/*
+ * Coalesce block r2 into block r1.
+ * Assumes base addr of region 1 < base addr of region 2
+ */
+
+static void __init
+mem_pieces_coalesce_regions(struct mem_pieces *mp,
+ unsigned int r1,
+ unsigned int r2)
+{
+ unsigned int i;
+
+ mp->regions[r1].size += mp->regions[r2].size;
+ for (i = r2; i < mp->n_regions-1; i++) {
+ mp->regions[i].address = mp->regions[i+1].address;
+ mp->regions[i].size = mp->regions[i+1].size;
+ }
+ --mp->n_regions;
+
+}
Index: arch/ppc/mm/mem_pieces.h
===================================================================
--- 413e8c09a51b5e4ee6850da2b7a65f9a9af0be9c/arch/ppc/mm/mem_pieces.h (mode:100644)
+++ uncommitted/arch/ppc/mm/mem_pieces.h (mode:100644)
@@ -17,8 +17,6 @@
#ifndef __MEM_PIECES_H__
#define __MEM_PIECES_H__
-#include <asm/prom.h>
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -26,20 +24,34 @@
/* Type Definitions */
+struct mem_pieces_property {
+ unsigned int address;
+ unsigned int size;
+};
+
+
#define MEM_PIECES_MAX 32
struct mem_pieces {
int n_regions;
- struct reg_property regions[MEM_PIECES_MAX];
+ struct mem_pieces_property regions[MEM_PIECES_MAX];
};
/* Function Prototypes */
-extern void *mem_pieces_find(unsigned int size, unsigned int align);
-extern void mem_pieces_remove(struct mem_pieces *mp, unsigned int start,
+extern void mem_pieces_reset(struct mem_pieces *mp);
+extern int mem_pieces_add(struct mem_pieces *mp,
+ unsigned int base, unsigned int size);
+extern void *mem_pieces_find(struct mem_pieces *mp,
+ unsigned int size, unsigned int align);
+extern void mem_pieces_remove(struct mem_pieces *mp,
+ unsigned int start,
unsigned int size, int must_exist);
extern void mem_pieces_coalesce(struct mem_pieces *mp);
extern void mem_pieces_sort(struct mem_pieces *mp);
+extern unsigned int mem_pieces_get_phys_mem_size(struct mem_pieces *mp);
+extern void mem_pieces_print(struct mem_pieces *);
+
#ifdef __cplusplus
}
Index: arch/ppc/mm/ppc_mmu.c
===================================================================
--- 413e8c09a51b5e4ee6850da2b7a65f9a9af0be9c/arch/ppc/mm/ppc_mmu.c (mode:100644)
+++ uncommitted/arch/ppc/mm/ppc_mmu.c (mode:100644)
@@ -186,6 +186,7 @@
unsigned int hmask, mb, mb2;
unsigned int n_hpteg, lg_n_hpteg;
+ extern struct mem_pieces phys_avail;
extern unsigned int hash_page_patch_A[];
extern unsigned int hash_page_patch_B[], hash_page_patch_C[];
extern unsigned int hash_page[];
@@ -245,7 +246,7 @@
* Find some memory for the hash table.
*/
if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322);
- Hash = mem_pieces_find(Hash_size, Hash_size);
+ Hash = mem_pieces_find(&phys_avail, Hash_size, Hash_size);
cacheable_memzero(Hash, Hash_size);
_SDR1 = __pa(Hash) | SDR1_LOW_BITS;
#endif /* CONFIG_POWER4 */
Index: arch/ppc/platforms/pmac_setup.c
===================================================================
--- 413e8c09a51b5e4ee6850da2b7a65f9a9af0be9c/arch/ppc/platforms/pmac_setup.c (mode:100644)
+++ uncommitted/arch/ppc/platforms/pmac_setup.c (mode:100644)
@@ -575,7 +575,6 @@
static int __init
get_mem_prop(char *name, struct mem_pieces *mp)
{
- struct reg_property *rp;
int i, s;
unsigned int *ip;
int nac = prom_n_addr_cells(memory_node);
@@ -588,18 +587,16 @@
return 0;
}
s /= (nsc + nac) * 4;
- rp = mp->regions;
for (i = 0; i < s; ++i, ip += nac+nsc) {
+ unsigned int size;
if (nac >= 2 && ip[nac-2] != 0)
continue;
- rp->address = ip[nac-1];
if (nsc >= 2 && ip[nac+nsc-2] != 0)
- rp->size = ~0U;
+ size = ~0U;
else
- rp->size = ip[nac+nsc-1];
- ++rp;
+ size = ip[nac+nsc-1];
+ mem_pieces_add(mp, ip[nac-1], size);
}
- mp->n_regions = rp - mp->regions;
/* Make sure the pieces are sorted. */
mem_pieces_sort(mp);
@@ -620,6 +617,8 @@
unsigned long a, total;
struct mem_pieces phys_mem;
+ mem_pieces_reset(&phys_mem);
+
/*
* Find out where physical memory is, and check that it
* starts at 0 and is contiguous. It seems that RAM is
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox