diff options
Diffstat (limited to 'arch/arm')
28 files changed, 1375 insertions, 952 deletions
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 796f812ab..f60dc3564 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -6,6 +6,66 @@ #include <linux/linkage.h> .section ".start", #alloc, #execinstr + +/* + * Debugging stuff + */ + .macro kputc,val + mov r0, \val + bl putc + .endm + + .macro kphex,val,len + mov r0, \val + mov r1, #\len + bl phex + .endm + + .macro debug_reloc_start +#ifdef DEBUG + kputc #'\n' + kphex r6, 8 + kputc #':' + kphex r5, 8 + kputc #'-' + kphex r8, 8 + kputc #'>' + kphex r4, 8 + kputc #'\n' +#endif + .endm + + .macro debug_reloc_end +#ifdef DEBUG + mov r8, r0 + kphex r5, 8 + kputc #'-' + kphex r8, 8 + kputc #'\n' + mov r0, r4 + bl memdump +#endif + .endm + +#if 0 + .macro loadsp, rb + mov \rb, #0x7c000000 + .endm + + .macro writeb, rb + strb \rb, [r3, #0x3f8] + .endm +#else + .macro loadsp, rb + mov \rb, #0x03000000 + orr \rb, \rb, #0x00010000 + .endm + + .macro writeb, rb + strb \rb, [r3, #0x3f8 << 2] + .endm +#endif + /* * sort out different calling conventions */ @@ -42,6 +102,8 @@ start: cmp r2, r3 blt 1b + bl cache_on + mov r1, sp @ malloc space above stack add r2, sp, #0x10000 @ 64k max @@ -77,15 +139,87 @@ start: cmp r2, r3 blt 1b - eor r1, r6, #0x44 << 24 @ SA-110 or SA-1100? - eor r1, r1, #0x01 << 16 - eor r1, r1, #0xa1 << 8 - movs r1, r1, lsr #5 - mcreq p15, 0, r1, c7, c7, 0 @ flush I & D-cache - mcreq p15, 0, r1, c7, c10, 4 @ drain WB + bl cache_clean_flush add pc, r5, r0 @ call relocation code /* + * Page table physical address list + */ + .align 5 + .type pgtable,#object +pgtable: .word 0x00004000 @ 0x00 + .word 0x10004000 @ 0x01 + .word 0x00000000 @ 0x02 + .word 0x40004000 @ 0x03 + .word 0x00004000 @ 0x04 + .word 0x00004000 @ 0x05 + .word 0x00004000 @ 0x06 + .word 0x80004000 @ 0x07 + .word 0x00004000 @ 0x08 + .word 0x00000000 @ 0x09 + .word 0x00000000 @ 0x0a + .word 0x00000000 @ 0x0b + .word 0x00000000 @ 0x0c + .word 0x00000000 @ 0x0d + .word 0x10004000 @ 0x0e + .word 0x08004000 @ 0x0f + .word 0xc0004000 @ 0x10 + .size pgtable,. - pgtable +1: + + .type LC0, #object +LC0: .word __bss_start + .word _end + .word _load_addr + .word _start + .word user_stack+4096 + .size LC0, . - LC0 + + .align 5 +cache_on: ldr r1, proc_sa110_type + eor r1, r1, r6 + movs r1, r1, lsr #5 + movne pc, lr + cmp r7, #(1b - pgtable) >> 2 + movge pc, lr + adr r3, pgtable + ldr r3, [r3, r7, lsl #2] + teq r3, #0 + moveq pc, lr +/* + * Initialise the page tables + */ + mov r0, r3 + mov r8, r0, lsr #18 + mov r8, r8, lsl #18 @ start of RAM + add r9, r8, #0x20000000 @ the maximum RAM size + mov r1, #0x12 + orr r1, r1, #3 << 10 + add r2, r3, #16384 +1: cmp r1, r8 @ if virt > start of RAM + orrge r1, r1, #0x0c @ set cacheable, bufferable + cmp r1, r9 @ if virt > end of RAM + bicge r1, r1, #0x0c @ clear cacheable, bufferable + str r1, [r0], #4 @ 1:1 mapping + add r1, r1, #1048576 + teq r0, r2 + bne 1b + + mov r0, #0 + mcr p15, 0, r0, c7, c10, 4 @ drain write buffer + mcr p15, 0, r0, c8, c7 @ flush I,D TLBs + mcr p15, 0, r3, c2, c0 @ load page table pointer + mov r0, #-1 + mcr p15, 0, r0, c3, c0 @ load domain access register + mrc p15, 0, r0, c1, c0 + orr r0, r0, #0x1000 @ I-cache enable +#ifndef DEBUG + orr r0, r0, #0x003d @ Write buffer, mmu +#endif + mcr p15, 0, r0, c1, c0 + mov pc, lr + +/* * r0 = decompressed kernel length * r1-r3 = unused * r4 = kernel execution address @@ -94,87 +228,68 @@ start: * r7 = architecture ID * r8-r14 = unused */ + .align 5 reloc_start: add r8, r5, r0 -#if 0 - mov r0, #'\n' - bl putc - mov r0, r6 - mov r1, #8 - bl phex - mov r0, #':' - bl putc - mov r0, r5 - mov r1, #8 - bl phex - mov r0, #'-' - bl putc - mov r0, r8 - mov r1, #8 - bl phex - mov r0, #'>' - bl putc - mov r0, r4 - mov r1, #8 - bl phex - mov r0, #'\n' - bl putc -#endif - mov r0, r8 + debug_reloc_start mov r1, r4 1: .rept 4 - ldmia r5!, {r2, r3, r8 - r13} @ relocate kernel - stmia r1!, {r2, r3, r8 - r13} + ldmia r5!, {r0, r2, r3, r9 - r13} @ relocate kernel + stmia r1!, {r0, r2, r3, r9 - r13} .endr - cmp r5, r0 + cmp r5, r8 blt 1b -#if 0 - mov r8, r0 - mov r0, r5 - mov r1, #8 - bl phex - mov r0, #'-' - bl putc - mov r0, r8 - mov r1, #8 - bl phex - mov r0, #'\n' - bl putc - mov r0, r4 - bl memdump -#endif - eor r0, r6, #0x44 << 24 @ SA-110 or SA-1100? - eor r0, r0, #0x01 << 16 - eor r0, r0, #0xa1 << 8 - movs r0, r0, lsr #5 - mcreq p15, 0, r0, c7, c7, 0 @ flush I cache - mcreq p15, 0, r1, c7, c10, 4 @ drain WB - -call_kernel: mov r0, #0 + debug_reloc_end + +call_kernel: bl cache_clean_flush + bl cache_off + mov r0, #0 mov r1, r7 @ restore architecture number mov pc, r4 @ call kernel -phexbuf: .space 12 + .type proc_sa110_type,#object +proc_sa110_type: + .word 0x4401a100 + .size proc_sa110_type, . - proc_sa110_type -#if 0 - .macro loadsp, rb - mov \rb, #0x7c000000 - .endm +/* + * Turn off StrongARM cache and MMU + */ + .align 5 +cache_off: ldr r1, proc_sa110_type + eor r1, r1, r6 + movs r1, r1, lsr #5 + movne pc, lr + mrc p15, 0, r0, c1, c0 + bic r0, r0, #0x000d + mcr p15, 0, r0, c1, c0 + mov pc, lr - .macro writeb, rb - strb \rb, [r3, #0x3f8] - .endm -#else - .macro loadsp, rb - mov \rb, #0x03000000 - orr \rb, \rb, #0x00010000 - .endm +/* + * Clean and flush the cache to maintain consistency. + */ + .align 5 +cache_clean_flush: + ldr r1, proc_sa110_type @ SA-110 or SA-1100? + eor r1, r1, r6 + movs r1, r1, lsr #5 + movne pc, lr - .macro writeb, rb - strb \rb, [r3, #0x3f8 << 2] - .endm -#endif + bic r1, pc, #31 + add r2, r1, #32768 +1: ldr r12, [r1], #32 + teq r1, r2 + bne 1b + + mcr p15, 0, r1, c7, c7, 0 @ flush I cache + mcr p15, 0, r1, c7, c10, 4 @ drain WB + mov pc, lr + +#ifdef DEBUG + .type phexbuf,#object +phexbuf: .space 12 + .size phexbuf, . - phexbuf phex: adr r3, phexbuf mov r2, #0 @@ -240,14 +355,10 @@ memdump: mov r12, r0 cmp r11, #64 blt 2b mov pc, r10 +#endif + reloc_end: -LC0: .word __bss_start - .word _end - .word _load_addr - .word _start - .word user_stack+4096 .align - .section ".stack" user_stack: .space 4096 diff --git a/arch/arm/config.in b/arch/arm/config.in index fa124b5fd..f00835051 100644 --- a/arch/arm/config.in +++ b/arch/arm/config.in @@ -137,9 +137,6 @@ else define_bool CONFIG_ISA_DMA n fi -define_bool CONFIG_SBUS n -define_bool CONFIG_PCMCIA n - if [ "$CONFIG_CPU_32" = "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then bool 'Kernel-mode alignment trap handler' CONFIG_ALIGNMENT_TRAP fi @@ -222,7 +219,6 @@ if [ "$CONFIG_ARCH_ACORN" = "y" ]; then fi fi - #source drivers/misc/Config.in if [ "$CONFIG_VT" = "y" ]; then diff --git a/arch/arm/def-configs/ebsa110 b/arch/arm/def-configs/ebsa110 index 0e4acdebc..09fff229c 100644 --- a/arch/arm/def-configs/ebsa110 +++ b/arch/arm/def-configs/ebsa110 @@ -2,6 +2,12 @@ # Automatically generated make config: don't edit # CONFIG_ARM=y +CONFIG_UID16=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y # # System and processor type @@ -12,20 +18,13 @@ CONFIG_ARM=y CONFIG_ARCH_EBSA110=y # CONFIG_FOOTBRIDGE is not set # CONFIG_ARCH_ACORN is not set -# CONFIG_ISA_DMA is not set CONFIG_CPU_32=y # CONFIG_CPU_26 is not set -# CONFIG_CPU_ARM2 is not set -# CONFIG_CPU_ARM3 is not set -# CONFIG_CPU_ARM6 is not set -# CONFIG_CPU_ARM7 is not set +CONFIG_CPU_32v4=y CONFIG_CPU_SA110=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -# CONFIG_TEXT_SECTIONS is not set +# CONFIG_PCI is not set +# CONFIG_ISA is not set +# CONFIG_ISA_DMA is not set # # Loadable module support @@ -42,29 +41,52 @@ CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_NWFPE is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set CONFIG_BINFMT_AOUT=y -CONFIG_BINFMT_ELF=m +CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Parallel port support +# CONFIG_PARPORT=y CONFIG_PARPORT_PC=y +CONFIG_PARPORT_PC_FIFO=y +CONFIG_PARPORT_PC_SUPERIO=y +# CONFIG_PARPORT_ARC is not set +# CONFIG_PARPORT_AMIGA is not set +# CONFIG_PARPORT_MFC3 is not set +# CONFIG_PARPORT_ATARI is not set +# CONFIG_PARPORT_SUNBPP is not set +# CONFIG_PARPORT_OTHER is not set +CONFIG_PARPORT_1284=y CONFIG_CMDLINE="root=/dev/nfs rw mem=16M console=ttyS1,38400n8" CONFIG_LEDS=y # -# Plug and Play support +# I2O device support # -# CONFIG_PNP is not set +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set # -# Block devices +# Plug and Play configuration # -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_IDE is not set +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set # -# Please see Documentation/ide.txt for help/info on IDE drives +# Block devices # -# CONFIG_BLK_DEV_HD_ONLY is not set +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set # # Additional Block Devices @@ -74,10 +96,6 @@ CONFIG_BLK_DEV_NBD=m # CONFIG_BLK_DEV_MD is not set CONFIG_BLK_DEV_RAM=y # CONFIG_BLK_DEV_INITRD is not set -# CONFIG_BLK_DEV_XD is not set -CONFIG_PARIDE_PARPORT=y -# CONFIG_PARIDE is not set -# CONFIG_BLK_DEV_HD is not set # # Character devices @@ -94,29 +112,39 @@ CONFIG_SERIAL_EXTENDED=y # CONFIG_SERIAL_NONSTANDARD is not set # CONFIG_UNIX98_PTYS is not set CONFIG_PRINTER=m -CONFIG_PRINTER_READBACK=y -CONFIG_MOUSE=y +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set + +# +# I2C support +# +# CONFIG_I2C is not set # # Mice # -# CONFIG_ATIXL_BUSMOUSE is not set # CONFIG_BUSMOUSE is not set -# CONFIG_MS_BUSMOUSE is not set +CONFIG_MOUSE=y # CONFIG_PSMOUSE is not set # CONFIG_82C710_MOUSE is not set # CONFIG_PC110_PAD is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set # CONFIG_QIC02_TAPE is not set -CONFIG_WATCHDOG=y # # Watchdog Cards # +CONFIG_WATCHDOG=y # CONFIG_WATCHDOG_NOWAYOUT is not set # CONFIG_WDT is not set CONFIG_SOFT_WATCHDOG=y # CONFIG_PCWATCHDOG is not set # CONFIG_ACQUIRE_WDT is not set +# CONFIG_MIXCOMWD is not set # CONFIG_NVRAM is not set # CONFIG_RTC is not set @@ -124,64 +152,92 @@ CONFIG_SOFT_WATCHDOG=y # Video For Linux # # CONFIG_VIDEO_DEV is not set - -# -# Joystick support -# -# CONFIG_JOYSTICK is not set # CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set # # Ftape, the floppy tape device driver # # CONFIG_FTAPE is not set +# CONFIG_DRM is not set +# CONFIG_DRM_TDFX is not set +# CONFIG_AGP is not set # # Networking options # CONFIG_PACKET=m -# CONFIG_NETLINK is not set -CONFIG_FIREWALL=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +CONFIG_RTNETLINK=y +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_RTNETLINK=y +CONFIG_NETLINK=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_FWMARK=y +CONFIG_IP_ROUTE_NAT=y +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_TOS is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +# CONFIG_IP_ROUTE_LARGE_TABLES is not set CONFIG_IP_PNP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set -CONFIG_IP_FIREWALL=y -CONFIG_IP_ALWAYS_DEFRAG=y -# CONFIG_IP_TRANSPARENT_PROXY is not set -CONFIG_IP_MASQUERADE=y - -# -# Protocol-specific masquerading support will be built as modules. -# -CONFIG_IP_MASQUERADE_ICMP=y - -# -# Protocol-specific masquerading support will be built as modules. -# -# CONFIG_IP_MASQUERADE_MOD is not set # CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set +# CONFIG_IP_MROUTE is not set +CONFIG_IP_ALIAS=y +# CONFIG_ARPD is not set CONFIG_SYN_COOKIES=y # # (it is safe to leave these untouched) # -# CONFIG_INET_RARP is not set # CONFIG_SKB_LARGE is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=y +CONFIG_IP_NF_FTP=y +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_LIMIT=y +# CONFIG_IP_NF_MATCH_MAC is not set +CONFIG_IP_NF_MATCH_MARK=y +CONFIG_IP_NF_MATCH_MULTIPORT=y +CONFIG_IP_NF_MATCH_TOS=y +CONFIG_IP_NF_MATCH_STATE=y +# CONFIG_IP_NF_MATCH_UNCLEAN is not set +# CONFIG_IP_NF_MATCH_OWNER is not set +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +# CONFIG_IP_NF_TARGET_MIRROR is not set +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_TARGET_TOS=y +CONFIG_IP_NF_TARGET_MARK=y +CONFIG_IP_NF_TARGET_LOG=y # CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set # # # # CONFIG_IPX is not set # CONFIG_ATALK is not set +# CONFIG_DECNET is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_BRIDGE is not set @@ -190,7 +246,6 @@ CONFIG_SYN_COOKIES=y # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set # CONFIG_NET_HW_FLOWCONTROL is not set -# CONFIG_CPU_IS_SLOW is not set # # QoS and/or fair queueing @@ -203,7 +258,7 @@ CONFIG_SYN_COOKIES=y # CONFIG_HAMRADIO is not set # -# IrDA subsystem support +# IrDA (infrared) support # # CONFIG_IRDA is not set @@ -211,37 +266,72 @@ CONFIG_SYN_COOKIES=y # Network device support # CONFIG_NETDEVICES=y + +# +# ARCnet devices +# # CONFIG_ARCNET is not set -# CONFIG_DUMMY is not set +CONFIG_DUMMY=m +# CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# CONFIG_NET_ETHERNET=y CONFIG_ARM_AM79C961A=y # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_RTL8139 is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_ACENIC is not set +# CONFIG_AT1700 is not set +# CONFIG_DEPCA is not set # CONFIG_NET_ISA is not set -# CONFIG_NET_EISA is not set +# CONFIG_NET_PCI is not set # CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_YELLOWFIN is not set +# CONFIG_ACENIC is not set +# CONFIG_SK98LIN is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set -# CONFIG_DLCI is not set # CONFIG_PLIP is not set CONFIG_PPP=y +CONFIG_PPP_ASYNC=y +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +# CONFIG_SLIP is not set # -# CCP compressors for PPP are only built as modules. +# Wireless LAN (non-hamradio) # -# CONFIG_SLIP is not set # CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# # CONFIG_TR is not set -# CONFIG_SHAPER is not set -# CONFIG_HOSTESS_SV11 is not set -# CONFIG_COSA is not set +# CONFIG_NET_FC is not set # CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set # # SCSI support @@ -249,27 +339,35 @@ CONFIG_PPP=y # CONFIG_SCSI is not set # -# Filesystems +# File systems # # CONFIG_QUOTA is not set -CONFIG_AUTOFS_FS=m +CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set # CONFIG_ISO9660_FS is not set # CONFIG_JOLIET is not set CONFIG_MINIX_FS=y # CONFIG_NTFS_FS is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS is not set # CONFIG_QNX4FS_FS is not set # CONFIG_ROMFS_FS is not set # CONFIG_EXT2_FS is not set # CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set # CONFIG_UFS_FS is not set # @@ -287,22 +385,28 @@ CONFIG_LOCKD=y # # Partition Types # +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set # CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set # CONFIG_MAC_PARTITION is not set # CONFIG_MSDOS_PARTITION is not set # CONFIG_SGI_PARTITION is not set # CONFIG_SUN_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ACORN_PARTITION is not set # CONFIG_NLS is not set # +# USB support +# +# CONFIG_USB is not set + +# # Kernel hacking # -CONFIG_FRAME_POINTER=y +# CONFIG_FRAME_POINTER is not set CONFIG_DEBUG_ERRORS=y # CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_INFO is not set # CONFIG_MAGIC_SYSRQ is not set -# CONFIG_ARTHUR is not set # CONFIG_DEBUG_LL is not set diff --git a/arch/arm/defconfig b/arch/arm/defconfig index c5b389476..077eef8b3 100644 --- a/arch/arm/defconfig +++ b/arch/arm/defconfig @@ -536,8 +536,8 @@ CONFIG_BLK_DEV_IDEDMA=y CONFIG_IDEDMA_PCI_EXPERIMENTAL=y # CONFIG_IDEDMA_PCI_WIP is not set # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set -# CONFIG_BLK_DEV_AEC6210 is not set -# CONFIG_AEC6210_TUNING is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set # CONFIG_BLK_DEV_ALI15X3 is not set # CONFIG_WDC_ALI15X3 is not set # CONFIG_BLK_DEV_AMD7409 is not set diff --git a/arch/arm/kernel/arch.c b/arch/arm/kernel/arch.c index e9cca7748..717ba4ca9 100644 --- a/arch/arm/kernel/arch.c +++ b/arch/arm/kernel/arch.c @@ -1,45 +1,39 @@ /* * linux/arch/arm/kernel/arch.c * - * Architecture specifics + * Architecture specific fixups. This is where any + * parameters in the params struct are fixed up, or + * any additional architecture specific information + * is pulled from the params struct. */ #include <linux/config.h> #include <linux/tty.h> #include <linux/init.h> +#include <asm/dec21285.h> #include <asm/elf.h> #include <asm/setup.h> #include <asm/system.h> #include "arch.h" -extern unsigned int system_rev; -extern unsigned int system_serial_low; -extern unsigned int system_serial_high; - unsigned int vram_size; -#ifdef CONFIG_ARCH_ACORN -unsigned int memc_ctrl_reg; -unsigned int number_mfm_drives; -#endif extern void setup_initrd(unsigned int start, unsigned int size); extern void setup_ramdisk(int doload, int prompt, int start, unsigned int rd_sz); -/* - * Architecture specific fixups. This is where any - * parameters in the params struct are fixed up, or - * any additional architecture specific information - * is pulled from the params struct. - */ +#ifdef CONFIG_ARCH_ACORN + +unsigned int memc_ctrl_reg; +unsigned int number_mfm_drives; + static void __init fixup_acorn(struct machine_desc *desc, struct param_struct *params, char **cmdline, struct meminfo *mi) { -#ifdef CONFIG_ARCH_ACORN - int i; - if (machine_is_riscpc()) { + int i; + /* * RiscPC can't handle half-word loads and stores */ @@ -69,9 +63,36 @@ fixup_acorn(struct machine_desc *desc, struct param_struct *params, } memc_ctrl_reg = params->u1.s.memc_control_reg; number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3; -#endif } +#ifdef CONFIG_ARCH_RPC +MACHINE_START(RISCPC, "Acorn-RiscPC") + MAINTAINER("Russell King") + BOOT_MEM(0x10000000, 0x03000000, 0xe0000000) + BOOT_PARAMS(0x10000100) + DISABLE_PARPORT(0) + DISABLE_PARPORT(1) + FIXUP(fixup_acorn) +MACHINE_END +#endif +#ifdef CONFIG_ARCH_ARC +MACHINE_START(ARCHIMEDES, "Acorn-Archimedes") + MAINTAINER("Dave Gilbert") + BOOT_PARAMS(0x0207c000) + FIXUP(fixup_acorn) +MACHINE_END +#endif +#ifdef CONFIG_ARCH_A5K +MACHINE_START(A5K, "Acorn-A5000") + MAINTAINER("Russell King") + BOOT_PARAMS(0x0207c000) + FIXUP(fixup_acorn) +MACHINE_END +#endif +#endif + +#ifdef CONFIG_ARCH_EBSA285 + static void __init fixup_ebsa285(struct machine_desc *desc, struct param_struct *params, char **cmdline, struct meminfo *mi) @@ -82,6 +103,16 @@ fixup_ebsa285(struct machine_desc *desc, struct param_struct *params, ORIG_VIDEO_LINES = params->u1.s.video_num_rows; } +MACHINE_START(EBSA285, "EBSA285") + MAINTAINER("Russell King") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) + BOOT_PARAMS(0x00000100) + VIDEO(0x000a0000, 0x000bffff) + FIXUP(fixup_ebsa285) +MACHINE_END +#endif + +#ifdef CONFIG_ARCH_NETWINDER /* * Older NeTTroms either do not provide a parameters * page, or they don't supply correct information in @@ -105,6 +136,18 @@ fixup_netwinder(struct machine_desc *desc, struct param_struct *params, } } +MACHINE_START(NETWINDER, "Rebel-NetWinder") + MAINTAINER("Russell King/Rebel.com") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) + BOOT_PARAMS(0x00000100) + VIDEO(0x000a0000, 0x000bffff) + DISABLE_PARPORT(0) + DISABLE_PARPORT(2) + FIXUP(fixup_netwinder) +MACHINE_END +#endif + +#ifdef CONFIG_ARCH_CATS /* * CATS uses soft-reboot by default, since * hard reboots fail on early boards. @@ -118,11 +161,20 @@ fixup_cats(struct machine_desc *desc, struct param_struct *params, ORIG_Y = 24; } +MACHINE_START(CATS, "Chalice-CATS") + MAINTAINER("Philip Blundell") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) + SOFT_REBOOT + FIXUP(fixup_cats) +MACHINE_END +#endif + +#ifdef CONFIG_ARCH_CO285 + static void __init fixup_coebsa285(struct machine_desc *desc, struct param_struct *params, char **cmdline, struct meminfo *mi) { -#if 0 extern unsigned long boot_memory_end; extern char boot_command_line[]; @@ -131,242 +183,228 @@ fixup_coebsa285(struct machine_desc *desc, struct param_struct *params, mi->bank[0].size = boot_memory_end; *cmdline = boot_command_line; -#endif } +MACHINE_START(CO285, "co-EBSA285") + MAINTAINER("Mark van Doesburg") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0x7cf00000) + FIXUP(fixup_coebsa285) +MACHINE_END +#endif + +#ifdef CONFIG_ARCH_SA1100 + +extern void select_sa1100_io_desc(void); +#define SET_BANK(__nr,__start,__size) \ + mi->bank[__nr].start = (__start), \ + mi->bank[__nr].size = (__size) static void __init fixup_sa1100(struct machine_desc *desc, struct param_struct *params, char **cmdline, struct meminfo *mi) { -#ifdef CONFIG_ARCH_SA1100 - int i; - extern struct mem_desc { - unsigned long phys_start; - unsigned long length; - } mem_desc[]; - extern unsigned int mem_desc_size; - - for( i = 0; i < mem_desc_size; i++ ) { - if( i >= NR_BANKS ) { - printk( __FUNCTION__ - ": mem_desc too large for meminfo structure\n"); - break; - } - mi->bank[i].start = mem_desc[i].phys_start; - mi->bank[i].size = mem_desc[i].length; + select_sa1100_io_desc(); + + if (machine_is_assabet()) { + SET_BANK( 0, 0xc0000000, 32*1024*1024 ); + mi->nr_banks = 1; + + ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + setup_ramdisk( 1, 0, 0, 8192 ); + setup_initrd( 0xc0800000, 3*1024*1024 ); } - mi->nr_banks = i; - -#if defined(CONFIG_SA1100_BRUTUS) - ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); - setup_ramdisk( 1, 0, 0, 8192 ); - setup_initrd( __phys_to_virt(0xd8000000), 3*1024*1024 ); -#elif defined(CONFIG_SA1100_EMPEG) - ROOT_DEV = MKDEV( 3, 1 ); /* /dev/hda1 */ - setup_ramdisk( 1, 0, 0, 4096 ); - setup_initrd( 0xd0000000+((1024-320)*1024), (320*1024) ); -#elif defined(CONFIG_SA1100_THINCLIENT) - ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); - setup_ramdisk( 1, 0, 0, 8192 ); - setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 ); -#elif defined(CONFIG_SA1100_TIFON) - ROOT_DEV = MKDEV(UNNAMED_MAJOR, 0); - setup_ramdisk(1, 0, 0, 4096); - setup_initrd( 0xd0000000 + 0x1100004, 0x140000 ); -#elif defined(CONFIG_SA1100_VICTOR) - ROOT_DEV = MKDEV( 60, 2 ); - - /* Get command line parameters passed from the loader (if any) */ - if( *((char*)0xc0000000) ) - strcpy( default_command_line, ((char *)0xc0000000) ); - - /* power off if any problem */ - strcat( default_command_line, " panic=1" ); -#elif defined(CONFIG_SA1100_LART) - ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); - setup_ramdisk(1, 0, 0, 8192); - setup_initrd(0xc0400000, 0x00400000); -#endif -#endif -} -#define NO_PARAMS 0 -#define NO_VIDEO 0, 0 + else if (machine_is_brutus()) { + SET_BANK( 0, 0xc0000000, 4*1024*1024 ); + SET_BANK( 1, 0xc8000000, 4*1024*1024 ); + SET_BANK( 2, 0xd0000000, 4*1024*1024 ); + SET_BANK( 3, 0xd8000000, 4*1024*1024 ); + mi->nr_banks = 4; -/* - * This is the list of all architectures supported by - * this kernel. This should be integrated with the list - * in head-armv.S. - */ -static struct machine_desc machine_desc[] __attribute__ ((__section__ (".arch.info"))) = { -#ifdef CONFIG_ARCH_EBSA110 - { - MACH_TYPE_EBSA110, - "EBSA110", /* RMK */ - 0x00000400, - NO_VIDEO, - 1, 0, 1, 0, 1, - NULL - }, + ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + setup_ramdisk( 1, 0, 0, 8192 ); + setup_initrd( __phys_to_virt(0xd8000000), 3*1024*1024 ); + } + + else if (machine_is_empeg()) { + SET_BANK( 0, 0xc0000000, 4*1024*1024 ); + SET_BANK( 1, 0xc8000000, 4*1024*1024 ); + mi->nr_banks = 2; + + ROOT_DEV = MKDEV( 3, 1 ); /* /dev/hda1 */ + setup_ramdisk( 1, 0, 0, 4096 ); + setup_initrd( 0xd0000000+((1024-320)*1024), (320*1024) ); + } + + else if (machine_is_lart()) { + /* + * Note that LART is a special case - it doesn't use physical + * address line A23 on the DRAM, so we effectively have 4 * 8MB + * in two SA1100 banks. + */ + SET_BANK( 0, 0xc0000000, 8*1024*1024 ); + SET_BANK( 1, 0xc1000000, 8*1024*1024 ); + SET_BANK( 2, 0xc8000000, 8*1024*1024 ); + SET_BANK( 3, 0xc9000000, 8*1024*1024 ); + mi->nr_banks = 4; + + ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + setup_ramdisk(1, 0, 0, 8192); + setup_initrd(0xc0400000, 4*1024*1024); + } + + else if (machine_is_thinclient()) { + SET_BANK( 0, 0xc0000000, 16*1024*1024 ); + mi->nr_banks = 1; + + ROOT_DEV = MKDEV(RAMDISK_MAJOR,0); + setup_ramdisk( 1, 0, 0, 8192 ); + setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 ); + } + + else if (machine_is_tifon()) { + SET_BANK( 0, 0xc0000000, 16*1024*1024 ); + SET_BANK( 1, 0xc8000000, 16*1024*1024 ); + mi->nr_banks = 2; + + ROOT_DEV = MKDEV(UNNAMED_MAJOR, 0); + setup_ramdisk(1, 0, 0, 4096); + setup_initrd( 0xd0000000 + 0x1100004, 0x140000 ); + } + + else if (machine_is_victor()) { + SET_BANK( 0, 0xc0000000, 4*1024*1024 ); + mi->nr_banks = 1; + + ROOT_DEV = MKDEV( 60, 2 ); + + /* Get command line parameters passed from the loader (if any) */ + if( *((char*)0xc0000000) ) + strcpy( *cmdline, ((char *)0xc0000000) ); + + /* power off if any problem */ + strcat( *cmdline, " panic=1" ); + } + +} + +#ifdef CONFIG_SA1100_ASSABET +MACHINE_START(ASSABET, "Intel-Assabet") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) +MACHINE_END #endif -#ifdef CONFIG_ARCH_RPC - { - MACH_TYPE_RISCPC, - "Acorn-RiscPC", /* RMK */ - 0x10000100, - NO_VIDEO, - 1, 1, 0, 0, 0, - fixup_acorn - }, +#ifdef CONFIG_SA1100_BITSY +MACHINE_START(BITSY, "Compaq Bitsy") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100) + FIXUP(fixup_sa1100) +MACHINE_END #endif -#ifdef CONFIG_ARCH_NEXUSPCI - { - MACH_TYPE_NEXUSPCI, - "FTV/PCI", /* Philip Blundell */ - NO_PARAMS, - NO_VIDEO, - 0, 0, 0, 0, 0, - NULL - }, +#ifdef CONFIG_SA1100_BRUTUS +MACHINE_START(BRUTUS, "Intel Brutus (SA1100 eval board)") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) +MACHINE_END #endif -#ifdef CONFIG_ARCH_EBSA285 - { - MACH_TYPE_EBSA285, - "EBSA285", /* RMK */ - 0x00000100, - 0x000a0000, 0x000bffff, - 0, 0, 0, 0, 0, - fixup_ebsa285 - }, +#ifdef CONFIG_SA1100_EMPEG +MACHINE_START(EMPEG, "empeg MP3 Car Audio Player") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) +MACHINE_END #endif -#ifdef CONFIG_ARCH_NETWINDER - { - MACH_TYPE_NETWINDER, - "Rebel-NetWinder", /* RMK */ - 0x00000100, - 0x000a0000, 0x000bffff, - 1, 0, 1, 0, 0, - fixup_netwinder - }, +#ifdef CONFIG_SA1100_ITSY +MACHINE_START(ITSY, "Compaq Itsy") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + BOOT_PARAMS(0xc0000100 + FIXUP(fixup_sa1100) +MACHINE_END #endif -#ifdef CONFIG_ARCH_CATS - { - MACH_TYPE_CATS, - "Chalice-CATS", /* Philip Blundell */ - NO_PARAMS, - 0x000a0000, 0x000bffff, - 0, 0, 0, 0, 1, - fixup_cats - }, +#ifdef CONFIG_SA1100_LART +MACHINE_START(LART, "LART") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) +MACHINE_END #endif -#ifdef CONFIG_ARCH_TBOX - { - MACH_TYPE_TBOX, - "unknown-TBOX", /* Philip Blundell */ - NO_PARAMS, - NO_VIDEO, - 0, 0, 0, 0, 0, - NULL - }, +#ifdef CONFIG_SA1100_PLEB +MACHINE_START(PLEB, "PLEB") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) +MACHINE_END #endif -#ifdef CONFIG_ARCH_CO285 - { - MACH_TYPE_CO285, - "co-EBSA285", /* Mark van Doesburg */ - NO_PARAMS, - NO_VIDEO, - 0, 0, 0, 0, 0, - fixup_coebsa285 - }, +#ifdef CONFIG_SA1100_THINCLIENT +MACHINE_START(THINCLIENT, "ADS ThinClient") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) +MACHINE_END #endif -#ifdef CONFIG_ARCH_CLPS7110 - { - MACH_TYPE_CLPS7110, - "CL-PS7110", /* Werner Almesberger */ - NO_PARAMS, - NO_VIDEO, - 0, 0, 0, 0, 0, - NULL - }, +#ifdef CONFIG_SA1100_TIFON +MACHINE_START(TIFON, "Tifon") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) +MACHINE_END #endif -#ifdef CONFIG_ARCH_ARC - { - MACH_TYPE_ARCHIMEDES, - "Acorn-Archimedes",/* RMK/DAG */ - 0x0207c000, - NO_VIDEO, - 0, 0, 0, 0, 0, - fixup_acorn - }, +#ifdef CONFIG_SA1100_VICTOR +MACHINE_START(VICTOR, "VisuAide Victor") + BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) + FIXUP(fixup_sa1100) +MACHINE_END #endif -#ifdef CONFIG_ARCH_A5K - { - MACH_TYPE_A5K, - "Acorn-A5000", /* RMK/PB */ - 0x0207c000, - NO_VIDEO, - 0, 0, 0, 0, 0, - fixup_acorn - }, +#endif + +#ifdef CONFIG_ARCH_EBSA110 +MACHINE_START(EBSA110, "EBSA110") + MAINTAINER("Russell King") + BOOT_MEM(0x00000000, 0xe0000000, 0xe0000000) + BOOT_PARAMS(0x00000400) + DISABLE_PARPORT(0) + DISABLE_PARPORT(2) + SOFT_REBOOT +MACHINE_END +#endif +#ifdef CONFIG_ARCH_NEXUSPCI +MACHINE_START(NEXUSPCI, "FTV/PCI") + MAINTAINER("Philip Blundell") + BOOT_MEM(0x40000000, 0x10000000, 0xe0000000) +MACHINE_END +#endif +#ifdef CONFIG_ARCH_TBOX +MACHINE_START(TBOX, "unknown-TBOX") + MAINTAINER("Philip Blundell") + BOOT_MEM(0x80000000, 0x00400000, 0xe0000000) +MACHINE_END +#endif +#ifdef CONFIG_ARCH_CLPS7110 +MACHINE_START(CLPS7110, "CL-PS7110") + MAINTAINER("Werner Almesberger") +MACHINE_END #endif #ifdef CONFIG_ARCH_ETOILE - { - MACH_TYPE_ETOILE, - "Etoile", /* Alex de Vries */ - NO_PARAMS, - NO_VIDEO, - 0, 0, 0, 0, 0, - NULL - }, +MACHINE_START(ETOILE, "Etoile") + MAINTAINER("Alex de Vries") +MACHINE_END #endif #ifdef CONFIG_ARCH_LACIE_NAS - { - MACH_TYPE_LACIE_NAS, - "LaCie_NAS", /* Benjamin Herrenschmidt */ - NO_PARAMS, - NO_VIDEO, - 0, 0, 0, 0, 0, - NULL - }, +MACHINE_START(LACIE_NAS, "LaCie_NAS") + MAINTAINER("Benjamin Herrenschmidt") +MACHINE_END #endif #ifdef CONFIG_ARCH_CLPS7500 - { - MACH_TYPE_CLPS7500, - "CL-PS7500", /* Philip Blundell */ - NO_PARAMS, - NO_VIDEO, - 0, 0, 0, 0, 0, - NULL - }, +MACHINE_START(CLPS7500, "CL-PS7500") + MAINTAINER("Philip Blundell") + BOOT_MEM(0x10000000, 0x03000000, 0xe0000000) +MACHINE_END #endif #ifdef CONFIG_ARCH_SHARK - { - MACH_TYPE_SHARK, - "Shark", /* Alexander Schulz */ - NO_PARAMS, - 0x06000000, 0x06000000+0x001fffff, - 0, 0, 0, 0, 0, - NULL - }, -#endif -#ifdef CONFIG_ARCH_SA1100 - { - MACH_TYPE_SA1100, - "SA1100-based", /* Nicolas Pitre */ - NO_PARAMS, - NO_VIDEO, - 0, 0, 0, 0, 0, - fixup_sa1100 - }, +MACHINE_START(SHARK, "Shark") + MAINTAINER("Alexander Schulz") + BOOT_MEM(0x08000000, 0x40000000, 0xe0000000) + VIDEO(0x06000000, 0x061fffff) +MACHINE_END #endif #ifdef CONFIG_ARCH_PERSONAL_SERVER - { - MACH_TYPE_PERSONAL_SERVER, - "Compaq Personal Server", - NO_PARAMS, - NO_VIDEO, - 0, 0, 0, 0, 0, - NULL - } +MACHINE_START(PERSONAL_SERVER, "Compaq Personal Server") + MAINTAINER("Jamey Hicks / George France") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) + BOOT_PARAMS(0x00000100) +MACHINE_END #endif -}; diff --git a/arch/arm/kernel/arch.h b/arch/arm/kernel/arch.h index b7635b11e..91de77772 100644 --- a/arch/arm/kernel/arch.h +++ b/arch/arm/kernel/arch.h @@ -1,9 +1,27 @@ +/* + * The size of struct machine_desc + * (for assembler code) + */ +#define SIZEOF_MACHINE_DESC 40 + +#ifndef __ASSEMBLY__ + struct machine_desc { + /* + * Note! The first four elements are used + * by assembler code in head-armv.S + */ unsigned int nr; /* architecture number */ + unsigned int phys_ram; /* start of physical ram */ + unsigned int phys_io; /* start of physical io */ + unsigned int virt_io; /* start of virtual io */ + const char *name; /* architecture name */ unsigned int param_offset; /* parameter page */ + unsigned int video_start; /* start of video RAM */ unsigned int video_end; /* end of video RAM */ + unsigned int reserve_lp0 :1; /* never has lp0 */ unsigned int reserve_lp1 :1; /* never has lp1 */ unsigned int reserve_lp2 :1; /* never has lp2 */ @@ -13,3 +31,43 @@ struct machine_desc { struct param_struct *, char **, struct meminfo *); }; + +/* + * Set of macros to define architecture features + */ +#define MACHINE_START(_type,_name) \ +const struct machine_desc __mach_desc_##_type \ + __attribute__((__section__(".arch.info"))) = { \ + nr: MACH_TYPE_##_type##, \ + name: _name, + +#define MAINTAINER(n) + +#define BOOT_MEM(_pram,_pio,_vio) \ + phys_ram: _pram, \ + phys_io: _pio, \ + virt_io: _vio, + +#define BOOT_PARAMS(_params) \ + param_offset: _params, + +#define VIDEO(_start,_end) \ + video_start: _start, \ + video_end: _end, + +#define DISABLE_PARPORT(_n) \ + reserve_lp##_n##: 1, + +#define BROKEN_HLT \ + broken_hlt: 1, + +#define SOFT_REBOOT \ + soft_reboot: 1, + +#define FIXUP(_func) \ + fixup: _func, + +#define MACHINE_END \ +}; + +#endif diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 02a4f6cf0..ffd0f1b5e 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -101,6 +101,7 @@ EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(system_rev); EXPORT_SYMBOL(system_serial_low); EXPORT_SYMBOL(system_serial_high); +EXPORT_SYMBOL(mem_fclk_21285); EXPORT_SYMBOL(__bug); EXPORT_SYMBOL(__readwrite_bug); EXPORT_SYMBOL(enable_irq); diff --git a/arch/arm/kernel/arthur.c b/arch/arm/kernel/arthur.c index 77c7d7396..8a8a5510d 100644 --- a/arch/arm/kernel/arthur.c +++ b/arch/arm/kernel/arthur.c @@ -59,11 +59,7 @@ static struct exec_domain arthur_exec_domain = { PER_RISCOS, PER_RISCOS, arthur_to_linux_signals, linux_to_arthur_signals, -#ifdef MODULE - &__this_module, /* No usage counter. */ -#else - NULL, -#endif + THIS_MODULE, NULL /* Nothing after this in the list. */ }; diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index c4ccd64e3..835bce140 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -21,7 +21,7 @@ int have_isa_bridge; extern void hw_init(void); -void pcibios_report_device_errors(void) +void pcibios_report_device_errors(int warn) { struct pci_dev *dev; @@ -34,8 +34,11 @@ void pcibios_report_device_errors(void) continue; pci_write_config_word(dev, PCI_STATUS, status & 0xf900); - printk(KERN_DEBUG "PCI: %02X:%02X: status %04X on %s\n", - dev->bus->number, dev->devfn, status, dev->name); + + if (warn) + printk(KERN_DEBUG "PCI: %02X:%02X: status %04X " + "on %s\n", dev->bus->number, dev->devfn, + status, dev->name); } } @@ -48,10 +51,6 @@ void pcibios_report_device_errors(void) * - (0x48) enable all memory requests from ISA to be channeled to PCI * - (0x42) disable ping-pong (as per errata) * - (0x40) enable PCI packet retry - * - (0x44) Route INTA to IRQ11 - * - (0x83) don't use CPU park enable, park on last master, disable GAT bit - * - (0x80) default rotating priorities - * - (0x81) rotate bank 4 */ static void __init pci_fixup_83c553(struct pci_dev *dev) { @@ -64,10 +63,26 @@ static void __init pci_fixup_83c553(struct pci_dev *dev) pci_write_config_byte(dev, 0x48, 0xff); pci_write_config_byte(dev, 0x42, 0x00); pci_write_config_byte(dev, 0x40, 0x22); - pci_write_config_word(dev, 0x44, 0xb000); - pci_write_config_byte(dev, 0x83, 0x02); + + /* + * We used to set the arbiter to "park on last master" + * (bit 1 set), but unfortunately the CyberPro does not + * park the bus. We must therefore park on CPU. + */ + pci_write_config_byte(dev, 0x83, 0x00); + + /* + * Rotate priorities of each PCI request + */ pci_write_config_byte(dev, 0x80, 0xe0); pci_write_config_byte(dev, 0x81, 0x01); + + /* + * Route INTA input to IRQ 11, and set + * IRQ11 to be level sensitive. + */ + pci_write_config_word(dev, 0x44, 0xb000); + outb(0x08, 0x4d1); } static void __init pci_fixup_unassign(struct pci_dev *dev) @@ -77,6 +92,23 @@ static void __init pci_fixup_unassign(struct pci_dev *dev) } /* + * Prevent the PCI layer from seeing the resources + * allocated to this device. These resources are + * of no consequence to the PCI layer (they are + * handled elsewhere). + */ +static void __init pci_fixup_disable(struct pci_dev *dev) +{ + int i; + + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + dev->resource[i].start = 0; + dev->resource[i].end = 0; + dev->resource[i].flags = 0; + } +} + +/* * PCI IDE controllers use non-standard I/O port * decoding, respect it. */ @@ -100,6 +132,10 @@ static void __init pci_fixup_ide_bases(struct pci_dev *dev) struct pci_fixup pcibios_fixups[] = { { PCI_FIXUP_HEADER, + PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, + pci_fixup_disable + }, { + PCI_FIXUP_HEADER, PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553, pci_fixup_83c553 }, { @@ -339,6 +375,7 @@ static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin) case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000): case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010): + case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000): return IRQ_NETWINDER_VGA; default: diff --git a/arch/arm/kernel/debug-armv.S b/arch/arm/kernel/debug-armv.S index 5802dac70..ce7f2f94c 100644 --- a/arch/arm/kernel/debug-armv.S +++ b/arch/arm/kernel/debug-armv.S @@ -68,7 +68,10 @@ #ifndef CONFIG_DEBUG_DC21285_PORT /* For NetWinder debugging */ .macro addruart,rx - mov \rx, #0xff000000 + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + moveq \rx, #0x7c000000 @ physical + movne \rx, #0xff000000 @ virtual orr \rx, \rx, #0x000003f8 .endm @@ -133,7 +136,10 @@ #elif defined(CONFIG_ARCH_SA1100) .macro addruart,rx - mov \rx, #0xf8000000 + mrc p15, 0, \rx, c1, c0 + tst \rx, #1 @ MMU enabled? + moveq \rx, #0x80000000 @ physical base address + movne \rx, #0xf8000000 @ virtual address add \rx, \rx, #0x00050000 @ Ser3 @add \rx, \rx, #0x00010000 @ Ser1 .endm @@ -171,7 +177,7 @@ ENTRY(printhex4) ENTRY(printhex2) mov r1, #2 -printhex: ldr r2, =hexbuf +printhex: adr r2, hexbuf add r3, r2, r1 mov r1, #0 strb r1, [r3] @@ -209,5 +215,4 @@ ENTRY(printch) mov r0, #0 b 1b - .bss hexbuf: .space 16 diff --git a/arch/arm/kernel/dec21285.c b/arch/arm/kernel/dec21285.c index 64c5861f0..bc8a951e2 100644 --- a/arch/arm/kernel/dec21285.c +++ b/arch/arm/kernel/dec21285.c @@ -23,18 +23,28 @@ #define MAX_SLOTS 21 extern int setup_arm_irq(int, struct irqaction *); -extern void pcibios_report_device_errors(void); +extern void pcibios_report_device_errors(int warn); static unsigned long -dc21285_base_address(struct pci_dev *dev, int where) +dc21285_base_address(struct pci_dev *dev) { unsigned long addr = 0; unsigned int devfn = dev->devfn; - if (dev->bus->number != 0) + if (dev->bus->number == 0) { + if (PCI_SLOT(devfn) == 0) + /* + * For devfn 0, point at the 21285 + */ + addr = ARMCSR_BASE; + else { + devfn -= 1 << 3; + + if (devfn < PCI_DEVFN(MAX_SLOTS, 0)) + addr = PCICFG0_BASE | 0xc00000 | (devfn << 8); + } + } else addr = PCICFG1_BASE | (dev->bus->number << 16) | (devfn << 8); - else if (devfn < PCI_DEVFN(MAX_SLOTS, 0)) - addr = PCICFG0_BASE | 0xc00000 | (devfn << 8); return addr; } @@ -42,7 +52,7 @@ dc21285_base_address(struct pci_dev *dev, int where) static int dc21285_read_config_byte(struct pci_dev *dev, int where, u8 *value) { - unsigned long addr = dc21285_base_address(dev, where); + unsigned long addr = dc21285_base_address(dev); u8 v; if (addr) @@ -59,7 +69,7 @@ dc21285_read_config_byte(struct pci_dev *dev, int where, u8 *value) static int dc21285_read_config_word(struct pci_dev *dev, int where, u16 *value) { - unsigned long addr = dc21285_base_address(dev, where); + unsigned long addr = dc21285_base_address(dev); u16 v; if (addr) @@ -76,7 +86,7 @@ dc21285_read_config_word(struct pci_dev *dev, int where, u16 *value) static int dc21285_read_config_dword(struct pci_dev *dev, int where, u32 *value) { - unsigned long addr = dc21285_base_address(dev, where); + unsigned long addr = dc21285_base_address(dev); u32 v; if (addr) @@ -93,7 +103,7 @@ dc21285_read_config_dword(struct pci_dev *dev, int where, u32 *value) static int dc21285_write_config_byte(struct pci_dev *dev, int where, u8 value) { - unsigned long addr = dc21285_base_address(dev, where); + unsigned long addr = dc21285_base_address(dev); if (addr) asm("str%?b %0, [%1, %2]" @@ -105,7 +115,7 @@ dc21285_write_config_byte(struct pci_dev *dev, int where, u8 value) static int dc21285_write_config_word(struct pci_dev *dev, int where, u16 value) { - unsigned long addr = dc21285_base_address(dev, where); + unsigned long addr = dc21285_base_address(dev); if (addr) asm("str%?h %0, [%1, %2]" @@ -117,7 +127,7 @@ dc21285_write_config_word(struct pci_dev *dev, int where, u16 value) static int dc21285_write_config_dword(struct pci_dev *dev, int where, u32 value) { - unsigned long addr = dc21285_base_address(dev, where); + unsigned long addr = dc21285_base_address(dev); if (addr) asm("str%? %0, [%1, %2]" @@ -147,6 +157,9 @@ dc21285_error(int irq, void *dev_id, struct pt_regs *regs) unsigned long irqstatus = *CSR_IRQ_RAWSTATUS; int warn = time_after_eq(jiffies, next_warn); + if (machine_is_netwinder()) + warn = 0; + ctrl |= SA110_CNTL_DISCARDTIMER; if (warn) { @@ -193,7 +206,7 @@ dc21285_error(int irq, void *dev_id, struct pt_regs *regs) if (warn) printk("pc=[<%08lX>]\n", instruction_pointer(regs)); - pcibios_report_device_errors(); + pcibios_report_device_errors(warn); *CSR_PCICMD = cmd; *CSR_SA110_CNTL = ctrl; diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 97dfef0c1..97fcfc522 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -6,7 +6,7 @@ #define S_OFF 8 .macro get_softirq, rd -#ifdef __SMP__ +#ifdef CONFIG_SMP #error SMP not supported #else ldr \rd, __softirq_state diff --git a/arch/arm/kernel/head-armv.S b/arch/arm/kernel/head-armv.S index 27a280b8b..956d9ccd2 100644 --- a/arch/arm/kernel/head-armv.S +++ b/arch/arm/kernel/head-armv.S @@ -12,6 +12,8 @@ #include <asm/hardware.h> #include <asm/dec21285.h> +#include "arch.h" + #if (TEXTADDR & 0xffff) != 0x8000 #error TEXTADDR must start at 0xXXXX8000 #endif @@ -231,6 +233,13 @@ __create_page_tables: * Generally, only serious errors cause this. */ __error: +#ifdef CONFIG_DEBUG_LL + mov r8, r0 @ preserve r0 + adr r0, err_str + bl printascii + mov r0, r8 + bl printch +#endif #ifdef CONFIG_ARCH_RPC /* * Turn the screen red on a error - RiscPC only. @@ -247,7 +256,10 @@ __error: 1: mov r0, r0 b 1b - +#ifdef CONFIG_DEBUG_LL +err_str: .asciz "\nError: " + .align +#endif /* * Read processor ID register (CP#15, CR0), and determine @@ -262,9 +274,9 @@ __error: __lookup_processor_type: adr r5, 2f ldmia r5, {r7, r9, r10} - sub r5, r5, r9 + sub r5, r5, r10 add r7, r7, r5 - add r10, r10, r5 + add r10, r9, r5 mrc p15, 0, r9, c0, c0 @ get processor id 1: ldmia r10, {r5, r6, r8} @ value, mask, mmuflags eor r5, r5, r9 @@ -277,8 +289,10 @@ __lookup_processor_type: mov pc, lr 2: .long __proc_info_end - .long 2b .long __proc_info_begin + .long 2b + .long __arch_info_begin + .long __arch_info_end /* * Lookup machine architecture @@ -290,135 +304,18 @@ __lookup_processor_type: * r7 = byte offset into page tables for IO */ __lookup_architecture_type: - cmp r1, #(__arch_types_end - __arch_types_start) / 16 - bge 1f - adr r4, __arch_types_start - add r4, r4, r1, lsl #4 - ldmia r4, {r4, r5, r6, r7} - mov r7, r7, lsr #18 + adr r4, 2b + ldmia r4, {r2, r3, r5, r6, r7} @ throw away r2, r3 + sub r5, r4, r5 + add r4, r6, r5 + add r7, r7, r5 +1: ldr r5, [r4] + teq r5, r1 + beq 2f + add r4, r4, #SIZEOF_MACHINE_DESC + cmp r4, r7 + blt 1b + mov r7, #0 mov pc, lr -1: mov r7, #0 +2: ldmib r4, {r5, r6, r7} mov pc, lr - -/* - * Machine parameters. Each machine requires 4 words, which are: - * - * word0: unused - * word1: physical start address of RAM - * word2: physical start address of IO - * word3: virtual start address of IO - * - * The IO mappings entered here are used to set up mappings - * required for debugging information to be shown to the user. - * paging_init() does the real page table initialisation. - */ - .type __arch_types_start, #object - @ 0x00 - DEC EBSA110 -__arch_types_start: - .long 0 - .long 0 - .long 0xe0000000 - .long 0xe0000000 - - @ 0x01 - Acorn RiscPC - .long 0 - .long 0x10000000 - .long 0x03000000 - .long 0xe0000000 - - @ 0x02 - Unused - .long 0 - .long 0 - .long 0xe0000000 - .long 0xe0000000 - - @ 0x03 - NexusPCI - .long 0 - .long 0x40000000 - .long 0x10000000 - .long 0xe0000000 - - @ 0x04 - DEC EBSA285 - .long 0 - .long 0 - .long DC21285_ARMCSR_BASE - .long 0xfe000000 - - @ 0x05 - Rebel.com NetWinder - .long 0 - .long 0 - .long DC21285_ARMCSR_BASE - .long 0xfe000000 - - @ 0x06 - CATS - .long 0 - .long 0 - .long DC21285_ARMCSR_BASE - .long 0xfe000000 - - @ 0x07 - tbox - .long 0 - .long 0x80000000 - .long 0x00400000 @ Uart - .long 0xe0000000 - - @ 0x08 - DEC EBSA285 as co-processor - .long 0 - .long 0 - .long DC21285_ARMCSR_BASE @ Physical I/O base address - .long 0x7cf00000 @ Virtual I/O base address - - @ 0x09 - CL-PS7110 - .long 0 - .long 0 - .long 0 - .long 0 - - @ 0x0a - Acorn Archimedes - .long 0 - .long 0 - .long 0 - .long 0 - - @ 0x0b - Acorn A5000 - .long 0 - .long 0 - .long 0 - .long 0 - - @ 0x0c - Etoile - .long 0 - .long 0 - .long 0 - .long 0 - - @ 0x0d - LaCie_NAS - .long 0 - .long 0 - .long 0 - .long 0 - - @ 0x0e - CL-PS7500 - .long 0 - .long 0x10000000 - .long 0x03000000 - .long 0xe0000000 - - @ 0x0f - Digital Shark (DNARD) - .long 0 - .long 0x08000000 - .long 0x40000000 - .long 0xe0000000 - - @ 0x10 - SA1100 - .long 0 - .long 0xc0000000 - .long 0x80000000 - .long 0xf8000000 - - /* - * Don't add anything here unless you have an - * architecture number allocated - see - * Documentation/arm/README - */ -__arch_types_end: diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 699cea4ab..1b26ced94 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -118,10 +118,8 @@ void enable_irq(unsigned int irq) cliIF(); irq_desc[irq].probing = 0; irq_desc[irq].triggered = 0; - if (!irq_desc[irq].noautoenable) { - irq_desc[irq].enabled = 1; - irq_desc[irq].unmask(irq); - } + irq_desc[irq].enabled = 1; + irq_desc[irq].unmask(irq); spin_unlock_irqrestore(&irq_controller_lock, flags); } diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index f04b422b4..ec67dcbd0 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -5,15 +5,14 @@ */ #include <linux/config.h> #include <linux/kernel.h> -#include <linux/mm.h> #include <linux/stddef.h> #include <linux/ioport.h> #include <linux/delay.h> #include <linux/utsname.h> #include <linux/blk.h> #include <linux/console.h> -#include <linux/init.h> #include <linux/bootmem.h> +#include <linux/init.h> #include <asm/elf.h> #include <asm/hardware.h> @@ -33,6 +32,7 @@ #endif extern void paging_init(struct meminfo *); +extern void bootmem_init(struct meminfo *); extern void reboot_setup(char *str); extern void disable_hlt(void); extern int root_mountflags; @@ -43,6 +43,7 @@ unsigned int __machine_arch_type; unsigned int system_rev; unsigned int system_serial_low; unsigned int system_serial_high; +unsigned int mem_fclk_21285 = 50000000; unsigned int elf_hwcap; #ifdef MULTI_CPU @@ -199,7 +200,8 @@ parse_cmdline(struct meminfo *mi, char **cmdline_p, char *from) if (to != command_line) to -= 1; - /* If the user specifies memory size, we + /* + * If the user specifies memory size, we * blow away any automatically generated * size. */ @@ -256,137 +258,6 @@ void __init setup_initrd(unsigned int start, unsigned int size) #endif } -#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT) -#define V_PFN_DOWN(x) O_PFN_DOWN(__pa(x)) - -#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT) -#define V_PFN_UP(x) O_PFN_UP(__pa(x)) - -#define PFN_SIZE(x) ((x) >> PAGE_SHIFT) -#define PFN_RANGE(s,e) PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \ - (((unsigned long)(s)) & PAGE_MASK)) - -/* - * FIXME: These can be removed when Ingo's cleanup patch goes in - */ -#define free_bootmem(s,sz) free_bootmem((s)<<PAGE_SHIFT, (sz)<<PAGE_SHIFT) -#define reserve_bootmem(s,sz) reserve_bootmem((s)<<PAGE_SHIFT, (sz)<<PAGE_SHIFT) - -static unsigned int __init -find_bootmap_pfn(struct meminfo *mi, unsigned int bootmap_pages) -{ - unsigned int start_pfn, bank, bootmap_pfn; - - start_pfn = V_PFN_UP(&_end); - bootmap_pfn = 0; - - /* - * FIXME: We really want to avoid allocating the bootmap - * over the top of the initrd. - */ -#ifdef CONFIG_BLK_DEV_INITRD - if (initrd_start) { - if (__pa(initrd_end) > mi->end) { - printk ("initrd extends beyond end of memory " - "(0x%08lx > 0x%08lx) - disabling initrd\n", - __pa(initrd_end), mi->end); - initrd_start = 0; - initrd_end = 0; - } - } -#endif - - for (bank = 0; bank < mi->nr_banks; bank ++) { - unsigned int start, end; - - if (mi->bank[bank].size == 0) - continue; - - start = O_PFN_UP(mi->bank[bank].start); - end = O_PFN_DOWN(mi->bank[bank].size + - mi->bank[bank].start); - - if (end < start_pfn) - continue; - - if (start < start_pfn) - start = start_pfn; - - if (end <= start) - continue; - - if (end - start >= bootmap_pages) { - bootmap_pfn = start; - break; - } - } - - if (bootmap_pfn == 0) - BUG(); - - return bootmap_pfn; -} - -/* - * Initialise the bootmem allocator. - */ -static void __init setup_bootmem(struct meminfo *mi) -{ - unsigned int end_pfn, start_pfn, bootmap_pages, bootmap_pfn; - unsigned int i; - - /* - * Calculate the physical address of the top of memory. - */ - mi->end = 0; - for (i = 0; i < mi->nr_banks; i++) { - unsigned long end; - - if (mi->bank[i].size != 0) { - end = mi->bank[i].start + mi->bank[i].size; - if (mi->end < end) - mi->end = end; - } - } - - start_pfn = O_PFN_UP(PHYS_OFFSET); - end_pfn = O_PFN_DOWN(mi->end); - bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); - bootmap_pfn = find_bootmap_pfn(mi, bootmap_pages); - - /* - * Initialise the boot-time allocator - */ - init_bootmem_start(bootmap_pfn, start_pfn, end_pfn); - - /* - * Register all available RAM with the bootmem allocator. - */ - for (i = 0; i < mi->nr_banks; i++) - if (mi->bank[i].size) - free_bootmem(O_PFN_UP(mi->bank[i].start), - PFN_SIZE(mi->bank[i].size)); - - /* - * Register the reserved regions with bootmem - */ - reserve_bootmem(bootmap_pfn, bootmap_pages); - reserve_bootmem(V_PFN_DOWN(&_stext), PFN_RANGE(&_stext, &_end)); - -#ifdef CONFIG_CPU_32 - /* - * Reserve the page tables. These are already in use. - */ - reserve_bootmem(V_PFN_DOWN(swapper_pg_dir), - PFN_SIZE(PTRS_PER_PGD * sizeof(void *))); -#endif -#ifdef CONFIG_BLK_DEV_INITRD - if (initrd_start) - reserve_bootmem(V_PFN_DOWN(initrd_start), - PFN_RANGE(initrd_start, initrd_end)); -#endif -} - static void __init request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc) { @@ -487,6 +358,9 @@ void __init setup_arch(char **cmdline_p) system_serial_low = params->u1.s.system_serial_low; system_serial_high = params->u1.s.system_serial_high; + if (params->u1.s.mem_fclk_21285 > 0) + mem_fclk_21285 = params->u1.s.mem_fclk_21285; + setup_ramdisk((params->u1.s.flags & FLAG_RDLOAD) == 0, (params->u1.s.flags & FLAG_RDPROMPT) == 0, params->u1.s.rd_start, @@ -518,9 +392,8 @@ void __init setup_arch(char **cmdline_p) memcpy(saved_command_line, from, COMMAND_LINE_SIZE); saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; parse_cmdline(&meminfo, cmdline_p, from); - setup_bootmem(&meminfo); + bootmem_init(&meminfo); request_standard_resources(&meminfo, mdesc); - paging_init(&meminfo); #ifdef CONFIG_VT diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c index 0fcad67c0..c79b323a9 100644 --- a/arch/arm/kernel/time.c +++ b/arch/arm/kernel/time.c @@ -30,6 +30,7 @@ extern int setup_arm_irq(int, struct irqaction *); extern void setup_timer(void); +extern rwlock_t xtime_lock; extern volatile unsigned long lost_ticks; /* change this if you have some constant time drift */ @@ -59,7 +60,8 @@ static unsigned long dummy_gettimeoffset(void) } /* - * hook for getting the time offset + * hook for getting the time offset. Note that it is + * always called with interrupts disabled. */ unsigned long (*gettimeoffset)(void) = dummy_gettimeoffset; @@ -175,29 +177,33 @@ static void do_leds(void) void do_gettimeofday(struct timeval *tv) { unsigned long flags; + unsigned long usec, sec; - save_flags_cli (flags); - *tv = xtime; - tv->tv_usec += gettimeoffset(); + read_lock_irqsave(&xtime_lock, flags); + usec = gettimeoffset(); + { + unsigned long lost = lost_ticks; - /* - * xtime is atomically updated in timer_bh. lost_ticks is - * nonzero if the timer bottom half hasnt executed yet. - */ - if (lost_ticks) - tv->tv_usec += USECS_PER_JIFFY; - - restore_flags(flags); - - if (tv->tv_usec >= 1000000) { - tv->tv_usec -= 1000000; - tv->tv_sec++; + if (lost) + usec += lost * USECS_PER_JIFFY; } + sec = xtime.tv_sec; + usec += xtime.tv_usec; + read_unlock_irqrestore(&xtime_lock, flags); + + /* usec may have gone up a lot: be safe */ + while (usec >= 1000000) { + usec -= 1000000; + sec++; + } + + tv->tv_sec = sec; + tv->tv_usec = usec; } void do_settimeofday(struct timeval *tv) { - cli (); + write_lock_irq(&xtime_lock); /* This is revolting. We need to set the xtime.tv_usec * correctly. However, the value in this location is * is value at the last tick. @@ -205,8 +211,9 @@ void do_settimeofday(struct timeval *tv) * would have done, and then undo it! */ tv->tv_usec -= gettimeoffset(); + tv->tv_usec -= lost_ticks * USECS_PER_JIFFY; - if (tv->tv_usec < 0) { + while (tv->tv_usec < 0) { tv->tv_usec += 1000000; tv->tv_sec--; } @@ -216,7 +223,7 @@ void do_settimeofday(struct timeval *tv) time_status |= STA_UNSYNC; time_maxerror = NTP_PHASE_LIMIT; time_esterror = NTP_PHASE_LIMIT; - sti(); + write_unlock_irq(&xtime_lock); } static struct irqaction timer_irq = { diff --git a/arch/arm/lib/csumpartialcopy.S b/arch/arm/lib/csumpartialcopy.S index 7289619da..fc52662a8 100644 --- a/arch/arm/lib/csumpartialcopy.S +++ b/arch/arm/lib/csumpartialcopy.S @@ -12,16 +12,46 @@ * Params : r0 = src, r1 = dst, r2 = len, r3 = checksum * Returns : r0 = new checksum */ + + .macro save_regs + stmfd sp!, {r4 - r8, fp, ip, lr, pc} + .endm + + .macro load_regs,flags + LOADREGS(\flags,fp,{r4 - r8, fp, sp, pc}) + .endm + + .macro load1b, reg1 + ldrb \reg1, [r0], #1 + .endm + + .macro load2b, reg1, reg2 + ldrb \reg1, [r0], #1 + ldrb \reg2, [r0], #1 + .endm + + .macro load1l, reg1 + ldr \reg1, [r0], #4 + .endm + + .macro load2l, reg1, reg2 + ldr \reg1, [r0], #4 + ldr \reg2, [r0], #4 + .endm + + .macro load4l, reg1, reg2, reg3, reg4 + ldmia r0!, {\reg1, \reg2, \reg3, \reg4} + .endm + ENTRY(csum_partial_copy_nocheck) mov ip, sp - stmfd sp!, {r4 - r8, fp, ip, lr, pc} + save_regs sub fp, ip, #4 cmp r2, #4 - blt Ltoo_small + blt .too_small tst r1, #2 @ Test destination alignment - beq Ldst_aligned - ldrb ip, [r0], #1 - ldrb r8, [r0], #1 + beq .dst_aligned + load2b ip, r8 subs r2, r2, #2 @ We do not know if SRC is aligned... orr ip, ip, r8, lsl #8 adds r3, r3, ip @@ -29,12 +59,12 @@ ENTRY(csum_partial_copy_nocheck) strb ip, [r1], #1 mov ip, ip, lsr #8 strb ip, [r1], #1 @ Destination now aligned -Ldst_aligned: tst r0, #3 - bne Lsrc_not_aligned +.dst_aligned: tst r0, #3 + bne .src_not_aligned adds r3, r3, #0 bics ip, r2, #15 @ Routine for src & dst aligned - beq 3f -1: ldmia r0!, {r4, r5, r6, r7} + beq 2f +1: load4l r4, r5, r6, r7 stmia r1!, {r4, r5, r6, r7} adcs r3, r3, r4 adcs r3, r3, r5 @@ -43,65 +73,69 @@ Ldst_aligned: tst r0, #3 sub ip, ip, #16 teq ip, #0 bne 1b -3: ands ip, r2, #12 - beq 5f - tst ip, #8 +2: ands ip, r2, #12 beq 4f - ldmia r0!, {r4, r5} + tst ip, #8 + beq 3f + load2l r4, r5 stmia r1!, {r4, r5} adcs r3, r3, r4 adcs r3, r3, r5 tst ip, #4 - beq 5f -4: ldr r4, [r0], #4 + beq 4f +3: load1l r4 str r4, [r1], #4 adcs r3, r3, r4 -5: ands r2, r2, #3 +4: ands r2, r2, #3 adceq r0, r3, #0 - LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) - ldr r4, [r0], #4 + load_regs eqea + load1l r4 tst r2, #2 - beq Lexit_r4 + beq .exit adcs r3, r3, r4, lsl #16 strb r4, [r1], #1 mov r4, r4, lsr #8 strb r4, [r1], #1 mov r4, r4, lsr #8 - b Lexit_r4 +.exit: tst r2, #1 + strneb r4, [r1], #1 + andne r4, r4, #255 + adcnes r3, r3, r4 + adcs r0, r3, #0 + load_regs ea -Ltoo_small: teq r2, #0 - LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) +.too_small: teq r2, #0 + load_regs eqea cmp r2, #2 - blt Ltoo_small1 - ldrb ip, [r0], #1 - ldrb r8, [r0], #1 + blt .too_small1 + load2b ip, r8 orr ip, ip, r8, lsl #8 adds r3, r3, ip strb ip, [r1], #1 strb r8, [r1], #1 tst r2, #1 -Ltoo_small1: ldrneb r4, [r0], #1 -Lexit_r4: tst r2, #1 - strneb r4, [r1], #1 - andne r4, r4, #255 - adcnes r3, r3, r4 - adcs r0, r3, #0 - LOADREGS(ea,fp,{r4 - r8, fp, sp, pc}) +.too_small1: @ C = 0 + beq .csum_exit + load1b ip + strb ip, [r1], #1 + adcs r3, r3, ip +.csum_exit: adc r0, r3, #0 + load_regs ea -Lsrc_not_aligned: +.src_not_aligned: cmp r2, #4 - blt Ltoo_small + blt .too_small and ip, r0, #3 bic r0, r0, #3 - ldr r4, [r0], #4 + load1l r4 cmp ip, #2 - beq Lsrc2_aligned - bhi Lsrc3_aligned + beq .src2_aligned + bhi .src3_aligned mov r4, r4, lsr #8 adds r3, r3, #0 bics ip, r2, #15 beq 2f -1: ldmia r0!, {r5, r6, r7, r8} +1: load4l r5, r6, r7, r8 orr r4, r4, r5, lsl #24 mov r5, r5, lsr #8 orr r5, r5, r6, lsl #24 @@ -122,7 +156,7 @@ Lsrc_not_aligned: beq 4f tst ip, #8 beq 3f - ldmia r0!, {r5, r6} + load2l r5, r6 orr r4, r4, r5, lsl #24 mov r5, r5, lsr #8 orr r5, r5, r6, lsl #24 @@ -132,28 +166,28 @@ Lsrc_not_aligned: mov r4, r6, lsr #8 tst ip, #4 beq 4f -3: ldr r5, [r0], #4 +3: load1l r5 orr r4, r4, r5, lsl #24 str r4, [r1], #4 adcs r3, r3, r4 mov r4, r5, lsr #8 4: ands r2, r2, #3 adceq r0, r3, #0 - LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) + load_regs eqea tst r2, #2 - beq Lexit_r4 + beq .exit adcs r3, r3, r4, lsl #16 strb r4, [r1], #1 mov r4, r4, lsr #8 strb r4, [r1], #1 mov r4, r4, lsr #8 - b Lexit_r4 + b .exit -Lsrc2_aligned: mov r4, r4, lsr #16 +.src2_aligned: mov r4, r4, lsr #16 adds r3, r3, #0 bics ip, r2, #15 beq 2f -1: ldmia r0!, {r5, r6, r7, r8} +1: load4l r5, r6, r7, r8 orr r4, r4, r5, lsl #16 mov r5, r5, lsr #16 orr r5, r5, r6, lsl #16 @@ -174,7 +208,7 @@ Lsrc2_aligned: mov r4, r4, lsr #16 beq 4f tst ip, #8 beq 3f - ldmia r0!, {r5, r6} + load2l r5, r6 orr r4, r4, r5, lsl #16 mov r5, r5, lsr #16 orr r5, r5, r6, lsl #16 @@ -184,28 +218,31 @@ Lsrc2_aligned: mov r4, r4, lsr #16 mov r4, r6, lsr #16 tst ip, #4 beq 4f -3: ldr r5, [r0], #4 +3: load1l r5 orr r4, r4, r5, lsl #16 str r4, [r1], #4 adcs r3, r3, r4 mov r4, r5, lsr #16 4: ands r2, r2, #3 adceq r0, r3, #0 - LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) + load_regs eqea tst r2, #2 - beq Lexit_r4 + beq .exit adcs r3, r3, r4, lsl #16 strb r4, [r1], #1 mov r4, r4, lsr #8 strb r4, [r1], #1 - ldrb r4, [r0], #1 - b Lexit_r4 + tst r2, #1 + adceq r0, r3, #0 + load_regs eqea + load1b r4 + b .exit -Lsrc3_aligned: mov r4, r4, lsr #24 +.src3_aligned: mov r4, r4, lsr #24 adds r3, r3, #0 bics ip, r2, #15 beq 2f -1: ldmia r0!, {r5, r6, r7, r8} +1: load4l r5, r6, r7, r8 orr r4, r4, r5, lsl #8 mov r5, r5, lsr #24 orr r5, r5, r6, lsl #8 @@ -226,7 +263,7 @@ Lsrc3_aligned: mov r4, r4, lsr #24 beq 4f tst ip, #8 beq 3f - ldmia r0!, {r5, r6} + load2l r5, r6 orr r4, r4, r5, lsl #8 mov r5, r5, lsr #24 orr r5, r5, r6, lsl #8 @@ -236,22 +273,20 @@ Lsrc3_aligned: mov r4, r4, lsr #24 mov r4, r6, lsr #24 tst ip, #4 beq 4f -3: ldr r5, [r0], #4 +3: load1l r5 orr r4, r4, r5, lsl #8 str r4, [r1], #4 adcs r3, r3, r4 mov r4, r5, lsr #24 4: ands r2, r2, #3 adceq r0, r3, #0 - LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc}) + load_regs eqea tst r2, #2 - beq Lexit_r4 + beq .exit adcs r3, r3, r4, lsl #16 strb r4, [r1], #1 - ldr r4, [r0], #4 + load1l r4 strb r4, [r1], #1 adcs r3, r3, r4, lsl #24 mov r4, r4, lsr #8 - b Lexit_r4 - - + b .exit diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S index f698c0d26..cde500440 100644 --- a/arch/arm/lib/csumpartialcopyuser.S +++ b/arch/arm/lib/csumpartialcopyuser.S @@ -153,9 +153,9 @@ ENTRY(csum_partial_copy_from_user) save_regs sub fp, ip, #4 cmp r2, #4 - blt .too_small_user + blt .too_small tst r1, #2 @ Test destination alignment - beq .dst_aligned_user + beq .dst_aligned load2b ip, r8 subs r2, r2, #2 @ We do not know if SRC is aligned... orr ip, ip, r8, lsl #8 @@ -164,9 +164,8 @@ ENTRY(csum_partial_copy_from_user) strb ip, [r1], #1 mov ip, ip, lsr #8 strb ip, [r1], #1 @ Destination now aligned -.dst_aligned_user: - tst r0, #3 - bne .src_not_aligned_user +.dst_aligned: tst r0, #3 + bne .src_not_aligned adds r3, r3, #0 bics ip, r2, #15 @ Routine for src & dst aligned beq 2f @@ -210,18 +209,17 @@ ENTRY(csum_partial_copy_from_user) adcs r0, r3, #0 load_regs ea -.too_small_user: - teq r2, #0 +.too_small: teq r2, #0 load_regs eqea cmp r2, #2 - blt .too_small_user1 + blt .too_small1 load2b ip, r8 orr ip, ip, r8, lsl #8 adds r3, r3, ip strb ip, [r1], #1 strb r8, [r1], #1 tst r2, #1 -.too_small_user1: @ C = 0 +.too_small1: @ C = 0 beq .csum_exit load1b ip strb ip, [r1], #1 @@ -229,15 +227,15 @@ ENTRY(csum_partial_copy_from_user) .csum_exit: adc r0, r3, #0 load_regs ea -.src_not_aligned_user: +.src_not_aligned: cmp r2, #4 - blt .too_small_user + blt .too_small and ip, r0, #3 bic r0, r0, #3 load1l r4 cmp ip, #2 - beq .src2_aligned_user - bhi .src3_aligned_user + beq .src2_aligned + bhi .src3_aligned mov r4, r4, lsr #8 adds r3, r3, #0 bics ip, r2, #15 @@ -290,8 +288,7 @@ ENTRY(csum_partial_copy_from_user) mov r4, r4, lsr #8 b .exit -.src2_aligned_user: - mov r4, r4, lsr #16 +.src2_aligned: mov r4, r4, lsr #16 adds r3, r3, #0 bics ip, r2, #15 beq 2f @@ -346,8 +343,7 @@ ENTRY(csum_partial_copy_from_user) load1b r4 b .exit -.src3_aligned_user: - mov r4, r4, lsr #24 +.src3_aligned: mov r4, r4, lsr #24 adds r3, r3, #0 bics ip, r2, #15 beq 2f diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index 76d1a5c74..310107678 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c @@ -29,20 +29,29 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) if (in_interrupt()) BUG(); + size = PAGE_ALIGN(size); order = get_order(size); page = __get_free_pages(gfp, order); if (!page) goto no_page; - memset((void *)page, 0, PAGE_SIZE << order); - clean_cache_area(page, PAGE_SIZE << order); + memset((void *)page, 0, size); + clean_cache_area(page, size); *dma_handle = virt_to_bus((void *)page); - ret = __ioremap(virt_to_phys((void *)page), PAGE_SIZE << order, 0); - if (ret) + ret = __ioremap(virt_to_phys((void *)page), size, 0); + if (ret) { + /* free wasted pages */ + unsigned long end = page + (PAGE_SIZE << order); + page += size; + while (page < end) { + free_page(page); + page += PAGE_SIZE; + } return ret; + } free_pages(page, order); no_page: @@ -81,18 +90,18 @@ void consistent_free(void *vaddr) /* * make an area consistent. */ -void consistent_sync(void *vaddr, size_t size, int rw) +void consistent_sync(void *vaddr, size_t size, int direction) { - switch (rw) { - case 0: + switch (direction) { + case PCI_DMA_NONE: BUG(); - case 1: /* invalidate only */ + case PCI_DMA_FROMDEVICE: /* invalidate only */ dma_cache_inv(vaddr, size); break; - case 2: /* writeback only */ + case PCI_DMA_TODEVICE: /* writeback only */ dma_cache_wback(vaddr, size); break; - case 3: /* writeback and invalidate */ + case PCI_DMA_BIDIRECTIONAL: /* writeback and invalidate */ dma_cache_wback_inv(vaddr, size); break; } diff --git a/arch/arm/mm/fault-common.c b/arch/arm/mm/fault-common.c index c34c37203..14cf5a925 100644 --- a/arch/arm/mm/fault-common.c +++ b/arch/arm/mm/fault-common.c @@ -123,7 +123,7 @@ good_area: * make sure we exit gracefully rather than endlessly redo * the fault. */ - if (!handle_mm_fault(tsk, vma, addr & PAGE_MASK, DO_COW(mode))) + if (!handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(mode))) goto do_sigbus; up(&mm->mmap_sem); diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index e7b8c8bb9..61feb6a55 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -1,9 +1,8 @@ /* * linux/arch/arm/mm/init.c * - * Copyright (C) 1995-1999 Russell King + * Copyright (C) 1995-2000 Russell King */ - #include <linux/config.h> #include <linux/signal.h> #include <linux/sched.h> @@ -32,9 +31,22 @@ #include "map.h" +#ifdef CONFIG_CPU_32 +#define TABLE_OFFSET (PTRS_PER_PTE) +#else +#define TABLE_OFFSET 0 +#endif +#define TABLE_SIZE ((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(void *)) + static unsigned long totalram_pages; -struct meminfo meminfo; pgd_t swapper_pg_dir[PTRS_PER_PGD]; +extern int _stext, _text, _etext, _edata, _end; + +/* + * The sole use of this is to pass memory configuration + * data from paging_init to mem_init. + */ +static struct meminfo __initdata meminfo; /* * empty_bad_page is the page that is used for page faults when @@ -119,33 +131,36 @@ int do_check_pgt_cache(int low, int high) void show_mem(void) { int free = 0, total = 0, reserved = 0; - int shared = 0, cached = 0; - struct page *page, *end; + int shared = 0, cached = 0, node; printk("Mem-info:\n"); show_free_areas(); printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); - page = mem_map; - end = mem_map + max_mapnr; + for (node = 0; node < numnodes; node++) { + struct page *page, *end; - do { - if (PageSkip(page)) { - page = page->next_hash; - if (page == NULL) - break; - } - total++; - if (PageReserved(page)) - reserved++; - else if (PageSwapCache(page)) - cached++; - else if (!page_count(page)) - free++; - else - shared += atomic_read(&page->count) - 1; - page++; - } while (page < end); + page = NODE_MEM_MAP(node); + end = page + NODE_DATA(node)->node_size; + + do { + if (PageSkip(page)) { + page = page->next_hash; + if (page == NULL) + break; + } + total++; + if (PageReserved(page)) + reserved++; + else if (PageSwapCache(page)) + cached++; + else if (!page_count(page)) + free++; + else + shared += atomic_read(&page->count) - 1; + page++; + } while (page < end); + } printk("%d pages of RAM\n", total); printk("%d free pages\n", free); @@ -158,24 +173,173 @@ void show_mem(void) show_buffers(); } +#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define V_PFN_DOWN(x) O_PFN_DOWN(__pa(x)) + +#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT) +#define V_PFN_UP(x) O_PFN_UP(__pa(x)) + +#define PFN_SIZE(x) ((x) >> PAGE_SHIFT) +#define PFN_RANGE(s,e) PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \ + (((unsigned long)(s)) & PAGE_MASK)) + +static unsigned int __init +find_bootmap_pfn(struct meminfo *mi, unsigned int bootmap_pages) +{ + unsigned int start_pfn, bank, bootmap_pfn; + + start_pfn = V_PFN_UP(&_end); + bootmap_pfn = 0; + + /* + * FIXME: We really want to avoid allocating the bootmap + * over the top of the initrd. + */ +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) { + if (__pa(initrd_end) > mi->end) { + printk ("initrd extends beyond end of memory " + "(0x%08lx > 0x%08lx) - disabling initrd\n", + __pa(initrd_end), mi->end); + initrd_start = 0; + initrd_end = 0; + } + } +#endif + + for (bank = 0; bank < mi->nr_banks; bank ++) { + unsigned int start, end; + + if (mi->bank[bank].size == 0) + continue; + + start = O_PFN_UP(mi->bank[bank].start); + end = O_PFN_DOWN(mi->bank[bank].size + + mi->bank[bank].start); + + if (end < start_pfn) + continue; + + if (start < start_pfn) + start = start_pfn; + + if (end <= start) + continue; + + if (end - start >= bootmap_pages) { + bootmap_pfn = start; + break; + } + } + + if (bootmap_pfn == 0) + BUG(); + + return bootmap_pfn; +} + +/* + * Initialise one node of the bootmem allocator. For now, we + * only initialise node 0. Notice that we have a bootmem + * bitmap per node. + */ +static void __init setup_bootmem_node(int node, struct meminfo *mi) +{ + unsigned int end_pfn, start_pfn, bootmap_pages, bootmap_pfn; + unsigned int i; + + if (node != 0) /* only initialise node 0 for now */ + return; + + start_pfn = O_PFN_UP(PHYS_OFFSET); + end_pfn = O_PFN_DOWN(mi->end); + bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn); + bootmap_pfn = find_bootmap_pfn(mi, bootmap_pages); + + /* + * Initialise the boot-time allocator + */ + init_bootmem_node(node, bootmap_pfn, start_pfn, end_pfn); + + /* + * Register all available RAM with the bootmem allocator. + */ + for (i = 0; i < mi->nr_banks; i++) + if (mi->bank[i].size) + free_bootmem_node(node, mi->bank[i].start, + PFN_SIZE(mi->bank[i].size) << PAGE_SHIFT); + + reserve_bootmem_node(node, bootmap_pfn << PAGE_SHIFT, + bootmap_pages << PAGE_SHIFT); +} + +/* + * Initialise the bootmem allocator. + */ +void __init bootmem_init(struct meminfo *mi) +{ + unsigned int i, node; + + /* + * Calculate the physical address of the top of memory. + * Note that there are no guarantees assumed about the + * ordering of the bank information. + */ + mi->end = 0; + for (i = 0; i < mi->nr_banks; i++) { + unsigned long end; + + if (mi->bank[i].size != 0) { + end = mi->bank[i].start + mi->bank[i].size; + if (mi->end < end) + mi->end = end; + } + } + + max_low_pfn = O_PFN_DOWN(mi->end - PHYS_OFFSET); + + /* + * Setup each node + */ + for (node = 0; node < numnodes; node++) + setup_bootmem_node(node, mi); + + /* + * Register the kernel text and data with bootmem. + * Note that this can only be in node 0. + */ + reserve_bootmem_node(0, V_PFN_DOWN(&_stext) << PAGE_SHIFT, + PFN_RANGE(&_stext, &_end) << PAGE_SHIFT); + +#ifdef CONFIG_CPU_32 + /* + * Reserve the page tables. These are already in use, + * and can only be in node 0. + */ + reserve_bootmem_node(0, V_PFN_DOWN(swapper_pg_dir) << PAGE_SHIFT, + PFN_SIZE(PTRS_PER_PGD * sizeof(void *)) << PAGE_SHIFT); +#endif +#ifdef CONFIG_BLK_DEV_INITRD + /* + * This may be in any bank. Currently, we assume that + * it is in bank 0. + */ + if (initrd_start) + reserve_bootmem_node(0, V_PFN_DOWN(initrd_start) << PAGE_SHIFT, + PFN_RANGE(initrd_start, initrd_end) << PAGE_SHIFT); +#endif +} + /* * paging_init() sets up the page tables... */ void __init paging_init(struct meminfo *mi) { void *zero_page, *bad_page, *bad_table; - unsigned long zone_size[MAX_NR_ZONES]; - int i; + int node; memcpy(&meminfo, mi, sizeof(meminfo)); -#ifdef CONFIG_CPU_32 -#define TABLE_OFFSET (PTRS_PER_PTE) -#else -#define TABLE_OFFSET 0 -#endif -#define TABLE_SIZE ((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(void *)) - /* * allocate what we need for the bad pages */ @@ -186,31 +350,42 @@ void __init paging_init(struct meminfo *mi) /* * initialise the page tables */ - pagetable_init(); + pagetable_init(mi); flush_tlb_all(); /* - * Initialise the zones and mem_map + * initialise the zones within each node */ - for (i = 0; i < MAX_NR_ZONES; i++) - zone_size[i] = 0; + for (node = 0; node < numnodes; node++) { + unsigned long zone_size[MAX_NR_ZONES]; + unsigned long zhole_size[MAX_NR_ZONES]; + struct bootmem_data *bdata; + pg_data_t *pgdat; + int i; - /* - * Calculate the size of the zones. On ARM, we don't have - * any problems with DMA or highmem, so all memory is - * allocated to the DMA zone. - */ - for (i = 0; i < mi->nr_banks; i++) { - if (mi->bank[i].size) { - unsigned int end; - - end = (mi->bank[i].start - PHYS_OFFSET + - mi->bank[i].size) >> PAGE_SHIFT; - if (zone_size[0] < end) - zone_size[0] = end; + /* + * Initialise the zone size information. + */ + for (i = 0; i < MAX_NR_ZONES; i++) { + zone_size[i] = 0; + zhole_size[i] = 0; } + + pgdat = NODE_DATA(node); + bdata = pgdat->bdata; + + /* + * The size of this node has already been determined. + * If we need to do anything fancy with the allocation + * of this memory to the zones, now is the time to do + * it. For now, we don't touch zhole_size. + */ + zone_size[0] = bdata->node_low_pfn - + (bdata->node_boot_start >> PAGE_SHIFT); + + free_area_init_node(node, pgdat, zone_size, + bdata->node_boot_start, zhole_size); } - free_area_init(zone_size); /* * finish off the bad pages once @@ -256,32 +431,33 @@ static inline void free_unused_mem_map(void) */ void __init mem_init(void) { - extern char __init_begin, __init_end, _text, _etext, _end; + extern char __init_begin, __init_end; unsigned int codepages, datapages, initpages; - int i; + int i, node; codepages = &_etext - &_text; datapages = &_end - &_etext; initpages = &__init_end - &__init_begin; - max_mapnr = max_low_pfn; - high_memory = (void *)__va(PHYS_OFFSET + max_low_pfn * PAGE_SIZE); + high_memory = (void *)__va(meminfo.end); + max_mapnr = MAP_NR(high_memory); /* * We may have non-contiguous memory. Setup the PageSkip stuff, * and mark the areas of mem_map which can be freed */ if (meminfo.nr_banks != 1) - create_memmap_holes(); + create_memmap_holes(&meminfo); /* this will put all unused low memory onto the freelists */ - totalram_pages += free_all_bootmem(); + for (node = 0; node < numnodes; node++) + totalram_pages += free_all_bootmem_node(node); /* * Since our memory may not be contiguous, calculate the * real number of pages we have in this system */ - printk("Memory:"); + printk(KERN_INFO "Memory:"); num_physpages = 0; for (i = 0; i < meminfo.nr_banks; i++) { @@ -290,7 +466,8 @@ void __init mem_init(void) } printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT)); - printk("Memory: %luKB available (%dK code, %dK data, %dK init)\n", + printk(KERN_NOTICE "Memory: %luKB available (%dK code, " + "%dK data, %dK init)\n", (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), codepages >> 10, datapages >> 10, initpages >> 10); diff --git a/arch/arm/mm/map.h b/arch/arm/mm/map.h index b596c6479..1d071748d 100644 --- a/arch/arm/mm/map.h +++ b/arch/arm/mm/map.h @@ -19,7 +19,7 @@ struct map_desc { extern struct map_desc io_desc[]; extern unsigned int io_desc_size; -extern void zonesize_init(unsigned int *); -extern void create_memmap_holes(void); -extern void pagetable_init(void); +struct meminfo; +extern void create_memmap_holes(struct meminfo *); +extern void pagetable_init(struct meminfo *); diff --git a/arch/arm/mm/mm-armo.c b/arch/arm/mm/mm-armo.c index f4bf7cad5..dc1647a2d 100644 --- a/arch/arm/mm/mm-armo.c +++ b/arch/arm/mm/mm-armo.c @@ -147,7 +147,7 @@ void setup_mm_for_reboot(char mode) * some more work to get it to fit into our separate processor and * architecture structure. */ -void __init pagetable_init(void) +void __init pagetable_init(struct meminfo *mi) { pte_t *pte; int i; @@ -165,6 +165,6 @@ void __init pagetable_init(void) /* * We never have holes in the memmap */ -void __init create_memmap_holes(void) +void __init create_memmap_holes(struct meminfo *mi) { } diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 5d46369eb..f58bc66f5 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -310,7 +310,7 @@ void setup_mm_for_reboot(char mode) } } -void __init pagetable_init(void) +void __init pagetable_init(struct meminfo *mi) { struct map_desc *init_maps, *p, *q; unsigned long address = 0; @@ -335,13 +335,13 @@ void __init pagetable_init(void) p ++; - for (i = 0; i < meminfo.nr_banks; i++) { - if (meminfo.bank[i].size == 0) + for (i = 0; i < mi->nr_banks; i++) { + if (mi->bank[i].size == 0) continue; - p->physical = meminfo.bank[i].start; + p->physical = mi->bank[i].start; p->virtual = __phys_to_virt(p->physical); - p->length = meminfo.bank[i].size; + p->length = mi->bank[i].size; p->domain = DOMAIN_KERNEL; p->prot_read = 0; p->prot_write = 1; @@ -414,7 +414,7 @@ void __init pagetable_init(void) * The mem_map array can get very big. Mark the end of the valid mem_map * banks with PG_skip, and setup the address validity bitmap. */ -void __init create_memmap_holes(void) +void __init create_memmap_holes(struct meminfo *mi) { unsigned int start_pfn, end_pfn = -1; struct page *pg = NULL; @@ -423,11 +423,11 @@ void __init create_memmap_holes(void) #define PFN(x) (((x) - PHYS_OFFSET) >> PAGE_SHIFT) #define free_bootmem(s,sz) free_bootmem(((s)<<PAGE_SHIFT)+PHYS_OFFSET, (sz)<<PAGE_SHIFT) - for (i = 0; i < meminfo.nr_banks; i++) { - if (meminfo.bank[i].size == 0) + for (i = 0; i < mi->nr_banks; i++) { + if (mi->bank[i].size == 0) continue; - start_pfn = PFN(meminfo.bank[i].start); + start_pfn = PFN(mi->bank[i].start); /* * subtle here - if we have a full bank, then @@ -447,9 +447,9 @@ void __init create_memmap_holes(void) pg = NULL; } - end_pfn = PFN(meminfo.bank[i].start + meminfo.bank[i].size); + end_pfn = PFN(mi->bank[i].start + mi->bank[i].size); - if (end_pfn != PFN(meminfo.end)) + if (end_pfn != PFN(mi->end)) pg = mem_map + end_pfn; } diff --git a/arch/arm/mm/mm-ebsa110.c b/arch/arm/mm/mm-ebsa110.c index a1172b1f1..f16c93793 100644 --- a/arch/arm/mm/mm-ebsa110.c +++ b/arch/arm/mm/mm-ebsa110.c @@ -8,6 +8,7 @@ #include <linux/mm.h> #include <linux/init.h> +#include <asm/hardware.h> #include <asm/pgtable.h> #include <asm/page.h> @@ -15,7 +16,7 @@ #define SIZE(x) (sizeof(x) / sizeof(x[0])) -const struct map_desc io_desc[] __initdata = { +struct map_desc io_desc[] __initdata = { { IO_BASE - PGDIR_SIZE, 0xc0000000, PGDIR_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, { IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 } }; diff --git a/arch/arm/mm/mm-rpc.c b/arch/arm/mm/mm-rpc.c index 0490cbdd0..494a61988 100644 --- a/arch/arm/mm/mm-rpc.c +++ b/arch/arm/mm/mm-rpc.c @@ -18,7 +18,7 @@ struct map_desc io_desc[] __initdata = { /* VRAM */ - { SCREEN2_BASE, SCREEN_START, 2*1048576, DOMAIN_IO, 0, 1, 0, 0 }, + { SCREEN_BASE, SCREEN_START, 2*1048576, DOMAIN_IO, 0, 1, 0, 0 }, /* IO space */ { IO_BASE, IO_START, IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 }, /* EASI space */ diff --git a/arch/arm/mm/mm-sa1100.c b/arch/arm/mm/mm-sa1100.c index 1cb1a3b58..5674dbe37 100644 --- a/arch/arm/mm/mm-sa1100.c +++ b/arch/arm/mm/mm-sa1100.c @@ -9,6 +9,10 @@ * 1999/12/04 Nicolas Pitre <nico@cam.org> * Converted memory definition for struct meminfo initialisations. * Memory is listed physically now. + * + * 2000/04/07 Nicolas Pitre <nico@cam.org> + * Reworked for real-time selection of memory definitions + * */ #include <linux/config.h> @@ -23,79 +27,109 @@ #define SIZE(x) (sizeof(x) / sizeof(x[0])) -/* - * These are the RAM memory mappings for SA1100 implementations. - * Note that LART is a special case - it doesn't use physical - * address line A23 on the DRAM, so we effectively have 4 * 8MB - * in two banks. - */ -struct mem_desc { - unsigned long phys_start; - unsigned long length; -} mem_desc[] __initdata = { -#if defined(CONFIG_SA1100_BRUTUS) - { 0xc0000000, 0x00400000 }, /* 4MB */ - { 0xc8000000, 0x00400000 }, /* 4MB */ - { 0xd0000000, 0x00400000 }, /* 4MB */ - { 0xd8000000, 0x00400000 } /* 4MB */ -#elif defined(CONFIG_SA1100_EMPEG) - { 0xc0000000, 0x00400000 }, /* 4MB */ - { 0xc8000000, 0x00400000 } /* 4MB */ -#elif defined(CONFIG_SA1100_LART) - { 0xc0000000, 0x00800000 }, /* 8MB */ - { 0xc1000000, 0x00800000 }, /* 8MB */ - { 0xc8000000, 0x00800000 }, /* 8MB */ - { 0xc9000000, 0x00800000 } /* 8MB */ -#elif defined(CONFIG_SA1100_VICTOR) - { 0xc0000000, 0x00400000 } /* 4MB */ -#elif defined(CONFIG_SA1100_THINCLIENT) - { 0xc0000000, 0x01000000 } /* 16MB */ -#elif defined(CONFIG_SA1100_TIFON) - { 0xc0000000, 0x01000000 }, /* 16MB */ - { 0xc8000000, 0x01000000 } /* 16MB */ -#else -#error missing memory configuration +#define SA1100_STD_IO_MAPPING \ + /* virtual physical length domain r w c b */ \ + { 0xe0000000, 0x20000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA0 IO */ \ + { 0xe4000000, 0x30000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA1 IO */ \ + { 0xe8000000, 0x28000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA0 attr */ \ + { 0xec000000, 0x38000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA1 attr */ \ + { 0xf0000000, 0x2c000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA0 mem */ \ + { 0xf4000000, 0x3c000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA1 mem */ \ + { 0xf8000000, 0x80000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCM */ \ + { 0xfa000000, 0x90000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* SCM */ \ + { 0xfc000000, 0xa0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* MER */ \ + { 0xfe000000, 0xb0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 } /* LCD + DMA */ + + +static struct map_desc assabet_io_desc[] __initdata = { +#ifdef CONFIG_SA1100_ASSABET + { 0xd0000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ + { 0xdc000000, 0x12000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Board Control Register */ + SA1100_STD_IO_MAPPING #endif }; -unsigned int __initdata mem_desc_size = SIZE(mem_desc); +static struct map_desc bitsy_io_desc[] __initdata = { +#ifdef CONFIG_SA1100_BITSY + { 0xd0000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */ + SA1100_STD_IO_MAPPING +#endif +}; +static struct map_desc empeg_io_desc[] __initdata = { +#ifdef CONFIG_SA1100_EMPEG + { EMPEG_FLASHBASE, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */ + SA1100_STD_IO_MAPPING +#endif +}; -struct map_desc io_desc[] __initdata = { - /* virtual physical length domain r w c b */ -#if defined(CONFIG_SA1100_VICTOR) - { 0xd0000000, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */ -#elif defined(CONFIG_SA1100_EMPEG) - { EMPEG_FLASHBASE, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */ -#elif defined(CONFIG_SA1100_THINCLIENT) +static struct map_desc thinclient_io_desc[] __initdata = { +#ifdef CONFIG_SA1100_THINCLIENT #if 1 - /* ThinClient: only one of those... */ -// { 0xd0000000, 0x00000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 when JP1 2-4 */ - { 0xd0000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 when JP1 3-4 */ + /* ThinClient: only one of those... */ +// { 0xd0000000, 0x00000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 when JP1 2-4 */ + { 0xd0000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 when JP1 3-4 */ #else - /* GraphicsClient: */ - { 0xd0000000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */ - { 0xd0800000, 0x18000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 3 */ + /* GraphicsClient: */ + { 0xd0000000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */ + { 0xd0800000, 0x18000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 3 */ +#endif + { 0xdc000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */ + SA1100_STD_IO_MAPPING #endif -#elif defined(CONFIG_SA1100_TIFON) - { 0xd0000000, 0x00000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */ - { 0xd0800000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 2 */ +}; + +static struct map_desc tifon_io_desc[] __initdata = { +#ifdef CONFIG_SA1100_TIFON + { 0xd0000000, 0x00000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */ + { 0xd0800000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 2 */ + SA1100_STD_IO_MAPPING #endif -#if defined( CONFIG_SA1101 ) - { 0xdc000000, SA1101_BASE, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA1101 */ -#elif defined( CONFIG_SA1100_THINCLIENT ) - { 0xdc000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */ +}; + +static struct map_desc victor_io_desc[] __initdata = { +#ifdef CONFIG_SA1100_VICTOR + { 0xd0000000, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */ + SA1100_STD_IO_MAPPING #endif - { 0xe0000000, 0x20000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA0 IO */ - { 0xe4000000, 0x30000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA1 IO */ - { 0xe8000000, 0x28000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA0 attr */ - { 0xec000000, 0x38000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA1 attr */ - { 0xf0000000, 0x2c000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA0 mem */ - { 0xf4000000, 0x3c000000, 0x04000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA1 mem */ - { 0xf8000000, 0x80000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCM */ - { 0xfa000000, 0x90000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* SCM */ - { 0xfc000000, 0xa0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* MER */ - { 0xfe000000, 0xb0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 } /* LCD + DMA */ }; -unsigned int __initdata io_desc_size = SIZE(io_desc); + +static struct map_desc default_io_desc[] __initdata = { + SA1100_STD_IO_MAPPING +}; + + +/* + * Here it would be wiser to simply assign a pointer to the appropriate + * list, but io_desc is already declared as an array in "map.h". + */ +struct map_desc io_desc[20] __initdata = { { 0, }, }; +unsigned int io_desc_size; + +void __init select_sa1100_io_desc(void) +{ + if( machine_is_assabet() ) { + memcpy( io_desc, assabet_io_desc, sizeof(assabet_io_desc) ); + io_desc_size = SIZE(assabet_io_desc); + } else if( machine_is_bitsy() ) { + memcpy( io_desc, bitsy_io_desc, sizeof(bitsy_io_desc) ); + io_desc_size = SIZE(bitsy_io_desc); + } else if( machine_is_empeg() ) { + memcpy( io_desc, empeg_io_desc, sizeof(empeg_io_desc) ); + io_desc_size = SIZE(empeg_io_desc); + } else if( machine_is_thinclient() ) { + memcpy( io_desc, thinclient_io_desc, sizeof(thinclient_io_desc) ); + io_desc_size = SIZE(thinclient_io_desc); + } else if( machine_is_tifon() ) { + memcpy( io_desc, tifon_io_desc, sizeof(tifon_io_desc) ); + io_desc_size = SIZE(tifon_io_desc); + } else if( machine_is_victor() ) { + memcpy( io_desc, victor_io_desc, sizeof(victor_io_desc) ); + io_desc_size = SIZE(victor_io_desc); + } else { + memcpy( io_desc, default_io_desc, sizeof(default_io_desc) ); + io_desc_size = SIZE(default_io_desc); + } +} + diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S index 13c1f2773..9ae5fb9d6 100644 --- a/arch/arm/mm/proc-sa110.S +++ b/arch/arm/mm/proc-sa110.S @@ -4,7 +4,9 @@ * (C) 1997-2000 Russell King * * These are the low level assembler for performing cache and TLB - * functions on the StrongARM-110 and StrongARM-1100 + * functions on the StrongARM-110, StrongARM-1100 and StrongARM-1110. + * + * Note that SA1100 and SA1110 share everything but their name and CPU ID. */ #include <linux/linkage.h> #include <asm/assembler.h> @@ -420,13 +422,12 @@ ENTRY(cpu_sa1100_proc_init) mov pc, lr ENTRY(cpu_sa110_proc_fin) -ENTRY(cpu_sa1100_proc_fin) stmfd sp!, {r1, lr} mrs r0, cpsr orr r0, r0, #F_BIT | I_BIT msr cpsr, r0 bl cpu_sa110_flush_cache_all @ clean caches - mov r0, #0 +1: mov r0, #0 mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x1000 @ ...i............ @@ -434,8 +435,17 @@ ENTRY(cpu_sa1100_proc_fin) mcr p15, 0, r0, c1, c0, 0 @ disable caches ldmfd sp!, {r1, pc} +ENTRY(cpu_sa1100_proc_fin) + stmfd sp!, {r1, lr} + mrs r0, cpsr + orr r0, r0, #F_BIT | I_BIT + msr cpsr, r0 + bl cpu_sa1100_flush_cache_all @ clean caches + b 1b + + .align 5 -idle: mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt +idle: mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt, cache aligned mov r0, r0 @ safety mov pc, lr /* @@ -483,16 +493,14 @@ ENTRY(cpu_sa1100_reset) bic ip, ip, #0x1100 @ ...i...s........ mcr p15, 0, ip, c1, c0, 0 @ ctrl register mov pc, r0 -/* - * Purpose : Function pointers used to access above functions - all calls - * come through these - */ + cpu_manu_name: .asciz "Intel" -ENTRY(cpu_sa110_name) - .asciz "StrongARM-110" -ENTRY(cpu_sa1100_name) +cpu_sa110_name: .asciz "StrongARM-110" +cpu_sa1100_name: .asciz "StrongARM-1100" +cpu_sa1110_name: + .asciz "StrongARM-1110" .align .section ".text.init", #alloc, #execinstr @@ -511,6 +519,13 @@ __sa110_setup: mov r0, #0 orr r0, r0, #0x1100 @ ...I...S........ mov pc, lr + .text + +/* + * Purpose : Function pointers used to access above functions - all calls + * come through these + */ + .type sa110_processor_functions, #object ENTRY(sa110_processor_functions) .word cpu_sa110_data_abort @@ -543,6 +558,9 @@ cpu_sa110_info: .size cpu_sa110_info, . - cpu_sa110_info +/* + * SA1100 and SA1110 share the same function calls + */ .type sa1100_processor_functions, #object ENTRY(sa1100_processor_functions) .word cpu_sa1100_data_abort @@ -573,6 +591,12 @@ cpu_sa1100_info: .long cpu_sa1100_name .size cpu_sa1100_info, . - cpu_sa1100_info +cpu_sa1110_info: + .long cpu_manu_name + .long cpu_sa1110_name + .size cpu_sa1110_info, . - cpu_sa1110_info + + .type cpu_arch_name, #object cpu_arch_name: .asciz "armv4" .size cpu_arch_name, . - cpu_arch_name @@ -610,4 +634,17 @@ __sa1100_proc_info: .long sa1100_processor_functions .size __sa1100_proc_info, . - __sa1100_proc_info + .type __sa1110_proc_info,#object +__sa1110_proc_info: + .long 0x6901b110 + .long 0xfffffff0 + .long 0x00000c02 + b __sa110_setup + .long cpu_arch_name + .long cpu_elf_name + .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT + .long cpu_sa1110_info + .long sa1100_processor_functions + .size __sa1110_proc_info, . - __sa1110_proc_info + |