From 272069b7ea18ab94404e480c4a091b94cdcc315c Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 4 Sep 2003 18:16:47 +1000 Subject: [PATCH] PPC32: Add support for the PPC 440 family of embedded processors. This has three main parts: (1) support for the 440GP and 440GX processors, (2) support for the "Ebony" and "Ocotea" reference boards for those processors, and (3) support for 64-bit physical addresses. The 440GP and 440GX are "Book E" processors, and this introduces a CONFIG_BOOKE and some definitions that apply to all Book E processors. Having 64-bit physical addresses means that PTEs are now 64 bits. The PTE pages stay at 4kB, and the pgdir expands to 8kB. --- arch/ppc/Kconfig | 13 +- arch/ppc/Makefile | 2 +- arch/ppc/boot/simple/Makefile | 7 +- arch/ppc/boot/simple/misc.c | 13 + arch/ppc/configs/ebony_defconfig | 560 +++++++++++++++ arch/ppc/configs/ocotea_defconfig | 574 ++++++++++++++++ arch/ppc/kernel/Makefile | 1 + arch/ppc/kernel/cputable.c | 11 +- arch/ppc/kernel/head_44x.S | 1056 +++++++++++++++++++++++++++++ arch/ppc/kernel/misc.S | 28 +- arch/ppc/kernel/ppc_ksyms.c | 5 +- arch/ppc/mm/44x_mmu.c | 162 +++++ arch/ppc/mm/Makefile | 1 + arch/ppc/mm/cachemap.c | 5 +- arch/ppc/mm/init.c | 1 + arch/ppc/mm/mmu_decl.h | 3 +- arch/ppc/mm/pgtable.c | 40 +- arch/ppc/platforms/4xx/Kconfig | 57 +- arch/ppc/platforms/4xx/Makefile | 4 + arch/ppc/platforms/4xx/ebony.c | 536 +++++++++++++++ arch/ppc/platforms/4xx/ebony.h | 96 +++ arch/ppc/platforms/4xx/ibm440gp.c | 31 + arch/ppc/platforms/4xx/ibm440gp.h | 102 +++ arch/ppc/platforms/4xx/ibm440gx.c | 37 + arch/ppc/platforms/4xx/ibm440gx.h | 123 ++++ arch/ppc/platforms/4xx/ocotea.c | 459 +++++++++++++ arch/ppc/platforms/4xx/ocotea.h | 84 +++ arch/ppc/syslib/Makefile | 4 + arch/ppc/syslib/ibm440gp_common.c | 77 +++ arch/ppc/syslib/ibm440gp_common.h | 45 ++ arch/ppc/syslib/ibm44x_common.c | 37 + include/asm-ppc/ibm44x.h | 435 ++++++++++++ include/asm-ppc/ibm4xx.h | 18 + include/asm-ppc/io.h | 13 +- include/asm-ppc/irq.h | 8 +- include/asm-ppc/mmu.h | 62 ++ include/asm-ppc/page.h | 28 +- include/asm-ppc/pgalloc.h | 7 + include/asm-ppc/pgtable.h | 96 ++- include/asm-ppc/ppc_asm.h | 6 +- include/asm-ppc/processor.h | 159 ++++- include/asm-ppc/serial.h | 2 +- include/asm-ppc/tlbflush.h | 12 +- 43 files changed, 4954 insertions(+), 66 deletions(-) create mode 100644 arch/ppc/configs/ebony_defconfig create mode 100644 arch/ppc/configs/ocotea_defconfig create mode 100644 arch/ppc/kernel/head_44x.S create mode 100644 arch/ppc/mm/44x_mmu.c create mode 100644 arch/ppc/platforms/4xx/ebony.c create mode 100755 arch/ppc/platforms/4xx/ebony.h create mode 100644 arch/ppc/platforms/4xx/ibm440gp.c create mode 100644 arch/ppc/platforms/4xx/ibm440gp.h create mode 100644 arch/ppc/platforms/4xx/ibm440gx.c create mode 100644 arch/ppc/platforms/4xx/ibm440gx.h create mode 100644 arch/ppc/platforms/4xx/ocotea.c create mode 100644 arch/ppc/platforms/4xx/ocotea.h create mode 100644 arch/ppc/syslib/ibm440gp_common.c create mode 100644 arch/ppc/syslib/ibm440gp_common.h create mode 100644 arch/ppc/syslib/ibm44x_common.c create mode 100644 include/asm-ppc/ibm44x.h diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index 22d91c235e70a..7e5aa4fa045c5 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -66,6 +66,9 @@ config 6xx config 40x bool "40x" +config 44x + bool "44x" + config POWER3 bool "POWER3" @@ -74,6 +77,11 @@ config 8xx endchoice +config PTE_64BIT + bool + depends on 44x + default y + source arch/ppc/platforms/4xx/Kconfig config 8260 @@ -766,8 +774,8 @@ config MCA RS/6000 machines are currently not supported by Linux. config PCI - bool "PCI support" if 4xx || 8260 - default y if !4xx && !8260 && !8xx && !APUS + bool "PCI support" if 40x || 8260 + default y if !40x && !8260 && !8xx && !APUS default PCI_PERMEDIA if !4xx && !8260 && !8xx && APUS default PCI_QSPAN if !4xx && !8260 && 8xx help @@ -1143,6 +1151,7 @@ config BOOT_LOAD_BOOL config BOOT_LOAD hex "Link/load address for booting" if BOOT_LOAD_BOOL default "0x00400000" if 40x || 8xx || 8260 + default "0x01000000" if 44x default "0x00800000" config PIN_TLB diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index 5db110d1c75bf..52d06170c3760 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -29,7 +29,7 @@ CFLAGS += $(cflags-y) head-y := arch/ppc/kernel/head.o head-$(CONFIG_8xx) := arch/ppc/kernel/head_8xx.o head-$(CONFIG_4xx) := arch/ppc/kernel/head_4xx.o -head-$(CONFIG_440) := arch/ppc/kernel/head_44x.o +head-$(CONFIG_44x) := arch/ppc/kernel/head_44x.o head-$(CONFIG_6xx) += arch/ppc/kernel/idle_6xx.o diff --git a/arch/ppc/boot/simple/Makefile b/arch/ppc/boot/simple/Makefile index 28231b85cfdb1..3ead7056e3a76 100644 --- a/arch/ppc/boot/simple/Makefile +++ b/arch/ppc/boot/simple/Makefile @@ -48,11 +48,16 @@ zimageinitrd-$(CONFIG_IBM_OPENBIOS) := zImage.initrd-TREE zimage-$(CONFIG_EBONY) := zImage-TREE zimageinitrd-$(CONFIG_EBONY) := zImage.initrd-TREE - extra.o-$(CONFIG_EBONY) := direct.o end-$(CONFIG_EBONY) := ebony entrypoint-$(CONFIG_EBONY) := 0x01000000 tftpimage-$(CONFIG_EBONY) := /tftpboot/zImage.$(end-y) + zimage-$(CONFIG_OCOTEA) := zImage-TREE +zimageinitrd-$(CONFIG_OCOTEA) := zImage.initrd-TREE + end-$(CONFIG_OCOTEA) := ocotea + entrypoint-$(CONFIG_OCOTEA) := 0x01000000 + tftpimage-$(CONFIG_OCOTEA) := /tftpboot/zImage.$(end-y) + extra.o-$(CONFIG_EV64260) := direct.o misc-ev64260.o tftpimage-$(CONFIG_EV64260) := /tftpboot/zImage.ev64260 diff --git a/arch/ppc/boot/simple/misc.c b/arch/ppc/boot/simple/misc.c index c14e633386ea4..6597200b829d9 100644 --- a/arch/ppc/boot/simple/misc.c +++ b/arch/ppc/boot/simple/misc.c @@ -25,6 +25,9 @@ #include #include #include +#ifdef CONFIG_44x +#include +#endif #include "nonstdio.h" #include "zlib.h" @@ -80,6 +83,16 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) serial_fixups(); com_port = serial_init(0, NULL); +#ifdef CONFIG_44x + /* Reset MAL */ + mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); + /* Wait for reset */ + while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; + /* Reset EMAC */ + *(volatile unsigned long *)PPC44x_EMAC0_MR0 = 0x20000000; + __asm__ __volatile__("eieio"); +#endif + #if defined(CONFIG_LOPEC) || defined(CONFIG_PAL4) /* * Call get_mem_size(), which is memory controller dependent, diff --git a/arch/ppc/configs/ebony_defconfig b/arch/ppc/configs/ebony_defconfig new file mode 100644 index 0000000000000..b466152a06d53 --- /dev/null +++ b/arch/ppc/configs/ebony_defconfig @@ -0,0 +1,560 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MMU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +# CONFIG_6xx is not set +# CONFIG_40x is not set +CONFIG_44x=y +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +CONFIG_PTE_64BIT=y +CONFIG_4xx=y + +# +# IBM 4xx options +# +CONFIG_EBONY=y +# CONFIG_OCOTEA is not set +CONFIG_440GP=y +CONFIG_440=y +CONFIG_PIN_TLB=y +CONFIG_BOOKE=y +CONFIG_IBM_OCP=y +# CONFIG_PM is not set +CONFIG_NOT_COHERENT_CACHE=y +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_CPU_FREQ is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_PC_KEYBOARD is not set +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PCI_LEGACY_PROC is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="ip=on" + +# +# 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_BOOT_LOAD=0x01000000 + +# +# Generic Driver Options +# + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +CONFIG_LBD=y + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# 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 +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +# CONFIG_EXT2_FS 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 +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA 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_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS 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_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 + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Library routines +# +CONFIG_CRC32=y + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SLAB is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +CONFIG_BDI_SWITCH=y +# CONFIG_DEBUG_INFO is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set +CONFIG_OCP=y + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set diff --git a/arch/ppc/configs/ocotea_defconfig b/arch/ppc/configs/ocotea_defconfig new file mode 100644 index 0000000000000..0f398257ef7b4 --- /dev/null +++ b/arch/ppc/configs/ocotea_defconfig @@ -0,0 +1,574 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MMU=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_HAVE_DEC_LOCK=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y + +# +# General setup +# +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_IKCONFIG is not set +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_PPC32=y +# CONFIG_6xx is not set +# CONFIG_40x is not set +CONFIG_44x=y +# CONFIG_POWER3 is not set +# CONFIG_8xx is not set +CONFIG_PTE_64BIT=y +CONFIG_4xx=y + +# +# IBM 4xx options +# +# CONFIG_EBONY is not set +CONFIG_OCOTEA=y +CONFIG_440GX=y +CONFIG_440A=y +CONFIG_PIN_TLB=y +CONFIG_BOOKE=y +CONFIG_IBM_OCP=y +CONFIG_IBM_EMAC4=y +# CONFIG_PM is not set +CONFIG_NOT_COHERENT_CACHE=y +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_CPU_FREQ is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +# CONFIG_PC_KEYBOARD is not set +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_PCI_LEGACY_PROC is not set +# CONFIG_PCI_NAMES is not set +# CONFIG_HOTPLUG is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="ip=on console=ttyS0,115200" + +# +# 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_BOOT_LOAD=0x01000000 + +# +# Generic Driver Options +# + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play support +# +# CONFIG_PNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_LBD is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support (EXPERIMENTAL) +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_DHCP is not set +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +# CONFIG_IPV6 is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set + +# +# IP: Netfilter Configuration +# +# CONFIG_IP_NF_CONNTRACK is not set +# CONFIG_IP_NF_QUEUE is not set +# CONFIG_IP_NF_IPTABLES is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_COMPAT_IPCHAINS is not set +# CONFIG_IP_NF_COMPAT_IPFWADM is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IPV6_SCTP__=y +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_LLC is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_OAKNET is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_IXGB is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices (depends on LLC=y) +# +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN_BOOL is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +# CONFIG_MDA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input I/O drivers +# +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y +# CONFIG_SERIO is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_SHARE_IRQ=y +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +# CONFIG_SERIAL_8250_MULTIPORT is not set +# CONFIG_SERIAL_8250_RSA is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# I2C Hardware Sensors Mainboard support +# + +# +# I2C Hardware Sensors Chip support +# +# CONFIG_I2C_SENSOR is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_QIC02_TAPE is not set + +# +# 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 +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# File systems +# +# CONFIG_EXT2_FS 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 +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA 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_FAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +CONFIG_DEVPTS_FS=y +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS 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_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 + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +# CONFIG_EXPORTFS is not set +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_GSS is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BT is not set + +# +# Library routines +# +CONFIG_CRC32=y + +# +# Kernel hacking +# +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SLAB is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +CONFIG_BDI_SWITCH=y +CONFIG_DEBUG_INFO=y +# CONFIG_SERIAL_TEXT_DEBUG is not set +CONFIG_OCP=y + +# +# Security options +# +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index a00393bbdf332..77760d6fafd76 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -12,6 +12,7 @@ endif # Start off with 'head.o', change as needed. extra-y := head.o extra-$(CONFIG_40x) := head_4xx.o +extra-$(CONFIG_44x) := head_44x.o extra-$(CONFIG_8xx) := head_8xx.o extra-$(CONFIG_6xx) += idle_6xx.o extra-y += vmlinux.lds.s diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c index 2d67a182b1069..71c2c441a14fe 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/ppc/kernel/cputable.c @@ -433,7 +433,7 @@ struct cpu_spec cpu_specs[] = { }, #endif /* CONFIG_40x */ -#ifdef CONFIG_440 +#ifdef CONFIG_44x { /* 440GP Rev. B */ 0xf0000fff, 0x40000440, "440GP Rev. B", CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, @@ -448,7 +448,14 @@ struct cpu_spec cpu_specs[] = { 32, 32, 0, /*__setup_cpu_440 */ }, -#endif /* CONFIG_440 */ + { /* 440GX Rev. A */ + 0xf0000fff, 0x50000850, "440GX Rev. A", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, + 32, 32, + 0, /*__setup_cpu_440 */ + }, +#endif /* CONFIG_44x */ #if !CLASSIC_PPC { /* default match */ 0x00000000, 0x00000000, "(generic PPC)", diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S new file mode 100644 index 0000000000000..125f131a3c308 --- /dev/null +++ b/arch/ppc/kernel/head_44x.S @@ -0,0 +1,1056 @@ +/* + * arch/ppc/kernel/head_44x.S + * + * Kernel execution entry point code. + * + * Matt Porter + * + * Copyright 2002-2003 MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Macros + */ + +#define SET_IVOR(vector_number, vector_label) \ + li r26,vector_label@l; \ + mtspr SPRN_IVOR##vector_number,r26; \ + sync + +/* As with the other PowerPC ports, it is expected that when code + * execution begins here, the following registers contain valid, yet + * optional, information: + * + * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.) + * r4 - Starting address of the init RAM disk + * r5 - Ending address of the init RAM disk + * r6 - Start of kernel command line string (e.g. "mem=128") + * r7 - End of kernel command line string + * + */ + .text +_GLOBAL(_stext) +_GLOBAL(_start) + /* + * Reserve a word at a fixed location to store the address + * of abatron_pteptrs + */ + nop +/* + * Save parameters we are passed + */ + mr r31,r3 + mr r30,r4 + mr r29,r5 + mr r28,r6 + mr r27,r7 + li r24,0 /* CPU number */ + +/* + * Set up the initial MMU state + * + * We are still executing code at the virtual address + * mappings set by the firmware for the base of RAM. + * + * We first invalidate all TLB entries but the one + * we are running from. We then load the KERNELBASE + * mappings so we can begin to use kernel addresses + * natively and so the interrupt vector locations are + * permanently pinned (necessary since Book E + * implementations always have translation enabled). + * + * TODO: Use the known TLB entry we are running from to + * determine which physical region we are located + * in. This can be used to determine where in RAM + * (on a shared CPU system) or PCI memory space + * (on a DRAMless system) we are located. + * For now, we assume a perfect world which means + * we are located at the base of DRAM (physical 0). + */ + +/* + * Search TLB for entry that we are currently using. + * Invalidate all entries but the one we are using. + */ + /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */ + mfspr r3,SPRN_MMUCR /* Get MMUCR */ + lis r4,PPC44x_MMUCR_STS@h + ori r4,r4,PPC44x_MMUCR_TID@l /* Create mask */ + andc r3,r3,r4 /* Clear out TID/STS bits */ + mfspr r4,SPRN_PID /* Get PID */ + or r3,r3,r4 /* Set TID bits */ + mfmsr r5 /* Get MSR */ + andi. r5,r5,MSR_IS@l /* TS=1? */ + beq wmmucr /* If not, leave STS=0 */ + oris r3,r3,PPC44x_MMUCR_STS@h /* Set STS=1 */ +wmmucr: mtspr SPRN_MMUCR,r3 /* Put MMUCR */ + sync + + bl invstr /* Find our address */ +invstr: mflr r5 /* Make it accessible */ + tlbsx r23,0,r5 /* Find entry we are in */ + li r4,0 /* Start at TLB entry 0 */ + li r3,0 /* Set PAGEID inval value */ +1: cmpw r23,r4 /* Is this our entry? */ + beq skpinv /* If so, skip the inval */ + tlbwe r3,r4,PPC44x_TLB_PAGEID /* If not, inval the entry */ +skpinv: addi r4,r4,1 /* Increment */ + cmpwi r4,64 /* Are we done? */ + bne 1b /* If not, repeat */ + isync /* If so, context change */ + +/* + * Configure and load pinned entries into TLB slots 62 and 63. + */ + + lis r3,KERNELBASE@h /* Load the kernel virtual address */ + ori r3,r3,KERNELBASE@l + + /* Kernel is at the base of RAM */ + li r4, 0 /* Load the kernel physical address */ + + /* Load the kernel PID = 0 */ + li r0,0 + mtspr SPRN_PID,r0 + sync + + /* Load the kernel TID = 0 */ + mfspr r5,SPRN_MMUCR + lis r6, PPC44x_MMUCR_TID@h + ori r6,r6,PPC44x_MMUCR_TID@l + andc r5,r5,r6 + mtspr SPRN_MMUCR,r5 + sync + + /* pageid fields */ + clrrwi r3,r3,10 /* Mask off the effective page number */ + ori r3,r3,(PPC44x_TLB_VALID | PPC44x_TLB_PAGESZ(PPC44x_PAGESZ_256M)) + + /* xlat fields */ + clrrwi r4,r4,10 /* Mask off the real page number */ + /* ERPN is 0 for first 4GB page */ + + /* attrib fields */ + /* Added guarded bit to protect against speculative loads/stores */ + li r5,0 + ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G) + + li r0,62 /* TLB slot 62 */ + + tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ + tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ + tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */ + + /* Force context change */ + mfmsr r0 + mtspr SRR1, r0 + lis r0,3f@h + ori r0,r0,3f@l + mtspr SRR0,r0 + sync + rfi + + /* If necessary, invalidate original entry we used */ +3: cmpwi r23,62 + beq 4f + li r6,0 + tlbwe r6,r23,PPC44x_TLB_PAGEID + sync + +4: ori r3,r3,PPC44x_TLB_TS /* TS = 1 */ + + li r0,63 /* TLB slot 63 */ + + tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ + tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ + tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */ + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + /* + * Add temporary UART mapping for early debug. This + * mapping must be identical to that used by the early + * bootloader code since the same asm/serial.h parameters + * are used for polled operation. + */ + /* pageid fields */ + lis r3,0xe000 + ori r3,r3,(PPC44x_TLB_VALID | PPC44x_TLB_PAGESZ(PPC44x_PAGESZ_256M)) + + /* xlat fields */ + lis r4,0x4000 /* RPN is 0x40000000 */ + ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */ + + /* attrib fields */ + li r5,0 + ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G) + + li r0,60 /* TLB slot 60 */ + + tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ + tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ + tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */ + + ori r3,r3,PPC44x_TLB_TS /* Translation state 1 */ + + li r0,61 /* TLB slot 61 */ + + tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ + tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ + tlbwe r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */ +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + + /* Force context change */ + isync + + /* Establish the interrupt vector offsets */ + SET_IVOR(0, CriticalInput); + SET_IVOR(1, MachineCheck); + SET_IVOR(2, DataStorage); + SET_IVOR(3, InstructionStorage); + SET_IVOR(4, ExternalInput); + SET_IVOR(5, Alignment); + SET_IVOR(6, Program); + SET_IVOR(7, FloatingPointUnavailable); + SET_IVOR(8, SystemCall); + SET_IVOR(9, AuxillaryProcessorUnavailable); + SET_IVOR(10, Decrementer); + SET_IVOR(11, FixedIntervalTimer); + SET_IVOR(12, WatchdogTimer); + SET_IVOR(13, DataTLBError); + SET_IVOR(14, InstructionTLBError); + SET_IVOR(15, Debug); + + /* Establish the interrupt vector base */ + lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ + mtspr SPRN_IVPR,r4 + + /* + * This is where the main kernel code starts. + */ + + /* ptr to current */ + lis r2,init_task@h + ori r2,r2,init_task@l + + /* ptr to current thread */ + addi r4,r2,THREAD /* init task's THREAD */ + mtspr SPRG3,r4 + + /* stack */ + lis r1,init_thread_union@h + ori r1,r1,init_thread_union@l + li r0,0 + stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1) + + bl early_init + +/* + * Decide what sort of machine this is and initialize the MMU. + */ + mr r3,r31 + mr r4,r30 + mr r5,r29 + mr r6,r28 + mr r7,r27 + bl machine_init + bl MMU_init + + /* Setup 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 + lis r4, KERNELBASE@h + ori r4, r4, KERNELBASE@l + stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */ + stw r6, 0(r5) + + /* Let's move on */ + lis r4,start_kernel@h + ori r4,r4,start_kernel@l + lis r3,MSR_KERNEL@h + ori r3,r3,MSR_KERNEL@l + mtspr SRR0,r4 + mtspr SRR1,r3 + rfi /* change context and jump to start_kernel */ + +/* + * Interrupt vector entry code + * + * The Book E MMUs are always on so we don't need to handle + * interrupts in real mode as with previous PPC processors. In + * this case we handle interrupts in the kernel virtual address + * space. + * + * Interrupt vectors are dynamically placed relative to the + * interrupt prefix as determined by the address of interrupt_base. + * The interrupt vectors offsets are programmed using the labels + * for each interrupt vector entry. + * + * Interrupt vectors must be aligned on a 16 byte boundary. + * We align on a 32 byte cache line boundary for good measure. + */ + +#define NORMAL_EXCEPTION_PROLOG \ + mtspr SPRN_SPRG0,r10; /* save two registers to work with */\ + mtspr SPRN_SPRG1,r11; \ + mtspr SPRN_SPRG2,r1; \ + mfcr r10; /* save CR in r10 for now */\ + mfspr r11,SPRN_SRR1; /* check whether user or kernel */\ + andi. r11,r11,MSR_PR; \ + beq 1f; \ + mfspr r1,SPRG3; /* if from user, start at top of */\ + lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\ + addi r1,r1,THREAD_SIZE; \ +1: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\ + tophys(r11,r1); \ + stw r10,_CCR(r11); /* save various registers */\ + stw r12,GPR12(r11); \ + stw r9,GPR9(r11); \ + mfspr r10,SPRG0; \ + stw r10,GPR10(r11); \ + mfspr r12,SPRG1; \ + stw r12,GPR11(r11); \ + mflr r10; \ + stw r10,_LINK(r11); \ + mfspr r10,SPRG2; \ + mfspr r12,SRR0; \ + stw r10,GPR1(r11); \ + mfspr r9,SRR1; \ + stw r10,0(r11); \ + rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\ + stw r0,GPR0(r11); \ + SAVE_4GPRS(3, r11); \ + SAVE_2GPRS(7, r11) + +/* + * Exception prolog for critical exceptions. This is a little different + * from the normal exception prolog above since a critical exception + * can potentially occur at any point during normal exception processing. + * Thus we cannot use the same SPRG registers as the normal prolog above. + * Instead we use a couple of words of memory at low physical addresses. + * This is OK since we don't support SMP on these processors. + */ +/* XXX but we don't have RAM mapped at 0 in space 0 -- paulus. */ +#define CRITICAL_EXCEPTION_PROLOG \ + stw r10,crit_r10@l(0); /* save two registers to work with */\ + stw r11,crit_r11@l(0); \ + mfspr r10,SPRG0; \ + stw r10,crit_sprg0@l(0); \ + mfspr r10,SPRG1; \ + stw r10,crit_sprg1@l(0); \ + mfspr r10,SPRG4R; \ + stw r10,crit_sprg4@l(0); \ + mfspr r10,SPRG5R; \ + stw r10,crit_sprg5@l(0); \ + mfspr r10,SPRG6R; \ + stw r10,crit_sprg6@l(0); \ + mfspr r10,SPRG7R; \ + stw r10,crit_sprg7@l(0); \ + mfspr r10,SPRN_PID; \ + stw r10,crit_pid@l(0); \ + mfspr r10,SRR0; \ + stw r10,crit_srr0@l(0); \ + mfspr r10,SRR1; \ + stw r10,crit_srr1@l(0); \ + mfcr r10; /* save CR in r10 for now */\ + mfspr r11,SPRN_CSRR1; /* check whether user or kernel */\ + andi. r11,r11,MSR_PR; \ + lis r11,critical_stack_top@h; \ + ori r11,r11,critical_stack_top@l; \ + beq 1f; \ + /* COMING FROM USER MODE */ \ + mfspr r11,SPRG3; /* if from user, start at top of */\ + lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\ + addi r11,r11,THREAD_SIZE; \ +1: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\ + tophys(r11,r11); \ + stw r10,_CCR(r11); /* save various registers */\ + stw r12,GPR12(r11); \ + stw r9,GPR9(r11); \ + mflr r10; \ + stw r10,_LINK(r11); \ + mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\ + stw r12,_DEAR(r11); /* since they may have had stuff */\ + mfspr r9,SPRN_ESR; /* in them at the point where the */\ + stw r9,_ESR(r11); /* exception was taken */\ + mfspr r12,CSRR0; \ + stw r1,GPR1(r11); \ + mfspr r9,CSRR1; \ + stw r1,0(r11); \ + tovirt(r1,r11); \ + rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\ + stw r0,GPR0(r11); \ + SAVE_4GPRS(3, r11); \ + SAVE_2GPRS(7, r11) + +/* + * Exception vectors. + */ +#define START_EXCEPTION(label) \ + .align 5; \ +label: + +#define FINISH_EXCEPTION(func) \ + bl transfer_to_handler_full; \ + .long func; \ + .long ret_from_except_full + +#define EXCEPTION(n, label, hdlr, xfer) \ + START_EXCEPTION(label); \ + NORMAL_EXCEPTION_PROLOG; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + xfer(n, hdlr) + +#define CRITICAL_EXCEPTION(n, label, hdlr) \ + START_EXCEPTION(label); \ + CRITICAL_EXCEPTION_PROLOG; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ + NOCOPY, transfer_to_handler_full, \ + ret_from_except_full) + +#define EXC_XFER_TEMPLATE(hdlr, trap, msr, copyee, tfer, ret) \ + li r10,trap; \ + stw r10,TRAP(r11); \ + lis r10,msr@h; \ + ori r10,r10,msr@l; \ + copyee(r10, r9); \ + bl tfer; \ + .long hdlr; \ + .long ret + +#define COPY_EE(d, s) rlwimi d,s,0,16,16 +#define NOCOPY(d, s) + +#define EXC_XFER_STD(n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, NOCOPY, transfer_to_handler_full, \ + ret_from_except_full) + +#define EXC_XFER_LITE(n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, NOCOPY, transfer_to_handler, \ + ret_from_except) + +#define EXC_XFER_EE(n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n, MSR_KERNEL, COPY_EE, transfer_to_handler_full, \ + ret_from_except_full) + +#define EXC_XFER_EE_LITE(n, hdlr) \ + EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, COPY_EE, transfer_to_handler, \ + ret_from_except) + +interrupt_base: + /* Critical Input Interrupt */ + CRITICAL_EXCEPTION(0x0100, CriticalInput, UnknownException) + + /* Machine Check Interrupt */ + CRITICAL_EXCEPTION(0x0200, MachineCheck, MachineCheckException) + + /* Data Storage Interrupt */ + START_EXCEPTION(DataStorage) + mtspr SPRG0, r10 /* Save some working registers */ + mtspr SPRG1, r11 + mtspr SPRG4W, r12 + mtspr SPRG5W, r13 + mtspr SPRG6W, r14 + mfcr r11 + mtspr SPRG7W, r11 + + /* + * Check if it was a store fault, if not then bail + * because a user tried to access a kernel or + * read-protected page. Otherwise, get the + * offending address and handle it. + */ + mfspr r10, SPRN_ESR + andis. r10, r10, ESR_ST@h + beq 2f + + mfspr r10, SPRN_DEAR /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + andis. r11, r10, 0x8000 + beq 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + + mfspr r12,SPRN_MMUCR /* Set TID to 0 */ + li r13,PPC44x_MMUCR_TID@l + andc r12,r12,r13 + mtspr SPRN_MMUCR,r12 + + b 4f + + /* Get the PGD for the current thread */ +3: + mfspr r11,SPRG3 + lwz r11,PGDIR(r11) + + /* Load MMUCR with our PID and STS= */ + mfspr r12,SPRN_MMUCR /* Get MMUCR */ + lis r13,PPC44x_MMUCR_STS@h + ori r13,r13,PPC44x_MMUCR_TID@l /* Create mask */ + andc r12,r12,r13 /* Clear out TID/STS bits */ + mfspr r13,SPRN_PID /* Get PID */ + or r12,r12,r13 /* Set TID bits */ + mfspr r14,SPRN_SRR1 /* Get SRR1 */ + andi. r14,r14,MSR_IS@l /* TS=1? */ + beq 4f /* If not, leave STS=0 */ + oris r12,r12,PPC44x_MMUCR_STS@h /* Set STS=1 */ + mtspr SPRN_MMUCR,r12 +4: + rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ + lwzx r11, r12, r11 /* Get pgd/pmd entry */ + rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ + beq 2f /* Bail if no table */ + + rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ + lwz r11, 4(r12) /* Get pte entry */ + + andi. r13, r11, _PAGE_RW /* Is it writeable? */ + beq 2f /* Bail if not */ + + /* Update 'changed'. + */ + ori r11, r11, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE + stw r11, 4(r12) /* Update Linux page table */ + + /* FIXME: Staticly setting some permissions */ + li r13, 0x003f /* Set UX,UW,UR,SX,SW,SR */ + andi. r11,r11,0xffff /* Clear MS 16 bits */ + /* FIXME: Force attributes */ + ori r11,r11, 0x0100 /* Set G */ + /* FIXME: Already set in PTE */ + rlwimi r11,r13,0,26,31 /* Insert static perms */ + + lis r13,0xffff + ori r13,r13,0x0fff /* Set U0-U3 mask */ + and r11,r11,r13 /* Clear U0-U3 */ + + /* find the TLB index that caused the fault. It has to be here. */ + tlbsx r14, 0, r10 + + tlbwe r11, r14, PPC44x_TLB_ATTRIB /* Write ATTRIB */ + + /* Done...restore registers and get out of here. + */ + mfspr r11, SPRG7R + mtcr r11 + mfspr r14, SPRG6R + mfspr r13, SPRG5R + mfspr r12, SPRG4R + + mfspr r11, SPRG1 + mfspr r10, SPRG0 + rfi /* Force context change */ + +2: + /* + * The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ + mfspr r11, SPRG7R + mtcr r11 + mfspr r14, SPRG6R + mfspr r13, SPRG5R + mfspr r12, SPRG4R + + mfspr r11, SPRG1 + mfspr r10, SPRG0 + b data_access + + /* Instruction Storage Interrupt */ + START_EXCEPTION(InstructionStorage) + NORMAL_EXCEPTION_PROLOG + mr r4,r12 /* Pass SRR0 as arg2 */ + li r5,0 /* Pass zero as arg3 */ + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE_LITE(0x0400, do_page_fault) + + /* External Input Interrupt */ + EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE) + + /* Alignment Interrupt */ + START_EXCEPTION(Alignment) + NORMAL_EXCEPTION_PROLOG + mfspr r4,SPRN_DEAR /* Grab the DEAR and save it */ + stw r4,_DEAR(r11) + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE(0x0600, AlignmentException) + + /* Program Interrupt */ + START_EXCEPTION(Program) + NORMAL_EXCEPTION_PROLOG + mfspr r4,SPRN_ESR /* Grab the ESR and save it */ + stw r4,_ESR(r11) + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE(0x700, ProgramCheckException) + + /* Floating Point Unavailable Interrupt */ + EXCEPTION(0x2010, FloatingPointUnavailable, UnknownException, EXC_XFER_EE) + + /* System Call Interrupt */ + START_EXCEPTION(SystemCall) + NORMAL_EXCEPTION_PROLOG + EXC_XFER_EE_LITE(0x0c00, DoSyscall) + + /* Auxillary Processor Unavailable Interrupt */ + EXCEPTION(0x2020, AuxillaryProcessorUnavailable, UnknownException, EXC_XFER_EE) + + /* Decrementer Interrupt */ + START_EXCEPTION(Decrementer) + NORMAL_EXCEPTION_PROLOG + lis r0,TSR_DIS@h /* Setup the DEC interrupt mask */ + mtspr SPRN_TSR,r0 /* Clear the DEC interrupt */ + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_LITE(0x1000, timer_interrupt) + + /* Fixed Internal Timer Interrupt */ + /* TODO: Add FIT support */ + EXCEPTION(0x1010, FixedIntervalTimer, UnknownException, EXC_XFER_EE) + + /* Watchdog Timer Interrupt */ + /* TODO: Add watchdog support */ + CRITICAL_EXCEPTION(0x1020, WatchdogTimer, UnknownException) + + /* Data TLB Error Interrupt */ + START_EXCEPTION(DataTLBError) + mtspr SPRG0, r10 /* Save some working registers */ + mtspr SPRG1, r11 + mtspr SPRG4W, r12 + mtspr SPRG5W, r13 + mtspr SPRG6W, r14 + mfcr r11 + mtspr SPRG7W, r11 + mfspr r10, SPRN_DEAR /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + andis. r11, r10, 0x8000 + beq 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + + mfspr r12,SPRN_MMUCR /* Set TID to 0 */ + li r13,PPC44x_MMUCR_TID@l + andc r12,r12,r13 + mtspr SPRN_MMUCR,r12 + + b 4f + + /* Get the PGD for the current thread */ +3: + mfspr r11,SPRG3 + lwz r11,PGDIR(r11) + + /* Load PID into MMUCR TID */ + li r13,PPC44x_MMUCR_TID@l /* Create mask */ + andc r12,r12,r13 /* Clear out TID/STS bits */ + mfspr r13,SPRN_PID /* Get PID */ + or r12,r12,r13 + mtspr SPRN_MMUCR,r12 +4: + rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ + lwzx r11, r12, r11 /* Get pgd/pmd entry */ + rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ + beq 2f /* Bail if no table */ + + rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ + lwz r11, 4(r12) /* Get pte entry */ + andi. r13, r11, _PAGE_PRESENT /* Is the page present? */ + beq 2f /* Bail if not present */ + + ori r11, r11, _PAGE_ACCESSED + stw r11, 4(r12) + + /* Jump to common tlb load */ + b finish_tlb_load + +2: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ + mfspr r11, SPRG7R + mtcr r11 + mfspr r14, SPRG6R + mfspr r13, SPRG5R + mfspr r12, SPRG4R + mfspr r11, SPRG1 + mfspr r10, SPRG0 + b data_access + + /* Instruction TLB Error Interrupt */ + /* + * Nearly the same as above, except we get our + * information from different registers and bailout + * to a different point. + */ + START_EXCEPTION(InstructionTLBError) + mtspr SPRG0, r10 /* Save some working registers */ + mtspr SPRG1, r11 + mtspr SPRG4W, r12 + mtspr SPRG5W, r13 + mtspr SPRG6W, r14 + mfcr r11 + mtspr SPRG7W, r11 + mfspr r10, SRR0 /* Get faulting address */ + + /* If we are faulting a kernel address, we have to use the + * kernel page tables. + */ + andis. r11, r10, 0x8000 + beq 3f + lis r11, swapper_pg_dir@h + ori r11, r11, swapper_pg_dir@l + + mfspr r12,SPRN_MMUCR /* Set TID to 0 */ + li r13,PPC44x_MMUCR_TID@l + andc r12,r12,r13 + mtspr SPRN_MMUCR,r12 + + b 4f + + /* Get the PGD for the current thread */ +3: + mfspr r11,SPRG3 + lwz r11,PGDIR(r11) + + /* Load PID into MMUCR TID */ + li r13,PPC44x_MMUCR_TID@l /* Create mask */ + andc r12,r13,r13 /* Clear out TID/STS bits */ + mfspr r13,SPRN_PID /* Get PID */ + or r12,r12,r13 + mtspr SPRN_MMUCR,r12 + +4: + rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ + lwzx r11, r12, r11 /* Get pgd/pmd entry */ + rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ + beq 2f /* Bail if no table */ + + rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ + lwz r11, 4(r12) /* Get pte entry */ + andi. r13, r11, _PAGE_PRESENT /* Is the page present? */ + beq 2f /* Bail if not present */ + + ori r11, r11, _PAGE_ACCESSED + stw r11, 4(r12) + + /* Jump to common TLB load point */ + b finish_tlb_load + +2: + /* The bailout. Restore registers to pre-exception conditions + * and call the heavyweights to help us out. + */ + mfspr r11, SPRG7R + mtcr r11 + mfspr r14, SPRG6R + mfspr r13, SPRG5R + mfspr r12, SPRG4R + mfspr r11, SPRG1 + mfspr r10, SPRG0 + b InstructionStorage + +/* Check for a single step debug exception while in an exception + * handler before state has been saved. This is to catch the case + * where an instruction that we are trying to single step causes + * an exception (eg ITLB/DTLB miss) and thus the first instruction of + * the exception handler generates a single step debug exception. + * + * If we get a debug trap on the first instruction of an exception handler, + * we reset the MSR_DE in the _exception handler's_ MSR (the debug trap is + * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR). + * The exception handler was handling a non-critical interrupt, so it will + * save (and later restore) the MSR via SPRN_SRR1, which will still have + * the MSR_DE bit set. + */ + /* Debug Interrupt */ + CRITICAL_EXCEPTION(0x2000, Debug, DebugException) +#if 0 + START_EXCEPTION(Debug) + /* This first instruction was already executed by the exception + * handler and must be the first instruction of every exception + * handler. + */ + mtspr SPRN_SPRG0,r10 /* Save some working registers... */ + mtspr SPRN_SPRG1,r11 + mtspr SPRN_SPRG4W,r12 + mfcr r10 /* ..and the cr because we change it */ + + mfspr r11,SPRN_CSRR1 /* MSR at the time of fault */ + andi. r11,r11,MSR_PR + bne+ 2f /* trapped from problem state */ + + mfspr r11,SPRN_CSRR0 /* Faulting instruction address */ + lis r12, KERNELBASE@h + ori r12, r12, KERNELBASE@l + cmplw r11,r12 + blt+ 2f /* addr below exception vectors */ + + lis r12, Debug@h + ori r12, r12, Debug@l + cmplw r11,r12 + bgt+ 2f /* addr above TLB exception vectors */ + + lis r11,DBSR_IC@h /* Remove the trap status */ + mtspr SPRN_DBSR,r11 + + mfspr r11,SPRN_CSRR1 + rlwinm r11,r11,0,23,21 /* clear MSR_DE */ + mtspr SPRN_CSRR1, r11 /* restore MSR at rcfi without DE */ + + mtcrf 0xff,r10 /* restore registers */ + mfspr r12,SPRN_SPRG4R + mfspr r11,SPRN_SPRG1 + mfspr r10,SPRN_SPRG0 + + sync + rfci /* return to the exception handler */ + b . /* prevent prefetch past rfci */ + +2: + mtcrf 0xff,r10 /* restore registers */ + mfspr r12,SPRN_SPRG4R + mfspr r11,SPRN_SPRG1 + mfspr r10,SPRN_SPRG0 + + CRIT_EXCEPTION_PROLOG + addi r3,r1,STACK_FRAME_OVERHEAD + li r7,CRIT_EXC; + li r9,MSR_KERNEL + FINISH_EXCEPTION(DebugException) +#endif + +/* + * Local functions + */ + /* + * Data TLB exceptions will bail out to this point + * if they can't resolve the lightweight TLB fault. + */ +data_access: + NORMAL_EXCEPTION_PROLOG + mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */ + stw r5,_ESR(r11) + mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */ + stw r4,_DEAR(r11) + addi r3,r1,STACK_FRAME_OVERHEAD + EXC_XFER_EE_LITE(0x0300, do_page_fault) + +/* + + * Both the instruction and data TLB miss get to this + * point to load the TLB. + * r10 - EA of fault + * r11 - available to use + * r12 - Pointer to the 64-bit PTE + * r13 - available to use + * r14 - available to use + * MMUCR - loaded with proper value when we get here + * Upon exit, we reload everything and RFI. + */ +finish_tlb_load: + /* + * We set execute, because we don't have the granularity to + * properly set this at the page level (Linux problem). + * If shared is set, we cause a zero PID->TID load. + * Many of these bits are software only. Bits we don't set + * here we (properly should) assume have the appropriate value. + */ + + /* Load the next available TLB index */ + lis r13, tlb_44x_index@h + ori r13, r13, tlb_44x_index@l + lwz r14, 0(r13) + /* Load the TLB high watermark */ + lis r13, tlb_44x_hwater@h + ori r13, r13, tlb_44x_hwater@l + lwz r11, 0(r13) + + + /* Increment, rollover, and store TLB index */ + addi r14, r14, 1 + cmpw 0, r14, r11 /* reserve entries 62-63 for kernel */ + ble 7f + li r14, 0 +7: + /* Load the next available TLB index */ + lis r13, tlb_44x_index@h + ori r13, r13, tlb_44x_index@l + stw r14, 0(r13) + +6: + lwz r13, 0(r12) /* Get MS word of PTE */ + lwz r11, 4(r12) /* Get LS word of PTE */ + rlwimi r13, r11, 0, 0 , 19 /* Insert RPN */ + tlbwe r13, r14, PPC44x_TLB_XLAT /* Write XLAT */ + + /* + * Create PAGEID. This is the faulting address plus + * a set of static bits. The static bits are page + * size and valid. Bits 20 and 21 should be zero + * for a page size of 4KB. + */ + li r12, 0x0210 /* Set size and valid */ + mfspr r13, SPRN_SRR1 /* Get SRR1 */ + andi. r13, r13, MSR_IS@l + beq 7f + ori r12, r12, PPC44x_TLB_TS@l /* Set TS=1 */ +7: rlwimi r10, r12, 0, 20, 31 /* Insert statics */ + tlbwe r10, r14, PPC44x_TLB_PAGEID /* Write PAGEID */ + + /* FIXME: Staticly setting some permissions */ + li r13, 0x002d /* Set UX,UR,SX,SR */ + andi. r11, r11, 0xffff /* Clear MS 16 bits */ + andi. r12, r11, 0x0002 /* _PAGE_HWWRITE? */ + beq 8f + ori r13, r13, 0x0002 /* Set SW */ + /* FIXME: Force attributes */ +8: ori r11, r11, 0x0100 /* Set G */ + /* FIXME: Already set in PTE */ + rlwimi r11, r13, 0, 26, 31 /* Insert static perms */ + + lis r13,0xffff + ori r13,r13,0x0fff /* Set U0-U3 mask */ + and r11,r11,r13 /* Clear U0-U3 */ + tlbwe r11, r14, PPC44x_TLB_ATTRIB /* Write ATTRIB */ + + /* Done...restore registers and get out of here. + */ + mfspr r11, SPRG7R + mtcr r11 + mfspr r14, SPRG6R + mfspr r13, SPRG5R + mfspr r12, SPRG4R + mfspr r11, SPRG1 + mfspr r10, SPRG0 + rfi /* Force context change */ + +/* + * Global functions + */ + +/* + * extern void giveup_altivec(struct task_struct *prev) + * + * The 44x core does not have an AltiVec unit. + */ +_GLOBAL(giveup_altivec) + blr + +/* + * extern void giveup_fpu(struct task_struct *prev) + * + * The 44x core does not have an FPU. + */ +_GLOBAL(giveup_fpu) + blr + +/* + * extern void abort(void) + * + * At present, this routine just applies a system reset. + */ +_GLOBAL(abort) + mfspr r13,SPRN_DBCR0 + oris r13,r13,DBCR_RST(DBCR_RST_SYSTEM)@h + mtspr SPRN_DBCR0,r13 + +_GLOBAL(set_context) + +#ifdef CONFIG_BDI_SWITCH + /* Context switch the PTE pointer for the Abatron BDI2000. + * The PGDIR is the second parameter. + */ + lis r5, abatron_pteptrs@h + ori r5, r5, abatron_pteptrs@l + stw r4, 0x4(r5) +#endif + mtspr SPRN_PID,r3 + isync /* Force context change */ + blr + +/* + * We put a few things here that have to be page-aligned. This stuff + * goes at the beginning of the data segment, which is page-aligned. + */ + .data +_GLOBAL(sdata) +_GLOBAL(empty_zero_page) + .space 4096 + +/* + * To support >32-bit physical addresses, we use an 8KB pgdir. + */ +_GLOBAL(swapper_pg_dir) + .space 8192 + +/* Stack for handling critical exceptions from kernel mode */ + .section .bss +critical_stack_bottom: + .space 4096 +critical_stack_top: + .previous + +/* + * This space gets a copy of optional info passed to us by the bootstrap + * which is used to pass parameters into the kernel like root=/dev/sda1, etc. + */ +_GLOBAL(cmd_line) + .space 512 + +/* + * Room for two PTE pointers, usually the kernel and current user pointers + * to their respective root page table. + */ +abatron_pteptrs: + .space 8 + +/* + * This area is used for temporarily saving registers during the + * critical exception prolog. + */ +crit_save: +_GLOBAL(crit_r10) + .space 4 +_GLOBAL(crit_r11) + .space 4 +_GLOBAL(crit_sprg0) + .space 4 +_GLOBAL(crit_sprg1) + .space 4 +_GLOBAL(crit_sprg4) + .space 4 +_GLOBAL(crit_sprg5) + .space 4 +_GLOBAL(crit_sprg6) + .space 4 +_GLOBAL(crit_sprg7) + .space 4 +_GLOBAL(crit_pid) + .space 4 +_GLOBAL(crit_srr0) + .space 4 +_GLOBAL(crit_srr1) + .space 4 diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index c076529683c9e..a41d10ee16142 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -405,16 +405,20 @@ _GLOBAL(_tlbia) sync /* Flush to memory before changing mapping */ tlbia isync /* Flush shadow TLB */ -#elif defined(CONFIG_440) +#elif defined(CONFIG_44x) lis r3,0 sync 1: - tlbwe r3,r3,PPC440_TLB_PAGEID + tlbwe r3,r3,PPC44x_TLB_PAGEID addi r3,r3,1 - cmpwi 0,r3,61 + /* Load high watermark */ + lis r4,tlb_44x_hwater@h + ori r4,r4,tlb_44x_hwater@l + lwz r5,0(r4) + cmpw 0,r3,r5 ble 1b isync -#else /* !(CONFIG_40x || CONFIG_440) */ +#else /* !(CONFIG_40x || CONFIG_44x) */ #if defined(CONFIG_SMP) rlwinm r8,r1,0,0,18 lwz r8,TI_CPU(r8) @@ -465,17 +469,17 @@ _GLOBAL(_tlbie) tlbwe r3, r3, TLB_TAG isync 10: -#elif defined(CONFIG_440) +#elif defined(CONFIG_44x) mfspr r4,SPRN_MMUCR /* Get MMUCR */ - lis r5,PPC440_MMUCR_STS@h - ori r5,r5,PPC440_MMUCR_TID@l /* Create mask */ + lis r5,PPC44x_MMUCR_STS@h + ori r5,r5,PPC44x_MMUCR_TID@l /* Create mask */ andc r4,r4,r5 /* Clear out TID/STS bits */ mfspr r5,SPRN_PID /* Get PID */ or r4,r4,r5 /* Set TID bits */ mfmsr r6 /* Get MSR */ andi. r6,r6,MSR_IS@l /* TS=1? */ beq 11f /* If not, leave STS=0 */ - oris r4,r4,PPC440_MMUCR_STS@h /* Set STS=1 */ + oris r4,r4,PPC44x_MMUCR_STS@h /* Set STS=1 */ 11: mtspr SPRN_MMUCR, r4 /* Put MMUCR */ tlbsx. r3, 0, r3 @@ -486,10 +490,10 @@ _GLOBAL(_tlbie) * the V bit in the TLB_PAGEID, loading this * value will invalidate the TLB entry. */ - tlbwe r3, r3, PPC440_TLB_PAGEID + tlbwe r3, r3, PPC44x_TLB_PAGEID isync 10: -#else /* !(CONFIG_40x || CONFIG_440) */ +#else /* !(CONFIG_40x || CONFIG_44x) */ #if defined(CONFIG_SMP) rlwinm r8,r1,0,0,18 lwz r8,TI_CPU(r8) @@ -658,9 +662,9 @@ _GLOBAL(invalidate_dcache_range) #ifdef CONFIG_NOT_COHERENT_CACHE /* * 40x cores have 8K or 16K dcache and 32 byte line size. - * 440 has a 32K dcache and 32 byte line size. + * 44x has a 32K dcache and 32 byte line size. * 8xx has 1, 2, 4, 8K variants. - * For now, cover the worst case of the 440. + * For now, cover the worst case of the 44x. * Must be called with external interrupts disabled. */ #define CACHE_NWAYS 64 diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index a70d77b33147d..d7daa458535f0 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -155,6 +155,9 @@ EXPORT_SYMBOL(_outsl_ns); EXPORT_SYMBOL(iopa); EXPORT_SYMBOL(mm_ptov); EXPORT_SYMBOL(ioremap); +#ifdef CONFIG_44x +EXPORT_SYMBOL(ioremap64); +#endif EXPORT_SYMBOL(__ioremap); EXPORT_SYMBOL(iounmap); EXPORT_SYMBOL(ioremap_bot); /* aka VMALLOC_END */ @@ -353,7 +356,7 @@ EXPORT_SYMBOL(debugger_fault_handler); EXPORT_SYMBOL(cpm_install_handler); EXPORT_SYMBOL(cpm_free_handler); #endif /* CONFIG_8xx */ -#if defined(CONFIG_8xx) || defined(CONFIG_40x) +#if defined(CONFIG_8xx) || defined(CONFIG_4xx) EXPORT_SYMBOL(__res); #endif #if defined(CONFIG_8xx) diff --git a/arch/ppc/mm/44x_mmu.c b/arch/ppc/mm/44x_mmu.c new file mode 100644 index 0000000000000..8c71ed6caca61 --- /dev/null +++ b/arch/ppc/mm/44x_mmu.c @@ -0,0 +1,162 @@ +/* + * Modifications by Matt Porter (mporter@mvista.com) to support + * PPC44x Book E processors. + * + * This file contains the routines for initializing the MMU + * on the 4xx series of chips. + * -- paulus + * + * Derived from arch/ppc/mm/init.c: + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) + * and Cort Dougan (PReP) (cort@cs.nmt.edu) + * Copyright (C) 1996 Paul Mackerras + * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * + * Derived from "arch/i386/mm/init.c" + * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mmu_decl.h" +#include "mem_pieces.h" + +extern char etext[], _stext[]; +extern struct mem_pieces phys_avail; + +/* Used by the 44x TLB replacement exception handler. + * Just needed it declared someplace. + */ +unsigned int tlb_44x_index = 0; +unsigned int tlb_44x_hwater = 61; + +/* + * "Pins" a 256MB TLB entry in AS0 for kernel lowmem + */ +static void __init +ppc44x_pin_tlb(int slot, unsigned int virt, unsigned int phys) +{ + unsigned long attrib; + + __asm__ __volatile__("\ + clrrwi %2,%2,10\n\ + ori %2,%2,%4\n\ + clrrwi %1,%1,10\n\ + li %0,0\n\ + ori %0,%0,%5\n\ + tlbwe %2,%3,%6\n\ + tlbwe %1,%3,%7\n\ + tlbwe %0,%3,%8" + : + : "r" (attrib), "r" (phys), "r" (virt), "r" (slot), + "i" (PPC44x_TLB_VALID | PPC44x_TLB_PAGESZ(PPC44x_PAGESZ_256M)), + "i" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G), + "i" (PPC44x_TLB_PAGEID), + "i" (PPC44x_TLB_XLAT), + "i" (PPC44x_TLB_ATTRIB)); +} + +/* + * Configure PPC44x TLB for AS0 exception processing. + */ +static void __init +ppc44x_tlb_config(void) +{ + unsigned int pinned_tlbs = 1; + int i; + + /* + * If lowmem is not on a pin tlb entry size boundary, + * then reserve the last page of system memory. This + * eliminates the possibility of a speculative dcache + * fetch past the end of system memory that would + * result in a machine check exception. + */ + if (total_lowmem | (PPC44x_PIN_SIZE - 1)) + mem_pieces_remove(&phys_avail, total_lowmem - PAGE_SIZE, PAGE_SIZE, 1); + + /* Determine number of entries necessary to cover lowmem */ + pinned_tlbs = (unsigned int) + (_ALIGN(total_lowmem, PPC44x_PIN_SIZE) >> PPC44x_PIN_SHIFT); + + /* Write upper watermark to save location */ + tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs; + + /* If necessary, set additional pinned TLBs */ + if (pinned_tlbs > 1) + for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) { + unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC44x_PIN_SIZE; + ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr); + } +} + +/* + * MMU_init_hw does the chip-specific initialization of the MMU hardware. + */ +void __init MMU_init_hw(void) +{ + flush_instruction_cache(); + + ppc44x_tlb_config(); +} + +/* TODO: Add large page lowmem mapping support */ +unsigned long __init mmu_mapin_ram(void) +{ + unsigned long v, s, f = _PAGE_GUARDED; + phys_addr_t p; + + v = KERNELBASE; + p = PPC_MEMSTART; + + for (s = 0; s < total_lowmem; s += PAGE_SIZE) { + if ((char *) v >= _stext && (char *) v < etext) + f |= _PAGE_RAM_TEXT; + else + f |= _PAGE_RAM; + map_page(v, p, f); + v += PAGE_SIZE; + p += PAGE_SIZE; + } + + if (ppc_md.progress) + ppc_md.progress("MMU:mmu_mapin_ram done", 0x401); + + return s; +} diff --git a/arch/ppc/mm/Makefile b/arch/ppc/mm/Makefile index 01d5f46c07641..0ed5eb8aad03a 100644 --- a/arch/ppc/mm/Makefile +++ b/arch/ppc/mm/Makefile @@ -11,4 +11,5 @@ obj-y := fault.o init.o mem_pieces.o extable.o \ obj-$(CONFIG_PPC_STD_MMU) += hashtable.o ppc_mmu.o tlb.o obj-$(CONFIG_40x) += 4xx_mmu.o +obj-$(CONFIG_44x) += 44x_mmu.o obj-$(CONFIG_NOT_COHERENT_CACHE) += cachemap.o diff --git a/arch/ppc/mm/cachemap.c b/arch/ppc/mm/cachemap.c index b8b9efa7fa5eb..e16f8f0cc47d8 100644 --- a/arch/ppc/mm/cachemap.c +++ b/arch/ppc/mm/cachemap.c @@ -48,7 +48,7 @@ #include #include -int map_page(unsigned long va, unsigned long pa, int flags); +int map_page(unsigned long va, phys_addr_t pa, int flags); /* This function will allocate the requested contiguous pages and * map them into the kernel's vmalloc() space. This is done so we @@ -61,7 +61,8 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) { int order, err; struct page *page, *free, *end; - unsigned long pa, flags, offset; + phys_addr_t pa; + unsigned long flags, offset; struct vm_struct *area = NULL; unsigned long va = 0; diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index e535c560fabbf..2d775dad695ff 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -6,6 +6,7 @@ * and Cort Dougan (PReP) (cort@cs.nmt.edu) * Copyright (C) 1996 Paul Mackerras * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). + * PPC44x/36-bit changes by Matt Porter (mporter@mvista.com) * * Derived from "arch/i386/mm/init.c" * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds diff --git a/arch/ppc/mm/mmu_decl.h b/arch/ppc/mm/mmu_decl.h index cd7389ea8e1e9..3099b7088d459 100644 --- a/arch/ppc/mm/mmu_decl.h +++ b/arch/ppc/mm/mmu_decl.h @@ -20,9 +20,10 @@ * */ #include +#include extern void mapin_ram(void); -extern int map_page(unsigned long va, unsigned long pa, int flags); +extern int map_page(unsigned long va, phys_addr_t pa, int flags); extern void setbat(int index, unsigned long virt, unsigned long phys, unsigned int size, int flags); extern void reserve_phys_mem(unsigned long start, unsigned long size); diff --git a/arch/ppc/mm/pgtable.c b/arch/ppc/mm/pgtable.c index 3768c66520cbe..de3d8224114d5 100644 --- a/arch/ppc/mm/pgtable.c +++ b/arch/ppc/mm/pgtable.c @@ -55,11 +55,18 @@ void setbat(int index, unsigned long virt, unsigned long phys, #define p_mapped_by_bats(x) (0UL) #endif /* HAVE_BATS */ +#ifdef CONFIG_44x +/* 44x uses an 8kB pgdir because it has 8-byte Linux PTEs. */ +#define PGDIR_ORDER 1 +#else +#define PGDIR_ORDER 0 +#endif + pgd_t *pgd_alloc(struct mm_struct *mm) { pgd_t *ret; - if ((ret = (pgd_t *)__get_free_page(GFP_KERNEL)) != NULL) + if ((ret = (pgd_t *)__get_free_pages(GFP_KERNEL, PGDIR_ORDER)) != NULL) clear_page(ret); return ret; } @@ -110,16 +117,33 @@ void pte_free(struct page *pte) __free_page(pte); } +#ifndef CONFIG_44x +void * +ioremap(phys_addr_t addr, unsigned long size) +{ + return __ioremap(addr, size, _PAGE_NO_CACHE); +} +#else /* CONFIG_44x */ void * -ioremap(unsigned long addr, unsigned long size) +ioremap64(unsigned long long addr, unsigned long size) { return __ioremap(addr, size, _PAGE_NO_CACHE); } void * -__ioremap(unsigned long addr, unsigned long size, unsigned long flags) +ioremap(phys_addr_t addr, unsigned long size) +{ + phys_addr_t addr64 = fixup_bigphys_addr(addr, size);; + + return ioremap64(addr64, size); +} +#endif /* CONFIG_44x */ + +void * +__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags) { - unsigned long p, v, i; + unsigned long v, i; + phys_addr_t p; int err; /* @@ -144,7 +168,7 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags) */ if ( mem_init_done && (p < virt_to_phys(high_memory)) ) { - printk("__ioremap(): phys addr %0lx is RAM lr %p\n", p, + printk("__ioremap(): phys addr "PTE_FMT" is RAM lr %p\n", p, __builtin_return_address(0)); return NULL; } @@ -195,7 +219,7 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags) } out: - return (void *) (v + (addr & ~PAGE_MASK)); + return (void *) (v + ((unsigned long)addr & ~PAGE_MASK)); } void iounmap(void *addr) @@ -211,7 +235,7 @@ void iounmap(void *addr) } int -map_page(unsigned long va, unsigned long pa, int flags) +map_page(unsigned long va, phys_addr_t pa, int flags) { pmd_t *pd; pte_t *pg; @@ -261,7 +285,7 @@ void __init mapin_ram(void) * virt, phys, size must all be page-aligned. * This should only be called before ioremap is called. */ -void __init io_block_mapping(unsigned long virt, unsigned long phys, +void __init io_block_mapping(unsigned long virt, phys_addr_t phys, unsigned int size, int flags) { int i; diff --git a/arch/ppc/platforms/4xx/Kconfig b/arch/ppc/platforms/4xx/Kconfig index 759a88325c4a5..9cc0b4fc95280 100644 --- a/arch/ppc/platforms/4xx/Kconfig +++ b/arch/ppc/platforms/4xx/Kconfig @@ -1,6 +1,6 @@ config 4xx bool - depends on 40x + depends on 40x || 44x default y menu "IBM 4xx options" @@ -57,6 +57,23 @@ config WALNUT endchoice +choice + prompt "Machine Type" + depends on 44x + default EBONY + +config EBONY + bool "Ebony" + help + This option enables support for the IBM PPC440GP evaluation board. + +config OCOTEA + bool "Ocotea" + help + This option enables support for the IBM PPC440GX evaluation board. + +endchoice + config EP405PC bool "EP405PC Support" depends on EP405 @@ -70,6 +87,26 @@ config NP405H depends on ASH default y +config 440GP + bool + depends on EBONY + default y + +config 440GX + bool + depends on OCOTEA + default y + +config 440 + bool + depends on 440GP + default y + +config 440A + bool + depends on 440GX + default y + # All 405-based cores up until the 405GPR and 405EP have this errata. config IBM405_ERR77 bool @@ -82,9 +119,25 @@ config IBM405_ERR51 depends on 40x && !405GPR default y + +config PIN_TLB + bool + depends on 44x + default y + +config BOOKE + bool + depends on 44x + default y + config IBM_OCP bool - depends on ASH || BEECH || CEDAR || CPCI405 || EP405 || REDWOOD_4 || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT + depends on ASH || BEECH || CEDAR || CPCI405 || EBONY || EP405 || OCOTEA || REDWOOD_4 || REDWOOD_5 || REDWOOD_6 || SYCAMORE || WALNUT + default y + +config IBM_EMAC4 + bool + depends on 440GX default y config NP405L diff --git a/arch/ppc/platforms/4xx/Makefile b/arch/ppc/platforms/4xx/Makefile index e7233f9bd9ea2..5ea683316b614 100644 --- a/arch/ppc/platforms/4xx/Makefile +++ b/arch/ppc/platforms/4xx/Makefile @@ -5,8 +5,10 @@ obj-$(CONFIG_ASH) += ash.o obj-$(CONFIG_BEECH) += beech.o obj-$(CONFIG_CEDAR) += cedar.o obj-$(CONFIG_CPCI405) += cpci405.o +obj-$(CONFIG_EBONY) += ebony.o obj-$(CONFIG_EP405) += ep405.o obj-$(CONFIG_OAK) += oak.o +obj-$(CONFIG_OCOTEA) += ocotea.o obj-$(CONFIG_REDWOOD_4) += redwood.o obj-$(CONFIG_REDWOOD_5) += redwood5.o obj-$(CONFIG_REDWOOD_6) += redwood6.o @@ -21,4 +23,6 @@ obj-$(CONFIG_NP405H) += ibmnp405h.o obj-$(CONFIG_REDWOOD_6) += ibmstbx25.o obj-$(CONFIG_NP4GS3) += ibmnp4gs.o obj-$(CONFIG_405LP) += ibm405lp.o +obj-$(CONFIG_EBONY) += ibm440gp.o +obj-$(CONFIG_OCOTEA) += ibm440gx.o obj-$(CONFIG_405GPR) += ibm405gpr.o diff --git a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c new file mode 100644 index 0000000000000..e2577b8f7c63b --- /dev/null +++ b/arch/ppc/platforms/4xx/ebony.c @@ -0,0 +1,536 @@ +/* + * arch/ppc/platforms/ebony.c + * + * Ebony board specific routines + * + * Matt Porter + * + * Copyright 2002 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Ebony IRQ triggering/polarity settings + */ +static u_char ebony_IRQ_initsenses[] __initdata = { + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 0: UART 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 1: UART 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 2: IIC 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 3: IIC 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 4: PCI Inb Mess */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 5: PCI Cmd Wrt */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 6: PCI PM */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 7: PCI MSI 0 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 8: PCI MSI 1 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 9: PCI MSI 2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 10: MAL TX EOB */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 11: MAL RX EOB */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 12: DMA Chan 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 13: DMA Chan 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 14: DMA Chan 2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 15: DMA Chan 3 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 16: Reserved */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 17: Reserved */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 18: GPT Timer 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 19: GPT Timer 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 20: GPT Timer 2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 21: GPT Timer 3 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 22: GPT Timer 4 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 23: Ext Int 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 24: Ext Int 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 25: Ext Int 2 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 26: Ext Int 3 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 27: Ext Int 4 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE), /* 28: Ext Int 5 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 29: Ext Int 6 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 30: UIC1 NC Int */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 31: UIC1 Crit Int */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 32: MAL SERR */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 33: MAL TXDE */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 34: MAL RXDE */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 35: ECC Unc Err */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 36: ECC Corr Err */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 37: Ext Bus Ctrl */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 38: Ext Bus Mstr */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 39: OPB->PLB */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 40: PCI MSI 3 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 41: PCI MSI 4 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 42: PCI MSI 5 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 43: PCI MSI 6 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 44: PCI MSI 7 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 45: PCI MSI 8 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 46: PCI MSI 9 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 47: PCI MSI 10 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 48: PCI MSI 11 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 49: PLB Perf Mon */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 50: Ext Int 7 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 51: Ext Int 8 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 52: Ext Int 9 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 53: Ext Int 10 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 54: Ext Int 11 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 55: Ext Int 12 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 56: Ser ROM Err */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 57: Reserved */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 58: Reserved */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 59: PCI Async Err */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 60: EMAC 0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 61: EMAC 0 WOL */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 62: EMAC 1 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 63: EMAC 1 WOL */ +}; + +extern void abort(void); + +/* Global Variables */ +bd_t __res; + +static void __init +ebony_calibrate_decr(void) +{ + unsigned int freq; + + /* + * Determine system clock speed + * + * If we are on Rev. B silicon, then use + * default external system clock. If we are + * on Rev. C silicon then errata forces us to + * use the internal clock. + */ + switch (PVR_REV(mfspr(PVR))) { + case PVR_REV(PVR_440GP_RB): + freq = EBONY_440GP_RB_SYSCLK; + break; + case PVR_REV(PVR_440GP_RC1): + default: + freq = EBONY_440GP_RC_SYSCLK; + break; + } + + tb_ticks_per_jiffy = freq / HZ; + tb_to_us = mulhwu_scale_factor(freq, 1000000); + + /* Set the time base to zero */ + mtspr(SPRN_TBWL, 0); + mtspr(SPRN_TBWU, 0); + + /* Clear any pending timer interrupts */ + mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); + + /* Enable decrementer interrupt */ + mtspr(SPRN_TCR, TCR_DIE); +} + +static int +ebony_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "vendor\t\t: IBM\n"); + seq_printf(m, "machine\t\t: Ebony\n"); + + return 0; +} + +static inline int +ebony_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 23, 23, 23, 23 }, /* IDSEL 1 - PCI Slot 0 */ + { 24, 24, 24, 24 }, /* IDSEL 2 - PCI Slot 1 */ + { 25, 25, 25, 25 }, /* IDSEL 3 - PCI Slot 2 */ + { 26, 26, 26, 26 }, /* IDSEL 4 - PCI Slot 3 */ + }; + + const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +#define PCIX_WRITEL(value, offset) \ + (writel(value, (u32)pcix_reg_base+offset)) + +/* + * FIXME: This is only here to "make it work". This will move + * to a ibm_pcix.c which will contain a generic IBM PCIX bridge + * configuration library. -Matt + */ +static void __init +ebony_setup_pcix(void) +{ + void *pcix_reg_base; + + pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX0_REG_SIZE); + + /* Disable all windows */ + PCIX_WRITEL(0, PCIX0_POM0SA); + PCIX_WRITEL(0, PCIX0_POM1SA); + PCIX_WRITEL(0, PCIX0_POM2SA); + PCIX_WRITEL(0, PCIX0_PIM0SA); + PCIX_WRITEL(0, PCIX0_PIM1SA); + PCIX_WRITEL(0, PCIX0_PIM2SA); + + /* Setup 2GB PLB->PCI outbound mem window (3_8000_0000->0_8000_0000) */ + PCIX_WRITEL(0x00000003, PCIX0_POM0LAH); + PCIX_WRITEL(0x80000000, PCIX0_POM0LAL); + PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH); + PCIX_WRITEL(0x80000000, PCIX0_POM0PCIAL); + PCIX_WRITEL(0x80000001, PCIX0_POM0SA); + + /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */ + PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH); + PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL); + PCIX_WRITEL(0x80000007, PCIX0_PIM0SA); + + eieio(); +} + +static void __init +ebony_setup_hose(void) +{ + struct pci_controller *hose; + + /* Configure windows on the PCI-X host bridge */ + ebony_setup_pcix(); + + hose = pcibios_alloc_controller(); + + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + hose->pci_mem_offset = EBONY_PCI_MEM_OFFSET; + + pci_init_resource(&hose->io_resource, + EBONY_PCI_LOWER_IO, + EBONY_PCI_UPPER_IO, + IORESOURCE_IO, + "PCI host bridge"); + + pci_init_resource(&hose->mem_resources[0], + EBONY_PCI_LOWER_MEM, + EBONY_PCI_UPPER_MEM, + IORESOURCE_MEM, + "PCI host bridge"); + + hose->io_space.start = EBONY_PCI_LOWER_IO; + hose->io_space.end = EBONY_PCI_UPPER_IO; + hose->mem_space.start = EBONY_PCI_LOWER_MEM; + hose->mem_space.end = EBONY_PCI_UPPER_MEM; + isa_io_base = + (unsigned long)ioremap64(EBONY_PCI_IO_BASE, EBONY_PCI_IO_SIZE); + hose->io_base_virt = (void *)isa_io_base; + + setup_indirect_pci(hose, + EBONY_PCI_CFGA_PLB32, + EBONY_PCI_CFGD_PLB32); + hose->set_cfg_type = 1; + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = ebony_map_irq; +} + +TODC_ALLOC(); + +static void __init +ebony_early_serial_map(void) +{ + struct uart_port port; + + /* Setup ioremapped serial port access */ + memset(&port, 0, sizeof(port)); + port.membase = ioremap64(PPC440GP_UART0_ADDR, 8); + port.irq = 0; + port.uartclk = BASE_BAUD * 16; + port.regshift = 0; + port.iotype = SERIAL_IO_MEM; + port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + port.line = 0; + + if (early_serial_setup(&port) != 0) { + printk("Early serial init of port 0 failed\n"); + } + + port.membase = ioremap64(PPC440GP_UART1_ADDR, 8); + port.irq = 1; + port.line = 1; + + if (early_serial_setup(&port) != 0) { + printk("Early serial init of port 1 failed\n"); + } +} + +static void __init +ebony_setup_arch(void) +{ + unsigned char * vpd_base; + struct ibm440gp_clocks clocks; + +#if !defined(CONFIG_BDI_SWITCH) + /* + * The Abatron BDI JTAG debugger does not tolerate others + * mucking with the debug registers. + */ + mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM)); +#endif + + /* Retrieve MAC addresses */ + vpd_base = ioremap64(EBONY_VPD_BASE, EBONY_VPD_SIZE); + memcpy(__res.bi_enetaddr[0],EBONY_NA0_ADDR(vpd_base),6); + memcpy(__res.bi_enetaddr[1],EBONY_NA1_ADDR(vpd_base),6); + + /* + * Determine various clocks. + * To be completely correct we should get SysClk + * from FPGA, because it can be changed by on-board switches + * --ebs + */ + ibm440gp_get_clocks(&clocks, 33333333, 6 * 1843200); + __res.bi_opb_busfreq = clocks.opb; + + /* Use IIC in standard (100 kHz) mode */ + __res.bi_iic_fast[0] = __res.bi_iic_fast[1] = 0; + + /* Setup TODC access */ + TODC_INIT(TODC_TYPE_DS1743, + 0, + 0, + ioremap64(EBONY_RTC_ADDR, EBONY_RTC_SIZE), + 8); + + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + + /* Setup PCI host bridge */ + ebony_setup_hose(); + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = Root_RAM0; + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = Root_NFS; +#else + ROOT_DEV = Root_HDA1; +#endif + +#ifdef CONFIG_VT + conswitchp = &dummy_con; +#endif + + ebony_early_serial_map(); + + ibm4xxPIC_InitSenses = ebony_IRQ_initsenses; + ibm4xxPIC_NumInitSenses = sizeof(ebony_IRQ_initsenses); + + /* Identify the system */ + printk("IBM Ebony port (MontaVista Software, Inc. (source@mvista.com))\n"); +} + +static void +ebony_restart(char *cmd) +{ + local_irq_disable(); + abort(); +} + +static void +ebony_power_off(void) +{ + local_irq_disable(); + for(;;); +} + +static void +ebony_halt(void) +{ + local_irq_disable(); + for(;;); +} + +/* + * Read the 440GP memory controller to get size of system memory. + */ +static unsigned long __init +ebony_find_end_of_memory(void) +{ + u32 i, bank_config; + u32 mem_size = 0; + + for (i=0; i<4; i++) + { + switch (i) + { + case 0: + mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B0CR); + break; + case 1: + mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B1CR); + break; + case 2: + mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B2CR); + break; + case 3: + mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B3CR); + break; + } + + bank_config = mfdcr(DCRN_SDRAM0_CFGDATA); + + if (!(bank_config & SDRAM_CONFIG_BANK_ENABLE)) + continue; + switch (SDRAM_CONFIG_BANK_SIZE(bank_config)) + { + case SDRAM_CONFIG_SIZE_8M: + mem_size += PPC44x_MEM_SIZE_8M; + break; + case SDRAM_CONFIG_SIZE_16M: + mem_size += PPC44x_MEM_SIZE_16M; + break; + case SDRAM_CONFIG_SIZE_32M: + mem_size += PPC44x_MEM_SIZE_32M; + break; + case SDRAM_CONFIG_SIZE_64M: + mem_size += PPC44x_MEM_SIZE_64M; + break; + case SDRAM_CONFIG_SIZE_128M: + mem_size += PPC44x_MEM_SIZE_128M; + break; + case SDRAM_CONFIG_SIZE_256M: + mem_size += PPC44x_MEM_SIZE_256M; + break; + case SDRAM_CONFIG_SIZE_512M: + mem_size += PPC44x_MEM_SIZE_512M; + break; + } + } + return mem_size; +} + +static void __init +ebony_init_irq(void) +{ + int i; + + ppc4xx_pic_init(); + + for (i = 0; i < NR_IRQS; i++) + irq_desc[i].handler = ppc4xx_pic; +} + +#ifdef CONFIG_SERIAL_TEXT_DEBUG +#include +#include +#include + +static struct serial_state rs_table[RS_TABLE_SIZE] = { + SERIAL_PORT_DFNS /* Defined in */ +}; + +static void +ebony_progress(char *s, unsigned short hex) +{ + volatile char c; + volatile unsigned long com_port; + u16 shift; + + com_port = (unsigned long)rs_table[0].iomem_base; + shift = rs_table[0].iomem_reg_shift; + + while ((c = *s++) != 0) { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = c; + + } + + /* Send LF/CR to pretty up output */ + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\r'; + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\n'; +} +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + +void __init platform_init(unsigned long r3, unsigned long r4, + unsigned long r5, unsigned long r6, unsigned long r7) +{ + parse_bootinfo((struct bi_record *) (r3 + KERNELBASE)); + + ppc_md.setup_arch = ebony_setup_arch; + ppc_md.show_cpuinfo = ebony_show_cpuinfo; + ppc_md.init_IRQ = ebony_init_irq; + ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */ + + ppc_md.find_end_of_memory = ebony_find_end_of_memory; + + ppc_md.restart = ebony_restart; + ppc_md.power_off = ebony_power_off; + ppc_md.halt = ebony_halt; + + ppc_md.calibrate_decr = ebony_calibrate_decr; + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + + ppc_md.nvram_read_val = todc_direct_read_val; + ppc_md.nvram_write_val = todc_direct_write_val; + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ppc_md.progress = ebony_progress; +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ +#ifdef CONFIG_KGDB + ppc_md.early_serial_map = ebony_early_serial_map; +#endif +} + diff --git a/arch/ppc/platforms/4xx/ebony.h b/arch/ppc/platforms/4xx/ebony.h new file mode 100755 index 0000000000000..c852552f167ee --- /dev/null +++ b/arch/ppc/platforms/4xx/ebony.h @@ -0,0 +1,96 @@ +/* + * arch/ppc/platforms/ebony.h + * + * Ebony board definitions + * + * Matt Porter + * + * Copyright 2002 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifdef __KERNEL__ +#ifndef __ASM_EBONY_H__ +#define __ASM_EBONY_H__ + +#include +#include + +/* F/W TLB mapping used in bootloader glue to reset EMAC */ +#define PPC44x_EMAC0_MR0 0xE0000800 + +/* Macros to get at Ebony VPD info */ +#define EBONY_VPD_BASE 0x00000001fffffe00ULL +#define EBONY_VPD_SIZE 0x24 +#define EBONY_NA0_OFFSET 0x0c +#define EBONY_NA1_OFFSET 0x18 +#define EBONY_NA0_ADDR(base) (base + EBONY_NA0_OFFSET) +#define EBONY_NA1_ADDR(base) (base + EBONY_NA1_OFFSET) + +/* Default clock rates for Rev. B and Rev. C silicon */ +#define EBONY_440GP_RB_SYSCLK 33000000 +#define EBONY_440GP_RC_SYSCLK 400000000 + +/* RTC/NVRAM location */ +#define EBONY_RTC_ADDR 0x0000000148000000ULL +#define EBONY_RTC_SIZE 0x2000 + +/* Flash */ +#define EBONY_FPGA_ADDR 0x0000000148300000 +#define EBONY_BOOT_SMALL_FLASH(x) (x & 0x20) +#define EBONY_ONBRD_FLASH_EN(x) (x & 0x02) +#define EBONY_FLASH_SEL(x) (x & 0x01) +#define EBONY_SMALL_FLASH_LOW1 0x00000001ff800000 +#define EBONY_SMALL_FLASH_LOW2 0x00000001ff880000 +#define EBONY_SMALL_FLASH_HIGH1 0x00000001fff00000 +#define EBONY_SMALL_FLASH_HIGH2 0x00000001fff80000 +#define EBONY_SMALL_FLASH_SIZE 0x80000 +#define EBONY_LARGE_FLASH_LOW 0x00000001ff800000 +#define EBONY_LARGE_FLASH_HIGH 0x00000001ffc00000 +#define EBONY_LARGE_FLASH_SIZE 0x400000 + +#define EBONY_SMALL_FLASH_BASE 0x00000001fff80000 +#define EBONY_LARGE_FLASH_BASE 0x00000001ff800000 + +/* + * Serial port defines + */ + +/* OpenBIOS defined UART mappings, used before early_serial_setup */ +#define UART0_IO_BASE (u8 *) 0xE0000200 +#define UART1_IO_BASE (u8 *) 0xE0000300 + +#define BASE_BAUD 33000000/3/16 +#define UART0_INT 0 +#define UART1_INT 1 + +#define STD_UART_OP(num) \ + { 0, BASE_BAUD, 0, UART##num##_INT, \ + (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ + iomem_base: UART##num##_IO_BASE, \ + io_type: SERIAL_IO_MEM}, + +#define SERIAL_PORT_DFNS \ + STD_UART_OP(0) \ + STD_UART_OP(1) + +/* PCI support */ +#define EBONY_PCI_LOWER_IO 0x00000000 +#define EBONY_PCI_UPPER_IO 0x0000ffff +#define EBONY_PCI_LOWER_MEM 0x80002000 +#define EBONY_PCI_UPPER_MEM 0xffffefff + +#define EBONY_PCI_CFGREGS_BASE 0x000000020ec00000 +#define EBONY_PCI_CFGA_PLB32 0x0ec00000 +#define EBONY_PCI_CFGD_PLB32 0x0ec00004 + +#define EBONY_PCI_IO_BASE 0x0000000208000000ULL +#define EBONY_PCI_IO_SIZE 0x00010000 +#define EBONY_PCI_MEM_OFFSET 0x00000000 + +#endif /* __ASM_EBONY_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/4xx/ibm440gp.c b/arch/ppc/platforms/4xx/ibm440gp.c new file mode 100644 index 0000000000000..7bdd7455afcdf --- /dev/null +++ b/arch/ppc/platforms/4xx/ibm440gp.c @@ -0,0 +1,31 @@ +/* + * arch/ppc/platforms/4xx/ibm440gp.c + * + * PPC440GP I/O descriptions + * + * Matt Porter + * + * Copyright 2002 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include +#include +#include + +struct ocp_def core_ocp[] __initdata = { + {OCP_VENDOR_IBM, OCP_FUNC_OPB, PPC440GP_OPB_BASE_START, OCP_IRQ_NA, OCP_CPM_NA}, + {OCP_VENDOR_IBM, OCP_FUNC_16550, PPC440GP_UART0_ADDR, UART0_INT, IBM_CPM_UART0}, + {OCP_VENDOR_IBM, OCP_FUNC_16550, PPC440GP_UART1_ADDR, UART1_INT, IBM_CPM_UART1}, + {OCP_VENDOR_IBM, OCP_FUNC_IIC, PPC440GP_IIC0_ADDR, IIC0_IRQ, IBM_CPM_IIC0}, + {OCP_VENDOR_IBM, OCP_FUNC_IIC, PPC440GP_IIC1_ADDR, IIC1_IRQ, IBM_CPM_IIC1}, + {OCP_VENDOR_IBM, OCP_FUNC_GPIO, PPC440GP_GPIO0_ADDR, OCP_IRQ_NA, IBM_CPM_GPIO0}, + {OCP_VENDOR_IBM, OCP_FUNC_EMAC, PPC440GP_EMAC0_ADDR, BL_MAC_ETH0, OCP_CPM_NA}, + {OCP_VENDOR_IBM, OCP_FUNC_EMAC, PPC440GP_EMAC1_ADDR, BL_MAC_ETH1, OCP_CPM_NA}, + {OCP_VENDOR_IBM, OCP_FUNC_ZMII, PPC440GP_ZMII_ADDR, OCP_IRQ_NA, OCP_CPM_NA}, + {OCP_VENDOR_INVALID, OCP_FUNC_INVALID, 0x0, OCP_IRQ_NA, OCP_CPM_NA}, +}; diff --git a/arch/ppc/platforms/4xx/ibm440gp.h b/arch/ppc/platforms/4xx/ibm440gp.h new file mode 100644 index 0000000000000..b8c1a4fb66e71 --- /dev/null +++ b/arch/ppc/platforms/4xx/ibm440gp.h @@ -0,0 +1,102 @@ +/* + * arch/ppc/platforms/4xx/ibm440gp.h + * + * PPC440GP definitions + * + * Roland Dreier + * + * Copyright 2002 Roland Dreier + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This file contains code that was originally in the files ibm44x.h + * and ebony.h, which were written by Matt Porter of MontaVista Software Inc. + */ + +#ifdef __KERNEL__ +#ifndef __PPC_PLATFORMS_IBM440GP_H +#define __PPC_PLATFORMS_IBM440GP_H + +#include + +#define EMAC_NUMS 2 +#define UART_NUMS 2 +#define ZMII_NUMS 1 +#define IIC_NUMS 2 +#define IIC0_IRQ 2 +#define IIC1_IRQ 3 +#define GPIO_NUMS 1 + +/* UART location */ +#define PPC440GP_UART0_ADDR 0x0000000140000200ULL +#define PPC440GP_UART1_ADDR 0x0000000140000300ULL + +/* EMAC location */ +#define PPC440GP_EMAC0_ADDR 0x0000000140000800ULL +#define PPC440GP_EMAC1_ADDR 0x0000000140000900ULL +#define PPC440GP_EMAC_SIZE 0x70 + +/* EMAC IRQ's */ +#define BL_MAC_WOL 61 /* WOL */ +#define BL_MAC_WOL1 63 /* WOL */ +#define BL_MAL_SERR 32 /* MAL SERR */ +#define BL_MAL_TXDE 33 /* MAL TXDE */ +#define BL_MAL_RXDE 34 /* MAL RXDE */ +#define BL_MAL_TXEOB 10 /* MAL TX EOB */ +#define BL_MAL_RXEOB 11 /* MAL RX EOB */ +#define BL_MAC_ETH0 60 /* MAC */ +#define BL_MAC_ETH1 62 /* MAC */ + +/* ZMII location */ +#define PPC440GP_ZMII_ADDR 0x0000000140000780ULL +#define PPC440GP_ZMII_SIZE 0x0c + +/* I2C location */ +#define PPC440GP_IIC0_ADDR 0x40000400 +#define PPC440GP_IIC1_ADDR 0x40000500 + +/* GPIO location */ +#define PPC440GP_GPIO0_ADDR 0x0000000140000700ULL + +/* Clock and Power Management */ +#define IBM_CPM_IIC0 0x80000000 /* IIC interface */ +#define IBM_CPM_IIC1 0x40000000 /* IIC interface */ +#define IBM_CPM_PCI 0x20000000 /* PCI bridge */ +#define IBM_CPM_CPU 0x02000000 /* processor core */ +#define IBM_CPM_DMA 0x01000000 /* DMA controller */ +#define IBM_CPM_BGO 0x00800000 /* PLB to OPB bus arbiter */ +#define IBM_CPM_BGI 0x00400000 /* OPB to PLB bridge */ +#define IBM_CPM_EBC 0x00200000 /* External Bux Controller */ +#define IBM_CPM_EBM 0x00100000 /* Ext Bus Master Interface */ +#define IBM_CPM_DMC 0x00080000 /* SDRAM peripheral controller */ +#define IBM_CPM_PLB 0x00040000 /* PLB bus arbiter */ +#define IBM_CPM_SRAM 0x00020000 /* SRAM memory controller */ +#define IBM_CPM_PPM 0x00002000 /* PLB Performance Monitor */ +#define IBM_CPM_UIC1 0x00001000 /* Universal Interrupt Controller */ +#define IBM_CPM_GPIO0 0x00000800 /* General Purpose IO (??) */ +#define IBM_CPM_GPT 0x00000400 /* General Purpose Timers */ +#define IBM_CPM_UART0 0x00000200 /* serial port 0 */ +#define IBM_CPM_UART1 0x00000100 /* serial port 1 */ +#define IBM_CPM_UIC0 0x00000080 /* Universal Interrupt Controller */ +#define IBM_CPM_TMRCLK 0x00000040 /* CPU timers */ + +#define DFLT_IBM4xx_PM ~(IBM_CPM_UIC | IBM_CPM_UIC1 | IBM_CPM_CPU \ + | IBM_CPM_EBC | IBM_CPM_SRAM | IBM_CPM_BGO \ + | IBM_CPM_EBM | IBM_CPM_PLB | IBM_CPM_OPB \ + | IBM_CPM_TMRCLK | IBM_CPM_DMA | IBM_CPM_PCI) + +#define PPC440GP_OPB_BASE_START 0x0000000140000000ULL + +/* + * Serial port defines + */ +#define RS_TABLE_SIZE 2 + +#include +#include + +#endif /* __PPC_PLATFORMS_IBM440GP_H */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/4xx/ibm440gx.c b/arch/ppc/platforms/4xx/ibm440gx.c new file mode 100644 index 0000000000000..42677b8b1ecf9 --- /dev/null +++ b/arch/ppc/platforms/4xx/ibm440gx.c @@ -0,0 +1,37 @@ +/* + * arch/ppc/platforms/ibm440gx.c + * + * PPC440GX I/O descriptions + * + * Matt Porter + * + * Copyright 2002-2003 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct ocp_def core_ocp[] __initdata = { + {OCP_VENDOR_IBM, OCP_FUNC_OPB, PPC440GX_OPB_BASE_START, OCP_IRQ_NA, OCP_CPM_NA}, + {OCP_VENDOR_IBM, OCP_FUNC_16550, PPC440GX_UART0_ADDR, UART0_IRQ, IBM_CPM_UART0}, + {OCP_VENDOR_IBM, OCP_FUNC_16550, PPC440GX_UART1_ADDR, UART1_IRQ, IBM_CPM_UART1}, + {OCP_VENDOR_IBM, OCP_FUNC_IIC, PPC440GX_IIC0_ADDR, IIC0_IRQ, IBM_CPM_IIC0}, + {OCP_VENDOR_IBM, OCP_FUNC_IIC, PPC440GX_IIC1_ADDR, IIC1_IRQ, IBM_CPM_IIC1}, + {OCP_VENDOR_IBM, OCP_FUNC_GPIO, PPC440GX_GPIO0_ADDR, OCP_IRQ_NA, IBM_CPM_GPIO0}, + {OCP_VENDOR_IBM, OCP_FUNC_EMAC, PPC440GX_EMAC0_ADDR, BL_MAC_ETH0, OCP_CPM_NA}, + {OCP_VENDOR_IBM, OCP_FUNC_EMAC, PPC440GX_EMAC1_ADDR, BL_MAC_ETH1, OCP_CPM_NA}, + {OCP_VENDOR_IBM, OCP_FUNC_ZMII, PPC440GX_ZMII_ADDR, OCP_IRQ_NA, OCP_CPM_NA}, + {OCP_VENDOR_INVALID, OCP_FUNC_INVALID, 0x0, OCP_IRQ_NA, OCP_CPM_NA}, +}; diff --git a/arch/ppc/platforms/4xx/ibm440gx.h b/arch/ppc/platforms/4xx/ibm440gx.h new file mode 100644 index 0000000000000..7299b4c42319e --- /dev/null +++ b/arch/ppc/platforms/4xx/ibm440gx.h @@ -0,0 +1,123 @@ +/* + * arch/ppc/platforms/ibm440gx.h + * + * PPC440GX definitions + * + * Matt Porter + * + * Copyright 2002 Roland Dreier + * Copyright 2003 MontaVista Software, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifdef __KERNEL__ +#ifndef __PPC_PLATFORMS_IBM440GX_H +#define __PPC_PLATFORMS_IBM440GX_H + +#include + +#include + +/* UART */ +#define PPC440GX_UART0_ADDR 0x0000000140000200ULL +#define PPC440GX_UART1_ADDR 0x0000000140000300ULL +#define UART0_IRQ 0 +#define UART1_IRQ 1 + +/* EMAC */ +#define PPC440GX_EMAC0_ADDR 0x0000000140000800ULL +#define PPC440GX_EMAC1_ADDR 0x0000000140000900ULL +#define PPC440GX_EMAC2_ADDR 0x0000000140000C00ULL +#define PPC440GX_EMAC3_ADDR 0x0000000140000E00ULL +#define PPC440GX_EMAC_SIZE 0xFC +#define EMAC_NUMS 2 +#define BL_MAC_WOL 61 /* WOL */ +#define BL_MAC_WOL1 63 /* WOL */ +#define BL_MAC_WOL2 65 /* WOL */ +#define BL_MAC_WOL3 67 /* WOL */ +#define BL_MAL_SERR 32 /* MAL SERR */ +#define BL_MAL_TXDE 33 /* MAL TXDE */ +#define BL_MAL_RXDE 34 /* MAL RXDE */ +#define BL_MAL_TXEOB 10 /* MAL TX EOB */ +#define BL_MAL_RXEOB 11 /* MAL RX EOB */ +#define BL_MAC_ETH0 60 /* MAC */ +#define BL_MAC_ETH1 62 /* MAC */ +#define BL_MAC_ETH2 64 /* MAC */ +#define BL_MAC_ETH3 66 /* MAC */ +#define BL_TAH0 68 /* TAH 0 */ +#define BL_TAH1 69 /* TAH 1 */ + +/* TAH */ +#define PPC440GX_TAH0_ADDR 0x0000000140000B00ULL +#define PPC440GX_TAH1_ADDR 0x0000000140000D00ULL +#define PPC440GX_TAH_SIZE 0xFC + +/* ZMII */ +#define PPC440GX_ZMII_ADDR 0x0000000140000780ULL +#define PPC440GX_ZMII_SIZE 0x0c + +/* RGMII */ +#define PPC440GX_RGMII_ADDR 0x0000000140000790ULL +#define PPC440GX_RGMII_SIZE 0x0c + +/* IIC */ +#define PPC440GX_IIC0_ADDR 0x40000400 +#define PPC440GX_IIC1_ADDR 0x40000500 +#define IIC0_IRQ 2 +#define IIC1_IRQ 3 + +/* GPIO */ +#define PPC440GX_GPIO0_ADDR 0x0000000140000700ULL + +/* Clock and Power Management */ +#define IBM_CPM_IIC0 0x80000000 /* IIC interface */ +#define IBM_CPM_IIC1 0x40000000 /* IIC interface */ +#define IBM_CPM_PCI 0x20000000 /* PCI bridge */ +#define IBM_CPM_RGMII 0x10000000 /* RGMII */ +#define IBM_CPM_TAHOE0 0x08000000 /* TAHOE 0 */ +#define IBM_CPM_TAHOE1 0x04000000 /* TAHOE 1 */ +#define IBM_CPM_CPU 0x02000000 /* processor core */ +#define IBM_CPM_DMA 0x01000000 /* DMA controller */ +#define IBM_CPM_BGO 0x00800000 /* PLB to OPB bus arbiter */ +#define IBM_CPM_BGI 0x00400000 /* OPB to PLB bridge */ +#define IBM_CPM_EBC 0x00200000 /* External Bux Controller */ +#define IBM_CPM_EBM 0x00100000 /* Ext Bus Master Interface */ +#define IBM_CPM_DMC 0x00080000 /* SDRAM peripheral controller */ +#define IBM_CPM_PLB 0x00040000 /* PLB bus arbiter */ +#define IBM_CPM_SRAM 0x00020000 /* SRAM memory controller */ +#define IBM_CPM_PPM 0x00002000 /* PLB Performance Monitor */ +#define IBM_CPM_UIC1 0x00001000 /* Universal Interrupt Controller */ +#define IBM_CPM_GPIO0 0x00000800 /* General Purpose IO (??) */ +#define IBM_CPM_GPT 0x00000400 /* General Purpose Timers */ +#define IBM_CPM_UART0 0x00000200 /* serial port 0 */ +#define IBM_CPM_UART1 0x00000100 /* serial port 1 */ +#define IBM_CPM_UIC0 0x00000080 /* Universal Interrupt Controller */ +#define IBM_CPM_TMRCLK 0x00000040 /* CPU timers */ +#define IBM_CPM_EMAC0 0x00000020 /* EMAC 0 */ +#define IBM_CPM_EMAC1 0x00000010 /* EMAC 1 */ +#define IBM_CPM_EMAC2 0x00000008 /* EMAC 2 */ +#define IBM_CPM_EMAC3 0x00000004 /* EMAC 3 */ + +#define DFLT_IBM4xx_PM ~(IBM_CPM_UIC | IBM_CPM_UIC1 | IBM_CPM_CPU \ + | IBM_CPM_EBC | IBM_CPM_SRAM | IBM_CPM_BGO \ + | IBM_CPM_EBM | IBM_CPM_PLB | IBM_CPM_OPB \ + | IBM_CPM_TMRCLK | IBM_CPM_DMA | IBM_CPM_PCI \ + | IBM_CPM_TAHOE0 | IBM_CPM_TAHOE1 \ + | IBM_CPM_EMAC0 | IBM_CPM_EMAC1 \ + | IBM_CPM_EMAC2 | IBM_CPM_EMAC3 ) + +/* OPB */ +#define PPC440GX_OPB_BASE_START 0x0000000140000000ULL + +/* + * Serial port defines + */ +#define RS_TABLE_SIZE 2 + +#endif /* __PPC_PLATFORMS_IBM440GX_H */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c new file mode 100644 index 0000000000000..7acf4aedcc84c --- /dev/null +++ b/arch/ppc/platforms/4xx/ocotea.c @@ -0,0 +1,459 @@ +/* + * arch/ppc/platforms/ocotea.c + * + * Ocotea board specific routines + * + * Matt Porter + * + * Copyright 2003 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void abort(void); + +/* Global Variables */ +bd_t __res; + +static void __init +ocotea_calibrate_decr(void) +{ + unsigned int freq; + + freq = OCOTEA_SYSCLK; + + tb_ticks_per_jiffy = freq / HZ; + tb_to_us = mulhwu_scale_factor(freq, 1000000); + + /* Set the time base to zero */ + mtspr(SPRN_TBWL, 0); + mtspr(SPRN_TBWU, 0); + + /* Clear any pending timer interrupts */ + mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS); + + /* Enable decrementer interrupt */ + mtspr(SPRN_TCR, TCR_DIE); +} + +static int +ocotea_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "vendor\t\t: IBM\n"); + seq_printf(m, "machine\t\t: PPC440GX EVB (Ocotea)\n"); + + return 0; +} +static inline int +ocotea_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 23, 23, 23, 23 }, /* IDSEL 1 - PCI Slot 0 */ + { 24, 24, 24, 24 }, /* IDSEL 2 - PCI Slot 1 */ + { 25, 25, 25, 25 }, /* IDSEL 3 - PCI Slot 2 */ + { 26, 26, 26, 26 }, /* IDSEL 4 - PCI Slot 3 */ + }; + + const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +#define PCIX_READW(offset) \ + (readw((u32)pcix_reg_base+offset)) + +#define PCIX_WRITEW(value, offset) \ + (writew(value, (u32)pcix_reg_base+offset)) + +#define PCIX_WRITEL(value, offset) \ + (writel(value, (u32)pcix_reg_base+offset)) + +/* + * FIXME: This is only here to "make it work". This will move + * to a ibm_pcix.c which will contain a generic IBM PCIX bridge + * configuration library. -Matt + */ +static void __init +ocotea_setup_pcix(void) +{ + void *pcix_reg_base; + + pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX0_REG_SIZE); + + /* Enable PCIX0 I/O, Mem, and Busmaster cycles */ + PCIX_WRITEW(PCIX_READW(PCIX0_COMMAND) | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER, PCIX0_COMMAND); + + /* Disable all windows */ + PCIX_WRITEL(0, PCIX0_POM0SA); + PCIX_WRITEL(0, PCIX0_POM1SA); + PCIX_WRITEL(0, PCIX0_POM2SA); + PCIX_WRITEL(0, PCIX0_PIM0SA); + PCIX_WRITEL(0, PCIX0_PIM0SAH); + PCIX_WRITEL(0, PCIX0_PIM1SA); + PCIX_WRITEL(0, PCIX0_PIM2SA); + PCIX_WRITEL(0, PCIX0_PIM2SAH); + + /* Setup 2GB PLB->PCI outbound mem window (3_8000_0000->0_8000_0000) */ + PCIX_WRITEL(0x00000003, PCIX0_POM0LAH); + PCIX_WRITEL(0x80000000, PCIX0_POM0LAL); + PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH); + PCIX_WRITEL(0x80000000, PCIX0_POM0PCIAL); + PCIX_WRITEL(0x80000001, PCIX0_POM0SA); + + /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */ + PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH); + PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL); + PCIX_WRITEL(0xe0000007, PCIX0_PIM0SA); + + eieio(); +} + +static void __init +ocotea_setup_hose(void) +{ + struct pci_controller *hose; + + /* Configure windows on the PCI-X host bridge */ + ocotea_setup_pcix(); + + hose = pcibios_alloc_controller(); + + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + hose->pci_mem_offset = OCOTEA_PCI_MEM_OFFSET; + + pci_init_resource(&hose->io_resource, + OCOTEA_PCI_LOWER_IO, + OCOTEA_PCI_UPPER_IO, + IORESOURCE_IO, + "PCI host bridge"); + + pci_init_resource(&hose->mem_resources[0], + OCOTEA_PCI_LOWER_MEM, + OCOTEA_PCI_UPPER_MEM, + IORESOURCE_MEM, + "PCI host bridge"); + + hose->io_space.start = OCOTEA_PCI_LOWER_IO; + hose->io_space.end = OCOTEA_PCI_UPPER_IO; + hose->mem_space.start = OCOTEA_PCI_LOWER_MEM; + hose->mem_space.end = OCOTEA_PCI_UPPER_MEM; + isa_io_base = + (unsigned long)ioremap64(OCOTEA_PCI_IO_BASE, OCOTEA_PCI_IO_SIZE); + hose->io_base_virt = (void *)isa_io_base; + + setup_indirect_pci(hose, + OCOTEA_PCI_CFGA_PLB32, + OCOTEA_PCI_CFGD_PLB32); + hose->set_cfg_type = 1; + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = ocotea_map_irq; +} + + +TODC_ALLOC(); + +static void __init +ocotea_early_serial_map(void) +{ + struct uart_port port; + + /* Setup ioremapped serial port access */ + memset(&port, 0, sizeof(port)); + port.membase = ioremap64(PPC440GX_UART0_ADDR, 8); + port.irq = 0; + port.uartclk = BASE_BAUD * 16; + port.regshift = 0; + port.iotype = SERIAL_IO_MEM; + port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; + port.line = 0; + + if (early_serial_setup(&port) != 0) { + printk("Early serial init of port 0 failed\n"); + } + + port.membase = ioremap64(PPC440GX_UART1_ADDR, 8); + port.irq = 1; + port.line = 1; + + if (early_serial_setup(&port) != 0) { + printk("Early serial init of port 1 failed\n"); + } +} + +static void __init +ocotea_setup_arch(void) +{ + unsigned char *addr; + unsigned long long mac64; + + /* Retrieve MAC addresses from flash */ + addr = ioremap64(OCOTEA_MAC_BASE, OCOTEA_MAC_SIZE); + mac64 = simple_strtoull(addr, 0, 16); + memcpy(__res.bi_enetaddr[0], (char *)&mac64+2, 6); + mac64 = simple_strtoull(addr+OCOTEA_MAC1_OFFSET, 0, 16); + memcpy(__res.bi_enetaddr[1], (char *)&mac64+2, 6); + iounmap(addr); + +#if !defined(CONFIG_BDI_SWITCH) + /* + * The Abatron BDI JTAG debugger does not tolerate others + * mucking with the debug registers. + */ + mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM)); +#endif + + /* Setup TODC access */ + TODC_INIT(TODC_TYPE_DS1743, + 0, + 0, + ioremap64(OCOTEA_RTC_ADDR, OCOTEA_RTC_SIZE), + 8); + + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + + /* Setup PCI host bridge */ + ocotea_setup_hose(); + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = Root_RAM0; + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = Root_NFS; +#else + ROOT_DEV = Root_HDA1; +#endif + +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#endif + + ocotea_early_serial_map(); + + /* Identify the system */ + printk("IBM Ocotea port (MontaVista Software, Inc. )\n"); +} + +static void +ocotea_restart(char *cmd) +{ + local_irq_disable(); + abort(); +} + +static void +ocotea_power_off(void) +{ + local_irq_disable(); + for(;;); +} + +static void +ocotea_halt(void) +{ + local_irq_disable(); + for(;;); +} + +/* + * Read the 440GX memory controller to get size of system memory. + */ +static unsigned long __init +ocotea_find_end_of_memory(void) +{ + u32 i, bank_config; + u32 mem_size = 0; + + for (i=0; i<4; i++) + { + switch (i) + { + case 0: + mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B0CR); + break; + case 1: + mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B1CR); + break; + case 2: + mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B2CR); + break; + case 3: + mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B3CR); + break; + } + + bank_config = mfdcr(DCRN_SDRAM0_CFGDATA); + + if (!(bank_config & SDRAM_CONFIG_BANK_ENABLE)) + continue; + switch (SDRAM_CONFIG_BANK_SIZE(bank_config)) + { + case SDRAM_CONFIG_SIZE_8M: + mem_size += PPC44x_MEM_SIZE_8M; + break; + case SDRAM_CONFIG_SIZE_16M: + mem_size += PPC44x_MEM_SIZE_16M; + break; + case SDRAM_CONFIG_SIZE_32M: + mem_size += PPC44x_MEM_SIZE_32M; + break; + case SDRAM_CONFIG_SIZE_64M: + mem_size += PPC44x_MEM_SIZE_64M; + break; + case SDRAM_CONFIG_SIZE_128M: + mem_size += PPC44x_MEM_SIZE_128M; + break; + case SDRAM_CONFIG_SIZE_256M: + mem_size += PPC44x_MEM_SIZE_256M; + break; + case SDRAM_CONFIG_SIZE_512M: + mem_size += PPC44x_MEM_SIZE_512M; + break; + } + } + return mem_size; +} + +static void __init +ocotea_init_irq(void) +{ + int i; + + /* Enable PPC440GP interrupt compatibility mode */ + SDR_WRITE(DCRN_SDR_MFR,SDR_READ(DCRN_SDR_MFR) | DCRN_SDR_MFR_PCM); + + ppc4xx_pic_init(); + + for (i = 0; i < NR_IRQS; i++) + irq_desc[i].handler = ppc4xx_pic; +} + +#ifdef CONFIG_SERIAL_TEXT_DEBUG +#include +#include +#include +struct serial_state rs_table[RS_TABLE_SIZE] = { + SERIAL_PORT_DFNS /* Defined in */ +}; + +static void +ocotea_progress(char *s, unsigned short hex) +{ + volatile char c; + volatile unsigned long com_port; + u16 shift; + + com_port = (unsigned long)rs_table[0].iomem_base; + shift = rs_table[0].iomem_reg_shift; + + while ((c = *s++) != 0) { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = c; + + } + + /* Send LF/CR to pretty up output */ + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\r'; + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\n'; +} +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + +#if 0 +static void __init +ocotea_map_io(void) +{ + io_block_mapping(0xe0000000, 0x0000000140000000, + 0x00001000, _PAGE_IO); +} +#endif + +void __init platform_init(unsigned long r3, unsigned long r4, + unsigned long r5, unsigned long r6, unsigned long r7) +{ + parse_bootinfo((struct bi_record *) (r3 + KERNELBASE)); + + ppc_md.setup_arch = ocotea_setup_arch; + ppc_md.show_cpuinfo = ocotea_show_cpuinfo; + ppc_md.init_IRQ = ocotea_init_irq; + ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */ + + ppc_md.find_end_of_memory = ocotea_find_end_of_memory; + + ppc_md.restart = ocotea_restart; + ppc_md.power_off = ocotea_power_off; + ppc_md.halt = ocotea_halt; + + ppc_md.calibrate_decr = ocotea_calibrate_decr; + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + + ppc_md.nvram_read_val = todc_direct_read_val; + ppc_md.nvram_write_val = todc_direct_write_val; + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ppc_md.progress = ocotea_progress; +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ +#ifdef CONFIG_KGDB + ppc_md.early_serial_map = ocotea_early_serial_map; +#endif +} diff --git a/arch/ppc/platforms/4xx/ocotea.h b/arch/ppc/platforms/4xx/ocotea.h new file mode 100644 index 0000000000000..2f2b5ab2f2b1c --- /dev/null +++ b/arch/ppc/platforms/4xx/ocotea.h @@ -0,0 +1,84 @@ +/* + * arch/ppc/platforms/ocotea.h + * + * Ocotea board definitions + * + * Matt Porter + * + * Copyright 2003 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#ifdef __KERNEL__ +#ifndef __ASM_OCOTEA_H__ +#define __ASM_OCOTEA_H__ + +#include +#include + +/* F/W TLB mapping used in bootloader glue to reset EMAC */ +#define PPC44x_EMAC0_MR0 0xE0000800 + +/* Location of MAC addresses in firmware */ +#define OCOTEA_MAC_BASE (OCOTEA_SMALL_FLASH_HIGH+0xc0500) +#define OCOTEA_MAC_SIZE 0x200 +#define OCOTEA_MAC1_OFFSET 0x100 + +/* Default clock rate */ +#define OCOTEA_SYSCLK 25000000 + +/* RTC/NVRAM location */ +#define OCOTEA_RTC_ADDR 0x0000000148000000ULL +#define OCOTEA_RTC_SIZE 0x2000 + +/* Flash */ +#define OCOTEA_FPGA_ADDR 0x0000000148300000ULL +#define OCOTEA_BOOT_LARGE_FLASH(x) (x & 0x40) +#define OCOTEA_SMALL_FLASH_LOW 0x00000001ff900000ULL +#define OCOTEA_SMALL_FLASH_HIGH 0x00000001fff00000ULL +#define OCOTEA_SMALL_FLASH_SIZE 0x100000 +#define OCOTEA_LARGE_FLASH_LOW 0x00000001ff800000ULL +#define OCOTEA_LARGE_FLASH_HIGH 0x00000001ffc00000ULL +#define OCOTEA_LARGE_FLASH_SIZE 0x400000 + +/* + * Serial port defines + */ +#define RS_TABLE_SIZE 2 + +/* OpenBIOS defined UART mappings, used before early_serial_setup */ +#define UART0_IO_BASE (u8 *) 0xE0000200 +#define UART1_IO_BASE (u8 *) 0xE0000300 + +#define BASE_BAUD 11059200/16 +#define STD_UART_OP(num) \ + { 0, BASE_BAUD, 0, UART##num##_IRQ, \ + (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \ + iomem_base: UART##num##_IO_BASE, \ + io_type: SERIAL_IO_MEM}, + +#define SERIAL_PORT_DFNS \ + STD_UART_OP(0) \ + STD_UART_OP(1) + +/* PCI support */ +#define OCOTEA_PCI_LOWER_IO 0x00000000 +#define OCOTEA_PCI_UPPER_IO 0x0000ffff +#define OCOTEA_PCI_LOWER_MEM 0x80000000 +#define OCOTEA_PCI_UPPER_MEM 0xffffefff + +#define OCOTEA_PCI_CFGREGS_BASE 0x000000020ec00000ULL +#define OCOTEA_PCI_CFGA_PLB32 0x0ec00000 +#define OCOTEA_PCI_CFGD_PLB32 0x0ec00004 + +#define OCOTEA_PCI_IO_BASE 0x0000000208000000ULL +#define OCOTEA_PCI_IO_SIZE 0x00010000 +#define OCOTEA_PCI_MEM_OFFSET 0x00000000 + +#endif /* __ASM_OCOTEA_H__ */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/syslib/Makefile b/arch/ppc/syslib/Makefile index c4621a1459291..59dd330444bcf 100644 --- a/arch/ppc/syslib/Makefile +++ b/arch/ppc/syslib/Makefile @@ -13,6 +13,8 @@ CFLAGS_prom_init.o += -mrelocatable-lib CFLAGS_btext.o += -mrelocatable-lib obj-$(CONFIG_PPCBUG_NVRAM) += prep_nvram.o +obj-$(CONFIG_44x) += ibm44x_common.o +obj-$(CONFIG_440GP) += ibm440gp_common.o ifeq ($(CONFIG_4xx),y) obj-$(CONFIG_4xx) += ppc4xx_pic.o obj-$(CONFIG_40x) += ppc4xx_setup.o @@ -33,6 +35,7 @@ obj-$(CONFIG_PPC_CHRP) += open_pic.o indirect_pci.o i8259.o obj-$(CONFIG_PPC_PREP) += open_pic.o indirect_pci.o i8259.o obj-$(CONFIG_ADIR) += i8259.o indirect_pci.o pci_auto.o \ todc_time.o +obj-$(CONFIG_EBONY) += indirect_pci.o pci_auto.o todc_time.o obj-$(CONFIG_EV64260) += gt64260_common.o gt64260_pic.o \ indirect_pci.o todc_time.o pci_auto.o obj-$(CONFIG_GEMINI) += open_pic.o i8259.o indirect_pci.o @@ -46,6 +49,7 @@ obj-$(CONFIG_MENF1) += todc_time.o i8259.o mpc10x_common.o \ pci_auto.o indirect_pci.o obj-$(CONFIG_MVME5100) += open_pic.o todc_time.o indirect_pci.o \ i8259.o pci_auto.o pplus_common.o +obj-$(CONFIG_OCOTEA) += indirect_pci.o pci_auto.o todc_time.o obj-$(CONFIG_PAL4) += cpc700_pic.o obj-$(CONFIG_PCORE) += mpc10x_common.o todc_time.o i8259.o \ indirect_pci.o pci_auto.o diff --git a/arch/ppc/syslib/ibm440gp_common.c b/arch/ppc/syslib/ibm440gp_common.c new file mode 100644 index 0000000000000..cc1382db846b3 --- /dev/null +++ b/arch/ppc/syslib/ibm440gp_common.c @@ -0,0 +1,77 @@ +/* + * arch/ppc/syslib/ibm440gp_common.c + * + * PPC440GP system library + * + * Matt Porter + * Copyright 2002-2003 MontaVista Software Inc. + * + * Eugene Surovegin or + * Copyright (c) 2003 Zultys Technologies + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include +#include +#include +#include + +/* + * Calculate 440GP clocks + */ +void __init ibm440gp_get_clocks(struct ibm440gp_clocks* p, + unsigned int sys_clk, + unsigned int ser_clk) +{ + u32 cpc0_sys0 = mfdcr(DCRN_CPC0_SYS0); + u32 cpc0_cr0 = mfdcr(DCRN_CPC0_CR0); + u32 opdv, epdv; + + if (cpc0_sys0 & 0x2){ + /* Bypass system PLL */ + p->cpu = p->plb = sys_clk; + } + else { + u32 fbdv, fwdva, fwdvb, m, vco; + + fbdv = (cpc0_sys0 >> 18) & 0x0f; + if (!fbdv) + fbdv = 16; + + fwdva = 8 - ((cpc0_sys0 >> 15) & 0x7); + fwdvb = 8 - ((cpc0_sys0 >> 12) & 0x7); + + /* Feedback path */ + if (cpc0_sys0 & 0x00000080){ + /* PerClk */ + m = fwdvb * opdv * epdv; + } + else { + /* CPU clock */ + m = fbdv * fwdva; + } + vco = sys_clk * m; + p->cpu = vco / fwdva; + p->plb = vco / fwdvb; + } + + opdv = ((cpc0_sys0 >> 10) & 0x3) + 1; + epdv = ((cpc0_sys0 >> 8) & 0x3) + 1; + + p->opb = p->plb / opdv; + p->ebc = p->opb / epdv; + + if (cpc0_cr0 & 0x00400000){ + /* External UART clock */ + p->uart = ser_clk; + } + else { + /* Internal UART clock */ + u32 uart_div = ((cpc0_cr0 >> 16) & 0x1f) + 1; + p->uart = p->plb / uart_div; + } +} diff --git a/arch/ppc/syslib/ibm440gp_common.h b/arch/ppc/syslib/ibm440gp_common.h new file mode 100644 index 0000000000000..63dbd4a9c4343 --- /dev/null +++ b/arch/ppc/syslib/ibm440gp_common.h @@ -0,0 +1,45 @@ +/* + * arch/ppc/syslib/ibm440gp_common.h + * + * PPC440GP system library + * + * Eugene Surovegin or + * Copyright (c) 2003 Zultys Technologies + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#ifdef __KERNEL__ +#ifndef __PPC_SYSLIB_IBM440GP_COMMON_H +#define __PPC_SYSLIB_IBM440GP_COMMON_H + +#ifndef __ASSEMBLY__ + +#include +#include + +/* + * All clocks are in Hz + */ +struct ibm440gp_clocks { + unsigned int cpu; /* CPUCoreClk */ + unsigned int plb; /* PLBClk */ + unsigned int opb; /* OPBClk */ + unsigned int ebc; /* PerClk */ + unsigned int uart; +}; + +/* + * Please, refer to the Figure 13.1 in 440GP user manual + * + * if internal UART clock is used, ser_clk is ignored + */ +void ibm440gp_get_clocks(struct ibm440gp_clocks*, unsigned int sys_clk, + unsigned int ser_clk) __init; + +#endif /* __ASSEMBLY__ */ +#endif /* __PPC_SYSLIB_IBM440GP_COMMON_H */ +#endif /* __KERNEL__ */ diff --git a/arch/ppc/syslib/ibm44x_common.c b/arch/ppc/syslib/ibm44x_common.c new file mode 100644 index 0000000000000..a0cefdc7c1da9 --- /dev/null +++ b/arch/ppc/syslib/ibm44x_common.c @@ -0,0 +1,37 @@ +/* + * arch/ppc/syslib/ibm44x_common.c + * + * PPC44x system library + * + * Matt Porter + * Copyright 2002-2003 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ +#include +#include +#include +#include + +phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size) +{ + phys_addr_t page_4gb = 0; + + /* + * Trap the least significant 32-bit portions of an + * address in the 440's 36-bit address space. Fix + * them up with the appropriate ERPN + */ + if ((addr >= PPC44x_IO_LO) && (addr < PPC44x_IO_HI)) + page_4gb = PPC44x_IO_PAGE; + else if ((addr >= PPC44x_PCICFG_LO) && (addr < PPC44x_PCICFG_HI)) + page_4gb = PPC44x_PCICFG_PAGE; + else if ((addr >= PPC44x_PCIMEM_LO) && (addr < PPC44x_PCIMEM_HI)) + page_4gb = PPC44x_PCIMEM_PAGE; + + return (page_4gb | addr); +}; diff --git a/include/asm-ppc/ibm44x.h b/include/asm-ppc/ibm44x.h new file mode 100644 index 0000000000000..ff6b72df2c10b --- /dev/null +++ b/include/asm-ppc/ibm44x.h @@ -0,0 +1,435 @@ +/* + * include/asm-ppc/ibm44x.h + * + * PPC44x definitions + * + * Matt Porter + * + * Copyright 2002-2003 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifdef __KERNEL__ +#ifndef __ASM_IBM44x_H__ +#define __ASM_IBM44x_H__ + +#include + +#ifndef __ASSEMBLY__ +/* + * Data structure defining board information maintained by the boot + * ROM on IBM's "Ebony" evaluation board. An effort has been made to + * keep the field names consistent with the 8xx 'bd_t' board info + * structures. + * + * Ebony firmware stores MAC addresses in the F/W VPD area. The + * firmware must store the other dynamic values in NVRAM like on + * the previous 40x systems so they should be accessible if we + * really want them. + */ +typedef struct board_info { + unsigned char bi_enetaddr[2][6]; /* EMAC addresses */ + unsigned int bi_opb_busfreq; /* OPB clock in Hz */ + int bi_iic_fast[2]; /* Use fast i2c mode */ +} bd_t; +#endif /* __ASSEMBLY__ */ + +#ifndef NR_BOARD_IRQS +#define NR_BOARD_IRQS 0 +#endif + +#define _IO_BASE isa_io_base +#define _ISA_MEM_BASE isa_mem_base +#define PCI_DRAM_OFFSET pci_dram_offset + +/* TLB entry offset/size used for pinning kernel lowmem */ +#define PPC44x_PIN_SHIFT 28 +#define PPC44x_PIN_SIZE (1 << PPC44x_PIN_SHIFT) + +/* Lowest TLB slot consumed by the default pinned TLBs */ +#define PPC44x_LOW_SLOT 62 + +/* + * Standard 4GB "page" definitions + */ +#define PPC44x_IO_PAGE 0x0000000100000000ULL +#define PPC44x_PCICFG_PAGE 0x0000000200000000ULL +#define PPC44x_PCIIO_PAGE PPC44x_PCICFG_PAGE +#define PPC44x_PCIMEM_PAGE 0x0000000300000000ULL + +/* + * 36-bit trap ranges + */ +#define PPC44x_IO_LO 0x40000000 +#define PPC44x_IO_HI 0x40001000 +#define PPC44x_PCICFG_LO 0x0ec00000 +#define PPC44x_PCICFG_HI 0x0ec7ffff +#define PPC44x_PCIMEM_LO 0x80002000 +#define PPC44x_PCIMEM_HI 0xffffffff + +/* + * The "residual" board information structure the boot loader passes + * into the kernel. + */ +#ifndef __ASSEMBLY__ + +/* + * SPRN definitions + */ +#define SPRN_CPC0_GPIO 0xe5/BEARLRL + +/* + * DCRN definitions + */ + +#ifdef CONFIG_440GX +/* SDRs */ +#define DCRN_SDR_CONFIG_ADDR 0xe +#define DCRN_SDR_CONFIG_DATA 0xf +#define DCRN_SDR_PFC0 0x4100 +#define DCRN_SDR_PFC1 0x4101 +#define DCRN_SDR_MFR 0x4300 +#define DCRN_SDR_MFR_TAH0 0x80000000 /* TAHOE0 Enable */ +#define DCRN_SDR_MFR_TAH1 0x40000000 /* TAHOE1 Enable */ +#define DCRN_SDR_MFR_PCM 0x10000000 /* PPC440GP irq compat mode */ +#define DCRN_SDR_MFR_ECS 0x08000000 /* EMAC int clk */ +#define DCRN_SDR_MFR_T0TXFL 0x00080000 +#define DCRN_SDR_MFR_T0TXFH 0x00040000 +#define DCRN_SDR_MFR_T1TXFL 0x00020000 +#define DCRN_SDR_MFR_T1TXFH 0x00010000 +#define DCRN_SDR_MFR_E0TXFL 0x00008000 +#define DCRN_SDR_MFR_E0TXFH 0x00004000 +#define DCRN_SDR_MFR_E0RXFL 0x00002000 +#define DCRN_SDR_MFR_E0RXFH 0x00001000 +#define DCRN_SDR_MFR_E1TXFL 0x00000800 +#define DCRN_SDR_MFR_E1TXFH 0x00000400 +#define DCRN_SDR_MFR_E1RXFL 0x00000200 +#define DCRN_SDR_MFR_E1RXFH 0x00000100 +#define DCRN_SDR_MFR_E2TXFL 0x00000080 +#define DCRN_SDR_MFR_E2TXFH 0x00000040 +#define DCRN_SDR_MFR_E2RXFL 0x00000020 +#define DCRN_SDR_MFR_E2RXFH 0x00000010 +#define DCRN_SDR_MFR_E3TXFL 0x00000008 +#define DCRN_SDR_MFR_E3TXFH 0x00000004 +#define DCRN_SDR_MFR_E3RXFL 0x00000002 +#define DCRN_SDR_MFR_E3RXFH 0x00000001 + +/* SDR read/write helper macros */ +#define SDR_READ(offset) ({\ + mtdcr(DCRN_SDR_CONFIG_ADDR, offset); \ + mfdcr(DCRN_SDR_CONFIG_DATA);}) +#define SDR_WRITE(offset, data) ({\ + mtdcr(DCRN_SDR_CONFIG_ADDR, offset); \ + mtdcr(DCRN_SDR_CONFIG_DATA,data);}) +#endif /* CONFIG_440GX */ + +/* Base DCRNs */ +#define DCRN_DMA0_BASE 0x100 +#define DCRN_DMA1_BASE 0x108 +#define DCRN_DMA2_BASE 0x110 +#define DCRN_DMA3_BASE 0x118 +#define DCRN_DMASR_BASE 0x120 +#define DCRNCAP_DMA_SG 1 /* have DMA scatter/gather capability */ +#define DCRN_MAL_BASE 0x180 + +/* UIC */ +#define DCRN_UIC0_BASE 0xc0 +#define DCRN_UIC1_BASE 0xd0 +#define UIC0 DCRN_UIC0_BASE +#define UIC1 DCRN_UIC1_BASE + +#define DCRN_UIC_SR(base) (base + 0x0) +#define DCRN_UIC_ER(base) (base + 0x2) +#define DCRN_UIC_CR(base) (base + 0x3) +#define DCRN_UIC_PR(base) (base + 0x4) +#define DCRN_UIC_TR(base) (base + 0x5) +#define DCRN_UIC_MSR(base) (base + 0x6) +#define DCRN_UIC_VR(base) (base + 0x7) +#define DCRN_UIC_VCR(base) (base + 0x8) + +#define UIC0_UIC1NC 30 /* UIC1 non-critical interrupt */ +#define UIC0_UIC1CR 31 /* UIC1 critical interrupt */ + +/* 440GP MAL DCRs */ +#define DCRN_MALCR(base) (base + 0x0) /* Configuration */ +#define DCRN_MALESR(base) (base + 0x1) /* Error Status */ +#define DCRN_MALIER(base) (base + 0x2) /* Interrupt Enable */ +#define DCRN_MALTXCASR(base) (base + 0x4) /* Tx Channel Active Set */ +#define DCRN_MALTXCARR(base) (base + 0x5) /* Tx Channel Active Reset */ +#define DCRN_MALTXEOBISR(base) (base + 0x6) /* Tx End of Buffer Interrupt Status */ +#define DCRN_MALTXDEIR(base) (base + 0x7) /* Tx Descriptor Error Interrupt */ +#define DCRN_MALRXCASR(base) (base + 0x10) /* Rx Channel Active Set */ +#define DCRN_MALRXCARR(base) (base + 0x11) /* Rx Channel Active Reset */ +#define DCRN_MALRXEOBISR(base) (base + 0x12) /* Rx End of Buffer Interrupt Status */ +#define DCRN_MALRXDEIR(base) (base + 0x13) /* Rx Descriptor Error Interrupt */ +#define DCRN_MALTXCTP0R(base) (base + 0x20) /* Channel Tx 0 Channel Table Pointer */ +#define DCRN_MALTXCTP1R(base) (base + 0x21) /* Channel Tx 1 Channel Table Pointer */ +#define DCRN_MALTXCTP2R(base) (base + 0x22) /* Channel Tx 2 Channel Table Pointer */ +#define DCRN_MALTXCTP3R(base) (base + 0x23) /* Channel Tx 3 Channel Table Pointer */ +#define DCRN_MALRXCTP0R(base) (base + 0x40) /* Channel Rx 0 Channel Table Pointer */ +#define DCRN_MALRXCTP1R(base) (base + 0x41) /* Channel Rx 1 Channel Table Pointer */ +#define DCRN_MALRCBS0(base) (base + 0x60) /* Channel Rx 0 Channel Buffer Size */ +#define DCRN_MALRCBS1(base) (base + 0x61) /* Channel Rx 1 Channel Buffer Size */ + +/* Compatibility DCRN's */ +#define DCRN_MALRXCTP2R(base) ((base) + 0x42) /* Channel Rx 2 Channel Table Pointer */ +#define DCRN_MALRXCTP3R(base) ((base) + 0x43) /* Channel Rx 3 Channel Table Pointer */ +#define DCRN_MALTXCTP4R(base) ((base) + 0x24) /* Channel Tx 4 Channel Table Pointer */ +#define DCRN_MALTXCTP5R(base) ((base) + 0x25) /* Channel Tx 5 Channel Table Pointer */ +#define DCRN_MALTXCTP6R(base) ((base) + 0x26) /* Channel Tx 6 Channel Table Pointer */ +#define DCRN_MALTXCTP7R(base) ((base) + 0x27) /* Channel Tx 7 Channel Table Pointer */ +#define DCRN_MALRCBS2(base) ((base) + 0x62) /* Channel Rx 2 Channel Buffer Size */ +#define DCRN_MALRCBS3(base) ((base) + 0x63) /* Channel Rx 3 Channel Buffer Size */ + + +#define MALCR_MMSR 0x80000000 /* MAL Software reset */ +#define MALCR_PLBP_1 0x00400000 /* MAL reqest priority: */ +#define MALCR_PLBP_2 0x00800000 /* lowsest is 00 */ +#define MALCR_PLBP_3 0x00C00000 /* highest */ +#define MALCR_GA 0x00200000 /* Guarded Active Bit */ +#define MALCR_OA 0x00100000 /* Ordered Active Bit */ +#define MALCR_PLBLE 0x00080000 /* PLB Lock Error Bit */ +#define MALCR_PLBLT_1 0x00040000 /* PLB Latency Timer */ +#define MALCR_PLBLT_2 0x00020000 +#define MALCR_PLBLT_3 0x00010000 +#define MALCR_PLBLT_4 0x00008000 +#ifdef CONFIG_440GP +#define MALCR_PLBLT_DEFAULT 0x00330000 /* PLB Latency Timer default */ +#else +#define MALCR_PLBLT_DEFAULT 0x00ff0000 /* PLB Latency Timer default */ +#endif +#define MALCR_PLBB 0x00004000 /* PLB Burst Deactivation Bit */ +#define MALCR_OPBBL 0x00000080 /* OPB Lock Bit */ +#define MALCR_EOPIE 0x00000004 /* End Of Packet Interrupt Enable */ +#define MALCR_LEA 0x00000002 /* Locked Error Active */ +#define MALCR_MSD 0x00000001 /* MAL Scroll Descriptor Bit */ +/* DCRN_MALESR */ +#define MALESR_EVB 0x80000000 /* Error Valid Bit */ +#define MALESR_CIDRX 0x40000000 /* Channel ID Receive */ +#define MALESR_DE 0x00100000 /* Descriptor Error */ +#define MALESR_OEN 0x00080000 /* OPB Non-Fullword Error */ +#define MALESR_OTE 0x00040000 /* OPB Timeout Error */ +#define MALESR_OSE 0x00020000 /* OPB Slave Error */ +#define MALESR_PEIN 0x00010000 /* PLB Bus Error Indication */ +#define MALESR_DEI 0x00000010 /* Descriptor Error Interrupt */ +#define MALESR_ONEI 0x00000008 /* OPB Non-Fullword Error Interrupt */ +#define MALESR_OTEI 0x00000004 /* OPB Timeout Error Interrupt */ +#define MALESR_OSEI 0x00000002 /* OPB Slace Error Interrupt */ +#define MALESR_PBEI 0x00000001 /* PLB Bus Error Interrupt */ +/* DCRN_MALIER */ +#define MALIER_DE 0x00000010 /* Descriptor Error Interrupt Enable */ +#define MALIER_NE 0x00000008 /* OPB Non-word Transfer Int Enable */ +#define MALIER_TE 0x00000004 /* OPB Time Out Error Interrupt Enable */ +#define MALIER_OPBE 0x00000002 /* OPB Slave Error Interrupt Enable */ +#define MALIER_PLBE 0x00000001 /* PLB Error Interrupt Enable */ +/* DCRN_MALTXEOBISR */ +#define MALOBISR_CH0 0x80000000 /* EOB channel 1 bit */ +#define MALOBISR_CH2 0x40000000 /* EOB channel 2 bit */ + +/* 440GP PLB Arbiter DCRs */ +#define DCRN_PLB0_REVID 0x082 /* PLB Arbiter Revision ID */ +#define DCRN_PLB0_ACR 0x083 /* PLB Arbiter Control */ +#define DCRN_PLB0_BESR 0x084 /* PLB Error Status */ +#define DCRN_PLB0_BEARL 0x086 /* PLB Error Address Low */ +#define DCRN_PLB0_BEAR DCRN_PLB0_BEARL /* 40x compatibility */ +#define DCRN_PLB0_BEARH 0x087 /* PLB Error Address High */ + +/* 440GP Clock, PM, chip control */ +#define DCRN_CPC0_SR 0x0b0 +#define DCRN_CPC0_ER 0x0b1 +#define DCRN_CPC0_FR 0x0b2 +#define DCRN_CPC0_SYS0 0x0e0 +#define DCRN_CPC0_SYS1 0x0e1 +#define DCRN_CPC0_CUST0 0x0e2 +#define DCRN_CPC0_CUST1 0x0e3 +#define DCRN_CPC0_STRP0 0x0e4 +#define DCRN_CPC0_STRP1 0x0e5 +#define DCRN_CPC0_STRP2 0x0e6 +#define DCRN_CPC0_STRP3 0x0e7 +#define DCRN_CPC0_GPIO 0x0e8 +#define DCRN_CPC0_PLB 0x0e9 +#define DCRN_CPC0_CR1 0x0ea +#define DCRN_CPC0_CR0 0x0eb +#define DCRN_CPC0_MIRQ0 0x0ec +#define DCRN_CPC0_MIRQ1 0x0ed +#define DCRN_CPC0_JTAGID 0x0ef + +/* 440GP DMA controller DCRs */ +#define DCRN_DMACR0 (DCRN_DMA0_BASE + 0x0) /* DMA Channel Control 0 */ +#define DCRN_DMACT0 (DCRN_DMA0_BASE + 0x1) /* DMA Count 0 */ +#define DCRN_DMASAH0 (DCRN_DMA0_BASE + 0x2) /* DMA Src Addr High 0 */ +#define DCRN_DMASA0 (DCRN_DMA0_BASE + 0x3) /* DMA Src Addr Low 0 */ +#define DCRN_DMADAH0 (DCRN_DMA0_BASE + 0x4) /* DMA Dest Addr High 0 */ +#define DCRN_DMADA0 (DCRN_DMA0_BASE + 0x5) /* DMA Dest Addr Low 0 */ +#define DCRN_ASGH0 (DCRN_DMA0_BASE + 0x6) /* DMA SG Desc Addr High 0 */ +#define DCRN_ASG0 (DCRN_DMA0_BASE + 0x7) /* DMA SG Desc Addr Low 0 */ + +#define DCRN_DMACR1 (DCRN_DMA1_BASE + 0x0) /* DMA Channel Control 1 */ +#define DCRN_DMACT1 (DCRN_DMA1_BASE + 0x1) /* DMA Count 1 */ +#define DCRN_DMASAH1 (DCRN_DMA1_BASE + 0x2) /* DMA Src Addr High 1 */ +#define DCRN_DMASA1 (DCRN_DMA1_BASE + 0x3) /* DMA Src Addr Low 1 */ +#define DCRN_DMADAH1 (DCRN_DMA1_BASE + 0x4) /* DMA Dest Addr High 1 */ +#define DCRN_DMADA1 (DCRN_DMA1_BASE + 0x5) /* DMA Dest Addr Low 1 */ +#define DCRN_ASGH1 (DCRN_DMA1_BASE + 0x6) /* DMA SG Desc Addr High 1 */ +#define DCRN_ASG1 (DCRN_DMA1_BASE + 0x7) /* DMA SG Desc Addr Low 1 */ + +#define DCRN_DMACR2 (DCRN_DMA2_BASE + 0x0) /* DMA Channel Control 2 */ +#define DCRN_DMACT2 (DCRN_DMA2_BASE + 0x1) /* DMA Count 2 */ +#define DCRN_DMASAH2 (DCRN_DMA2_BASE + 0x2) /* DMA Src Addr High 2 */ +#define DCRN_DMASA2 (DCRN_DMA2_BASE + 0x3) /* DMA Src Addr Low 2 */ +#define DCRN_DMADAH2 (DCRN_DMA2_BASE + 0x4) /* DMA Dest Addr High 2 */ +#define DCRN_DMADA2 (DCRN_DMA2_BASE + 0x5) /* DMA Dest Addr Low 2 */ +#define DCRN_ASGH2 (DCRN_DMA2_BASE + 0x6) /* DMA SG Desc Addr High 2 */ +#define DCRN_ASG2 (DCRN_DMA2_BASE + 0x7) /* DMA SG Desc Addr Low 2 */ + +#define DCRN_DMACR3 (DCRN_DMA3_BASE + 0x0) /* DMA Channel Control 3 */ +#define DCRN_DMACT3 (DCRN_DMA3_BASE + 0x1) /* DMA Count 3 */ +#define DCRN_DMASAH3 (DCRN_DMA3_BASE + 0x2) /* DMA Src Addr High 3 */ +#define DCRN_DMASA3 (DCRN_DMA3_BASE + 0x3) /* DMA Src Addr Low 3 */ +#define DCRN_DMADAH3 (DCRN_DMA3_BASE + 0x4) /* DMA Dest Addr High 3 */ +#define DCRN_DMADA3 (DCRN_DMA3_BASE + 0x5) /* DMA Dest Addr Low 3 */ +#define DCRN_ASGH3 (DCRN_DMA3_BASE + 0x6) /* DMA SG Desc Addr High 3 */ +#define DCRN_ASG3 (DCRN_DMA3_BASE + 0x7) /* DMA SG Desc Addr Low 3 */ + +#define DCRN_DMASR (DCRN_DMASR_BASE + 0x0) /* DMA Status Register */ +#define DCRN_ASGC (DCRN_DMASR_BASE + 0x3) /* DMA Scatter/Gather Command */ +#define DCRN_SLP (DCRN_DMASR_BASE + 0x5) /* DMA Sleep Register */ +#define DCRN_POL (DCRN_DMASR_BASE + 0x6) /* DMA Polarity Register */ + +/* 440GP DRAM controller DCRs */ +#define DCRN_SDRAM0_CFGADDR 0x010 +#define DCRN_SDRAM0_CFGDATA 0x011 + +#define SDRAM0_B0CR 0x40 +#define SDRAM0_B1CR 0x44 +#define SDRAM0_B2CR 0x48 +#define SDRAM0_B3CR 0x4c + +#define SDRAM_CONFIG_BANK_ENABLE 0x00000001 +#define SDRAM_CONFIG_SIZE_MASK 0x000e0000 +#define SDRAM_CONFIG_BANK_SIZE(reg) ((reg & SDRAM_CONFIG_SIZE_MASK) >> 17) +#define SDRAM_CONFIG_SIZE_8M 0x00000001 +#define SDRAM_CONFIG_SIZE_16M 0x00000002 +#define SDRAM_CONFIG_SIZE_32M 0x00000003 +#define SDRAM_CONFIG_SIZE_64M 0x00000004 +#define SDRAM_CONFIG_SIZE_128M 0x00000005 +#define SDRAM_CONFIG_SIZE_256M 0x00000006 +#define SDRAM_CONFIG_SIZE_512M 0x00000007 +#define PPC44x_MEM_SIZE_8M 0x00800000 +#define PPC44x_MEM_SIZE_16M 0x01000000 +#define PPC44x_MEM_SIZE_32M 0x02000000 +#define PPC44x_MEM_SIZE_64M 0x04000000 +#define PPC44x_MEM_SIZE_128M 0x08000000 +#define PPC44x_MEM_SIZE_256M 0x10000000 +#define PPC44x_MEM_SIZE_512M 0x20000000 + +/* + * PCI-X definitions + */ +#define PCIX0_REG_BASE 0x20ec80000ULL +#define PCIX0_REG_SIZE 0x200 + +#define PCIX0_VENDID 0x000 +#define PCIX0_DEVID 0x002 +#define PCIX0_COMMAND 0x004 +#define PCIX0_STATUS 0x006 +#define PCIX0_REVID 0x008 +#define PCIX0_CLS 0x009 +#define PCIX0_CACHELS 0x00c +#define PCIX0_LATTIM 0x00d +#define PCIX0_HDTYPE 0x00e +#define PCIX0_BIST 0x00f +#define PCIX0_BAR0L 0x010 +#define PCIX0_BAR0H 0x014 +#define PCIX0_BAR1 0x018 +#define PCIX0_BAR2L 0x01c +#define PCIX0_BAR2H 0x020 +#define PCIX0_BAR3 0x024 +#define PCIX0_CISPTR 0x028 +#define PCIX0_SBSYSVID 0x02c +#define PCIX0_SBSYSID 0x02e +#define PCIX0_EROMBA 0x030 +#define PCIX0_CAP 0x034 +#define PCIX0_RES0 0x035 +#define PCIX0_RES1 0x036 +#define PCIX0_RES2 0x038 +#define PCIX0_INTLN 0x03c +#define PCIX0_INTPN 0x03d +#define PCIX0_MINGNT 0x03e +#define PCIX0_MAXLTNCY 0x03f +#define PCIX0_BRDGOPT1 0x040 +#define PCIX0_BRDGOPT2 0x044 +#define PCIX0_ERREN 0x050 +#define PCIX0_ERRSTS 0x054 +#define PCIX0_PLBBESR 0x058 +#define PCIX0_PLBBEARL 0x05c +#define PCIX0_PLBBEARH 0x060 +#define PCIX0_POM0LAL 0x068 +#define PCIX0_POM0LAH 0x06c +#define PCIX0_POM0SA 0x070 +#define PCIX0_POM0PCIAL 0x074 +#define PCIX0_POM0PCIAH 0x078 +#define PCIX0_POM1LAL 0x07c +#define PCIX0_POM1LAH 0x080 +#define PCIX0_POM1SA 0x084 +#define PCIX0_POM1PCIAL 0x088 +#define PCIX0_POM1PCIAH 0x08c +#define PCIX0_POM2SA 0x090 +#define PCIX0_PIM0SAL 0x098 +#define PCIX0_PIM0SA PCIX0_PIM0SAL +#define PCIX0_PIM0LAL 0x09c +#define PCIX0_PIM0LAH 0x0a0 +#define PCIX0_PIM1SA 0x0a4 +#define PCIX0_PIM1LAL 0x0a8 +#define PCIX0_PIM1LAH 0x0ac +#define PCIX0_PIM2SAL 0x0b0 +#define PCIX0_PIM2SA PCIX0_PIM2SAL +#define PCIX0_PIM2LAL 0x0b4 +#define PCIX0_PIM2LAH 0x0b8 +#define PCIX0_OMCAPID 0x0c0 +#define PCIX0_OMNIPTR 0x0c1 +#define PCIX0_OMMC 0x0c2 +#define PCIX0_OMMA 0x0c4 +#define PCIX0_OMMUA 0x0c8 +#define PCIX0_OMMDATA 0x0cc +#define PCIX0_OMMEOI 0x0ce +#define PCIX0_PMCAPID 0x0d0 +#define PCIX0_PMNIPTR 0x0d1 +#define PCIX0_PMC 0x0d2 +#define PCIX0_PMCSR 0x0d4 +#define PCIX0_PMCSRBSE 0x0d6 +#define PCIX0_PMDATA 0x0d7 +#define PCIX0_PMSCRR 0x0d8 +#define PCIX0_CAPID 0x0dc +#define PCIX0_NIPTR 0x0dd +#define PCIX0_CMD 0x0de +#define PCIX0_STS 0x0e0 +#define PCIX0_IDR 0x0e4 +#define PCIX0_CID 0x0e8 +#define PCIX0_RID 0x0ec +#define PCIX0_PIM0SAH 0x0f8 +#define PCIX0_PIM2SAH 0x0fc +#define PCIX0_MSGIL 0x100 +#define PCIX0_MSGIH 0x104 +#define PCIX0_MSGOL 0x108 +#define PCIX0_MSGOH 0x10c +#define PCIX0_IM 0x1f8 + +#define IIC_OWN 0x55 +#define IIC_CLOCK 50 + +#undef NR_UICS +#define NR_UICS 2 +#define UIC_CASCADE_MASK 0x0003 /* bits 30 & 31 */ + +#define BD_EMAC_ADDR(e,i) bi_enetaddr[e][i] + +#include + +#endif /* __ASSEMBLY__ */ +#endif /* __ASM_IBM44x_H__ */ +#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/ibm4xx.h b/include/asm-ppc/ibm4xx.h index 4884067dbcd9c..c8da43c8512f0 100644 --- a/include/asm-ppc/ibm4xx.h +++ b/include/asm-ppc/ibm4xx.h @@ -122,7 +122,25 @@ void ppc4xx_init(unsigned long r3, unsigned long r4, unsigned long r5, #define PCI_DRAM_OFFSET 0 #endif +#elif CONFIG_44x + +#if defined(CONFIG_EBONY) +#include +#endif + +#if defined(CONFIG_OCOTEA) +#include +#endif #endif /* CONFIG_40x */ + +#ifndef __ASSEMBLY__ +/* + * The "residual" board information structure the boot loader passes + * into the kernel. + */ +extern bd_t __res; +#endif + #endif /* __ASM_IBM4XX_H__ */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h index b67f27323f46f..55e67291c3d2b 100644 --- a/include/asm-ppc/io.h +++ b/include/asm-ppc/io.h @@ -4,9 +4,11 @@ #include #include +#include #include #include +#include #define SIO_CONFIG_RA 0x398 #define SIO_CONFIG_RD 0x399 @@ -22,7 +24,7 @@ #define PREP_ISA_MEM_BASE 0xc0000000 #define PREP_PCI_DRAM_OFFSET 0x80000000 -#if defined(CONFIG_40x) +#if defined(CONFIG_4xx) #include #elif defined(CONFIG_8xx) #include @@ -197,14 +199,17 @@ extern void _outsl_ns(volatile u32 *port, const void *buf, int nl); * Map in an area of physical address space, for accessing * I/O devices etc. */ -extern void *__ioremap(unsigned long address, unsigned long size, +extern void *__ioremap(phys_addr_t address, unsigned long size, unsigned long flags); -extern void *ioremap(unsigned long address, unsigned long size); +extern void *ioremap(phys_addr_t address, unsigned long size); +#ifdef CONFIG_44x +extern void *ioremap64(unsigned long long address, unsigned long size); +#endif #define ioremap_nocache(addr, size) ioremap((addr), (size)) extern void iounmap(void *addr); extern unsigned long iopa(unsigned long addr); extern unsigned long mm_ptov(unsigned long addr) __attribute__ ((const)); -extern void io_block_mapping(unsigned long virt, unsigned long phys, +extern void io_block_mapping(unsigned long virt, phys_addr_t phys, unsigned int size, int flags); /* diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h index 6ca586ab8f4ee..02b993f6c3c73 100644 --- a/include/asm-ppc/irq.h +++ b/include/asm-ppc/irq.h @@ -71,11 +71,11 @@ irq_canonicalize(int irq) return (irq); } -#elif defined(CONFIG_440) -#include +#elif defined(CONFIG_44x) +#include -#define NR_UIC_IRQS 64 -#define NR_IRQS (NR_UIC_IRQS + NR_BOARD_IRQS) +#define NR_UIC_IRQS 32 +#define NR_IRQS ((NR_UIC_IRQS * NR_UICS) + NR_BOARD_IRQS) static __inline__ int irq_canonicalize(int irq) diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h index 7b729cdf52f42..b75b24e4c0564 100644 --- a/include/asm-ppc/mmu.h +++ b/include/asm-ppc/mmu.h @@ -10,6 +10,18 @@ #ifndef __ASSEMBLY__ +/* + * Define physical address type. Machines using split size + * virtual/physical addressing like 32-bit virtual / 36-bit + * physical need a larger than native word size type. -Matt + */ +#ifndef CONFIG_PTE_64BIT +typedef unsigned long phys_addr_t; +#else +typedef unsigned long long phys_addr_t; +extern phys_addr_t fixup_bigphys_addr(phys_addr_t, phys_addr_t); +#endif + /* Default "unsigned long" context */ typedef unsigned long mm_context_t; @@ -320,5 +332,55 @@ typedef struct _P601_BAT { #define TLB_M 0x00000002 /* Memory is coherent */ #define TLB_G 0x00000001 /* Memory is guarded from prefetch */ +/* + * PPC440 support + */ +#define PPC44x_MMUCR_TID 0x000000ff +#define PPC44x_MMUCR_STS 0x00010000 + +#define PPC44x_TLB_PAGEID 0 +#define PPC44x_TLB_XLAT 1 +#define PPC44x_TLB_ATTRIB 2 + +/* Page identification fields */ +#define PPC44x_TLB_EPN_MASK 0xfffffc00 /* Effective Page Number */ +#define PPC44x_TLB_VALID 0x00000200 /* Valid flag */ +#define PPC44x_TLB_TS 0x00000100 /* Translation address space */ +#define PPC44x_TLB_PAGESZ_MASK 0x000000f0 +#define PPC44x_TLB_PAGESZ(x) (x << 4) +#define PPC44x_PAGESZ_1K 0 +#define PPC44x_PAGESZ_4K 1 +#define PPC44x_PAGESZ_16K 2 +#define PPC44x_PAGESZ_64K 3 +#define PPC44x_PAGESZ_256K 4 +#define PPC44x_PAGESZ_1M 5 +#define PPC44x_PAGESZ_16M 7 +#define PPC44x_PAGESZ_256M 9 + +/* Translation fields */ +#define PPC44x_TLB_RPN_MASK 0xfffffc00 /* Real Page Number */ +#define PPC44x_TLB_ERPN_MASK 0x0000000f + +/* Storage attribute and access control fields */ +#define PPC44x_TLB_ATTR_MASK 0x0000ff80 +#define PPC44x_TLB_U0 0x00008000 /* User 0 */ +#define PPC44x_TLB_U1 0x00004000 /* User 1 */ +#define PPC44x_TLB_U2 0x00002000 /* User 2 */ +#define PPC44x_TLB_U3 0x00001000 /* User 3 */ +#define PPC44x_TLB_W 0x00000800 /* Caching is write-through */ +#define PPC44x_TLB_I 0x00000400 /* Caching is inhibited */ +#define PPC44x_TLB_M 0x00000200 /* Memory is coherent */ +#define PPC44x_TLB_G 0x00000100 /* Memory is guarded */ +#define PPC44x_TLB_E 0x00000080 /* Memory is guarded */ + +#define PPC44x_TLB_PERM_MASK 0x0000003f +#define PPC44x_TLB_UX 0x00000020 /* User execution */ +#define PPC44x_TLB_UW 0x00000010 /* User write */ +#define PPC44x_TLB_UR 0x00000008 /* User read */ +#define PPC44x_TLB_SX 0x00000004 /* Super execution */ +#define PPC44x_TLB_SW 0x00000002 /* Super write */ +#define PPC44x_TLB_SR 0x00000001 /* Super read */ + + #endif /* _PPC_MMU_H_ */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h index b8f25854778dc..6d2a8a40368f5 100644 --- a/include/asm-ppc/page.h +++ b/include/asm-ppc/page.h @@ -4,7 +4,12 @@ /* PAGE_SHIFT determines the page size */ #define PAGE_SHIFT 12 #define PAGE_SIZE (1UL << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) + +/* + * Subtle: this is an int (not an unsigned long) and so it + * gets extended to 64 bits the way want (i.e. with 1s). -- paulus + */ +#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) #ifdef __KERNEL__ #include @@ -15,13 +20,27 @@ #ifndef __ASSEMBLY__ -#define STRICT_MM_TYPECHECKS +/* + * The basic type of a PTE - 64 bits for those CPUs with > 32 bit + * physical addressing. For now this just the IBM PPC440. + */ +#ifdef CONFIG_PTE_64BIT +typedef unsigned long long pte_basic_t; +#define PTE_SHIFT (PAGE_SHIFT - 3) /* 512 ptes per page */ +#define PTE_FMT "%16Lx" +#else +typedef unsigned long pte_basic_t; +#define PTE_SHIFT (PAGE_SHIFT - 2) /* 1024 ptes per page */ +#define PTE_FMT "%.8lx" +#endif + +#undef STRICT_MM_TYPECHECKS #ifdef STRICT_MM_TYPECHECKS /* * These are used to make use of C type-checking.. */ -typedef struct { unsigned long pte; } pte_t; +typedef struct { pte_basic_t pte; } pte_t; typedef struct { unsigned long pmd; } pmd_t; typedef struct { unsigned long pgd; } pgd_t; typedef struct { unsigned long pgprot; } pgprot_t; @@ -40,7 +59,7 @@ typedef struct { unsigned long pgprot; } pgprot_t; /* * .. while these make it easier on the compiler */ -typedef unsigned long pte_t; +typedef pte_basic_t pte_t; typedef unsigned long pmd_t; typedef unsigned long pgd_t; typedef unsigned long pgprot_t; @@ -123,6 +142,7 @@ static inline void* ___va(unsigned long p) #define pfn_to_page(pfn) (mem_map + ((pfn) - PPC_PGSTART)) #define page_to_pfn(page) ((unsigned long)((page) - mem_map) + PPC_PGSTART) #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) +#define page_to_virt(page) __va(page_to_pfn(page) << PAGE_SHIFT) #define pfn_valid(pfn) (((pfn) - PPC_PGSTART) < max_mapnr) #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) diff --git a/include/asm-ppc/pgalloc.h b/include/asm-ppc/pgalloc.h index 7d5d0455cc005..faf91bc03022e 100644 --- a/include/asm-ppc/pgalloc.h +++ b/include/asm-ppc/pgalloc.h @@ -20,10 +20,17 @@ extern void pgd_free(pgd_t *pgd); #define __pmd_free_tlb(tlb,x) do { } while (0) #define pgd_populate(mm, pmd, pte) BUG() +#ifndef CONFIG_BOOKE #define pmd_populate_kernel(mm, pmd, pte) \ (pmd_val(*(pmd)) = __pa(pte) | _PMD_PRESENT) #define pmd_populate(mm, pmd, pte) \ (pmd_val(*(pmd)) = (page_to_pfn(pte) << PAGE_SHIFT) | _PMD_PRESENT) +#else +#define pmd_populate_kernel(mm, pmd, pte) \ + (pmd_val(*(pmd)) = (unsigned long)pte | _PMD_PRESENT) +#define pmd_populate(mm, pmd, pte) \ + (pmd_val(*(pmd)) = (unsigned long)page_to_virt(pte) | _PMD_PRESENT) +#endif extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr); extern struct page *pte_alloc_one(struct mm_struct *mm, unsigned long addr); diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index 73a8f18d22cf9..0399c8cfbcab4 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h @@ -65,13 +65,23 @@ extern unsigned long ioremap_bot, ioremap_base; * and ITLB, respectively (see "mmu.h" for definitions). */ -/* PMD_SHIFT determines the size of the area mapped by the second-level page tables */ -#define PMD_SHIFT 22 +/* + * The normal case is that PTEs are 32-bits and we have a 1-page + * 1024-entry pgdir pointing to 1-page 1024-entry PTE pages. -- paulus + * + * For any >32-bit physical address platform, we can use the following + * two level page table layout where the pgdir is 8KB and the MS 13 bits + * are an index to the second level table. The combined pgdir/pmd first + * level has 2048 entries and the second level has 512 64-bit PTE entries. + * -Matt + */ +/* PMD_SHIFT determines the size of the area mapped by the PTE pages */ +#define PMD_SHIFT (PAGE_SHIFT + PTE_SHIFT) #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) -/* PGDIR_SHIFT determines what a third-level page table entry can map */ -#define PGDIR_SHIFT 22 +/* PGDIR_SHIFT determines what a top-level page table entry can map */ +#define PGDIR_SHIFT PMD_SHIFT #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) @@ -79,9 +89,10 @@ extern unsigned long ioremap_bot, ioremap_base; * entries per page directory level: our page-table tree is two-level, so * we don't really have any PMD directory. */ -#define PTRS_PER_PTE 1024 +#define PTRS_PER_PTE (1 << PTE_SHIFT) #define PTRS_PER_PMD 1 -#define PTRS_PER_PGD 1024 +#define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT)) + #define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) #define FIRST_USER_PGD_NR 0 @@ -89,7 +100,7 @@ extern unsigned long ioremap_bot, ioremap_base; #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS) #define pte_ERROR(e) \ - printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) + printk("%s:%d: bad pte "PTE_FMT".\n", __FILE__, __LINE__, pte_val(e)) #define pmd_ERROR(e) \ printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) #define pgd_ERROR(e) \ @@ -113,7 +124,11 @@ extern unsigned long ioremap_bot, ioremap_base; * of RAM. -- Cort */ #define VMALLOC_OFFSET (0x1000000) /* 16M */ +#ifdef CONFIG_44x +#define VMALLOC_START (((_ALIGN((long)high_memory, PPC44x_PIN_SIZE) + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))) +#else #define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))) +#endif #define VMALLOC_VMADDR(x) ((unsigned long)(x)) #define VMALLOC_END ioremap_bot @@ -170,6 +185,44 @@ extern unsigned long ioremap_bot, ioremap_base; #define _PMD_SIZE_16M 0x0e0 #define PMD_PAGE_SIZE(pmdval) (1024 << (((pmdval) & _PMD_SIZE) >> 4)) +#elif defined(CONFIG_44x) +/* + * Definitions for PPC440 + * + * Because of the 3 word TLB entries to support 36-bit addressing, + * the attribute are difficult to map in such a fashion that they + * are easily loaded during exception processing. I decided to + * organize the entry so the ERPN is the only portion in the + * upper word of the PTE and the attribute bits below are packed + * in as sensibly as they can be in the area below a 4KB page size + * oriented RPN. This at least makes it easy to load the RPN and + * ERPN fields in the TLB. -Matt + * + * Note that these bits preclude future use of a page size + * less than 4KB. + */ +#define _PAGE_PRESENT 0x00000001 /* S: PTE valid */ +#define _PAGE_RW 0x00000002 /* S: Write permission */ +#define _PAGE_DIRTY 0x00000004 /* S: Page dirty */ +#define _PAGE_ACCESSED 0x00000008 /* S: Page referenced */ +#define _PAGE_HWWRITE 0x00000010 /* H: Dirty & RW */ +#define _PAGE_HWEXEC 0x00000020 /* H: Execute permission */ +#define _PAGE_USER 0x00000040 /* S: User page */ +#define _PAGE_ENDIAN 0x00000080 /* H: E bit */ +#define _PAGE_GUARDED 0x00000100 /* H: G bit */ +#define _PAGE_COHERENT 0x00000200 /* H: M bit */ +#define _PAGE_FILE 0x00000400 /* S: nonlinear file mapping */ +#define _PAGE_NO_CACHE 0x00000400 /* H: I bit */ +#define _PAGE_WRITETHRU 0x00000800 /* H: W bit */ + +/* TODO: Add large page lowmem mapping support */ +#define _PMD_PRESENT 0 +#define _PMD_PRESENT_MASK (PAGE_MASK) +#define _PMD_BAD (~PAGE_MASK) + +/* ERPN in a PTE never gets cleared, ignore it */ +#define _PTE_NONE_MASK 0xffffffff00000000ULL + #elif defined(CONFIG_8xx) /* Definitions for 8xx embedded chips. */ #define _PAGE_PRESENT 0x0001 /* Page is valid */ @@ -270,7 +323,11 @@ extern unsigned long ioremap_bot, ioremap_base; #define _PAGE_BASE (_PAGE_PRESENT | _PAGE_ACCESSED) #define _PAGE_WRENABLE (_PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE) +#ifndef CONFIG_44x #define _PAGE_KERNEL (_PAGE_BASE | _PAGE_SHARED | _PAGE_WRENABLE) +#else +#define _PAGE_KERNEL (_PAGE_BASE | _PAGE_SHARED | _PAGE_WRENABLE | _PAGE_GUARDED) +#endif #ifdef CONFIG_PPC_STD_MMU /* On standard PPC MMU, no user access implies kernel read/write access, @@ -283,7 +340,7 @@ extern unsigned long ioremap_bot, ioremap_base; #define _PAGE_IO (_PAGE_KERNEL | _PAGE_NO_CACHE | _PAGE_GUARDED) #define _PAGE_RAM (_PAGE_KERNEL | _PAGE_HWEXEC) -#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) +#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH) /* We want the debuggers to be able to set breakpoints anywhere, so * don't write protect the kernel text */ #define _PAGE_RAM_TEXT _PAGE_RAM @@ -420,6 +477,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) * * pte_update clears and sets bit atomically, and returns * the old pte value. + * The ((unsigned long)(p+1) - 4) hack is to get to the least-significant + * 32 bits of the PTE regardless of whether PTEs are 32 or 64 bits. */ static inline unsigned long pte_update(pte_t *p, unsigned long clr, unsigned long set) @@ -434,7 +493,7 @@ static inline unsigned long pte_update(pte_t *p, unsigned long clr, " stwcx. %1,0,%3\n\ bne- 1b" : "=&r" (old), "=&r" (tmp), "=m" (*p) - : "r" (p), "r" (clr), "r" (set), "m" (*p) + : "r" ((unsigned long)(p+1) - 4), "r" (clr), "r" (set), "m" (*p) : "cc" ); return old; } @@ -485,11 +544,25 @@ static inline void ptep_mkdirty(pte_t *ptep) #define pte_same(A,B) (((pte_val(A) ^ pte_val(B)) & ~_PAGE_HASHPTE) == 0) +/* + * Note that on Book E processors, the pmd contains the kernel virtual + * (lowmem) address of the pte page. The physical address is less useful + * because everything runs with translation enabled (even the TLB miss + * handler). On everything else the pmd contains the physical address + * of the pte page. -- paulus + */ +#ifndef CONFIG_BOOKE #define pmd_page_kernel(pmd) \ ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) #define pmd_page(pmd) \ (mem_map + (pmd_val(pmd) >> PAGE_SHIFT)) - +#else +#define pmd_page_kernel(pmd) \ + ((unsigned long) (pmd_val(pmd) & PAGE_MASK)) +#define pmd_page(pmd) \ + (mem_map + (__pa(pmd_val(pmd)) >> PAGE_SHIFT)) +#endif + /* to find an entry in a kernel page-table-directory */ #define pgd_offset_k(address) pgd_offset(&init_mm, address) @@ -516,7 +589,8 @@ static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) #define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) #define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1) -extern pgd_t swapper_pg_dir[1024]; +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; + extern void paging_init(void); /* diff --git a/include/asm-ppc/ppc_asm.h b/include/asm-ppc/ppc_asm.h index 39049bcac7fce..afd99032491cb 100644 --- a/include/asm-ppc/ppc_asm.h +++ b/include/asm-ppc/ppc_asm.h @@ -107,7 +107,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) bdnz 0b #endif -#if !defined(CONFIG_440) +#if !defined(CONFIG_44x) /* * On APUS (Amiga PowerPC cpu upgrade board), we don't know the * physical base address of RAM at compile time. @@ -125,7 +125,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) .align 1; \ .long 0b; \ .previous -#else /* CONFIG_440 */ +#else /* CONFIG_44x */ #define tophys(rd,rs) \ mr rd,rs @@ -133,7 +133,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_601) #define tovirt(rd,rs) \ mr rd,rs -#endif /* CONFIG_440 */ +#endif /* CONFIG_44x */ /* * On 64-bit cpus, we use the rfid instruction instead of rfi, but diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index 21c2c819b98f6..e13d0a0b1f45a 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -2,6 +2,12 @@ #ifndef __ASM_PPC_PROCESSOR_H #define __ASM_PPC_PROCESSOR_H +/* + * The Book E definitions are hacked into here for 440 right + * now. This whole thing needs regorganized (maybe two files) + * so that it becomes readable. -Matt + */ + /* * Default implementation of macro that returns current * instruction pointer ("program counter"). @@ -45,6 +51,11 @@ #define MSR_RI (1<<1) /* Recoverable Exception */ #define MSR_LE (1<<0) /* Little Endian */ +#ifdef CONFIG_BOOKE +#define MSR_IS MSR_IR /* Instruction Space */ +#define MSR_DS MSR_DR /* Data Space */ +#endif + #ifdef CONFIG_APUS_FAST_EXCEPT #define MSR_ (MSR_ME|MSR_IP|MSR_RI) #else @@ -93,8 +104,13 @@ #define SPRN_CDBCR 0x3D7 /* Cache Debug Control Register */ #define SPRN_CTR 0x009 /* Count Register */ #define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ +#ifndef CONFIG_BOOKE #define SPRN_DAC1 0x3F6 /* Data Address Compare 1 */ #define SPRN_DAC2 0x3F7 /* Data Address Compare 2 */ +#else +#define SPRN_DAC1 0x13C /* Book E Data Address Compare 1 */ +#define SPRN_DAC2 0x13D /* Book E Data Address Compare 2 */ +#endif /* CONFIG_BOOKE */ #define SPRN_DAR 0x013 /* Data Address Register */ #define SPRN_DBAT0L 0x219 /* Data BAT 0 Lower Register */ #define SPRN_DBAT0U 0x218 /* Data BAT 0 Upper Register */ @@ -146,7 +162,11 @@ #define DBCR_SDA 0x00000004 /* Second DAC Enable */ #define DBCR_JOI 0x00000002 /* JTAG Serial Outbound Int. Enable */ #define DBCR_JII 0x00000001 /* JTAG Serial Inbound Int. Enable */ +#ifndef CONFIG_BOOKE #define SPRN_DBCR0 0x3F2 /* Debug Control Register 0 */ +#else +#define SPRN_DBCR0 0x134 /* Book E Debug Control Register 0 */ +#endif /* CONFIG_BOOKE */ #define DBCR0_EDM 0x80000000 /* External Debug Mode */ #define DBCR0_IDM 0x40000000 /* Internal Debug Mode */ #define DBCR0_RST 0x30000000 /* all the bits in the RST field */ @@ -169,11 +189,18 @@ #define DBCR0_IA12T 0x00008000 /* Instr Addr 1-2 range Toggle */ #define DBCR0_IA34T 0x00004000 /* Instr Addr 3-4 range Toggle */ #define DBCR0_FT 0x00000001 /* Freeze Timers on debug event */ +#ifndef CONFIG_BOOKE #define SPRN_DBCR1 0x3BD /* Debug Control Register 1 */ #define SPRN_DBSR 0x3F0 /* Debug Status Register */ #define DBSR_IC 0x80000000 /* Instruction Completion */ #define DBSR_BT 0x40000000 /* Branch taken */ #define DBSR_TIE 0x10000000 /* Trap Instruction debug Event */ +#else +#define SPRN_DBCR1 0x135 /* Book E Debug Control Register 1 */ +#define SPRN_DBSR 0x130 /* Book E Debug Status Register */ +#define DBSR_IC 0x08000000 /* Book E Instruction Completion */ +#define DBSR_TIE 0x01000000 /* Book E Trap Instruction Event */ +#endif /* CONFIG_BOOKE */ #define SPRN_DCCR 0x3FA /* Data Cache Cacheability Register */ #define DCCR_NOCACHE 0 /* Noncacheable */ #define DCCR_CACHE 1 /* Cacheable */ @@ -181,7 +208,11 @@ #define SPRN_DCWR 0x3BA /* Data Cache Write-thru Register */ #define DCWR_COPY 0 /* Copy-back */ #define DCWR_WRITE 1 /* Write-through */ +#ifndef CONFIG_BOOKE #define SPRN_DEAR 0x3D5 /* Data Error Address Register */ +#else +#define SPRN_DEAR 0x03D /* Book E Data Error Address Register */ +#endif /* CONFIG_BOOKE */ #define SPRN_DEC 0x016 /* Decrement Register */ #define SPRN_DER 0x095 /* Debug Enable Regsiter */ #define DER_RSTE 0x40000000 /* Reset Interrupt */ @@ -206,12 +237,16 @@ #define SPRN_DMISS 0x3D0 /* Data TLB Miss Register */ #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ #define SPRN_EAR 0x11A /* External Address Register */ +#ifndef CONFIG_BOOKE #define SPRN_ESR 0x3D4 /* Exception Syndrome Register */ +#else +#define SPRN_ESR 0x03E /* Book E Exception Syndrome Register */ +#endif /* CONFIG_BOOKE */ #define ESR_MCI 0x80000000 /* 405 Machine Check - Instruction */ -#define ESR_IMCP 0x80000000 /* 403 Inst. Mach. Check - Protection */ -#define ESR_IMCN 0x40000000 /* 403 Inst. Mach. Check - Non-config */ -#define ESR_IMCB 0x20000000 /* 403 Inst. Mach. Check - Bus error */ -#define ESR_IMCT 0x10000000 /* 403 Inst. Mach. Check - Timeout */ +#define ESR_IMCP 0x80000000 /* Instr. Machine Check - Protection */ +#define ESR_IMCN 0x40000000 /* Instr. Machine Check - Non-config */ +#define ESR_IMCB 0x20000000 /* Instr. Machine Check - Bus error */ +#define ESR_IMCT 0x10000000 /* Instr. Machine Check - Timeout */ #define ESR_PIL 0x08000000 /* Program Exception - Illegal */ #define ESR_PPR 0x04000000 /* Program Exception - Priveleged */ #define ESR_PTR 0x02000000 /* Program Exception - Trap */ @@ -266,8 +301,13 @@ #define HID1_SYNCBE (1<<11) /* 7450 ABE for sync, eieio */ #define HID1_ABE (1<<10) /* 7450 Address Broadcast Enable */ #define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ +#ifndef CONFIG_BOOKE #define SPRN_IAC1 0x3F4 /* Instruction Address Compare 1 */ #define SPRN_IAC2 0x3F5 /* Instruction Address Compare 2 */ +#else +#define SPRN_IAC1 0x138 /* Book E Instruction Address Compare 1 */ +#define SPRN_IAC2 0x139 /* Book E Instruction Address Compare 2 */ +#endif /* CONFIG_BOOKE */ #define SPRN_IBAT0L 0x211 /* Instruction BAT 0 Lower Register */ #define SPRN_IBAT0U 0x210 /* Instruction BAT 0 Upper Register */ #define SPRN_IBAT1L 0x213 /* Instruction BAT 1 Lower Register */ @@ -358,8 +398,13 @@ #define SPRN_PBL2 0x3FE /* Protection Bound Lower 2 */ #define SPRN_PBU1 0x3FD /* Protection Bound Upper 1 */ #define SPRN_PBU2 0x3FF /* Protection Bound Upper 2 */ +#ifndef CONFIG_BOOKE #define SPRN_PID 0x3B1 /* Process ID */ #define SPRN_PIR 0x3FF /* Processor Identification Register */ +#else +#define SPRN_PID 0x030 /* Book E Process ID */ +#define SPRN_PIR 0x11E /* Book E Processor Identification Register */ +#endif /* CONFIG_BOOKE */ #define SPRN_PIT 0x3DB /* Programmable Interval Timer */ #define SPRN_PMC1 0x3B9 /* Performance Counter Register 1 */ #define SPRN_PMC2 0x3BA /* Performance Counter Register 2 */ @@ -375,6 +420,7 @@ #define SGR_NORMAL 0 #define SGR_GUARDED 1 #define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */ +#define SPRN_SLER 0x3BB /* Little-endian real mode */ #define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */ #define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */ #define SPRN_SPRG2 0x112 /* Special Purpose Register General 2 */ @@ -387,6 +433,7 @@ #define SPRN_SRR1 0x01B /* Save/Restore Register 1 */ #define SPRN_SRR2 0x3DE /* Save/Restore Register 2 */ #define SPRN_SRR3 0x3DF /* Save/Restore Register 3 */ +#define SPRN_SU0R 0x3BC /* "User 0" real mode */ #define SPRN_TBHI 0x3DC /* Time Base High (4xx) */ #define SPRN_TBHU 0x3CC /* Time Base High User-mode (4xx) */ #define SPRN_TBLO 0x3DD /* Time Base Low (4xx) */ @@ -395,7 +442,11 @@ #define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */ #define SPRN_TBWL 0x11C /* Time Base Lower Register (super, R/W) */ #define SPRN_TBWU 0x11D /* Time Base Upper Register (super, R/W) */ +#ifndef CONFIG_BOOKE #define SPRN_TCR 0x3DA /* Timer Control Register */ +#else +#define SPRN_TCR 0x154 /* Book E Timer Control Register */ +#endif #define TCR_WP(x) (((x)&0x3)<<30) /* WDT Period */ #define TCR_WP_MASK TCR_WP(3) #define WP_2_17 0 /* 2^17 clocks */ @@ -410,6 +461,7 @@ #define WRC_SYSTEM 3 /* System reset will occur */ #define TCR_WIE 0x08000000 /* WDT Interrupt Enable */ #define TCR_PIE 0x04000000 /* PIT Interrupt Enable */ +#define TCR_DIE TCR_PIE /* DEC Interrupt Enable */ #define TCR_FP(x) (((x)&0x3)<<24) /* FIT Period */ #define TCR_FP_MASK TCR_FP(3) #define FP_2_9 0 /* 2^9 clocks */ @@ -431,7 +483,11 @@ #define SPRN_THRM3 0x3FE /* Thermal Management Register 3 */ #define THRM3_E (1<<0) #define SPRN_TLBMISS 0x3D4 /* 980 7450 TLB Miss Register */ +#ifndef CONFIG_BOOKE #define SPRN_TSR 0x3D8 /* Timer Status Register */ +#else +#define SPRN_TSR 0x150 /* Book E Timer Status Register */ +#endif /* CONFIG_BOOKE */ #define TSR_ENW 0x80000000 /* Enable Next Watchdog */ #define TSR_WIS 0x40000000 /* WDT Interrupt Status */ #define TSR_WRS(x) (((x)&0x3)<<28) /* WDT Reset Status */ @@ -440,6 +496,7 @@ #define WRS_CHIP 2 /* WDT forced chip reset */ #define WRS_SYSTEM 3 /* WDT forced system reset */ #define TSR_PIS 0x08000000 /* PIT Interrupt Status */ +#define TSR_DIS TSR_PIS /* DEC Interrupt Status */ #define TSR_FIS 0x04000000 /* FIT Interrupt Status */ #define SPRN_UMMCR0 0x3A8 /* User Monitor Mode Control Register 0 */ #define SPRN_UMMCR1 0x3AC /* User Monitor Mode Control Register 0 */ @@ -452,6 +509,45 @@ #define SPRN_XER 0x001 /* Fixed Point Exception Register */ #define SPRN_ZPR 0x3B0 /* Zone Protection Register */ +/* Book E definitions */ +#define SPRN_DECAR 0x036 /* Decrementer Auto Reload Register */ +#define SPRN_CSRR0 0x03A /* Critical Save and Restore Register 0 */ +#define SPRN_CSRR1 0x03B /* Critical Save and Restore Register 1 */ +#define SPRN_IVPR 0x03F /* Interrupt Vector Prefix Register */ +#define SPRN_USPRG0 0x100 /* User Special Purpose Register General 0 */ +#define SPRN_SPRG4R 0x104 /* Special Purpose Register General 4 Read */ +#define SPRN_SPRG5R 0x105 /* Special Purpose Register General 5 Read */ +#define SPRN_SPRG6R 0x106 /* Special Purpose Register General 6 Read */ +#define SPRN_SPRG7R 0x107 /* Special Purpose Register General 7 Read */ +#define SPRN_SPRG4W 0x114 /* Special Purpose Register General 4 Write */ +#define SPRN_SPRG5W 0x115 /* Special Purpose Register General 5 Write */ +#define SPRN_SPRG6W 0x116 /* Special Purpose Register General 6 Write */ +#define SPRN_SPRG7W 0x117 /* Special Purpose Register General 7 Write */ +#define SPRN_DBCR2 0x136 /* Debug Control Register 2 */ +#define SPRN_IAC3 0x13A /* Instruction Address Compare 3 */ +#define SPRN_IAC4 0x13B /* Instruction Address Compare 4 */ +#define SPRN_DVC1 0x13E /* */ +#define SPRN_DVC2 0x13F /* */ +#define SPRN_IVOR0 0x190 /* Interrupt Vector Offset Register 0 */ +#define SPRN_IVOR1 0x191 /* Interrupt Vector Offset Register 1 */ +#define SPRN_IVOR2 0x192 /* Interrupt Vector Offset Register 2 */ +#define SPRN_IVOR3 0x193 /* Interrupt Vector Offset Register 3 */ +#define SPRN_IVOR4 0x194 /* Interrupt Vector Offset Register 4 */ +#define SPRN_IVOR5 0x195 /* Interrupt Vector Offset Register 5 */ +#define SPRN_IVOR6 0x196 /* Interrupt Vector Offset Register 6 */ +#define SPRN_IVOR7 0x197 /* Interrupt Vector Offset Register 7 */ +#define SPRN_IVOR8 0x198 /* Interrupt Vector Offset Register 8 */ +#define SPRN_IVOR9 0x199 /* Interrupt Vector Offset Register 9 */ +#define SPRN_IVOR10 0x19a /* Interrupt Vector Offset Register 10 */ +#define SPRN_IVOR11 0x19b /* Interrupt Vector Offset Register 11 */ +#define SPRN_IVOR12 0x19c /* Interrupt Vector Offset Register 12 */ +#define SPRN_IVOR13 0x19d /* Interrupt Vector Offset Register 13 */ +#define SPRN_IVOR14 0x19e /* Interrupt Vector Offset Register 14 */ +#define SPRN_IVOR15 0x19f /* Interrupt Vector Offset Register 15 */ +#define SPRN_MMUCR 0x3b2 /* MMU Control Register */ + +#define ESR_ST 0x00800000 /* Store Operation */ + /* Short-hand versions for a number of the above SPRNs */ #define CTR SPRN_CTR /* Counter Register */ @@ -524,6 +620,16 @@ #define SPRG5 SPRN_SPRG5 #define SPRG6 SPRN_SPRG6 #define SPRG7 SPRN_SPRG7 +#define SPRG4R SPRN_SPRG4R /* Book E Supervisor Private Registers */ +#define SPRG5R SPRN_SPRG5R +#define SPRG6R SPRN_SPRG6R +#define SPRG7R SPRN_SPRG7R +#define SPRG4W SPRN_SPRG4W +#define SPRG5W SPRN_SPRG5W +#define SPRG6W SPRN_SPRG6W +#define SPRG7W SPRN_SPRG7W +#define CSRR0 SPRN_CSRR0 /* Critical Save and Restore Register 0 */ +#define CSRR1 SPRN_CSRR1 /* Critical Save and Restore Register 1 */ #define SRR0 SPRN_SRR0 /* Save and Restore Register 0 */ #define SRR1 SPRN_SRR1 /* Save and Restore Register 1 */ #define SRR2 SPRN_SRR2 /* Save and Restore Register 2 */ @@ -557,6 +663,51 @@ #define PVR_MAJ(pvr) (((pvr) >> 4) & 0xF) /* Major revision field */ #define PVR_MIN(pvr) (((pvr) >> 0) & 0xF) /* Minor revision field */ +/* Processor Version Numbers */ + +#define PVR_403GA 0x00200000 +#define PVR_403GB 0x00200100 +#define PVR_403GC 0x00200200 +#define PVR_403GCX 0x00201400 +#define PVR_405GP 0x40110000 +#define PVR_STB03XXX 0x40310000 +#define PVR_NP405H 0x41410000 +#define PVR_NP405L 0x41610000 +#define PVR_440GP_RB 0x40120440 +#define PVR_440GP_RC1 0x40120481 +#define PVR_440GP_RC2 0x40200481 +#define PVR_440GX_RC1 0x51b21850 +#define PVR_601 0x00010000 +#define PVR_602 0x00050000 +#define PVR_603 0x00030000 +#define PVR_603e 0x00060000 +#define PVR_603ev 0x00070000 +#define PVR_603r 0x00071000 +#define PVR_604 0x00040000 +#define PVR_604e 0x00090000 +#define PVR_604r 0x000A0000 +#define PVR_620 0x00140000 +#define PVR_740 0x00080000 +#define PVR_750 PVR_740 +#define PVR_740P 0x10080000 +#define PVR_750P PVR_740P +#define PVR_7400 0x000C0000 +#define PVR_7410 0x800C0000 +#define PVR_7450 0x80000000 +/* + * For the 8xx processors, all of them report the same PVR family for + * the PowerPC core. The various versions of these processors must be + * differentiated by the version number in the Communication Processor + * Module (CPM). + */ +#define PVR_821 0x00500000 +#define PVR_823 PVR_821 +#define PVR_850 PVR_821 +#define PVR_860 PVR_821 +#define PVR_8240 0x00810100 +#define PVR_8245 0x80811014 +#define PVR_8260 PVR_8240 + /* We only need to define a new _MACH_xxx for machines which are part of * a configuration which supports more than one type of different machine. * This is currently limited to CONFIG_PPC_MULTIPLATFORM and CHRP/PReP/PMac. -- Tom diff --git a/include/asm-ppc/serial.h b/include/asm-ppc/serial.h index 5d121448d3c18..2d9e8642cc870 100644 --- a/include/asm-ppc/serial.h +++ b/include/asm-ppc/serial.h @@ -28,7 +28,7 @@ #include #elif defined(CONFIG_SPRUCE) #include -#elif defined(CONFIG_40x) +#elif defined(CONFIG_4xx) #include #else diff --git a/include/asm-ppc/tlbflush.h b/include/asm-ppc/tlbflush.h index 2ccb0b20d2af4..a441eb07e0e5f 100644 --- a/include/asm-ppc/tlbflush.h +++ b/include/asm-ppc/tlbflush.h @@ -19,17 +19,23 @@ extern void _tlbia(void); #if defined(CONFIG_4xx) +#ifndef CONFIG_44x +#define __tlbia() asm volatile ("sync; tlbia; isync" : : : "memory") +#else +#define __tlbia _tlbia +#endif + static inline void flush_tlb_mm(struct mm_struct *mm) - { _tlbia(); } + { __tlbia(); } static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) { _tlbie(vmaddr); } static inline void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) - { _tlbia(); } + { __tlbia(); } static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) - { _tlbia(); } + { __tlbia(); } #elif defined(CONFIG_8xx) #define __tlbia() asm volatile ("tlbia; sync" : : : "memory") -- 2.53.0