diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/Documentation/Configure.help linuxppc64_2_4/Documentation/Configure.help
--- ../tue/linux-2.4.10-ac12/Documentation/Configure.help Tue Oct 16 16:54:39 2001
+++ linuxppc64_2_4/Documentation/Configure.help Fri Oct 12 11:00:43 2001
@@ -179,6 +179,14 @@
from Motorola. The Linux PowerPC port has a home page at
.
+PowerPC64 processor
+CONFIG_PPC64
+ The PowerPC architecture was designed for both 32 bit and 64 bit
+ processor implementations. 64 bit PowerPC processors are in many
+ ways a superset of their 32 bit PowerPC cousins. Each 64 bit PowerPC
+ processor also has a 32 bit mode to allow for 32 bit compatibility.
+ The home of the PowerPC 64 Linux project is at
+
Motorola 68K processors
CONFIG_M68K
The Motorola 68K microprocessors are now obsolete, having been
@@ -14442,6 +14450,13 @@
hard drives and ADFS-formatted floppy disks. This is experimental
codes, so if you're unsure, say N.
+JFS filesystem support
+CONFIG_JFS_FS
+ This is a port of IBM's Journaled Filesystem . More information is
+ available in the file Documentation/filesystems/jfs.txt.
+
+ If you do not intend to use the JFS filesystem, say N.
+
/dev/pts file system for Unix98 PTYs
CONFIG_DEVPTS_FS
You should say Y here if you said Y to "Unix98 PTY support" above.
@@ -20083,6 +20098,46 @@
Select APUS if configuring for a PowerUP Amiga. More information is
available at: .
+# Choice: i or p
+Platform support
+CONFIG_PPC_ISERIES
+ Linux runs on certain models of the IBM AS/400, now known as the
+ IBM iSeries. Generally if you can run LPAR (Logical Partitioning)
+ on your iSeries you can run Linux in a partition on your machine.
+
+ Linux also runs on most models of IBM pSeries hardware. (pSeries
+ used to be known as the RS/6000)
+
+ If you have an iSeries and want to run Linux in a partition,
+ select the iSeries option to build your kernel.
+
+ If you have a pSeries and want to run Linux, select pSeries
+ as the option to build your kernel.
+
+ See for exact model information to see what
+ can run the 64 bit PowerPC kernel.
+
+ iSeries Linux information from IBM can be found at:
+
+
+ pSeries Linux information from IBM can be found at:
+
+
+ Project information can be found at:
+
+
+
+Platform support
+CONFIG_PPC_PSERIES
+ Linux runs on most models of IBM pSeries hardware. (pSeries used
+ to be known as the RS/6000)
+
+ See for exact model information for the
+ 64 bit PowerPC kernel.
+
+ pSeries Linux information from IBM can be found at:
+
+
Synergy-Gemini
CONFIG_GEMINI
Select Gemini if configuring for a Synergy Microsystems' Gemini
@@ -20456,6 +20511,13 @@
, but the EST8260 cannot be found on it
and has probably been discontinued or rebadged.
+Support for Large Memory
+CONFIG_MSCHUNKS
+ MsChunks stands for Main Store Chunks and specifically allows the
+ 64 bit PowerPC Linux kernel to optimize for machines with sparse
+ discontiguous memory. iSeries kernels need to have this on.
+ It is recommended that for pSeries hardware that you answer Y.
+
ADB raw keycode support
CONFIG_MAC_ADBKEYCODES
This provides support for sending raw ADB keycodes to console
@@ -23197,6 +23259,11 @@
CONFIG_XMON
Include in-kernel hooks for the xmon kernel monitor/debugger
supported by the PPC port.
+
+Include realtime debugging
+CONFIG_PPCDBG
+ Include in-kernel PowerPC 64 information hooks that may be turned on/off
+ in real time.
Include kgdb kernel debugger
CONFIG_KWDB
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/Documentation/cachetlb.txt linuxppc64_2_4/Documentation/cachetlb.txt
--- ../tue/linux-2.4.10-ac12/Documentation/cachetlb.txt Sun Mar 25 20:14:20 2001
+++ linuxppc64_2_4/Documentation/cachetlb.txt Fri Sep 7 06:23:33 2001
@@ -260,8 +260,9 @@
Here is the new interface:
- void copy_user_page(void *to, void *from, unsigned long address)
- void clear_user_page(void *to, unsigned long address)
+ void copy_user_page(struct page *to, struct page *from,
+ unsigned long address)
+ void clear_user_page(struct page *to, unsigned long address)
These two routines store data in user anonymous or COW
pages. It allows a port to efficiently avoid D-cache alias
@@ -279,6 +280,11 @@
If D-cache aliasing is not an issue, these two routines may
simply call memcpy/memset directly and do nothing more.
+
+ There are default versions of these procedures supplied in
+ include/linux/highmem.h. If a port does not want to use the
+ default versions it should declare them and define the symbol
+ __HAVE_ARCH_USER_PAGE in include/asm/page.h.
void flush_dcache_page(struct page *page)
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/Documentation/filesystems/00-INDEX linuxppc64_2_4/Documentation/filesystems/00-INDEX
--- ../tue/linux-2.4.10-ac12/Documentation/filesystems/00-INDEX Wed Jun 20 13:10:27 2001
+++ linuxppc64_2_4/Documentation/filesystems/00-INDEX Thu Sep 13 14:29:38 2001
@@ -22,6 +22,8 @@
- info and mount options for the OS/2 HPFS.
isofs.txt
- info and mount options for the ISO 9660 (CDROM) filesystem.
+jfs.txt
+ - info and mount options for the JFS filesystem.
ncpfs.txt
- info on Novell Netware(tm) filesystem using NCP protocol.
ntfs.txt
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/Documentation/filesystems/changelog.jfs linuxppc64_2_4/Documentation/filesystems/changelog.jfs
--- ../tue/linux-2.4.10-ac12/Documentation/filesystems/changelog.jfs Wed Dec 31 18:00:00 1969
+++ linuxppc64_2_4/Documentation/filesystems/changelog.jfs Thu Sep 13 14:31:38 2001
@@ -0,0 +1,594 @@
+IBM's Journaled File System (JFS) for Linux version 1.0.4
+Team members
+Steve Best sbest@us.ibm.com
+Dave Kleikamp shaggy@us.ibm.com
+Barry Arndt barndt@us.ibm.com
+
+
+Release August 31, 2001 (version 1.0.4)
+
+This is our forty-second release of IBM's Enterprise JFS technology port to Linux.
+Beta 1 was release 0.1.0 on 12/8/2000, Beta 2 was release 0.2.0 on 3/7/2001,
+Beta 3 was release 0.3.0 on 4/30/2001, and release 1.0.0 on 6/28/2001.
+
+The first drop on February 2, 2000 (jfs-0.0.1.tar.gz) had the following
+functionality (enough to allow other developers to evaluate and potentially
+contribute to this project):
+
+ - MKFS functional and able to format an existing or newly created partition for JFS.
+ - mount/unmount functional
+ - able to view the self(.) and parent (..) directories entries.
+
+The second drop on February 28, 2000 (jfs-0.0.2.tar.gz) had fixes for MKFS and the
+following utilities logredo, xchkdmp, xpeek are functional. The file system was able
+to mkdir, create files and directories were working (and rm, rmdir).
+
+The third drop on March 24, 2000 (jfs-0.0.3.tar.gz) provided read and write capability
+for the file system. Also, support for hard and soft links are functional.
+
+The fourth drop on March 29,2000 (jfs-0.0.4.tar.gz) provided rename capability for
+the file system and fixes for write problems.
+
+The fifth drop on April 6, 2000 (jfs-0.0.5.tar.gz) provided mknod capability for the
+file system.
+
+The sixth drop on April 21, 2000 (jfs-0.0.6.tar.gz) provided fixes for the file system
+and utilities.
+
+The seventh drop on May 11, 2000 (jfs-0.0.7.tar.gz) provided changes to the file system
+to be able to work on the development kernel 2.3.99-pre6. Drop 7 contains fixes for the
+file system to be built within the kernel.
+
+The eighth drop on June 20, 2000 (jfs-0.0.8.tar.gz) provided fixes for the file system
+and changes to the file system to be able to work on the development kernel 2.4.0-test1-ac21.
+In the utility area: fsck and logdump are functional.
+
+The ninth drop on July 13, 2000 (jfs-0.0.9.tar.gz) has the meta-data of the file system
+using the page cache. In the utility area: fixes for fsck.jfs and xpeek are included.
+
+The tenth drop on August 11, 2000 provided fixes for the file system
+and changes to the file system to be able to work on the development kernel 2.4.0-test5.
+In the utility area: fixes for fsck.jfs are included. The utility portion of extendfs has
+been ported (still need to port the file system portion for extendfs). Man pages have
+been written for the utilities. The compiler warnings have been removed from all of the
+utilities.
+
+The eleventh drop on September 1, 2000 provided fixes for the file system
+and changes to the file system to be able to work on the development kernel 2.4.0-test7.
+The utility portion of defrag has been ported (still need to port the file system portion
+for defrag).
+
+The twelfth drop on September 15, 2000 (jfs-0.0.12.tar.gz) provided the Transaction
+Manager Log I/O routines.
+
+The thirteenth drop on September 29, 2000 (jfs-0.0.13.tar.gz) provided case-sensitive
+support. In the utility area: fsck.jfs has the support for block/character special files.
+Note: The JFS partition must be formatted/reformatted using mkfs.jfs created by drop 13
+for case-sensitive to work.
+
+The fourteenth drop on October 4, 2000 (jfs-0.0.14.tar.gz) included a fix to the file
+system for not mounting a JFS partition if the size of the partition is > 4G on 2.2.x
+series of the kernel.
+
+The fifteenth drop on October 9, 2000 (jfs-0.0.15.tar.gz) included the Transaction
+Manager routines (Initialize, Begin, Locks, End). The file system has fixes and
+changes to the file system to be able to work on the development kernel 2.4.0-test9.
+The utility xchklog has been ported.
+
+The sixteenth drop on October 27, 2000 (jfs-0.0.16.tar.gz) included the Transaction
+Manager routines (Commit, Buffer Management, Abort). The file system and utilities
+have fixes included.
+
+The seventeenth drop on November 10, 2000 (jfs-0.0.17.tar.gz) has the transaction
+sub operations back into the file system operations. The file system is now journaling
+appropriate file system operations. The file system is temporary doing synchronous logging
+(which slows down operations that are logged) to make sure that the transaction processing
+is right. Asynchronous logging will be added shortly. The file system has fixes and changes
+to the file system to be able to work on the development kernel 2.4.0-test10.
+
+The eighteenth drop on November 15, 2000 (jfs-0.0.18.tar.gz) included fixes to the file
+system.
+
+The nineteenth drop on December 4, 2000 (jfs-0.0.19.tar.gz) is now doing asynchronous
+logging. The file system has fixes and changes to the file system to be able to work
+on the development kernel 2.4.0-test11.
+
+The twentieth drop on December 8, 2000 (jfs-0.1.0.tar.gz beta) included fixes to the file
+system.
+
+The twenty-first drop on December 14, 2000 (jfs-0.1.1.tar.gz) included a fsck fix
+to handle sparse files correctly. The file system has fixes and changes to the file
+system to be able to work on the development kernel 2.4.0-test12 and 2.2.18 kernel.
+
+The twenty-second drop on January 5, 2001 (jfs-0.1.2.tar.gz) included fixes to the
+file system. The file system has changes to able to work on the 2.4.0 kernel.
+
+The twenty-third drop on January 12, 2001 (jfs-0.1.3.tar.gz) included fixes to the
+file system. Fsck now supports fifo correctly.
+
+The twenty-fourth drop on January 26, 2001 (jfs-0.1.4.tar.gz) included fixes to the
+file system. The new feature in the file system is "Lazy Commit" which increases
+performance while going asynchronous logging. The main makefile for the utilities
+now has an install option.
+
+The twenty-fifth drop on February 7, 2001 (jfs-0.1.5.tar.gz) included fixes to the
+file system.
+
+The twenty-sixth drop on February 26, 2001 (jfs-0.1.6.tar.gz) included fixes to the
+file system. The log manager no longer uses the page cache for log pages, this
+eliminates dead-locks that were occurring in the log manager. The file system has
+general work done to remove SMP dead-lock problems. Fsck now supports default values
+passed by fstab correctly.
+
+The twenty-seventh drop on March 7, 2001 (beta 2) (jfs-0.2.0.tar.gz) included fixes to the
+file system. This drop contains jfsprogs.spec that can be used to create RPM for the
+JFS utilities. The file system has general work done to remove SMP and UP hang related problems.
+The file system performance has been increased by changes to extent inode cache.
+
+The twenty-eighth drop on March 21, 2001 (jfs-0.2.1.tar.gz) included fixes to the
+file system. The file system has been changed to use standard types.
+
+The twenty-ninth drop on April 2, 2001 (jfs-0.2.2.tar.gz) included fixes to the
+file system. The utilities have been changed to use standard types.
+
+The thirtieth drop on April 30, 2001 (jfs-0.3.0.tar.gz) included fixes to the
+file system. The rest of the utilities have been changed to use standard types.
+Both the file system and the utilities have been changed to use endian macros,
+so that JFS will now store the meta-data as little endian when running on all
+architectures, with this change you must re-format all of the JFS partitions
+using the new mkfs.jfs included in this drop, if you are running on a big-endian system.
+
+The thirty-first drop on May 9, 2001 (jfs-0.3.1.tar.gz) included fixes to the file
+system and the utilities.
+
+The thirty-second drop on May 18, 2001 (jfs-0.3.2-patch.tar.gz) included fixes to the file
+system and the utilities.
+
+The thirty-third drop on May 25, 2001 (jfs-0.3.3-patch.tar.gz) included fixes to the file
+system and the utilities.
+
+The thirty-fourth drop on June 8, 2001 (jfs-0.3.4-patch.tar.gz) included fixes to the
+file system and the utilities.
+
+The thirty-fifth drop on June 15, 2001 (jfs-0.3.5-patch.tar.gz) includes fixes to the
+file system and utilities.
+
+The thirty-sixth drop on June 22, 2001 (jfs-0.3.6-patch.tar.gz) includes fixes to the
+file system and utilities. The change made to the file system to fix the rm -rf problem
+is a disk layout change and with this change you must re-format all of the JFS partitions
+using the new mkfs.jfs included in this drop to have the rm -rf problem fixed.
+
+
+The thirty-seventh drop on June 25, 2001 (jfs-0.3.7-patch.tar.gz) includes fixes to the
+file system and utilities.
+
+The thirty-eighth drop on June 28, 2001 (jfs-1.0.0-patch.tar.gz) includes fixes to the
+file system and utilities.
+
+The thirty-ninth drop on July 10, 2001 (jfs-1.0.1-patch.tar.gz) includes fixes to the
+file system and utilities.
+
+The fortieth drop on August 3, 2001 (jfs-1.0.2-patch.tar.gz) includes fixes to the
+file system and utilities.
+
+The forty-first drop on August 20, 2001 (jfs-1.0.3-patch.tar.gz) includes fixes to the
+file system and utilities.
+
+
+The forty-second drop on August 31, 2001 (jfs-2.2-1.0.4-patch.tar.gz or
+jfs-2.4-1.0.4-patch.tar.gz) includes fixes to the file system and utilities.
+
+Drop 42 has the temporary restriction that the block size must be 4K. MKFS.jfs defaults
+the block size to 4K.
+
+
+JFS today:
+
+
+- Utilities:
+ Function in drop 1
+ - MKFS.JFS builds on 2.2.12
+ - MKFS successfully formats a new partition for JFS
+
+ Function and Fixes in drop 2
+ - MKFS supports all parameters now
+ - MKFS has fixes from release pre-alpha 0.0.1
+ mkfs.jfs results in segmentation fault if no arguments are specified
+ mkfs.jfs hangs on invocation
+
+ - XPEEK, utility to PEEK and POKE JFS on-disk data/structures
+
+ Function and Fixes in drop 5
+ - MKFS.jfs has a fix to support -l option correctly.
+
+ Function and Fixes in drop 6
+ - libfs has compiler warning fixes and a bug fix
+
+ Function in drop 8
+ - fsck.jfs successfully checks and repairs a jfs partition
+ - logdump, utility that dumps the contents of the journal log.
+
+ Function and Fixes in drop 9
+ - fixes for fsck.jfs and xpeek have been done.
+
+ Function and Fixes in drop 10
+ - fixes for fsck.jfs
+ - man pages for utilities
+ - extendfs utility part has been ported (still need to port FS portion)
+ - compiler warnings have been removed.
+
+ Function and Fixes in drop 11
+ - defrag utility part has been ported (still need to port FS portion)
+
+ Function and Fixes in drop 13
+ - fsck.jfs supports block special files and character special files (Jitterbug problem #28)
+
+ Function and Fixes in drop 15
+ - ported xchklog utility, extracts a log from fsck.
+
+ Function and Fixes in drop 16
+ - fixes for fsck.jfs to handle case-sensitive support correctly (Jitterbug problem #36)
+ - cleanup changes for the utilities
+
+ Function and Fixes in drop 18
+ - cleanup changes for the utilities
+
+ Function and Fixes in drop 21
+ - fix in fsck to handle sparse files correctly
+
+ Function and Fixes in drop 23
+ - fix in fsck to handle fifo correctly
+
+ Function and Fixes in drop 24
+ - man pages updates for the utilities
+ - install option for utilities
+
+ Function and Fixes in drop 26
+ - man page updates for fsck
+ - fsck now supports default options passed by fstab correctly
+
+ Function and Fixes in drop 27
+ - new jfsprogs.spec file
+ - fix in fsck for hard links
+ - fix for unicode conversion problem
+
+ Function and Fixes in drop 29
+ - cleanup changes for the utilities
+ - Code cleanup to use standard types
+
+ Function and Fixes in drop 30
+ - added endian macros support
+ - Code cleanup to use standard types (part 2)
+ - mkfs now clears out the 1st 4k bytes of the partition
+
+ Function and Fixes in drop 31
+ - completed endian macros support needed for xpeek
+ - added socket support for fsck
+ - minor bug fixes
+
+ Function and Fixes in drop 32
+ - Remove the warning message from fsck when partition is mounted read-only
+
+ Function and Fixes in drop 33
+ - Fix fsck to handle mount read-only correctly
+ - Fix top level utilities makefile to be able to easily overide version of gcc compiler
+ - Man pages are now available in html format
+
+ Function and Fixes in drop 34
+ - fsck fix to handle pre-existing lost+found sub dir
+
+ Function and Fixes in drop 35
+ - updated fsck error handling
+ - updated mkfs config options and the man page for fsck
+
+ Function and Fixes in drop 36
+ - Fixed jitterbug # 10 rm -rf fails on a big directory
+
+ Function and Fixes in drop 38
+ - Fixed small logredo problem
+
+ Function and Fixes in drop 39 (1.0.1)
+ - Updated jfsprogs.spec file make it work on more distros
+ - Add force option to mkfs so the confirmation message isn't displayed
+ - Fixed fsck to handle index table on the root directory.
+ - Fixed error message displayed when partition was just created and haven't rebooted (jitterbug 130)
+ - Correctly place the built utilities in /sbin vs. /usr/sbin when using the make install
+ option.
+
+ Note: If you have used the make install option to copy over the utilities from a
+ previous release then you should remove the following JFS utilities (fsck.jfs, logdump,
+ logredo, mkfs.jfs, xchkdmp, xchklog, and xpeek) that could be in /usr/sbin. This release
+ of make install places the utilities in the correct location which is /sbin.
+
+ Function and Fixes in drop 40 (1.0.2)
+ - Fixed mkfs to display the correct error message if device name is not valid
+ or missing
+ - gzip the man pages and place /usr/share/man/man8
+ - Fixed mkfs to properly setup buf_ai (caused Bus error with mkfs on SPARC Linux)
+ - Fixed fsck to display path correctly
+
+ Function and Fixes in drop 41 (1.0.3)
+ - Fixed compiler warnings on 64 bit systems
+ - Created jfsutils package
+
+ Function and Fixes in drop 42 (1.0.4)
+ - Fixed typecast problem causing intermittent fsck failures on 64 bit hardware (jitterbug 159)
+ - Fixed pointer calculation problem causing intermittent fsck failures on 64 bit hardware
+ - Fixed compiler warnings on s/390 and IA64
+ - Fixed structure size mismatch between file system and utilities causing fsck problems when
+ large numbers of inodes are used
+ - Fixed seg fault in fsck when logging path lengths greater than 512 characters
+ - Fixed fsck printf format errors
+
+
+- JFS:
+ Function in drop 1
+ - builds on 2.2.12
+ - successfully MOUNTs & UMOUNTs
+ - limited READ capability (i.e. LS is operational)
+ - other system commands (i.e. DF, CHOWN, CHMOD, etc. working limited)
+
+ Function and Fixes in drop 2
+ - Write capabilities are operational
+ - MKDIR
+ - CREATE file
+ - RMDIR
+ - RM
+ - Problems fixed from release pre-alpha 0.0.1
+ using 2.2.14 jfs_imap.c:3004: `event' undeclared (first use in this function)
+
+ Function and Fixes in drop 3
+ - WRITE a file
+ - READ a file
+ - Support for hard and soft links
+
+ Function and Fixes in drop 4
+ - MV
+ - Executables can now be started from a jfs partition
+ - Problems while writing files have been fixed
+
+ Function and Fixes in drop 5
+ - added support for special files (mknod)
+ - alpha changes have been included
+
+ Function and Fixes in drop 6
+ - Jitterbug problem 9 du output is incorrect on jfs
+ - Jitterbug problem 11 unresolved symbol jfs_rwlock_lock on SMP build
+
+ Function and Fixes in drop 7
+ - moved JFS upto the 2.3.x development kernel (2.3.99-pre6)
+ - Jitterbug problem 14 can't build JFS within the kernel
+
+ Function and Fixes in drop 8
+ - moved JFS upto the 2.4.0 development kernel (2.4.0-test1-ac21)
+ - Jitterbug problem 17 undefined: jfs_rdwrlock_lock
+ - PowerPC build problem
+
+ Function and Fixes in drop 9
+ - moved JFS upto the 2.4.0 development kernel (2.4.0-test3)
+ - moved meta-data from buffer cache to page cache
+ - fixes for the file system are included
+
+ Function and Fixes in drop 10
+ - moved JFS upto the 2.4.0 development kernel (2.4.0-test5)
+ - fixes for the file system are included
+
+ Function and Fixes in drop 11
+ - moved JFS upto the 2.4.0 development kernel (2.4.0-test7)
+ - fixes for the file system are included
+ - start of journaling code has been included (jfs_txnmgr.h)
+ - WIP of log manager (jfs_logmgr.c)
+
+ Function and Fixes in drop 12
+ - Transaction Manager Log I/O -> Write log records is functional
+
+ Function and Fixes in drop 13
+ - case-sensitive support has been added
+
+ Function and Fixes in drop 14
+ - JFS mount error 22 is fixed (Jitterbug problem #30)
+
+ Function and Fixes in drop 15
+ - Following Transaction Manager routines are functional
+ Initialize -> Initialize transaction manager
+ Begin -> Start a transaction
+ Locks -> Acquire/release locks
+ End -> End a transaction
+ - moved JFS upto the 2.4.0 development kernel (2.4.0-test9)
+ - Fixed 2.2.x series block write problem.
+
+ Function and Fixes in drop 16
+ - Following Transaction Manager routines are functional
+ Commit -> Commit the transaction
+ Buffer Management -> Update inode, directory, extent
+ Abort -> Stop the commit from occurring
+ - File System build problem on 2.2.x series of the kernel (Jitterbug #35)
+ - Fixed case-sensitive bug in the filesystem (Jitterbug #36)
+
+
+ Function and Fixes in drop 17
+ - Added transaction sub operations back into the file system operations.
+ - The file system is now journaling appropriate file system operations.
+ - moved JFS upto the 2.4.0 development kernel (2.4.0-test10)
+
+ Function and Fixes in drop 18
+ - symlink fix
+ - inode corruption problem
+
+ Function and Fixes in drop 19
+ - Added asynchronous logging support back into the file system.
+ - moved JFS upto the 2.4.0 development kernel (2.4.0-test11)
+ - Fixes to transaction related hang problems.
+
+ Function and Fixes in drop 20
+ - Fix to remove memory on module cleanup
+
+ Function and Fixes in drop 21
+ - Fix so fsck doesn't report the message
+ Secondary file/directory allocation structure(2) is not a correct redundant copy of primary structure.
+ - Fix for setup of finish_aync_io
+ - moved JFS upto the 2.4.0 development kernel (2.4.0-test12)
+ - moved JFS upto the 2.2.18 kernel
+
+ Function and Fixes in drop 22
+
+ - moved JFS upto the 2.4.0 kernel
+ - Fix to do transaction processing for mknod correctly
+ - Fix for spinlock.h needed on 2.2.18 ppc
+
+ Function and Fixes in drop 23
+ - Fix for undefined BUG() in 2.2.x series
+ - Fix for 2.2 kernels, struct pipe_inode_info overlays the file system dependent portion of the inode structure.
+
+ Function and Fixes in drop 24
+ - rmmod jfs fix
+ - Implemented "Lazy Commit" - asynchronous logging enhancement to increase performance
+ - Removed ino_t from on-disk structures (fixes a mount problem)
+
+ Function and Fixes in drop 25
+ - Fix for deadlocks by putting IWRITE_LOCK/UNLOCK within jfs_delete_inode
+ - Fix to handle removing a link to an inode that isn't the last link.
+ - Fixes to general transaction processing SMP related hangs.
+
+ Function and Fixes in drop 26
+ - Fix for file writes on 2.2.x series of the kernel
+ - Change to log pages, so they no longer use the page cache.
+ - Fixes to general transaction processing SMP related dead-lock problems
+
+ Function and Fixes in drop 27
+ - Report error on read_metapage failure in jfs_readlink
+ - Report correct error in jfs_lookup if VFS fails to locate the inode
+ - Fix for a buffer overrun problem in jfs_readlink when compiled for linux-2.2
+ - Fix to support fsync call correctly (jitterbug #57)
+ - Fixes to general SMP related dead-lock problems
+ - Fix to define BUG() if 2.2 and !i386
+ - Fixes to general UP related hangs
+ - Changes to handling the inode extent cache increase the performance of the file system
+
+ Function and Fixes in drop 28
+ - Added ifdef IS_KIOBUFIO so JFS will be if kiobufs is in the kernel. Kiobufs has changed
+ the # of parameters for generic_make_request()
+ - Make jfsFYI a module parameter
+ insmod jfs.o jfsFYI=1 will turn on JFS FYI messages without having to recompile this
+ option is only supported on the 2.4.x kernel level.
+ - Defines cleanup_module() in terms of exit_jfs_fs()
+ - Fix to jfs_read_super, if get_empty_inode returns NULL cleanup correctly
+ - Code cleanup to use standard types
+
+
+ Function and Fixes in drop 29
+ - Fix for assert(iagp->wmap[extno] & mask); (line #2875) in jfs_imap while running dbench
+ - Fixed hang on scsi
+ - added /proc/fs/jfs/jfsFYI (2.4.* kernels only)
+ echo 1 > /proc/fs/jfs/jfsFYI ; Turns on very verbose output to syslog
+ echo 0 > /proc/fs/jfs/jfsFYI ; Turns it back off
+
+ Notes:
+ - IMPORTANT: If building jfs.o as a module on 2.2.* kernels, you will have to rebuild and
+ install the kernel to add wake_up_process to ksyms.c. Not needed on 2.4.* kernels.
+
+ Function and Fixes in drop 30
+ - Added endian macros support
+ - Fixed dbench hang
+ - jfs fails SPEC SFS validation on both NFSv2/NFSv3, fix to not add null-terminator to the symlink
+ value and accounting for it in the size.
+ - Fixed a bug where a casting of a 32 bit block # wasn't correct when a 64 bit value is needed.
+ xtLookup messages where display in the /var/log/messages (i.e of a message is below)
+ xtLookup: lstart (0x80000) >= size (0x80000)
+
+ Notes: release 0.3.0 requires a re-format of the JFS partition, if the system architecture is
+ big-endian (i.e. s/390, PowerPC, etc.)
+
+ Function and Fixes in drop 31
+ - Removed max hard links check (showed up during cp -a /usr /jfs/usr)
+ - Fixed inode writing hang could have showed up running (dbench, iozone, etc),
+ the change was to prevent a deadlock during inode writing.
+
+ Function and Fixes in drop 32
+ - Fix for assert(mp->count) jfs_metapage.c 675! report as hardlink problem in drop 31 (dtDeleteUp
+ was discarding the wrong metapage_t.
+ - Fix seg fault problem while creating hard links.
+ - Fixed dbench hang do to transaction locks not being freed.
+ - Added support to correctly handle read-only and remounting the file system.
+
+ Function and Fixes in drop 33
+
+ - Fixed statfs call to return the maximum number of inodes that JFS could allocate. (problem
+ reported as rpm exits with a (x) inodes needed message without installing the package).
+ - Fix to handle a case where a inode wasn't getting written to disk.
+ - Increase the performance of unlinking files.
+ - Fix to null terminate symlinks.
+ - General SMP fixes.
+
+ Function and Fixes in drop 34
+
+ - Fixed to remove a hang waiting on inode (jitterbug #73)
+ - Fixed dbench hang on SMP 8-way
+ - Fixed a log sync problem, improved performance with this fix
+
+ Function and Fixes in drop 35
+ - Increase the performance of unlinking files, most unlinks are done asynchronously now
+ - Fixed "XT_GETPAGE: xtree page corrupt" during creating files on nfs mounted partition
+
+ Function and Fixes in drop 36
+ - Fixed jitterbug # 10 rm -rf fails on a big directory
+
+ Notes: release 0.3.6 requires a re-format of the JFS partition, for the rm -rf problem
+ to be fixed.
+
+ Function and Fixes in drop 37
+ - Fixed find_entry called with index = 0 or 1 (jitterbug #126)
+ - Fixed the rm -rf case where if files weren't created sequential
+ then the rm -rf wasn't working correctly
+
+
+ Notes: If you used release 0.3.6 please re-format all JFS partitions, for the rm -rf problem
+ to be fixed.
+
+ Function and Fixes in drop 38
+ - Fixed some general log problems
+
+ Function and Fixes in drop 39 (1.0.1)
+ - Fixed hang during copying files on 2.2.x series
+ - Fixed TxLock compile problem
+ - Fixed to correctly update the number of blocks for directories (this was causing the FS
+ to show fsck error after compiling mozilla).
+ - Fixed to prevent old data from being written to disk from the page cache.
+
+ Function and Fixes in drop40 (1.0.2)
+ - Fixed multiple truncate hang
+ - Fixed hang on unlink a file and sync happening at the same time
+ - Improved handling of kmalloc error conditions
+ - Fixed hang in blk_get_queue and SMP deadlock: bh_end_io call generic_make_request
+ (jitterbug 145 and 146)
+ - stbl was not set correctly set in dtDelete
+ - changed trap to printk in dbAllocAG to avoid system hang
+
+ Function and Fixes in drop41 (1.0.3)
+ - Patch to move from previous release to latest release needs to update the version number in super.c
+ - Jitterbug problems (134,140,152) removing files have been fixed
+ - Set rc=ENOSPC if ialloc fails in jfs_create and jfs_mkdir
+ - Fixed jfs_txnmgr.c 775! assert
+ - Fixed jfs_txnmgr.c 884! assert(mp->nohomeok==0)
+ - Fix hang - prevent tblocks from being exhausted
+ - Fix oops trying to mount reiserfs
+ - Fail more gracefully in jfs_imap.c
+ - Print more information when char2uni fails
+ - Fix timing problem between Block map and metapage cache - jitterbug 139
+ - Code Cleanup (removed many ifdef's, obsolete code, ran code through indent) Mostly 2.4 tree
+ - Split source tree (Now have a separate source tree for 2.2, 2.4, and jfsutils)
+
+ Function and Fixes in drop42 (1.0.4)
+ - Fixed compiler warnings in the FS when building on 64 bits systems
+ - Fixed deadlock where jfsCommit hung in hold_metapage
+ - Fixed problems with remount
+ - Reserve metapages for jfsCommit thread
+ - Get rid of buggy invalidate_metapage & use discard_metapage
+ - Don't hand metapages to jfsIOthread (too many context switches) (jitterbug 125, bugzilla 238)
+ - Fix error message in jfs_strtoUCS
+
+
+Please send bugs, comments, cards and letters to linuxjfs@us.ibm.com.
+
+The JFS mailing list can be subscribed to by using the link labeled "Mail list Subscribe"
+at our web page http://oss.software.ibm.com/jfs/.
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/Documentation/filesystems/jfs.txt linuxppc64_2_4/Documentation/filesystems/jfs.txt
--- ../tue/linux-2.4.10-ac12/Documentation/filesystems/jfs.txt Wed Dec 31 18:00:00 1969
+++ linuxppc64_2_4/Documentation/filesystems/jfs.txt Thu Sep 13 14:29:38 2001
@@ -0,0 +1,153 @@
+IBM's Journaled File System (JFS) for Linux version 1.0.4
+Team members
+Steve Best sbest@us.ibm.com
+Dave Kleikamp shaggy@us.ibm.com
+Barry Arndt barndt@us.ibm.com
+
+
+Release August 31, 2001 (version 1.0.4)
+
+This is our forty-second release of IBM's Enterprise JFS technology port to Linux.
+Beta 1 was release 0.1.0 on 12/8/2000, Beta 2 was release 0.2.0 on 3/7/2001,
+Beta 3 was release 0.3.0 on 4/30/2001, and release 1.0.0 on 6/28/2001.
+
+The changelog.jfs file contains detailed information of changes done in each source
+code drop.
+
+JFS has a source tree that can be built on 2.2.14 - 2.2.19 and 2.4.0 - 2.4.9
+kernel.org source trees.
+
+There is a anonymous cvs access available for the JFS tree. The steps below are
+what is needed to pull the JFS cvs tree from the oss.software.ibm.com server.
+
+id anoncvs
+password anoncvs
+
+To checkout 2.2.x series of the JFS files do the following:
+CVSROOT should be set to :pserver:anoncvs@oss.software.ibm.com:/usr/cvs/jfs
+cvs checkout linux-2.2.12
+
+To checkout 2.4.x series of the JFS files do the following:
+CVSROOT should be set to :pserver:anoncvs@oss.software.ibm.com:/usr/cvs/jfs
+cvs checkout linux24
+
+To checkout the JFS utilities do the following:
+CVSROOT should be set to :pserver:anoncvs@oss.software.ibm.com:/usr/cvs/jfs
+cvs checkout jfsutils
+
+The jfs-2.4-1.0.4-patch.tar.gz file contains a readme and patch files for different
+levels of the 2.4 kernel. Please see the README in the jfs-2.4-1.0.4-patch.tar.gz
+file for help on applying the two patch files.
+
+Similarly jfs-2.2-1.0.4-patch.tar.gz contains a readme and patch files for
+different levels of the 2.2 kernel.
+
+The following files in the kernel source tree have been changed so JFS can be built.
+The jfs-2.4-1.0.4.tar.gz source tar ball now contains each of the files below with
+the extension of the kernel level it is associated with. As an example, there are now
+three Config.in files named Config.in-2.4.0, Config.in-2.4.5, and Config.in-2.4.7.
+
+Similarly, the jfs-2.2-1.0.4.tar.gz source tar ball contains the files
+Config.in-2.2.14, Config.in-2.2.16, and Config.in-2.2.18.
+
+If you use the tar ball to build JFS you must rename each of the kernel files to the
+file names listed below. The standard kernel from www.kernel.org is the source of the
+kernel files that are included in the jfs tar files.
+
+In sub dir fs Config.in, Makefile, filesystem.c
+In sub dir fs/nls Config.in
+In sub dir arch/i386 defconfig
+In sub dir Documentation Configure.help
+In sub dir Documentation/filesystems 00-INDEX
+In sub dir include/linux fs.h
+In sub dir linux MAINTAINERS
+In sub dir linux/kernel/ksyms.c
+
+Please backup the above files before the JFS patch file is added to the kernel source
+tree. There are three new header files in the sub dir include/linux named jfs_fs.h,
+jfs_fs_i.h,and jfs_fs_sb.h. All other JFS files are located in the include/linux/jfs
+or fs/jfs sub dirs.
+
+Our development team has used the Linux kernel levels 2.2.14-2.2.19 and
+2.4.0 - 2.4.9 kernels with gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
+for our port so far. A goal of the JFS team is to have JFS run on all architectures
+that Linux supports, there is no architecture specific code in JFS. JFS has been run
+on the following architectures (x86, PowerPC, Alpha, s/390, ARM) so far.
+
+To make JFS build, during the "make config" step of building the kernel answer y to
+the Prompt for development and/or incomplete code/drivers in the Code maturity level
+options section. In the Filesystems section use the m for the answer to
+JFS filesystem support (experimental) (CONFIG_JFS_FS) [Y/m/n?]
+
+Note: If you are use JFS as module on the 2.2.x series of the kernel you must rebuild
+the kernel and run that rebuilt kernel for JFS to run. The reason for this change is
+that JFS needs to export symbols.
+
+Build in /usr/src/linux with the command:
+
+
+make modules
+make modules_install
+
+If you rebuild jfs.o after having mounted and unmounted a partition, "modprobe -r jfs"
+will unload the old module.
+
+For the file system debugging messages are being written to /var/log/messages.
+
+There are two ways to the build the JFS utilities, the first using the jfsprogs.spec
+file and the second way is to run make and then make install in the
+/jfsutils sub dir.
+
+To use the jfsprogs.spec located in sub dir jfsutils/SPECS you need to update
+the version of JFS in the spec file, also the corresponding jfs-x.x.x-patch.tar.gz file
+must be in the SOURCES directory of your system. Now it's time to begin the build. First,
+change into the directory holding jfsprogs.spec file:
+
+cd /jfsutils/SPECS
+
+Next, start the build with a rpm -b command:
+
+rpm -ba jfsprogs.spec
+
+The a following the -b option directs RPM to perform all phases of the build process.
+
+
+The second way to build the utilities for JFS (mkfs, xpeek, logredo, xchkdmp, fsck, logdump, xchklog).
+
+Build in /jfsutils with the command:
+
+make
+make install
+
+One of results of this build is a program called mkfs.jfs.
+To format a JFS partition use the following command.
+
+ mkfs -t jfs device-name
+
+will result in the specified device being formatted.
+
+
+
+JFS TODO list:
+
+Plans for our near term development items
+
+ - Fix for 2.2.* SMP kernel hangs
+ - get defrag capabilities operational in the FS
+ - get extendfs capabilities operational in the FS
+ - test EXTENDFS utility, for growing JFS partitions
+ - test defrag utility, calls file system to defrag the file system.
+ - add support for block sizes (512,1024,2048)
+ - add support for logfile on dedicated partition
+
+
+Longer term work items
+
+ - get access control list functionality operational
+ - get extended attributes functionality operational
+ - add quota support
+
+Please send bugs, comments, cards and letters to linuxjfs@us.ibm.com.
+
+The JFS mailing list can be subscribed to by using the link labeled "Mail list Subscribe"
+at our web page http://oss.software.ibm.com/jfs/.
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/Documentation/video4linux/README.buz linuxppc64_2_4/Documentation/video4linux/README.buz
--- ../tue/linux-2.4.10-ac12/Documentation/video4linux/README.buz Wed Dec 31 18:00:00 1969
+++ linuxppc64_2_4/Documentation/video4linux/README.buz Fri May 4 17:14:03 2001
@@ -0,0 +1,212 @@
+Iomega Buz Driver for Linux
+===========================
+
+by Rainer Johanni
+
+Compiling and Loading the Driver
+================================
+
+You must run a 2.2.x kernel in order to use this driver.
+
+To compile the driver, just type make.
+
+Besides the files in this directory, the driver needs the
+'videodev' and the 'i2c' module from the Linux kernel.
+In order to get these modules available, enable module support
+for VIDEODEV and BTTV (which implies i2c) in your kernel
+configuration. You find these devices in the menu
+"Character Devices" in your Kernel Configuration.
+
+Before you load the driver you must have a video device
+at major device node 81. If you don't have it yet, do the
+following (as root!):
+
+cd /dev
+mknod video0 c 81 0
+ln -s video0 video
+
+Edit the 'update' script if you want to give the driver
+special options and then type (as root)
+
+./update
+
+to insert all the necessary modules into the kernel.
+
+If you want to make full use of the Video for Linux uncompressed
+grabbing facilities, you must either
+
+- obtain and install the "big_physarea patch" for your kernel and
+ set aside the necessary memory during boot time.
+ There seem to be several versions of this patch against
+ various kernel versions floating around in the net,
+ you may obtain one e.g. from:
+ http://www.polyware.nl/~middelin/patch/bigphysarea-2.2.1.tar.gz
+ You also have to compile your driver AFTER installing that patch
+ in order to get it working
+
+ or
+
+- start your kernel with the mem=xxx option, where xxx is your
+ real memory minus the memory needed for the buffers.
+ For doing this add an entry in lilo.conf (if you use lilo):
+ append "mem=xxxM"
+ or add a line in your linux.par file (if you use loadlin):
+ mem=xxxM
+
+The second method is by far easier, however it is dangerous
+if more than one driver at a time has the idea to use the memory
+leftover by setting the mem=xxx parameter below the actual
+memory size.
+
+Read also below how to use this memory!
+
+
+
+Driver Options
+==============
+
+You are able to customize the behavior of the driver by giving
+it some options at start time.
+
+default_input, default_norm
+---------------------------
+
+As soon as the driver is loaded, the Buz samples video signals
+from one of its input ports and displays it on its output.
+The driver uses the Composite Input and the video norm PAL for this.
+If you want to change this default behavior, set default_input=1
+(for S-VHS input) or default_norm=1 for NTSC.
+
+v4l_nbufs, v4l_bufsize
+----------------------
+
+In order to make to make full use of the Video for Linux picture
+grabbing facilities of the driver (which are needed by many
+Video for Linux applications), the driver needs a set of
+physically contiguous buffers for grabbing. These parameters
+determine how many buffers of which size the driver will
+allocate at open (the open will fail if it is unable to do so!).
+
+These values do not affect the MJPEG grabbing facilities of the driver,
+they are needed for uncompressed image grabbing only!!!
+
+v4l_nbufs is the number of buffers to allocate, a value of 2 (the default)
+should be sufficient in almost all cases. Only special applications
+(streaming captures) will need more buffers and then mostly the
+MJPEG capturing features of the Buz will be more appropriate.
+So leave this parameter at it's default unless you know what you do.
+
+The things for v4l_bufsize are more complicated:
+v4l_bufsize is set by default to 128 [KB] which is the maximum
+amount of physically contiguous memory Linux is able to allocate
+without kernel changes. This is sufficient for grabbing 24 bit color images
+up to sizes of approx. 240x180 pixels (240*180*3 = 129600, 128 KB = 131072).
+
+In order to be able to capture bigger images you have either to
+- obtain and install the "big_physarea patch" and set aside
+ the necessary memory during boot time or
+- start your kernel with the mem=xxx option, where xxx is your
+ real memory minus the memory needed for the buffers.
+In that case, useful settings for v4l_bufsize are
+- 1296 [Kb] for grabbing 24 bit images of max size 768*576
+- 1728 [Kb] for 32bit images of same size (4*768*576 = 1728 Kb!)
+You may reduce these numbers accordingly if you know you are only
+grabbing 720 pixels wide images or NTSC images (max height 480).
+
+In some cases it may happen that Linux isn't even able to obtain
+the default 128 KB buffers. If you don't need uncompressed image
+grabbing at all, set v4l_bufsize to an arbitrary small value (e.g. 4)
+in order to be able to open the video device.
+
+vidmem
+------
+
+The video mem address of the video card.
+The driver has a little database for some videocards
+to determine it from there. If your video card is not in there
+you have either to give it to the driver as a parameter
+or set in in a VIDIOCSFBUF ioctl
+
+The videocard database is contained in the file "videocards.h"
+Gernot Ziegler wants to keep an actual version of that file.
+If your card is not contained in that file, look at
+http://www.lysator.liu.se/~gz/buz/ for an actual version of
+"videocards.h".
+
+triton, natoma
+--------------
+
+The driver tries to detect if you have a triton or natome chipset
+in order to take special measures for these chipsets.
+If this detection fails but you are sure you have such a chipset,
+set the corresponding variable to 1.
+This is a very special option and may go away in the future.
+
+
+
+Programming interface
+=====================
+
+This driver should be fully compliant to Video for Linux, so all
+tools working with Video for Linux should work with (hopefully)
+no problems.
+
+A description of the Video for Linux programming interface can be found at:
+http://roadrunner.swansea.linux.org.uk/v4lapi.shtml
+
+Besides the Video for Linux interface, the driver has a "proprietary"
+interface for accessing the Buz's MJPEG capture and playback facilities.
+
+The ioctls for that interface are as follows:
+
+BUZIOC_G_PARAMS
+BUZIOC_S_PARAMS
+
+Get and set the parameters of the buz. The user should always
+do a BUZIOC_G_PARAMS (with a struct buz_params) to obtain the default
+settings, change what he likes and then make a BUZIOC_S_PARAMS call.
+A typical application should at least set the members
+input, norm and decimation of the struct buz_params.
+For a full description of all members see "buz.h"
+
+BUZIOC_REQBUFS
+
+Before being able to capture/playback, the user has to request
+the buffers he is wanting to use. Fill the structure
+buz_requestbuffers with the size (recommended: 256*1024) and
+the number (recommended 32 up to 256). There are no such restrictions
+as for the Video for Linux buffers, you should LEAVE SUFFICIENT
+MEMORY for your system however, else strange things will happen ....
+On return, the buz_requestbuffers structure contains number and
+size of the actually allocated buffers.
+You should use these numbers for doing a mmap of the buffers
+into the user space.
+The BUZIOC_REQBUFS ioctl also makes it happen, that the next mmap
+maps the MJPEG buffer instead of the V4L buffers.
+
+BUZIOC_QBUF_CAPT
+BUZIOC_QBUF_PLAY
+
+Queue a buffer for capture or playback. The first call also starts
+streaming capture. When streaming capture is going on, you may
+only queue further buffers or issue syncs until streaming
+capture is switched off again with a argument of -1 to
+a BUZIOC_QBUF_CAPT/BUZIOC_QBUF_PLAY ioctl.
+
+BUZIOC_SYNC
+
+Issue this ioctl when all buffers are queued. This ioctl will
+block until the first buffer becomes free for saving its
+data to disk (after BUZIOC_QBUF_CAPT) or for reuse (after BUZIOC_QBUF_PLAY).
+
+BUZIOC_G_STATUS
+
+Get the status of the input lines (video source connected/norm).
+This ioctl may be subject to change.
+
+
+
+
+
+See the examples directory delivered with this driver
+for actual coding examples!
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/MAINTAINERS linuxppc64_2_4/MAINTAINERS
--- ../tue/linux-2.4.10-ac12/MAINTAINERS Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/MAINTAINERS Wed Oct 10 14:03:02 2001
@@ -802,6 +802,13 @@
W: http://sources.redhat.com/jffs2/
S: Maintained
+JFS FILESYSTEM
+P: Dave Kleikamp
+M: shaggy@austin.ibm.com
+L: jfs-discussion@oss.software.ibm.com
+W: http://oss.software.ibm.com/developerworks/opensource/jfs/
+S: Supported
+
JOYSTICK DRIVER
P: Vojtech Pavlik
M: vojtech@suse.cz
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/Makefile linuxppc64_2_4/Makefile
--- ../tue/linux-2.4.10-ac12/Makefile Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/Makefile Fri Oct 12 11:00:43 2001
@@ -10,11 +10,13 @@
# SUBARCH tells the usermode build what the underlying arch is. That is set
# first, and if a usermode build is happening, the "ARCH=um" on the command
# line overrides the setting of ARCH below. If a native build is happening,
-# then ARCH is assigned, getting whatever value it gets normally, and
+# then ARCH is assigned, getting whatever value it gets normally, and
# SUBARCH is subsequently ignored.
SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
-ARCH := $(SUBARCH)
+#ARCH := $(SUBARCH)
+
+ARCH := ppc64
CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
else if [ -x /bin/bash ]; then echo /bin/bash; \
@@ -27,7 +29,7 @@
HOSTCC = gcc
HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
-CROSS_COMPILE =
+CROSS_COMPILE = /usr/local/ppc64-current3.0/bin/powerpc64-linux-
#
# Include the make variables (CC, etc...)
@@ -97,7 +99,7 @@
CPPFLAGS := -D__KERNEL__ -I$(HPATH)
CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \
- -fomit-frame-pointer -fno-strict-aliasing -fno-common
+ -fomit-frame-pointer -fno-strict-aliasing -fno-common
AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS)
#
@@ -160,6 +162,7 @@
DRIVERS-$(CONFIG_SCSI) += drivers/scsi/scsidrv.o
DRIVERS-$(CONFIG_FUSION_BOOT) += drivers/message/fusion/fusion.o
DRIVERS-$(CONFIG_IEEE1394) += drivers/ieee1394/ieee1394drv.o
+DRIVERS-$(CONFIG_PPC_ISERIES) += drivers/iseries/iseries.o
ifneq ($(CONFIG_CD_NO_IDESCSI)$(CONFIG_BLK_DEV_IDECD)$(CONFIG_BLK_DEV_SR)$(CONFIG_PARIDE_PCD),)
DRIVERS-y += drivers/cdrom/driver.o
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/i386/defconfig linuxppc64_2_4/arch/i386/defconfig
--- ../tue/linux-2.4.10-ac12/arch/i386/defconfig Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/i386/defconfig Wed Oct 10 13:56:51 2001
@@ -607,6 +607,7 @@
# CONFIG_RAMFS is not set
CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
+# CONFIG_JFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_NTFS_FS is not set
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/Makefile linuxppc64_2_4/arch/ppc64/Makefile
--- ../tue/linux-2.4.10-ac12/arch/ppc64/Makefile Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/Makefile Thu Oct 11 09:06:59 2001
@@ -21,14 +21,22 @@
ASFLAGS =
LINKFLAGS = -T arch/ppc64/vmlinux.lds -Ttext $(KERNELLOAD) -Bstatic
-CPPFLAGS := $(CPPFLAGS) -D__powerpc__ -include $(TOPDIR)/arch/ppc64/mymacros.h
-CFLAGS := $(CFLAGS) -D__linux__ -D__powerpc__ -fsigned-char -Wa,-Saix \
+CPPFLAGS := $(CPPFLAGS) -D__powerpc__
+CFLAGS := $(CFLAGS) -D__linux__ -D__powerpc__ -fsigned-char \
-msoft-float -pipe -Wno-uninitialized $(PRINTK) \
- -include $(TOPDIR)/arch/ppc64/mymacros.h -mminimal-toc \
- -fno-builtin
+ -mminimal-toc -fno-builtin
CPP = $(CC) -E $(CFLAGS)
+# For 64-bit apps, temporarily reduce the size of the address space
+# available to user application. This allow us to use strace without
+# having to compile a strace64 program. This shouldn't affect anyone
+# other than Steve Munroe, Peter Bergner. I will back this hack out
+# later... -Peter
+#CPPFLAGS := $(CPPFLAGS) -DPPC64_32B_ADDR_SPACE
+#CFLAGS := $(CFLAGS) -DPPC64_32B_ADDR_SPACE
+
+
HEAD := arch/ppc64/kernel/head.o
ARCH_SUBDIRS = arch/ppc64/kernel arch/ppc64/mm arch/ppc64/lib
@@ -53,29 +61,21 @@
BOOT_TARGETS = zImage znetboot.initrd zImage.initrd
ifdef CONFIG_PPC_PSERIES
-$(BOOT_TARGETS): $(CHECKS) vmlinux
+$(BOOT_TARGETS): vmlinux
@$(MAKEBOOT) $@
-znetboot: $(CHECKS) vmlinux
-ifdef CONFIG_ALL_PPC
+znetboot: vmlinux
ifdef CONFIG_SMP
cp -f vmlinux /tftpboot/vmlinux.smp
else
- cp -f vmlinux /tftpboot/vmlinux.smp.64
-endif
+ cp -f vmlinux /tftpboot/vmlinux
endif
@$(MAKEBOOT) $@
endif
-.PHONY: clean_config
-clean_config:
+%_config: arch/ppc64/configs/%_defconfig
rm -f .config arch/ppc64/defconfig
-
-chrp_config: clean_config
- cp -f arch/ppc64/configs/chrp_defconfig arch/ppc64/defconfig
-
-common_config: clean_config
- cp -f arch/ppc64/configs/common_defconfig arch/ppc64/defconfig
+ cp -f arch/ppc64/configs/$(@:config=defconfig) arch/ppc64/defconfig
archclean:
rm -f arch/ppc64/kernel/{ppc_defs.h,checks,mk_defs.s,mk_defs_out.c,mk_defs_tpl}
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/boot/Makefile linuxppc64_2_4/arch/ppc64/boot/Makefile
--- ../tue/linux-2.4.10-ac12/arch/ppc64/boot/Makefile Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/boot/Makefile Tue Oct 16 14:56:18 2001
@@ -16,11 +16,17 @@
# compiling from an intel box. Once the 64bit ppc gcc is
# stable it will probably simply be a compiler switch to
# compile for 32bit mode.
+# To make it easier to setup a cross compiler,
+# CROSS32_COMPILE is setup as a prefix just like CROSS_COMPILE
+# in the toplevel makefile.
-BOOTCC = $(HOSTCC)
+CROSS32_COMPILE =
+#CROSS32_COMPILE = /usr/local/ppc/bin/powerpc-linux-
+
+BOOTCC = $(CROSS32_COMPILE)gcc
BOOTCFLAGS = $(HOSTCFLAGS) -I$(HPATH)
-BOOTLD = ld
-BOOTAS = as
+BOOTLD = $(CROSS32_COMPILE)ld
+BOOTAS = $(CROSS32_COMPILE)as
BOOTAFLAGS = -D__ASSEMBLY__ $(HOSTCFLAGS)
.c.o:
@@ -29,7 +35,7 @@
$(BOOTCC) $(BOOTAFLAGS) -traditional -c -o $*.o $<
CFLAGS = $(CPPFLAGS) -O -fno-builtin -DSTDC_HEADERS
-LD_ARGS = -Ttext 0x00400000
+LD_ARGS = -Ttext 0x00400000 -e _start
OBJS = crt0.o start.o main.o zlib.o image.o imagesize.o
#LIBS = $(TOPDIR)/lib/lib.a
@@ -41,11 +47,39 @@
TFTPIMAGE=/tftpboot/zImage.chrp
endif
+
+ifeq ($(CONFIG_PPC_ISERIES),y)
+all: vmlinux.sm
+else
all: $(TOPDIR)/zImage
+endif
+
znetboot: zImage
cp zImage $(TFTPIMAGE)
+
+ifeq ($(CONFIG_PPC_ISERIES),y)
+
+addSystemMap: addSystemMap.c
+ $(HOSTCC) $(HOSTCFLAGS) -o addSystemMap addSystemMap.c
+
+vmlinux.sm: $(TOPDIR)/vmlinux addSystemMap
+ ./addSystemMap $(TOPDIR)/System.map $(TOPDIR)/vmlinux vmlinux.sm
+
+
+addRamDisk: addRamDisk.c
+ $(HOSTCC) $(HOSTCFLAGS) -o addRamDisk addRamDisk.c
+
+vmlinux.initrd: $(TOPDIR)/vmlinux addRamDisk ramdisk.image $(TOPDIR)/System.map
+ ./addRamDisk ramdisk.image $(TOPDIR)/System.map $(TOPDIR)/vmlinux vmlinux.initrd
+
+vmlinux.sminitrd: vmlinux.sm addRamDisk ramdisk.image $(TOPDIR)/System.map
+ ./addRamDisk ramdisk.image $(TOPDIR)/System.map vmlinux.sm vmlinux.sminitrd
+
+endif
+
+
znetboot.initrd: zImage.initrd
cp zImage.initrd $(TFTPIMAGE)
@@ -84,7 +118,7 @@
imagesize.c: vmlinux.gz
clean:
- rm -f piggyback note addnote $(OBJS) zImage vmlinux.gz no_initrd.o
+ rm -f piggyback note addnote $(OBJS) zImage zImage.initrd vmlinux.gz no_initrd.o imagesize.c addSystemMap vmlinux.sm addRamDisk vmlinux.initrd vmlinux.sminitrd
fastdep:
$(TOPDIR)/scripts/mkdep *.[Sch] > .depend
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/boot/addRamDisk.c linuxppc64_2_4/arch/ppc64/boot/addRamDisk.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/boot/addRamDisk.c Wed Dec 31 18:00:00 1969
+++ linuxppc64_2_4/arch/ppc64/boot/addRamDisk.c Mon Oct 8 21:26:21 2001
@@ -0,0 +1,324 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define ElfHeaderSize (64 * 1024)
+#define ElfPages (ElfHeaderSize / 4096)
+#define KERNELBASE (0xc000000000000000)
+
+void get4k(FILE *file, char *buf )
+{
+ unsigned j;
+ unsigned num = fread(buf, 1, 4096, file);
+ for ( j=num; j<4096; ++j )
+ buf[j] = 0;
+}
+
+void put4k(FILE *file, char *buf )
+{
+ fwrite(buf, 1, 4096, file);
+}
+
+void death(const char *msg, FILE *fdesc, const char *fname)
+{
+ printf(msg);
+ fclose(fdesc);
+ unlink(fname);
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ char inbuf[4096];
+ FILE *ramDisk = NULL;
+ FILE *sysmap = NULL;
+ FILE *inputVmlinux = NULL;
+ FILE *outputVmlinux = NULL;
+
+ unsigned i = 0;
+ unsigned long ramFileLen = 0;
+ unsigned long ramLen = 0;
+ unsigned long roundR = 0;
+
+ unsigned long sysmapFileLen = 0;
+ unsigned long sysmapLen = 0;
+ unsigned long sysmapPages = 0;
+ char* ptr_end = NULL;
+ unsigned long offset_end = 0;
+
+ unsigned long kernelLen = 0;
+ unsigned long actualKernelLen = 0;
+ unsigned long round = 0;
+ unsigned long roundedKernelLen = 0;
+ unsigned long ramStartOffs = 0;
+ unsigned long ramPages = 0;
+ unsigned long roundedKernelPages = 0;
+ unsigned long hvReleaseData = 0;
+ u_int32_t eyeCatcher = 0xc8a5d9c4;
+ unsigned long naca = 0;
+ unsigned long xRamDisk = 0;
+ unsigned long xRamDiskSize = 0;
+ long padPages = 0;
+
+
+ if (argc < 2)
+ {
+ printf("Name of RAM disk file missing.\n");
+ exit(1);
+ }
+
+ if (argc < 3)
+ {
+ printf("Name of System Map input file is missing.\n");
+ exit(1);
+ }
+
+ if (argc < 4)
+ {
+ printf("Name of vmlinux file missing.\n");
+ exit(1);
+ }
+
+ if (argc < 5)
+ {
+ printf("Name of vmlinux output file missing.\n");
+ exit(1);
+ }
+
+
+ ramDisk = fopen(argv[1], "r");
+ if ( ! ramDisk )
+ {
+ printf("RAM disk file \"%s\" failed to open.\n", argv[1]);
+ exit(1);
+ }
+
+ sysmap = fopen(argv[2], "r");
+ if ( ! sysmap )
+ {
+ printf("System Map file \"%s\" failed to open.\n", argv[2]);
+ exit(1);
+ }
+
+ inputVmlinux = fopen(argv[3], "r");
+ if ( ! inputVmlinux )
+ {
+ printf("vmlinux file \"%s\" failed to open.\n", argv[3]);
+ exit(1);
+ }
+
+ outputVmlinux = fopen(argv[4], "w+");
+ if ( ! outputVmlinux )
+ {
+ printf("output vmlinux file \"%s\" failed to open.\n", argv[4]);
+ exit(1);
+ }
+
+
+
+ /* Input Vmlinux file */
+ fseek(inputVmlinux, 0, SEEK_END);
+ kernelLen = ftell(inputVmlinux);
+ fseek(inputVmlinux, 0, SEEK_SET);
+ printf("kernel file size = %d\n", kernelLen);
+ if ( kernelLen == 0 )
+ {
+ printf("You must have a linux kernel specified as argv[3]\n");
+ exit(1);
+ }
+
+ actualKernelLen = kernelLen - ElfHeaderSize;
+
+ printf("actual kernel length (minus ELF header) = %d\n", actualKernelLen);
+
+ round = actualKernelLen % 4096;
+ roundedKernelLen = actualKernelLen;
+ if ( round )
+ roundedKernelLen += (4096 - round);
+ printf("Vmlinux length rounded up to a 4k multiple = %ld/0x%lx \n", roundedKernelLen, roundedKernelLen);
+ roundedKernelPages = roundedKernelLen / 4096;
+ printf("Vmlinux pages to copy = %ld/0x%lx \n", roundedKernelPages, roundedKernelPages);
+
+
+
+ /* Input System Map file */
+ /* (needs to be processed simply to determine if we need to add pad pages due to the static variables not being included in the vmlinux) */
+ fseek(sysmap, 0, SEEK_END);
+ sysmapFileLen = ftell(sysmap);
+ fseek(sysmap, 0, SEEK_SET);
+ printf("%s file size = %ld/0x%lx \n", argv[2], sysmapFileLen, sysmapFileLen);
+
+ sysmapLen = sysmapFileLen;
+
+ roundR = 4096 - (sysmapLen % 4096);
+ if (roundR)
+ {
+ printf("Rounding System Map file up to a multiple of 4096, adding %ld/0x%lx \n", roundR, roundR);
+ sysmapLen += roundR;
+ }
+ printf("Rounded System Map size is %ld/0x%lx \n", sysmapLen, sysmapLen);
+
+ /* Process the Sysmap file to determine where _end is */
+ sysmapPages = sysmapLen / 4096;
+ for (i=0; i
+#include
+#include
+#include
+#include
+#include
+
+void xlate( char * inb, char * trb, unsigned len )
+{
+ unsigned i;
+ for ( i=0; i> 4;
+ char c2 = c & 0xf;
+ if ( c1 > 9 )
+ c1 = c1 + 'A' - 10;
+ else
+ c1 = c1 + '0';
+ if ( c2 > 9 )
+ c2 = c2 + 'A' - 10;
+ else
+ c2 = c2 + '0';
+ *trb++ = c1;
+ *trb++ = c2;
+ }
+ *trb = 0;
+}
+
+#define ElfHeaderSize (64 * 1024)
+#define ElfPages (ElfHeaderSize / 4096)
+
+void get4k( /*istream *inf*/FILE *file, char *buf )
+{
+ unsigned j;
+ unsigned num = fread(buf, 1, 4096, file);
+ for ( j=num; j<4096; ++j )
+ buf[j] = 0;
+}
+
+void put4k( /*ostream *outf*/FILE *file, char *buf )
+{
+ fwrite(buf, 1, 4096, file);
+}
+
+int main(int argc, char **argv)
+{
+ char inbuf[4096];
+ FILE *sysmap = NULL;
+ char* ptr_end = NULL;
+ FILE *inputVmlinux = NULL;
+ FILE *outputVmlinux = NULL;
+ long i = 0;
+ unsigned long sysmapFileLen = 0;
+ unsigned long sysmapLen = 0;
+ unsigned long roundR = 0;
+ unsigned long kernelLen = 0;
+ unsigned long actualKernelLen = 0;
+ unsigned long round = 0;
+ unsigned long roundedKernelLen = 0;
+ unsigned long sysmapStartOffs = 0;
+ unsigned long sysmapPages = 0;
+ unsigned long roundedKernelPages = 0;
+ long padPages = 0;
+ if ( argc < 2 )
+ {
+ printf("Name of System Map file missing.\n");
+ exit(1);
+ }
+
+ if ( argc < 3 )
+ {
+ printf("Name of vmlinux file missing.\n");
+ exit(1);
+ }
+
+ if ( argc < 4 )
+ {
+ printf("Name of vmlinux output file missing.\n");
+ exit(1);
+ }
+
+ sysmap = fopen(argv[1], "r");
+ if ( ! sysmap )
+ {
+ printf("System Map file \"%s\" failed to open.\n", argv[1]);
+ exit(1);
+ }
+ inputVmlinux = fopen(argv[2], "r");
+ if ( ! inputVmlinux )
+ {
+ printf("vmlinux file \"%s\" failed to open.\n", argv[2]);
+ exit(1);
+ }
+ outputVmlinux = fopen(argv[3], "w");
+ if ( ! outputVmlinux )
+ {
+ printf("output vmlinux file \"%s\" failed to open.\n", argv[3]);
+ exit(1);
+ }
+
+
+
+ fseek(inputVmlinux, 0, SEEK_END);
+ kernelLen = ftell(inputVmlinux);
+ fseek(inputVmlinux, 0, SEEK_SET);
+ printf("kernel file size = %ld\n", kernelLen);
+ if ( kernelLen == 0 )
+ {
+ printf("You must have a linux kernel specified as argv[2]\n");
+ exit(1);
+ }
+
+
+ actualKernelLen = kernelLen - ElfHeaderSize;
+
+ printf("actual kernel length (minus ELF header) = %ld/%lxx \n", actualKernelLen, actualKernelLen);
+
+ round = actualKernelLen % 4096;
+ roundedKernelLen = actualKernelLen;
+ if ( round )
+ roundedKernelLen += (4096 - round);
+
+ printf("Kernel length rounded up to a 4k multiple = %ld/%lxx \n", roundedKernelLen, roundedKernelLen);
+ roundedKernelPages = roundedKernelLen / 4096;
+ printf("Kernel pages to copy = %ld/%lxx\n", roundedKernelPages, roundedKernelPages);
+
+
+
+ /* Sysmap file */
+ fseek(sysmap, 0, SEEK_END);
+ sysmapFileLen = ftell(sysmap);
+ fseek(sysmap, 0, SEEK_SET);
+ printf("%s file size = %ld\n", argv[1], sysmapFileLen);
+
+ sysmapLen = sysmapFileLen;
+
+ roundR = 4096 - (sysmapLen % 4096);
+ if (roundR)
+ {
+ printf("Rounding System Map file up to a multiple of 4096, adding %ld\n", roundR);
+ sysmapLen += roundR;
+ }
+ printf("Rounded System Map size is %ld\n", sysmapLen);
+
+ /* Process the Sysmap file to determine the true end of the kernel */
+ sysmapPages = sysmapLen / 4096;
+ printf("System map pages to copy = %ld\n", sysmapPages);
+ for (i=0; i
#include
#include
-#include
+#include
-#define _ALIGN(addr,size) (((addr)+(size)-1)&(~((size)-1)))
+void memmove(void *dst, void *im, int len);
extern void *finddevice(const char *);
extern int getprop(void *, const char *, void *, int);
@@ -25,16 +24,15 @@
void *claim(unsigned int, unsigned int, unsigned int);
void flush_cache(void *, int);
void pause(void);
+static struct bi_record *make_bi_recs(unsigned long);
#define RAM_START 0x00000000
#define RAM_END (64<<20)
#define BOOT_START ((unsigned long)_start)
-#define BOOT_END ((unsigned long)(_end + 0xFFF) & ~0xFFF)
-
-#define RAM_FREE ((unsigned long)(_end+0x1000)&~0xFFF)
+#define BOOT_END ((unsigned long)_end)
-// Value picked to match that used by yaboot
+/* Value picked to match that used by yaboot */
#define PROG_START 0x01400000
char *avail_ram;
@@ -42,6 +40,8 @@
char *avail_high;
unsigned int heap_use;
unsigned int heap_max;
+unsigned long initrd_start = 0;
+unsigned long initrd_size = 0;
extern char _end[];
extern char image_data[];
@@ -54,32 +54,37 @@
static char scratch[128<<10]; /* 128kB of scratch space for gunzip */
+typedef void (*kernel_entry_t)( unsigned long,
+ unsigned long,
+ void *,
+ struct bi_record *);
+
void
-chrpboot(int a1, int a2, void *prom)
+chrpboot(unsigned long a1, unsigned long a2, void *prom)
{
- unsigned sa, len;
- void *dst, *claim_addr;
+ unsigned len;
+ void *dst = (void *)-1;
+ unsigned long claim_addr;
unsigned char *im;
- unsigned initrd_start, initrd_size;
extern char _start;
+ struct bi_record *bi_recs;
+ kernel_entry_t kernel_entry;
printf("chrpboot starting: loaded at 0x%x\n\r", (unsigned)&_start);
- printf(" initrd_len = 0x%x\n\r", (unsigned)initrd_len);
if (initrd_len) {
initrd_size = initrd_len;
initrd_start = (RAM_END - initrd_size) & ~0xFFF;
- a1 = initrd_start;
- a2 = initrd_size;
+ a1 = a2 = 0;
claim(initrd_start, RAM_END - initrd_start, 0);
- printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n\r",
- initrd_start, (unsigned)initrd_data, initrd_size);
+ printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r",
+ initrd_start, (unsigned long)initrd_data, initrd_size);
memcpy((void *)initrd_start, (void *)initrd_data, initrd_size);
}
im = image_data;
len = image_len;
- uncompressed_size = _ALIGN(uncompressed_size, (1<<12)); /* page align it */
+ uncompressed_size = PAGE_ALIGN(uncompressed_size);
for(claim_addr = PROG_START;
claim_addr <= PROG_START * 8;
@@ -108,48 +113,72 @@
}
flush_cache(dst, len);
- make_bi_recs((unsigned long)dst + len);
- sa = (unsigned long)dst;
- printf("start address = 0x%x\n\r", (unsigned) sa);
+ bi_recs = make_bi_recs((unsigned long)dst + len);
+
+ kernel_entry = (kernel_entry_t)dst;
+ printf( "kernel:\n\r"
+ " entry addr = 0x%lx\n\r"
+ " a1 = 0x%lx,\n\r"
+ " a2 = 0x%lx,\n\r"
+ " prom = 0x%lx,\n\r"
+ " bi_recs = 0x%lx,\n\r",
+ (unsigned long)kernel_entry, a1, a2,
+ (unsigned long)prom, (unsigned long)bi_recs);
- (*(void (*)(int, int, void *))sa)(a1, a2, prom);
+ kernel_entry( a1, a2, prom, bi_recs );
printf("returned?\n\r");
pause();
}
-void make_bi_recs(unsigned long addr)
+static struct bi_record *
+make_bi_recs(unsigned long addr)
{
+ struct bi_record *bi_recs;
struct bi_record *rec;
-
- rec = (struct bi_record *)_ALIGN(addr + (1<<20) -1, (1<<20));
+ bi_recs = rec = bi_rec_init(addr);
+
+ rec = bi_rec_alloc(rec, 1);
rec->tag = BI_FIRST;
- rec->size = sizeof(struct bi_record);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
+ /* rec->data[0] = ...; # Written below before return */
+
+ rec = bi_rec_alloc_bytes(rec, strlen("chrpboot")+1);
rec->tag = BI_BOOTLOADER_ID;
sprintf( (char *)rec->data, "chrpboot");
- rec->size = sizeof(struct bi_record) + strlen("chrpboot") + 1;
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
-
+
+ rec = bi_rec_alloc(rec, 2);
rec->tag = BI_MACHTYPE;
- rec->data[0] = _MACH_chrp;
+ rec->data[0] = _MACH_pSeries;
rec->data[1] = 1;
- rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ if ( initrd_size > 0 ) {
+ rec = bi_rec_alloc(rec, 2);
+ rec->tag = BI_INITRD;
+ rec->data[0] = initrd_start;
+ rec->data[1] = initrd_size;
+ }
+
#if 0
- rec->tag = BI_SYSMAP;
- rec->data[0] = (unsigned long)sysmap_data;
- rec->data[1] = sysmap_len;
- rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
+ if ( sysmap_len > 0 ) {
+ rec = bi_rec_alloc(rec, 2);
+ rec->tag = BI_SYSMAP;
+ rec->data[0] = (unsigned long)sysmap_data;
+ rec->data[1] = sysmap_len;
+ }
#endif
+
+ rec = bi_rec_alloc(rec, 0);
rec->tag = BI_LAST;
- rec->size = sizeof(struct bi_record);
- rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ /* Save the _end_ address of the bi_rec's in the first bi_rec
+ * data field for easy access by the kernel.
+ */
+ bi_recs->data[0] = (bi_rec_field)rec + rec->size;
+
+ return bi_recs;
}
struct memchunk {
@@ -212,47 +241,48 @@
void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
{
- z_stream s;
- int r, i, flags;
+ z_stream s;
+ int r, i, flags;
+
+ /* skip header */
+ i = 10;
+ flags = src[3];
+ if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+ printf("bad gzipped data\n\r");
+ exit();
+ }
+ if ((flags & EXTRA_FIELD) != 0)
+ i = 12 + src[10] + (src[11] << 8);
+ if ((flags & ORIG_NAME) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & COMMENT) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & HEAD_CRC) != 0)
+ i += 2;
+ if (i >= *lenp) {
+ printf("gunzip: ran out of data in header\n\r");
+ exit();
+ }
- /* skip header */
- i = 10;
- flags = src[3];
- if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
- printf("bad gzipped data\n\r");
- exit();
- }
- if ((flags & EXTRA_FIELD) != 0)
- i = 12 + src[10] + (src[11] << 8);
- if ((flags & ORIG_NAME) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & COMMENT) != 0)
- while (src[i++] != 0)
- ;
- if ((flags & HEAD_CRC) != 0)
- i += 2;
- if (i >= *lenp) {
- printf("gunzip: ran out of data in header\n\r");
- exit();
- }
-
- s.zalloc = zalloc;
- s.zfree = zfree;
- r = inflateInit2(&s, -MAX_WBITS);
- if (r != Z_OK) {
- printf("inflateInit2 returned %d\n\r", r);
- exit();
- }
- s.next_in = src + i;
- s.avail_in = *lenp - i;
- s.next_out = dst;
- s.avail_out = dstlen;
- r = inflate(&s, Z_FINISH);
- if (r != Z_OK && r != Z_STREAM_END) {
- printf("inflate returned %d msg: %s\n\r", r, s.msg);
- exit();
- }
- *lenp = s.next_out - (unsigned char *) dst;
- inflateEnd(&s);
+ s.zalloc = zalloc;
+ s.zfree = zfree;
+ r = inflateInit2(&s, -MAX_WBITS);
+ if (r != Z_OK) {
+ printf("inflateInit2 returned %d\n\r", r);
+ exit();
+ }
+ s.next_in = src + i;
+ s.avail_in = *lenp - i;
+ s.next_out = dst;
+ s.avail_out = dstlen;
+ r = inflate(&s, Z_FINISH);
+ if (r != Z_OK && r != Z_STREAM_END) {
+ printf("inflate returned %d msg: %s\n\r", r, s.msg);
+ exit();
+ }
+ *lenp = s.next_out - (unsigned char *) dst;
+ inflateEnd(&s);
}
+
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/boot/start.c linuxppc64_2_4/arch/ppc64/boot/start.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/boot/start.c Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/boot/start.c Thu Sep 13 14:13:35 2001
@@ -30,200 +30,200 @@
void
start(int a1, int a2, void *promptr)
{
- prom = (int (*)(void *)) promptr;
- chosen_handle = finddevice("/chosen");
- if (chosen_handle == (void *) -1)
- exit();
- if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
- exit();
- stderr = stdout;
- if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
+ prom = (int (*)(void *)) promptr;
+ chosen_handle = finddevice("/chosen");
+ if (chosen_handle == (void *) -1)
+ exit();
+ if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
+ exit();
+ stderr = stdout;
+ if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
exit();
- chrpboot(a1, a2, promptr);
- for (;;)
- exit();
+ chrpboot(a1, a2, promptr);
+ for (;;)
+ exit();
}
int
write(void *handle, void *ptr, int nb)
{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- void *ihandle;
- void *addr;
- int len;
- int actual;
- } args;
-
- args.service = "write";
- args.nargs = 3;
- args.nret = 1;
- args.ihandle = handle;
- args.addr = ptr;
- args.len = nb;
- args.actual = -1;
- (*prom)(&args);
- return args.actual;
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ void *ihandle;
+ void *addr;
+ int len;
+ int actual;
+ } args;
+
+ args.service = "write";
+ args.nargs = 3;
+ args.nret = 1;
+ args.ihandle = handle;
+ args.addr = ptr;
+ args.len = nb;
+ args.actual = -1;
+ (*prom)(&args);
+ return args.actual;
}
int
read(void *handle, void *ptr, int nb)
{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- void *ihandle;
- void *addr;
- int len;
- int actual;
- } args;
-
- args.service = "read";
- args.nargs = 3;
- args.nret = 1;
- args.ihandle = handle;
- args.addr = ptr;
- args.len = nb;
- args.actual = -1;
- (*prom)(&args);
- return args.actual;
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ void *ihandle;
+ void *addr;
+ int len;
+ int actual;
+ } args;
+
+ args.service = "read";
+ args.nargs = 3;
+ args.nret = 1;
+ args.ihandle = handle;
+ args.addr = ptr;
+ args.len = nb;
+ args.actual = -1;
+ (*prom)(&args);
+ return args.actual;
}
void
exit()
{
- struct prom_args {
- char *service;
- } args;
+ struct prom_args {
+ char *service;
+ } args;
- for (;;) {
- args.service = "exit";
- (*prom)(&args);
- }
+ for (;;) {
+ args.service = "exit";
+ (*prom)(&args);
+ }
}
void
pause(void)
{
- struct prom_args {
- char *service;
- } args;
+ struct prom_args {
+ char *service;
+ } args;
- args.service = "enter";
- (*prom)(&args);
+ args.service = "enter";
+ (*prom)(&args);
}
void *
finddevice(const char *name)
{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- const char *devspec;
- void *phandle;
- } args;
-
- args.service = "finddevice";
- args.nargs = 1;
- args.nret = 1;
- args.devspec = name;
- args.phandle = (void *) -1;
- (*prom)(&args);
- return args.phandle;
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ const char *devspec;
+ void *phandle;
+ } args;
+
+ args.service = "finddevice";
+ args.nargs = 1;
+ args.nret = 1;
+ args.devspec = name;
+ args.phandle = (void *) -1;
+ (*prom)(&args);
+ return args.phandle;
}
void *
-claim(unsigned int virt, unsigned int size, unsigned int align)
+claim(unsigned long virt, unsigned long size, unsigned long align)
{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- unsigned int virt;
- unsigned int size;
- unsigned int align;
- void *ret;
- } args;
-
- args.service = "claim";
- args.nargs = 3;
- args.nret = 1;
- args.virt = virt;
- args.size = size;
- args.align = align;
- (*prom)(&args);
- return args.ret;
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ unsigned int virt;
+ unsigned int size;
+ unsigned int align;
+ void *ret;
+ } args;
+
+ args.service = "claim";
+ args.nargs = 3;
+ args.nret = 1;
+ args.virt = virt;
+ args.size = size;
+ args.align = align;
+ (*prom)(&args);
+ return args.ret;
}
int
getprop(void *phandle, const char *name, void *buf, int buflen)
{
- struct prom_args {
- char *service;
- int nargs;
- int nret;
- void *phandle;
- const char *name;
- void *buf;
- int buflen;
- int size;
- } args;
-
- args.service = "getprop";
- args.nargs = 4;
- args.nret = 1;
- args.phandle = phandle;
- args.name = name;
- args.buf = buf;
- args.buflen = buflen;
- args.size = -1;
- (*prom)(&args);
- return args.size;
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ void *phandle;
+ const char *name;
+ void *buf;
+ int buflen;
+ int size;
+ } args;
+
+ args.service = "getprop";
+ args.nargs = 4;
+ args.nret = 1;
+ args.phandle = phandle;
+ args.name = name;
+ args.buf = buf;
+ args.buflen = buflen;
+ args.size = -1;
+ (*prom)(&args);
+ return args.size;
}
int
putc(int c, void *f)
{
- char ch = c;
+ char ch = c;
- if (c == '\n')
- putc('\r', f);
- return write(f, &ch, 1) == 1? c: -1;
+ if (c == '\n')
+ putc('\r', f);
+ return write(f, &ch, 1) == 1? c: -1;
}
int
putchar(int c)
{
- return putc(c, stdout);
+ return putc(c, stdout);
}
int
fputs(char *str, void *f)
{
- int n = strlen(str);
+ int n = strlen(str);
- return write(f, str, n) == n? 0: -1;
+ return write(f, str, n) == n? 0: -1;
}
int
readchar(void)
{
- char ch;
+ char ch;
- for (;;) {
- switch (read(stdin, &ch, 1)) {
- case 1:
- return ch;
- case -1:
- printk("read(stdin) returned -1\r\n");
- return -1;
+ for (;;) {
+ switch (read(stdin, &ch, 1)) {
+ case 1:
+ return ch;
+ case -1:
+ printk("read(stdin) returned -1\r\n");
+ return -1;
+ }
}
- }
}
static char line[256];
@@ -233,53 +233,53 @@
int
getchar(void)
{
- int c;
+ int c;
- if (lineleft == 0) {
- lineptr = line;
- for (;;) {
- c = readchar();
- if (c == -1 || c == 4)
- break;
- if (c == '\r' || c == '\n') {
- *lineptr++ = '\n';
- putchar('\n');
- break;
- }
- switch (c) {
- case 0177:
- case '\b':
- if (lineptr > line) {
- putchar('\b');
- putchar(' ');
- putchar('\b');
- --lineptr;
- }
- break;
- case 'U' & 0x1F:
- while (lineptr > line) {
- putchar('\b');
- putchar(' ');
- putchar('\b');
- --lineptr;
- }
- break;
- default:
- if (lineptr >= &line[sizeof(line) - 1])
- putchar('\a');
- else {
- putchar(c);
- *lineptr++ = c;
+ if (lineleft == 0) {
+ lineptr = line;
+ for (;;) {
+ c = readchar();
+ if (c == -1 || c == 4)
+ break;
+ if (c == '\r' || c == '\n') {
+ *lineptr++ = '\n';
+ putchar('\n');
+ break;
+ }
+ switch (c) {
+ case 0177:
+ case '\b':
+ if (lineptr > line) {
+ putchar('\b');
+ putchar(' ');
+ putchar('\b');
+ --lineptr;
+ }
+ break;
+ case 'U' & 0x1F:
+ while (lineptr > line) {
+ putchar('\b');
+ putchar(' ');
+ putchar('\b');
+ --lineptr;
+ }
+ break;
+ default:
+ if (lineptr >= &line[sizeof(line) - 1])
+ putchar('\a');
+ else {
+ putchar(c);
+ *lineptr++ = c;
+ }
+ }
}
- }
+ lineleft = lineptr - line;
+ lineptr = line;
}
- lineleft = lineptr - line;
- lineptr = line;
- }
- if (lineleft == 0)
- return -1;
- --lineleft;
- return *lineptr++;
+ if (lineleft == 0)
+ return -1;
+ --lineleft;
+ return *lineptr++;
}
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/boot/zImage.lds linuxppc64_2_4/arch/ppc64/boot/zImage.lds
--- ../tue/linux-2.4.10-ac12/arch/ppc64/boot/zImage.lds Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/boot/zImage.lds Tue Sep 11 08:57:14 2001
@@ -33,6 +33,7 @@
*(.fixup)
*(.got1)
}
+ . = ALIGN(4096);
_etext = .;
PROVIDE (etext = .);
.rodata :
@@ -45,7 +46,7 @@
.ctors : { *(.ctors) }
.dtors : { *(.dtors) }
/* Read-write section, merged into data segment: */
- . = (. + 0x0FFF) & 0xFFFFF000;
+ . = ALIGN(4096);
.data :
{
*(.data)
@@ -56,11 +57,13 @@
*(.dynamic)
CONSTRUCTORS
}
+ . = ALIGN(4096);
_edata = .;
PROVIDE (edata = .);
.fixup : { *(.fixup) }
+ . = ALIGN(4096);
__bss_start = .;
.bss :
{
@@ -69,6 +72,7 @@
*(.bss)
*(COMMON)
}
+ . = ALIGN(4096);
_end = . ;
PROVIDE (end = .);
}
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/config.in linuxppc64_2_4/arch/ppc64/config.in
--- ../tue/linux-2.4.10-ac12/arch/ppc64/config.in Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/config.in Thu Oct 11 10:30:12 2001
@@ -26,6 +26,12 @@
iSeries CONFIG_PPC_ISERIES" CONFIG_PPC_PSERIES
bool 'Symmetric multi-processing support' CONFIG_SMP
+if [ "$CONFIG_SMP" = "y" ]; then
+ bool ' Distribute interrupts on all CPUs by default' CONFIG_IRQ_ALL_CPUS
+ if [ "$CONFIG_PPC_PSERIES" = "y" ]; then
+ bool ' Hardware multithreading' CONFIG_HMT
+ fi
+fi
if [ "$CONFIG_PPC_ISERIES" = "y" ]; then
define_bool CONFIG_MSCHUNKS y
else
@@ -152,6 +158,46 @@
comment 'Console drivers'
source drivers/video/Config.in
endmenu
+
+
+if [ "$CONFIG_PPC_ISERIES" = "y" ]; then
+mainmenu_option next_comment
+comment 'iSeries device drivers'
+ dep_tristate 'iSeries Virtual Console Support' CONFIG_VIOCONS $CONFIG_PPC_ISERIES
+ dep_tristate 'iSeries Virtual I/O disk support' CONFIG_VIODASD $CONFIG_PPC_ISERIES
+ if [ "$CONFIG_VIODASD" = "y" -o "$CONFIG_VIODASD" = "m" ]; then
+ bool 'iSeries Virtual disk IDE emulation' CONFIG_VIODASD_IDE
+ fi
+ dep_tristate 'iSeries Virtual I/O CD support' CONFIG_VIOCD $CONFIG_PPC_ISERIES
+ if [ "$CONFIG_VIOCD" = "y" -o "$CONFIG_VIOCD" = "m" ]; then
+ bool 'iSeries Virtual CD Aztech emulation' CONFIG_VIOCD_AZTECH
+ fi
+ dep_tristate 'iSeries Virtual Tape Support' CONFIG_VIOTAPE $CONFIG_PPC_ISERIES
+ dep_tristate 'iSeries Virtual Ethernet driver support' CONFIG_VETH $CONFIG_PPC_ISERIES
+endmenu
+fi
+
+if [ "$CONFIG_VIOCONS" = "n" ]; then
+ if [ "$CONFIG_VIODASD" = "n" ]; then
+ if [ "$CONFIG_VIOTAPE" = "n" ]; then
+ if [ "$CONFIG_VIOCD" = "n" ]; then
+ define_bool CONFIG_VIOPATH n
+ else
+ define_bool CONFIG_VIOPATH y
+ fi
+ else
+ define_bool CONFIG_VIOPATH y
+ fi
+ else
+ define_bool CONFIG_VIOPATH y
+ fi
+else
+ define_bool CONFIG_VIOPATH y
+fi
+
+if [ "$CONFIG_VIOCD" = "y" ]; then
+ define_bool CONFIG_CD_NO_IDESCSI y
+fi
source drivers/char/Config.in
source fs/Config.in
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/configs/iSeries_devfs_defconfig linuxppc64_2_4/arch/ppc64/configs/iSeries_devfs_defconfig
--- ../tue/linux-2.4.10-ac12/arch/ppc64/configs/iSeries_devfs_defconfig Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/configs/iSeries_devfs_defconfig Thu Oct 4 17:38:24 2001
@@ -1,5 +1,5 @@
#
-# Automatically generated make config: don't edit
+# Automatically generated by make menuconfig: don't edit
#
# CONFIG_UID16 is not set
# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
@@ -19,14 +19,16 @@
CONFIG_SERIAL_CONSOLE=y
# CONFIG_PPC_PSERIES is not set
CONFIG_PPC_ISERIES=y
-CONFIG_MSCHUNKS=y
CONFIG_SMP=y
+CONFIG_IRQ_ALL_CPUS=y
CONFIG_MSCHUNKS=y
#
# Loadable module support
#
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
#
# General setup
@@ -69,8 +71,6 @@
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
-CONFIG_VIODASD=y
-# CONFIG_VIODASD_IDE is not set
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
@@ -85,13 +85,13 @@
#
# Multi-device support (RAID and LVM)
#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_LVM is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID5=m
+CONFIG_BLK_DEV_LVM=m
#
# Networking options
@@ -119,10 +119,6 @@
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
# CONFIG_ATM is not set
-
-#
-#
-#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_DECNET is not set
@@ -146,7 +142,69 @@
#
# SCSI support
#
-# CONFIG_SCSI is not set
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+CONFIG_CHR_DEV_ST=m
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_SR_EXTRA_DEVS=2
+CONFIG_CHR_DEV_SG=m
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR_D700 is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_MESH is not set
+# CONFIG_SCSI_MAC53C94 is not set
#
# IEEE 1394 (FireWire) support (EXPERIMENTAL)
@@ -171,19 +229,63 @@
#
# Ethernet (10 or 100Mbit)
#
-# CONFIG_NET_ETHERNET is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_OAKNET is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_LAN_SAA9730 is not set
+# CONFIG_NET_POCKET is not set
#
# Ethernet (1000 Mbit)
#
-# CONFIG_ACENIC is not set
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
# CONFIG_DL2K is not set
# CONFIG_MYRI_SBUS is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_SK98LIN is not set
-CONFIG_VETH=y
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PLIP is not set
@@ -198,7 +300,10 @@
#
# Token Ring devices
#
-# CONFIG_TR is not set
+CONFIG_TR=y
+CONFIG_IBMOL=m
+# CONFIG_IBMLS is not set
+# CONFIG_TMS380TR is not set
# CONFIG_NET_FC is not set
# CONFIG_RCPCI is not set
# CONFIG_SHAPER is not set
@@ -238,6 +343,18 @@
# CONFIG_FB is not set
#
+# iSeries device drivers
+#
+CONFIG_VIOCONS=y
+CONFIG_VIODASD=y
+# CONFIG_VIODASD_IDE is not set
+CONFIG_VIOCD=m
+# CONFIG_VIOCD_AZTECH is not set
+CONFIG_VIOTAPE=m
+CONFIG_VETH=y
+CONFIG_VIOPATH=y
+
+#
# Character devices
#
# CONFIG_VT is not set
@@ -246,7 +363,6 @@
# CONFIG_SERIAL_NONSTANDARD is not set
CONFIG_UNIX98_PTYS=y
CONFIG_UNIX98_PTY_COUNT=256
-CONFIG_VIOCONS=y
#
# I2C support
@@ -270,10 +386,6 @@
# CONFIG_INPUT_EMU10K1 is not set
# CONFIG_INPUT_SERIO is not set
# CONFIG_INPUT_SERPORT is not set
-
-#
-# Joysticks
-#
# CONFIG_INPUT_ANALOG is not set
# CONFIG_INPUT_A3D is not set
# CONFIG_INPUT_ADI is not set
@@ -294,7 +406,6 @@
# CONFIG_INPUT_GAMECON is not set
# CONFIG_INPUT_TURBOGRAFX is not set
# CONFIG_QIC02_TAPE is not set
-# CONFIG_VIOTAPE is not set
#
# Watchdog Cards
@@ -345,6 +456,7 @@
# CONFIG_RAMFS is not set
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
+# CONFIG_JFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_FREEVXFS_FS is not set
# CONFIG_NTFS_FS is not set
@@ -373,8 +485,8 @@
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_ROOT_NFS is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
@@ -447,70 +559,44 @@
# USB support
#
# CONFIG_USB is not set
-
-#
-# USB Controllers
-#
# CONFIG_USB_UHCI is not set
# CONFIG_USB_UHCI_ALT is not set
# CONFIG_USB_OHCI is not set
-
-#
-# USB Device Class drivers
-#
# CONFIG_USB_AUDIO is not set
# CONFIG_USB_BLUETOOTH is not set
# CONFIG_USB_STORAGE is not set
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
# CONFIG_USB_STORAGE_JUMPSHOT is not set
# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
# CONFIG_USB_HID is not set
# CONFIG_USB_HIDDEV is not set
# CONFIG_USB_KBD is not set
# CONFIG_USB_MOUSE is not set
# CONFIG_USB_WACOM is not set
-
-#
-# USB Imaging devices
-#
# CONFIG_USB_DC2XX is not set
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_SCANNER is not set
# CONFIG_USB_MICROTEK is not set
# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
# CONFIG_USB_IBMCAM is not set
# CONFIG_USB_OV511 is not set
# CONFIG_USB_PWC is not set
# CONFIG_USB_SE401 is not set
# CONFIG_USB_DSBR is not set
# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
# CONFIG_USB_PLUSB is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_CATC is not set
# CONFIG_USB_CDCETHER is not set
# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
# CONFIG_USB_USS720 is not set
#
@@ -537,10 +623,6 @@
# CONFIG_USB_SERIAL_PL2303 is not set
# CONFIG_USB_SERIAL_CYBERJACK is not set
# CONFIG_USB_SERIAL_OMNINET is not set
-
-#
-# Miscellaneous USB drivers
-#
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_ID75 is not set
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig linuxppc64_2_4/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig
--- ../tue/linux-2.4.10-ac12/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig Wed Dec 31 18:00:00 1969
+++ linuxppc64_2_4/arch/ppc64/configs/iSeries_nodevfs_ideemul_defconfig Mon Oct 15 08:21:48 2001
@@ -0,0 +1,685 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+# CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_PPC64=y
+CONFIG_ALL_PPC=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_PPC_PSERIES is not set
+CONFIG_PPC_ISERIES=y
+CONFIG_SMP=y
+CONFIG_IRQ_ALL_CPUS=y
+CONFIG_MSCHUNKS=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
+#
+# General setup
+#
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+# CONFIG_EISA is not set
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_ELF32=y
+CONFIG_BINFMT_MISC=y
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+# CONFIG_PNPBIOS is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=64000
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID5=m
+# CONFIG_MD_MULTIPATH is not set
+CONFIG_BLK_DEV_LVM=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+CONFIG_RTNETLINK=y
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_RTNETLINK=y
+CONFIG_NETLINK=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_NAT=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_TOS=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_ROUTE_LARGE_TABLES=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=y
+CONFIG_NET_IPGRE=y
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC 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
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+CONFIG_CHR_DEV_ST=m
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_SR_EXTRA_DEVS=2
+CONFIG_CHR_DEV_SG=y
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_MESH is not set
+# CONFIG_SCSI_MAC53C94 is not set
+
+#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# Network device support
+#
+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
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+# CONFIG_OAKNET is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+CONFIG_PCNET32=m
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
+# CONFIG_ES3210 is not set
+# CONFIG_8139TOO is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+# CONFIG_DL2K is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP 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
+#
+CONFIG_TR=y
+CONFIG_IBMOL=m
+# CONFIG_IBMLS is not set
+# CONFIG_TMS380TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+CONFIG_CD_NO_IDESCSI=y
+# CONFIG_AZTCD is not set
+# CONFIG_GSCD is not set
+# CONFIG_SBPCD is not set
+# CONFIG_MCD is not set
+# CONFIG_MCDX is not set
+# CONFIG_OPTCD is not set
+# CONFIG_CM206 is not set
+# CONFIG_SJCD is not set
+# CONFIG_ISP16_CDI is not set
+# CONFIG_CDU31A is not set
+# CONFIG_CDU535 is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# iSeries device drivers
+#
+CONFIG_VIOCONS=y
+CONFIG_VIODASD=y
+CONFIG_VIODASD_IDE=y
+CONFIG_VIOCD=m
+# CONFIG_VIOCD_AZTECH is not set
+CONFIG_VIOTAPE=m
+CONFIG_VETH=y
+CONFIG_VIOPATH=y
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_COMPUTONE is not set
+# CONFIG_ROCKETPORT is not set
+# CONFIG_CYCLADES is not set
+# CONFIG_DIGIEPCA is not set
+# CONFIG_DIGI is not set
+# CONFIG_ESPSERIAL is not set
+# CONFIG_MOXA_INTELLIO is not set
+# CONFIG_MOXA_SMARTIO is not set
+# CONFIG_ISI is not set
+# CONFIG_SYNCLINK is not set
+# CONFIG_N_HDLC is not set
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_SX is not set
+# CONFIG_RIO is not set
+# CONFIG_STALDRV is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=1024
+# CONFIG_HVC_CONSOLE is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_INPUT_GAMEPORT is not set
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+# CONFIG_INPUT_CS461X is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_INPUT_SERIO is not set
+# CONFIG_INPUT_SERPORT is not set
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+# CONFIG_INPUT_IFORCE_USB is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_STINGER is not set
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_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_MWAVE is not set
+
+#
+# File systems
+#
+CONFIG_QUOTA=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_CMS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_FREEVXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=y
+CONFIG_NFSD_V3=y
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_SMB_FS=y
+# CONFIG_SMB_NLS_DEFAULT is not set
+CONFIG_NCP_FS=y
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_SMALLDOS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_SMB_NLS=y
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+# CONFIG_USB_UHCI is not set
+# CONFIG_USB_UHCI_ALT is not set
+# CONFIG_USB_OHCI is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_HID is not set
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_DABUSB is not set
+# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_USS720 is not set
+
+#
+# USB Serial Converter support
+#
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_ID75 is not set
+
+#
+# Kernel hacking
+#
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
+# CONFIG_PPCDBG is not set
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/configs/pSeries_defconfig linuxppc64_2_4/arch/ppc64/configs/pSeries_defconfig
--- ../tue/linux-2.4.10-ac12/arch/ppc64/configs/pSeries_defconfig Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/configs/pSeries_defconfig Mon Oct 8 20:27:07 2001
@@ -20,12 +20,17 @@
# CONFIG_PPC_ISERIES is not set
CONFIG_PPC_PSERIES=y
CONFIG_SMP=y
+CONFIG_IRQ_ALL_CPUS=y
+# CONFIG_HMT is not set
CONFIG_MSCHUNKS=y
#
# Loadable module support
#
CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
#
# General setup
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/defconfig linuxppc64_2_4/arch/ppc64/defconfig
--- ../tue/linux-2.4.10-ac12/arch/ppc64/defconfig Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/defconfig Wed Oct 10 14:53:43 2001
@@ -1,9 +1,10 @@
#
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
#
# CONFIG_UID16 is not set
# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
#
# Code maturity level options
@@ -17,15 +18,19 @@
CONFIG_PPC64=y
CONFIG_ALL_PPC=y
CONFIG_SERIAL_CONSOLE=y
-# CONFIG_PPC_ISERIES is not set
CONFIG_PPC_PSERIES=y
+# CONFIG_PPC_ISERIES is not set
CONFIG_SMP=y
+CONFIG_IRQ_ALL_CPUS=y
+# CONFIG_HMT is not set
CONFIG_MSCHUNKS=y
#
# Loadable module support
#
CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
#
# General setup
@@ -54,7 +59,6 @@
# CONFIG_VGA_CONSOLE is not set
CONFIG_FB=y
CONFIG_PROC_DEVICETREE=y
-# CONFIG_MOTOROLA_HOTSWAP is not set
#
# Memory Technology Devices (MTD)
@@ -92,6 +96,7 @@
# CONFIG_MD_RAID0 is not set
# CONFIG_MD_RAID1 is not set
# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
# CONFIG_BLK_DEV_LVM is not set
#
@@ -117,6 +122,10 @@
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
# CONFIG_ATM is not set
+
+#
+#
+#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_DECNET is not set
@@ -134,11 +143,6 @@
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set
-
-#
-# ATA/IDE/MFM/RLL support
-#
-# CONFIG_IDE is not set
# CONFIG_BLK_DEV_IDE_MODES is not set
# CONFIG_BLK_DEV_HD is not set
@@ -146,6 +150,10 @@
# SCSI support
#
CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
CONFIG_BLK_DEV_SD=y
CONFIG_SD_EXTRA_DEVS=40
CONFIG_CHR_DEV_ST=y
@@ -154,6 +162,10 @@
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_SR_EXTRA_DEVS=2
CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
# CONFIG_SCSI_DEBUG_QUEUES is not set
# CONFIG_SCSI_MULTI_LUN is not set
# CONFIG_SCSI_CONSTANTS is not set
@@ -188,7 +200,6 @@
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR_D700 is not set
# CONFIG_SCSI_NCR53C7xx is not set
# CONFIG_SCSI_NCR53C8XX is not set
CONFIG_SCSI_SYM53C8XX=y
@@ -291,6 +302,7 @@
# CONFIG_ACENIC_OMIT_TIGON_I is not set
# CONFIG_DL2K is not set
# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_SK98LIN is not set
@@ -362,7 +374,6 @@
# CONFIG_FB_IMSTT is not set
# CONFIG_FB_S3TRIO is not set
# CONFIG_FB_VGA16 is not set
-# CONFIG_FB_E1355 is not set
CONFIG_FB_MATROX=y
CONFIG_FB_MATROX_MILLENIUM=y
CONFIG_FB_MATROX_MYSTIQUE=y
@@ -374,6 +385,7 @@
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_SIS is not set
# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FBCON_ADVANCED is not set
CONFIG_FBCON_CFB8=y
@@ -387,6 +399,7 @@
# CONFIG_FONT_SUN8x16 is not set
# CONFIG_FONT_PEARL_8x8 is not set
# CONFIG_FONT_ACORN_8x8 is not set
+CONFIG_VIOPATH=y
#
# Character devices
@@ -399,6 +412,7 @@
# CONFIG_SERIAL_NONSTANDARD is not set
CONFIG_UNIX98_PTYS=y
CONFIG_UNIX98_PTY_COUNT=256
+# CONFIG_HVC_CONSOLE is not set
#
# I2C support
@@ -425,6 +439,10 @@
# CONFIG_INPUT_EMU10K1 is not set
# CONFIG_INPUT_SERIO is not set
# CONFIG_INPUT_SERPORT is not set
+
+#
+# Joysticks
+#
# CONFIG_INPUT_ANALOG is not set
# CONFIG_INPUT_A3D is not set
# CONFIG_INPUT_ADI is not set
@@ -465,6 +483,7 @@
# CONFIG_FTAPE is not set
# CONFIG_AGP is not set
# CONFIG_DRM is not set
+# CONFIG_MWAVE is not set
#
# File systems
@@ -496,6 +515,8 @@
# CONFIG_RAMFS is not set
CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_FREEVXFS_FS is not set
# CONFIG_NTFS_FS is not set
@@ -540,6 +561,8 @@
# CONFIG_NCPFS_SMALLDOS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+# CONFIG_ZLIB_FS_INFLATE is not set
#
# Partition Types
@@ -599,47 +622,78 @@
# USB support
#
# CONFIG_USB is not set
+
+#
+# USB Controllers
+#
# CONFIG_USB_UHCI is not set
# CONFIG_USB_UHCI_ALT is not set
# CONFIG_USB_OHCI is not set
+
+#
+# USB Device Class drivers
+#
# CONFIG_USB_AUDIO is not set
# CONFIG_USB_BLUETOOTH is not set
# CONFIG_USB_STORAGE is not set
# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
# CONFIG_USB_STORAGE_SDDR09 is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
+
+#
+# USB Human Interface Devices (HID)
+#
# CONFIG_USB_HID is not set
# CONFIG_USB_HIDDEV is not set
# CONFIG_USB_KBD is not set
# CONFIG_USB_MOUSE is not set
# CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
# CONFIG_USB_DC2XX is not set
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_SCANNER is not set
# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HP5300 is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
# CONFIG_USB_IBMCAM is not set
# CONFIG_USB_OV511 is not set
# CONFIG_USB_PWC is not set
# CONFIG_USB_SE401 is not set
# CONFIG_USB_DSBR is not set
# CONFIG_USB_DABUSB is not set
+
+#
+# USB Network adaptors
+#
# CONFIG_USB_PLUSB is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_CATC is not set
# CONFIG_USB_CDCETHER is not set
# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
# CONFIG_USB_USS720 is not set
#
# USB Serial Converter support
#
# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_DEBUG is not set
# CONFIG_USB_SERIAL_GENERIC is not set
# CONFIG_USB_SERIAL_BELKIN is not set
# CONFIG_USB_SERIAL_WHITEHEAT is not set
@@ -647,6 +701,7 @@
# CONFIG_USB_SERIAL_EMPEG is not set
# CONFIG_USB_SERIAL_FTDI_SIO is not set
# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IR is not set
# CONFIG_USB_SERIAL_EDGEPORT is not set
# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
# CONFIG_USB_SERIAL_KEYSPAN is not set
@@ -659,8 +714,14 @@
# CONFIG_USB_SERIAL_MCT_U232 is not set
# CONFIG_USB_SERIAL_PL2303 is not set
# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# Miscellaneous USB drivers
+#
# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_ID75 is not set
#
# Kernel hacking
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/HvLpConfig.c linuxppc64_2_4/arch/ppc64/kernel/HvLpConfig.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/HvLpConfig.c Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/HvLpConfig.c Mon Sep 24 18:25:38 2001
@@ -26,38 +26,3 @@
return HvLpConfig_getLpIndex();
}
-const HvLpIndexMap HvLpIndexMapDefault = (1 << (sizeof(HvLpIndexMap) * 8 - 1));
-const HvLpIndex HvHardcodedPrimaryLpIndex = 0;
-const HvLpIndex HvMaxArchitectedLps = HVMAXARCHITECTEDLPS;
-const HvLpVirtualLanIndex HvMaxArchitectedVirtualLans = 16;
-const HvLpSharedPoolIndex HvMaxArchitectedSharedPools = 16;
-const HvLpSharedPoolIndex HvMaxSupportedSharedPools = 1;
-const HvLpIndex HvMaxRuntimeLpsPreCondor = 12;
-const HvLpIndex HvMaxRuntimeLps = HVMAXARCHITECTEDLPS;
-const HvLpIndex HvLpIndexInvalid = 0xff;
-const u16 HvInvalidProcIndex = 0xffff;
-const u32 HvVirtualFlashSize = 0x200;
-const u32 HvMaxBusesPreCondor = 32;
-const u32 HvMaxBusesCondor = 256;
-const u32 HvMaxArchitectedBuses = 512;
-const HvLpBus HvCspBusNumber = 1;
-const u32 HvMaxSanHwSets = 16;
-const HvLpCard HvMaxSystemIops = 200;
-const HvLpCard HvMaxBusIops = 20;
-const u16 HvMaxUnitsPerIop = 100;
-const u64 HvPageSize = 4 * 1024;
-const u64 HvChunkSize = HVCHUNKSIZE;
-const u64 HvChunksPerMeg = HVCHUNKSPERMEG;
-const u64 HvPagesPerChunk = HVPAGESPERCHUNK;
-const u64 HvPagesPerMeg = HVPAGESPERMEG;
-const u64 HvLpMinMegsPrimary = HVLPMINMEGSPRIMARY;
-const u64 HvLpMinMegsSecondary = HVLPMINMEGSSECONDARY;
-const u64 HvLpMinChunksPrimary = HVLPMINMEGSPRIMARY * HVCHUNKSPERMEG;
-const u64 HvLpMinChunksSecondary = HVLPMINMEGSSECONDARY * HVCHUNKSPERMEG;
-const u64 HvLpMinPagesPrimary = HVLPMINMEGSPRIMARY * HVPAGESPERMEG;
-const u64 HvLpMinPagesSecondary = HVLPMINMEGSSECONDARY * HVPAGESPERMEG;
-const u8 HvLpMinProcs = 1;
-const u8 HvLpConfigMinInteract = 1;
-const u16 HvLpMinSharedProcUnitsX100 = 10;
-const u16 HvLpMaxSharedProcUnitsX100 = 100;
-const HvLpSharedPoolIndex HvLpSharedPoolIndexInvalid = 0xff;
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/ItLpQueue.c linuxppc64_2_4/arch/ppc64/kernel/ItLpQueue.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/ItLpQueue.c Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/ItLpQueue.c Tue Sep 18 14:27:22 2001
@@ -10,14 +10,43 @@
#include
#include
+#include
#include
+#include
#include
#include
#include
#include
+static __inline__ int set_inUse( struct ItLpQueue * lpQueue )
+{
+ int t;
+ u32 * inUseP = &(lpQueue->xInUseWord);
+
+ __asm__ __volatile__("\n\
+1: lwarx %0,0,%2 \n\
+ cmpi 0,%0,0 \n\
+ li %0,0 \n\
+ bne- 2f \n\
+ addi %0,%0,1 \n\
+ stwcx. %0,0,%2 \n\
+ bne- 1b \n\
+2: eieio"
+ : "=&r" (t), "=m" (lpQueue->xInUseWord)
+ : "r" (inUseP), "m" (lpQueue->xInUseWord)
+ : "cc");
+
+ return t;
+}
+
+static __inline__ void clear_inUse( struct ItLpQueue * lpQueue )
+{
+ lpQueue->xInUseWord = 0;
+}
+
/* Array of LpEvent handler functions */
extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
+unsigned long ItLpQueueInProcess = 0;
struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue )
{
@@ -76,7 +105,16 @@
{
unsigned numIntsProcessed = 0;
struct HvLpEvent * nextLpEvent;
+
+ /* If we have recursed, just return */
+ if ( !set_inUse( lpQueue ) )
+ return 0;
+ if (ItLpQueueInProcess == 0)
+ ItLpQueueInProcess = 1;
+ else
+ BUG();
+
for (;;) {
nextLpEvent = ItLpQueue_getNextLpEvent( lpQueue );
if ( nextLpEvent ) {
@@ -119,5 +157,12 @@
else /* If nothing left then we are done */
break;
}
+
+ ItLpQueueInProcess = 0;
+ mb();
+ clear_inUse( lpQueue );
+
+ get_paca()->lpEvent_count += numIntsProcessed;
+
return numIntsProcessed;
}
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/LparData.c linuxppc64_2_4/arch/ppc64/kernel/LparData.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/LparData.c Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/LparData.c Tue Oct 9 09:18:59 2001
@@ -71,7 +71,7 @@
0, /* shared processors */
0, /* HMT allowed */
6, /* TEMP: This allows non-GA driver */
- 3, /* We are v5r1m0 */
+ 4, /* We are v5r2m0 */
3, /* Min supported PLIC = v5r1m0 */
3, /* Min usuable PLIC = v5r1m0 */
{ 0xd3, 0x89, 0x95, 0xa4, /* "Linux 2.4 "*/
@@ -188,9 +188,10 @@
26992, /* 7 length of MS VPD */
0, /* 8 */
sizeof(struct ItLpNaca),/* 9 length of LP Naca */
- sizeof(struct SpCommArea), /* 10 */
+ 0, /* 10 */
256, /* 11 length of Recovery Log Buf */
- 0,0,0,0, /* 12 - 15 */
+ sizeof(struct SpCommArea), /* 12 length of SP Comm Area */
+ 0,0,0, /* 13 - 15 */
sizeof(struct IoHriProcessorVpd),/* 16 length of Proc Vpd */
0,0,0,0,0,0, /* 17 - 22 */
sizeof(struct ItLpQueue),/* 23 length of Lp Queue */
@@ -204,9 +205,10 @@
&xMsVpd, /* 7 MS Vpd */
0, /* 8 */
&itLpNaca, /* 9 LpNaca */
- &xSpCommArea, /* 10 */
+ 0, /* 10 */
&xRecoveryLogBuffer, /* 11 Recovery Log Buffer */
- 0,0,0,0, /* 12 - 15 */
+ &xSpCommArea, /* 12 SP Comm Area */
+ 0,0,0, /* 13 - 15 */
&xIoHriProcessorVpd, /* 16 Proc Vpd */
0,0,0,0,0,0, /* 17 - 22 */
&xItLpQueue, /* 23 Lp Queue */
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/Makefile linuxppc64_2_4/arch/ppc64/kernel/Makefile
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/Makefile Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/Makefile Sat Oct 6 15:14:17 2001
@@ -24,16 +24,20 @@
align.o semaphore.o bitops.o stab.o htab.o pacaData.o \
LparData.o udbg.o binfmt_elf32.o sys_ppc32.o sys32.o \
ioctl32.o ptrace32.o signal32.o open_pic.o xics.o \
+ pSeries_lpar.o pSeries_hvCall.o \
pmc.o mf_proc.o proc_pmc.o proc_pcifr.o iSeries_setup.o \
- ItLpQueue.o hvCall.o mf.o viopath.o HvLpEvent.o \
- iSeries_proc.o HvCall.o flight_recorder.o HvLpConfig.o
+ ItLpQueue.o hvCall.o mf.o HvLpEvent.o ras.o \
+ iSeries_proc.o HvCall.o flight_recorder.o HvLpConfig.o \
+ rtc.o
-obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_PCI) += pci.o pci_dn.o pci_dma.o
ifeq ($(CONFIG_PPC_ISERIES),y)
-obj-$(CONFIG_PCI) += iSeries_dma.o iSeries_rtc.o
-else
-obj-$(CONFIG_PCI) += pci_dma.o
+obj-$(CONFIG_PCI) += iSeries_pci.o iSeries_pci_reset.o iSeries_IoMmTable.o iSeries_irq.o iSeries_VpdInfo.o XmPciLpEvent.o
+endif
+ifeq ($(CONFIG_PPC_PSERIES),y)
+obj-$(CONFIG_PCI) += pSeries_pci.o
+obj-y += rtasd.o
endif
obj-$(CONFIG_KGDB) += ppc-stub.o
@@ -46,8 +50,8 @@
endif
ifeq ($(CONFIG_ALL_PPC),y)
- obj-y += prom.o lmb.o rtas.o rtas-eventscan.o rtas-proc.o chrp_setup.o \
- chrp_time.o pSeries_pci.o i8259.o
+ obj-y += prom.o lmb.o rtas.o rtas-proc.o chrp_setup.o \
+ i8259.o
endif
include $(TOPDIR)/Rules.make
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/XmPciLpEvent.c linuxppc64_2_4/arch/ppc64/kernel/XmPciLpEvent.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/XmPciLpEvent.c Wed Dec 31 18:00:00 1969
+++ linuxppc64_2_4/arch/ppc64/kernel/XmPciLpEvent.c Thu Sep 27 11:19:20 2001
@@ -0,0 +1,155 @@
+/*
+ * File XmPciLpEvent.h created by Wayne Holm on Mon Jan 15 2001.
+ *
+ * This module handles PCI interrupt events sent by the iSeries Hypervisor.
+*/
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+long Pci_Interrupt_Count = 0;
+long Pci_Event_Count = 0;
+
+enum XmPciLpEvent_Subtype {
+ XmPciLpEvent_BusCreated = 0, // PHB has been created
+ XmPciLpEvent_BusFailed = 1, // PHB has failed
+ XmPciLpEvent_BusRecovered = 12, // PHB has been recovered
+ XmPciLpEvent_NodeFailed = 4, // Multi-adapter bridge has failed
+ XmPciLpEvent_NodeRecovered = 5, // Multi-adapter bridge has recovered
+ XmPciLpEvent_SlotInterrupt = 22 // Slot interrupt
+};
+
+struct XmPciLpEvent_BusInterrupt {
+ HvBusNumber busNumber;
+ HvSubBusNumber subBusNumber;
+};
+
+struct XmPciLpEvent_NodeInterrupt {
+ HvBusNumber busNumber;
+ HvSubBusNumber subBusNumber;
+ HvAgentId deviceId;
+};
+
+struct XmPciLpEvent {
+ struct HvLpEvent hvLpEvent;
+
+ union {
+ u64 alignData; // Align on an 8-byte boundary
+
+ struct {
+ u32 fisr;
+ HvBusNumber busNumber;
+ HvSubBusNumber subBusNumber;
+ HvAgentId deviceId;
+ } slotInterrupt;
+
+ struct XmPciLpEvent_BusInterrupt busFailed;
+ struct XmPciLpEvent_BusInterrupt busRecovered;
+ struct XmPciLpEvent_BusInterrupt busCreated;
+
+ struct XmPciLpEvent_NodeInterrupt nodeFailed;
+ struct XmPciLpEvent_NodeInterrupt nodeRecovered;
+
+ } eventData;
+
+};
+
+static void intReceived(struct XmPciLpEvent* eventParm, struct pt_regs* regsParm);
+
+static void XmPciLpEvent_handler( struct HvLpEvent* eventParm, struct pt_regs* regsParm) {
+ //PPCDBG(PPCDBG_BUSWALK,"XmPciLpEvent_handler, type 0x%x\n",eventParm->xType );
+ ++Pci_Event_Count;
+
+ if (eventParm && eventParm->xType == HvLpEvent_Type_PciIo) {
+ switch( eventParm->xFlags.xFunction ) {
+ case HvLpEvent_Function_Int:
+ intReceived( (struct XmPciLpEvent*)eventParm, regsParm );
+ break;
+ case HvLpEvent_Function_Ack:
+ printk(KERN_ERR "XmPciLpEvent.c: unexpected ack received\n");
+ break;
+ default:
+ printk(KERN_ERR "XmPciLpEvent.c: unexpected event function %d\n",(int)eventParm->xFlags.xFunction);
+ break;
+ }
+ }
+ else if (event) {
+ printk(KERN_ERR "XmPciLpEvent.c: Unrecognized PCI event type 0x%x\n",(int)eventParm->xType);
+ }
+ else {
+ printk(KERN_ERR "XmPciLpEvent.c: NULL event received\n");
+ }
+}
+
+static void intReceived(struct XmPciLpEvent* eventParm, struct pt_regs* regsParm) {
+ int irq;
+
+ ++Pci_Interrupt_Count;
+ //PPCDBG(PPCDBG_BUSWALK,"PCI: XmPciLpEvent.c: intReceived\n");
+
+ switch (eventParm->hvLpEvent.xSubtype) {
+ case XmPciLpEvent_SlotInterrupt:
+ irq = eventParm->hvLpEvent.xCorrelationToken;
+ /* Dispatch the interrupt handlers for this irq */
+ ppc_irq_dispatch_handler(regsParm, irq);
+ HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber,
+ eventParm->eventData.slotInterrupt.subBusNumber,
+ eventParm->eventData.slotInterrupt.deviceId);
+ break;
+ /* Ignore error recovery events for now */
+ case XmPciLpEvent_BusCreated:
+ printk(KERN_INFO "XmPciLpEvent.c: system bus %d created\n", eventParm->eventData.busCreated.busNumber);
+ break;
+ case XmPciLpEvent_BusFailed:
+ printk(KERN_INFO "XmPciLpEvent.c: system bus %d failed\n", eventParm->eventData.busFailed.busNumber);
+ break;
+ case XmPciLpEvent_BusRecovered:
+ printk(KERN_INFO "XmPciLpEvent.c: system bus %d recovered\n", eventParm->eventData.busRecovered.busNumber);
+ break;
+ case XmPciLpEvent_NodeFailed:
+ printk(KERN_INFO "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d failed\n", eventParm->eventData.nodeFailed.busNumber, eventParm->eventData.nodeFailed.subBusNumber, eventParm->eventData.nodeFailed.deviceId);
+ break;
+ case XmPciLpEvent_NodeRecovered:
+ printk(KERN_INFO "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d recovered\n", eventParm->eventData.nodeRecovered.busNumber, eventParm->eventData.nodeRecovered.subBusNumber, eventParm->eventData.nodeRecovered.deviceId);
+ break;
+ default:
+ printk(KERN_ERR "XmPciLpEvent.c: unrecognized event subtype 0x%x\n",
+ eventParm->hvLpEvent.xSubtype);
+ break;
+ };
+}
+
+
+/* This should be called sometime prior to buswalk (init_IRQ would be good) */
+int XmPciLpEvent_init() {
+ int xRc;
+ PPCDBG(PPCDBG_BUSWALK,"XmPciLpEvent_init, Register Event type 0x%04X\n",HvLpEvent_Type_PciIo);
+
+ xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo, &XmPciLpEvent_handler);
+ if (xRc == 0) {
+ xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0);
+ if (xRc != 0) {
+ printk(KERN_ERR "XmPciLpEvent.c: open event path failed with rc 0x%x\n", xRc);
+ }
+ }
+ else {
+ printk(KERN_ERR "XmPciLpEvent.c: register handler failed with rc 0x%x\n", xRc);
+ }
+ return xRc;
+}
+
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/align.c linuxppc64_2_4/arch/ppc64/kernel/align.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/align.c Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/align.c Fri Sep 14 07:41:02 2001
@@ -252,11 +252,6 @@
}
flags = aligninfo[instr].flags;
-
- /* For the 4xx-family processors, the 'dar' field of the
- * pt_regs structure is overloaded and is really from the DEAR.
- */
-
addr = (unsigned char *)regs->dar;
/* Verify the address of the operand */
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/binfmt_elf32.c linuxppc64_2_4/arch/ppc64/kernel/binfmt_elf32.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/binfmt_elf32.c Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/binfmt_elf32.c Tue Sep 25 13:52:29 2001
@@ -70,6 +70,7 @@
#define NEW_TO_OLD_UID(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
#define NEW_TO_OLD_GID(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
+extern void start_thread32(struct pt_regs *, unsigned long, unsigned long);
#undef start_thread
#define start_thread start_thread32
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/chrp_setup.c linuxppc64_2_4/arch/ppc64/kernel/chrp_setup.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/chrp_setup.c Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/chrp_setup.c Sat Sep 29 13:41:46 2001
@@ -51,6 +51,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -68,11 +69,6 @@
extern volatile unsigned char *chrp_int_ack_special;
extern struct Naca *naca;
-unsigned long chrp_get_rtc_time(void);
-int chrp_set_rtc_time(unsigned long nowtime);
-void chrp_calibrate_decr(void);
-long chrp_time_init(void);
-
void chrp_setup_pci_ptrs(void);
void chrp_progress(char *, unsigned short);
void chrp_request_regions(void);
@@ -83,15 +79,19 @@
char raw_mode);
extern char pckbd_unexpected_up(unsigned char keycode);
extern void pckbd_leds(unsigned char leds);
-extern int pckbd_rate(struct kbd_repeat *rep);
extern void pckbd_init_hw(void);
extern unsigned char pckbd_sysrq_xlate[128];
extern void openpic_init_IRQ(void);
+extern void init_ras_IRQ(void);
extern void find_and_init_phbs(void);
extern void pSeries_pcibios_fixup(void);
extern void iSeries_pcibios_fixup(void);
+extern void pSeries_get_rtc_time(struct rtc_time *rtc_time);
+extern int pSeries_set_rtc_time(struct rtc_time *rtc_time);
+void pSeries_calibrate_decr(void);
+
kdev_t boot_dev;
unsigned long virtPython0Facilities = 0; // python0 facility area (memory mapped io) (64-bit format) VIRTUAL address.
@@ -100,8 +100,6 @@
extern int probingmem;
extern unsigned long loops_per_jiffy;
-extern void *comport1;
-
#ifdef CONFIG_BLK_DEV_RAM
extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */
extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */
@@ -124,53 +122,6 @@
return len;
}
-/*
- * Fixes for the National Semiconductor PC78308VUL SuperI/O
- *
- * Some versions of Open Firmware incorrectly initialize the IRQ settings
- * for keyboard and mouse
- */
-static inline void __init sio_write(u8 val, u8 index)
-{
- outb(index, 0x15c);
- outb(val, 0x15d);
-}
-
-static inline u8 __init sio_read(u8 index)
-{
- outb(index, 0x15c);
- return inb(0x15d);
-}
-
-static void __init sio_fixup_irq(const char *name, u8 device, u8 level,
- u8 type)
-{
- u8 level0, type0, active;
- struct device_node *root;
-
- root = find_path_device("/");
- if (root &&
- !strncmp(get_property(root, "model", NULL), "IBM,LongTrail", 13 ) )
- {
- /* select logical device */
- sio_write(device, 0x07);
- active = sio_read(0x30);
- level0 = sio_read(0x70);
- type0 = sio_read(0x71);
- printk("sio: %s irq level %d, type %d, %sactive: ", name, level0, type0,
- !active ? "in" : "");
- if (level0 == level && type0 == type && active)
- printk("OK\n");
- else {
- printk("remapping to level %d, type %d, active\n", level, type);
- sio_write(0x01, 0x30);
- sio_write(level, 0x70);
- sio_write(type, 0x71);
- }
- }
-
-}
-
void __init chrp_request_regions(void) {
request_region(0x20,0x20,"pic1");
request_region(0xa0,0x20,"pic2");
@@ -230,17 +181,6 @@
#ifdef CONFIG_DUMMY_CONSOLE
conswitchp = &dummy_con;
#endif
-
- /* Get the event scan rate for the rtas so we know how
- * often it expects a heartbeat. -- Cort
- */
- if (rtas.event_scan.rate) {
- ppc_md.heartbeat = rtas_event_scan;
- ppc_md.heartbeat_reset = (HZ/rtas.event_scan.rate*60)-1;
- ppc_md.heartbeat_count = 1;
- printk("RTAS Event Scan Rate: %lu (%lu jiffies)\n",
- rtas.event_scan.rate, ppc_md.heartbeat_reset);
- }
}
void __init
@@ -254,10 +194,36 @@
ppc_md.progress(UTS_RELEASE, 0x7777);
}
+
+/* Early initialization. Relocation is on but do not reference unbolted pages */
+void __init pSeries_init_early(void)
+{
+#ifdef CONFIG_PPC_PSERIES /* This ifdef should go away */
+ void *comport;
+
+ htpe_init_pSeries();
+ tce_init_pSeries();
+ pSeries_pcibios_init_early();
+
+#ifdef CONFIG_SMP
+ smp_init_pSeries();
+#endif
+
+ /* Map the uart for udbg. */
+ comport = (void *)ioremap(naca->serialPortAddr, 16);
+ udbg_init_uart(comport);
+
+ ppc_md.udbg_putc = udbg_putc;
+ ppc_md.udbg_getc = udbg_getc;
+ ppc_md.udbg_getc_poll = udbg_getc_poll;
+#endif
+}
+
void __init
chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
{
+#if 0 /* PPPBBB remove this later... -Peter */
#ifdef CONFIG_BLK_DEV_INITRD
/* take care of initrd if we have one */
if ( r6 )
@@ -266,8 +232,7 @@
initrd_end = __va(r6 + r7);
}
#endif /* CONFIG_BLK_DEV_INITRD */
-
- /* pci_dram_offset/isa_io_base/isa_mem_base set by setup_pci_ptrs() */
+#endif
ppc_md.ppc_machine = _machine;
@@ -275,7 +240,7 @@
ppc_md.setup_residual = NULL;
ppc_md.get_cpuinfo = chrp_get_cpuinfo;
if(naca->interrupt_controller == IC_OPEN_PIC) {
- ppc_md.init_IRQ = openpic_init_IRQ;
+ ppc_md.init_IRQ = openpic_init_IRQ;
ppc_md.get_irq = openpic_get_irq;
ppc_md.post_irq = NULL;
} else {
@@ -283,6 +248,7 @@
ppc_md.get_irq = xics_get_irq;
ppc_md.post_irq = NULL;
}
+ ppc_md.init_ras_IRQ = init_ras_IRQ;
#ifndef CONFIG_PPC_ISERIES
ppc_md.pcibios_fixup = pSeries_pcibios_fixup;
@@ -298,26 +264,31 @@
ppc_md.power_off = rtas_power_off;
ppc_md.halt = rtas_halt;
- ppc_md.time_init = chrp_time_init;
- ppc_md.set_rtc_time = chrp_set_rtc_time;
- ppc_md.get_rtc_time = chrp_get_rtc_time;
- ppc_md.calibrate_decr = chrp_calibrate_decr;
+ ppc_md.time_init = NULL;
+ ppc_md.get_boot_time = pSeries_get_rtc_time;
+ ppc_md.get_rtc_time = pSeries_get_rtc_time;
+ ppc_md.set_rtc_time = pSeries_set_rtc_time;
+ ppc_md.calibrate_decr = pSeries_calibrate_decr;
+
+ ppc_md.progress = chrp_progress;
#ifdef CONFIG_VT
- ppc_md.kbd_setkeycode = pckbd_setkeycode;
- ppc_md.kbd_getkeycode = pckbd_getkeycode;
- ppc_md.kbd_translate = pckbd_translate;
- ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
- ppc_md.kbd_leds = pckbd_leds;
- ppc_md.kbd_init_hw = pckbd_init_hw;
- ppc_md.kbd_rate = pckbd_rate;
+ {
+ struct device_node *dn = find_type_devices("keyboard");
+ if (dn) {
+ ppc_md.kbd_setkeycode = pckbd_setkeycode;
+ ppc_md.kbd_getkeycode = pckbd_getkeycode;
+ ppc_md.kbd_translate = pckbd_translate;
+ ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
+ ppc_md.kbd_leds = pckbd_leds;
+ ppc_md.kbd_init_hw = pckbd_init_hw;
#ifdef CONFIG_MAGIC_SYSRQ
- ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate;
- SYSRQ_KEY = 0x63; /* Print Screen */
-#endif /* CONFIG_MAGIC_SYSRQ */
-#endif /* CONFIG_VT */
-
- ppc_md.progress = chrp_progress;
+ ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate;
+ SYSRQ_KEY = 0x63; /* Print Screen */
+#endif
+ }
+ }
+#endif
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
ppc_ide_md.insw = chrp_ide_insw;
@@ -332,6 +303,7 @@
ppc_ide_md.io_base = _IO_BASE;
#endif
+
ppc_md.progress("Linux ppc64\n", 0x0);
}
@@ -343,12 +315,12 @@
char *os;
static int max_width;
- if ( (_machine != _MACH_chrp) || !rtas.base )
- return;
-
if (hex)
udbg_printf(" %s\n", s);
+ if (!rtas.base || (_machine != _MACH_pSeries))
+ return;
+
if (max_width == 0) {
if ( (root = find_path_device("/rtas")) &&
(p = (unsigned int *)get_property(root,
@@ -386,9 +358,26 @@
call_rtas( "display-character", 1, 1, NULL, ' ' );
}
-void chrp_init_map_io_space(void)
+void __init pSeries_calibrate_decr(void)
{
- /* naca->serialPortAddr is initialized earlier in prom.c */
- comport1 = (void *)ioremap(naca->serialPortAddr, PAGE_SIZE);
-}
+ struct device_node *cpu;
+ int *fp;
+ unsigned long freq;
+
+ /*
+ * The cpu node should have a timebase-frequency property
+ * to tell us the rate at which the decrementer counts.
+ */
+ freq = 16666000; /* hardcoded default */
+ cpu = find_type_devices("cpu");
+ if (cpu != 0) {
+ fp = (int *) get_property(cpu, "timebase-frequency", NULL);
+ if (fp != 0)
+ freq = *fp;
+ }
+ printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
+ freq/1000000, freq%1000000 );
+ tb_ticks_per_jiffy = freq / HZ;
+ tb_ticks_per_usec = freq / 1000000;
+}
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/chrp_time.c linuxppc64_2_4/arch/ppc64/kernel/chrp_time.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/chrp_time.c Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/chrp_time.c Wed Dec 31 18:00:00 1969
@@ -1,203 +0,0 @@
-/*
- * linux/arch/i386/kernel/time.c
- *
- * Copyright (C) 1991, 1992, 1995 Linus Torvalds
- *
- * Adapted for PowerPC (PreP) by Gary Thomas
- * Modified by Cort Dougan (cort@cs.nmt.edu)
- * copied and modified from intel version
- * Modified for PPC64 by PPC64 Team, Copyright IBM Corp
- *
- * 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 "time.h" */
-
-static int nvram_as1 = NVRAM_AS1;
-static int nvram_as0 = NVRAM_AS0;
-static int nvram_data = NVRAM_DATA;
-
-long __init chrp_time_init(void)
-{
- struct device_node *rtcs;
- int base;
-
- rtcs = find_compatible_devices("rtc", "pnpPNP,b00");
- if (rtcs == NULL || rtcs->addrs == NULL) {
- return 0;
- }
- base = rtcs->addrs[0].address;
- nvram_as1 = 0;
- nvram_as0 = base;
- nvram_data = base + 1;
-
- return 0;
-}
-
-int __chrp chrp_cmos_clock_read(int addr)
-{
- int retval;
-
-#if 1 /* DRENG -- see chrp_time_init, chrp_cmos_clock_write
- * I think this is broken in general on 64b --
- * nvram_as0 = -1 in 64b format
- */
- if (nvram_as1 != 0) {
- outb(addr>>8, nvram_as1);
- }
- outb(addr, nvram_as0);
- retval = inb(nvram_data);
- return retval;
-#else
- return(-1);
-#endif
-}
-
-void __chrp chrp_cmos_clock_write(unsigned long val, int addr)
-{
-#if 1 /* DRENG -- see chrp_cmos_clock_read */
- if (nvram_as1 != 0)
- outb(addr>>8, nvram_as1);
- outb(addr, nvram_as0);
- outb(val, nvram_data);
- return;
-#else
- return;
-#endif
-}
-
-/*
- * Set the hardware clock. -- Cort
- */
-int __chrp chrp_set_rtc_time(unsigned long nowtime)
-{
- unsigned char save_control, save_freq_select;
- struct rtc_time tm;
-
- to_tm(nowtime, &tm);
-
- save_control = chrp_cmos_clock_read(RTC_CONTROL); /* tell the clock it's being set */
-
- chrp_cmos_clock_write((save_control|RTC_SET), RTC_CONTROL);
-
- save_freq_select = chrp_cmos_clock_read(RTC_FREQ_SELECT); /* stop and reset prescaler */
-
- chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
-
- tm.tm_year -= 1900;
- if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
- BIN_TO_BCD(tm.tm_sec);
- BIN_TO_BCD(tm.tm_min);
- BIN_TO_BCD(tm.tm_hour);
- BIN_TO_BCD(tm.tm_mon);
- BIN_TO_BCD(tm.tm_mday);
- BIN_TO_BCD(tm.tm_year);
- }
- chrp_cmos_clock_write(tm.tm_sec,RTC_SECONDS);
- chrp_cmos_clock_write(tm.tm_min,RTC_MINUTES);
- chrp_cmos_clock_write(tm.tm_hour,RTC_HOURS);
- chrp_cmos_clock_write(tm.tm_mon,RTC_MONTH);
- chrp_cmos_clock_write(tm.tm_mday,RTC_DAY_OF_MONTH);
- chrp_cmos_clock_write(tm.tm_year,RTC_YEAR);
-
- /* The following flags have to be released exactly in this order,
- * otherwise the DS12887 (popular MC146818A clone with integrated
- * battery and quartz) will not reset the oscillator and will not
- * update precisely 500 ms later. You won't find this mentioned in
- * the Dallas Semiconductor data sheets, but who believes data
- * sheets anyway ... -- Markus Kuhn
- */
- chrp_cmos_clock_write(save_control, RTC_CONTROL);
- chrp_cmos_clock_write(save_freq_select, RTC_FREQ_SELECT);
-
- if ( (time_state == TIME_ERROR) || (time_state == TIME_BAD) )
- time_state = TIME_OK;
- return 0;
-}
-
-unsigned long __chrp chrp_get_rtc_time(void)
-{
- unsigned int year, mon, day, hour, min, sec;
- int i;
-
- /* The Linux interpretation of the CMOS clock register contents:
- * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
- * RTC registers show the second which has precisely just started.
- * Let's hope other operating systems interpret the RTC the same way.
- */
- /* read RTC exactly on falling edge of update flag */
- for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
- if (chrp_cmos_clock_read(RTC_FREQ_SELECT) & RTC_UIP)
- break;
- for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
- if (!(chrp_cmos_clock_read(RTC_FREQ_SELECT) & RTC_UIP))
- break;
- do { /* Isn't this overkill ? UIP above should guarantee consistency */
- sec = chrp_cmos_clock_read(RTC_SECONDS);
- min = chrp_cmos_clock_read(RTC_MINUTES);
- hour = chrp_cmos_clock_read(RTC_HOURS);
- day = chrp_cmos_clock_read(RTC_DAY_OF_MONTH);
- mon = chrp_cmos_clock_read(RTC_MONTH);
- year = chrp_cmos_clock_read(RTC_YEAR);
- } while (sec != chrp_cmos_clock_read(RTC_SECONDS));
- if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
- {
- BCD_TO_BIN(sec);
- BCD_TO_BIN(min);
- BCD_TO_BIN(hour);
- BCD_TO_BIN(day);
- BCD_TO_BIN(mon);
- BCD_TO_BIN(year);
- }
- if ((year += 1900) < 1970)
- year += 100;
- return mktime(year, mon, day, hour, min, sec);
-}
-
-extern void setup_default_decr(void);
-
-void __init chrp_calibrate_decr(void)
-{
- struct device_node *cpu;
- int *fp;
- unsigned long freq;
-
- /*
- * The cpu node should have a timebase-frequency property
- * to tell us the rate at which the decrementer counts.
- */
- freq = 16666000; /* hardcoded default */
- cpu = find_type_devices("cpu");
- if (cpu != 0) {
- fp = (int *) get_property(cpu, "timebase-frequency", NULL);
- if (fp != 0)
- freq = *fp;
- }
- printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
- freq/1000000, freq%1000000 );
-
- tb_ticks_per_jiffy = freq / HZ;
- tb_ticks_per_usec = freq / 1000000;
- setup_default_decr();
-}
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/entry.S linuxppc64_2_4/arch/ppc64/kernel/entry.S
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/entry.S Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/entry.S Tue Sep 18 14:27:22 2001
@@ -32,6 +32,10 @@
#include
#include
+#ifdef CONFIG_PPC_ISERIES
+#define DO_SOFT_DISABLE
+#endif
+
#undef SHOW_SYSCALLS
#undef SHOW_SYSCALLS_TASK
@@ -324,19 +328,19 @@
_GLOBAL(ret_from_except)
#ifdef CONFIG_PPC_ISERIES
- ld r5,_MSR(r1)
- andi. r5,r5,MSR_EE
+ ld r5,SOFTE(r1)
+ cmpdi 0,r5,0
beq 4f
irq_recheck:
- mfmsr r5
- andi. r5,r5,MSR_EE
- bne 4f
/*
* Check for pending interrupts (iSeries)
*/
- CHECKANYINT(r4,r5)
+ CHECKANYINT(r3,r4)
beq+ 4f /* skip do_IRQ if no interrupts */
+ mfspr r5,SPRG3
+ li r3,0
+ stb r3,PACAPROCENABLED(r5) /* ensure we are disabled */
addi r3,r1,STACK_FRAME_OVERHEAD
bl .do_IRQ
b irq_recheck /* loop back and handle more */
@@ -386,23 +390,31 @@
rldicl r0,r0,16,0 /* clear MSR_EE */
mtmsrd r0 /* Update machine state */
#ifdef CONFIG_PPC_ISERIES
- ld r0,_MSR(r1)
- andi. r3,r0,MSR_EE
+ ld r0,SOFTE(r1)
+ cmpi 0,r0,0
beq+ 1f
CHECKANYINT(r4,r3)
- bne- irq_recheck
+ beq+ 1f
+ mfmsr r0
+ ori r0,r0,MSR_EE
+ mtmsr r0
+ b irq_recheck
1:
#endif
stdcx. r0,0,r1 /* to clear the reservation */
+ mfspr r4,SPRG3 /* current task's PACA */
+#ifdef DO_SOFT_DISABLE
+ ld r0,SOFTE(r1)
+ stb r0,PACAPROCENABLED(r4)
+#endif
/* if returning to user mode, save kernel SP */
ld r0,_MSR(r1)
andi. r0,r0,MSR_PR
beq+ 1f
addi r0,r1,INT_FRAME_SIZE /* size of frame */
- mfspr r4,SPRG3 /* current task's PACA */
ld r2,PACACURRENT(r4) /* Get 'current' */
std r0,THREAD+KSP(r2) /* save kernel stack pointer */
std r1,PACAKSAVE(r4) /* save exception stack pointer */
@@ -419,58 +431,8 @@
ld r4,GPR4(r1)
ld r1,GPR1(r1)
- /* sync required to force memory operations on this processor */
- /* to complete before the current thread gives up control. */
- SYNC
rfid
-#ifdef CONFIG_PPC_ISERIES
-/*
- * Fake an interrupt from kernel mode.
- * This is used when enable_irq loses an interrupt.
- * We only fill in the stack frame minimally.
- */
-_GLOBAL(fake_interrupt)
- mflr r0
- std r0,16(r1)
- stdu r1,-(INT_FRAME_SIZE)(r1)
- std r0,_NIP(r1)
- std r0,_LINK(r1)
- mfmsr r3
- std r3,_MSR(r1)
- li r0,0x0fac
- std r0,TRAP(r1)
- addi r3,r1,STACK_FRAME_OVERHEAD
- li r4,1
- bl .do_IRQ
- addi r1,r1,INT_FRAME_SIZE
- ld r0,16(r1)
- mtlr r0
- blr
-
-/*
- * Fake a decrementer from kernel mode.
- * This is used when the decrementer pops in
- * the hypervisor. We only fill in the stack
- * frame minimally
- */
-_GLOBAL(fake_decrementer)
- mflr r0
- std r0,16(r1)
- stdu r1,-(INT_FRAME_SIZE)(r1)
- std r0,_NIP(r1)
- std r0,_LINK(r1)
- mfmsr r3
- std r3,_MSR(r1)
- li r0,0x0fac
- std r0,TRAP(r1)
- addi r3,r1,STACK_FRAME_OVERHEAD
- bl .timer_interrupt
- addi r1,r1,INT_FRAME_SIZE
- ld r0,16(r1)
- mtlr r0
- blr
-#endif
/*
* On CHRP, the Run-Time Abstraction Services (RTAS) have to be
* called with the MMU off.
@@ -633,7 +595,7 @@
rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
andc r11,r11,r12
mtmsrd r11
- SYNC
+ isync
REST_8GPRS(2, r1) // Restore the TOC & incoming param(s)
REST_8GPRS(14, r1) // Restore the non-volatiles
@@ -643,7 +605,7 @@
mfspr r1,SPRG2
ld r6,_MSR(r1)
mtmsrd r6
- SYNC
+ isync
REST_GPR(2, r1) // Restore the TOC
REST_8GPRS(14, r1) // Restore the non-volatiles
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/flight_recorder.c linuxppc64_2_4/arch/ppc64/kernel/flight_recorder.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/flight_recorder.c Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/flight_recorder.c Thu Sep 27 11:19:20 2001
@@ -50,6 +50,7 @@
static char LogText[512];
static int LogTextIndex;
+static int LogCount = 0;
static spinlock_t Fr_Lock;
/************************************************************************
@@ -82,7 +83,8 @@
LogTime.tm_hour,LogTime.tm_min, LogTime.tm_sec);
}
else {
- LogTextIndex = 0;
+ ++LogCount;
+ LogTextIndex = sprintf(LogText,"%04d. ",LogCount);
}
}
/************************************************************************/
@@ -164,7 +166,7 @@
memset(Fr,SizeOfFr,0);
strcpy(Fr->Signature,Signature);
Fr->Size = FrSize;
- Fr->Flags = 2;
+ Fr->Flags = 0;
Fr->StartPointer = (char*)&Fr->Buffer;
Fr->EndPointer = (char*)Fr + Fr->Size;
Fr->NextPointer = Fr->StartPointer;
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/head.S linuxppc64_2_4/arch/ppc64/kernel/head.S
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/head.S Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/head.S Mon Oct 15 02:51:01 2001
@@ -35,6 +35,10 @@
#include
#include
+#ifdef CONFIG_PPC_ISERIES
+#define DO_SOFT_DISABLE
+#endif
+
/*
* We layout physical memory as follows:
* 0x0000 - 0x00ff : Secondary processor spin code
@@ -47,6 +51,17 @@
*/
/*
+ * SPRG Usage
+ *
+ * Register Definition
+ *
+ * SPRG0 reserved for hypervisor
+ * SPRG1 temp - used to save gpr
+ * SPRG2 temp - used to save gpr
+ * SPRG3 virt addr of Paca
+ */
+
+/*
* Entering into this code we make the following assumptions:
* For pSeries:
* 1. The MMU is off & open firmware is running in real mode.
@@ -75,6 +90,15 @@
.llong msChunks-KERNELBASE
.llong pidhash-KERNELBASE
+ /* Offset 0x38 - Pointer to start of embedded System.map */
+ .globl embedded_sysmap_start
+embedded_sysmap_start:
+ .llong 0
+ /* Offset 0x40 - Pointer to end of embedded System.map */
+ .globl embedded_sysmap_end
+embedded_sysmap_end:
+ .llong 0
+
/* Secondary processors spin on this value until it goes to 1. */
.globl __secondary_hold_spinloop
__secondary_hold_spinloop:
@@ -95,30 +119,30 @@
* All of it must fit below the first exception vector at 0x100.
*/
_GLOBAL(__secondary_hold)
- /* Grab our cpu# */
+ /* Grab our linux cpu number */
mr r24,r3
/* Tell the master cpu we're here */
/* Relocation is off & we are located at an address less */
/* than 0x100, so only need to grab low order offset. */
- li r3,__secondary_hold_acknowledge@l
- std r24,0(r3)
-
- /* Get the address on which we are going to spin. */
- li r3,__secondary_hold_spinloop@l
+ std r24,__secondary_hold_acknowledge@l(0)
/* All secondary cpu's wait here until told to start. */
-100: ld r4,0(r3)
+100: ld r4,__secondary_hold_spinloop@l(0)
cmpdi 0,r4,1
bne 100b
+#ifdef CONFIG_HMT
+ b .hmt_init
+#else
#ifdef CONFIG_SMP
mr r3,r24
b .pseries_secondary_smp_init
#else
BUG_OPCODE
#endif
-
+#endif
+
/*
* The following macros define the code that appears as
* the prologue to each of the exception handlers. They
@@ -135,72 +159,114 @@
* This is the start of the interrupt handlers for Pseries
* This code runs with relocation off.
*/
+#define EXCEPTION_PROLOG_PSERIES(label) \
+ mtspr SPRG2,r20; /* use SPRG2 as scratch reg */ \
+ mtspr SPRG1,r21; /* save r21 */ \
+ mfspr r20,SPRG3; /* get Paca virt addr */ \
+ clrldi r20,r20,12; /* convert virt to real addr */ \
+ ld r21,PACAEXCSP(r20); /* get exception stack ptr */ \
+ addi r21,r21,-EXC_FRAME_SIZE; /* make exception frame */ \
+ std r21,PACAEXCSP(r20); /* update exception stack ptr */ \
+ clrldi r20,r21,12; /* convert virt to real addr */ \
+ std r22,32(r20); /* Save r22 in exc. frame */ \
+ std r23,40(r20); /* Save r23 in exc. frame */ \
+ mfspr r22,SRR0; /* EA of interrupted instr */ \
+ std r22,0(r20); /* Save SRR0 in exc. frame */ \
+ mfspr r23,SRR1; /* machine state at interrupt */ \
+ std r23,8(r20); /* Save SRR1 in exc. frame */ \
+ mfspr r22,SPRG2; \
+ std r22,16(r20); /* Save r20 in exc. frame */ \
+ mfspr r23,SPRG1; \
+ std r23,24(r20); /* Save r21 in exc. frame */ \
+ mfspr r20,SPRG3; /* get Paca virt addr again */ \
+ SET_REG_TO_LABEL(r22,label); /* Get addr to branch to */ \
+ mfmsr r23; \
+ rotldi r23,r23,4; \
+ ori r23,r23,0x32B; /* Set IR, DR, RI, SF, ISF, HV*/ \
+ rotldi r23,r23,60; /* for generic handlers */ \
+ mtspr SRR0,r22; \
+ mtspr SRR1,r23; \
+ mfcr r23; /* save CR in r23 */ \
+ rfid
-#define EXCEPTION_PROLOG_PSERIES(label) \
- mtspr SPRG2,r20; /* use SPRG2 as scratch reg */ \
- mfspr r20,SPRG3; /* get Paca virt addr */ \
- clrldi r20,r20,12; /* convert virt to real addr */ \
- std r21,PACAR21(r20); /* Save GPR21 in Paca */ \
- mfspr r21,SRR0; /* EA of interrupted instr */ \
- std r21,LPPACA+LPPACASRR0(r20); /* Set SRR0 in ItLpPaca */ \
- mfspr r21,SRR1; /* machine state at interrupt */ \
- std r21,LPPACA+LPPACASRR1(r20); /* Set SRR1 in ItLpPaca */ \
- SET_REG_TO_LABEL(r21,label); /* Get addr to branch to */ \
- mtspr SRR0,r21; \
- li r20,0x5; /* Turn on 64b, 64bints */ \
- sldi r20,r20,61; \
- ori r20,r20,0x30; /* for generic handlers */ \
- mfmsr r21; /* Turn on IR & DR */ \
- or r21,r21,r20; /* for generic handlers */ \
- mtspr SRR1,r21; \
- rfid /* Jump to generic handlers */
/*
* This is the start of the interrupt handlers for i_series
* This code runs with relocation on.
*/
-
#define EXCEPTION_PROLOG_ISERIES \
- mtspr SPRG2,r20; /* use SPRG2 as scratch reg */\
- mfspr r20,SPRG3; /* get Paca */\
- std r21,PACAR21(r20) /* Save GPR21 in Paca */
-
-#define EXCEPTION_PROLOG_COMMON \
- mfspr r20,SPRG3; /* get Paca virt addr */ \
- std r22,PACAR22(r20); /* Save GPR22 in Paca */\
- mfcr r22; \
- ld r21,LPPACA+LPPACASRR1(r20); /* Get SRR1 from ItLpPaca */ \
- andi. r21,r21,MSR_PR; /* Set CR for later branch */ \
- beq+ 1f; \
- ld r21,PACAKSAVE(r20); /* exception stack to use */\
- b 2f; \
-1: \
- subi r21,r1,INT_FRAME_SIZE;/* alloc exc. frame */ \
-2: \
- std r22,_CCR(r21); /* save CR in stackframe */\
- ld r22,PACAR21(r20); /* Get GPR21 from Paca */\
- std r22,GPR21(r21); /* Save GPR21 in stackframe */\
- ld r22,PACAR22(r20); /* Get GPR22 from Paca */\
- std r22,GPR22(r21); /* Save GPR22 in stackframe */\
- std r23,GPR23(r21); /* Save GPR23 in stackframe */\
- mfspr r22,SPRG2; /* Get GPR20 from SPRG2 */\
- std r22,GPR20(r21); /* Save GPR20 in stackframe */\
- mflr r22; \
- std r22,_LINK(r21); \
- mfctr r22; \
- std r22,_CTR(r21); \
- mfspr r22,XER; \
- std r22,_XER(r21); \
- ld r22,LPPACA+LPPACASRR0(r20); /* Get SRR0 from ItLpPaca */\
- ld r23,LPPACA+LPPACASRR1(r20); /* Get SRR1 from ItLpPaca */\
- SAVE_8GPRS(0, r21); \
- SAVE_4GPRS(8, r21); \
- SAVE_2GPRS(12, r21); \
- ld r2,PACATOC(r20); \
- std r1,0(r21); \
- mr r1,r21
+ mtspr SPRG2,r20; /* use SPRG2 as scratch reg */\
+ mtspr SPRG1,r21; /* save r21 */\
+ mfspr r20,SPRG3; /* get Paca */\
+ ld r21,PACAEXCSP(r20); /* get exception stack ptr */\
+ addi r21,r21,-EXC_FRAME_SIZE; /* make exception frame */\
+ std r21,PACAEXCSP(r20); /* update exception stack ptr */\
+ std r22,32(r21); /* save r22 on exception frame */\
+ std r23,40(r21); /* Save r23 in exc. frame */\
+ ld r22,LPPACA+LPPACASRR0(r20); /* Get SRR0 from ItLpPaca */\
+ std r22,0(r21); /* save SRR0 in exc. frame */\
+ ld r23,LPPACA+LPPACASRR1(r20); /* Get SRR1 from ItLpPaca */\
+ std r23,8(r21); /* save SRR1 in exc. frame */\
+ mfspr r22,SPRG2; \
+ std r22,16(r21); /* Save r20 in exc. frame */\
+ mfspr r23,SPRG1; \
+ std r23,24(r21); /* Save r21 in exc. frame */\
+ mfcr r23; /* save CR in r23 */
+
+/*
+ * The common exception prolog is used for all except a few exceptions
+ * such as a segment miss on a kernel address. We have to be prepared
+ * to take another exception from the point where we first touch the
+ * kernel stack onwards.
+ *
+ * On entry r20 points to the paca and r21 points to the exception
+ * frame on entry, r23 contains the saved CR, and relocation is on.
+ */
+#define EXCEPTION_PROLOG_COMMON \
+ mfspr r22,DAR; /* Save DAR in exc. frame */ \
+ std r22,48(r21); \
+ mfspr r22,DSISR; /* Save DSISR in exc. frame */ \
+ std r22,56(r21); \
+ ld r22,8(r21); /* Get SRR1 from exc. frame */ \
+ andi. r22,r22,MSR_PR; /* Set CR for later branch */ \
+ mr r22,r1; /* Save r1 */ \
+ subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \
+ beq- 1f; \
+ ld r1,PACAKSAVE(r20); /* kernel stack to use */ \
+1: std r22,GPR1(r1); /* save r1 in stackframe */ \
+ std r22,0(r1); /* make stack chain pointer */ \
+ std r23,_CCR(r1); /* save CR in stackframe */ \
+ ld r22,16(r21); /* move r20 to stackframe */ \
+ std r22,GPR20(r1); \
+ ld r23,24(r21); /* move r21 to stackframe */ \
+ std r23,GPR21(r1); \
+ ld r22,32(r21); /* move r22 to stackframe */ \
+ std r22,GPR22(r1); \
+ ld r23,40(r21); /* move r23 to stackframe */ \
+ std r23,GPR23(r1); \
+ mflr r22; /* save LR in stackframe */ \
+ std r22,_LINK(r1); \
+ mfctr r23; /* save CTR in stackframe */ \
+ std r23,_CTR(r1); \
+ mfspr r22,XER; /* save XER in stackframe */ \
+ std r22,_XER(r1); \
+ ld r23,48(r21); /* move DAR to stackframe */ \
+ std r23,_DAR(r1); \
+ ld r22,56(r21); /* move DSISR to stackframe */ \
+ std r22,_DSISR(r1); \
+ lbz r22,PACAPROCENABLED(r20); \
+ std r22,SOFTE(r1); \
+ ld r22,0(r21); /* get SRR0 from exc. frame */ \
+ ld r23,8(r21); /* get SRR1 from exc. frame */ \
+ addi r21,r21,EXC_FRAME_SIZE;/* pop off exception frame */ \
+ std r21,PACAEXCSP(r20); \
+ SAVE_GPR(0, r1); /* save r0 in stackframe */ \
+ SAVE_8GPRS(2, r1); /* save r2 - r13 in stackframe */ \
+ SAVE_4GPRS(10, r1); \
+ ld r2,PACATOC(r20)
+
/*
* Note: code which follows this uses cr0.eq (set if from kernel),
- * r21, r22 (SRR0), and r23 (SRR1).
+ * r1, r22 (SRR0), and r23 (SRR1).
*/
/*
@@ -218,16 +284,25 @@
EXCEPTION_PROLOG_ISERIES; \
b label##_common
+#define MASKABLE_EXCEPTION_ISERIES( label ) \
+ .globl label##_Iseries; \
+label##_Iseries: \
+ EXCEPTION_PROLOG_ISERIES; \
+ lbz r22,PACAPROCENABLED(r20); \
+ cmpi 0,r22,0; \
+ beq- label##_Iseries_masked; \
+ b label##_common
+
#define STD_EXCEPTION_COMMON( trap, label, hdlr ) \
.globl label##_common; \
label##_common: \
EXCEPTION_PROLOG_COMMON; \
addi r3,r1,STACK_FRAME_OVERHEAD; \
- SET_REG_TO_CONST(r20, MSR_KERNEL); \
+ li r20,0; \
li r6,trap; \
- bl .transfer_to_handler; \
- .llong hdlr; \
- .llong .ret_from_except
+ bl .save_remaining_regs; \
+ bl hdlr; \
+ b .ret_from_except
/*
* Start of pSeries system interrupt routines
@@ -253,6 +328,7 @@
STD_EXCEPTION_PSERIES( 0xd00, SingleStep )
STD_EXCEPTION_PSERIES( 0xe00, Trap_0e )
STD_EXCEPTION_PSERIES( 0xf00, PerformanceMonitor )
+ STD_EXCEPTION_PSERIES( 0x1300, InstructionBreakpoint )
. = 0x4000
.globl __end_interupts
@@ -318,11 +394,11 @@
STD_EXCEPTION_ISERIES( DataAccessSLB )
STD_EXCEPTION_ISERIES( InstructionAccess )
STD_EXCEPTION_ISERIES( InstructionAccessSLB )
- STD_EXCEPTION_ISERIES( HardwareInterrupt )
+ MASKABLE_EXCEPTION_ISERIES( HardwareInterrupt )
STD_EXCEPTION_ISERIES( Alignment )
STD_EXCEPTION_ISERIES( ProgramCheck )
STD_EXCEPTION_ISERIES( FPUnavailable )
- STD_EXCEPTION_ISERIES( Decrementer )
+ MASKABLE_EXCEPTION_ISERIES( Decrementer )
STD_EXCEPTION_ISERIES( Trap_0a )
STD_EXCEPTION_ISERIES( Trap_0b )
STD_EXCEPTION_ISERIES( SystemCall )
@@ -362,9 +438,7 @@
/* Let the Hypervisor know we are alive */
/* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
lis r3,0x8002
- rldicr r0,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */
- rldicl r3,r3,0,48 /* r3 = r3 & 0x000000000000ffff */
- or r3,r3,r0 /* r3 = r3 | r0 */
+ rldicr r3,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */
#else /* CONFIG_SMP */
/* Yield the processor. This is required for non-SMP kernels
which are running on multi-threaded machines. */
@@ -380,6 +454,30 @@
b 1b /* If SMP not configured, secondaries
* loop forever */
+ .globl HardwareInterrupt_Iseries_masked
+HardwareInterrupt_Iseries_masked:
+ b maskable_exception_exit
+
+ .globl Decrementer_Iseries_masked
+Decrementer_Iseries_masked:
+ li r22,1
+ stb r22,PACALPPACA+LPPACADECRINT(r20)
+ lwz r22,PACADEFAULTDECR(r20)
+ mtspr DEC,r22
+maskable_exception_exit:
+ mtcrf 0xff,r23 /* Restore regs and free exception frame */
+ ld r22,0(r21)
+ ld r23,8(r21)
+ mtspr SRR0,r22
+ mtspr SRR1,r23
+ ld r22,32(r21)
+ ld r23,40(r21)
+ addi r21,r21,EXC_FRAME_SIZE
+ std r21,PACAEXCSP(r20)
+ mfspr r21,SPRG1
+ mfspr r20,SPRG2
+ rfid
+
/*** Common interrupt handlers ***/
STD_EXCEPTION_COMMON( 0x100, SystemReset, .SystemResetException )
@@ -390,32 +488,54 @@
STD_EXCEPTION_COMMON( 0xd00, SingleStep, .SingleStepException )
STD_EXCEPTION_COMMON( 0xe00, Trap_0e, .UnknownException )
STD_EXCEPTION_COMMON( 0xf00, PerformanceMonitor, .PerformanceMonitorException )
+ STD_EXCEPTION_COMMON(0x1300, InstructionBreakpoint, .InstructionBreakpointException )
-/* r20 is in SPRG2,
- r21 is in the PACA
-*/
+/*
+ * Return from an exception which is handled without calling
+ * save_remaining_regs. The caller is assumed to have done
+ * EXCEPTION_PROLOG_COMMON.
+ */
+fast_exception_return:
+ ld r3,_CCR(r1)
+ ld r4,_LINK(r1)
+ ld r5,_CTR(r1)
+ ld r6,_XER(r1)
+ mtcr r3
+ mtlr r4
+ mtctr r5
+ mtspr XER,r6
+ REST_GPR(0, r1)
+ REST_8GPRS(2, r1)
+ REST_4GPRS(10, r1)
+ mtspr SRR1,r23
+ mtspr SRR0,r22
+ REST_4GPRS(20, r1)
+ ld r1,GPR1(r1)
+ rfid
+
+
+/*
+ * Here r20 points to the PACA, r21 to the exception frame,
+ * r23 contains the saved CR.
+ * r20 - r23, SRR0 and SRR1 are saved in the exception frame.
+ */
.globl DataAccess_common
DataAccess_common:
- mfcr r20
- mfspr r21,DAR
- srdi r21,r21,60
- cmpi 0,r21,0xc
- bne 3f
+ mfspr r22,DAR
+ srdi r22,r22,60
+ cmpi 0,r22,0xc
- /* Segment faulted on a bolted segment. Go off and map that segment. */
- b .do_stab_bolted
+ /* Segment fault on a bolted segment. Go off and map that segment. */
+ beq .do_stab_bolted
-3: mtcr r20
EXCEPTION_PROLOG_COMMON
- mfspr r20,DSISR
- std r20,_DSISR(r21)
- andis. r0,r20,0xa450 /* weird error? */
+ ld r3,_DSISR(r1)
+ andis. r0,r3,0xa450 /* weird error? */
bne 1f /* if not, try to put a PTE */
- mfspr r3,DAR /* into the hash table */
- std r3,_DAR(r21)
- rlwinm r4,r20,32-23,29,29 /* DSISR_STORE -> _PAGE_RW */
+ andis. r0,r3,0x0020 /* Is it a page table fault? */
+ rlwinm r4,r3,32-23,29,29 /* DSISR_STORE -> _PAGE_RW */
+ ld r3,_DAR(r1) /* into the hash table */
- andis. r0,r20,0x0020 /* Is it a page table fault? */
beq 2f /* If so handle it */
li r4,0x300 /* Trap number */
bl .do_stab_SI
@@ -423,60 +543,44 @@
2: bl .do_hash_page_DSI /* Try to handle as hpte fault */
1:
- ld r4,_DAR(r21)
- ld r5,_DSISR(r21)
+ ld r4,_DAR(r1)
+ ld r5,_DSISR(r1)
addi r3,r1,STACK_FRAME_OVERHEAD
-
- SET_REG_TO_CONST(r20, MSR_KERNEL)
- rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
+#ifdef DO_SOFT_DISABLE
+ ld r20,SOFTE(r1) /* Copy saved SOFTE bit */
+#else
+ rldicl r20,r23,49,63 /* copy EE bit from saved MSR */
+#endif
li r6,0x300
- bl .transfer_to_handler
- .llong .do_page_fault
- .llong .ret_from_except
+ bl .save_remaining_regs
+ bl .do_page_fault
+ b .ret_from_except
.globl DataAccessSLB_common
DataAccessSLB_common:
+ mfspr r22,DAR
+ srdi r22,r22,60
+ cmpi 0,r22,0xc
+
+ /* Segment fault on a bolted segment. Go off and map that segment. */
+ beq .do_slb_bolted
+
EXCEPTION_PROLOG_COMMON
- mfspr r3,DAR
+ ld r3,_DAR(r1)
li r4,0x380 /* Exception vector */
bl .ste_allocate
or. r3,r3,r3 /* Check return code */
- bne 1f /* Branch on failure */
-
- /* SLB Allocation success - Return. */
- ld r3,_CCR(r21)
- ld r4,_LINK(r21)
- ld r5,_CTR(r21)
- ld r6,_XER(r21)
-
- mtcrf 0xff,r3
- mtlr r4
- mtctr r5
- mtspr XER,r6
- REST_8GPRS(0,r21)
- REST_4GPRS(8,r21)
- REST_2GPRS(12,r21)
- mtspr SRR1,r23
- mtspr SRR0,r22
- ld r20,GPR20(r21)
- ld r22,GPR22(r21)
- ld r23,GPR23(r21)
- ld r21,GPR21(r21)
- RFID
-
-1:
- mfspr r4,DAR
- std r4,_DAR(r21)
- mfspr r5,DSISR
- std r5,_DSISR(r21)
+ beq fast_exception_return /* Return if we succeeded */
addi r3,r1,STACK_FRAME_OVERHEAD
-
- SET_REG_TO_CONST(r20, MSR_KERNEL)
- rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
+#ifdef DO_SOFT_DISABLE
+ ld r20,SOFTE(r1)
+#else
+ rldicl r20,r23,49,63 /* copy EE bit from saved MSR */
+#endif
li r6,0x380
- bl .transfer_to_handler
- .llong .do_page_fault
- .llong .ret_from_except
+ bl .save_remaining_regs
+ bl .do_page_fault
+ b .ret_from_except
.globl InstructionAccess_common
InstructionAccess_common:
@@ -497,12 +601,15 @@
mr r4,r22
mr r5,r23
addi r3,r1,STACK_FRAME_OVERHEAD
- SET_REG_TO_CONST(r20, MSR_KERNEL)
- rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
+#ifdef DO_SOFT_DISABLE
+ ld r20,SOFTE(r1)
+#else
+ rldicl r20,r23,49,63 /* copy EE bit from saved MSR */
+#endif
li r6,0x400
- bl .transfer_to_handler
- .llong .do_page_fault
- .llong .ret_from_except
+ bl .save_remaining_regs
+ bl .do_page_fault
+ b .ret_from_except
.globl InstructionAccessSLB_common
InstructionAccessSLB_common:
@@ -511,89 +618,111 @@
li r4,0x480 /* Exception vector */
bl .ste_allocate
or. r3,r3,r3 /* Check return code */
- bne 1f /* Branch on failure */
+ beq fast_exception_return /* Return if we succeeded */
- /* SLB Allocation success - Return. */
- ld r3,_CCR(r21)
- ld r4,_LINK(r21)
- ld r5,_CTR(r21)
- ld r6,_XER(r21)
-
- mtcrf 0xff,r3
- mtlr r4
- mtctr r5
- mtspr XER,r6
- REST_8GPRS(0,r21)
- REST_4GPRS(8,r21)
- REST_2GPRS(12,r21)
- mtspr SRR1,r23
- mtspr SRR0,r22
- ld r20,GPR20(r21)
- ld r22,GPR22(r21)
- ld r23,GPR23(r21)
- ld r21,GPR21(r21)
- RFID
-
-1:
- mfspr r4,DAR
- std r4,_DAR(r21)
- mfspr r5,DSISR
- std r5,_DSISR(r21)
addi r3,r1,STACK_FRAME_OVERHEAD
-
- SET_REG_TO_CONST(r20, MSR_KERNEL)
- rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
+#ifdef DO_SOFT_DISABLE
+ ld r20,SOFTE(r1)
+#else
+ rldicl r20,r23,49,63 /* copy EE bit from saved MSR */
+#endif
li r6,0x380
- bl .transfer_to_handler
- .llong .do_page_fault
- .llong .ret_from_except
+ bl .save_remaining_regs
+ bl .do_page_fault
+ b .ret_from_except
.globl HardwareInterrupt_common
HardwareInterrupt_common:
EXCEPTION_PROLOG_COMMON
HardwareInterrupt_entry:
addi r3,r1,STACK_FRAME_OVERHEAD
- SET_REG_TO_CONST(r20, MSR_KERNEL)
+ li r20,0
li r6,0x500
- bl .transfer_to_handler
- .llong .do_IRQ
- .llong .ret_from_except
+ bl .save_remaining_regs
+ /* Determine if need to run do_irq on a hardware interrupt stack */
+ /* The first invocation of do_irq will occur on the kernel */
+ /* stack in the current stack */
+ /* All other invocations of do_irq will run on the hardware */
+ /* interrupt stack associated with the PACA of the current */
+ /* processor. */
+ /* */
+ /* The call to do_irq will preserve the value of r14 - r31 */
+ /* */
+ mfspr r20,SPRG3 /* get Paca */
+ lbz r21,PACAHRDWINTCOUNT(r20) /* get hardware interrupt cnt */
+ cmpi 0,r21,1 /* */
+ addi r21,r21,1 /* incr hardware interrupt cnt*/
+ stb r21,PACAHRDWINTCOUNT(r20) /* */
+ bne 2f /* */
+
+ mr r14,r1 /* preserve current r1 */
+ ld r1,PACAHRDWINTSTACK(r20) /* */
+ std r14,0(r1) /* set the back chain */
+ bl .do_IRQ
+ lbz r22,PACAHRDWINTCOUNT(r20) /* get hardware interrupt cnt */
+ cmp 0,r22,r21 /* debug test */
+ bne 3f
+ subi r21,r21,1
+ stb r21,PACAHRDWINTCOUNT(r20) /* */
+ mr r1,r14 /* */
+ b .ret_from_except
+
+2:
+ bl .do_IRQ
+
+ lbz r22,PACAHRDWINTCOUNT(r20) /* get hardware interrupt cnt */
+ cmp 0,r22,r21 /* debug test */
+ bne 3f /* */
+ subi r21,r21,1 /* decr hardware interrupt cnt*/
+ stb r21,PACAHRDWINTCOUNT(r20) /* */
+
+ b .ret_from_except
+
+3:
+ /* error - counts out of sync */
+#ifdef CONFIG_XMON
+ bl .xmon
+#endif
+4: b 4b
+
.globl Alignment_common
Alignment_common:
EXCEPTION_PROLOG_COMMON
- mfspr r4,DAR
- std r4,_DAR(r21)
- mfspr r5,DSISR
- std r5,_DSISR(r21)
addi r3,r1,STACK_FRAME_OVERHEAD
- SET_REG_TO_CONST(r20, MSR_KERNEL)
- rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
+#ifdef DO_SOFT_DISABLE
+ ld r20,SOFTE(r1)
+#else
+ rldicl r20,r23,49,63 /* copy EE bit from saved MSR */
+#endif
li r6,0x600
- bl .transfer_to_handler
- .llong .AlignmentException
- .llong .ret_from_except
+ bl .save_remaining_regs
+ bl .AlignmentException
+ b .ret_from_except
.globl ProgramCheck_common
ProgramCheck_common:
EXCEPTION_PROLOG_COMMON
addi r3,r1,STACK_FRAME_OVERHEAD
- SET_REG_TO_CONST(r20, MSR_KERNEL)
- rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
+#ifdef DO_SOFT_DISABLE
+ ld r20,SOFTE(r1)
+#else
+ rldicl r20,r23,49,63 /* copy EE bit from saved MSR */
+#endif
li r6,0x700
- bl .transfer_to_handler
- .llong .ProgramCheckException
- .llong .ret_from_except
+ bl .save_remaining_regs
+ bl .ProgramCheckException
+ b .ret_from_except
.globl FPUnavailable_common
FPUnavailable_common:
EXCEPTION_PROLOG_COMMON
bne .load_up_fpu /* if from user, just load it up */
- SET_REG_TO_CONST(r20, MSR_KERNEL)
+ li r20,0
li r6,0x800
- bl .transfer_to_handler /* if from kernel, take a trap */
- .llong .KernelFP
- .llong .ret_from_except
+ bl .save_remaining_regs /* if from kernel, take a trap */
+ bl .KernelFP
+ b .ret_from_except
.globl SystemCall_common
SystemCall_common:
@@ -605,13 +734,16 @@
beq+ HardwareInterrupt_entry
1:
#endif
- std r3,ORIG_GPR3(r21)
- SET_REG_TO_CONST(r20, MSR_KERNEL)
- rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
+ std r3,ORIG_GPR3(r1)
+#ifdef DO_SOFT_DISABLE
+ ld r20,SOFTE(r1)
+#else
+ rldicl r20,r23,49,63 /* copy EE bit from saved MSR */
+#endif
li r6,0xC00
- bl .transfer_to_handler
- .llong .DoSyscall
- .llong .ret_from_except
+ bl .save_remaining_regs
+ bl .DoSyscall
+ b .ret_from_except
_GLOBAL(do_hash_page_ISI)
li r4,0
@@ -620,7 +752,21 @@
ori r4,r4,1 /* add _PAGE_PRESENT */
mflr r21 /* Save LR in r21 */
- /* r21 restored later from r1 */
+
+#ifdef DO_SOFT_DISABLE
+ /*
+ * We hard enable here (but first soft disable) so that the hash_page
+ * code can spin on the hash_table_lock with problem on a shared
+ * processor.
+ */
+ li r0,0
+ stb r0,PACAPROCENABLED(r20) /* Soft Disabled */
+
+ mfmsr r0
+ ori r0,r0,MSR_EE
+ mtmsrd r0 /* Hard Enable */
+#endif
+
/*
* r3 contains the faulting address
* r4 contains the required access permissions
@@ -629,58 +775,61 @@
*/
bl .hash_page /* build HPTE if possible */
- mtlr r21 /* restore LR */
- mr r21,r1 /* restore r21 */
-
- or. r3,r3,r3 /* Check return code */
- bnelr /* Return to DSI or ISI on failure */
+#ifdef DO_SOFT_DISABLE
/*
- * The HPTE has been created/updated. Restore and retry the faulting inst
+ * Now go back to hard disabled.
*/
+ mfmsr r0
+ li r4,0
+ ori r4,r4,MSR_EE
+ andc r0,r0,r4
+ mtmsrd r0 /* Hard Disable */
+
+ ld r0,SOFTE(r1)
+ cmpdi 0,r0,0 /* See if we will soft enable in */
+ /* save_remaining_regs */
+ beq 5f
+ CHECKANYINT(r4,r5)
+ bne- HardwareInterrupt_entry /* Convert this DSI into an External */
+ /* to process interrupts which occurred */
+ /* during hash_page */
+5:
+ stb r0,PACAPROCENABLED(r20) /* Restore soft enable/disable status */
+#endif
+ or. r3,r3,r3 /* Check return code */
+ beq fast_exception_return /* Return from exception on success */
- ld r3,_CCR(r21)
- ld r4,_LINK(r21)
- ld r5,_CTR(r21)
- ld r6,_XER(r21)
- mtcrf 0xff,r3
- mtlr r4
- mtctr r5
- mtspr XER,r6
- REST_8GPRS(0,r21)
- REST_4GPRS(8,r21)
- REST_2GPRS(12,r21)
- mtspr SRR1,r23
- mtspr SRR0,r22
- ld r20,GPR20(r21)
- ld r22,GPR22(r21)
- ld r23,GPR23(r21)
- ld r21,GPR21(r21)
- rfid
+ mtlr r21 /* restore LR */
+ blr /* Return to DSI or ISI on failure */
-/* orig r20 is in SPRG2,
- orig r21 is in the PACA
- r20 contains CCR
-
- r22 needs to be saved
- r1 needs to be saved
- CCR needs to be saved
-*/
+/*
+ * r20 points to the PACA, r21 to the exception frame,
+ * r23 contains the saved CR.
+ * r20 - r23, SRR0 and SRR1 are saved in the exception frame.
+ * We assume we aren't going to take any exceptions during this procedure.
+ */
_GLOBAL(do_stab_bolted)
- mfsprg r21,3
- std r22,PACAR22(r21)
- std r1,PACAR1(r21)
- stw r20,PACACCR(r21)
- mfspr r21,DAR
+ std r23,48(r21) /* save CR in exc. frame */
+ mfspr r21,DSISR
+ andis. r21,r21,0x0020
+ bne+ 2f
+ li r3,0
+#ifdef CONFIG_XMON
+ bl .xmon
+#endif
+1: b 1b
+2:
/* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */
+ mfspr r21,DAR
rldicl r20,r21,36,32 /* Permits a full 32b of ESID */
rldicr r20,r20,15,48
rldicl r21,r21,4,60
or r20,r20,r21
li r21,9 /* VSID_RANDOMIZER */
- rldicr r21,r21,32,31
+ sldi r21,r21,32
oris r21,r21,58231
ori r21,r21,39831
@@ -699,20 +848,20 @@
/* Search the primary group for a free entry */
li r22,0
1:
- ld r1,0(r21) /* Test valid bit of the current ste */
- rldicl r1,r1,57,63
- cmpwi r1,0
+ ld r23,0(r21) /* Test valid bit of the current ste */
+ rldicl r23,r23,57,63
+ cmpwi r23,0
bne 2f
- ld r1,8(r21) /* Get the current vsid part of the ste */
- rldimi r1,r20,12,0 /* Insert the new vsid value */
- std r1,8(r21) /* Put new entry back into the stab */
+ ld r23,8(r21) /* Get the current vsid part of the ste */
+ rldimi r23,r20,12,0 /* Insert the new vsid value */
+ std r23,8(r21) /* Put new entry back into the stab */
eieio /* Order vsid update */
- ld r1,0(r21) /* Get the esid part of the ste */
+ ld r23,0(r21) /* Get the esid part of the ste */
mfspr r20,DAR /* Get the new esid */
rldicl r20,r20,36,28 /* Permits a full 36b of ESID */
- rldimi r1,r20,28,0 /* Insert the new esid value */
- ori r1,r1,144 /* Turn on valid and kp */
- std r1,0(r21) /* Put new entry back into the stab */
+ rldimi r23,r20,28,0 /* Insert the new esid value */
+ ori r23,r23,144 /* Turn on valid and kp */
+ std r23,0(r21) /* Put new entry back into the stab */
sync /* Order the update */
b 3f
2:
@@ -732,27 +881,27 @@
/* r21 currently points to and ste one past the group of interest */
/* make it point to the randomly selected entry */
subi r21,r21,128
- ori r21,r21,r22 /* r21 is the entry to invalidate */
+ or r21,r21,r22 /* r21 is the entry to invalidate */
isync /* mark the entry invalid */
- ld r1,0(r21)
+ ld r23,0(r21)
li r22,-129
- and r1,r1,r22
- std r1,0(r21)
+ and r23,r23,r22
+ std r23,0(r21)
sync
- ld r1,8(r21)
- rldimi r1,r20,12,0
- std r1,8(r21)
+ ld r23,8(r21)
+ rldimi r23,r20,12,0
+ std r23,8(r21)
eieio
- ld r1,0(r21) /* Get the esid part of the ste */
- mr r22,r1
- mfspr r20,DAR /* Get the new esid */
- rldicl r20,r20,36,32 /* Permits a full 32b of ESID */
- rldimi r1,r20,28,0 /* Insert the new esid value */
- ori r1,r1,144 /* Turn on valid and kp */
- std r1,0(r21) /* Put new entry back into the stab */
+ ld r23,0(r21) /* Get the esid part of the ste */
+ mr r22,r23
+ mfspr r20,DAR /* Get the new esid */
+ rldicl r20,r20,36,28 /* Permits a full 32b of ESID */
+ rldimi r23,r20,28,0 /* Insert the new esid value */
+ ori r23,r23,144 /* Turn on valid and kp */
+ std r23,0(r21) /* Put new entry back into the stab */
rldicl r22,r22,36,28
rldicr r22,r22,28,35
@@ -761,24 +910,108 @@
3:
/* All done -- return from exception. */
- mfsprg r20,3 /* Load the PACA pointer */
+ mfsprg r20,3 /* Load the PACA pointer */
+ ld r21,PACAEXCSP(r20) /* Get the exception frame pointer */
+ addi r22,r21,EXC_FRAME_SIZE
+ ld r23,48(r21) /* get saved CR */
+ std r22,PACAEXCSP(r20) /* pop off the exception frame */
+ mtcr r23 /* restore CR */
+ ld r22,0(r21) /* Get SRR0 from exc. frame */
+ ld r23,8(r21) /* Get SRR1 from exc. frame */
+ mtspr SRR0,r22
+
+ mtspr SRR1,r23
+ ld r20,16(r21) /* restore r20 from exc. frame */
+ ld r22,32(r21) /* restore r22 and r23 */
+ ld r23,40(r21)
+ ld r21,24(r21) /* restore r21 last */
+ rfid
+_TRACEBACK(do_stab_bolted)
+
+/*
+ * r20 points to the PACA, r21 to the exception frame,
+ * r23 contains the saved CR.
+ * r20 - r23, SRR0 and SRR1 are saved in the exception frame.
+ * We assume we aren't going to take any exceptions during this procedure.
+ */
+_GLOBAL(do_slb_bolted)
+ std r23,48(r21) /* save CR in exc. frame */
+
+ /* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */
+ mfspr r21,DAR
+ rldicl r20,r21,36,32 /* Permits a full 32b of ESID */
+ rldicr r20,r20,15,48
+ rldicl r21,r21,4,60
+ or r20,r20,r21
+
+ li r21,9 /* VSID_RANDOMIZER */
+ sldi r21,r21,32
+ oris r21,r21,58231
+ ori r21,r21,39831
+
+ mulld r20,r20,r21
+ clrldi r20,r20,28 /* r20 = vsid */
+
+ /* Search the SLB for a free entry */
+ li r22,1
+1:
+ slbmfee r23,r22
+ rldicl r23,r23,37,63
+ cmpwi r23,0
+ beq 3f /* Found an invalid entry */
+
+ addi r22,r22,1
+ cmpldi r22,64
+ blt 1b
+
+ /* Didn't find a free entry -- for now trap out. Do castouts later DRENG */
+ li r3,0
+#ifdef CONFIG_XMON
+ bl .xmon
+#endif
+2: b 2b
+
+ /* r20 = vsid, r22 = entry */
+3:
+ /* Put together the vsid portion of the entry. */
+ li r21,0
+ rldimi r21,r20,12,0
+ ori r20,r21,1024
+
+ /* Put together the esid portion of the entry. */
+ mfspr r21,DAR /* Get the new esid */
+ rldicl r21,r21,36,28 /* Permits a full 36b of ESID */
+ li r23,0
+ rldimi r23,r21,28,0 /* Insert esid */
+ oris r21,r23,2048 /* valid bit */
+ rldimi r21,r22,0,52 /* Insert entry */
- ld r22,LPPACA+LPPACASRR0(r20); /* Get SRR0 from ItLpPaca */
- ld r21,LPPACA+LPPACASRR1(r20); /* Get SRR1 from ItLpPaca */
- mtspr SRR1,r21
+ isync
+ slbmte r20,r21
+ isync
+
+ /* All done -- return from exception. */
+ mfsprg r20,3 /* Load the PACA pointer */
+ ld r21,PACAEXCSP(r20) /* Get the exception frame pointer */
+ addi r22,r21,EXC_FRAME_SIZE
+ ld r23,48(r21) /* get saved CR */
+ std r22,PACAEXCSP(r20) /* pop off the exception frame */
+ mtcr r23 /* restore CR */
+ ld r22,0(r21) /* Get SRR0 from exc. frame */
+ ld r23,8(r21) /* Get SRR1 from exc. frame */
mtspr SRR0,r22
- lwz r21,PACACCR(r20) /* Restore the clobbered regs */
- mtcr r21
- ld r1, PACAR1(r20)
- ld r21,PACAR21(r20)
- ld r22,PACAR22(r20)
- mfspr r20,SPRG2
+ mtspr SRR1,r23
+ ld r20,16(r21) /* restore r20 from exc. frame */
+ ld r22,32(r21) /* restore r22 and r23 */
+ ld r23,40(r21)
+ ld r21,24(r21) /* restore r21 last */
rfid
+_TRACEBACK(do_slb_bolted)
_GLOBAL(do_stab_SI)
mflr r21 /* Save LR in r21 */
- /* r21 restored later from r1 */
+
/*
* r3 contains the faulting address
* r4 contains the required access permissions
@@ -787,108 +1020,72 @@
*/
bl .ste_allocate /* build STE if possible */
- mtlr r21 /* restore LR */
- mr r21,r1 /* restore r21 */
-
or. r3,r3,r3 /* Check return code */
- bnelr /* Return to DSI or ISI on failure */
-
- /*
- * The STE has been created/updated. Restore and retry the faulting inst
- */
-
- ld r3,_CCR(r21)
- ld r4,_LINK(r21)
- ld r5,_CTR(r21)
- ld r6,_XER(r21)
-
- mtcrf 0xff,r3
- mtlr r4
- mtctr r5
- mtspr XER,r6
- REST_8GPRS(0,r21)
- REST_4GPRS(8,r21)
- REST_2GPRS(12,r21)
- mtspr SRR1,r23
- mtspr SRR0,r22
- ld r20,GPR20(r21)
- ld r22,GPR22(r21)
- ld r23,GPR23(r21)
- ld r21,GPR21(r21)
- rfid
+ beq fast_exception_return /* Return from exception on success */
+ mtlr r21 /* restore LR */
+ blr /* Return to DSI or ISI on failure */
/*
- * This code finishes saving the registers to the exception frame
- * and jumps to the appropriate handler for the exception. Address
- * translation is already on.
- */
-_GLOBAL(transfer_to_handler)
-/*
- * Save the rest of the registers into the pt_regs structure
- */
- std r22,_NIP(r21)
- std r23,_MSR(r21)
- std r6,TRAP(r21)
- ld r6,GPR6(r21)
- SAVE_2GPRS(14, r21)
- SAVE_4GPRS(16, r21)
- SAVE_8GPRS(24, r21)
-/*
- * Clear the RESULT field
+ * This code finishes saving the registers to the exception frame.
+ * Address translation is already on.
*/
+_GLOBAL(save_remaining_regs)
+ /*
+ * Save the rest of the registers into the pt_regs structure
+ */
+ std r22,_NIP(r1)
+ std r23,_MSR(r1)
+ std r6,TRAP(r1)
+ ld r6,GPR6(r1)
+ SAVE_2GPRS(14, r1)
+ SAVE_4GPRS(16, r1)
+ SAVE_8GPRS(24, r1)
+
+ /*
+ * Clear the RESULT field
+ */
li r22,0
- std r22,RESULT(r21)
-/*
- * Test if from user state; result will be tested later
- */
+ std r22,RESULT(r1)
+
+ /*
+ * Test if from user state; result will be tested later
+ */
andi. r23,r23,MSR_PR /* Set CR for later branch */
-/*
- * Indicate that r1 contains the kernel stack and
- * get the Kernel TOC and CURRENT pointers from the Paca
- */
+
+ /*
+ * Indicate that r1 contains the kernel stack and
+ * get the Kernel TOC and CURRENT pointers from the Paca
+ */
mfspr r23,SPRG3 /* Get PACA */
std r22,PACAKSAVE(r23) /* r1 is now kernel sp */
ld r2,PACATOC(r23) /* Get Kernel TOC pointer */
ld r22,PACACURRENT(r23) /* Get CURRENT */
-/*
- * If from user state, update THREAD.regs
- */
+
+ /*
+ * If from user state, update THREAD.regs
+ */
beq 2f /* Modify THREAD.regs if from user */
addi r24,r1,STACK_FRAME_OVERHEAD
std r24,THREAD+PT_REGS(r22)
2:
-/*
- * Since we store 'current' in the PACA now, we don't need to
- * set it here. When r2 was used as 'current' it had to be
- * set here because it could have been changed by the user.
- */
+ /*
+ * Since we store 'current' in the PACA now, we don't need to
+ * set it here. When r2 was used as 'current' it had to be
+ * set here because it could have been changed by the user.
+ */
-/*
- * Check for kernel stack overflow
- */
- addi r24,r22,TASK_STRUCT_SIZE /* check for kernel stack overflow */
- cmpld 0,r1,r22
- cmpld 1,r1,r24
- crand 1,1,4
- bgt- .stack_ovf /* if r22 < r1 < r22+TASK_STRUCT_SIZE */
-
-/*
- * Get the handler address and its return address and
- * rfid to the handler
- */
-/* MIKEC: Do we really need to rfid here? Since we are already running
- with relocate on, could we just branch to the handler?
- We also will be turning on MSR.EE for some interrupts here
-*/
- mflr r23
- ld r24,0(r23) /* virtual address of handler */
- ld r23,8(r23) /* where to go when done */
- mtspr SRR0,r24
- mtspr SRR1,r20
- mtlr r23
- rfid /* jump to handler */
+ SET_REG_TO_CONST(r22, MSR_KERNEL)
+
+#ifdef DO_SOFT_DISABLE
+ stb r20,PACAPROCENABLED(r23) /* possibly soft enable */
+ ori r22,r22,MSR_EE /* always hard enable */
+#else
+ rldimi r22,r20,15,48 /* Insert desired EE value */
+#endif
+
+ mtmsrd r22
+ blr
-#ifdef CONFIG_SMP
/*
* On pSeries, secondary processors spin in the following code.
* At entry, r3 = this processor's number (in Linux terms, not hardware).
@@ -918,11 +1115,12 @@
ldx r1,r3,r28
cmpi 0,r23,0
+#ifdef CONFIG_SMP
#ifdef SECONDARY_PROCESSORS
bne .__secondary_start
#endif
+#endif
b 1b /* Loop until told to go */
-#endif /* CONFIG_SMP */
_GLOBAL(__start_initialization_iSeries)
@@ -947,6 +1145,8 @@
li r3,1 /* Indicate to skip adding esid C to table */
bl .stab_initialize
+ bl .iSeries_fixup_klimit
+
b .start_here_common
_GLOBAL(__start_initialization_pSeries)
@@ -1106,20 +1306,6 @@
copy_to_here:
/*
- * On kernel stack overflow, load up an initial stack pointer
- * and call StackOverflow(regs), which should not return.
- */
-_STATIC(stack_ovf)
- addi r3,r1,STACK_FRAME_OVERHEAD
- LOADADDR(r1,init_task_union)
- addi r1,r1,TASK_UNION_SIZE-STACK_FRAME_OVERHEAD
- LOADADDR(r24,StackOverflow)
- SET_REG_TO_CONST(r20, MSR_KERNEL);
- mtspr SRR0,r24
- mtspr SRR1,r20
- rfid
-
-/*
* Disable FP for the task which had the FPU previously,
* and save its floating-point registers in its thread_struct.
* Enables the FPU for use in the kernel on return.
@@ -1130,7 +1316,7 @@
mfmsr r5 /* grab the current MSR */
ori r5,r5,MSR_FP
mtmsrd r5 /* enable use of fpu now */
- SYNC
+ isync
/*
* For SMP, we don't do lazy FPU switching because it just gets too
* horrendously complex, especially when a task switches from one CPU
@@ -1166,19 +1352,7 @@
std r4,last_task_used_math@l(r3)
#endif /* CONFIG_SMP */
/* restore registers and return */
- ld r3,_CCR(r21)
- ld r4,_LINK(r21)
- mtcrf 0xff,r3
- mtlr r4
- REST_2GPRS(1, r21)
- REST_4GPRS(3, r21)
- /* we haven't used ctr or xer */
- mtspr SRR1,r23
- mtspr SRR0,r22
- REST_GPR(20, r21)
- REST_2GPRS(22, r21)
- ld r21,GPR21(r21)
- rfid
+ b fast_exception_return
/*
* FP unavailable trap from kernel - print a message, but let
@@ -1206,7 +1380,7 @@
mfmsr r5
ori r5,r5,MSR_FP
mtmsrd r5 /* enable use of fpu now */
- SYNC
+ isync
cmpi 0,r3,0
beqlr- /* if no previous owner, done */
addi r3,r3,THREAD /* want THREAD of task */
@@ -1255,6 +1429,7 @@
std r2,PACATOC(r25)
li r6,0
std r6,PACAKSAVE(r25)
+ stb r6,PACAPROCENABLED(r25)
#ifndef CONFIG_PPC_ISERIES
/* Initialize the page table pointer register. */
@@ -1287,14 +1462,15 @@
#else
mtasr r4 /* set the stab location */
#endif
- slbia
-
li r7,0
mtlr r7
/* enable MMU and jump to start_secondary */
LOADADDR(r3,.start_secondary)
SET_REG_TO_CONST(r4, MSR_KERNEL)
+#ifdef DO_SOFT_DISABLE
+ ori r4,r4,MSR_EE
+#endif
mtspr SRR0,r3
mtspr SRR1,r4
rfid
@@ -1312,7 +1488,7 @@
rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
or r11,r11,r12
mtmsrd r11
- SYNC
+ isync
blr
/*
@@ -1327,7 +1503,7 @@
rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
andc r11,r11,r12
mtmsrd r11
- SYNC
+ isync
blr
@@ -1335,6 +1511,31 @@
* This is where the main kernel code starts.
*/
_STATIC(start_here_pSeries)
+ /* get a new offset, now that the kernel has moved. */
+ bl .reloc_offset
+ mr r26,r3
+
+ /* setup the naca pointer which is needed by *tab_initialize */
+ LOADADDR(r6,naca)
+ sub r6,r6,r26 /* addr of the variable naca */
+ li r27,0x4000
+ std r27,0(r6) /* set the value of naca */
+
+#ifdef CONFIG_HMT
+ /* Start up the second thread on cpu 0 */
+ mfspr r3,PVR
+ srwi r3,r3,16
+ cmpwi r3,0x34 /* Pulsar */
+ beq 90f
+ cmpwi r3,0x36 /* Icestar */
+ beq 90f
+ cmpwi r3,0x37 /* SStar */
+ beq 90f
+ b 91f /* HMT not supported */
+90: li r3,0
+ bl .hmt_start_secondary
+91:
+#endif
#ifdef CONFIG_SMP
/* All secondary cpus are now spinning on a common
@@ -1349,10 +1550,6 @@
std r3,0(r4)
#endif
- /* get a new offset, now that the kernel has moved. */
- bl .reloc_offset
- mr r26,r3
-
/* The following gets the stack and TOC set up with the regs */
/* pointing to the real addr of the kernel stack. This is */
/* all done to support the C function call below which sets */
@@ -1374,17 +1571,12 @@
addi r2,r2,0x4000
sub r2,r2,r26
- /* setup the naca pointer which is needed by *tab_initialize */
- LOADADDR(r6,naca)
- sub r6,r6,r26 /* addr of the variable naca */
- li r27,0x4000
- std r27,0(r6) /* set the value of naca */
-
/* Init naca->debug_switch so it can be used in stab & htab init. */
bl .ppcdbg_initialize
/* Get the pointer to the segment table which is used by */
/* stab_initialize */
+ li r27,0x4000
ld r6,PACA(r27) /* Get the base Paca pointer */
sub r6,r6,r26 /* convert to physical addr */
mtspr SPRG3,r6 /* PPPBBB: Temp... -Peter */
@@ -1394,7 +1586,6 @@
/* Initialize an initial memory mapping and turn on relocation. */
li r3,0 /* 0 -> include esid 0xC00000000 */
- slbia
bl .stab_initialize
bl .htab_initialize
@@ -1451,8 +1642,6 @@
SET_REG_TO_CONST(r8, KERNELBASE)
addi r8,r8,0x4000
std r8,0(r9) /* set the value of the naca ptr */
-
- bl .naca_init /* Set initial values in the naca */
LOADADDR(r4,naca) /* Get Naca ptr address */
ld r4,0(r4) /* Get the location of the naca */
@@ -1466,14 +1655,19 @@
std r2,PACATOC(r4)
li r5,0
std r0,PACAKSAVE(r4)
-/*
- * Register old definition new definition
- *
- * SPRG0 temp - used to save gpr reserved for hypervisor
- * SPRG1 temp - used to save gpr unused
- * SPRG2 0 or kernel stack frame temp - used to save gpr
- * SPRG3 Linux thread virt addr of Paca
- */
+
+ /* ptr to hardware interrupt stack for processor 0 */
+ LOADADDR(r3, hardware_int_paca0)
+ li r5,0x1000
+ sldi r5,r5,3
+ subi r5,r5,STACK_FRAME_OVERHEAD
+
+ add r3,r3,r5
+ std r3,PACAHRDWINTSTACK(r4)
+
+ li r3,0
+ stb r3,PACAHRDWINTCOUNT(r4)
+
/*
* Restore the parms passed in from the bootloader.
@@ -1488,8 +1682,89 @@
/* Load up the kernel context */
5:
- bl .start_kernel
+#ifdef DO_SOFT_DISABLE
+ mfspr r4,SPRG3
+ li r5,0
+ stb r5,PACAPROCENABLED(r4) /* Soft Disabled */
+ mfmsr r5
+ ori r5,r5,MSR_EE /* Hard Enabled */
+ mtmsrd r5
+#endif
+ bl .start_kernel
+
+_GLOBAL(hmt_init)
+#ifdef CONFIG_HMT
+ LOADADDR(r5, hmt_thread_data)
+ mfspr r7,PVR
+ srwi r7,r7,16
+ cmpwi r7,0x34 /* Pulsar */
+ beq 90f
+ cmpwi r7,0x36 /* Icestar */
+ beq 91f
+ cmpwi r7,0x37 /* SStar */
+ beq 91f
+ b 101f
+90: mfspr r6,PIR
+ andi. r6,r6,0x1f
+ b 92f
+91: mfspr r6,PIR
+ andi. r6,r6,0x3ff
+92: sldi r4,r24,3
+ stwx r6,r5,r4
+ bl .hmt_start_secondary
+ b 101f
+
+__hmt_secondary_hold:
+ LOADADDR(r5, hmt_thread_data)
+ clrldi r5,r5,4
+ li r7,0
+ mfspr r6,PIR
+ mfspr r8,PVR
+ srwi r8,r8,16
+ cmpwi r8,0x34
+ bne 93f
+ andi. r6,r6,0x1f
+ b 103f
+93: andi. r6,r6,0x3f
+
+103: lwzx r8,r5,r7
+ cmpw r8,r6
+ beq 104f
+ addi r7,r7,8
+ b 103b
+
+104: addi r7,r7,4
+ lwzx r9,r5,r7
+ mr r24,r9
+101:
+#endif
+ mr r3,r24
+ b .pseries_secondary_smp_init
+
+#ifdef CONFIG_HMT
+_GLOBAL(hmt_start_secondary)
+ LOADADDR(r4,__hmt_secondary_hold)
+ clrldi r4,r4,4
+ mtspr NIADORM, r4
+ mfspr r4, MSRDORM
+ li r5, -65
+ and r4, r4, r5
+ mtspr MSRDORM, r4
+ lis r4,0xffef
+ ori r4,r4,0x7403
+ mtspr TSC, r4
+ li r4,0x1f4
+ mtspr TST, r4
+ mfspr r4, HID0
+ ori r4, r4, 0x1
+ mtspr HID0, r4
+ mfspr r4, CTRLF
+ oris r4, r4, 0x40
+ mtspr CTRLT, r4
+ blr
+#endif
+
/*
* We put a few things here that have to be page-aligned.
* This stuff goes at the beginning of the data segment,
@@ -1511,9 +1786,10 @@
ioremap_dir:
.space 4096
- .globl bolted_dir
-bolted_dir:
- .space 4096
+ .globl hardware_int_paca0
+hardware_int_paca0:
+ .space 8*4096
+
/* 4096 * 31 bytes of storage */
.globl stab_array
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/htab.c linuxppc64_2_4/arch/ppc64/kernel/htab.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/htab.c Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/htab.c Mon Oct 15 02:54:31 2001
@@ -34,10 +34,12 @@
#include
#include
#include
+#include
#include
#include
#include
#include
+#include
#include
/* For iSeries */
@@ -47,19 +49,18 @@
* HPTE --> PowerPC Hashed Page Table Entry
*/
-HTAB htab_data = {NULL, NULL, 0, 0, 0};
+HTAB htab_data = {NULL, 0, 0, 0, 0};
-static ssize_t ppc_htab_read(struct file * file, char * buf,
- size_t count, loff_t *ppos);
-static ssize_t ppc_htab_write(struct file * file, const char * buffer,
- size_t count, loff_t *ppos);
-static long ppc_htab_lseek(struct file * file, loff_t offset, int orig);
int proc_dol2crvec(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp);
void htab_initialize(void);
void make_pte(HPTE * htab, unsigned long va, unsigned long pa,
int mode, unsigned long hash_mask);
+void make_pte_LPAR(HPTE *htab,
+ unsigned long va, unsigned long pa, int mode,
+ unsigned long hash_mask);
+
extern unsigned long reloc_offset(void);
extern unsigned long get_kernel_vsid( unsigned long ea );
extern void cacheable_memzero( void *, unsigned int );
@@ -72,17 +73,16 @@
extern inline void make_ste(unsigned long stab,
unsigned long esid, unsigned long vsid);
-extern pgd_t * bolted_pgd;
-
extern char _stext[], _etext[], __start_naca[], __end_stab[];
-static spinlock_t hash_table_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t hash_table_lock ____cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
#define PTRRELOC(x) ((typeof(x))((unsigned long)(x) - offset))
#define PTRUNRELOC(x) ((typeof(x))((unsigned long)(x) + offset))
#define RELOC(x) (*PTRRELOC(&(x)))
extern unsigned long htab_size( unsigned long );
+unsigned long hpte_getword0_iSeries( unsigned long slot );
static inline void
create_pte_mapping(unsigned long start, unsigned long end,
@@ -113,24 +113,36 @@
* Calculate the required size of the htab. We want the number of
* PTEGs to equal one half the number of real pages.
*/
- htab_size_bytes = htab_size(_naca->physicalMemorySize);
+ htab_size_bytes = 1UL << _naca->pftSize;
pteg_count = htab_size_bytes >> 7;
- _htab_data->htab_num_ptegs = pteg_count;
- _htab_data->htab_hash_mask = pteg_count - 1;
- /* Find storage for the HPT. Must be contiguous in
- * the absolute address space.
- */
- table = lmb_alloc(htab_size_bytes, htab_size_bytes);
- if ( !table )
- panic("ERROR, cannot find space for HPTE\n");
- _htab_data->htab = (HPTE *)__a2v(table);
+ /* For debug, make the HTAB 1/8 as big as it normally would be. */
+ ifppcdebug(PPCDBG_HTABSIZE) {
+ pteg_count >>= 3;
+ htab_size_bytes = pteg_count << 7;
+ }
- /* htab absolute addr + encoded htabsize */
- RELOC(_SDR1) = table + __ilog2(pteg_count) - 11;
+ _htab_data->htab_num_ptegs = pteg_count;
+ _htab_data->htab_hash_mask = pteg_count - 1;
- /* Initialize the HPT with no entries */
- cacheable_memzero((void *)table, htab_size_bytes);
+ if(_machine == _MACH_pSeries) {
+ /* Find storage for the HPT. Must be contiguous in
+ * the absolute address space.
+ */
+ table = lmb_alloc(htab_size_bytes, htab_size_bytes);
+ if ( !table )
+ panic("ERROR, cannot find space for HPTE\n");
+ _htab_data->htab = (HPTE *)__a2v(table);
+
+ /* htab absolute addr + encoded htabsize */
+ RELOC(_SDR1) = table + __ilog2(pteg_count) - 11;
+
+ /* Initialize the HPT with no entries */
+ cacheable_memzero((void *)table, htab_size_bytes);
+ } else {
+ _htab_data->htab = NULL;
+ RELOC(_SDR1) = 0;
+ }
mode_ro = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RXRX;
mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX;
@@ -175,6 +187,11 @@
unsigned long hash, i;
volatile unsigned long x = 1;
+ if(_machine == _MACH_pSeriesLP) {
+ make_pte_LPAR(htab, va, pa, mode, hash_mask);
+ return;
+ }
+
hash = hpt_hash( va >> 12 );
hptep = htab + ((hash & hash_mask)*HPTES_PER_GROUP);
@@ -194,44 +211,42 @@
for(;x;x|=1);
}
-void invalidate_hpte( unsigned long slot )
+/* Functions to invalidate a HPTE */
+static void hpte_invalidate_iSeries( unsigned long slot )
{
+ HvCallHpt_invalidateSetSwBitsGet( slot, 0, 0 );
+}
- /* Invalidate the HPTE */
-
- if ( _machine == _MACH_iSeries ) {
- HvCallHpt_invalidateSetSwBitsGet( slot, 0, 0 );
- }
- else {
- /* Local copy of the first doubleword of the HPTE */
- union {
- unsigned long d;
- Hpte_dword0 h;
- } hpte_dw0;
+static void hpte_invalidate_pSeries( unsigned long slot )
+{
+ /* Local copy of the first doubleword of the HPTE */
+ union {
+ unsigned long d;
+ Hpte_dword0 h;
+ } hpte_dw0;
- /* Locate the HPTE */
- HPTE * hptep = htab_data.htab + slot;
+ /* Locate the HPTE */
+ HPTE * hptep = htab_data.htab + slot;
- /* Get the first doubleword of the HPTE */
- hpte_dw0.d = hptep->dw0.dword0;
-
- /* Invalidate the hpte */
- hptep->dw0.dword0 = 0;
+ /* Get the first doubleword of the HPTE */
+ hpte_dw0.d = hptep->dw0.dword0;
- /* Invalidate the tlb */
- {
- unsigned long vsid, group, pi, pi_high;
-
- vsid = hpte_dw0.h.avpn >> 5;
- group = slot >> 3;
- if(hpte_dw0.h.h) {
- group = ~group;
- }
- pi = (vsid ^ group) & 0x7ff;
- pi_high = (hpte_dw0.h.avpn & 0x1f) << 11;
- pi |= pi_high;
- _tlbie(pi << 12);
- }
+ /* Invalidate the hpte */
+ hptep->dw0.dword0 = 0;
+
+ /* Invalidate the tlb */
+ {
+ unsigned long vsid, group, pi, pi_high;
+
+ vsid = hpte_dw0.h.avpn >> 5;
+ group = slot >> 3;
+ if(hpte_dw0.h.h) {
+ group = ~group;
+ }
+ pi = (vsid ^ group) & 0x7ff;
+ pi_high = (hpte_dw0.h.avpn & 0x1f) << 11;
+ pi |= pi_high;
+ _tlbie(pi << 12);
}
}
@@ -240,48 +255,73 @@
* return slot index (if in primary group)
* return -slot index (if in secondary group)
*/
-long select_hpte_slot( unsigned long vpn )
+static long hpte_selectslot_iSeries( unsigned long vpn )
{
-
-/****** Add code for iSeries ******/
-
- HPTE * hptep;
HPTE hpte;
+ long ret_slot, orig_slot;
unsigned long primary_hash;
unsigned long hpteg_slot;
- long ret_slot, orig_slot;
+ unsigned long slot;
unsigned i, k;
+ union {
+ unsigned long d;
+ Hpte_dword0 h;
+ } hpte_dw0;
- if ( _machine == _MACH_iSeries ) {
- ret_slot = orig_slot = HvCallHpt_findValid( &hpte, vpn );
- if ( hpte.dw0.dw0.v ) { /* If valid ...what do we do now? */
- udbg_printf( "select_hpte_slot: vpn 0x%016lx already valid at slot 0x%016lx\n", vpn, ret_slot );
- udbg_printf( "select_hpte_slot: returned hpte 0x%016lx 0x%016lx\n", hpte.dw0.dword0, hpte.dw1.dword1 );
-
- return (0x8000000000000000);
-/* panic("select_hpte_slot found entry already valid\n"); */
- }
- if ( ret_slot == -1 ) { /* -1 indicates no available slots */
- /*
- * Eventually we will have a hypervisor call which will allow us to conditionally
- * invalidate an hpte depending on whether it is bolted. For now, we need to look
- * each entry to see if it is bolted before we invalidate it.
- */
-
-
- /* ADD CODE HERE */
- /* add code to cast out a non-bolted hpte */
- }
- else {
- if ( ret_slot < 0 ) {
- ret_slot &= 0x7fffffffffffffff;
- ret_slot = -ret_slot;
+ ret_slot = orig_slot = HvCallHpt_findValid( &hpte, vpn );
+ if ( hpte.dw0.dw0.v ) { /* If valid ...what do we do now? */
+ udbg_printf( "hpte_selectslot_iSeries: vpn 0x%016lx already valid at slot 0x%016lx\n", vpn, ret_slot );
+ udbg_printf( "hpte_selectslot_iSeries: returned hpte 0x%016lx 0x%016lx\n", hpte.dw0.dword0, hpte.dw1.dword1 );
+
+ return (0x8000000000000000);
+ /* panic("select_hpte_slot found entry already valid\n"); */
+ }
+ if ( ret_slot == -1 ) { /* -1 indicates no available slots */
+
+ /* No available entry found in secondary group */
+
+ PMC_SW_SYSTEM(htab_capacity_castouts);
+
+ primary_hash = hpt_hash( vpn );
+ hpteg_slot = ( primary_hash & htab_data.htab_hash_mask ) * HPTES_PER_GROUP;
+ k = htab_data.next_round_robin++ & 0x7;
+
+ for ( i=0; idw0.dword0;
- }
+ HPTE hpte;
+ HvCallHpt_get( &hpte, slot );
+ dword0 = hpte.dw0.dword0;
+
+ return dword0;
+}
+unsigned long hpte_getword0_pSeries( unsigned long slot )
+{
+ unsigned long dword0;
+ HPTE * hptep = htab_data.htab + slot;
+
+ dword0 = hptep->dw0.dword0;
return dword0;
}
-long find_hpte( unsigned long vpn )
+static long hpte_find_iSeries(unsigned long vpn)
{
HPTE hpte;
long slot;
- if ( _machine == _MACH_iSeries ) {
- slot = HvCallHpt_findValid( &hpte, vpn );
- if ( hpte.dw0.dw0.v ) {
- if ( slot < 0 ) {
- slot &= 0x7fffffffffffffff;
- slot = -slot;
- }
+ slot = HvCallHpt_findValid( &hpte, vpn );
+ if ( hpte.dw0.dw0.v ) {
+ if ( slot < 0 ) {
+ slot &= 0x7fffffffffffffff;
+ slot = -slot;
}
- else
- slot = -1;
- }
- else {
- union {
- unsigned long d;
- Hpte_dword0 h;
- } hpte_dw0;
- unsigned long hash;
- unsigned long i,j;
+ } else
+ slot = -1;
+ return slot;
+}
- hash = hpt_hash( vpn );
- for ( j=0; j<2; ++j ) {
- slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
- for ( i=0; i> 11 ) ) &&
- ( hpte_dw0.h.v ) &&
- ( hpte_dw0.h.h == j ) ) {
- /* HPTE matches */
- if ( j )
- slot = -slot;
- return slot;
- }
- ++slot;
+static long hpte_find_pSeries(unsigned long vpn)
+{
+ union {
+ unsigned long d;
+ Hpte_dword0 h;
+ } hpte_dw0;
+ long slot;
+ unsigned long hash;
+ unsigned long i,j;
+
+ hash = hpt_hash( vpn );
+ for ( j=0; j<2; ++j ) {
+ slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
+ for ( i=0; i> 11 ) ) &&
+ ( hpte_dw0.h.v ) &&
+ ( hpte_dw0.h.h == j ) ) {
+ /* HPTE matches */
+ if ( j )
+ slot = -slot;
+ return slot;
}
- hash = ~hash;
+ ++slot;
}
- slot = -1;
+ hash = ~hash;
}
- return slot;
+ return -1;
}
/* This function is called by btmalloc to bolt an entry in the hpt */
@@ -421,7 +464,7 @@
spin_lock_irqsave( &hash_table_lock, flags );
- hpte_slot = select_hpte_slot( vpn );
+ hpte_slot = ppc_md.hpte_selectslot( vpn );
hash = 0;
if ( hpte_slot < 0 ) {
if ( hpte_slot == 0x8000000000000000 ) {
@@ -434,7 +477,7 @@
hash = 1;
hpte_slot = -hpte_slot;
}
- create_valid_hpte( hpte_slot, vpn, pa >> 12, hash, ptep,
+ ppc_md.hpte_create_valid( hpte_slot, vpn, pa >> 12, hash, ptep,
hpteflags, bolted );
if ( ptep ) {
@@ -465,10 +508,10 @@
* The HPTE is set with the vpn, rpn (converted to absolute)
* and flags
*/
-void create_valid_hpte(unsigned long slot, unsigned long vpn,
- unsigned long prpn, unsigned hash,
- void * ptep, unsigned hpteflags,
- unsigned bolted )
+static void hpte_create_valid_iSeries(unsigned long slot, unsigned long vpn,
+ unsigned long prpn, unsigned hash,
+ void * ptep, unsigned hpteflags,
+ unsigned bolted )
{
/* Local copy of HPTE */
struct {
@@ -500,33 +543,64 @@
lhpte.dw0.h.v = 1;
/* Now fill in the actual HPTE */
+ HvCallHpt_addValidate( slot, hash, (HPTE *)&lhpte );
+}
- PPCDBG(PPCDBG_MM, "create_valid_hpte: slot=0x%lx, hash=%d, hpte=0x%016lx 0x%016lx\n", slot, hash, lhpte.dw0.d, lhpte.dw1.d );
+static void hpte_create_valid_pSeries(unsigned long slot, unsigned long vpn,
+ unsigned long prpn, unsigned hash,
+ void * ptep, unsigned hpteflags,
+ unsigned bolted)
+{
+ /* Local copy of HPTE */
+ struct {
+ /* Local copy of first doubleword of HPTE */
+ union {
+ unsigned long d;
+ Hpte_dword0 h;
+ } dw0;
+ /* Local copy of second doubleword of HPTE */
+ union {
+ unsigned long d;
+ Hpte_dword1 h;
+ Hpte_dword1_flags f;
+ } dw1;
+ } lhpte;
- if ( _machine == _MACH_iSeries ) {
- HvCallHpt_addValidate( slot, hash, (HPTE *)&lhpte );
- }
- else {
- HPTE * hptep = htab_data.htab + slot;
+ unsigned long avpn = vpn >> 11;
+ unsigned long arpn = physRpn_to_absRpn( prpn );
- /* Set the second dword first so that the valid bit
- * is the last thing set
- */
+ HPTE *hptep;
- hptep->dw1.dword1 = lhpte.dw1.d;
+ /* Fill in the local HPTE with absolute rpn, avpn and flags */
+ lhpte.dw1.d = 0;
+ lhpte.dw1.h.rpn = arpn;
+ lhpte.dw1.f.flags = hpteflags;
- /* Guarantee the second dword is visible before
- * the valid bit
- */
+ lhpte.dw0.d = 0;
+ lhpte.dw0.h.avpn = avpn;
+ lhpte.dw0.h.h = hash;
+ lhpte.dw0.h.bolted = bolted;
+ lhpte.dw0.h.v = 1;
- __asm__ __volatile__ ("eieio" : : : "memory");
+ /* Now fill in the actual HPTE */
+ hptep = htab_data.htab + slot;
+
+ /* Set the second dword first so that the valid bit
+ * is the last thing set
+ */
+
+ hptep->dw1.dword1 = lhpte.dw1.d;
- /* Now set the first dword including the valid bit */
- hptep->dw0.dword0 = lhpte.dw0.d;
+ /* Guarantee the second dword is visible before
+ * the valid bit
+ */
+
+ __asm__ __volatile__ ("eieio" : : : "memory");
- __asm__ __volatile__ ("ptesync" : : : "memory");
+ /* Now set the first dword including the valid bit */
+ hptep->dw0.dword0 = lhpte.dw0.d;
- }
+ __asm__ __volatile__ ("ptesync" : : : "memory");
}
/* find_linux_pte returns the address of a linux pte for a given
@@ -564,49 +638,69 @@
1 ) );
}
-static void updateHptePP( long slot, unsigned long newpp, unsigned long va )
+static void hpte_updatepp_iSeries(long slot, unsigned long newpp, unsigned long va)
{
- if ( _machine == _MACH_iSeries ) {
- HvCallHpt_setPp( slot, newpp );
- }
- else {
- /* Local copy of first doubleword of HPTE */
- union {
- unsigned long d;
- Hpte_dword0 h;
- } hpte_dw0;
-
- /* Local copy of second doubleword of HPTE */
- union {
- unsigned long d;
- Hpte_dword1 h;
- Hpte_dword1_flags f;
- } hpte_dw1;
-
- HPTE * hptep = htab_data.htab + slot;
-
- /* Turn off valid bit in HPTE */
- hpte_dw0.d = hptep->dw0.dword0;
- hpte_dw0.h.v = 0;
- hptep->dw0.dword0 = hpte_dw0.d;
-
- /* Ensure it is out of the tlb too */
- _tlbie( va );
-
- /* Insert the new pp bits into the HPTE */
- hpte_dw1.d = hptep->dw1.dword1;
- hpte_dw1.h.pp = newpp;
- hptep->dw1.dword1 = hpte_dw1.d;
+ HvCallHpt_setPp( slot, newpp );
+}
- /* Ensure it is visible before validating */
- __asm__ __volatile__ ("eieio" : : : "memory");
+static void hpte_updatepp_pSeries(long slot, unsigned long newpp, unsigned long va)
+{
+ /* Local copy of first doubleword of HPTE */
+ union {
+ unsigned long d;
+ Hpte_dword0 h;
+ } hpte_dw0;
+
+ /* Local copy of second doubleword of HPTE */
+ union {
+ unsigned long d;
+ Hpte_dword1 h;
+ Hpte_dword1_flags f;
+ } hpte_dw1;
+
+ HPTE * hptep = htab_data.htab + slot;
+
+ /* Turn off valid bit in HPTE */
+ hpte_dw0.d = hptep->dw0.dword0;
+ hpte_dw0.h.v = 0;
+ hptep->dw0.dword0 = hpte_dw0.d;
+
+ /* Ensure it is out of the tlb too */
+ _tlbie( va );
+
+ /* Insert the new pp bits into the HPTE */
+ hpte_dw1.d = hptep->dw1.dword1;
+ hpte_dw1.h.pp = newpp;
+ hptep->dw1.dword1 = hpte_dw1.d;
+
+ /* Ensure it is visible before validating */
+ __asm__ __volatile__ ("eieio" : : : "memory");
+
+ /* Turn the valid bit back on in HPTE */
+ hpte_dw0.h.v = 1;
+ hptep->dw0.dword0 = hpte_dw0.d;
- /* Turn the valid bit back on in HPTE */
- hpte_dw0.h.v = 1;
- hptep->dw0.dword0 = hpte_dw0.d;
+ __asm__ __volatile__ ("ptesync" : : : "memory");
+}
- __asm__ __volatile__ ("ptesync" : : : "memory");
- }
+/* This is called very early. */
+void htpe_init_iSeries(void)
+{
+ ppc_md.hpte_invalidate = hpte_invalidate_iSeries;
+ ppc_md.hpte_updatepp = hpte_updatepp_iSeries;
+ ppc_md.hpte_getword0 = hpte_getword0_iSeries;
+ ppc_md.hpte_selectslot = hpte_selectslot_iSeries;
+ ppc_md.hpte_create_valid = hpte_create_valid_iSeries;
+ ppc_md.hpte_find = hpte_find_iSeries;
+}
+void htpe_init_pSeries(void)
+{
+ ppc_md.hpte_invalidate = hpte_invalidate_pSeries;
+ ppc_md.hpte_updatepp = hpte_updatepp_pSeries;
+ ppc_md.hpte_getword0 = hpte_getword0_pSeries;
+ ppc_md.hpte_selectslot = hpte_selectslot_pSeries;
+ ppc_md.hpte_create_valid = hpte_create_valid_pSeries;
+ ppc_md.hpte_find = hpte_find_pSeries;
}
/* Handle a fault by adding an HPTE
@@ -640,9 +734,7 @@
* we're bolting the entire 0xC0... region.
*/
udbg_printf("Doh!!! hash_page saw a kernel address...\n");
-#if defined(CONFIG_XMON)
- xmon(0);
-#endif
+ PPCDBG_ENTER_DEBUGGER();
for(;x;x|=1);
vsid = get_kernel_vsid( ea );
@@ -671,7 +763,6 @@
}
vsid = get_vsid(mm->context, ea );
break;
- case BOLTED_REGION_ID:
default:
/* Not a valid range, send the problem up to do_page_fault */
return 1;
@@ -760,7 +851,7 @@
if ( pte_val(old_pte) & _PAGE_HPTENOIX ) {
unsigned long slot;
pte_val(old_pte) &= ~_PAGE_HPTEFLAGS;
- slot = find_hpte( vpn );
+ slot = ppc_md.hpte_find( vpn );
if ( slot != -1 ) {
if ( slot < 0 ) {
pte_val(old_pte) |= _PAGE_SECONDARY;
@@ -800,12 +891,12 @@
slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
slot += (pte_val(old_pte) & _PAGE_GROUP_IX) >> 12;
/* If there is an HPTE for this page it is indexed by slot */
- hpte_dw0.d = get_hpte0( slot );
+ hpte_dw0.d = ppc_md.hpte_getword0( slot );
if ( (hpte_dw0.h.avpn == (vpn >> 11) ) &&
(hpte_dw0.h.v) &&
(hpte_dw0.h.h == secondary ) ){
/* HPTE matches */
- updateHptePP( slot, newpp, va );
+ ppc_md.hpte_updatepp( slot, newpp, va );
if ( !pte_same( old_pte, new_pte ) )
*ptep = new_pte;
}
@@ -822,7 +913,7 @@
*
* Find an available HPTE slot
*/
- slot = select_hpte_slot( vpn );
+ slot = ppc_md.hpte_selectslot( vpn );
/* Debug code */
if ( slot == 0x8000000000000000 ) {
@@ -865,7 +956,7 @@
hpteflags = (pte_val(new_pte) & 0x1f8) | newpp;
/* Create the HPTE */
- create_valid_hpte( slot, vpn, prpn, hash_ind, ptep, hpteflags, 0 );
+ ppc_md.hpte_create_valid( slot, vpn, prpn, hash_ind, ptep, hpteflags, 0 );
}
@@ -882,43 +973,6 @@
return rc;
}
-unsigned long ___pa(unsigned long ea)
-{
- unsigned long pa = 0;
- struct mm_struct *mm;
- void *pgdir = NULL;
- pte_t *ptep;
-
- switch( REGION_ID(ea) ) {
- case KERNEL_REGION_ID:
- pa = ea - PAGE_OFFSET;
- break;
- case VMALLOC_REGION_ID:
- mm = &init_mm;
- pgdir = mm->pgd;
- ptep = find_linux_pte(pgdir, ea);
- pa = pte_pagenr(*ptep) << PAGE_SHIFT;
- break;
- case IO_REGION_ID:
- mm = &ioremap_mm;
- pgdir = mm->pgd;
- ptep = find_linux_pte(pgdir, ea);
- pa = pte_pagenr(*ptep) << PAGE_SHIFT;
- break;
- case BOLTED_REGION_ID:
- pgdir = bolted_pgd;
- ptep = find_linux_pte(pgdir, ea);
- pa = pte_pagenr(*ptep) << PAGE_SHIFT;
- break;
- default:
- break;
- }
-
- pa |= (ea & (PAGE_SIZE-1));
-
- return(pa);
-}
-
void flush_hash_page( unsigned long context, unsigned long ea, pte_t pte )
{
unsigned long vsid, vpn, va, hash, secondary, slot, flags;
@@ -943,12 +997,12 @@
/* If there is an HPTE for this page it is indexed by slot */
spin_lock_irqsave( &hash_table_lock, flags);
- hpte_dw0.d = get_hpte0( slot );
+ hpte_dw0.d = ppc_md.hpte_getword0( slot );
if ( (hpte_dw0.h.avpn == (vpn >> 11) ) &&
(hpte_dw0.h.v) &&
(hpte_dw0.h.h == secondary ) ){
/* HPTE matches */
- invalidate_hpte( slot );
+ ppc_md.hpte_invalidate( slot );
}
else {
unsigned k;
@@ -959,7 +1013,7 @@
hash = ~hash;
slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
for ( k=0; k<8; ++k ) {
- hpte_dw0.d = get_hpte0( slot+k );
+ hpte_dw0.d = ppc_md.hpte_getword0( slot+k );
if ( ( hpte_dw0.h.avpn == (vpn >> 11) ) &&
( hpte_dw0.h.v ) &&
( hpte_dw0.h.h == secondary ) ) {
@@ -1101,67 +1155,57 @@
return 0;
}
-static long
-ppc_htab_lseek(struct file * file, loff_t offset, int orig)
-{
- switch (orig) {
- case 0:
- file->f_pos = offset;
- return(file->f_pos);
- case 1:
- file->f_pos += offset;
- return(file->f_pos);
- case 2:
- return(-EINVAL);
- default:
- return(-EINVAL);
- }
-}
-/*
- * Allow user to define performance counters and resize the hash table
- */
-static ssize_t ppc_htab_write(struct file * file, const char * buffer,
- size_t count, loff_t *ppos)
+static __inline__ void set_pp_bit(unsigned long pp, HPTE *addr)
{
- return -EINVAL;
+ unsigned long old;
+ unsigned long *p = (unsigned long *)(&(addr->dw1));
+
+ __asm__ __volatile__(
+ "1: ldarx %0,0,%3\n\
+ rldimi %0,%2,0,62\n\
+ stdcx. %0,0,%3\n\
+ bne 1b"
+ : "=&r" (old), "=m" (*p)
+ : "r" (pp), "r" (p), "m" (*p)
+ : "cc");
}
/*
- * print some useful info about the hash table. This function
- * is _REALLY_ slow (see the nested for loops below) but nothing
- * in here should be really timing critical. -- Cort
+ * Update the page protection bits. Intended to be used to create
+ * guard pages for kernel data structures on pages which are bolted
+ * in the HPT. Assumes pages being operated on will not be stolen.
*/
-static ssize_t ppc_htab_read(struct file * file, char * buf,
- size_t count, loff_t *ppos)
+void updateBoltedHptePP( unsigned long newpp, unsigned long ea )
{
- return -EINVAL;
-}
+ unsigned long vsid,va,vpn,flags;
+ long slot;
-/* round mem size up to next power of 2 -- htab size must be a power of 2 */
-unsigned long
-rounded_mem_size(unsigned long mem_size)
-{
- unsigned long rnd_mem_size;
+ if(_machine == _MACH_pSeriesLP)
+ return; /* hack for now. */
+
+ vsid = get_kernel_vsid( ea );
+ va = ( vsid << 28 ) | ( ea & 0x0fffffff );
+ vpn = va >> PAGE_SHIFT;
- rnd_mem_size = 1UL << (unsigned long)__ilog2(mem_size);
- if ( rnd_mem_size < mem_size )
- rnd_mem_size <<= 1;
+ slot = ppc_md.hpte_find( vpn );
+
+ if ( _machine == _MACH_iSeries ) {
+ HvCallHpt_setPp( slot, newpp );
+ } else {
+ HPTE * hptep = htab_data.htab + slot;
- return rnd_mem_size;
-}
+ if (!htab_data.htab) return;
+ set_pp_bit(newpp , hptep );
-unsigned long
-htab_size(unsigned long mem_size)
-{
- unsigned long offset = reloc_offset();
- struct Naca *_naca = RELOC(naca);
- unsigned long rnd_mem_size = rounded_mem_size(mem_size);
- unsigned long pteg_count = (rnd_mem_size >> (12 + 1)); /* #pages/2 */
- /* For debug, make the HTAB 1/8 as big as it normally would be. */
- if(_naca->debug_switch & PPCDBG_HTABSIZE) {
- pteg_count >>= 3;
+ /* Ensure it is out of the tlb too */
+ spin_lock_irqsave( &hash_table_lock, flags );
+ _tlbie( va );
+ spin_unlock_irqrestore( &hash_table_lock, flags );
+
+ /* Ensure it is visible before validating */
+ __asm__ __volatile__ ("eieio" : : : "memory");
+ __asm__ __volatile__ ("ptesync" : : : "memory");
}
- return (pteg_count << 7); /* pteg_count*128B/PTEG */
}
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/i8259.c linuxppc64_2_4/arch/ppc64/kernel/i8259.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/i8259.c Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/i8259.c Tue Oct 9 21:22:29 2001
@@ -10,6 +10,7 @@
#include
#include
#include
+#include
#include
#include "i8259.h"
#include
@@ -19,7 +20,7 @@
#define cached_A1 (cached_8259[0])
#define cached_21 (cached_8259[1])
-static spinlock_t i8259_lock = SPIN_LOCK_UNLOCKED;
+static spinlock_t i8259_lock ____cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
int i8259_pic_irq_offset;
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_IoMmTable.c linuxppc64_2_4/arch/ppc64/kernel/iSeries_IoMmTable.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_IoMmTable.c Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/iSeries_IoMmTable.c Sat Sep 22 08:10:50 2001
@@ -30,27 +30,32 @@
#include
#include
#include
+#include
#include "iSeries_IoMmTable.h"
#include "pci.h"
-void iSeries_allocateDeviceBars(struct pci_dev* PciDevPtr);
/*******************************************************************/
/* Table defines */
/* Entry size is 4 MB * 1024 Entries = 4GB. */
/*******************************************************************/
-#define iSeries_IoMmTable_Entry_Size 0x00400000
#define iSeries_IoMmTable_Size 1024
-#define iSeries_Base_Io_Memory 0xFFFFFFFF
+unsigned long iSeries_IoMmTable_Entry_Size = 0x0000000000400000;
+unsigned long iSeries_Base_Io_Memory = 0xE000000000000000;
+
+/*******************************************************************/
+/* Lookup Tables. */
+/*******************************************************************/
+struct iSeries_Device_Node* iSeries_IoMmTable[iSeries_IoMmTable_Size];
+u8 iSeries_IoBarTable[iSeries_IoMmTable_Size];
/*******************************************************************/
/* Static and Global variables */
/*******************************************************************/
-struct pci_dev* iSeries_IoMmTable[iSeries_IoMmTable_Size];
-u8 iSeries_IoBarTable[iSeries_IoMmTable_Size];
-static int iSeries_CurrentIndex;
+static long iSeries_CurrentIndex;
static char* iSeriesPciIoText = "iSeries PCI I/O";
static spinlock_t iSeriesIoMmTableLock = SPIN_LOCK_UNLOCKED;
+
/*******************************************************************/
/* iSeries_IoMmTable_Initialize */
/*******************************************************************/
@@ -59,15 +64,16 @@
/* methods. */
/*******************************************************************/
void iSeries_IoMmTable_Initialize(void) {
- int Index;
+ int Index = 0;
spin_lock(&iSeriesIoMmTableLock);
- for(Index=0;Indexresource[BarNumber];
iSeries_IoMmTable_AllocateEntry(PciDev, BarNumber);
@@ -98,90 +102,94 @@
/*******************************************************************/
/* - Allocates the number of entries required in table base on BAR */
/* size. */
-/* - This version, allocates top down, starting at 4GB. */
+/* - This version, allocates starting at iSeries_Base_Io_Memory and*/
+/* allocate up. */
/* - The size is round up to be a multiple of entry size. */
-/* - CurrentIndex is decremented to keep track of the last entry. */
+/* - CurrentIndex is incremented to keep track of the last entry. */
/* - Builds the resource entry for allocated BARs. */
/*******************************************************************/
void iSeries_IoMmTable_AllocateEntry(struct pci_dev* PciDev, int BarNumber) {
- struct resource* BarResource = &PciDev->resource[BarNumber];
- int BarSize = BarResource->end - BarResource->start;
- unsigned long BarStartAddr;
- unsigned long BarEndAddr;
- /***************************************************************/
- /* No space to allocate, skip Allocation. */
- /***************************************************************/
- if(BarSize == 0) return; /* Quick stage exit */
-
- /***************************************************************/
- /* Allocate the table entries needed. */
- /***************************************************************/
+ struct resource* BarResource = &PciDev->resource[BarNumber];
+ long BarSize = pci_resource_len(PciDev,BarNumber);
+ /***************************************************************
+ * No space to allocate, quick exit, skip Allocation. *
+ ***************************************************************/
+ if(BarSize == 0) return;
+ PPCDBG(PPCDBG_BUSWALK,"iSeries_IoMmTable_AllocateEntry Bar:%2d Index:0x%08X\n",BarNumber,iSeries_CurrentIndex);
+ /**************************************************************
+ * Set Resource values. *
+ ***************************************************************/
+ BarResource->name = iSeriesPciIoText;
+ BarResource->start = iSeries_IoMmTable_Entry_Size*(iSeries_CurrentIndex);
+ BarResource->start+= iSeries_Base_Io_Memory;
+ BarResource->end = BarResource->start+BarSize-1;
+ /**************************************************************
+ * Allocate the number of table entries needed. *
+ ***************************************************************/
spin_lock(&iSeriesIoMmTableLock);
- while(BarSize > 0) {
- iSeries_IoMmTable[iSeries_CurrentIndex] = PciDev;
+ while(BarSize > 0 ) {
+ iSeries_IoMmTable [iSeries_CurrentIndex] = (struct iSeries_Device_Node*)PciDev->sysdata;
iSeries_IoBarTable[iSeries_CurrentIndex] = BarNumber;
BarSize -= iSeries_IoMmTable_Entry_Size;
- --iSeries_CurrentIndex; /* Next Free entry */
+ ++iSeries_CurrentIndex;
}
spin_unlock(&iSeriesIoMmTableLock);
- BarStartAddr = iSeries_IoMmTable_Entry_Size*(iSeries_CurrentIndex+1);
- BarEndAddr = BarStartAddr + (BarResource->end - BarResource->start);
- /***************************************************************/
- /* Build Resource info */
- /***************************************************************/
- BarResource->name = iSeriesPciIoText;
- BarResource->start = (long)BarStartAddr;
- BarResource->end = (long)BarEndAddr;
-
- PPCDBG(PPCDBG_BUSWALK,"BarAloc %04X-%016LX\n",iSeries_CurrentIndex+1,BarStartAddr);
}
/*******************************************************************/
/* Translates an I/O Memory address to pci_dev* */
/*******************************************************************/
-struct pci_dev* iSeries_xlateIoMmAddress(unsigned long* IoAddress) {
- int PciDevIndex = (unsigned long)IoAddress/iSeries_IoMmTable_Entry_Size;
- struct pci_dev* PciDev = iSeries_IoMmTable[PciDevIndex];
- if(PciDev == 0) {
- printk("PCI: Invalid I/O Address: 0x%016LX\n",IoAddress);
- PCIFR("Invalid MMIO Address 0x%016LX",(unsigned long)IoAddress);
+struct iSeries_Device_Node* iSeries_xlateIoMmAddress(void* IoAddress) {
+ long TableIndex = ((unsigned long)IoAddress-iSeries_Base_Io_Memory)/iSeries_IoMmTable_Entry_Size;
+ struct iSeries_Device_Node* DevNode = iSeries_IoMmTable[TableIndex];
+ if(DevNode == NULL) {
+ printk("PCI: Invalid I/O Address: %p\n",IoAddress);
+ PCIFR( "Invalid MMIO Address %p", IoAddress);
}
- return PciDev;
+ return DevNode;
}
/************************************************************************/
/* Returns the Bar number of Address */
/************************************************************************/
-int iSeries_IoMmTable_Bar(unsigned long* IoAddress) {
- int BarIndex = (unsigned long)IoAddress/iSeries_IoMmTable_Entry_Size;
- int BarNumber = iSeries_IoBarTable[BarIndex];
- return BarNumber;
-}
-/************************************************************************/
-/* Return the Bar Base Address or 0. */
-/************************************************************************/
-unsigned long* iSeries_IoMmTable_BarBase(unsigned long* IoAddress) {
- unsigned long BaseAddr = 0;
- struct pci_dev* PciDev = iSeries_xlateIoMmAddress(IoAddress);
- if(PciDev != NULL) {
- int BarNumber = iSeries_IoMmTable_Bar(IoAddress);
- if(BarNumber != -1) {
- BaseAddr = PciDev->resource[BarNumber].start;
- }
- }
- return (unsigned long*)BaseAddr;
+int iSeries_IoMmTable_Bar(void* IoAddress) {
+ long TableIndex = ((unsigned long)IoAddress-iSeries_Base_Io_Memory)/iSeries_IoMmTable_Entry_Size;
+ return iSeries_IoBarTable[TableIndex];
+}
+/************************************************************************/
+/* Return the Bar Base Address or NULL */
+/************************************************************************/
+void* iSeries_IoMmTable_BarBase(void* IoAddress) {
+ int BarNumber;
+ long TableIndex = ((unsigned long)IoAddress-iSeries_Base_Io_Memory)/iSeries_IoMmTable_Entry_Size;
+ struct iSeries_Device_Node* Node = iSeries_IoMmTable[TableIndex];
+ if(Node == NULL ) return NULL;
+
+ BarNumber = iSeries_IoMmTable_Bar(IoAddress);
+ if(BarNumber == 0xFF) return NULL;
+
+ return (void*)(pci_resource_start(Node->PciDev,BarNumber));
}
/************************************************************************/
/* Return the Bar offset within the Bar Space */
/* Note: Assumes that address is valid. */
/************************************************************************/
-unsigned long iSeries_IoMmTable_BarOffset(unsigned long* IoAddress) {
+unsigned long iSeries_IoMmTable_BarOffset(void* IoAddress) {
return (unsigned long)IoAddress-(unsigned long)iSeries_IoMmTable_BarBase(IoAddress);
}
-/************************************************************************/
-/* Return 0 if Address is valid I/O Address */
-/************************************************************************/
-int iSeries_Is_IoMmAddress(unsigned long* IoAddress) {
- if( iSeries_xlateIoMmAddress(IoAddress) == NULL) return 1;
- else return 0;
+/************************************************************************
+ * List the table entries out.
+ * <4>PCI: 0. PciNode: 0xc0000000014cc300 Bar 0,
+ * <4>Pci: 1. Max Entries = 8
+ ************************************************************************/
+void iSeries_IoMmTable_Status(void) {
+ int Loop = 0;
+ struct iSeries_Device_Node* PciNode = NULL;
+ for(Loop = 0;Loop < iSeries_CurrentIndex;++Loop) {
+ if (PciNode != iSeries_IoMmTable[Loop] ) {
+ PciNode = iSeries_IoMmTable[Loop] ;
+ printk("\nPCI: %3d. PciNode: 0x%p Bar ",Loop,PciNode);
+ }
+ printk("%2d, ",iSeries_IoBarTable[Loop]);
+ }
+ printk("\nPci: %3d. Max Entries = %d\n",Loop, (int)(Loop*sizeof(void*)) );
}
-
-
+
\ No newline at end of file
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_IoMmTable.h linuxppc64_2_4/arch/ppc64/kernel/iSeries_IoMmTable.h
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_IoMmTable.h Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/iSeries_IoMmTable.h Sat Sep 22 08:11:22 2001
@@ -24,9 +24,12 @@
/************************************************************************/
/* Change Activity: */
/* Created December 12, 2000 */
+/* Ported to ppc64, August 30, 2001 */
/* End Change Activity */
/************************************************************************/
+struct pci_dev;
+
/************************************************************************/
/* iSeries_IoMmTable_Initialize */
/************************************************************************/
@@ -45,7 +48,7 @@
/* - Allocates ALL pci_dev BAR's and updates the resources with the BAR */
/* value. BARS with zero length will not have the resources. The */
/* HvCallPci_getBarParms is used to get the size of the BAR space. */
-/* It calls as400_IoMmTable_AllocateEntry to allocate each entry. */
+/* It calls iSeries_IoMmTable_AllocateEntry to allocate each entry. */
/* */
/* Parameters: */
/* pci_dev = Pointer to pci_dev structure that will be mapped to pseudo */
@@ -77,23 +80,22 @@
/************************************************************************/
/* iSeries_xlateIoMmAddress */
/************************************************************************/
-/* - Translates an I/O Memory address to pci_dev that has been allocated*/
-/* the psuedo I/O Address. */
+/* - Translates an I/O Memory address to Device Node that has been the */
+/* allocated the psuedo I/O Address. */
/* */
/* Parameters: */
/* IoAddress = I/O Memory Address. */
/* */
/* Return: */
-/* A pci_dev pointer to the device mapped to the I/O address. */
+/* A pci_dev to the device mapped to the I/O address. */
/************************************************************************/
-extern struct pci_dev* iSeries_xlateIoMmAddress(unsigned long* IoAddress);
+extern struct iSeries_Device_Node* iSeries_xlateIoMmAddress(void* IoAddress);
/************************************************************************/
/* Helper Methods */
/************************************************************************/
-extern int iSeries_IoMmTable_Bar(unsigned long *IoAddress);
-extern unsigned long* iSeries_IoMmTable_BarBase(unsigned long* IoAddress);
-extern unsigned long iSeries_IoMmTable_BarOffset(unsigned long* IoAddress);
-extern int iSeries_Is_IoMmAddress(unsigned long* IoAddress);
-
+extern int iSeries_IoMmTable_Bar(void* IoAddress);
+extern void* iSeries_IoMmTable_BarBase(void* IoAddress);
+extern unsigned long iSeries_IoMmTable_BarOffset(void* IoAddress);
+extern void iSeries_IoMmTable_Status(void);
#endif /* _ISERIES_IOMMTABLE_H */
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_VpdInfo.c linuxppc64_2_4/arch/ppc64/kernel/iSeries_VpdInfo.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_VpdInfo.c Wed Dec 31 18:00:00 1969
+++ linuxppc64_2_4/arch/ppc64/kernel/iSeries_VpdInfo.c Thu Sep 27 11:19:20 2001
@@ -0,0 +1,295 @@
+/************************************************************************/
+/* File iSeries_vpdInfo.c created by Allan Trautman on Fri Feb 2 2001. */
+/************************************************************************/
+/* This code gets the card location of the hardware */
+/* Copyright (C) 20yy */
+/* */
+/* This program is free software; you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation; either version 2 of the License, or */
+/* (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the: */
+/* Free Software Foundation, Inc., */
+/* 59 Temple Place, Suite 330, */
+/* Boston, MA 02111-1307 USA */
+/************************************************************************/
+/* Change Activity: */
+/* Created, Feb 2, 2001 */
+/* Ported to ppc64, August 20, 2001 */
+/* End Change Activity */
+/************************************************************************/
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+//#include
+#include
+#include "pci.h"
+
+/************************************************/
+/* Size of Bus VPD data */
+/************************************************/
+#define BUS_VPDSIZE 1024
+/************************************************/
+/* Bus Vpd Tags */
+/************************************************/
+#define VpdEndOfDataTag 0x78
+#define VpdEndOfAreaTag 0x79
+#define VpdIdStringTag 0x82
+#define VpdVendorAreaTag 0x84
+/************************************************/
+/* Mfg Area Tags */
+/************************************************/
+#define VpdFruFlag 0x4647 // "FG"
+#define VpdFruFrameId 0x4649 // "FI"
+#define VpdSlotMapFormat 0x4D46 // "MF"
+#define VpdAsmPartNumber 0x504E // "PN"
+#define VpdFruSerial 0x534E // "SN"
+#define VpdSlotMap 0x534D // "SM"
+
+/************************************************/
+/* Structures of the areas */
+/************************************************/
+struct MfgVpdAreaStruct {
+ u16 Tag;
+ u8 TagLength;
+ u8 AreaData1;
+ u8 AreaData2;
+};
+typedef struct MfgVpdAreaStruct MfgArea;
+#define MFG_ENTRY_SIZE 3
+
+struct SlotMapStruct {
+ u8 AgentId;
+ u8 SecondaryAgentId;
+ u8 PhbId;
+ char CardLocation[3];
+ char Parms[8];
+ char Reserved[2];
+};
+typedef struct SlotMapStruct SlotMap;
+#define SLOT_ENTRY_SIZE 16
+
+/****************************************************************
+ * *
+ * Bus, Card, Board, FrameId, CardLocation. *
+ ****************************************************************/
+LocationData* iSeries_GetLocationData(struct pci_dev* PciDev) {
+ struct iSeries_Device_Node* DevNode = (struct iSeries_Device_Node*)PciDev->sysdata;
+ LocationData* LocationPtr = (LocationData*)kmalloc(LOCATION_DATA_SIZE, GFP_KERNEL);
+ if(LocationPtr == NULL) {
+ printk("PCI: LocationData area allocation failed!\n");
+ return NULL;
+ }
+ memset(LocationPtr,0,LOCATION_DATA_SIZE);
+ LocationPtr->Bus = DevNode->BusNumber;
+ LocationPtr->Board = DevNode->Board;
+ LocationPtr->FrameId = DevNode->FrameId;
+ LocationPtr->Card = PCI_SLOT(DevNode->DevFn);
+ strcpy(&LocationPtr->CardLocation,&DevNode->CardLocation);
+ return LocationPtr;
+}
+
+/************************************************************************/
+/* Formats the device information. */
+/* - Pass in pci_dev* pointer to the device. */
+/* - Pass in buffer to place the data. Danger here is the buffer must */
+/* be as big as the client says it is. Should be at least 128 bytes.*/
+/* Return will the length of the string data put in the buffer. */
+/* Format: */
+/* PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet */
+/* controller */
+/************************************************************************/
+int iSeries_Device_Information(struct pci_dev* PciDev,char* Buffer, int BufferSize) {
+ struct iSeries_Device_Node* DevNode = (struct iSeries_Device_Node*)PciDev->sysdata;
+ char* BufPtr = Buffer;
+ int LineLen = 0;
+
+ if(DevNode == NULL) {
+ LineLen = sprintf(BufPtr+LineLen, "PCI: iSeries_Device_Information DevNode is NULL");
+ return LineLen;
+ }
+
+ if(BufferSize >= 128) {
+ LineLen = sprintf(BufPtr+LineLen,"PCI: Bus%3d, Device%3d, Vendor %04X ",
+ DevNode->BusNumber, PCI_SLOT(PciDev->devfn),PciDev->vendor);
+
+ LineLen += sprintf(BufPtr+LineLen,"Frame%3d, Card %4s ", DevNode->FrameId,DevNode->CardLocation);
+
+ if(pci_class_name(PciDev->class >> 8) == 0) {
+ LineLen += sprintf(BufPtr+LineLen,"0x%04X ",(int)(PciDev->class >> 8));
+ }
+ else {
+ LineLen += sprintf(BufPtr+LineLen,"%s",pci_class_name(PciDev->class >> 8) );
+ }
+ }
+ return LineLen;
+}
+/*****************************************************************/
+/* Parse the Slot Area */
+/*****************************************************************/
+void iSeries_Parse_SlotArea(SlotMap* MapPtr,int MapLen, struct iSeries_Device_Node* DevNode) {
+ int SlotMapLen = MapLen;
+ SlotMap* SlotMapPtr = MapPtr;
+ /*************************************************************/
+ /* Parse Slot label until we find the one requrested */
+ /*************************************************************/
+ while(SlotMapLen > 0) {
+ if(SlotMapPtr->AgentId == DevNode->AgentId ) {
+ /*******************************************************/
+ /* If Phb wasn't found, grab the entry first one found.*/
+ /*******************************************************/
+ if(DevNode->PhbId == 0xff) {
+ DevNode->PhbId = SlotMapPtr->PhbId;
+ }
+ /**************************************************/
+ /* Found it, extract the data. */
+ /**************************************************/
+ if( SlotMapPtr->PhbId == DevNode->PhbId ) {
+ memcpy(&DevNode->CardLocation,&SlotMapPtr->CardLocation,3);
+ DevNode->CardLocation[3] = 0;
+ //printk("PCI: Slot %p\n",SlotMapPtr);
+ break;
+ }
+ }
+ /*********************************************************/
+ /* Point to the next Slot */
+ /*********************************************************/
+ SlotMapPtr = (SlotMap*)((char*)SlotMapPtr+SLOT_ENTRY_SIZE);
+ SlotMapLen -= SLOT_ENTRY_SIZE;
+ }
+}
+/*****************************************************************/
+/* Parse the Mfg Area */
+/*****************************************************************/
+static void iSeries_Parse_MfgArea(u8* AreaData,int AreaLen, struct iSeries_Device_Node* DevNode) {
+ MfgArea* MfgAreaPtr = (MfgArea*)AreaData;
+ int MfgAreaLen = AreaLen;
+ u16 SlotMapFmt = 0;
+
+ /*************************************************************/
+ /* Parse Mfg Data */
+ /*************************************************************/
+ while(MfgAreaLen > 0) {
+ int MfgTagLen = MfgAreaPtr->TagLength;
+ /*******************************************************/
+ /* Frame ID (FI 4649020310 ) */
+ /*******************************************************/
+ if (MfgAreaPtr->Tag == VpdFruFrameId) { /* FI */
+ DevNode->FrameId = MfgAreaPtr->AreaData1;
+ }
+ /*******************************************************/
+ /* Slot Map Format (MF 4D46020004 ) */
+ /*******************************************************/
+ else if(MfgAreaPtr->Tag == VpdSlotMapFormat){ /* MF */
+ SlotMapFmt = (MfgAreaPtr->AreaData1*256)+(MfgAreaPtr->AreaData2);
+ }
+ /*******************************************************/
+ /* Slot Map (SM 534D90 */
+ /*******************************************************/
+ else if(MfgAreaPtr->Tag == VpdSlotMap){ /* SM */
+ SlotMap* SlotMapPtr;
+ if(SlotMapFmt == 0x1004) SlotMapPtr = (SlotMap*)((char*)MfgAreaPtr+MFG_ENTRY_SIZE+1);
+ else SlotMapPtr = (SlotMap*)((char*)MfgAreaPtr+MFG_ENTRY_SIZE);
+ iSeries_Parse_SlotArea(SlotMapPtr,MfgTagLen, DevNode);
+ }
+ /*********************************************************/
+ /* Point to the next Mfg Area */
+ /* Use defined size, sizeof give wrong answer */
+ /*********************************************************/
+ MfgAreaPtr = (MfgArea*)((char*)MfgAreaPtr + MfgTagLen + MFG_ENTRY_SIZE);
+ MfgAreaLen -= (MfgTagLen + MFG_ENTRY_SIZE);
+ }
+}
+/*****************************************************************/
+/* Look for "BUS".. Data is not Null terminated. */
+/* PHBID of 0xFF indicates PHB was not found in VPD Data. */
+/*****************************************************************/
+static int iSeries_Parse_PhbId(u8* AreaPtr,int AreaLength) {
+ u8* PhbPtr = AreaPtr;
+ int DataLen = AreaLength;
+ char PhbId = 0xFF;
+ while(DataLen > 0) {
+ if(*PhbPtr == 'B' && *(PhbPtr+1) == 'U' && *(PhbPtr+2) == 'S') {
+ PhbPtr += 3;
+ while(*PhbPtr == ' ') ++PhbPtr;
+ PhbId = (*PhbPtr & 0x0F);
+ break;
+ }
+ ++PhbPtr;
+ --DataLen;
+ }
+ return PhbId;
+}
+
+/****************************************************************/
+/* Parse out the VPD Areas */
+/****************************************************************/
+static void iSeries_Parse_Vpd(u8* VpdData, int VpdDataLen, struct iSeries_Device_Node* DevNode) {
+ u8* TagPtr = VpdData;
+ int DataLen = VpdDataLen-3;
+ /*************************************************************/
+ /* Parse the Areas */
+ /*************************************************************/
+ while(*TagPtr != VpdEndOfAreaTag && DataLen > 0) {
+ int AreaLen = *(TagPtr+1) + (*(TagPtr+2)*256);
+ u8* AreaData = TagPtr+3;
+
+ if (*TagPtr == VpdIdStringTag) {
+ DevNode->PhbId = iSeries_Parse_PhbId(AreaData,AreaLen);
+ }
+ else if(*TagPtr == VpdVendorAreaTag) {
+ iSeries_Parse_MfgArea(AreaData,AreaLen,DevNode);
+ }
+ /*********************************************************
+ * Point to next Area.
+ *********************************************************/
+ TagPtr = AreaData + AreaLen;
+ DataLen -= AreaLen;
+ }
+}
+/****************************************************************
+ * iSeries_Get_Location_Code(struct iSeries_Device_Node*) *
+ *
+ ****************************************************************/
+void iSeries_Get_Location_Code(struct iSeries_Device_Node* DevNode) {
+ int BusVpdLen = 0;
+ u8* BusVpdPtr = (u8*)kmalloc(BUS_VPDSIZE, GFP_KERNEL);
+ if(BusVpdPtr == NULL) {
+ printk("PCI: Bus VPD Buffer allocation failure.\n");
+ return;
+ }
+ BusVpdLen = HvCallPci_getBusVpd(DevNode->BusNumber,REALADDR(BusVpdPtr),BUS_VPDSIZE);
+ if(BusVpdLen == 0) {
+ kfree(BusVpdPtr);
+ printk("PCI: Bus VPD Buffer zero length.\n");
+ return;
+ }
+ //printk("PCI: BusVpdPtr: %p, %d\n",BusVpdPtr, BusVpdLen);
+ /*************************************************************/
+ /* Make sure this is what I think it is */
+ /*************************************************************/
+ if(*BusVpdPtr != VpdIdStringTag) { /*0x82 */
+ printk("PCI: Bus VPD Buffer missing starting tag.\n");
+ kfree(BusVpdPtr);
+ return;
+ }
+ /***************************************************************/
+ /***************************************************************/
+ iSeries_Parse_Vpd(BusVpdPtr,BusVpdLen, DevNode);
+ kfree(BusVpdPtr);
+}
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_dma.c linuxppc64_2_4/arch/ppc64/kernel/iSeries_dma.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_dma.c Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/iSeries_dma.c Wed Dec 31 18:00:00 1969
@@ -1,1121 +0,0 @@
-/*
- * iSeries_dma.c
- * Copyright (C) 2001 Mike Corrigan IBM Corporation
- *
- * Dynamic DMA mapping support.
- *
- * Manages the TCE space assigned to this partition
- *
- * modeled from pci-dma.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-/*#define DEBUG_TCE 1 */
-
-/*HACK HACK HACK */
-
-u8 iSeries_Get_Bus( struct pci_dev * dv )
-{
- return 0;
-}
-
-/* HACK HACK HACK */
-
-unsigned long phb_tce_table_init( void * x )
-{
- return (unsigned long)x;
-}
-
-
-struct TceTable virtBusTceTable; /* Tce table for virtual bus */
-
-struct TceTable * tceTables[256]; /* Tce tables for 256 busses
- * Bus 255 is the virtual bus
- * zero indicates no bus defined
- */
- /* allocates a contiguous range of tces (power-of-2 size) */
-static long alloc_tce_range( struct TceTable *,
- unsigned order );
- /* allocates a contiguous range of tces (power-of-2 size)
- * assumes lock already held
- */
-static long alloc_tce_range_nolock( struct TceTable *,
- unsigned order );
- /* frees a contiguous range of tces (power-of-2 size) */
-static void free_tce_range( struct TceTable *,
- long tcenum,
- unsigned order );
- /* frees a contiguous rnage of tces (power-of-2 size)
- * assumes lock already held
- */
-static void free_tce_range_nolock( struct TceTable *,
- long tcenum,
- unsigned order );
- /* allocates a range of tces and sets them to the pages */
-static dma_addr_t get_tces( struct TceTable *,
- unsigned order,
- void *page,
- unsigned numPages,
- int tceType,
- int direction );
-static void free_tces( struct TceTable *,
- dma_addr_t tce,
- unsigned order,
- unsigned numPages );
-static long test_tce_range( struct TceTable *,
- long tcenum,
- unsigned order );
-
-static unsigned fill_scatterlist_sg( struct scatterlist *sg, int nents,
- dma_addr_t dma_addr, unsigned long numTces );
-
-static unsigned long num_tces_sg( struct scatterlist *sg,
- int nents );
-
-static dma_addr_t create_tces_sg( struct TceTable *tbl,
- struct scatterlist *sg,
- int nents,
- unsigned numTces,
- int tceType,
- int direction );
-
-static unsigned __inline__ count_leading_zeros32( unsigned long x )
-{
- unsigned lz;
- asm("cntlzw %0,%1" : "=r"(lz) : "r"(x));
- return lz;
-}
-
-static void __inline__ build_tce( struct TceTable * tbl, long tcenum,
- unsigned long uaddr, int tceType, int direction )
-{
- u64 setTceRc;
- union Tce tce;
-
- tce.wholeTce = 0;
- tce.tceBits.rpn = (virt_to_absolute(uaddr)) >> PAGE_SHIFT;
- /* If for virtual bus */
- if ( tceType == TCE_VB ) {
- tce.tceBits.valid = 1;
- tce.tceBits.allIo = 1;
- if ( direction != PCI_DMA_TODEVICE )
- tce.tceBits.readWrite = 1;
- }
- /* If for PCI bus */
- else {
- tce.tceBits.readWrite = 1; // Read allowed
- if ( direction != PCI_DMA_TODEVICE )
- tce.tceBits.pciWrite = 1;
- }
- setTceRc = HvCallXm_setTce( (u64)tbl->index, (u64)tcenum, tce.wholeTce );
- if ( setTceRc ) {
- printk("build_tce: HvCallXm_setTce failed, rc=%ld, index=%ld, tcenum=%0lx, tce=%016lx\n",
- setTceRc, (u64)tbl->index, (u64)tcenum, tce.wholeTce );
- }
-
-}
-
-
-
-/* Build a TceTable structure. This contains a multi-level bit map which
- * is used to manage allocation of the tce space.
- */
-
-struct TceTable * build_tce_table( struct HvTceTableManagerCB * tceTableParms,
- struct TceTable * tbl )
-{
- unsigned long bits, bytes, totalBytes;
- unsigned long numBits[NUM_TCE_LEVELS], numBytes[NUM_TCE_LEVELS];
- unsigned i, k, m;
- unsigned char * pos, * p, b;
-
- tbl->size = tceTableParms->size;
- tbl->busNumber = tceTableParms->busNumber;
- tbl->startOffset = tceTableParms->startOffset;
- tbl->index = tceTableParms->index;
- spin_lock_init( &(tbl->lock) );
-
- tbl->mlbm.maxLevel = 0;
-
- /* Compute number of bits and bytes for each level of the
- * multi-level bit map
- */
- totalBytes = 0;
- bits = tbl->size * (PAGE_SIZE / sizeof( union Tce ));
-
- for ( i=0; imlbm.level[i].map = pos;
- tbl->mlbm.maxLevel = i;
-
- if ( numBits[i] & 1 ) {
- p = pos + numBytes[i] - 1;
- m = (( numBits[i] % 8) - 1) & 7;
- *p = 0x80 >> m;
-#ifdef DEBUG_TCE
- printk("build_tce_table: level %d last bit %x\n", i, 0x80>>m );
-#endif
- }
- }
- else
- tbl->mlbm.level[i].map = 0;
- pos += numBytes[i];
- /* see the comment up above on the totalBytes calculation
- * for why we do this. */
- pos += ((numBytes[i] + 7) / 8) * 8;
-
- tbl->mlbm.level[i].numBits = numBits[i];
- tbl->mlbm.level[i].numBytes = numBytes[i];
-
- }
-
- /* For the highest level, turn on all the bits */
-
- i = tbl->mlbm.maxLevel;
- p = tbl->mlbm.level[i].map;
- m = numBits[i];
-#ifdef DEBUG_TCE
- printk("build_tce_table: highest level (%d) has all bits set\n", i);
-#endif
- for (k=0; k= 8 ) {
- /* handle full bytes */
- *p++ = 0xff;
- m -= 8;
- }
- else {
- /* handle the last partial byte */
- b = 0x80;
- *p = 0;
- while (m) {
- *p |= b;
- b >>= 1;
- --m;
- }
- }
- }
-
- return tbl;
-
-}
-
-static long alloc_tce_range( struct TceTable *tbl, unsigned order )
-{
- long retval;
- unsigned long flags;
-
- /* Lock the tce allocation bitmap */
- spin_lock_irqsave( &(tbl->lock), flags );
-
- /* Do the actual work */
- retval = alloc_tce_range_nolock( tbl, order );
-
- /* Unlock the tce allocation bitmap */
- spin_unlock_irqrestore( &(tbl->lock), flags );
-
- return retval;
-}
-
-static long alloc_tce_range_nolock( struct TceTable *tbl, unsigned order )
-{
- unsigned long numBits, numBytes;
- unsigned long i, bit, block, mask;
- long tcenum;
- u32 * map;
-
- /* If the order (power of 2 size) requested is larger than our
- * biggest, indicate failure
- */
- if ( order > tbl->mlbm.maxLevel ) {
- printk("alloc_tce_range_nolock: invalid order requested, order = %d\n", order );
- return -1;
- }
-
- numBits = tbl->mlbm.level[order].numBits;
- numBytes = tbl->mlbm.level[order].numBytes;
- map = (u32 *)(tbl->mlbm.level[order].map);
-
- /* Initialize return value to -1 (failure) */
- tcenum = -1;
-
- /* Loop through the bytes of the bitmap */
- for (i=0; i> bit);
- *map &= mask;
- /* compute the index into our tce table for
- * the first tce in the block
- */
-#ifdef DEBUG_TCE
- printk("alloc_tce_range_nolock: allocating block %ld, (byte=%ld, bit=%ld) order %d\n", block, i, bit, order );
-#endif
- tcenum = block << order;
- break;
- }
- ++map;
- }
-
-#ifdef DEBUG_TCE
- if ( tcenum == -1 ) {
- printk("alloc_tce_range_nolock: no available blocks of order = %d\n", order );
- if ( order < tbl->mlbm.maxLevel )
- printk("alloc_tce_range_nolock: trying next bigger size\n" );
- else
- printk("alloc_tce_range_nolock: maximum size reached...failing\n");
- }
-#endif
-
- /* If no block of the requested size was found, try the next
- * size bigger. If one of those is found, return the second
- * half of the block to freespace and keep the first half
- */
- if ( ( tcenum == -1 ) && ( order < tbl->mlbm.maxLevel ) ) {
- tcenum = alloc_tce_range_nolock( tbl, order+1 );
- if ( tcenum != -1 ) {
- free_tce_range_nolock( tbl, tcenum+(1<lock), flags );
-
- /* Do the actual work */
- free_tce_range_nolock( tbl, tcenum, order );
-
- /* Unlock the tce allocation bitmap */
- spin_unlock_irqrestore( &(tbl->lock), flags );
-
-}
-
-static void free_tce_range_nolock( struct TceTable *tbl, long tcenum, unsigned order )
-{
- unsigned long block;
- unsigned byte, bit, mask, b;
- unsigned char * map, * bytep;
-
- if ( order > tbl->mlbm.maxLevel ) {
- printk("free_tce_range: order too large, order = %d, tcenum = %ld\n", order, tcenum );
- return;
- }
-
- block = tcenum >> order;
- if ( tcenum != (block << order ) ) {
- printk("free_tce_range: tcenum %lx is not on appropriate boundary for order %x\n", tcenum, order );
- return;
- }
- if ( block >= tbl->mlbm.level[order].numBits ) {
- printk("free_tce_range: tcenum %lx is outside the range of this map (order %x, numBits %lx\n", tcenum, order, tbl->mlbm.level[order].numBits );
- return;
- }
-#ifdef DEBUG_TCE
- if ( test_tce_range( tbl, tcenum, order ) ) {
- printk("free_tce_range: freeing range not completely allocated.\n");
- printk("free_tce_range: TceTable %p, tcenum %lx, order %x\n", tbl, tcenum, order );
- }
-#endif
- map = tbl->mlbm.level[order].map;
- byte = block / 8;
- bit = block % 8;
- mask = 0x80 >> bit;
- bytep = map + byte;
-#ifdef DEBUG_TCE
- printk("free_tce_range_nolock: freeing block %ld (byte=%d, bit=%d) of order %d\n",block, byte, bit, order);
- if ( *bytep & mask )
- printk("free_tce_range: already free: TceTable %p, tcenum %lx, order %x\n", tbl, tcenum, order );
-#endif
- *bytep |= mask;
-
- /* If there is a higher level in the bit map than this we may be
- * able to buddy up this block with its partner.
- * If this is the highest level we can't buddy up
- * If this level has an odd number of bits and
- * we are freeing the last block we can't buddy up
- */
- if ( ( order < tbl->mlbm.maxLevel ) &&
- ( ( 0 == ( tbl->mlbm.level[order].numBits & 1 ) ) ||
- ( block < tbl->mlbm.level[order].numBits-1 ) ) ) {
-
- /* See if we can buddy up the block we just freed */
- bit &= 6; /* get to the first of the buddy bits */
- mask = 0xc0 >> bit; /* build two bit mask */
- b = *bytep & mask; /* Get the two bits */
- if ( 0 == (b ^ mask) ) { /* If both bits are on */
- /* both of the buddy blocks are free we can combine them */
- *bytep ^= mask; /* turn off the two bits */
- block = ( byte * 8 ) + bit; /* block of first of buddies */
- tcenum = block << order;
- /* free the buddied block */
-#ifdef DEBUG_TCE
- printk("free_tce_range: buddying up block %ld and block %ld\n", block, block+1);
-#endif
- free_tce_range_nolock( tbl, tcenum, order+1 );
- }
- }
-}
-
-static long test_tce_range( struct TceTable *tbl, long tcenum, unsigned order )
-{
- unsigned long block;
- unsigned byte, bit, mask, b;
- long retval, retLeft, retRight;
- unsigned char * map;
-
- map = tbl->mlbm.level[order].map;
- block = tcenum >> order;
- byte = block / 8; /* Byte within bitmap */
- bit = block % 8; /* Bit within byte */
- mask = 0x80 >> bit;
- b = (*(map+byte) & mask ); /* 0 if block is allocated, else free */
- if ( b )
- retval = 1; /* 1 == block is free */
- else
- retval = 0; /* 0 == block is allocated */
- /* Test bits at all levels below this to ensure that all agree */
-
- if (order) {
- retLeft = test_tce_range( tbl, tcenum, order-1 );
- retRight = test_tce_range( tbl, tcenum+(1<<(order-1)), order-1 );
- if ( retLeft || retRight ) {
- retval = 2;
- }
- }
-
- /* Test bits at all levels above this to ensure that all agree */
-
- return retval;
-}
-
-static dma_addr_t get_tces( struct TceTable *tbl, unsigned order, void *page, unsigned numPages, int tceType, int direction )
-{
- long tcenum;
- unsigned long uaddr;
- unsigned i;
- dma_addr_t retTce = NO_TCE;
-
- uaddr = (unsigned long)page & PAGE_MASK;
-
- /* Allocate a range of tces */
- tcenum = alloc_tce_range( tbl, order );
- if ( tcenum != -1 ) {
- /* We got the tces we wanted */
- tcenum += tbl->startOffset; /* Offset into real TCE table */
- retTce = tcenum << PAGE_SHIFT; /* Set the return dma address */
- /* Setup a tce for each page */
- for (i=0; isize * (PAGE_SIZE / sizeof(union Tce))) - 1;
-
- tcenum = dma_addr >> PAGE_SHIFT;
- tcenum -= tbl->startOffset;
-
- if ( tcenum > maxTcenum ) {
- printk("free_tces: tcenum > maxTcenum, tcenum = %ld, maxTcenum = %ld\n",
- tcenum, maxTcenum );
- printk("free_tces: TCE Table at %16lx\n", (unsigned long)tbl );
- printk("free_tces: bus# %lu\n", (unsigned long)tbl->busNumber );
- printk("free_tces: size %lu\n", (unsigned long)tbl->size );
- printk("free_tces: startOff %lu\n", (unsigned long)tbl->startOffset );
- printk("free_tces: index %lu\n", (unsigned long)tbl->index );
- return;
- }
-
- freeTce = tcenum;
-
- for (i=0; iindex, (u64)tcenum, tce.wholeTce );
- if ( setTceRc ) {
- printk("free_tces: HvCallXm_setTce failed, rc=%ld, index=%ld, tcenum=%0lx, tce=%016lx\n",
- setTceRc, (u64)tbl->index, (u64)tcenum, tce.wholeTce );
- }
-
- ++tcenum;
- }
-
- free_tce_range( tbl, freeTce, order );
-
-}
-
-void __init create_virtual_bus_tce_table(void)
-{
- struct TceTable * t;
- struct HvTceTableManagerCB virtBusTceTableParms;
- u64 absParmsPtr;
-
- virtBusTceTableParms.busNumber = 255; /* Bus 255 is the virtual bus */
- virtBusTceTableParms.virtualBusFlag = 0xff; /* Ask for virtual bus */
-
- absParmsPtr = virt_to_absolute( (u64)&virtBusTceTableParms );
- HvCallXm_getTceTableParms( absParmsPtr );
-
- t = build_tce_table( &virtBusTceTableParms, &virtBusTceTable );
- if ( t ) {
- tceTables[255] = t;
- printk("Virtual Bus TCE table built successfully.\n");
- printk(" TCE table size = %ld entries\n",
- (unsigned long)t->size*(PAGE_SIZE/sizeof(union Tce)) );
- printk(" TCE table token = %d\n",
- (unsigned)t->index );
- printk(" TCE table start entry = 0x%lx\n",
- (unsigned long)t->startOffset );
- }
- else
- printk("Virtual Bus TCE table failed.\n");
-}
-
-void __init create_pci_bus_tce_table( unsigned busNumber )
-{
- struct TceTable * t;
- struct TceTable * newTceTable;
- struct HvTceTableManagerCB pciBusTceTableParms;
- u64 absParmsPtr;
- unsigned i;
-
- if ( busNumber > 254 ) {
- printk("PCI Bus TCE table failed.\n");
- printk(" Invalid bus number %u\n", busNumber );
- return;
- }
-
- newTceTable = kmalloc( sizeof(struct TceTable), GFP_KERNEL );
-
- pciBusTceTableParms.busNumber = busNumber;
- pciBusTceTableParms.virtualBusFlag = 0;
-
- absParmsPtr = virt_to_absolute( (u64)&pciBusTceTableParms );
- HvCallXm_getTceTableParms( absParmsPtr );
-
- /* Determine if the table identified by the index and startOffset
- * returned by the hypervisor for this bus has already been created.
- */
-
- for ( i=0; i<255; ++i ) {
- t = tceTables[i];
- if ( t ) {
- if ( ( t->index == pciBusTceTableParms.index ) &&
- ( t->startOffset == pciBusTceTableParms.startOffset ) ) {
- if ( t->size != pciBusTceTableParms.size )
- printk("PCI Bus %d Shares a TCE table with Bus %d, but sizes differ\n", busNumber, i );
- else
- printk("PCI Bus %d Shares a TCE table with Bus %d\n", busNumber, i );
- tceTables[busNumber] = t;
- break;
- }
- }
- }
-
- if ( ! tceTables[busNumber] ) {
- t = build_tce_table( &pciBusTceTableParms, newTceTable );
- if ( t ) {
- tceTables[busNumber] = t;
- printk("PCI Bus TCE table built successfully.\n");
- printk(" TCE table size = %ld entries\n",
- (unsigned long)t->size*(PAGE_SIZE/sizeof(union Tce)) );
- printk(" TCE table token = %d\n",
- (unsigned)t->index );
- printk(" TCE table start entry = 0x%lx\n",
- (unsigned long)t->startOffset );
- }
- else {
- kfree( newTceTable );
- printk("PCI Bus TCE table failed.\n");
- }
- }
-}
-
-
-/* Allocates a contiguous real buffer and creates TCEs over it.
- * Returns the virtual address of the buffer and sets dma_handle
- * to the dma address (tce) of the first page.
- */
-void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size,
- dma_addr_t *dma_handle)
-{
- struct TceTable * tbl;
- void *ret = NULL;
- unsigned order, nPages, bus;
- dma_addr_t tce;
- int tceType;
-
- size = PAGE_ALIGN(size);
- order = get_order(size);
- nPages = 1 << order;
-
- /* If no pci_dev then use virtual bus */
- if (hwdev == NULL ) {
- bus = 255;
- tceType = TCE_VB;
- }
- else {
-#ifdef CONFIG_PCI
- /* Get the iSeries bus # to use as an index
- * into the TCE table array
- */
- bus = ISERIES_GET_BUS( hwdev );
- tceType = TCE_PCI;
-#else
- BUG();
- return NULL;
-#endif /* CONFIG_PCI */
- }
-
- tbl = tceTables[bus];
- if ( tbl ) {
- /* Alloc enough pages (and possibly more) */
- ret = (void *)__get_free_pages( GFP_ATOMIC, order );
- if ( ret ) {
- /* Page allocation succeeded */
- memset(ret, 0, nPages << PAGE_SHIFT);
- /* Set up tces to cover the allocated range */
- tce = get_tces( tbl, order, ret, nPages, tceType,
- PCI_DMA_BIDIRECTIONAL );
- if ( tce == NO_TCE ) {
-/*#ifdef DEBUG_TCE */
- printk("pci_alloc_consistent: get_tces failed\n" );
-/*#endif */
- free_pages( (unsigned long)ret, order );
- ret = NULL;
- }
- else
- {
- *dma_handle = tce;
- }
- }
-/*#ifdef DEBUG_TCE */
- else
- printk("pci_alloc_consistent: __get_free_pages failed for order = %d\n", order);
-/*#endif*/
- }
-
- return ret;
-}
-
-void pci_free_consistent(struct pci_dev *hwdev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
-{
- struct TceTable * tbl;
- unsigned order, nPages, bus;
-
- size = PAGE_ALIGN(size);
- order = get_order(size);
- nPages = 1 << order;
-
- if ( order > 10 )
- printk("pci_free_consistent: order=%d, size=%ld, nPages=%d, dma_handle=%016lx, vaddr=%016lx\n",
- order, size, nPages, (unsigned long)dma_handle, (unsigned long)vaddr );
-
- /* If no pci_dev then use virtual bus */
- if (hwdev == NULL )
- bus = 255;
- else {
-#ifdef CONFIG_PCI
- /* Get the iSeries bus # to use as an index
- * into the TCE table array
- */
- bus = ISERIES_GET_BUS( hwdev );
-#else
- BUG();
- return;
-#endif /* CONFIG_PCI */
- }
-
- if ( bus > 255 ) {
- printk("pci_free_consistent: invalid bus # %d\n", bus );
- printk("pci_free_consistent: hwdev = %08lx\n", (unsigned long)hwdev );
- }
-
- tbl = tceTables[bus];
-
- if ( tbl ) {
- free_tces( tbl, dma_handle, order, nPages );
- free_pages( (unsigned long)vaddr, order );
- }
-}
-
-/* Creates TCEs for a user provided buffer. The user buffer must be
- * contiguous real kernel storage (not vmalloc). The address of the buffer
- * passed here is the kernel (virtual) address of the buffer. The buffer
- * need not be page aligned, the dma_addr_t returned will point to the same
- * byte within the page as vaddr.
- */
-dma_addr_t pci_map_single( struct pci_dev *hwdev, void *vaddr, size_t size, int direction )
-{
- struct TceTable * tbl;
- dma_addr_t dma_handle;
- unsigned long uaddr;
- unsigned order, nPages, bus;
- int tceType;
-
- if ( direction == PCI_DMA_NONE )
- BUG();
-
- dma_handle = NO_TCE;
-
- uaddr = (unsigned long)vaddr;
- nPages = PAGE_ALIGN( uaddr + size ) - ( uaddr & PAGE_MASK );
- order = get_order( nPages & PAGE_MASK );
- nPages >>= PAGE_SHIFT;
-
- /* If no pci_dev then use virtual bus */
- if (hwdev == NULL ) {
- bus = 255;
- tceType = TCE_VB;
- }
- else {
-#ifdef CONFIG_PCI
- /* Get the iSeries bus # to use as an index
- * into the TCE table array
- */
- bus = ISERIES_GET_BUS( hwdev );
- tceType = TCE_PCI;
-#else
- BUG();
- return NO_TCE;
-#endif /* CONFIG_PCI */
-
- }
-
- tbl = tceTables[bus];
-
- if ( tbl ) {
- dma_handle = get_tces( tbl, order, vaddr, nPages, tceType,
- direction );
- dma_handle |= ( uaddr & ~PAGE_MASK );
- }
-
- return dma_handle;
-}
-
-void pci_unmap_single( struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction )
-{
- struct TceTable * tbl;
- unsigned order, nPages, bus;
-
- if ( direction == PCI_DMA_NONE )
- BUG();
-
- nPages = PAGE_ALIGN( dma_handle + size ) - ( dma_handle & PAGE_MASK );
- order = get_order( nPages & PAGE_MASK );
- nPages >>= PAGE_SHIFT;
-
- if ( order > 10 )
- printk("pci_unmap_single: order=%d, size=%ld, nPages=%d, dma_handle=%016lx\n",
- order, size, nPages, (unsigned long)dma_handle );
-
- /* If no pci_dev then use virtual bus */
- if (hwdev == NULL )
- bus = 255;
- else {
-#ifdef CONFIG_PCI
- /* Get the iSeries bus # to use as an index
- * into the TCE table array
- */
- bus = ISERIES_GET_BUS( hwdev );
-#else
- BUG();
- return;
-#endif /* CONFIG_PCI */
- }
-
- if ( bus > 255 ) {
- printk("pci_unmap_single: invalid bus # %d\n", bus );
- printk("pci_unmap_single: hwdev = %08lx\n", (unsigned long)hwdev );
- }
-
- tbl = tceTables[bus];
-
- if ( tbl )
- free_tces( tbl, dma_handle, order, nPages );
-
-}
-
-/* Figure out how many TCEs are actually going to be required
- * to map this scatterlist. This code is not optimal. It
- * takes into account the case where entry n ends in the same
- * page in which entry n+1 starts. It does not handle the
- * general case of entry n ending in the same page in which
- * entry m starts.
- */
-static unsigned long num_tces_sg( struct scatterlist *sg, int nents )
-{
- unsigned long nTces, numPages, startPage, endPage, prevEndPage;
- unsigned i;
-
- prevEndPage = 0;
- nTces = 0;
-
- for (i=0; iaddress >> PAGE_SHIFT;
- endPage = ((unsigned long)sg->address + sg->length - 1) >> PAGE_SHIFT;
- numPages = endPage - startPage + 1;
- /* Simple optimization: if the previous entry ended
- * in the same page in which this entry starts
- * then we can reduce the required pages by one.
- * This matches assumptions in fill_scatterlist_sg and
- * create_tces_sg
- */
- if ( startPage == prevEndPage )
- --numPages;
- nTces += numPages;
- prevEndPage = endPage;
- sg++;
- }
- return nTces;
-}
-
-/* Fill in the dma data in the scatterlist
- * return the number of dma sg entries created
- */
-static unsigned fill_scatterlist_sg( struct scatterlist *sg, int nents,
- dma_addr_t dma_addr , unsigned long numTces)
-{
- struct scatterlist *dma_sg;
- u32 cur_start_dma;
- unsigned long cur_len_dma, cur_end_virt, uaddr;
- unsigned num_dma_ents;
-
- dma_sg = sg;
- num_dma_ents = 1;
-
- /* Process the first sg entry */
- cur_start_dma = dma_addr + ((unsigned long)sg->address & (~PAGE_MASK));
- cur_len_dma = sg->length;
- /* cur_end_virt holds the address of the byte immediately after the
- * end of the current buffer.
- */
- cur_end_virt = (unsigned long)sg->address + cur_len_dma;
- /* Later code assumes that unused sg->dma_address and sg->dma_length
- * fields will be zero. Other archs seem to assume that the user
- * (device driver) guarantees that...I don't want to depend on that
- */
- sg->dma_address = sg->dma_length = 0;
-
- /* Process the rest of the sg entries */
- while (--nents) {
- ++sg;
- /* Clear possibly unused fields. Note: sg >= dma_sg so
- * this can't be clearing a field we've already set
- */
- sg->dma_address = sg->dma_length = 0;
-
- /* Check if it is possible to make this next entry
- * contiguous (in dma space) with the previous entry.
- */
-
- /* The entries can be contiguous in dma space if
- * the previous entry ends immediately before the
- * start of the current entry (in virtual space)
- * or if the previous entry ends at a page boundary
- * and the current entry starts at a page boundary.
- */
- uaddr = (unsigned long)sg->address;
- if ( ( uaddr != cur_end_virt ) &&
- ( ( ( uaddr | cur_end_virt ) & (~PAGE_MASK) ) ||
- ( ( uaddr & PAGE_MASK ) == ( ( cur_end_virt-1 ) & PAGE_MASK ) ) ) ) {
- /* This entry can not be contiguous in dma space.
- * save the previous dma entry and start a new one
- */
- dma_sg->dma_address = cur_start_dma;
- dma_sg->dma_length = cur_len_dma;
-
- ++dma_sg;
- ++num_dma_ents;
-
- cur_start_dma += cur_len_dma-1;
- /* If the previous entry ends and this entry starts
- * in the same page then they share a tce. In that
- * case don't bump cur_start_dma to the next page
- * in dma space. This matches assumptions made in
- * num_tces_sg and create_tces_sg.
- */
- if ((uaddr & PAGE_MASK) == ((cur_end_virt-1) & PAGE_MASK))
- cur_start_dma &= PAGE_MASK;
- else
- cur_start_dma = PAGE_ALIGN(cur_start_dma+1);
- cur_start_dma += ( uaddr & (~PAGE_MASK) );
- cur_len_dma = 0;
- }
- /* Accumulate the length of this entry for the next
- * dma entry
- */
- cur_len_dma += sg->length;
- cur_end_virt = uaddr + sg->length;
- }
- /* Fill in the last dma entry */
- dma_sg->dma_address = cur_start_dma;
- dma_sg->dma_length = cur_len_dma;
-
- if ((((cur_start_dma +cur_len_dma - 1)>> PAGE_SHIFT) - (dma_addr >> PAGE_SHIFT) + 1) != numTces)
- {
- printk("fill_scatterlist_sg: numTces %ld, used tces %d\n",
- numTces,
- (unsigned)(((cur_start_dma + cur_len_dma - 1) >> PAGE_SHIFT) - (dma_addr >> PAGE_SHIFT) + 1));
- }
-
-
- return num_dma_ents;
-}
-
-/* Call the hypervisor to create the TCE entries.
- * return the number of TCEs created
- */
-static dma_addr_t create_tces_sg( struct TceTable *tbl, struct scatterlist *sg,
- int nents, unsigned numTces, int tceType, int direction )
-{
- unsigned order, i, j;
- unsigned long startPage, endPage, prevEndPage, numPages, uaddr;
- long tcenum, starttcenum;
- dma_addr_t dmaAddr;
-
- dmaAddr = NO_TCE;
-
- order = get_order( numTces << PAGE_SHIFT );
- /* allocate a block of tces */
- tcenum = alloc_tce_range( tbl, order );
- if ( tcenum != -1 ) {
- tcenum += tbl->startOffset;
- starttcenum = tcenum;
- dmaAddr = tcenum << PAGE_SHIFT;
- prevEndPage = 0;
- for (j=0; jaddress >> PAGE_SHIFT;
- endPage = ((unsigned long)sg->address + sg->length - 1) >> PAGE_SHIFT;
- numPages = endPage - startPage + 1;
-
- uaddr = (unsigned long)sg->address;
-
- /* If the previous entry ended in the same page that
- * the current page starts then they share that
- * tce and we reduce the number of tces we need
- * by one. This matches assumptions made in
- * num_tces_sg and fill_scatterlist_sg
- */
- if ( startPage == prevEndPage ) {
- --numPages;
- uaddr += PAGE_SIZE;
- }
-
- for (i=0; idma_address = pci_map_single( hwdev, sg->address,
- sg->length, direction );
- sg->dma_length = sg->length;
- return 1;
- }
-
- if ( direction == PCI_DMA_NONE )
- BUG();
-
- /* If no pci_dev then use virtual bus */
- if (hwdev == NULL ) {
- bus = 255;
- tceType = TCE_VB;
- }
- else {
-#ifdef CONFIG_PCI
- /* Get the iSeries bus # to use as an index
- * into the TCE table array
- */
- bus = ISERIES_GET_BUS( hwdev );
- tceType = TCE_PCI;
-#else
- BUG();
- return 0;
-#endif /* CONFIG_PCI */
- }
-
- tbl = tceTables[bus];
-
- if ( tbl ) {
- /* Compute the number of tces required */
- numTces = num_tces_sg( sg, nents );
- /* Create the tces and get the dma address */
- dma_handle = create_tces_sg( tbl, sg, nents, numTces,
- tceType, direction );
-
- /* Fill in the dma scatterlist */
- num_dma = fill_scatterlist_sg( sg, nents, dma_handle, numTces );
- }
-
- return num_dma;
-}
-
-void pci_unmap_sg( struct pci_dev *hwdev, struct scatterlist *sg, int nelms, int direction )
-{
- struct TceTable * tbl;
- unsigned order, numTces, bus, i;
- dma_addr_t dma_end_page, dma_start_page;
-
- if ( direction == PCI_DMA_NONE )
- BUG();
-
- dma_start_page = sg->dma_address & PAGE_MASK;
- for ( i=nelms; i>0; --i ) {
- unsigned k = i - 1;
- if ( sg[k].dma_length ) {
- dma_end_page = ( sg[k].dma_address +
- sg[k].dma_length - 1 ) & PAGE_MASK;
- break;
- }
- }
-
- numTces = ((dma_end_page - dma_start_page ) >> PAGE_SHIFT) + 1;
- order = get_order( numTces << PAGE_SHIFT );
-
- if ( order > 10 )
- printk("pci_unmap_sg: order=%d, numTces=%d, nelms=%d, dma_start_page=%016lx, dma_end_page=%016lx\n",
- order, numTces, nelms, (unsigned long)dma_start_page, (unsigned long)dma_end_page );
-
-
- /* If no pci_dev then use virtual bus */
- if (hwdev == NULL )
- bus = 255;
- else {
-#ifdef CONFIG_PCI
- /* Get the iSeries bus # to use as an index
- * into the TCE table array
- */
- bus = ISERIES_GET_BUS( hwdev );
-#else
- BUG();
- return;
-#endif /* CONFIG_PCI */
- }
-
- if ( bus > 255 ) {
- printk("pci_unmap_sg: invalid bus # %d\n", bus );
- printk("pci_unmap_sg: hwdev = %08lx\n", (unsigned long)hwdev );
- }
-
-
- tbl = tceTables[bus];
-
- if ( tbl )
- free_tces( tbl, dma_start_page, order, numTces );
-
-}
-
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_irq.c linuxppc64_2_4/arch/ppc64/kernel/iSeries_irq.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_irq.c Wed Dec 31 18:00:00 1969
+++ linuxppc64_2_4/arch/ppc64/kernel/iSeries_irq.c Wed Sep 19 20:33:58 2001
@@ -0,0 +1,251 @@
+/************************************************************************/
+/* This module supports the iSeries PCI bus interrupt handling */
+/* Copyright (C) 20yy */
+/* */
+/* This program is free software; you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation; either version 2 of the License, or */
+/* (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the: */
+/* Free Software Foundation, Inc., */
+/* 59 Temple Place, Suite 330, */
+/* Boston, MA 02111-1307 USA */
+/************************************************************************/
+/* Change Activity: */
+/* Created, December 13, 2000 by Wayne Holm */
+/* End Change Activity */
+/************************************************************************/
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+
+hw_irq_controller iSeries_IRQ_handler = {
+ "iSeries irq controller",
+ iSeries_startup_IRQ, /* startup */
+ iSeries_shutdown_IRQ, /* shutdown */
+ iSeries_enable_IRQ, /* enable */
+ iSeries_disable_IRQ, /* disable */
+ NULL, /* ack */
+ iSeries_end_IRQ, /* end */
+ NULL /* set_affinity */
+};
+
+
+struct iSeries_irqEntry {
+ u32 dsa;
+ struct iSeries_irqEntry* next;
+};
+
+struct iSeries_irqAnchor {
+ u8 valid : 1;
+ u8 reserved : 7;
+ u16 entryCount;
+ struct iSeries_irqEntry* head;
+};
+
+struct iSeries_irqAnchor iSeries_irqMap[NR_IRQS];
+
+void iSeries_init_irqMap(int irq);
+
+/* This is called by init_IRQ. set in ppc_md.init_IRQ by iSeries_setup.c */
+void __init iSeries_init_IRQ(void) {
+ int i;
+ for (i = 0; i < NR_IRQS; i++) {
+ irq_desc[i].handler = &iSeries_IRQ_handler;
+ irq_desc[i].status = 0;
+ irq_desc[i].status |= IRQ_DISABLED;
+ irq_desc[i].depth = 1;
+ iSeries_init_irqMap(i);
+ }
+ /* Register PCI event handler and open an event path */
+ PPCDBG(PPCDBG_BUSWALK,"Register PCI event handler and open an event path\n");
+ XmPciLpEvent_init();
+ return;
+}
+
+/**********************************************************************
+ * Called by iSeries_init_IRQ
+ * Prevent IRQs 0 and 255 from being used. IRQ 0 appears in
+ * uninitialized devices. IRQ 255 appears in the PCI interrupt
+ * line register if a PCI error occurs,
+ *********************************************************************/
+void __init iSeries_init_irqMap(int irq) {
+ iSeries_irqMap[irq].valid = (irq == 0 || irq == 255)? 0 : 1;
+ iSeries_irqMap[irq].entryCount = 0;
+ iSeries_irqMap[irq].head = NULL;
+}
+
+/* This is called out of iSeries_scan_slot to allocate an IRQ for an EADS slot */
+/* It calculates the irq value for the slot. */
+int __init iSeries_allocate_IRQ(HvBusNumber busNumber, HvSubBusNumber subBusNumber, HvAgentId deviceId) {
+ u8 idsel = (deviceId >> 4);
+ u8 function = deviceId & 0x0F;
+ int irq = ((((busNumber-1)*16 + (idsel-1)*8 + function)*9/8) % 254) + 1;
+ return irq;
+}
+
+/* This is called out of iSeries_scan_slot to assign the EADS slot to its IRQ number */
+int __init iSeries_assign_IRQ(int irq, HvBusNumber busNumber, HvSubBusNumber subBusNumber, HvAgentId deviceId) {
+ int rc;
+ u32 dsa = (busNumber << 16) | (subBusNumber << 8) | deviceId;
+ struct iSeries_irqEntry* newEntry;
+ unsigned long flags;
+
+ if (irq < 0 || irq >= NR_IRQS) {
+ return -1;
+ }
+ newEntry = kmalloc(sizeof(*newEntry), GFP_KERNEL);
+ if (newEntry == NULL) {
+ return -ENOMEM;
+ }
+ newEntry->dsa = dsa;
+ newEntry->next = NULL;
+ /********************************************************************
+ * Probably not necessary to lock the irq since allocation is only
+ * done during buswalk, but it should not hurt anything except a
+ * little performance to be smp safe.
+ *******************************************************************/
+ spin_lock_irqsave(&irq_desc[irq].lock, flags);
+
+ if (iSeries_irqMap[irq].valid) {
+ /* Push the new element onto the irq stack */
+ newEntry->next = iSeries_irqMap[irq].head;
+ iSeries_irqMap[irq].head = newEntry;
+ ++iSeries_irqMap[irq].entryCount;
+ rc = 0;
+ PPCDBG(PPCDBG_BUSWALK,"iSeries_assign_IRQ 0x%04X.%02X.%02X = 0x%04X\n",busNumber, subBusNumber, deviceId, irq);
+ }
+ else {
+ printk("PCI: Something is wrong with the iSeries_irqMap. \n");
+ kfree(newEntry);
+ rc = -1;
+ }
+ spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
+ return rc;
+}
+
+
+/* This is called by iSeries_activate_IRQs */
+unsigned int iSeries_startup_IRQ(unsigned int irq) {
+ struct iSeries_irqEntry* entry;
+ u32 bus, subBus, deviceId, function, mask;
+ for(entry=iSeries_irqMap[irq].head; entry!=NULL; entry=entry->next) {
+ bus = (entry->dsa >> 16) & 0xFFFF;
+ subBus = (entry->dsa >> 8) & 0xFF;
+ deviceId = entry->dsa & 0xFF;
+ function = deviceId & 0x0F;
+ /* Link the IRQ number to the bridge */
+ HvCallXm_connectBusUnit(bus, subBus, deviceId, irq);
+ /* Unmask bridge interrupts in the FISR */
+ mask = 0x01010000 << function;
+ HvCallPci_unmaskFisr(bus, subBus, deviceId, mask);
+ PPCDBG(PPCDBG_BUSWALK,"iSeries_activate_IRQ 0x%02X.%02X.%02X Irq:0x%02X\n",bus,subBus,deviceId,irq);
+ }
+ return 0;
+}
+
+/* This is called out of iSeries_fixup to activate interrupt
+ * generation for usable slots */
+void __init iSeries_activate_IRQs() {
+ int irq;
+ unsigned long flags;
+ for (irq=0; irq < NR_IRQS; irq++) {
+ spin_lock_irqsave(&irq_desc[irq].lock, flags);
+ irq_desc[irq].handler->startup(irq);
+ spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
+ }
+}
+
+/* this is not called anywhere currently */
+void iSeries_shutdown_IRQ(unsigned int irq) {
+ struct iSeries_irqEntry* entry;
+ u32 bus, subBus, deviceId, function, mask;
+
+ /* irq should be locked by the caller */
+
+ for(entry=iSeries_irqMap[irq].head; entry; entry=entry->next) {
+ bus = (entry->dsa >> 16) & 0xFFFF;
+ subBus = (entry->dsa >> 8) & 0xFF;
+ deviceId = entry->dsa & 0xFF;
+ function = deviceId & 0x0F;
+ /* Invalidate the IRQ number in the bridge */
+ HvCallXm_connectBusUnit(bus, subBus, deviceId, 0);
+ /* Mask bridge interrupts in the FISR */
+ mask = 0x01010000 << function;
+ HvCallPci_maskFisr(bus, subBus, deviceId, mask);
+ }
+
+}
+
+/***********************************************************
+ * This will be called by device drivers (via disable_IRQ)
+ * to disable INTA in the bridge interrupt status register.
+ ***********************************************************/
+void iSeries_disable_IRQ(unsigned int irq) {
+ struct iSeries_irqEntry* entry;
+ u32 bus, subBus, deviceId, mask;
+
+ /* The IRQ has already been locked by the caller */
+
+ for(entry=iSeries_irqMap[irq].head; entry; entry=entry->next) {
+ bus = (entry->dsa >> 16) & 0xFFFF;
+ subBus = (entry->dsa >> 8) & 0xFF;
+ deviceId = entry->dsa & 0xFF;
+ /* Mask secondary INTA */
+ mask = 0x80000000;
+ HvCallPci_maskInterrupts(bus, subBus, deviceId, mask);
+ PPCDBG(PPCDBG_BUSWALK,"iSeries_disable_IRQ 0x%02X.%02X.%02X 0x%04X\n",bus,subBus,deviceId,irq);
+ }
+}
+
+/***********************************************************
+ * This will be called by device drivers (via enable_IRQ)
+ * to enable INTA in the bridge interrupt status register.
+ ***********************************************************/
+void iSeries_enable_IRQ(unsigned int irq) {
+ struct iSeries_irqEntry* entry;
+ u32 bus, subBus, deviceId, mask;
+
+ /* The IRQ has already been locked by the caller */
+ for(entry=iSeries_irqMap[irq].head; entry; entry=entry->next) {
+ bus = (entry->dsa >> 16) & 0xFFFF;
+ subBus = (entry->dsa >> 8) & 0xFF;
+ deviceId = entry->dsa & 0xFF;
+ /* Unmask secondary INTA */
+ mask = 0x80000000;
+ HvCallPci_unmaskInterrupts(bus, subBus, deviceId, mask);
+ PPCDBG(PPCDBG_BUSWALK,"iSeries_enable_IRQ 0x%02X.%02X.%02X 0x%04X\n",bus,subBus,deviceId,irq);
+ }
+}
+
+/* Need to define this so ppc_irq_dispatch_handler will NOT call
+ enable_IRQ at the end of interrupt handling. However, this
+ does nothing because there is not enough information provided
+ to do the EOI HvCall. This is done by XmPciLpEvent.c */
+void iSeries_end_IRQ(unsigned int irq) {
+}
+
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_pci.c linuxppc64_2_4/arch/ppc64/kernel/iSeries_pci.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_pci.c Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/iSeries_pci.c Tue Oct 2 17:06:49 2001
@@ -27,62 +27,63 @@
#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 "iSeries_IoMmTable.h"
#include "pci.h"
extern struct pci_controller* hose_head;
extern struct pci_controller** hose_tail;
+extern int global_phb_number;
+extern int panic_timeout;
+
extern struct Naca *naca;
extern struct device_node *allnodes;
extern unsigned long phb_tce_table_init(struct pci_controller *phb);
+extern unsigned long iSeries_Base_Io_Memory;
extern struct pci_ops iSeries_pci_ops;
extern struct flightRecorder* PciFr;
-int PciTraceFlag = 0;
-
-struct pci_dev;
-
-struct i_device_node {
- struct list_head iDevice_Chain;
- char* Name;
- char* Type;
- struct pci_dev* PciDev;
- int BusNumber;
- int SubBus;
- int ReturnCode;
- int DevFn;
-};
+/*******************************************************************
+ * Counters and control flags.
+ *******************************************************************/
+extern long Pci_Io_Read_Count;
+extern long Pci_Io_Write_Count;
+extern long Pci_Cfg_Read_Count;
+extern long Pci_Cfg_Write_Count;
+extern long Pci_Error_Count;
+
+extern int Pci_Retry_Max;
+extern int Pci_Error_Flag;
+extern int Pci_Trace_Flag;
-LIST_HEAD(iDevice_List);
+extern void iSeries_MmIoTest(void);
/*******************************************************************
* Forward declares of prototypes.
*******************************************************************/
+struct iSeries_Device_Node* find_Device_Node(struct pci_dev* PciDev);
+struct iSeries_Device_Node* get_Device_Node(struct pci_dev* PciDev);
+
unsigned long find_and_init_phbs(void);
void fixup_resources(struct pci_dev *dev);
void iSeries_pcibios_fixup(void);
@@ -91,58 +92,98 @@
void iSeries_Scan_PHBs_Slots(struct pci_controller* Phb);
void iSeries_Scan_EADs_Bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel);
int iSeries_Scan_Bridge_Slot(HvBusNumber Bus, HvSubBusNumber SubBus, int MaxAgents);
+void list_device_nodes(void);
+
+struct pci_dev;
+
+LIST_HEAD(Global_Device_List);
+
+int DeviceCount = 0;
/**********************************************************************************
- *
- *
+ * Dump the iSeries Temp Device Node
+ *<4>buswalk [swapper : - DeviceNode: 0xC000000000634300
+ *<4>00. Device Node = 0xC000000000634300
+ *<4> - PciDev = 0x0000000000000000
+ *<4> - tDevice = 0x 17:01.00 0x1022 00
+ *<4> 4. Device Node = 0xC000000000634480
+ *<4> - PciDev = 0x0000000000000000
+ *<4> - Device = 0x 18:38.16 Irq:0xA7 Vendor:0x1014 Flags:0x00
+ *<4> - Devfn = 0xB0: 22.18
**********************************************************************************/
-#define ISERIES_PCI_READ_OP(size, call, type) \
-/***********************************************************************************/ \
-int iSeries_pci_read_config_##size(struct pci_dev* PciDev, int PciOffset, type ReadValue) { \
- struct i_device_node* DeviceNode = PciDev->sysdata; \
- if(DeviceNode->BusNumber == 0xFF) DeviceNode->ReturnCode = 0x301; return DeviceNode->ReturnCode; \
- DeviceNode->ReturnCode = HvCallPci_config##call(DeviceNode->BusNumber, DeviceNode->SubBus, \
- DeviceNode->DevFn, PciOffset, ReadValue); \
- if(DeviceNode->ReturnCode != 0 ) { \
- PCIFR("RC##size: %02X,%02X,%02X,%04X Rtn: %04X", \
- DeviceNode->BusNumber, DeviceNode->SubBus, DeviceNode->DevFn, PciOffset,DeviceNode->ReturnCode); \
- } \
- return DeviceNode->ReturnCode; \
-}
-/***********************************************************************************/ \
-#define ISERIES_PCI_WRITE_OP(size, call, type) \
-/***********************************************************************************/ \
-int iSeries_pci_write_config_##size(struct pci_dev* PciDev, int PciOffset, type WriteValue) { \
- struct i_device_node* DeviceNode = PciDev->sysdata; \
- DeviceNode->ReturnCode = HvCallPci_config##call(DeviceNode->BusNumber, DeviceNode->SubBus, \
- DeviceNode->DevFn, PciOffset, WriteValue); \
- if(DeviceNode->ReturnCode != 0 ) { \
- PCIFR("RC##size: %02X,%02X,%02X,%04X Rtn: %04X", \
- DeviceNode->BusNumber, DeviceNode->SubBus, DeviceNode->DevFn, PciOffset,DeviceNode->ReturnCode); \
- } \
- return DeviceNode->ReturnCode; \
-}
-
- ISERIES_PCI_READ_OP( byte, Load8, u8*)
- ISERIES_PCI_READ_OP( word, Load16, u16*)
- ISERIES_PCI_READ_OP( dword,Load32, u32*)
- ISERIES_PCI_WRITE_OP(byte, Store8, u8)
- ISERIES_PCI_WRITE_OP(word, Store16,u16)
- ISERIES_PCI_WRITE_OP(dword,Store32,u32)
-
-/************************************************************************/
-/* Branch Table */
-/************************************************************************/
-struct pci_ops iSeries_pci_ops = {
- iSeries_pci_read_config_byte,
- iSeries_pci_read_config_word,
- iSeries_pci_read_config_dword,
- iSeries_pci_write_config_byte,
- iSeries_pci_write_config_word,
- iSeries_pci_write_config_dword
-};
+void dumpDevice_Node(struct iSeries_Device_Node* DeviceNode) {
+ udbg_printf("Device Node = 0x%016LX\n",DeviceNode);
+ udbg_printf(" - PciDev = 0x%016LX\n",DeviceNode->PciDev);
+ udbg_printf(" - Device = 0x%4X:%02X.%02X (0x%02X)\n",
+ DeviceNode->BusNumber,
+ DeviceNode->SubBus,
+ DeviceNode->AgentId,
+ DeviceNode->DevFn);
+ udbg_printf(" = Irq:0x%02X Vendor:0x%04X Flags:0x%02X\n",
+ DeviceNode->Irq,
+ DeviceNode->Vendor,
+ DeviceNode->Flags );
+ udbg_printf(" - Location = %s\n",DeviceNode->CardLocation);
+}
+/**********************************************************************************
+ * Walk down the device node chain
+ **********************************************************************************/
+void list_device_nodes(void) {
+ struct list_head* Device_Node_Ptr = Global_Device_List.next;
+ while(Device_Node_Ptr != &Global_Device_List) {
+ dumpDevice_Node( (struct iSeries_Device_Node*)Device_Node_Ptr );
+ Device_Node_Ptr = Device_Node_Ptr->next;
+ }
+}
+/***********************************************************************
+ * build_device_node(u16 Bus, int SubBus, u8 DevFn)
+ *
+ ***********************************************************************/
+struct iSeries_Device_Node* build_device_node(HvBusNumber Bus, HvSubBusNumber SubBus, int AgentId, int Func) {
+ struct iSeries_Device_Node* DeviceNode;
+
+ PPCDBG(PPCDBG_BUSWALK,"- "__FUNCTION__" 0x%02X.%02X.%02X Func: %02X\n",Bus,SubBus,AgentId, Func);
+
+
+ DeviceNode = kmalloc(sizeof(struct iSeries_Device_Node), GFP_KERNEL);
+ if(DeviceNode == NULL) return NULL;
+
+ memset(DeviceNode,0,sizeof(struct iSeries_Device_Node) );
+ list_add_tail(&DeviceNode->Device_List,&Global_Device_List);
+ DeviceNode->DsaAddr = ((u64)Bus<<48)+((u64)SubBus<<40)+((u64)0x10<<32);
+ DeviceNode->BusNumber = Bus;
+ DeviceNode->SubBus = SubBus;
+ DeviceNode->AgentId = AgentId;
+ DeviceNode->DevFn = (0x80 | ((AgentId & 0x07) << 3) | (Func & 0x03));
+ DeviceNode->IoRetry = 0;
+ iSeries_Get_Location_Code(DeviceNode);
+ return DeviceNode;
+}
+/****************************************************************************
+*
+* Allocate pci_controller(phb) initialized common variables.
+*
+*****************************************************************************/
+struct pci_controller* pci_alloc_pci_controllerX(char *model, enum phb_types controller_type)
+{
+ struct pci_controller *hose;
+ hose = (struct pci_controller*)kmalloc(sizeof(struct pci_controller), GFP_KERNEL);
+ if(hose == NULL) return NULL;
+
+ memset(hose, 0, sizeof(struct pci_controller));
+ if(strlen(model) < 8) strcpy(hose->what,model);
+ else memcpy(hose->what,model,7);
+ hose->type = controller_type;
+ hose->global_number = global_phb_number;
+ global_phb_number++;
+
+ *hose_tail = hose;
+ hose_tail = &hose->next;
+ return hose;
+}
+
/****************************************************************************
*
* unsigned int __init find_and_init_phbs(void)
@@ -154,57 +195,33 @@
* owned or fully owned by this guest partition.
****************************************************************************/
unsigned long __init find_and_init_phbs(void) {
- struct pci_controller* hose;
- HvBusNumber BusNumber;
- int LxBusNumber = 0; /* Linux Bus number for grins */
+ struct pci_controller* phb;
+ HvBusNumber BusNumber;
PPCDBG(PPCDBG_BUSWALK,__FUNCTION__" Entry\n");
- /* Check to make sure the device probing will work on this iSeries Release. */
- if(hvReleaseData.xVrmIndex !=3) {
- printk("PCI: iSeries Lpar and Linux native PCI I/O code is incompatible.\n");
- printk("PCI: A newer version of the Linux kernel is need for this iSeries release.\n");
- return -1;
- }
- /* Check all possible buses. */
- for (BusNumber = 0; BusNumber < 256; BusNumber++) {
+ /* Check all possible buses. */
+ for (BusNumber = 0; BusNumber < 256; BusNumber++) {
int RtnCode = HvCallXm_testBus(BusNumber);
if (RtnCode == 0) {
- PPCDBG(PPCDBG_BUSWALK, "Create iSeries PHB controller: %04X\n",BusNumber);
- PCIFR("Create iSeries PHB controller: %04X",BusNumber);
-
- PPCDBG(PPCDBG_BUSWALK, "PCI: Allocate pci_controller for PBH HV\n");
- hose = (struct pci_controller *)kmalloc(sizeof(struct pci_controller),GFP_KERNEL);
- if(hose == NULL) {
+ phb = pci_alloc_pci_controllerX("PHB HV", phb_type_hypervisor);
+ if(phb == NULL) {
printk("PCI: Allocate pci_controller failed.\n");
- PCIFR( "PCI: Allocate pci_controller failed.\n");
- return -1;
+ PCIFR( "Allocate pci_controller failed.");
+ return -1;
}
- memset(hose, 0, sizeof(struct pci_controller));
- *hose_tail = hose;
- hose_tail = &hose->next;
- strcpy(hose->what,"PHB HV");
- hose->type = phb_type_hypervisor;
- hose->global_number = BusNumber;
- *hose_tail = hose;
- hose_tail = &hose->next;
-
- hose->local_number = BusNumber; /* Stuff HV bus number away. */
- hose->first_busno = LxBusNumber;/* This just for debug. pcibios will */
- hose->last_busno = 0xff; /* assign the bus numbers later. */
- hose->ops = &iSeries_pci_ops; /* Cnfg Reg Ops routines. */
- LxBusNumber += 1; /* Keep track for debug. */
-
- /*********************/
- /* TCE Table for Bus */
- /*********************/
- //create_pci_bus_tce_table(BusNumber);
-
- /*************************************************************************
- * Find and connect the devices.
- *************************************************************************/
- iSeries_Scan_PHBs_Slots(hose);
+ phb->pci_mem_offset = phb->local_number = BusNumber;
+ phb->first_busno = BusNumber;
+ phb->last_busno = BusNumber;
+ phb->ops = &iSeries_pci_ops;
+
+ PPCDBG(PPCDBG_BUSWALK, "Create iSeries pci_controller(%p), Bus: %04X\n",phb,BusNumber);
+ PCIFR("Create iSeries PHB controller: %04X",BusNumber);
+ /***************************************************/
+ /* Find and connect the devices. */
+ /***************************************************/
+ iSeries_Scan_PHBs_Slots(phb);
}
}
return 0;
@@ -214,29 +231,87 @@
*
* Chance to initialize and structures or variable before PCI Bus walk.
*
+ *<4>buswalk [swapper : iSeries_pcibios_init Entry.
+ *<4>buswalk [swapper : IoMmTable Initialized 0xC00000000034BD30
+ *<4>buswalk [swapper : find_and_init_phbs Entry
+ *<4>buswalk [swapper : Create iSeries pci_controller:(0xC00000001F5C7000), Bus 0x0017
+ *<4>buswalk [swapper : Connect EADs: 0x17.00.12 = 0x00
+ *<4>buswalk [swapper : iSeries_assign_IRQ 0x0017.00.12 = 0x0091
+ *<4>buswalk [swapper : - allocate and assign IRQ 0x17.00.12 = 0x91
+ *<4>buswalk [swapper : - FoundDevice: 0x17.28.10 = 0x12AE
+ *<4>buswalk [swapper : - build_device_node 0x17.28.12
+ *<4>buswalk [swapper : iSeries_pcibios_init Exit.
***********************************************************************/
void iSeries_pcibios_init(void) {
+ struct pci_controller *phb;
PPCDBG(PPCDBG_BUSWALK,__FUNCTION__" Entry.\n");
- /* find_and_init_phbs(); comment out until debugged. */
+
+ iSeries_IoMmTable_Initialize();
+
+ find_and_init_phbs();
+
+ /* Create the TCE Tables */
+ phb = hose_head;
+ while(phb != NULL) {
+ create_pci_bus_tce_table(phb->local_number);
+ phb = phb->next;
+ }
+ pci_assign_all_busses = 0;
PPCDBG(PPCDBG_BUSWALK,__FUNCTION__" Exit.\n");
}
/***********************************************************************
* iSeries_pcibios_fixup(void)
- *
- *
- *
***********************************************************************/
void __init iSeries_pcibios_fixup(void) {
- struct pci_dev *dev;
+ struct pci_dev* PciDev;
+ struct iSeries_Device_Node* DeviceNode;
+ char Buffer[256];
+ int DeviceCount = 0;
+
PPCDBG(PPCDBG_BUSWALK,__FUNCTION__" Entry.\n");
- return; /* Just return until debugged. */
- pci_assign_all_busses = 0;
+ /******************************************************/
+ /* Fix up at the device node and pci_dev relationship */
+ /******************************************************/
+ pci_for_each_dev(PciDev) {
+ DeviceNode = find_Device_Node(PciDev);
+ if(DeviceNode != NULL) {
+ ++DeviceCount;
+ PciDev->sysdata = (void*)DeviceNode;
+ DeviceNode->PciDev = PciDev;
+
+ PPCDBG(PPCDBG_BUSWALK,"PciDev 0x%p <==> DevNode 0x%p\n",PciDev,DeviceNode );
+
+ iSeries_allocateDeviceBars(PciDev);
+
+ PPCDBGCALL(PPCDBG_BUSWALK,dumpPci_Dev(PciDev) );
- pci_for_each_dev(dev) {
- PPCDBGCALL(PPCDBG_BUSWALK, dumpPci_Dev(dev) );
+ iSeries_Device_Information(PciDev,Buffer, sizeof(Buffer) );
+ printk("%d. %s\n",DeviceCount,Buffer);
+
+ } else {
+ printk("PCI: Device Tree not found for 0x%016lX\n",(unsigned long)PciDev);
+ }
}
+ iSeries_IoMmTable_Status();
+
+ iSeries_activate_IRQs();
+
+ // This is test code.
+ // mf_displaySrc(0xC9000100);
+ // Pci_CfgIoTest();
+ // mf_displaySrc(0xC9000500);
+ // Pci_MMIoTest();
+ // mf_displaySrc(0xC9000999);
+}
+/***********************************************************************
+ * iSeries_pcibios_fixup_bus(int Bus)
+ *
+ ***********************************************************************/
+void iSeries_pcibios_fixup_bus(struct pci_bus* PciBus) {
+ PPCDBG(PPCDBG_BUSWALK,__FUNCTION__"(0x%04X) Entry.\n",PciBus->number);
+
}
/***********************************************************************
* find_floppy(void)
@@ -247,8 +322,8 @@
* Note: On iSeries there will only be a virtual diskette.
***********************************************************************/
struct pci_dev*
-find_floppy() {
- PPCDBG(PPCDBG_BUSWALK,"\tFind Floppy pci_dev.. None on iSeries.\n");
+find_floppy(void) {
+ PPCDBG(PPCDBG_BUSWALK,"- Find Floppy pci_dev.. None on iSeries.\n");
return NULL;
}
@@ -256,57 +331,14 @@
/***********************************************************************
* fixup_resources(struct pci_dev *dev)
*
- *
- *
- *
***********************************************************************/
-void
-fixup_resources(struct pci_dev *dev) {
- struct pci_controller* phb = (struct pci_controller *)dev->sysdata;
-
- PPCDBG(PPCDBG_BUSWALK, "fixup_resources:\n");
- PPCDBG(PPCDBG_BUSWALK, "\tphb = 0x%016LX\n", phb);
- PPCDBG(PPCDBG_BUSWALK, "\tphb->local_number = 0x%004X \n", phb->local_number);
+void fixup_resources(struct pci_dev *PciDev) {
+ PPCDBG(PPCDBG_BUSWALK,__FUNCTION__" PciDev %p\n",PciDev);
}
-/***********************************************************************
- * build_device_node(u16 Bus, int SubBus, u8 DevFn)
- *
- *
- * char* loc-code
- * int vendor-id
- * int device-id..
- * int BusNumber
- * int SubBus
- * int ReturnCode
- *
- * int regs
- * int interrupts
- * char* loc-code
- ***********************************************************************/
-void
-build_device_node(HvBusNumber BusNumber, HvSubBusNumber SubBus, u8 DevFn) {\
- struct i_device_node* iDevice = kmalloc(sizeof(struct i_device_node), GFP_KERNEL);
- list_add_tail(&iDevice->iDevice_Chain,&iDevice_List);
-
-
-
-}
-
-void list_device_nodes(void) {
- struct list_head* iDevice_Node_Ptr = iDevice_List.next;
- int index = 1;
- PPCDBG(PPCDBG_BUSWALK,__FUNCTION__" Entry\n");
- while(iDevice_Node_Ptr != &iDevice_List) {
- iDevice_Node_Ptr = iDevice_Node_Ptr->next;
- ++index;
- }
-}
-
-
/********************************************************************************
-* Loop through each node function to find usable bridges.
+* Loop through each node function to find usable EADs bridges.
*********************************************************************************/
void iSeries_Scan_PHBs_Slots(struct pci_controller* Phb) {
struct HvCallPci_DeviceInfo* DevInfo;
@@ -316,8 +348,6 @@
int IdSel = 1;
int MaxAgents = 8;
- PPCDBG(PPCDBG_BUSWALK,__FUNCTION__" Entry\n");
-
DevInfo = (struct HvCallPci_DeviceInfo*)kmalloc(sizeof(struct HvCallPci_DeviceInfo), GFP_KERNEL);
if(DevInfo == NULL) return;
@@ -327,18 +357,15 @@
for (IdSel=1; IdSel < MaxAgents; ++IdSel) {
HvRc = HvCallPci_getDeviceInfo(Bus, SubBus, IdSel,REALADDR(DevInfo), sizeof(struct HvCallPci_DeviceInfo));
if (HvRc == 0) {
- PPCDBG(PPCDBG_BUSWALK,"\tFound Device 0x%02X\n",DevInfo->deviceType);
if(DevInfo->deviceType == HvCallPci_NodeDevice) {
- PPCDBG(PPCDBG_BUSWALK,"\tFound EADs Bridge(NodeDevice)\n");
iSeries_Scan_EADs_Bridge(Bus, SubBus, IdSel);
}
else {
- printk("PCI: Invalid System Configuration. \n");
+ printk("PCI: Invalid System Configuration(0x%02X.\n",DevInfo->deviceType);
}
}
}
kfree(DevInfo);
- PPCDBG(PPCDBG_BUSWALK,__FUNCTION__" Exit\n");
}
@@ -351,8 +378,6 @@
int Function;
int HvRc;
- PPCDBG(PPCDBG_BUSWALK,__FUNCTION__" Entry\n");
-
BridgeInfo = (struct HvCallPci_BridgeInfo*)kmalloc(sizeof(struct HvCallPci_BridgeInfo), GFP_KERNEL);
if(BridgeInfo == NULL) return;
@@ -363,41 +388,46 @@
AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
HvRc = HvCallXm_connectBusUnit(Bus, SubBus, AgentId, 0);
if (HvRc == 0) {
+ /* Connect EADs: 0x18.00.12 = 0x00 */
PPCDBG(PPCDBG_BUSWALK,"Connect EADs: 0x%02X.%02X.%02X = 0x%02X\n",Bus, SubBus, AgentId);
HvRc = HvCallPci_getBusUnitInfo(Bus, SubBus, AgentId,
REALADDR(BridgeInfo), sizeof(struct HvCallPci_BridgeInfo));
if (HvRc == 0) {
- PPCDBG(PPCDBG_BUSWALK,"\tBridgeInfo..: 0x%02X.%02X.%02X = 0x%02X\n",Bus, SubBus, AgentId,
- BridgeInfo->busUnitInfo.deviceType);
-
if (BridgeInfo->busUnitInfo.deviceType == HvCallPci_BridgeDevice) {
- PPCDBG(PPCDBG_BUSWALK,"\tScan_Bridge_Slot...: 0x%02X.%02X.%02X\n",Bus, SubBus, AgentId);
- iSeries_Scan_Bridge_Slot(Bus, BridgeInfo->subBusNumber,BridgeInfo->maxAgents);
+ /* Scan_Bridge_Slot...: 0x18.00.12 */
+ iSeries_Scan_Bridge_Slot(Bus,BridgeInfo->subBusNumber,BridgeInfo->maxAgents);
}
+ else {
+ printk("PCI: Invalid Bridge Configuration(0x%02X)\n",BridgeInfo->busUnitInfo.deviceType);
+ }
}
}
}
kfree(BridgeInfo);
- PPCDBG(PPCDBG_BUSWALK,__FUNCTION__" Exit\n");
}
/********************************************************************************
*
* This assumes that the node slot is always on the primary bus!
+*
*********************************************************************************/
int iSeries_Scan_Bridge_Slot(HvBusNumber Bus, HvSubBusNumber SubBus, int MaxAgents) {
+ struct iSeries_Device_Node* DeviceNode;
u16 VendorId = 0;
int HvRc = 0;
int Irq = 0;
int IdSel = ISERIES_GET_DEVICE_FROM_SUBBUS(SubBus);
int Function = ISERIES_GET_FUNCTION_FROM_SUBBUS(SubBus);
HvAgentId AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
- int ValidSlots = 0;
+ HvAgentId EADsIdSel = ISERIES_PCI_AGENTID(IdSel, Function);
+ int FirstSlotId= 0;
- PPCDBG(PPCDBG_BUSWALK,__FUNCTION__" Entry\n");
-
+ /**********************************************************/
+ /* iSeries_allocate_IRQ.: 0x18.00.12(0xA3) */
+ /**********************************************************/
Irq = iSeries_allocate_IRQ(Bus, 0, AgentId);
- PPCDBG(PPCDBG_BUSWALK,"\tiSeries_allocate_IRQ.: 0x%02X.%02X.%02X(0x%02X)\n", Bus, SubBus, AgentId, Irq);
+ iSeries_assign_IRQ(Irq, Bus, 0, AgentId);
+ PPCDBG(PPCDBG_BUSWALK,"- allocate and assign IRQ 0x%02X.%02X.%02X = 0x%02X\n",Bus, 0, AgentId, Irq );
/****************************************************************************
* Connect all functions of any device found.
@@ -405,27 +435,465 @@
for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) {
for (Function = 0; Function < 8; ++Function) {
AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
- HvRc = HvCallXm_connectBusUnit(Bus, SubBus, AgentId, Irq);
- if (HvRc == 0) {
- PPCDBG(PPCDBG_BUSWALK,"\tConnect....: 0x%02X.%02X.%02X Irq: 0x%02X\n",Bus, SubBus, AgentId, Irq);
- HvRc = HvCallPci_configLoad16(Bus, SubBus, AgentId, PCI_VENDOR_ID, &VendorId);
- if (HvRc == 0) {
- PPCDBG(PPCDBG_BUSWALK,"\tVendorId...: 0x%02X.%02X.%02X = 0x%04X\n",Bus, SubBus, AgentId, VendorId);
- ++ValidSlots;
+ if( HvCallXm_connectBusUnit(Bus, SubBus, AgentId, Irq) == 0) {
+ if( HvCallPci_configLoad16(Bus, SubBus, AgentId, PCI_VENDOR_ID, &VendorId) == 0) {
+ /**********************************************************/
+ /* FoundDevice: 0x18.28.10 = 0x12AE */
+ /**********************************************************/
+ HvCallPci_configStore8(Bus, SubBus, AgentId, PCI_INTERRUPT_LINE, Irq);
+ PPCDBG(PPCDBG_BUSWALK,"- FoundDevice: 0x%02X.%02X.%02X = 0x%04X\n",
+ Bus, SubBus, AgentId, VendorId);
+ ++DeviceCount;
+ PCIFR("Device(%4d): 0x%02X.%02X.%02X",DeviceCount,Bus, SubBus, AgentId);
+ DeviceNode = build_device_node(Bus, SubBus, EADsIdSel, Function);
+ DeviceNode->Vendor = VendorId;
+ DeviceNode->Irq = Irq;
+
+ /***********************************************************
+ * On the first device/function, assign irq to slot
+ ***********************************************************/
+ if(Function == 0) {
+ FirstSlotId = AgentId;
+ // AHT iSeries_assign_IRQ(Irq, Bus, SubBus, AgentId);
+ //iSeries_assign_IRQ(Irq, Bus, 0, AgentId);
+ }
}
}
- if (HvRc != 0) {
- PPCDBG(PPCDBG_BUSWALK,"\tConnect/Read Vendor failed: 0x%02X.%02X.%02X = 0x%02X\n",Bus, SubBus, AgentId, HvRc);
- }
- }
- /****************************************************************************
- * If a device is found, assign irq to slot
- ****************************************************************************/
- if (ValidSlots > 0) {
- PPCDBG(PPCDBG_BUSWALK,"\tiSeries_assign_IRQ 0x%02X.%02X.%02X = 0x%02X\n",Bus, SubBus, AgentId, Irq );
- iSeries_assign_IRQ(Irq, Bus, SubBus, AgentId);
}
}
- PPCDBG(PPCDBG_BUSWALK,__FUNCTION__" Exit\n");
return HvRc;
+}
+/************************************************************************/
+/* I/0 Memory copy MUST use mmio commands on iSeries */
+/* To do; For performance, include the hv call directly */
+/************************************************************************/
+void* iSeries_memset(void* dest, char c, size_t Count) {
+ u8 ByteValue = c;
+ long NumberOfBytes = Count;
+ char* IoBuffer = dest;
+ while(NumberOfBytes > 0) {
+ iSeries_Write_Byte( ByteValue, (void*)IoBuffer );
+ ++IoBuffer;
+ -- NumberOfBytes;
+ }
+ return dest;
+}
+void* iSeries_memcpy_toio(void *dest, void *source, size_t count) {
+ char *dst = dest;
+ char *src = source;
+ long NumberOfBytes = count;
+ while(NumberOfBytes > 0) {
+ iSeries_Write_Byte(*src++, (void*)dst++);
+ -- NumberOfBytes;
+ }
+ return dest;
+}
+void* iSeries_memcpy_fromio(void *dest, void *source, size_t count) {
+ char *dst = dest;
+ char *src = source;
+ long NumberOfBytes = count;
+ while(NumberOfBytes > 0) {
+ *dst++ = iSeries_Read_Byte( (void*)src++);
+ -- NumberOfBytes;
+ }
+ return dest;
+}
+/**********************************************************************************
+ * Look down the chain to find the matching Device Device
+ **********************************************************************************/
+struct iSeries_Device_Node* find_Device_Node(struct pci_dev* PciDev) {
+ struct list_head* Device_Node_Ptr = Global_Device_List.next;
+ int Bus = PciDev->bus->number;
+ int DevFn = PciDev->devfn;
+
+ while(Device_Node_Ptr != &Global_Device_List) {
+ struct iSeries_Device_Node* DevNode = (struct iSeries_Device_Node*)Device_Node_Ptr;
+ if(Bus == DevNode->BusNumber && DevFn == DevNode->DevFn) {
+ return DevNode;
+ }
+ Device_Node_Ptr = Device_Node_Ptr->next;
+ }
+ return NULL;
+}
+
+/**********************************************************************************
+ * Function to check if the Device Node is really the device node for the device.
+ * check to see if the Node passed is a pci_dev or device_node.
+ **********************************************************************************/
+struct iSeries_Device_Node* check_Device_Node(struct iSeries_Device_Node* Node) {
+ /* NULL Pointers */
+ if(Node->PciDev == NULL || (struct pci_dev*)Node->PciDev->sysdata == NULL) {
+ return find_Device_Node((struct pci_dev*)Node );
+ }
+ /* Does pci_dev point back to node. */
+ else if(Node == Node->PciDev->sysdata) {
+ return Node;
+ }
+ /* Else go searching. */
+ else {
+ return find_Device_Node((struct pci_dev*)Node);
+ }
+}
+/******************************************************************/
+/* Returns the device node for the passed pci_dev */
+/* Sanity Check Node PciDev to passed pci_dev */
+/* If none is found, returns a NULL which the client must handle. */
+/******************************************************************/
+struct iSeries_Device_Node* get_Device_Node(struct pci_dev* PciDev) {
+ struct iSeries_Device_Node* Node;
+ Node = (struct iSeries_Device_Node*)PciDev->sysdata;
+ if(Node == NULL ) {
+ Node = find_Device_Node(PciDev);
+ }
+ else if(Node->PciDev != PciDev) {
+ Node = find_Device_Node(PciDev);
+ }
+ return Node;
+}
+/**********************************************************************************
+ *
+ * Read PCI Config Space Code
+ *
+ **********************************************************************************/
+/** BYTE ****************************************************************************************/
+int iSeries_Node_read_config_byte(struct iSeries_Device_Node* DevNode, int Offset, u8* ReadValue) {
+ u8 ReadData;
+ if(DevNode == NULL) { return 0x301; }
+ ++Pci_Cfg_Read_Count;
+ DevNode->ReturnCode = HvCallPci_configLoad8(DevNode->BusNumber,DevNode->SubBus,0x10,
+ Offset,&ReadData);
+ if(Pci_Trace_Flag == 1) {
+ printk("RCB: 0x%02X.%02X 0x%04X = 0x%02X\n",DevNode->BusNumber,DevNode->DevFn,Offset,ReadData);
+ }
+ if(DevNode->ReturnCode != 0 ) {
+ printk("PCI: RCB(%016lX) Error: 0x%04X\n",DevNode->DsaAddr,DevNode->ReturnCode);
+ PCIFR( "RCB(%016lX) Error: 0x%04X", DevNode->DsaAddr,DevNode->ReturnCode);
+ }
+ *ReadValue = ReadData;
+ return DevNode->ReturnCode;
+}
+/** WORD ****************************************************************************************/
+int iSeries_Node_read_config_word(struct iSeries_Device_Node* DevNode, int Offset, u16* ReadValue) {
+ u16 ReadData;
+ if(DevNode == NULL) { return 0x301; }
+ ++Pci_Cfg_Read_Count;
+ DevNode->ReturnCode = HvCallPci_configLoad16(DevNode->BusNumber,DevNode->SubBus,0x10,
+ Offset,&ReadData);
+ if(Pci_Trace_Flag == 1) {
+ printk("RCW: 0x%02X.%02X 0x%04X = 0x%04X\n",DevNode->BusNumber,DevNode->DevFn,Offset,ReadData);
+ }
+ if(DevNode->ReturnCode != 0 ) {
+ printk("PCI: RCW(%016lX) Error: 0x%04X\n",DevNode->DsaAddr,DevNode->ReturnCode);
+ PCIFR( "RCW(%016lX) Error: 0x%04X", DevNode->DsaAddr,DevNode->ReturnCode);
+ }
+ *ReadValue = ReadData;
+ return DevNode->ReturnCode;
+}
+/** DWORD ****************************************************************************************/
+int iSeries_Node_read_config_dword(struct iSeries_Device_Node* DevNode, int Offset, u32* ReadValue) { u32 ReadData;
+ if(DevNode == NULL) { return 0x301; }
+ ++Pci_Cfg_Read_Count;
+ DevNode->ReturnCode = HvCallPci_configLoad32(DevNode->BusNumber,DevNode->SubBus,0x10,
+ Offset,&ReadData);
+ if(Pci_Trace_Flag == 1) {
+ printk("RCL: 0x%02X.%02X 0x%04X = 0x%08X\n",DevNode->BusNumber,DevNode->DevFn,Offset,ReadData);
+ }
+ if(DevNode->ReturnCode != 0 ) {
+ printk("PCI: RCL(%016lX) Error: 0x%04X\n",DevNode->DsaAddr,DevNode->ReturnCode);
+ PCIFR( "RCL(%016lX) Error: 0x%04X", DevNode->DsaAddr,DevNode->ReturnCode);
+ }
+ *ReadValue = ReadData;
+ return DevNode->ReturnCode;
+}
+int iSeries_pci_read_config_byte(struct pci_dev* PciDev, int Offset, u8* ReadValue) {
+ struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
+ if(DevNode == NULL) return 0x0301;
+ return iSeries_Node_read_config_byte( DevNode ,Offset,ReadValue);
+}
+int iSeries_pci_read_config_word(struct pci_dev* PciDev, int Offset, u16* ReadValue) {
+ struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
+ if(DevNode == NULL) return 0x0301;
+ return iSeries_Node_read_config_word( DevNode ,Offset,ReadValue );
+}
+int iSeries_pci_read_config_dword(struct pci_dev* PciDev, int Offset, u32* ReadValue) {
+ struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
+ if(DevNode == NULL) return 0x0301;
+ return iSeries_Node_read_config_dword(DevNode ,Offset,ReadValue );
+}
+/**********************************************************************************
+ *
+ * Write PCI Config Space Code
+ *
+ **********************************************************************************/
+/** BYTE ****************************************************************************************/
+int iSeries_Node_write_config_byte(struct iSeries_Device_Node* DevNode, int Offset, u8 WriteData) {
+ ++Pci_Cfg_Write_Count;
+ DevNode->ReturnCode = HvCallPci_configStore8(DevNode->BusNumber,DevNode->SubBus,0x10,
+ Offset,WriteData);
+ if(Pci_Trace_Flag == 1) {
+ printk("WCB: 0x%02X.%02X 0x%04X = 0x%02X\n",DevNode->BusNumber,DevNode->DevFn,Offset,WriteData);
+ }
+ if(DevNode->ReturnCode != 0 ) {
+ printk("PCI: WCB(%016lX) Error: 0x%04X\n",DevNode->DsaAddr,DevNode->ReturnCode);
+ PCIFR( "WCB(%016lX) Error: 0x%04X", DevNode->DsaAddr,DevNode->ReturnCode);
+ }
+ return DevNode->ReturnCode;
+}
+/** WORD ****************************************************************************************/
+int iSeries_Node_write_config_word(struct iSeries_Device_Node* DevNode, int Offset, u16 WriteData) {
+ ++Pci_Cfg_Write_Count;
+ DevNode->ReturnCode = HvCallPci_configStore16(DevNode->BusNumber,DevNode->SubBus,0x10,
+ Offset,WriteData);
+ if(Pci_Trace_Flag == 1) {
+ printk("WCW: 0x%02X.%02X 0x%04X = 0x%04X\n",DevNode->BusNumber,DevNode->DevFn,Offset,WriteData);
+ }
+ if(DevNode->ReturnCode != 0 ) {
+ printk("PCI: WCW(%016lX) Error: 0x%04X\n",DevNode->DsaAddr,DevNode->ReturnCode);
+ PCIFR( "WCW(%016lX) Error: 0x%04X", DevNode->DsaAddr,DevNode->ReturnCode);
+ }
+ return DevNode->ReturnCode;
+}
+/** DWORD ****************************************************************************************/
+int iSeries_Node_write_config_dword(struct iSeries_Device_Node* DevNode, int Offset, u32 WriteData) {
+ ++Pci_Cfg_Write_Count;
+ DevNode->ReturnCode = HvCallPci_configStore32(DevNode->BusNumber,DevNode->SubBus,0x10,
+ Offset,WriteData);
+ if(Pci_Trace_Flag == 1) {
+ printk("WCL: 0x%02X.%02X 0x%04X = 0x%08X\n",DevNode->BusNumber,DevNode->DevFn,Offset,WriteData);
+ }
+ if(DevNode->ReturnCode != 0 ) {
+ printk("PCI: WCL(%016lX) Error: 0x%04X\n",DevNode->DsaAddr,DevNode->ReturnCode);
+ PCIFR( "WCL(%016lX) Error: 0x%04X",DevNode->DsaAddr,DevNode->ReturnCode);
+ }
+ return DevNode->ReturnCode;
+}
+int iSeries_pci_write_config_byte( struct pci_dev* PciDev,int Offset, u8 WriteValue) {
+ struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
+ if(DevNode == NULL) return 0x0301;
+ return iSeries_Node_write_config_byte( DevNode,Offset,WriteValue);
+}
+int iSeries_pci_write_config_word( struct pci_dev* PciDev,int Offset,u16 WriteValue) {
+ struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
+ if(DevNode == NULL) return 0x0301;
+ return iSeries_Node_write_config_word( DevNode,Offset,WriteValue);
+}
+int iSeries_pci_write_config_dword(struct pci_dev* PciDev,int Offset,u32 WriteValue) {
+ struct iSeries_Device_Node* DevNode = get_Device_Node(PciDev);
+ if(DevNode == NULL) return 0x0301;
+ return iSeries_Node_write_config_dword(DevNode,Offset,WriteValue);
+}
+
+/************************************************************************/
+/* Branch Table */
+/************************************************************************/
+struct pci_ops iSeries_pci_ops = {
+ iSeries_pci_read_config_byte,
+ iSeries_pci_read_config_word,
+ iSeries_pci_read_config_dword,
+ iSeries_pci_write_config_byte,
+ iSeries_pci_write_config_word,
+ iSeries_pci_write_config_dword
+};
+
+/************************************************************************
+ * Check Return Code
+ * -> On Failure, print and log information.
+ * Increment Retry Count, if exceeds max, panic partition.
+ * -> If in retry, print and log success
+ ************************************************************************
+ * PCI: Device 23.90 ReadL I/O Error( 0): 0x1234
+ * PCI: Device 23.90 ReadL Retry( 1)
+ * PCI: Device 23.90 ReadL Retry Successful(1)
+ ************************************************************************/
+int CheckReturnCode(char* TextHdr, struct iSeries_Device_Node* DevNode) {
+ ++Pci_Error_Count;
+ if(DevNode->ReturnCode != 0) {
+ PCIFR( "Device 0x%04X:%02X :%s: I/O Error(%2d): 0x%04X",
+ DevNode->BusNumber, DevNode->DevFn,TextHdr,DevNode->IoRetry,DevNode->ReturnCode);
+ printk("Device 0x%04X:%02X :%s: I/O Error(%2d): 0x%04X\n",
+ DevNode->BusNumber, DevNode->DevFn,TextHdr,DevNode->IoRetry,DevNode->ReturnCode);
+ /*******************************************************/
+ /* Bump the retry and check for retry count exceeded. */
+ /* If, Exceeded, panic the system. */
+ /*******************************************************/
+ ++DevNode->IoRetry;
+ if(DevNode->IoRetry > Pci_Retry_Max && Pci_Error_Flag > 1 ) {
+ mf_displaySrc(0xB6000103);
+ panic_timeout = 0;
+ panic("PCI: Hardware I/O Error, SRC B6000103, Automatic Reboot Disabled.\n");
+ }
+ }
+ /********************************************************************
+ * If retry was in progress, log success and rest retry count *
+ *********************************************************************/
+ else if(DevNode->IoRetry > 0) {
+ DevNode->IoRetry = 0;
+ PCIFR("Device 0x%04X:%02X %s Retry Successful(%2d).",DevNode->BusNumber, DevNode->DevFn,
+ TextHdr, DevNode->IoRetry);
+ }
+ return DevNode->ReturnCode;
+}
+
+/************************************************************************/
+/* Read MM I/O Instructions for the iSeries */
+/* On MM I/O error, all ones are returned and iSeries_pci_IoError is cal*/
+/* else, data is returned in big Endian format. */
+/************************************************************************/
+/* iSeries_Read_Byte = Read Byte ( 8 bit) */
+/* iSeries_Read_Word = Read Word (16 bit) */
+/* iSeries_Read_Long = Read Long (32 bit) */
+/************************************************************************/
+u8 iSeries_Read_Byte(void* IoAddress) {
+ u8 IoData, Data;
+ struct iSeries_Device_Node* DevNode = check_Device_Node(iSeries_xlateIoMmAddress(IoAddress) );
+ int BarNumber = iSeries_IoMmTable_Bar(IoAddress);
+ int BarOffset = iSeries_IoMmTable_BarOffset(IoAddress);
+ if(DevNode != 0) {
+ ++Pci_Io_Read_Count;
+ DevNode->ReturnCode = HvCallPci_barLoad8(DevNode->BusNumber,DevNode->SubBus,0x10,
+ BarNumber,BarOffset,&IoData);
+ Data = IoData;
+ if(Pci_Trace_Flag == 1) {
+ printk("RDB: IoAddress 0x%016lX = 0x%02X\n",(unsigned long)IoAddress, Data);
+ printk("RDB: 0x%02X.%02X Bar: 0x%02X/0x%04X\n",
+ DevNode->BusNumber,DevNode->SubBus,BarNumber,BarOffset);
+ }
+ if(DevNode->ReturnCode != 0) {
+ CheckReturnCode("RDB",DevNode);
+ printk("RDB: %s Error: 0x%04X\n",DevNode->PciDev->slot_name,DevNode->ReturnCode);
+ }
+ }
+ return Data;
+}
+
+u16 iSeries_Read_Word(void* IoAddress) {
+ struct iSeries_Device_Node* DevNode = check_Device_Node(iSeries_xlateIoMmAddress(IoAddress) );
+ int BarNumber = iSeries_IoMmTable_Bar(IoAddress);
+ int BarOffset = iSeries_IoMmTable_BarOffset(IoAddress);
+ u16 IoData, Data;
+
+ if(DevNode != 0) {
+ ++Pci_Io_Read_Count;
+ DevNode->ReturnCode = HvCallPci_barLoad16(DevNode->BusNumber,DevNode->SubBus,0x10,
+ BarNumber,BarOffset,&IoData);
+ Data = swab16(IoData);
+
+ if(Pci_Trace_Flag == 1) {
+ printk("RDW: IoAddress 0x%016lX = 0x%04X\n",(unsigned long)IoAddress, Data);
+ printk("RDW: 0x%02X.%02X Bar: 0x%02X/0x%04X\n",
+ DevNode->BusNumber,DevNode->SubBus,BarNumber,BarOffset);
+ }
+ if(DevNode->ReturnCode != 0) {
+ CheckReturnCode("RDW",DevNode);
+ printk("RDW: %s Error: 0x%04X\n",DevNode->PciDev->slot_name,DevNode->ReturnCode);
+ }
+ }
+ return Data;
+}
+u32 iSeries_Read_Long(void* IoAddress) {
+ struct iSeries_Device_Node* DevNode = check_Device_Node(iSeries_xlateIoMmAddress(IoAddress) );
+ int BarNumber = iSeries_IoMmTable_Bar(IoAddress);
+ int BarOffset = iSeries_IoMmTable_BarOffset(IoAddress);
+ u32 IoData, Data;
+
+ if(DevNode != 0) {
+ ++Pci_Io_Read_Count;
+ DevNode->ReturnCode = HvCallPci_barLoad32(DevNode->BusNumber,DevNode->SubBus,0x10,
+ BarNumber,BarOffset,&IoData);
+ Data = swab32(IoData);
+
+ if(Pci_Trace_Flag == 1) {
+ printk("RDL: IoAddress 0x%016lX = 0x%08X\n",(unsigned long)IoAddress, Data);
+ printk("RDL: 0x%02X.%02X Bar: 0x%02X/0x%04X\n",
+ DevNode->BusNumber,DevNode->SubBus,BarNumber,BarOffset);
+ }
+ if(DevNode->ReturnCode != 0) {
+ CheckReturnCode("RDL",DevNode);
+ printk("RDL: %s Error: 0x%04X\n",DevNode->PciDev->slot_name,DevNode->ReturnCode);
+ }
+ }
+ return Data;
+}
+/************************************************************************/
+/* Write MM I/O Instructions for the iSeries */
+/************************************************************************/
+/* iSeries_Write_Byte = Write Byte (8 bit) */
+/* iSeries_Write_Word = Write Word(16 bit) */
+/* iSeries_Write_Long = Write Long(32 bit) */
+/************************************************************************/
+void iSeries_Write_Byte(u8 Data, void* IoAddress) {
+ struct iSeries_Device_Node* DevNode = check_Device_Node(iSeries_xlateIoMmAddress(IoAddress) );
+ int BarNumber = iSeries_IoMmTable_Bar(IoAddress);
+ int BarOffset = iSeries_IoMmTable_BarOffset(IoAddress);
+ u8 IoData = Data;
+
+ if(DevNode != 0 && BarNumber != -1) {
+ ++Pci_Io_Write_Count;
+ DevNode->ReturnCode = HvCallPci_barStore8 (DevNode->BusNumber,DevNode->SubBus,0x10,
+ BarNumber,BarOffset,IoData);
+ if(Pci_Trace_Flag == 1) {
+ printk("WWB: IoAddress 0x%016lX = 0x%02X\n",(unsigned long)IoAddress,Data);
+ printk("WWB: 0x%02X.%02X Bar: 0x%02X/0x%04X\n",
+ DevNode->BusNumber,DevNode->SubBus,BarNumber,BarOffset);
+ }
+ if(DevNode->ReturnCode != 0) {
+ CheckReturnCode("WWB",DevNode);
+ printk("WWB: %s Error: 0x%04X\n",DevNode->PciDev->slot_name,DevNode->ReturnCode);
+ }
+ }
+}
+void iSeries_Write_Word(u16 Data, void* IoAddress) {
+ struct iSeries_Device_Node* DevNode = check_Device_Node(iSeries_xlateIoMmAddress(IoAddress) );
+ int BarNumber = iSeries_IoMmTable_Bar(IoAddress);
+ int BarOffset = iSeries_IoMmTable_BarOffset(IoAddress);
+ u16 IoData = swab16(Data);
+
+ if(DevNode != 0 ) {
+ ++Pci_Io_Write_Count;
+ DevNode->ReturnCode = HvCallPci_barStore16(DevNode->BusNumber,DevNode->SubBus,0x10,
+ BarNumber,BarOffset,IoData);
+ if(Pci_Trace_Flag == 1) {
+ printk("WWW: IoAddress 0x%016lX = 0x%04X\n",(unsigned long)IoAddress,Data);
+ printk("WWW: 0x%02X.%02X Bar: 0x%02X/0x%04X\n",
+ DevNode->BusNumber,DevNode->SubBus,BarNumber,BarOffset);
+ }
+ if(DevNode->ReturnCode != 0) {
+ CheckReturnCode("WWW",DevNode);
+ printk("WWW: %s Error: 0x%04X\n",DevNode->PciDev->slot_name,DevNode->ReturnCode);
+ }
+ }
+}
+void iSeries_Write_Long(u32 Data, void* IoAddress) {
+ struct iSeries_Device_Node* DevNode = check_Device_Node(iSeries_xlateIoMmAddress(IoAddress) );
+ int BarNumber = iSeries_IoMmTable_Bar(IoAddress);
+ int BarOffset = iSeries_IoMmTable_BarOffset(IoAddress);
+ u32 IoData = swab32(Data);
+
+ if(DevNode != 0 && BarNumber != -1) {
+ ++Pci_Io_Write_Count;
+ DevNode->ReturnCode = HvCallPci_barStore32(DevNode->BusNumber,DevNode->SubBus,0x10,
+ BarNumber,BarOffset,IoData);
+ if(Pci_Trace_Flag == 1) {
+ printk("WWL: IoAddress 0x%016lX = 0x%08X\n",(unsigned long)IoAddress, Data);
+ printk("WWL: 0x%02X.%02X Bar: 0x%02X/0x%04X\n",
+ DevNode->BusNumber,DevNode->SubBus,BarNumber,BarOffset);
+ }
+ if(DevNode->ReturnCode != 0) {
+ CheckReturnCode("WWL",DevNode);
+ printk("WWL: %s Error: 0x%04X\n",DevNode->PciDev->slot_name,DevNode->ReturnCode);
+ }
+ }
+}
+/*
+ * This is called very early before the page table is setup.
+ * There are warnings here because of type mismatches.. Okay for now. AHT
+ */
+void
+iSeries_pcibios_init_early(void) {
+ ppc_md.pcibios_read_config_byte = iSeries_Node_read_config_byte;
+ ppc_md.pcibios_read_config_word = iSeries_Node_read_config_word;
+ ppc_md.pcibios_read_config_dword = iSeries_Node_read_config_dword;
+ ppc_md.pcibios_write_config_byte = iSeries_Node_write_config_byte;
+ ppc_md.pcibios_write_config_word = iSeries_Node_write_config_word;
+ ppc_md.pcibios_write_config_dword = iSeries_Node_write_config_dword;
}
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_pci_reset.c linuxppc64_2_4/arch/ppc64/kernel/iSeries_pci_reset.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_pci_reset.c Wed Dec 31 18:00:00 1969
+++ linuxppc64_2_4/arch/ppc64/kernel/iSeries_pci_reset.c Thu Sep 20 19:46:15 2001
@@ -0,0 +1,147 @@
+/************************************************************************/
+/* File iSeries_pci_reset.c created by Allan Trautman on Mar 21 2001. */
+/************************************************************************/
+/* This code supports the pci interface on the IBM iSeries systems. */
+/* Copyright (C) 20yy */
+/* */
+/* This program is free software; you can redistribute it and/or modify */
+/* it under the terms of the GNU General Public License as published by */
+/* the Free Software Foundation; either version 2 of the License, or */
+/* (at your option) any later version. */
+/* */
+/* This program is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
+/* GNU General Public License for more details. */
+/* */
+/* You should have received a copy of the GNU General Public License */
+/* along with this program; if not, write to the: */
+/* Free Software Foundation, Inc., */
+/* 59 Temple Place, Suite 330, */
+/* Boston, MA 02111-1307 USA */
+/************************************************************************/
+/* Change Activity: */
+/* Created, March 20, 2001 */
+/* April 30, 2001, Added return codes on functions. */
+/* September 10, 2001, Ported to ppc64. */
+/* End Change Activity */
+/************************************************************************/
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include "pci.h"
+
+/************************************************************************/
+/* Interface to toggle the reset line */
+/* Time is in .1 seconds, need for seconds. */
+/************************************************************************/
+int iSeries_Device_ToggleReset(struct pci_dev* PciDev, int AssertTime, int DelayTime) {
+ unsigned long AssertDelay, WaitDelay;
+ struct iSeries_Device_Node* DeviceNode = (struct iSeries_Device_Node*)PciDev->sysdata;
+ if(DeviceNode == NULL) {
+ printk("PCI: Pci Reset Failed, Device Node not found for pci_dev %p\n",PciDev);
+ return -1;
+ }
+ /********************************************************************
+ * Set defaults, Assert is .5 second, Wait is 3 seconds.
+ ********************************************************************/
+ if(AssertTime == 0) AssertDelay = ( 5 * HZ)/10;
+ else AssertDelay = (AssertTime*HZ)/10;
+ if(WaitDelay == 0) WaitDelay = (30 * HZ)/10;
+ else WaitDelay = (DelayTime* HZ)/10;
+
+ /********************************************************************
+ * Assert reset
+ ********************************************************************/
+ DeviceNode->ReturnCode = HvCallPci_setSlotReset(DeviceNode->BusNumber, 0x00, DeviceNode->AgentId, 1);
+ if(DeviceNode->ReturnCode == 0) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(AssertDelay); /* Sleep for the time */
+ DeviceNode->ReturnCode = HvCallPci_setSlotReset(DeviceNode->BusNumber, 0x00, DeviceNode->AgentId, 0);
+
+ /***************************************************************
+ * Wait for device to reset
+ ***************************************************************/
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(WaitDelay);
+ }
+ if(DeviceNode->ReturnCode == 0) {
+ PCIFR("Slot 0x%04X.%02 Reset\n",DeviceNode->BusNumber,DeviceNode->AgentId );
+ }
+ else {
+ printk("PCI: Slot 0x%04X.%02X Reset Failed, RCode: %04X\n",DeviceNode->BusNumber,DeviceNode->AgentId,DeviceNode->ReturnCode);
+ PCIFR( "Slot 0x%04X.%02X Reset Failed, RCode: %04X\n",DeviceNode->BusNumber,DeviceNode->AgentId,DeviceNode->ReturnCode);
+ }
+ return DeviceNode->ReturnCode;
+}
+
+/************************************************************************
+ * Saves the config registers for a device. *
+ ************************************************************************
+ * Note: This does byte reads so the data may appear byte swapped, *
+ * The data returned in the pci_config_reg_save_area structure to be *
+ * used to the restore of the data. If the save failed, the data *
+ * data will not be restore. Yes I know, you are most likey toast. *
+ ************************************************************************/
+int pci_save_config_regs(struct pci_dev* PciDev,struct pci_config_reg_save_area* SaveArea){
+ memset(SaveArea,0x00,sizeof(struct pci_config_reg_save_area) );
+ SaveArea->PciDev = PciDev;
+ SaveArea->RCode = 0;
+ SaveArea->Register = 0;
+ /******************************************************************
+ * Save All the Regs, NOTE: restore skips the first 16 bytes. *
+ ******************************************************************/
+ while(SaveArea->Register < REG_SAVE_SIZE && SaveArea->RCode == 0) {
+ SaveArea->RCode = pci_read_config_byte(PciDev, SaveArea->Register, &SaveArea->Regs[SaveArea->Register]);
+ ++SaveArea->Register;
+ }
+ if(SaveArea->RCode != 0) { /* Ouch */
+ SaveArea->Flags = 0x80;
+ printk("PCI: pci_restore_save_regs failed! %p\n 0x%04X",PciDev,SaveArea->RCode);
+ PCIFR( "pci_restore_save_regs failed! %p\n 0x%04X",PciDev,SaveArea->RCode);
+ }
+ else {
+ SaveArea->Flags = 0x01;
+ }
+ return SaveArea->RCode;
+}
+/************************************************************************
+ * Restores the registers saved via the save function. See the save *
+ * function for details. *
+ ************************************************************************/
+int pci_restore_config_regs(struct pci_dev* PciDev,struct pci_config_reg_save_area* SaveArea) {
+ if(SaveArea->PciDev != PciDev || SaveArea->Flags == 0x80 || SaveArea->RCode != 0) {
+ printk("PCI: pci_restore_config_regs failed! %p\n",PciDev);
+ return -1;
+ }
+ /******************************************************************
+ * Don't touch the Cmd or BIST regs, user must restore those. *
+ * Restore PCI_VENDOR_ID & PCI_DEVICE_ID *
+ * Restore PCI_CACHE_LINE_SIZE & PCI_LATENCY_TIMER *
+ * Restore Saved Regs from 0x10 to 0x3F *
+ ******************************************************************/
+ SaveArea->Register = 0;
+ while(SaveArea->Register < REG_SAVE_SIZE && SaveArea->RCode == 0) {
+ SaveArea->RCode = pci_write_config_byte(PciDev,SaveArea->Register,SaveArea->Regs[SaveArea->Register]);
+ ++SaveArea->Register;
+ if( SaveArea->Register == PCI_COMMAND) SaveArea->Register = PCI_CACHE_LINE_SIZE;
+ else if(SaveArea->Register == PCI_HEADER_TYPE) SaveArea->Register = PCI_BASE_ADDRESS_0;
+ }
+ if(SaveArea->RCode != 0) {
+ printk("PCI: pci_restore_config_regs failed! %p\n 0x%04X",PciDev,SaveArea->RCode);
+ PCIFR( "pci_restore_config_regs failed! %p\n 0x%04X",PciDev,SaveArea->RCode);
+ }
+ return SaveArea->RCode;
+}
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_setup.c linuxppc64_2_4/arch/ppc64/kernel/iSeries_setup.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_setup.c Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/iSeries_setup.c Fri Oct 12 14:16:21 2001
@@ -48,17 +48,21 @@
#include
#include
#include
-#include
/* Function Prototypes */
extern void abort(void);
+#ifdef CONFIG_PPC_ISERIES
static void build_iSeries_Memory_Map( void );
static void setup_iSeries_cache_sizes( void );
static void iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr);
+#endif
void build_valid_hpte( unsigned long vsid, unsigned long ea, unsigned long pa,
pte_t * ptep, unsigned hpteflags, unsigned bolted );
extern void ppcdbg_initialize(void);
+extern void iSeries_pcibios_init(void);
+extern void iSeries_pcibios_fixup(void);
+extern void iSeries_pcibios_fixup_bus(int);
/* Global Variables */
@@ -77,6 +81,9 @@
extern struct Naca *naca;
extern int rd_size; /* Defined in drivers/block/rd.c */
extern unsigned long klimit;
+extern unsigned long embedded_sysmap_start;
+extern unsigned long embedded_sysmap_end;
+static int mf_initialized = 0;
/*
* void __init iSeries_init_early()
@@ -85,7 +92,7 @@
void __init
iSeries_init_early(void)
{
-
+#ifdef CONFIG_PPC_ISERIES
ppcdbg_initialize();
#if defined(CONFIG_BLK_DEV_INITRD)
@@ -107,32 +114,27 @@
#endif /* CONFIG_BLK_DEV_INITRD */
{
- ROOT_DEV = MKDEV( VIODASD_MAJOR, 1 );
+ /* ROOT_DEV = MKDEV( VIODASD_MAJOR, 1 ); */
}
- /* Initialize the table which translate Linux physical addresses to
- * AS/400 absolute addresses
- */
-
- build_iSeries_Memory_Map();
-
- setup_iSeries_cache_sizes();
-
- /* Initialize machine-dependency vectors */
-
ppc_md.setup_arch = iSeries_setup_arch;
ppc_md.setup_residual = iSeries_setup_residual;
ppc_md.get_cpuinfo = iSeries_get_cpuinfo;
ppc_md.irq_cannonicalize = NULL;
ppc_md.init_IRQ = iSeries_init_IRQ;
+ ppc_md.init_ras_IRQ = NULL;
ppc_md.get_irq = iSeries_get_irq;
ppc_md.init = NULL;
+ ppc_md.pcibios_fixup = iSeries_pcibios_fixup;
+ ppc_md.pcibios_fixup_bus = iSeries_pcibios_fixup_bus;
+
ppc_md.restart = iSeries_restart;
ppc_md.power_off = iSeries_power_off;
ppc_md.halt = iSeries_halt;
ppc_md.time_init = NULL;
+ ppc_md.get_boot_time = iSeries_get_boot_time;
ppc_md.set_rtc_time = iSeries_set_rtc_time;
ppc_md.get_rtc_time = iSeries_get_rtc_time;
ppc_md.calibrate_decr = iSeries_calibrate_decr;
@@ -149,11 +151,27 @@
ppc_md.ppc_kbd_sysrq_xlate = NULL;
#endif
- if ( itLpNaca.xPirEnvironMode == 0 )
- piranha_simulator = 1;
+ htpe_init_iSeries();
+ tce_init_iSeries();
+
+ /* Initialize the table which translate Linux physical addresses to
+ * AS/400 absolute addresses
+ */
+
+ build_iSeries_Memory_Map();
+
+ setup_iSeries_cache_sizes();
+
+ /* Initialize machine-dependency vectors */
- return;
+#ifdef CONFIG_SMP
+ smp_init_iSeries();
+#endif
+
+ if ( itLpNaca.xPirEnvironMode == 0 )
+ piranha_simulator = 1;
+#endif
}
/*
@@ -188,15 +206,13 @@
iSeries_proc_early_init();
mf_init();
+ mf_initialized = 1;
+ mb();
iSeries_proc_callback( &pmc_proc_init );
-
- viopath_init();
-
- return;
}
-
+#ifdef CONFIG_PPC_ISERIES
/*
* The iSeries may have very large memories ( > 128 GB ) and a partition
* may get memory in "chunks" that may be anywhere in the 2**52 real
@@ -364,6 +380,10 @@
lmb_add( 0, naca->physicalMemorySize );
lmb_reserve( 0, __pa(klimit));
+ /*
+ * Hardcode to GP size. I am not sure where to get this info. DRENG
+ */
+ naca->slb_size = 64;
}
/*
@@ -421,6 +441,7 @@
}
}
}
+#endif /* CONFIG_PPC_ISERIES */
/*
* Document me.
@@ -514,77 +535,6 @@
return (len);
}
-#ifdef CONFIG_SMP
-void iSeries_spin_lock(spinlock_t *lock)
-{
- int i;
- for (;;) {
- for (i=1024; i>0; --i) {
- HMT_low();
- if ( lock->lock == 0 ) {
- HMT_medium();
- if ( __spin_trylock(lock) )
- return;
- }
- }
- HMT_medium();
- HvCallCfg_getLps();
- }
-}
-
-void iSeries_read_lock(__rwlock_t *rw)
-{
- int i;
- for (;;) {
- for (i=1024; i>0; --i) {
- HMT_low();
- if ( rw->lock >= 0 ) {
- HMT_medium();
- if ( __read_trylock(rw) )
- return;
- }
- }
- HMT_medium();
- HvCallCfg_getLps();
- }
-}
-
-void iSeries_write_lock(__rwlock_t *rw)
-{
- int i;
- for (;;) {
- for (i=1024; i>0; --i) {
- HMT_low();
- if ( rw->lock == 0 ) {
- HMT_medium();
- if ( __write_trylock(rw) )
- return;
- }
- }
- HMT_medium();
- HvCallCfg_getLps();
- }
-}
-
-void iSeries_brlock_spin( spinlock_t *lock )
-{
- int i;
- for(;;) {
- for (i=1024; i>0; --i) {
- HMT_low();
- if (lock->lock == 0) {
- HMT_medium();
- return;
- }
-
- }
- HMT_medium();
- HvCallCfg_getLps();
- }
-}
-
-#endif /* CONFIG_SMP */
-
int iSeries_get_cpuinfo(char *buffer)
{
int len = 0;
@@ -594,46 +544,6 @@
return len;
}
-static char * lpEventTypes[9]= {
-/* 0123456789012345678901234567890 */
- "Hypervisor\t\t",
- "Machine Facilities\t",
- "Session Manager\t\t",
- "SPD I/O\t\t\t",
- "Virtual Bus\t\t",
- "PCI I/O\t\t\t",
- "RIO I/O\t\t\t",
- "Virtual Lan\t\t",
- "Virtual I/O\t\t"
- };
-
-int get_ioevent_data(char *buffer)
-{
- int len = 0;
- unsigned i;
-
- len += sprintf(len+buffer,"LpEventQueue 0\n");
- len += sprintf(len+buffer," events processed:\t%lu\n",
- (unsigned long)xItLpQueue.xLpIntCount );
- /* display event counts by type */
- for (i=0; ixRamDisk)
+ klimit = KERNELBASE + (u64)naca->xRamDisk + (naca->xRamDiskSize * PAGE_SIZE);
+ else
+ { /* No ram disk was included - check and see if there was an embedded system map */
+ /* Change klimit to take into account any embedded system map */
+ if (embedded_sysmap_end)
+ klimit = KERNELBASE + ((embedded_sysmap_end+4095) & 0xfffffffffffff000);
+ }
}
+
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_setup.h linuxppc64_2_4/arch/ppc64/kernel/iSeries_setup.h
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/iSeries_setup.h Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/iSeries_setup.h Fri Sep 21 14:15:05 2001
@@ -19,11 +19,6 @@
#ifndef __ISERIES_SETUP_H__
#define __ISERIES_SETUP_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
extern void iSeries_init_early(void);
extern void iSeries_init(unsigned long r3,
unsigned long ird_start,
@@ -39,14 +34,10 @@
extern void iSeries_power_off(void);
extern void iSeries_halt(void);
extern void iSeries_time_init(void);
+extern void iSeries_get_boot_time(struct rtc_time *tm);
extern int iSeries_set_rtc_time(unsigned long now);
extern unsigned long iSeries_get_rtc_time(void);
extern void iSeries_calibrate_decr(void);
extern void iSeries_progress( char *, unsigned short );
-
-
-#ifdef __cplusplus
-}
-#endif
#endif /* __ISERIES_SETUP_H__ */
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/idle.c linuxppc64_2_4/arch/ppc64/kernel/idle.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/idle.c Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/idle.c Tue Oct 9 12:48:01 2001
@@ -51,16 +51,12 @@
CTRL &= ~RUNLATCH;
mtspr(CTRLT, CTRL);
- HMT_low();
-
paca = (struct Paca *)mfspr(SPRG3);
HvCall_setEnabledInterrupts( HvCall_MaskIPI |
HvCall_MaskLpEvent |
HvCall_MaskLpProd |
HvCall_MaskTimeout );
- __cli();
- __sti();
tb = get_tb();
/* Compute future tb value when yield should expire */
HvCall_yieldProcessor( HvCall_YieldTimed, tb+tb_ticks_per_jiffy );
@@ -71,58 +67,53 @@
if ( yieldTime < minYieldTime )
minYieldTime = yieldTime;
-
- /*
- * disable/enable will force any pending interrupts
- * to be seen.
- */
- __cli();
- /*
- * The decrementer stops during the yield. Just force
- * a fake decrementer now and the timer interrupt code
- * will straighten it all out. We have to do this
- * while disabled so we don't do it between where it is
- * checked and where it is reset.
+
+ /* The decrementer stops during the yield. Force a fake decrementer
+ * here and let the timer_interrupt code sort out the actual time.
*/
-
paca->xLpPaca.xIntDword.xFields.xDecrInt = 1;
- __sti();
+ process_iSeries_events();
}
int idled(void)
{
struct Paca *paca;
long oldval;
+ struct task_struct *current_local = current;
/* endless loop with no priority at all */
- current->nice = 20;
- current->counter = -100;
+ current_local->nice = 20;
+ current_local->counter = -100;
init_idle();
paca = (struct Paca *)mfspr(SPRG3);
for (;;) {
-
+#ifdef CONFIG_PPC_ISERIES
if ( paca->xLpPaca.xSharedProc ) {
- if ( !current->need_resched )
+ if ( ItLpQueue_isLpIntPending( paca->lpQueuePtr ) )
+ process_iSeries_events();
+ if ( !current_local->need_resched )
yield_shared_processor();
}
- else {
+ else
+#endif
+ {
/* Avoid an IPI by setting need_resched */
- oldval = xchg(¤t->need_resched, -1);
+ oldval = xchg(¤t_local->need_resched, -1);
if (!oldval) {
- while(current->need_resched == -1) {
+ while(current_local->need_resched == -1) {
#ifdef CONFIG_PPC_ISERIES
HMT_medium();
if ( ItLpQueue_isLpIntPending( paca->lpQueuePtr ) )
process_iSeries_events();
- HMT_low();
#endif
+ HMT_low();
}
}
}
- if (current->need_resched) {
- HMT_medium();
+ HMT_medium();
+ if (current_local->need_resched) {
schedule();
check_pgt_cache();
}
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/ioctl32.c linuxppc64_2_4/arch/ppc64/kernel/ioctl32.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/ioctl32.c Tue Oct 16 16:54:40 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/ioctl32.c Mon Oct 15 08:21:47 2001
@@ -63,9 +63,6 @@
#include
#include
#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
-/* Ugh. This header really is not clean */
-#define min min
-#define max max
#include
#endif /* LVM */
@@ -79,6 +76,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -94,6 +92,14 @@
#include
#include
#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
#include
/* Use this to get at 32-bit user passed pointers.
@@ -592,6 +598,44 @@
return err;
}
+static int mii_ioctl(unsigned long fd, unsigned int cmd, unsigned long arg)
+{
+ struct ifreq ifr;
+ mm_segment_t old_fs;
+ int err;
+ u32 data;
+
+ if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
+ return -EFAULT;
+ ifr.ifr_data = (__kernel_caddr_t) kmalloc(sizeof(struct mii_ioctl_data),
+ GFP_KERNEL);
+ if (!ifr.ifr_data)
+ return -EAGAIN;
+
+ __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
+ if (copy_from_user(ifr.ifr_data, (char *)A(data),
+ sizeof(struct mii_ioctl_data))) {
+ err = -EFAULT;
+ goto out;
+ }
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_ioctl(fd, cmd, (unsigned long)&ifr);
+ set_fs(old_fs);
+
+ if (!err) {
+ if (copy_to_user((char *)A(data),
+ ifr.ifr_data,
+ sizeof(struct mii_ioctl_data)))
+ err = -EFAULT;
+ }
+
+out:
+ kfree(ifr.ifr_data);
+ return err;
+}
+
static int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long arg)
{
struct ifreq ifr;
@@ -613,6 +657,12 @@
case SIOCGPPPSTATS:
case SIOCGPPPCSTATS:
case SIOCGPPPVER:
+ if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
+ return -EFAULT;
+ ifr.ifr_data = (__kernel_caddr_t)get_free_page(GFP_KERNEL);
+ if (!ifr.ifr_data)
+ return -EAGAIN;
+ break;
default:
if (copy_from_user(&ifr, (struct ifreq32 *)arg, sizeof(struct ifreq32)))
return -EFAULT;
@@ -641,6 +691,24 @@
case SIOCGPPPSTATS:
case SIOCGPPPCSTATS:
case SIOCGPPPVER:
+ {
+ u32 data;
+ int len;
+
+ __get_user(data, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_data));
+ if(cmd == SIOCGPPPVER)
+ len = strlen((char *)ifr.ifr_data) + 1;
+ else if(cmd == SIOCGPPPCSTATS)
+ len = sizeof(struct ppp_comp_stats);
+ else
+ len = sizeof(struct ppp_stats);
+
+ len = copy_to_user((char *)A(data), ifr.ifr_data, len);
+ free_page((unsigned long)ifr.ifr_data);
+ if(len)
+ return -EFAULT;
+ break;
+ }
case SIOCGIFMAP:
err = copy_to_user((struct ifreq32 *)arg, &ifr, sizeof(ifr.ifr_name));
err |= __put_user(ifr.ifr_map.mem_start, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.mem_start));
@@ -653,6 +721,14 @@
err = -EFAULT;
break;
}
+ } else {
+ switch (cmd) {
+ case SIOCGPPPSTATS:
+ case SIOCGPPPCSTATS:
+ case SIOCGPPPVER:
+ free_page((unsigned long)ifr.ifr_data);
+ break;
+ }
}
return err;
}
@@ -1656,10 +1732,10 @@
set_fs(old_fs);
if(err == 0) {
- __u32 redptr = (__u32)cmap.red;
- __u32 greenptr = (__u32)cmap.green;
- __u32 blueptr = (__u32)cmap.blue;
- __u32 transpptr = (__u32)cmap.transp;
+ __u32 redptr = (__u32)(__u64)cmap.red;
+ __u32 greenptr = (__u32)(__u64)cmap.green;
+ __u32 blueptr = (__u32)(__u64)cmap.blue;
+ __u32 transpptr = (__u32)(__u64)cmap.transp;
err = put_user(cmap.start, &((struct fb_cmap32 *)arg)->start);
err |= __put_user(cmap.len, &((struct fb_cmap32 *)arg)->len);
@@ -1690,10 +1766,10 @@
if (err) {
err = -EFAULT;
} else {
- cmap.red = (__u16 *)redptr;
- cmap.green = (__u16 *)greenptr;
- cmap.blue = (__u16 *)blueptr;
- cmap.transp = (__u16 *)transpptr;
+ cmap.red = (__u16 *)(__u64)redptr;
+ cmap.green = (__u16 *)(__u64)greenptr;
+ cmap.blue = (__u16 *)(__u64)blueptr;
+ cmap.transp = (__u16 *)(__u64)transpptr;
set_fs (KERNEL_DS);
err = sys_ioctl (fd, cmd, (unsigned long)&cmap);
set_fs (old_fs);
@@ -1820,7 +1896,7 @@
goto out;
}
- err = copy_from_user(iobuf.buffer, A(iobuf32.buffer), iobuf.length);
+ err = copy_from_user(iobuf.buffer, (void *)A(iobuf32.buffer), iobuf.length);
if (err) {
err = -EFAULT;
goto out;
@@ -1834,7 +1910,7 @@
goto out;
if(iobuf.buffer && iobuf.length > 0) {
- err = copy_to_user(A(iobuf32.buffer), iobuf.buffer, iobuf.length);
+ err = copy_to_user((void *)A(iobuf32.buffer), iobuf.buffer, iobuf.length);
if (err) {
err = -EFAULT;
goto out;
@@ -1874,7 +1950,7 @@
goto out;
}
- err = copy_from_user(sioc.arg, A(sioc32.arg), sioc32.length);
+ err = copy_from_user(sioc.arg, (void *)A(sioc32.arg), sioc32.length);
if (err) {
err = -EFAULT;
goto out;
@@ -1889,7 +1965,7 @@
}
if(sioc.arg && sioc.length > 0) {
- err = copy_to_user(A(sioc32.arg), sioc.arg, sioc.length);
+ err = copy_to_user((void *)A(sioc32.arg), sioc.arg, sioc.length);
if (err) {
err = -EFAULT;
goto out;
@@ -2005,7 +2081,7 @@
uint32_t pe_allocated;
uint32_t pe_stale;
u32 pe;
- u32 inode;
+ u32 bd;
uint8_t pv_uuid[UUID_LEN+1];
} pv32_t;
@@ -2227,7 +2303,7 @@
}
- v->pv[i]->pe = NULL; v->pv[i]->inode = NULL;
+ v->pv[i]->pe = NULL; v->pv[i]->bd = NULL;
}
}
if (!err) {
@@ -2269,14 +2345,14 @@
u.lv_bydev.lv = get_lv_t(ptr, &err);
if (err) return err;
u.lv_bydev.lv = &p;
- p.pe = NULL; p.inode = NULL;
+ p.pe = NULL; p.bd = NULL;
break;
case VG_EXTEND:
err = copy_from_user(&p, (void *)arg, sizeof(pv32_t) - 8 - UUID_LEN+1);
if (err) return -EFAULT;
err = copy_from_user(p.pv_uuid, ((pv32_t *)arg)->pv_uuid, UUID_LEN+1);
if (err) return -EFAULT;
- p.pe = NULL; p.inode = NULL;
+ p.pe = NULL; p.bd = NULL;
karg = &p;
break;
case PV_CHANGE:
@@ -2289,7 +2365,7 @@
if (cmd == PV_CHANGE) {
err = copy_from_user(&p, (void *)A(ptr), sizeof(pv32_t) - 8 - UUID_LEN+1);
if (err) return -EFAULT;
- p.pe = NULL; p.inode = NULL;
+ p.pe = NULL; p.bd = NULL;
}
break;
}
@@ -2938,6 +3014,452 @@
return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, arg);
}
+struct usbdevfs_ctrltransfer32 {
+ __u8 requesttype;
+ __u8 request;
+ __u16 value;
+ __u16 index;
+ __u16 length;
+ __u32 timeout; /* in milliseconds */
+ __u32 data;
+};
+
+#define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32)
+
+static int do_usbdevfs_control(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ struct usbdevfs_ctrltransfer kctrl;
+ struct usbdevfs_ctrltransfer32 *uctrl;
+ mm_segment_t old_fs;
+ __u32 udata;
+ void *uptr, *kptr;
+ int err;
+
+ uctrl = (struct usbdevfs_ctrltransfer32 *) arg;
+
+ if (copy_from_user(&kctrl, uctrl,
+ (sizeof(struct usbdevfs_ctrltransfer) -
+ sizeof(void *))))
+ return -EFAULT;
+
+ if (get_user(udata, &uctrl->data))
+ return -EFAULT;
+ uptr = (void *) A(udata);
+
+ /* In usbdevice_fs, it limits the control buffer to a page,
+ * for simplicity so do we.
+ */
+ if (!uptr || kctrl.length > PAGE_SIZE)
+ return -EINVAL;
+
+ kptr = (void *)__get_free_page(GFP_KERNEL);
+
+ if ((kctrl.requesttype & 0x80) == 0) {
+ err = -EFAULT;
+ if (copy_from_user(kptr, uptr, kctrl.length))
+ goto out;
+ }
+
+ kctrl.data = kptr;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_ioctl(fd, USBDEVFS_CONTROL, (unsigned long)&kctrl);
+ set_fs(old_fs);
+
+ if (err >= 0 &&
+ ((kctrl.requesttype & 0x80) != 0)) {
+ if (copy_to_user(uptr, kptr, kctrl.length))
+ err = -EFAULT;
+ }
+
+out:
+ free_page((unsigned long) kptr);
+ return err;
+}
+
+struct usbdevfs_bulktransfer32 {
+ unsigned int ep;
+ unsigned int len;
+ unsigned int timeout; /* in milliseconds */
+ __u32 data;
+};
+
+#define USBDEVFS_BULK32 _IOWR('U', 2, struct usbdevfs_bulktransfer32)
+
+static int do_usbdevfs_bulk(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ struct usbdevfs_bulktransfer kbulk;
+ struct usbdevfs_bulktransfer32 *ubulk;
+ mm_segment_t old_fs;
+ __u32 udata;
+ void *uptr, *kptr;
+ int err;
+
+ ubulk = (struct usbdevfs_bulktransfer32 *) arg;
+
+ if (get_user(kbulk.ep, &ubulk->ep) ||
+ get_user(kbulk.len, &ubulk->len) ||
+ get_user(kbulk.timeout, &ubulk->timeout) ||
+ get_user(udata, &ubulk->data))
+ return -EFAULT;
+
+ uptr = (void *) A(udata);
+
+ /* In usbdevice_fs, it limits the control buffer to a page,
+ * for simplicity so do we.
+ */
+ if (!uptr || kbulk.len > PAGE_SIZE)
+ return -EINVAL;
+
+ kptr = (void *) __get_free_page(GFP_KERNEL);
+
+ if ((kbulk.ep & 0x80) == 0) {
+ err = -EFAULT;
+ if (copy_from_user(kptr, uptr, kbulk.len))
+ goto out;
+ }
+
+ kbulk.data = kptr;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_ioctl(fd, USBDEVFS_BULK, (unsigned long) &kbulk);
+ set_fs(old_fs);
+
+ if (err >= 0 &&
+ ((kbulk.ep & 0x80) != 0)) {
+ if (copy_to_user(uptr, kptr, kbulk.len))
+ err = -EFAULT;
+ }
+
+out:
+ free_page((unsigned long) kptr);
+ return err;
+}
+
+/* This needs more work before we can enable it. Unfortunately
+ * because of the fancy asynchronous way URB status/error is written
+ * back to userspace, we'll need to fiddle with USB devio internals
+ * and/or reimplement entirely the frontend of it ourselves. -DaveM
+ *
+ * The issue is:
+ *
+ * When an URB is submitted via usbdevicefs it is put onto an
+ * asynchronous queue. When the URB completes, it may be reaped
+ * via another ioctl. During this reaping the status is written
+ * back to userspace along with the length of the transfer.
+ *
+ * We must translate into 64-bit kernel types so we pass in a kernel
+ * space copy of the usbdevfs_urb structure. This would mean that we
+ * must do something to deal with the async entry reaping. First we
+ * have to deal somehow with this transitory memory we've allocated.
+ * This is problematic since there are many call sites from which the
+ * async entries can be destroyed (and thus when we'd need to free up
+ * this kernel memory). One of which is the close() op of usbdevicefs.
+ * To handle that we'd need to make our own file_operations struct which
+ * overrides usbdevicefs's release op with our own which runs usbdevicefs's
+ * real release op then frees up the kernel memory.
+ *
+ * But how to keep track of these kernel buffers? We'd need to either
+ * keep track of them in some table _or_ know about usbdevicefs internals
+ * (ie. the exact layout of it's file private, which is actually defined
+ * in linux/usbdevice_fs.h, the layout of the async queues are private to
+ * devio.c)
+ *
+ * There is one possible other solution I considered, also involving knowledge
+ * of usbdevicefs internals:
+ *
+ * After an URB is submitted, we "fix up" the address back to the user
+ * space one. This would work if the status/length fields written back
+ * by the async URB completion lines up perfectly in the 32-bit type with
+ * the 64-bit kernel type. Unfortunately, it does not because the iso
+ * frame descriptors, at the end of the struct, can be written back.
+ *
+ * I think we'll just need to simply duplicate the devio URB engine here.
+ */
+#if 0
+struct usbdevfs_urb32 {
+ __u8 type;
+ __u8 endpoint;
+ __s32 status;
+ __u32 flags;
+ __u32 buffer;
+ __s32 buffer_length;
+ __s32 actual_length;
+ __s32 start_frame;
+ __s32 number_of_packets;
+ __s32 error_count;
+ __u32 signr;
+ __u32 usercontext; /* unused */
+ struct usbdevfs_iso_packet_desc iso_frame_desc[0];
+};
+
+#define USBDEVFS_SUBMITURB32 _IOR('U', 10, struct usbdevfs_urb32)
+
+static int get_urb32(struct usbdevfs_urb *kurb,
+ struct usbdevfs_urb32 *uurb)
+{
+ if (get_user(kurb->type, &uurb->type) ||
+ __get_user(kurb->endpoint, &uurb->endpoint) ||
+ __get_user(kurb->status, &uurb->status) ||
+ __get_user(kurb->flags, &uurb->flags) ||
+ __get_user(kurb->buffer_length, &uurb->buffer_length) ||
+ __get_user(kurb->actual_length, &uurb->actual_length) ||
+ __get_user(kurb->start_frame, &uurb->start_frame) ||
+ __get_user(kurb->number_of_packets, &uurb->number_of_packets) ||
+ __get_user(kurb->error_count, &uurb->error_count) ||
+ __get_user(kurb->signr, &uurb->signr))
+ return -EFAULT;
+
+ kurb->usercontext = 0; /* unused currently */
+
+ return 0;
+}
+
+/* Just put back the values which usbdevfs actually changes. */
+static int put_urb32(struct usbdevfs_urb *kurb,
+ struct usbdevfs_urb32 *uurb)
+{
+ if (put_user(kurb->status, &uurb->status) ||
+ __put_user(kurb->actual_length, &uurb->actual_length) ||
+ __put_user(kurb->error_count, &uurb->error_count))
+ return -EFAULT;
+
+ if (kurb->number_of_packets != 0) {
+ int i;
+
+ for (i = 0; i < kurb->number_of_packets; i++) {
+ if (__put_user(kurb->iso_frame_desc[i].actual_length,
+ &uurb->iso_frame_desc[i].actual_length) ||
+ __put_user(kurb->iso_frame_desc[i].status,
+ &uurb->iso_frame_desc[i].status))
+ return -EFAULT;
+ }
+ }
+
+ return 0;
+}
+
+static int get_urb32_isoframes(struct usbdevfs_urb *kurb,
+ struct usbdevfs_urb32 *uurb)
+{
+ unsigned int totlen;
+ int i;
+
+ if (kurb->type != USBDEVFS_URB_TYPE_ISO) {
+ kurb->number_of_packets = 0;
+ return 0;
+ }
+
+ if (kurb->number_of_packets < 1 ||
+ kurb->number_of_packets > 128)
+ return -EINVAL;
+
+ if (copy_from_user(&kurb->iso_frame_desc[0],
+ &uurb->iso_frame_desc[0],
+ sizeof(struct usbdevfs_iso_packet_desc) *
+ kurb->number_of_packets))
+ return -EFAULT;
+
+ totlen = 0;
+ for (i = 0; i < kurb->number_of_packets; i++) {
+ unsigned int this_len;
+
+ this_len = kurb->iso_frame_desc[i].length;
+ if (this_len > 1023)
+ return -EINVAL;
+
+ totlen += this_len;
+ }
+
+ if (totlen > 32768)
+ return -EINVAL;
+
+ kurb->buffer_length = totlen;
+
+ return 0;
+}
+
+static int do_usbdevfs_urb(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ struct usbdevfs_urb *kurb;
+ struct usbdevfs_urb32 *uurb;
+ mm_segment_t old_fs;
+ __u32 udata;
+ void *uptr, *kptr;
+ unsigned int buflen;
+ int err;
+
+ uurb = (struct usbdevfs_urb32 *) arg;
+
+ err = -ENOMEM;
+ kurb = kmalloc(sizeof(struct usbdevfs_urb) +
+ (sizeof(struct usbdevfs_iso_packet_desc) * 128),
+ GFP_KERNEL);
+ if (!kurb)
+ goto out;
+
+ err = -EFAULT;
+ if (get_urb32(kurb, uurb))
+ goto out;
+
+ err = get_urb32_isoframes(kurb, uurb);
+ if (err)
+ goto out;
+
+ err = -EFAULT;
+ if (__get_user(udata, &uurb->buffer))
+ uptr = (void *) A(udata);
+
+ err = -ENOMEM;
+ buflen = kurb->buffer_length;
+ kptr = kmalloc(buflen, GFP_KERNEL);
+ if (!kptr)
+ goto out;
+
+ kurb->buffer = kptr;
+
+ err = -EFAULT;
+ if (copy_from_user(kptr, uptr, buflen))
+ goto out_kptr;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_ioctl(fd, USBDEVFS_SUBMITURB, (unsigned long) kurb);
+ set_fs(old_fs);
+
+ if (err >= 0) {
+ /* XXX Shit, this doesn't work for async URBs :-( XXX */
+ if (put_urb32(kurb, uurb)) {
+ err = -EFAULT;
+ } else if ((kurb->endpoint & USB_DIR_IN) != 0) {
+ if (copy_to_user(uptr, kptr, buflen))
+ err = -EFAULT;
+ }
+ }
+
+out_kptr:
+ kfree(kptr);
+
+out:
+ kfree(kurb);
+ return err;
+}
+#endif
+
+#define USBDEVFS_REAPURB32 _IOW('U', 12, u32)
+#define USBDEVFS_REAPURBNDELAY32 _IOW('U', 13, u32)
+
+static int do_usbdevfs_reapurb(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ mm_segment_t old_fs;
+ void *kptr;
+ int err;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_ioctl(fd,
+ (cmd == USBDEVFS_REAPURB32 ?
+ USBDEVFS_REAPURB :
+ USBDEVFS_REAPURBNDELAY),
+ (unsigned long) &kptr);
+ set_fs(old_fs);
+
+ if (err >= 0 &&
+ put_user(((u32)(long)kptr), (u32 *) A(arg)))
+ err = -EFAULT;
+
+ return err;
+}
+
+struct usbdevfs_disconnectsignal32 {
+ unsigned int signr;
+ u32 context;
+};
+
+#define USBDEVFS_DISCSIGNAL32 _IOR('U', 14, struct usbdevfs_disconnectsignal32)
+
+static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ struct usbdevfs_disconnectsignal kdis;
+ struct usbdevfs_disconnectsignal32 *udis;
+ mm_segment_t old_fs;
+ u32 uctx;
+ int err;
+
+ udis = (struct usbdevfs_disconnectsignal32 *) arg;
+
+ if (get_user(kdis.signr, &udis->signr) ||
+ __get_user(uctx, &udis->context))
+ return -EFAULT;
+
+ kdis.context = (void *) (long)uctx;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ err = sys_ioctl(fd, USBDEVFS_DISCSIGNAL, (unsigned long) &kdis);
+ set_fs(old_fs);
+
+ return err;
+}
+
+struct mtd_oob_buf32 {
+ u32 start;
+ u32 length;
+ u32 ptr; /* unsigned char* */
+};
+
+#define MEMWRITEOOB32 _IOWR('M',3,struct mtd_oob_buf32)
+#define MEMREADOOB32 _IOWR('M',4,struct mtd_oob_buf32)
+
+static inline int
+mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+ mm_segment_t old_fs = get_fs();
+ struct mtd_oob_buf32 *uarg = (struct mtd_oob_buf32 *)arg;
+ struct mtd_oob_buf karg;
+ u32 tmp;
+ char *ptr;
+ int ret;
+
+ if (get_user(karg.start, &uarg->start) ||
+ get_user(karg.length, &uarg->length) ||
+ get_user(tmp, &uarg->ptr))
+ return -EFAULT;
+
+ ptr = (char *)A(tmp);
+ if (0 >= karg.length)
+ return -EINVAL;
+
+ karg.ptr = kmalloc(karg.length, GFP_KERNEL);
+ if (NULL == karg.ptr)
+ return -ENOMEM;
+
+ if (copy_from_user(karg.ptr, ptr, karg.length)) {
+ kfree(karg.ptr);
+ return -EFAULT;
+ }
+
+ set_fs(KERNEL_DS);
+ if (MEMREADOOB32 == cmd)
+ ret = sys_ioctl(fd, MEMREADOOB, (unsigned long)&karg);
+ else if (MEMWRITEOOB32 == cmd)
+ ret = sys_ioctl(fd, MEMWRITEOOB, (unsigned long)&karg);
+ else
+ ret = -EINVAL;
+ set_fs(old_fs);
+
+ if (0 == ret && cmd == MEMREADOOB32) {
+ ret = copy_to_user(ptr, karg.ptr, karg.length);
+ ret |= put_user(karg.start, &uarg->start);
+ ret |= put_user(karg.length, &uarg->length);
+ }
+
+ kfree(karg.ptr);
+ return ((0 == ret) ? 0 : -EFAULT);
+}
+
struct ioctl_trans {
unsigned long cmd;
unsigned long handler;
@@ -3058,6 +3580,9 @@
COMPATIBLE_IOCTL(BLKFRASET),
COMPATIBLE_IOCTL(BLKSECTSET),
COMPATIBLE_IOCTL(BLKSSZGET),
+COMPATIBLE_IOCTL(BLKBSZGET),
+COMPATIBLE_IOCTL(BLKBSZSET),
+COMPATIBLE_IOCTL(BLKGETSIZE64),
/* RAID */
COMPATIBLE_IOCTL(RAID_VERSION),
@@ -3099,6 +3624,7 @@
COMPATIBLE_IOCTL(KDGKBSENT),
COMPATIBLE_IOCTL(KDSKBSENT),
COMPATIBLE_IOCTL(KDGKBDIACR),
+COMPATIBLE_IOCTL(KDKBDREP),
COMPATIBLE_IOCTL(KDSKBDIACR),
COMPATIBLE_IOCTL(KDGKBLED),
COMPATIBLE_IOCTL(KDSKBLED),
@@ -3112,6 +3638,7 @@
COMPATIBLE_IOCTL(PIO_UNIMAPCLR),
/* Big S */
COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN),
+COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST),
COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK),
COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK),
COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY),
@@ -3280,6 +3807,10 @@
COMPATIBLE_IOCTL(CDROM_LOCKDOOR),
COMPATIBLE_IOCTL(CDROM_DEBUG),
COMPATIBLE_IOCTL(CDROM_GET_CAPABILITY),
+/* DVD ioctls */
+COMPATIBLE_IOCTL(DVD_READ_STRUCT),
+COMPATIBLE_IOCTL(DVD_WRITE_STRUCT),
+COMPATIBLE_IOCTL(DVD_AUTH),
/* Big L */
COMPATIBLE_IOCTL(LOOP_SET_FD),
COMPATIBLE_IOCTL(LOOP_CLR_FD),
@@ -3507,7 +4038,7 @@
COMPATIBLE_IOCTL(DRM_IOCTL_ADD_DRAW),
COMPATIBLE_IOCTL(DRM_IOCTL_RM_DRAW),
COMPATIBLE_IOCTL(DRM_IOCTL_LOCK),
-OMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK),
+COMPATIBLE_IOCTL(DRM_IOCTL_UNLOCK),
COMPATIBLE_IOCTL(DRM_IOCTL_FINISH),
#endif /* DRM */
/* elevator */
@@ -3520,162 +4051,214 @@
COMPATIBLE_IOCTL(WDIOC_GETTEMP),
COMPATIBLE_IOCTL(WDIOC_SETOPTIONS),
COMPATIBLE_IOCTL(WDIOC_KEEPALIVE),
+/* Bluetooth ioctls */
+COMPATIBLE_IOCTL(HCIDEVUP),
+COMPATIBLE_IOCTL(HCIDEVDOWN),
+COMPATIBLE_IOCTL(HCIDEVRESET),
+COMPATIBLE_IOCTL(HCIRESETSTAT),
+COMPATIBLE_IOCTL(HCIGETINFO),
+COMPATIBLE_IOCTL(HCIGETDEVLIST),
+COMPATIBLE_IOCTL(HCISETRAW),
+COMPATIBLE_IOCTL(HCISETSCAN),
+COMPATIBLE_IOCTL(HCISETAUTH),
+COMPATIBLE_IOCTL(HCIINQUIRY),
COMPATIBLE_IOCTL(PCIIOC_CONTROLLER),
COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO),
COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM),
COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE),
-
- HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32),
- HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf),
- HANDLE_IOCTL(SIOCGIFFLAGS, dev_ifsioc),
- HANDLE_IOCTL(SIOCSIFFLAGS, dev_ifsioc),
- HANDLE_IOCTL(SIOCGIFMETRIC, dev_ifsioc),
- HANDLE_IOCTL(SIOCSIFMETRIC, dev_ifsioc),
- HANDLE_IOCTL(SIOCGIFMTU, dev_ifsioc),
- HANDLE_IOCTL(SIOCSIFMTU, dev_ifsioc),
- HANDLE_IOCTL(SIOCGIFMEM, dev_ifsioc),
- HANDLE_IOCTL(SIOCSIFMEM, dev_ifsioc),
- HANDLE_IOCTL(SIOCGIFHWADDR, dev_ifsioc),
- HANDLE_IOCTL(SIOCSIFHWADDR, dev_ifsioc),
- HANDLE_IOCTL(SIOCADDMULTI, dev_ifsioc),
- HANDLE_IOCTL(SIOCDELMULTI, dev_ifsioc),
- HANDLE_IOCTL(SIOCGIFINDEX, dev_ifsioc),
- HANDLE_IOCTL(SIOCGIFMAP, dev_ifsioc),
- HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc),
- HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc),
- HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc),
- HANDLE_IOCTL(SIOCGIFBRDADDR, dev_ifsioc),
- HANDLE_IOCTL(SIOCSIFBRDADDR, dev_ifsioc),
- HANDLE_IOCTL(SIOCGIFDSTADDR, dev_ifsioc),
- HANDLE_IOCTL(SIOCSIFDSTADDR, dev_ifsioc),
- HANDLE_IOCTL(SIOCGIFNETMASK, dev_ifsioc),
- HANDLE_IOCTL(SIOCSIFNETMASK, dev_ifsioc),
- HANDLE_IOCTL(SIOCSIFPFLAGS, dev_ifsioc),
- HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc),
- HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc),
- HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc),
- HANDLE_IOCTL(SIOCGPPPVER, dev_ifsioc),
- HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc),
- HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc),
- HANDLE_IOCTL(SIOCADDRT, routing_ioctl),
- HANDLE_IOCTL(SIOCDELRT, routing_ioctl),
- /* Note SIOCRTMSG is no longer, so this is safe and
- * the user would have seen just an -EINVAL anyways. */
- HANDLE_IOCTL(SIOCRTMSG, ret_einval),
- HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp),
- HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo),
- HANDLE_IOCTL(BLKRAGET, w_long),
- HANDLE_IOCTL(BLKGETSIZE, w_long),
- HANDLE_IOCTL(0x1260, broken_blkgetsize),
- HANDLE_IOCTL(BLKFRAGET, w_long),
- HANDLE_IOCTL(BLKSECTGET, w_long),
- HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans),
- HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans),
- HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans),
- HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans),
- HANDLE_IOCTL(HDIO_GET_32BIT, hdio_ioctl_trans),
- HANDLE_IOCTL(HDIO_GET_MULTCOUNT, hdio_ioctl_trans),
- HANDLE_IOCTL(HDIO_GET_NOWERR, hdio_ioctl_trans),
- HANDLE_IOCTL(HDIO_GET_NICE, hdio_ioctl_trans),
- HANDLE_IOCTL(FDSETPRM32, fd_ioctl_trans),
- HANDLE_IOCTL(FDDEFPRM32, fd_ioctl_trans),
- HANDLE_IOCTL(FDGETPRM32, fd_ioctl_trans),
- HANDLE_IOCTL(FDSETDRVPRM32, fd_ioctl_trans),
- HANDLE_IOCTL(FDGETDRVPRM32, fd_ioctl_trans),
- HANDLE_IOCTL(FDGETDRVSTAT32, fd_ioctl_trans),
- HANDLE_IOCTL(FDPOLLDRVSTAT32, fd_ioctl_trans),
- HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans),
- HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans),
- HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans),
- HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans),
- HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans),
- HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans),
- HANDLE_IOCTL(MTIOCGETCONFIG32, mt_ioctl_trans),
- HANDLE_IOCTL(MTIOCSETCONFIG32, mt_ioctl_trans),
- HANDLE_IOCTL(CDROMREADMODE2, cdrom_ioctl_trans),
- HANDLE_IOCTL(CDROMREADMODE1, cdrom_ioctl_trans),
- HANDLE_IOCTL(CDROMREADRAW, cdrom_ioctl_trans),
- HANDLE_IOCTL(CDROMREADCOOKED, cdrom_ioctl_trans),
- HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans),
- HANDLE_IOCTL(CDROMREADALL, cdrom_ioctl_trans),
- HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans),
- HANDLE_IOCTL(LOOP_SET_STATUS, loop_status),
- HANDLE_IOCTL(LOOP_GET_STATUS, loop_status),
- HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout),
+/* USB */
+COMPATIBLE_IOCTL(USBDEVFS_RESETEP),
+COMPATIBLE_IOCTL(USBDEVFS_SETINTERFACE),
+COMPATIBLE_IOCTL(USBDEVFS_SETCONFIGURATION),
+COMPATIBLE_IOCTL(USBDEVFS_GETDRIVER),
+COMPATIBLE_IOCTL(USBDEVFS_DISCARDURB),
+COMPATIBLE_IOCTL(USBDEVFS_CLAIMINTERFACE),
+COMPATIBLE_IOCTL(USBDEVFS_RELEASEINTERFACE),
+COMPATIBLE_IOCTL(USBDEVFS_CONNECTINFO),
+COMPATIBLE_IOCTL(USBDEVFS_HUB_PORTINFO),
+COMPATIBLE_IOCTL(USBDEVFS_RESET),
+COMPATIBLE_IOCTL(USBDEVFS_CLEAR_HALT),
+/* MTD */
+COMPATIBLE_IOCTL(MEMGETINFO),
+COMPATIBLE_IOCTL(MEMERASE),
+COMPATIBLE_IOCTL(MEMLOCK),
+COMPATIBLE_IOCTL(MEMUNLOCK),
+COMPATIBLE_IOCTL(MEMGETREGIONCOUNT),
+COMPATIBLE_IOCTL(MEMGETREGIONINFO),
+/* NBD */
+COMPATIBLE_IOCTL(NBD_SET_SOCK),
+COMPATIBLE_IOCTL(NBD_SET_BLKSIZE),
+COMPATIBLE_IOCTL(NBD_SET_SIZE),
+COMPATIBLE_IOCTL(NBD_DO_IT),
+COMPATIBLE_IOCTL(NBD_CLEAR_SOCK),
+COMPATIBLE_IOCTL(NBD_CLEAR_QUE),
+COMPATIBLE_IOCTL(NBD_PRINT_DEBUG),
+COMPATIBLE_IOCTL(NBD_SET_SIZE_BLOCKS),
+COMPATIBLE_IOCTL(NBD_DISCONNECT),
+/* And these ioctls need translation */
+HANDLE_IOCTL(MEMREADOOB32, mtd_rw_oob),
+HANDLE_IOCTL(MEMWRITEOOB32, mtd_rw_oob),
+HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32),
+HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf),
+HANDLE_IOCTL(SIOCGIFFLAGS, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFFLAGS, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFMETRIC, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFMETRIC, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFMTU, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFMTU, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFMEM, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFMEM, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFHWADDR, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFHWADDR, dev_ifsioc),
+HANDLE_IOCTL(SIOCADDMULTI, dev_ifsioc),
+HANDLE_IOCTL(SIOCDELMULTI, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFINDEX, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFMAP, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFMAP, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFADDR, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFADDR, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFBRDADDR, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFBRDADDR, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFDSTADDR, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFDSTADDR, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFNETMASK, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFNETMASK, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFPFLAGS, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFPFLAGS, dev_ifsioc),
+HANDLE_IOCTL(SIOCGPPPSTATS, dev_ifsioc),
+HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc),
+HANDLE_IOCTL(SIOCGPPPVER, dev_ifsioc),
+HANDLE_IOCTL(SIOCGIFTXQLEN, dev_ifsioc),
+HANDLE_IOCTL(SIOCSIFTXQLEN, dev_ifsioc),
+HANDLE_IOCTL(SIOCETHTOOL, ethtool_ioctl),
+HANDLE_IOCTL(SIOCGMIIPHY, mii_ioctl),
+HANDLE_IOCTL(SIOCGMIIREG, mii_ioctl),
+HANDLE_IOCTL(SIOCSMIIREG, mii_ioctl),
+HANDLE_IOCTL(SIOCADDRT, routing_ioctl),
+HANDLE_IOCTL(SIOCDELRT, routing_ioctl),
+/* Note SIOCRTMSG is no longer, so this is safe and
+ * the user would have seen just an -EINVAL anyways. */
+HANDLE_IOCTL(SIOCRTMSG, ret_einval),
+HANDLE_IOCTL(SIOCGSTAMP, do_siocgstamp),
+HANDLE_IOCTL(HDIO_GETGEO, hdio_getgeo),
+HANDLE_IOCTL(BLKRAGET, w_long),
+HANDLE_IOCTL(BLKGETSIZE, w_long),
+HANDLE_IOCTL(0x1260, broken_blkgetsize),
+HANDLE_IOCTL(BLKFRAGET, w_long),
+HANDLE_IOCTL(BLKSECTGET, w_long),
+HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans),
+HANDLE_IOCTL(HDIO_GET_KEEPSETTINGS, hdio_ioctl_trans),
+HANDLE_IOCTL(HDIO_GET_UNMASKINTR, hdio_ioctl_trans),
+HANDLE_IOCTL(HDIO_GET_DMA, hdio_ioctl_trans),
+HANDLE_IOCTL(HDIO_GET_32BIT, hdio_ioctl_trans),
+HANDLE_IOCTL(HDIO_GET_MULTCOUNT, hdio_ioctl_trans),
+HANDLE_IOCTL(HDIO_GET_NOWERR, hdio_ioctl_trans),
+HANDLE_IOCTL(HDIO_GET_NICE, hdio_ioctl_trans),
+HANDLE_IOCTL(FDSETPRM32, fd_ioctl_trans),
+HANDLE_IOCTL(FDDEFPRM32, fd_ioctl_trans),
+HANDLE_IOCTL(FDGETPRM32, fd_ioctl_trans),
+HANDLE_IOCTL(FDSETDRVPRM32, fd_ioctl_trans),
+HANDLE_IOCTL(FDGETDRVPRM32, fd_ioctl_trans),
+HANDLE_IOCTL(FDGETDRVSTAT32, fd_ioctl_trans),
+HANDLE_IOCTL(FDPOLLDRVSTAT32, fd_ioctl_trans),
+HANDLE_IOCTL(FDGETFDCSTAT32, fd_ioctl_trans),
+HANDLE_IOCTL(FDWERRORGET32, fd_ioctl_trans),
+HANDLE_IOCTL(PPPIOCGIDLE32, ppp_ioctl_trans),
+HANDLE_IOCTL(PPPIOCSCOMPRESS32, ppp_ioctl_trans),
+HANDLE_IOCTL(MTIOCGET32, mt_ioctl_trans),
+HANDLE_IOCTL(MTIOCPOS32, mt_ioctl_trans),
+HANDLE_IOCTL(MTIOCGETCONFIG32, mt_ioctl_trans),
+HANDLE_IOCTL(MTIOCSETCONFIG32, mt_ioctl_trans),
+HANDLE_IOCTL(CDROMREADMODE2, cdrom_ioctl_trans),
+HANDLE_IOCTL(CDROMREADMODE1, cdrom_ioctl_trans),
+HANDLE_IOCTL(CDROMREADRAW, cdrom_ioctl_trans),
+HANDLE_IOCTL(CDROMREADCOOKED, cdrom_ioctl_trans),
+HANDLE_IOCTL(CDROMREADAUDIO, cdrom_ioctl_trans),
+HANDLE_IOCTL(CDROMREADALL, cdrom_ioctl_trans),
+HANDLE_IOCTL(CDROM_SEND_PACKET, cdrom_ioctl_trans),
+HANDLE_IOCTL(LOOP_SET_STATUS, loop_status),
+HANDLE_IOCTL(LOOP_GET_STATUS, loop_status),
+HANDLE_IOCTL(AUTOFS_IOC_SETTIMEOUT32, ioc_settimeout),
#ifdef CONFIG_VT
- HANDLE_IOCTL(PIO_FONTX, do_fontx_ioctl),
- HANDLE_IOCTL(GIO_FONTX, do_fontx_ioctl),
- HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl),
- HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl),
- HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl),
- HANDLE_IOCTL(FBIOGET_FSCREENINFO, do_fbioget_fscreeninfo_ioctl),
- HANDLE_IOCTL(FBIOGETCMAP, do_fbiogetcmap_ioctl),
- HANDLE_IOCTL(FBIOPUTCMAP, do_fbioputcmap_ioctl),
+HANDLE_IOCTL(PIO_FONTX, do_fontx_ioctl),
+HANDLE_IOCTL(GIO_FONTX, do_fontx_ioctl),
+HANDLE_IOCTL(PIO_UNIMAP, do_unimap_ioctl),
+HANDLE_IOCTL(GIO_UNIMAP, do_unimap_ioctl),
+HANDLE_IOCTL(KDFONTOP, do_kdfontop_ioctl),
+HANDLE_IOCTL(FBIOGET_FSCREENINFO, do_fbioget_fscreeninfo_ioctl),
+HANDLE_IOCTL(FBIOGETCMAP, do_fbiogetcmap_ioctl),
+HANDLE_IOCTL(FBIOPUTCMAP, do_fbioputcmap_ioctl),
#endif
- HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl),
- HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl),
- HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl),
- HANDLE_IOCTL(EXT2_IOC32_SETVERSION, do_ext2_ioctl),
- HANDLE_IOCTL(VIDIOCGTUNER32, do_video_ioctl),
- HANDLE_IOCTL(VIDIOCSTUNER32, do_video_ioctl),
- HANDLE_IOCTL(VIDIOCGWIN32, do_video_ioctl),
- HANDLE_IOCTL(VIDIOCSWIN32, do_video_ioctl),
- HANDLE_IOCTL(VIDIOCGFBUF32, do_video_ioctl),
- HANDLE_IOCTL(VIDIOCSFBUF32, do_video_ioctl),
- HANDLE_IOCTL(VIDIOCGFREQ32, do_video_ioctl),
- HANDLE_IOCTL(VIDIOCSFREQ32, do_video_ioctl),
- /* One SMB ioctl needs translations. */
- HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid),
- HANDLE_IOCTL(ATM_GETLINKRATE32, do_atm_ioctl),
- HANDLE_IOCTL(ATM_GETNAMES32, do_atm_ioctl),
- HANDLE_IOCTL(ATM_GETTYPE32, do_atm_ioctl),
- HANDLE_IOCTL(ATM_GETESI32, do_atm_ioctl),
- HANDLE_IOCTL(ATM_GETADDR32, do_atm_ioctl),
- HANDLE_IOCTL(ATM_RSTADDR32, do_atm_ioctl),
- HANDLE_IOCTL(ATM_ADDADDR32, do_atm_ioctl),
- HANDLE_IOCTL(ATM_DELADDR32, do_atm_ioctl),
- HANDLE_IOCTL(ATM_GETCIRANGE32, do_atm_ioctl),
- HANDLE_IOCTL(ATM_SETCIRANGE32, do_atm_ioctl),
- HANDLE_IOCTL(ATM_SETESI32, do_atm_ioctl),
- HANDLE_IOCTL(ATM_SETESIF32, do_atm_ioctl),
- HANDLE_IOCTL(ATM_GETSTAT32, do_atm_ioctl),
- HANDLE_IOCTL(ATM_GETSTATZ32, do_atm_ioctl),
- HANDLE_IOCTL(ATM_GETLOOP32, do_atm_ioctl),
- HANDLE_IOCTL(ATM_SETLOOP32, do_atm_ioctl),
- HANDLE_IOCTL(ATM_QUERYLOOP32, do_atm_ioctl),
- HANDLE_IOCTL(SONET_GETSTAT, do_atm_ioctl),
- HANDLE_IOCTL(SONET_GETSTATZ, do_atm_ioctl),
- HANDLE_IOCTL(SONET_GETDIAG, do_atm_ioctl),
- HANDLE_IOCTL(SONET_SETDIAG, do_atm_ioctl),
- HANDLE_IOCTL(SONET_CLRDIAG, do_atm_ioctl),
- HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl),
- HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl),
- HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl)
+HANDLE_IOCTL(EXT2_IOC32_GETFLAGS, do_ext2_ioctl),
+HANDLE_IOCTL(EXT2_IOC32_SETFLAGS, do_ext2_ioctl),
+HANDLE_IOCTL(EXT2_IOC32_GETVERSION, do_ext2_ioctl),
+HANDLE_IOCTL(EXT2_IOC32_SETVERSION, do_ext2_ioctl),
+HANDLE_IOCTL(VIDIOCGTUNER32, do_video_ioctl),
+HANDLE_IOCTL(VIDIOCSTUNER32, do_video_ioctl),
+HANDLE_IOCTL(VIDIOCGWIN32, do_video_ioctl),
+HANDLE_IOCTL(VIDIOCSWIN32, do_video_ioctl),
+HANDLE_IOCTL(VIDIOCGFBUF32, do_video_ioctl),
+HANDLE_IOCTL(VIDIOCSFBUF32, do_video_ioctl),
+HANDLE_IOCTL(VIDIOCGFREQ32, do_video_ioctl),
+HANDLE_IOCTL(VIDIOCSFREQ32, do_video_ioctl),
+/* One SMB ioctl needs translations. */
+HANDLE_IOCTL(SMB_IOC_GETMOUNTUID_32, do_smb_getmountuid),
+HANDLE_IOCTL(ATM_GETLINKRATE32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_GETNAMES32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_GETTYPE32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_GETESI32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_GETADDR32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_RSTADDR32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_ADDADDR32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_DELADDR32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_GETCIRANGE32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_SETCIRANGE32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_SETESI32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_SETESIF32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_GETSTAT32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_GETSTATZ32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_GETLOOP32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_SETLOOP32, do_atm_ioctl),
+HANDLE_IOCTL(ATM_QUERYLOOP32, do_atm_ioctl),
+HANDLE_IOCTL(SONET_GETSTAT, do_atm_ioctl),
+HANDLE_IOCTL(SONET_GETSTATZ, do_atm_ioctl),
+HANDLE_IOCTL(SONET_GETDIAG, do_atm_ioctl),
+HANDLE_IOCTL(SONET_SETDIAG, do_atm_ioctl),
+HANDLE_IOCTL(SONET_CLRDIAG, do_atm_ioctl),
+HANDLE_IOCTL(SONET_SETFRAMING, do_atm_ioctl),
+HANDLE_IOCTL(SONET_GETFRAMING, do_atm_ioctl),
+HANDLE_IOCTL(SONET_GETFRSENSE, do_atm_ioctl),
#if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
- ,HANDLE_IOCTL(VG_STATUS, do_lvm_ioctl),
- HANDLE_IOCTL(VG_CREATE, do_lvm_ioctl),
- HANDLE_IOCTL(VG_EXTEND, do_lvm_ioctl),
- HANDLE_IOCTL(LV_CREATE, do_lvm_ioctl),
- HANDLE_IOCTL(LV_REMOVE, do_lvm_ioctl),
- HANDLE_IOCTL(LV_EXTEND, do_lvm_ioctl),
- HANDLE_IOCTL(LV_REDUCE, do_lvm_ioctl),
- HANDLE_IOCTL(LV_RENAME, do_lvm_ioctl),
- HANDLE_IOCTL(LV_STATUS_BYNAME, do_lvm_ioctl),
- HANDLE_IOCTL(LV_STATUS_BYINDEX, do_lvm_ioctl),
- HANDLE_IOCTL(PV_CHANGE, do_lvm_ioctl),
- HANDLE_IOCTL(PV_STATUS, do_lvm_ioctl)
+HANDLE_IOCTL(VG_STATUS, do_lvm_ioctl),
+HANDLE_IOCTL(VG_CREATE, do_lvm_ioctl),
+HANDLE_IOCTL(VG_EXTEND, do_lvm_ioctl),
+HANDLE_IOCTL(LV_CREATE, do_lvm_ioctl),
+HANDLE_IOCTL(LV_REMOVE, do_lvm_ioctl),
+HANDLE_IOCTL(LV_EXTEND, do_lvm_ioctl),
+HANDLE_IOCTL(LV_REDUCE, do_lvm_ioctl),
+HANDLE_IOCTL(LV_RENAME, do_lvm_ioctl),
+HANDLE_IOCTL(LV_STATUS_BYNAME, do_lvm_ioctl),
+HANDLE_IOCTL(LV_STATUS_BYINDEX, do_lvm_ioctl),
+HANDLE_IOCTL(PV_CHANGE, do_lvm_ioctl),
+HANDLE_IOCTL(PV_STATUS, do_lvm_ioctl),
#endif /* LVM */
#if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
- ,HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version),
- HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique),
- HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique),
- HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap),
- HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs),
- HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs),
- HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs),
- HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma),
- HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx)
+HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version),
+HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique),
+HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique),
+HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap),
+HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs),
+HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs),
+HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs),
+HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma),
+HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx),
#endif /* DRM */
+HANDLE_IOCTL(USBDEVFS_CONTROL32, do_usbdevfs_control),
+HANDLE_IOCTL(USBDEVFS_BULK32, do_usbdevfs_bulk),
+/*HANDLE_IOCTL(USBDEVFS_SUBMITURB32, do_usbdevfs_urb)*/
+HANDLE_IOCTL(USBDEVFS_REAPURB32, do_usbdevfs_reapurb),
+HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb),
+HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal),
};
unsigned long ioctl32_hash_table[1024];
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/irq.c linuxppc64_2_4/arch/ppc64/kernel/irq.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/irq.c Tue Oct 16 16:54:41 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/irq.c Wed Sep 26 13:41:13 2001
@@ -23,14 +23,6 @@
* instead of just grabbing them. Thus setups with different IRQ numbers
* shouldn't result in any weird surprises, and installing new handlers
* should be easier.
- *
- * The MPC8xx has an interrupt mask in the SIU. If a bit is set, the
- * interrupt is _enabled_. As expected, IRQ0 is bit 0 in the 32-bit
- * mask register (of which only 16 are defined), hence the weird shifting
- * and compliment of the cached_irq_mask. I want to be able to stuff
- * this right into the SIU SMASK register.
- * Many of the prep/chrp functions are conditional compiled on CONFIG_8xx
- * to reduce code space and undefined function references.
*/
@@ -83,9 +75,6 @@
int ppc_spurious_interrupts = 0;
struct irqaction *ppc_irq_action[NR_IRQS];
-unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
-unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
-atomic_t ppc_n_lost_interrupts;
unsigned long lpEvent_count = 0;
#ifdef CONFIG_XMON
extern void xmon(struct pt_regs *regs);
@@ -538,22 +527,18 @@
/* every arch is required to have a get_irq -- Cort */
irq = ppc_md.get_irq( regs );
- if ( irq < 0 )
- {
+ if ( irq >= 0 ) {
+ ppc_irq_dispatch_handler( regs, irq );
+ if (ppc_md.post_irq)
+ ppc_md.post_irq( regs, irq );
+ } else {
/* -2 means ignore, already handled */
- if (irq != -2)
- {
+ if (irq != -2) {
printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
- irq, regs->nip);
+ irq, regs->nip);
ppc_spurious_interrupts++;
}
- goto out;
}
- ppc_irq_dispatch_handler( regs, irq );
- if (ppc_md.post_irq)
- ppc_md.post_irq( regs, irq );
-
- out:
}
/* if on iSeries partition */
else {
@@ -565,7 +550,7 @@
}
#endif /* CONFIG_SMP */
lpq = paca->lpQueuePtr;
- if ( lpq )
+ if ( lpq && ItLpQueue_isLpIntPending( lpq ) )
lpEvent_count += ItLpQueue_process( lpq, regs );
}
@@ -610,6 +595,7 @@
once++;
ppc_md.init_IRQ();
+ if(ppc_md.init_ras_IRQ) ppc_md.init_ras_IRQ();
}
#ifdef CONFIG_SMP
@@ -779,7 +765,7 @@
{
if (count < HEX_DIGITS+1)
return -EINVAL;
- return sprintf (page, "%08x\n", irq_affinity[(int)data]);
+ return sprintf (page, "%08x\n", irq_affinity[(int)(long)data]);
}
static unsigned int parse_hex_value (const char *buffer,
@@ -822,7 +808,7 @@
static int irq_affinity_write_proc (struct file *file, const char *buffer,
unsigned long count, void *data)
{
- int irq = (int) data, full_count = count, err;
+ int irq = (int)(long) data, full_count = count, err;
unsigned long new_value;
if (!irq_desc[irq].handler->set_affinity)
@@ -890,7 +876,7 @@
entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
entry->nlink = 1;
- entry->data = (void *)irq;
+ entry->data = (void *)(long)irq;
entry->read_proc = irq_affinity_read_proc;
entry->write_proc = irq_affinity_write_proc;
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/lmb.c linuxppc64_2_4/arch/ppc64/kernel/lmb.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/lmb.c Tue Oct 16 16:54:41 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/lmb.c Tue Sep 25 13:52:29 2001
@@ -17,6 +17,7 @@
#include
#include
#include
+#include
extern unsigned long klimit;
extern unsigned long reloc_offset(void);
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/local_irq.h linuxppc64_2_4/arch/ppc64/kernel/local_irq.h
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/local_irq.h Tue Oct 16 16:54:41 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/local_irq.h Sat Sep 15 22:35:39 2001
@@ -22,8 +22,5 @@
extern int ppc_spurious_interrupts;
extern int ppc_second_irq;
extern struct irqaction *ppc_irq_action[NR_IRQS];
-extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
-extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
-extern atomic_t ppc_n_lost_interrupts;
#endif /* _PPC_KERNEL_LOCAL_IRQ_H */
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/mf.c linuxppc64_2_4/arch/ppc64/kernel/mf.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/mf.c Tue Oct 16 16:54:41 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/mf.c Tue Sep 25 13:52:29 2001
@@ -41,6 +41,7 @@
#include
#include
+extern struct pci_dev * iSeries_vio_dev;
/*
* This is the structure layout for the Machine Facilites LPAR event
@@ -289,7 +290,7 @@
if( newElement == NULL )
{
- printk( KERN_ERR "mf.c: unable to kmalloc %d bytes\n", sizeof(struct StackElement) );
+ printk( KERN_ERR "mf.c: unable to kmalloc %ld bytes\n", sizeof(struct StackElement) );
return NULL;
}
@@ -880,7 +881,7 @@
struct VspCmdData myVspCmd;
int rc = 0;
dma_addr_t dma_addr = 0;
- char *page = pci_alloc_consistent(NULL, size, &dma_addr);
+ char *page = pci_alloc_consistent(iSeries_vio_dev, size, &dma_addr);
if (page == NULL) {
printk(KERN_ERR "mf.c: couldn't allocate memory to set command line\n");
@@ -898,7 +899,7 @@
mb();
rc = signalVspInstruction(&myVspCmd);
- pci_free_consistent(NULL, size, page, dma_addr);
+ pci_free_consistent(iSeries_vio_dev, size, page, dma_addr);
}
int mf_getCmdLine(char *cmdline, int *size, u64 side)
@@ -906,7 +907,7 @@
struct VspCmdData myVspCmd;
int rc = 0;
int len = *size;
- dma_addr_t dma_addr = pci_map_single(NULL, cmdline, *size, PCI_DMA_FROMDEVICE);
+ dma_addr_t dma_addr = pci_map_single(iSeries_vio_dev, cmdline, *size, PCI_DMA_FROMDEVICE);
memset(cmdline, 0, *size);
memset(&myVspCmd, 0, sizeof(myVspCmd));
@@ -931,7 +932,7 @@
*/
}
- pci_unmap_single(NULL, dma_addr, *size, PCI_DMA_FROMDEVICE);
+ pci_unmap_single(iSeries_vio_dev, dma_addr, *size, PCI_DMA_FROMDEVICE);
return len;
}
@@ -944,7 +945,7 @@
dma_addr_t dma_addr = 0;
- char *page = pci_alloc_consistent(NULL, size, &dma_addr);
+ char *page = pci_alloc_consistent(iSeries_vio_dev, size, &dma_addr);
if (page == NULL) {
printk(KERN_ERR "mf.c: couldn't allocate memory to set vmlinux chunk\n");
@@ -975,7 +976,7 @@
}
}
- pci_free_consistent(NULL, size, page, dma_addr);
+ pci_free_consistent(iSeries_vio_dev, size, page, dma_addr);
return rc;
}
@@ -986,7 +987,7 @@
int rc = 0;
int len = *size;
- dma_addr_t dma_addr = pci_map_single(NULL, buffer, *size, PCI_DMA_FROMDEVICE);
+ dma_addr_t dma_addr = pci_map_single(iSeries_vio_dev, buffer, *size, PCI_DMA_FROMDEVICE);
memset(buffer, 0, len);
@@ -1012,7 +1013,7 @@
}
}
- pci_unmap_single(NULL, dma_addr, *size, PCI_DMA_FROMDEVICE);
+ pci_unmap_single(iSeries_vio_dev, dma_addr, *size, PCI_DMA_FROMDEVICE);
return rc;
}
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/misc.S linuxppc64_2_4/arch/ppc64/kernel/misc.S
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/misc.S Tue Oct 16 16:54:41 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/misc.S Mon Oct 8 20:27:39 2001
@@ -63,14 +63,11 @@
mr r3,r1
blr
-_GLOBAL(get_paca)
- mfspr r3,SPRG3;
- blr
-
-/* void __no_use_save_flags(unsigned long *flags) */
+#ifdef CONFIG_PPC_ISERIES
+/* unsigned long __no_use_save_flags(void) */
_GLOBAL(__no_use_save_flags)
- mfmsr r4
- std r4,0(r3)
+ mfspr r4,SPRG3
+ lbz r3,PACAPROCENABLED(r4)
blr
/* void __no_use_restore_flags(unsigned long flags) */
@@ -81,125 +78,54 @@
* sense anyway.
* -- Cort
*/
- mfmsr r5
- mr r4,r3
- mr r3,r5
- rlwimi r3,r4,0,16,16
- /* Copy all except the MSR_EE bit from r4 (current MSR value)
- to r3. This is the sort of thing the rlwimi instruction is
- designed for. -- paulus. */
+ mfspr r6,SPRG3
+ lbz r5,PACAPROCENABLED(r6)
/* Check if things are setup the way we want _already_. */
cmpw 0,r3,r5
beqlr
/* are we enabling interrupts? */
- rlwinm. r0,r3,0,16,16
- beq 1f
- /* Check pending interrupts
- * A decrementer, IPI or PMC interrupt may have occurred
- * while we were in the hypervisor (which enables)
- */
+ cmpi 0,r3,0
+ stb r3,PACAPROCENABLED(r6)
+ beqlr
+ /* Check pending interrupts */
CHECKANYINT(r4,r5)
- beq+ 1f
+ beqlr
/*
* Handle pending interrupts in interrupt context
*/
- mtmsrd r3
li r0,0x5555
- sc
- blr
-1:
- sync
- mtmsrd r3
- isync
- blr
-/* void __no_lpq_restore_flags(unsigned long flags) */
-_GLOBAL(__no_lpq_restore_flags)
- mfmsr r5
- mr r4,r3
- mr r3,r5
- rlwimi r3,r4,0,16,16
- /* Copy all except the MSR_EE bit from r4 (current MSR value)
- to r3. This is the sort of thing the rlwimi instruction is
- designed for. -- paulus. */
- /* Check if things are setup the way we want _already_. */
- cmpw 0,r3,r5
- beqlr
- sync
- mtmsrd r3
- isync
+ sc
blr
_GLOBAL(__no_use_cli)
- mfmsr r0 /* Get current interrupt state */
- rlwinm r3,r0,16+1,32-1,31 /* Extract old value of 'EE' */
- rldicl r0,r0,48,1
- rldicl r0,r0,16,0 /* clear MSR_EE in r0 */
- mtmsrd r0 /* Update machine state */
+ mfspr r5,SPRG3
+ lbz r3,PACAPROCENABLED(r5)
+ li r4,0
+ stb r4,PACAPROCENABLED(r5)
blr /* Done */
_GLOBAL(__no_use_sti)
- mfmsr r3 /* Get current state */
- ori r3,r3,MSR_EE /* Turn on 'EE' bit */
+ mfspr r6,SPRG3
+ li r3,1
+ stb r3,PACAPROCENABLED(r6)
/* Check for pending interrupts
* A decrementer, IPI or PMC interrupt may have occurred
* while we were in the hypervisor (which enables)
*/
CHECKANYINT(r4,r5)
- beq+ 1f
+ beqlr
/*
* Handle pending interrupts in interrupt context
*/
- mtmsrd r3
li r0,0x5555
sc
blr
-1:
- sync /* Some chip revs have problems here... */
- mtmsrd r3 /* Update machine state */
- blr
-
-/*
- * We were about to enable interrupts but we have to simulate
- * some interrupts that were lost by enable_irq first.
- */
-#if 0
-_GLOBAL(do_fake_interrupt)
- mflr r0
- std r0,16(r1)
- std r3,-8(r1)
- stdu r1,-(STACK_FRAME_OVERHEAD+16)(r1)
-1: bl .fake_interrupt
- /* Check for pending interrupt
- * A decrementer, IPI or PMC interrupt may have occurred
- * while we were in the hypervisor (which enables)
- */
- CHECKANYINT(r4,r5)
- bne- 1b
- addi r1,r1,STACK_FRAME_OVERHEAD+16
- ld r3,-8(r1)
- ld r0,16(r1)
- mtlr r0
- mtmsrd r3
- blr
-#endif
-/*
- * complement mask on the msr then "or" some values on.
- * _nmask_and_or_msr(nmask, value_to_or)
- */
-_GLOBAL(_nmask_and_or_msr)
- mfmsr r0 /* Get current msr */
- andc r0,r0,r3 /* And off the bits set in r3 (first parm) */
- or r0,r0,r4 /* Or on the bits in r4 (second parm) */
- mtmsrd r0 /* Update machine state */
- SYNC
- blr /* Done */
-
+#endif
/*
* Flush instruction cache.
- * This is a no-op on the 601.
*/
_GLOBAL(flush_instruction_cache)
@@ -210,15 +136,13 @@
* the cache lines that are actually
* modified
*/
- mfspr r3,PVR
- rlwinm r3,r3,16,16,31
- cmpi 0,r3,1
- beqlr /* for 601, do nothing */
- /* 603/604 processor - use invalidate-all bit in HID0 */
+ /* use invalidate-all bit in HID0
+ * - is this consistent across all 64-bit cpus? -- paulus */
mfspr r3,HID0
ori r3,r3,HID0_ICFI
mtspr HID0,r3
- SYNC
+ sync
+ isync
blr
/*
@@ -269,7 +193,6 @@
2: icbi 0,r6
add r6,r6,r7
bdnz 2b
- sync
isync
blr
@@ -308,11 +231,10 @@
* Flush a particular page from the data cache to RAM.
* Note: this is necessary because the instruction cache does *not*
* snoop from the data cache.
- * This is a no-op on the 601 which has a unified cache.
*
- * void __flush_page_to_ram(void *page)
+ * void __flush_dcache_icache(void *page)
*/
-_GLOBAL(__flush_page_to_ram)
+_GLOBAL(__flush_dcache_icache)
/*
* Flush the data cache to memory
*
@@ -340,130 +262,26 @@
1: icbi 0,r3
add r3,r3,r5
bdnz 1b
- sync
- isync
- blr
-
-
-/*
- * Flush a particular page from the instruction cache.
- * Note: this is necessary because the instruction cache does *not*
- * snoop from the data cache.
- *
- * void __flush_icache_page(void *page)
- */
-_GLOBAL(__flush_icache_page)
-/*
- * Different systems have different cache line sizes
- */
-
-/* Invalidate the icache */
-
- LOADADDR(r6,naca)
- ld r6,0(r6)
- clrrdi r3,r3,12 /* Page align */
- lhz r4,ICACHEL1LINESPERPAGE(r6) /* Get # icache lines per page */
- lhz r5,ICACHEL1LINESIZE(r6) /* Get icache line size */
- mtctr r4
-1: icbi 0,r3
- add r3,r3,r5
- bdnz 1b
- sync
isync
blr
/*
- * Clear a page using the dcbz instruction, which doesn't cause any
- * memory traffic (except to write out any cache lines which get
- * displaced). This only works on cacheable memory.
+ * Copy a whole page. Assumes a 4096B page size.
*/
-_GLOBAL(clear_page)
- LOADADDR(r6,naca)
- ld r6,0(r6)
- clrrdi r3,r3,12 /* Page align */
- lhz r4,DCACHEL1LINESPERPAGE(r6) /* Get # dcache lines per page */
- lhz r5,DCACHEL1LINESIZE(r6) /* Get dcache line size */
- mtctr r4
-0: dcbz 0,r3
- add r3,r3,r5
- bdnz 0b
- blr
-
-/*
- * Copy a whole page. We use the dcbz instruction on the destination
- * to reduce memory traffic (it eliminates the unnecessary reads of
- * the destination into cache). This requires that the destination
- * is cacheable.
- */
-#define COPY_32_BYTES \
- ld r6,8(r4); \
- ld r7,16(r4); \
- ld r8,24(r4); \
- ldu r9,32(r4); \
- std r6,8(r3); \
- std r7,16(r3); \
- std r8,24(r3); \
- stdu r9,32(r3)
-
_GLOBAL(copy_page)
-
- LOADADDR(r9,naca)
- ld r9,0(r9)
clrrdi r3,r3,12 /* Page align */
clrrdi r4,r4,12 /* Page align */
- lhz r5,DCACHEL1LINESPERPAGE(r9) /* Get # dcache lines per page */
- lhz r0,DCACHEL1LINESIZE(r9) /* Get dcache line size */
+ li r5,256
mtctr r5
addi r3,r3,-8
addi r4,r4,-8
- li r10,8
-
- cmpi 0,r0,32
- beq do_32_byte_line
- cmpi 0,r0,64
- beq do_64_byte_line
- cmpi 0,r0,128
- beq do_128_byte_line
-
- /* We don't have code specifically for this cache line size */
- /* Assume that the cache line size is at least 32 (and of */
- /* course a multiple of 32) */
- /* This code will work for all power-of-2 cache line sizes */
- /* from 32 to 4096 */
-
-1: mr r5,r0
- dcbz r10,r3
-0: COPY_32_BYTES
- addi r5,r5,-32
- or. r5,r5,r5
- bne 0b
- bdnz 1b
- blr
- .globl do_32_byte_line
-do_32_byte_line:
- dcbz r10,r3
- COPY_32_BYTES
- bdnz do_32_byte_line
- blr
-
- .globl do_64_byte_line
-do_64_byte_line:
- dcbz r10,r3
- COPY_32_BYTES
- COPY_32_BYTES
- bdnz do_64_byte_line
- blr
-
- .globl do_128_byte_line
-do_128_byte_line:
- dcbz r10,r3
- COPY_32_BYTES
- COPY_32_BYTES
- COPY_32_BYTES
- COPY_32_BYTES
- bdnz do_128_byte_line
- blr
+1: ld r6,8(r4)
+ ldu r7,16(r4)
+ std r6,8(r3)
+ stdu r7,16(r3)
+ bdnz+ 1b
+ blr
/*
* I/O string operations
@@ -647,20 +465,14 @@
mfspr r3,PVR
blr
-_GLOBAL(_get_HID0)
- mfspr r3,HID0
- blr
-
-_GLOBAL(_get_ICTC)
- mfspr r3,ICTC
+_GLOBAL(_get_PIR)
+ mfspr r3,PIR
blr
-_GLOBAL(_set_ICTC)
- mtspr ICTC,r3
+_GLOBAL(_get_HID0)
+ mfspr r3,HID0
blr
-
-
_GLOBAL(cvt_fd)
lfd 0,-4(r5) /* load up fpscr value */
mtfsf 0xff,0
@@ -679,15 +491,6 @@
stfd 0,-4(r5)
blr
-_GLOBAL(__clear_msr_me)
- mfmsr r0 /* Get current interrupt state */
- lis r3,0
- ori r3,r3,MSR_ME
- andc r0,r0,r3 /* Clears bit in (r4) */
- sync /* Some chip revs have problems here */
- mtmsrd r0 /* Update machine state */
- blr
-
/*
* Create a kernel thread
* kernel_thread(fn, arg, flags)
@@ -704,7 +507,9 @@
ld r5,PACACURRENT(r5) /* Get 'current' */
li r0,0 /* clear out p->thread.regs */
std r0,THREAD+PT_REGS(r5) /* since we don't have user ctx */
-
+ std r0,THREAD+THREAD_FLAGS(r5)
+
+ ld r2,8(r6)
ld r6,0(r6)
mtlr r6 /* fn addr in lr */
mr r3,r4 /* load arg and call fn */
@@ -713,38 +518,6 @@
li r3,0
sc
-/*
- * This routine is just here to keep GCC happy - sigh...
- */
-_GLOBAL(__main)
- blr
-
-#define SYSCALL(name) \
-_GLOBAL(name) \
- li r0,__NR_##name; \
- sc; \
- bnslr; \
- /* MIKEC: Is errno a 32-bit int or a 64-bit long ? */\
- LOADBASE(r4,errno); \
- stw r3,errno@l(r4); \
- li r3,-1; \
- blr
-
-#define __NR__exit __NR_exit
-
-SYSCALL(sync)
-SYSCALL(setsid)
-SYSCALL(write)
-SYSCALL(dup)
-SYSCALL(execve)
-SYSCALL(open)
-SYSCALL(close)
-SYSCALL(waitpid)
-SYSCALL(fork)
-SYSCALL(delete_module)
-SYSCALL(_exit)
-SYSCALL(lseek)
-SYSCALL(read)
#ifdef CONFIG_BINFMT_ELF32
/* Why isn't this a) automatic, b) written in 'C'? */
.data
@@ -899,7 +672,7 @@
.llong .sys32_writev
.llong .sys32_getsid
.llong .sys_fdatasync
- .llong .sys_sysctl
+ .llong .sys32_sysctl
.llong .sys_mlock /* 150 */
.llong .sys_munlock
.llong .sys32_mlockall
@@ -977,7 +750,7 @@
.llong .sys_unlink /* 10 */
.llong .sys_execve
.llong .sys_chdir
- .llong .sys_time
+ .llong .sys64_time
.llong .sys_mknod
.llong .sys_chmod /* 15 */
.llong .sys_lchown
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/mk_defs.c linuxppc64_2_4/arch/ppc64/kernel/mk_defs.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/mk_defs.c Tue Oct 16 16:54:41 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/mk_defs.c Thu Oct 4 01:23:47 2001
@@ -69,13 +69,17 @@
DEFINE(PACASTABREAL, offsetof(struct Paca, xStab_data.real));
DEFINE(PACASTABVIRT, offsetof(struct Paca, xStab_data.virt));
DEFINE(PACAR1, offsetof(struct Paca, xR1));
- DEFINE(PACAR21, offsetof(struct Paca, xR21));
- DEFINE(PACAR22, offsetof(struct Paca, xR22));
- DEFINE(PACACCR, offsetof(struct Paca, xCCR));
DEFINE(PACALPQUEUE, offsetof(struct Paca, lpQueuePtr));
- DEFINE(PACALPPACA, offsetof(struct Paca, xLpPaca));
DEFINE(PACATOC, offsetof(struct Paca, xTOC));
+ DEFINE(PACAEXCSP, offsetof(struct Paca, exception_sp));
+ DEFINE(PACAHRDWINTSTACK, offsetof(struct Paca, xHrdIntStack));
+ DEFINE(PACAPROCENABLED, offsetof(struct Paca, xProcEnabled));
+ DEFINE(PACAHRDWINTCOUNT, offsetof(struct Paca, xHrdIntCount));
+ DEFINE(PACADEFAULTDECR, offsetof(struct Paca, default_decr));
+ DEFINE(PACALPPACA, offsetof(struct Paca, xLpPaca));
DEFINE(LPPACA, offsetof(struct Paca, xLpPaca));
+ DEFINE(PACAREGSAV, offsetof(struct Paca, xRegSav));
+ DEFINE(PACAEXC, offsetof(struct Paca, exception_stack));
DEFINE(LPPACASRR0, offsetof(struct ItLpPaca, xSavedSrr0));
DEFINE(LPPACASRR1, offsetof(struct ItLpPaca, xSavedSrr1));
DEFINE(LPPACAANYINT, offsetof(struct ItLpPaca, xIntDword.xAnyInt));
@@ -132,6 +136,7 @@
DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3));
DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result));
DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
+ DEFINE(SOFTE, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, softe));
DEFINE(CLONE_VM, CLONE_VM);
return 0;
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/open_pic.c linuxppc64_2_4/arch/ppc64/kernel/open_pic.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/open_pic.c Tue Oct 16 16:54:41 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/open_pic.c Fri Aug 31 15:48:52 2001
@@ -87,10 +87,10 @@
*/
#ifdef CONFIG_SMP
#define THIS_CPU Processor[cpu]
-#define DECL_THIS_CPU int cpu = cpu_hw_index[smp_processor_id()]
+#define DECL_THIS_CPU int cpu = hard_smp_processor_id()
#define CHECK_THIS_CPU check_arg_cpu(cpu)
#else
-#define THIS_CPU Processor[cpu_hw_index[0]]
+#define THIS_CPU Processor[hard_smp_processor_id()]
#define DECL_THIS_CPU
#define CHECK_THIS_CPU
#endif /* CONFIG_SMP */
@@ -358,7 +358,7 @@
/* SIOint (8259 cascade) is special */
if (offset) {
openpic_initirq(0, 8, offset, 1, 1);
- openpic_mapirq(0, 1<>= 1)
- mask |= (cpumask & 1) << cpu_hw_index[i];
+ mask |= (cpumask & 1) << get_hard_smp_processor_id(i);
return mask;
}
@@ -595,7 +595,7 @@
{
#ifdef CONFIG_IRQ_ALL_CPUS
int i;
- u32 msk = 1 << cpu_hw_index[smp_processor_id()];
+ u32 msk = 1 << hard_smp_processor_id();
#endif
spin_lock(&openpic_setup_lock);
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/pSeries_hvCall.S linuxppc64_2_4/arch/ppc64/kernel/pSeries_hvCall.S
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/pSeries_hvCall.S Wed Dec 31 18:00:00 1969
+++ linuxppc64_2_4/arch/ppc64/kernel/pSeries_hvCall.S Tue Oct 16 14:58:06 2001
@@ -0,0 +1,23 @@
+/*
+ * arch/ppc64/kernel/pSeries_hvCall.S
+ *
+ *
+ * This file contains the generic code to perform a call to the
+ * pSeries LPAR hypervisor.
+ * NOTE: this file will go away when we move to inline this work.
+ *
+ * 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 "ppc_asm.h"
+
+/* no code yet */
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/pSeries_lpar.c linuxppc64_2_4/arch/ppc64/kernel/pSeries_lpar.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/pSeries_lpar.c Wed Dec 31 18:00:00 1969
+++ linuxppc64_2_4/arch/ppc64/kernel/pSeries_lpar.c Sat Oct 6 16:03:54 2001
@@ -0,0 +1,26 @@
+/*
+ * pSeries_lpar.c
+ * Copyright (C) 2001 Todd Inglett, IBM Corporation
+ *
+ * pSeries LPAR support.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* NOTE: only stubs for linking at this time. */
+void pSeriesLP_init_early(void) {}
+void make_pte_LPAR(void) {}
+
+struct { void *a, *b, *d, *e; } pSeriesLP_ops = {0, 0, 0, 0};
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/pSeries_pci.c linuxppc64_2_4/arch/ppc64/kernel/pSeries_pci.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/pSeries_pci.c Tue Oct 16 16:54:41 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/pSeries_pci.c Sat Sep 29 13:40:48 2001
@@ -46,18 +46,7 @@
#include "open_pic.h"
#include "pci.h"
-/* Supporting macros *********************************************/
-#define TESTBIT(value,bits) ((value&bits) == bits)
-#define TRUE 1
-#define FALSE 0
-
-extern struct pci_controller* hose_head;
-extern struct pci_controller** hose_tail;
-extern struct Naca *naca;
-extern struct pci_ops rtas_pci_ops;
-extern struct pci_ops ibm_phb_pci_ops;
extern struct device_node *allnodes;
-extern unsigned long phb_tce_table_init(struct pci_controller *phb);
/*******************************************************************
* Forward declares of prototypes.
@@ -65,33 +54,72 @@
unsigned long find_and_init_phbs(void);
struct pci_controller* alloc_phb(struct device_node *dev, char *model, unsigned int addr_size_words) ;
void pSeries_pcibios_fixup(void);
-void pci_build_bar_resources(struct pci_dev* Pci_Dev, int BarCount);
-void pci_build_rom_resources(struct pci_dev* Pci_Dev);
-void pci_set_BARS(struct pci_dev* Pci_Dev);
+static int rtas_fake_read(struct device_node *dn, int offset, int nbytes, unsigned long *returnval);
/**********************************************************************************
*
* pSeries I/O Operations to access the PCI configuration space.
*
**********************************************************************************/
-#define RTAS_PCI_READ_OP(size, type, nbytes) \
-int __chrp \
-rtas_read_config_##size(struct pci_dev *dev, int offset, type val) { \
- unsigned long ReturnValue, ConfigAddr; \
- int ReturnCode; \
- ConfigAddr = ((dev->bus->number&0x0000FF) << 16) | (dev->devfn << 8) | (offset & 0xff); \
- ReturnCode = call_rtas("read-pci-config", 2, 2, &ReturnValue, ConfigAddr, nbytes);\
- *val = ReturnValue; \
- return ReturnCode; \
-}
-#define RTAS_PCI_WRITE_OP(size, type, nbytes) \
-int __chrp \
-rtas_write_config_##size(struct pci_dev *dev, int offset, type val) { \
- unsigned long ConfigAddr; \
- int ReturnCode; \
- ConfigAddr = ((dev->bus->number&0x0000FF) << 16) | (dev->devfn << 8) | (offset & 0xff); \
- ReturnCode = call_rtas("write-pci-config", 3, 1, NULL, ConfigAddr, nbytes, (ulong)val); \
- return ReturnCode; \
+#define RTAS_PCI_READ_OP(size, type, nbytes) \
+int __chrp \
+rtas_read_config_##size(struct device_node *dn, int offset, type val) { \
+ unsigned long returnval = ~0L; \
+ unsigned long buid; \
+ unsigned int addr; \
+ int ret; \
+ \
+ if (dn == NULL) { \
+ ret = -2; \
+ } else if (dn->status) { \
+ ret = -1; \
+ } else { \
+ addr = (dn->busno << 16) | (dn->devfn << 8) | offset; \
+ buid = dn->phb->buid; \
+ if (buid) { \
+ ret = call_rtas("ibm,read-pci-config", 4, 2, &returnval, addr, buid >> 32, buid & 0xffffffff, nbytes); \
+ if (ret == -4) \
+ ret = rtas_fake_read(dn, offset, nbytes, &returnval); \
+ } else { \
+ ret = call_rtas("read-pci-config", 2, 2, &returnval, addr, nbytes); \
+ } \
+ } \
+ *val = returnval; \
+ return ret; \
+} \
+int __chrp \
+rtas_pci_read_config_##size(struct pci_dev *dev, int offset, type val) { \
+ struct device_node *dn = pci_device_to_OF_node(dev); \
+ int ret = rtas_read_config_##size(dn, offset, val); \
+ /* udbg_printf("read bus=%x, devfn=%x, ret=%d phb=%lx, dn=%lx\n", dev->bus->number, dev->devfn, ret, dn ? dn->phb : 0, dn); */ \
+ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; \
+}
+
+#define RTAS_PCI_WRITE_OP(size, type, nbytes) \
+int __chrp \
+rtas_write_config_##size(struct device_node *dn, int offset, type val) { \
+ unsigned long buid; \
+ unsigned int addr; \
+ int ret; \
+ \
+ if (dn == NULL) { \
+ ret = -2; \
+ } else if (dn->status) { \
+ ret = -1; \
+ } else { \
+ buid = dn->phb->buid; \
+ addr = (dn->busno << 16) | (dn->devfn << 8) | offset; \
+ if (buid) { \
+ ret = call_rtas("ibm,write-pci-config", 5, 1, NULL, addr, buid >> 32, buid & 0xffffffff, nbytes, (ulong) val); \
+ } else { \
+ ret = call_rtas("write-pci-config", 3, 1, NULL, addr, nbytes, (ulong)val); \
+ } \
+ } \
+ return ret; \
+} \
+int __chrp \
+rtas_pci_write_config_##size(struct pci_dev *dev, int offset, type val) { \
+ return rtas_write_config_##size(pci_device_to_OF_node(dev), offset, val); \
}
RTAS_PCI_READ_OP(byte, u8 *, 1)
@@ -102,73 +130,54 @@
RTAS_PCI_WRITE_OP(dword, u32, 4)
struct pci_ops rtas_pci_ops = {
- rtas_read_config_byte,
- rtas_read_config_word,
- rtas_read_config_dword,
- rtas_write_config_byte,
- rtas_write_config_word,
- rtas_write_config_dword,
- pci_read_bar_registers,
- pci_read_irq_line
+ rtas_pci_read_config_byte,
+ rtas_pci_read_config_word,
+ rtas_pci_read_config_dword,
+ rtas_pci_write_config_byte,
+ rtas_pci_write_config_word,
+ rtas_pci_write_config_dword,
};
-/**********************************************************************************
- *
- * pSeries I/O Operations to access the PCI configuration space.
- * This is the support for Large Systems(>256 buses).
- *
- **********************************************************************************/
-#define RTAS64_PCI_READ_OP(size, type, nbytes) \
-int __chrp \
-rtas64_read_config_##size(struct pci_dev *dev, int offset, type val) \
-{ \
- struct pci_controller *hose = dev->sysdata; \
- unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) \
- | (((dev->bus->number) & 0xff) << 16); \
- unsigned long ret = ~0UL; \
- int rval; \
- int buidhi = hose->buid >> 32; \
- int buidlo = hose->buid & 0xffffffff; \
- \
- rval = call_rtas("ibm,read-pci-config", 4, 2, &ret, \
- addr, buidhi, buidlo, nbytes); \
- *val = ret; \
- /* udbg_printf("%08x %08x SYM Read Config %d\n",addr, ret,rval); */ \
- return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; \
-}
+/*
+ * Handle the case where rtas refuses to do a pci config read.
+ * This currently only happens with some PHBs in which case we totally fake
+ * out the values (and call it a speedwagaon -- something we could look up in the
+ * device tree).
+ */
+static int
+rtas_fake_read(struct device_node *dn, int offset, int nbytes, unsigned long *returnval)
+{
+ char *device_type = (char *)get_property(dn, "device_type", 0);
+ u32 *class_code = (u32 *)get_property(dn, "class-code", 0);
-#define RTAS64_PCI_WRITE_OP(size, type, nbytes) \
-int __chrp \
-rtas64_write_config_##size(struct pci_dev *dev, int offset, type val) \
-{ \
- struct pci_controller *hose = dev->sysdata; \
- unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) \
- | (((dev->bus->number) & 0xff) << 16); \
- int rval; \
- int buidhi = hose->buid >> 32; \
- int buidlo = hose->buid & 0xffffffff; \
- \
- rval = call_rtas("ibm,write-pci-config", 5, 1, NULL, \
- addr, buidhi, buidlo, nbytes, (ulong)val); \
- /* udbg_printf("%08x %08x SYM Write Config %d\n",addr, val,rval); */ \
- return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; \
-}
+ *returnval = ~0; /* float by default */
-RTAS64_PCI_READ_OP(byte, u8 *, 1)
-RTAS64_PCI_READ_OP(word, u16 *, 2)
-RTAS64_PCI_READ_OP(dword, u32 *, 4)
-RTAS64_PCI_WRITE_OP(byte, u8, 1)
-RTAS64_PCI_WRITE_OP(word, u16, 2)
-RTAS64_PCI_WRITE_OP(dword, u32, 4)
-
-struct pci_ops rtas64_pci_ops = {
- rtas64_read_config_byte,
- rtas64_read_config_word,
- rtas64_read_config_dword,
- rtas64_write_config_byte,
- rtas64_write_config_word,
- rtas64_write_config_dword
-};
+ /* udbg_printf("rtas_fake_read dn=%p, offset=0x%02x, nbytes=%d, device_type=%s\n", dn, offset, nbytes, device_type ? device_type : ""); */
+ if (class_code || (device_type && strcmp(device_type, "pci") != 0))
+ return -3; /* Not a phb. We don't fake anything else (yet) */
+
+ if (nbytes == 1) {
+ if (offset == PCI_HEADER_TYPE)
+ *returnval = 0x80; /* multifunction */
+ else if (offset == PCI_INTERRUPT_PIN || offset == PCI_INTERRUPT_LINE)
+ *returnval = 0;
+ } else if (nbytes == 2) {
+ if (offset == PCI_SUBSYSTEM_VENDOR_ID || offset == PCI_SUBSYSTEM_ID)
+ *returnval = 0;
+ else if (offset == PCI_COMMAND)
+ *returnval = PCI_COMMAND_PARITY|PCI_COMMAND_MASTER|PCI_COMMAND_MEMORY;
+ } else if (nbytes == 4) {
+ if (offset == PCI_VENDOR_ID)
+ *returnval = 0x1014 | (0x102 << 16); /* a phb */
+ else if (offset == PCI_REVISION_ID)
+ *returnval = PCI_CLASS_BRIDGE_HOST << 16; /* revs are zero */
+ else if ((offset >= PCI_BASE_ADDRESS_0 && offset <= PCI_BASE_ADDRESS_5) || offset == PCI_ROM_ADDRESS)
+ *returnval = 0;
+ }
+
+ /* udbg_printf("rtas_fake_read returning value %lx\n", *returnval); */
+ return 0;
+}
/******************************************************************
@@ -204,216 +213,6 @@
PPCDBG(PPCDBG_BUSWALK,"\tDevice: %s pci_dev->irq = 0x%02X\n",Pci_Dev->slot_name,Pci_Dev->irq);
return 0;
}
-/******************************************************************
- * pci_set_BARS
- *
- * Sets the IOA BAR registers from the values from the register
- * values found in the OpenFirmware node for the device. Or in
- * the future, assigns space in phb and sets the values.
- ******************************************************************/
-void
-pci_set_BARS(struct pci_dev* Pci_Dev) {
- int AddrIndex;
- struct device_node *Device_Node = pci_device_to_OF_node(Pci_Dev);
-
- if(Device_Node == 0 || Device_Node->n_addrs == 0 || Device_Node->addrs == NULL) {
- PPCDBG(PPCDBG_BUSWALK, "\tDevice Node was not found or no defined bars\n");
- return;
- }
- PPCDBG(PPCDBG_BUSWALK, "\tSet Bar Regs(%d)\n",Device_Node->n_addrs);
- for(AddrIndex = 0; AddrIndex < Device_Node->n_addrs; ++AddrIndex) {
- int PciReg = (Device_Node->addrs[AddrIndex].space & 0x000000FF);
- u32 PciBar = Device_Node->addrs[AddrIndex].address;
- int BarSze = Device_Node->addrs[AddrIndex].size;
-
- PPCDBG(PPCDBG_BUSWALK, "\tPciBar 0x%02X, 0x%08X, 0x%08X\n",PciReg,PciBar,BarSze);
- pci_write_config_dword(Pci_Dev, PciReg,PciBar);
- }
-}
-/******************************************************************
- *
- * pci_build_bar_registers
- *
- * This function will build the resources based on the information
- * that is extracted from the BAR register. The original BAR value
- * is saved and restored.
- *
- * Note: This is pSeries brand specific code.
- * In the future, this code will be setting the initial BAR
- * value and handing out the memory space in the PHB.
- ******************************************************************/
-void
-pci_build_bar_resources(struct pci_dev* Pci_Dev, int Count) {
- int BarRegister = PCI_BASE_ADDRESS_0;
- int EndingBar = BarRegister + (Count*4);
- int ResourceIndex = 0;
- PPCDBG(PPCDBG_BUSWALK, "\npci_read_bar_registers %s\n",Pci_Dev->slot_name);
-
- /**************************************************************
- * Read Bars until the ending bar has been read.
- **************************************************************/
- for(BarRegister = PCI_BASE_ADDRESS_0;BarRegister <= EndingBar; BarRegister += 4) {
- struct resource* Resource = &Pci_Dev->resource[ResourceIndex];
- u32 BarSaveArea, BarSizeBits, BarSize;
- u64 BarStart;
- /**********************************************************
- * Save the original bar value and check for success.
- **********************************************************/
- if((pci_read_config_dword( Pci_Dev, BarRegister, &BarSaveArea) != 0) ||
- (BarSaveArea == 0xFFFFFFFF )) {
- BarRegister += 4;
- continue;
- }
- /**********************************************************
- * Write all ones to register to get the size of area.
- **********************************************************/
- pci_write_config_dword(Pci_Dev, BarRegister, 0xFFFFFFFF);
- pci_read_config_dword( Pci_Dev, BarRegister, &BarSizeBits);
- pci_write_config_dword(Pci_Dev, BarRegister, BarSaveArea);
-
- /**********************************************************
- * Error reading bar(all ones back) or unimplemented BAR(zero)
- **********************************************************/
- if(( BarSizeBits == 0xFFFFFFFF ) || BarSizeBits == 0 ) {
- BarRegister += 4;
- continue;
- }
- Resource->name = Pci_Dev->name;
- /**********************************************************
- * Test and read Io Space, It is always 32 bits.
- **********************************************************/
- if(TESTBIT(BarSizeBits,PCI_BASE_ADDRESS_SPACE_IO) == TRUE) {
- BarSize = (~(BarSizeBits&PCI_BASE_ADDRESS_IO_MASK)) +1;
- Resource->flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO;
- Resource->start = BarSaveArea & PCI_BASE_ADDRESS_IO_MASK;
- Resource->end = Resource->start + BarSize - 1;
- ++ResourceIndex;
- }
- /**********************************************************
- * Memory Space, could be 32 bits or 64 bits
- **********************************************************/
- else {
- Resource->flags = IORESOURCE_MEM;
- if( TESTBIT(BarSizeBits,PCI_BASE_ADDRESS_MEM_PREFETCH) == TRUE) {
- Resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
- }
- BarStart = BarSaveArea &PCI_BASE_ADDRESS_MEM_MASK;
- BarSize = ~((BarSizeBits)&PCI_BASE_ADDRESS_MEM_MASK)+1;
- /**********************************************************
- * 64 bit register, read next register to get the high 32
- * bits. PCI Spec says to write both and THEN read.
- **********************************************************/
- if( TESTBIT(BarSizeBits,PCI_BASE_ADDRESS_MEM_TYPE_64) == TRUE) {
- u64 High64Bits;
- u32 BarHigh64Save;
- Resource->flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
- BarRegister += 4; /* Index to next Bar */
- pci_read_config_dword( Pci_Dev, BarRegister, &BarHigh64Save);
- High64Bits = BarHigh64Save;
- BarStart += (High64Bits<< 32);
- pci_write_config_dword(Pci_Dev, BarRegister-4,0xFFFFFFFF);
- pci_write_config_dword(Pci_Dev, BarRegister, 0xFFFFFFFF);
- pci_read_config_dword( Pci_Dev, BarRegister-4,&BarSizeBits);
- BarSize = ~((BarSizeBits)&PCI_BASE_ADDRESS_MEM_MASK)+1;
- pci_read_config_dword( Pci_Dev, BarRegister, &BarSizeBits);
- High64Bits = ~(BarSizeBits);
- BarSize += (High64Bits << 32);
- pci_write_config_dword(Pci_Dev, BarRegister-4,BarSaveArea);
- pci_write_config_dword(Pci_Dev, BarRegister, BarHigh64Save);
- ++ResourceIndex; /* Skip next resource */
- }
- /**********************************************************
- * Set resource fields with values.
- **********************************************************/
- Resource->start = BarStart;
- Resource->end = BarStart + BarSize - 1;
- ++ResourceIndex;
- }
- }
- PPCDBGCALL(PPCDBG_BUSWALK, dumpPci_Dev(Pci_Dev) );
-}
-/******************************************************************
- *
- * Read the rom register
- *
- ******************************************************************/
-void
-pci_build_rom_resources(struct pci_dev* Pci_Dev) {
- u32 RomSaveArea, RomSizeBits;
- u64 RomSize = 0;
- struct resource* Resource = &Pci_Dev->resource[PCI_ROM_RESOURCE];
- PPCDBG(PPCDBG_BUSWALK, "\tpci_read_bar_Rom \n");
-
- pci_read_config_dword( Pci_Dev, PCI_ROM_ADDRESS, &RomSaveArea);
- pci_write_config_dword(Pci_Dev, PCI_ROM_ADDRESS, 0XFFFFFFFF);
- pci_read_config_dword( Pci_Dev, PCI_ROM_ADDRESS, &RomSizeBits);
- pci_write_config_dword(Pci_Dev, PCI_ROM_ADDRESS, RomSaveArea);
-
- if( (RomSizeBits&PCI_ROM_ADDRESS_ENABLE) == PCI_ROM_ADDRESS_ENABLE) {
- RomSize = ~(RomSizeBits) & PCI_ROM_ADDRESS_MASK;
- if(RomSize > 0) {
- Resource->name = Pci_Dev->name;
- Resource->flags = IORESOURCE_MEM | IORESOURCE_READONLY | IORESOURCE_PREFETCH;
- Resource->start = RomSaveArea;
- Resource->end = Resource->start + RomSize - 1;
- }
- }
-}
-/******************************************************************
- *
- * pci_read_bar_registers
- *
- * This function is the hook from the independant code to the arch
- * dependant code to set and read the BAR registers.
- *
- * Note: This is pSeries brand specific code.
- * In the future, this code will be setting the initial BAR
- * value and handing out the PBH memory space.
- ******************************************************************/
-int
-pci_read_bar_registers(struct pci_dev* Pci_Dev, int Count, int RomFlag) {
- u16 Pci_Command_Register_Save = 0;
- u16 Pci_Mask_Reg;
- /**************************************************************
- * If Io or Memory is enabled, disable while the BARs are being
- * changed to avoid any side affects.
- **************************************************************/
- if(( pci_read_config_word( Pci_Dev, PCI_COMMAND, &Pci_Command_Register_Save) != 0 ) ||
- (Pci_Command_Register_Save == (u16)0xFFFF) ) {
- printk("PCI: Device %s Read Command Failed.\n",Pci_Dev->slot_name);
- PPCDBG(PPCDBG_BUSWALK,"\tDevice %s Read Command Failed.\n",Pci_Dev->slot_name);
- return -1;
- }
- Pci_Mask_Reg = Pci_Command_Register_Save &(PCI_COMMAND_IO|PCI_COMMAND_MEMORY);
- if( Pci_Mask_Reg != 0) {
- u16 ResetCmdReg = Pci_Command_Register_Save & (~Pci_Mask_Reg);
- pci_write_config_word( Pci_Dev, PCI_COMMAND, ResetCmdReg);
- }
- else {
- Pci_Command_Register_Save = 0;
- }
- /**************************************************************
- * Do the base BARS.
- **************************************************************/
- pci_build_bar_resources(Pci_Dev, Count);
-
- /**************************************************************
- * Rom Flag on, read ROM BARS.
- **************************************************************/
- if(RomFlag != 0) {
- pci_build_rom_resources(Pci_Dev);
- }
-
- /**************************************************************
- * If the Command Register was modifed, restore it.
- **************************************************************/
- if(Pci_Command_Register_Save != 0) {
- pci_write_config_word( Pci_Dev, PCI_COMMAND, Pci_Command_Register_Save);
- PPCDBG(PPCDBG_BUSWALK,"\tPCI_COMMAND Register Restored 0x%04X\n",
- Pci_Command_Register_Save);
- }
- return 0;
-}
/******************************************************************
* Find all PHBs in the system and initialize a set of data
@@ -432,7 +231,6 @@
struct resource *res;
unsigned int memno, rlen, i, index;
unsigned int *opprop;
-
PPCDBG(PPCDBG_PHBINIT, "find_and_init_phbs\n");
if(naca->interrupt_controller == IC_OPEN_PIC) {
@@ -449,6 +247,11 @@
return(-1);
}
+ if (find_type_devices("isa")) {
+ isa_io_limit = 0; /* allow all ISA ports down to zero. */
+ PPCDBG(PPCDBG_PHBINIT, "\tFound an ISA bus.\n");
+ }
+
index = 0;
/******************************************************************
@@ -476,10 +279,10 @@
range_stride = this_addr_count + root_addr_size_words + this_addr_size_words;
memno = 0;
- phb->io_base_phys = 0;
+ phb->io_base_phys = 0;
ranges = (unsigned int *) get_property(Pci_Node, "ranges", &rlen);
- PPCDBG(PPCDBG_PHBINIT, "\trange_stride = 0x%lx, rlen = 0x%x\n", range_stride, rlen);
+ PPCDBG(PPCDBG_PHBINIT, "\trange_stride = 0x%lx, rlen = 0x%x\n", range_stride, rlen);
for(i = 0; i < (rlen/sizeof(*ranges)); i+=range_stride) {
/* Put the PCI addr part of the current element into a
@@ -518,21 +321,26 @@
res = NULL;
switch ((range.child_addr.a_hi >> 24) & 0x3) {
case 1: /* I/O space */
+ PPCDBG(PPCDBG_PHBINIT, "\tIO Space\n");
phb->io_base_phys = range.parent_addr;
+ phb->io_base_virt = ioremap(phb->io_base_phys, range.size);
+ if (!isa_io_base)
+ isa_io_base = (unsigned long)phb->io_base_virt;
res = &phb->io_resource;
+ res->name = Pci_Node->full_name;
res->flags = IORESOURCE_IO;
- if (isa_io_base == 0) {
- isa_io_base = (unsigned long)
- ioremap(phb->io_base_phys, range.size);
- PPCDBG(PPCDBG_PHBINIT, "\tisa_io_base = 0x%lx\n", isa_io_base);
- }
+ res->start = ((((unsigned long) range.child_addr.a_mid) << 32) | (range.child_addr.a_lo));
+ res->start += (unsigned long)phb->io_base_virt - isa_io_base;
+ res->end = res->start + range.size - 1;
+ res->parent = NULL;
+ res->sibling = NULL;
+ res->child = NULL;
phb->pci_io_offset = range.parent_addr -
((((unsigned long)
range.child_addr.a_mid) << 32) |
(range.child_addr.a_lo));
PPCDBG(PPCDBG_PHBINIT, "\tpci_io_offset = 0x%lx\n",
phb->pci_io_offset);
-
break;
case 2: /* mem space */
PPCDBG(PPCDBG_PHBINIT, "\tMem Space\n");
@@ -542,37 +350,32 @@
(range.child_addr.a_lo));
PPCDBG(PPCDBG_PHBINIT, "\tpci_mem_offset = 0x%lx\n",
phb->pci_mem_offset);
- res = &(phb->mem_resources[memno]);
- res->flags = IORESOURCE_MEM;
- ++memno;
+ if (memno < sizeof(phb->mem_resources)/sizeof(phb->mem_resources[0])) {
+ res = &(phb->mem_resources[memno]);
+ ++memno;
+ res->name = Pci_Node->full_name;
+ res->flags = IORESOURCE_MEM;
+ res->start = range.parent_addr;
+ res->end = range.parent_addr + range.size - 1;
+ res->parent = NULL;
+ res->sibling = NULL;
+ res->child = NULL;
+ }
break;
}
- if (res) {
- res->name = Pci_Node->full_name;
- res->start = range.parent_addr;
- res->end = range.parent_addr + range.size - 1;
- res->parent = NULL;
- res->sibling = NULL;
- res->child = NULL;
- }
}
PPCDBG(PPCDBG_PHBINIT, "\tphb->io_base_phys = 0x%lx\n",
phb->io_base_phys);
PPCDBG(PPCDBG_PHBINIT, "\tphb->pci_mem_offset = 0x%lx\n",
phb->pci_mem_offset);
- if(naca->interrupt_controller == IC_OPEN_PIC) {
- if(root_addr_size_words == 1) {
- openpic_setup_ISU(index, opprop[index+1]);
- } else {
- openpic_setup_ISU(index,
- ((unsigned long)opprop[(index+1)*2]) << 32 |
- opprop[(index+1)*2+1]);
- }
- }
-
+ if(naca->interrupt_controller == IC_OPEN_PIC) {
+ int addr = root_addr_size_words * (index + 2) - 1;
+ openpic_setup_ISU(index, opprop[addr]);
+ }
index++;
}
+ pci_devs_phb_init();
return 0; /*Success */
}
@@ -587,7 +390,8 @@
struct pci_controller *phb;
unsigned int *ui_ptr = NULL, len;
struct reg_property64 reg_struct;
- int *bus_range;
+ int *bus_range;
+ int *buid_vals;
PPCDBG(PPCDBG_PHBINIT, "alloc_phb: %s\n", dev->full_name);
PPCDBG(PPCDBG_PHBINIT, "\tdev = 0x%lx\n", dev);
@@ -644,19 +448,25 @@
phb = pci_alloc_pci_controller("PHB SW",phb_type_speedwagon);
if(phb == NULL) return NULL;
- phb->cfg_addr = (volatile unsigned long *)
- ioremap(reg_struct.address + 0x140, PAGE_SIZE);
- phb->cfg_data = (char*)(phb->cfg_addr - 0x02); /* minus is correct */
- phb->phb_regs = (volatile unsigned long *)
- ioremap(reg_struct.address, PAGE_SIZE);
+ if (_machine == _MACH_pSeries) {
+ phb->cfg_addr = (volatile unsigned long *)
+ ioremap(reg_struct.address + 0x140, PAGE_SIZE);
+ phb->cfg_data = (char*)(phb->cfg_addr - 0x02); /* minus is correct */
+ phb->phb_regs = (volatile unsigned long *)
+ ioremap(reg_struct.address, PAGE_SIZE);
+ /* Speedwagon's register file is 1 MB in size. */
+ phb->chip_regs = ioremap(reg_struct.address & ~(0xfffffUL),
+ 0x100000);
+ PPCDBG(PPCDBG_PHBINIT, "\tmapping chip_regs from 0x%lx -> 0x%lx\n",
+ reg_struct.address & 0xfffff, phb->chip_regs);
+ } else {
+ phb->cfg_addr = NULL;
+ phb->cfg_data = NULL;
+ phb->phb_regs = NULL;
+ phb->chip_regs = NULL;
+ }
phb->local_number = ((reg_struct.address >> 12) & 0xf) - 0x8;
-
- /* Speedwagon's register file is 1 MB in size. */
- phb->chip_regs = ioremap(reg_struct.address & ~(0xfffffUL),
- 0x100000);
- PPCDBG(PPCDBG_PHBINIT, "\tmapping chip_regs from 0x%lx -> 0x%lx\n",
- reg_struct.address & 0xfffff, phb->chip_regs);
/***************************************************************
* Trying to build a known just gets the code in trouble.
***************************************************************/
@@ -678,17 +488,34 @@
***************************************************************/
phb->first_busno = bus_range[0];
phb->last_busno = bus_range[1];
- //phb->first_busno = (phb->global_number <<8) + bus_range[0];
- //phb->last_busno = (phb->global_number <<8) + bus_range[1];
phb->arch_data = dev;
- if( Pci_Large_Bus_System == 0 ) phb->ops = &rtas_pci_ops;
- else phb->ops = &rtas64_pci_ops;
+ phb->ops = &rtas_pci_ops;
- /***************************************************************
- * Build tce table for phb
- ***************************************************************/
- phb_tce_table_init(phb);
+ buid_vals = (int *) get_property(dev, "ibm,fw-phb-id", &len);
+ if (buid_vals == NULL || len < 2 * sizeof(int)) {
+ phb->buid = 0;
+ } else {
+ /* Big bus system. These systems start new bus numbers under
+ * each phb. Until pci domains are standard, we depend on a
+ * patch which makes bus numbers ints and we shift the phb
+ * number into the upper bits.
+ */
+ struct pci_bus check;
+ if (sizeof(check.number) == 1 || sizeof(check.primary) == 1 ||
+ sizeof(check.secondary) == 1 || sizeof(check.subordinate) == 1) {
+ udbg_printf("pSeries_pci: this system has large bus numbers and the kernel was not\n"
+ "built with the patch that fixes include/linux/pci.h struct pci_bus so\n"
+ "number, primary, secondary and subordinate are ints.\n");
+ panic("pSeries_pci: this system has large bus numbers and the kernel was not\n"
+ "built with the patch that fixes include/linux/pci.h struct pci_bus so\n"
+ "number, primary, secondary and subordinate are ints.\n");
+ }
+ phb->buid = (((unsigned long)buid_vals[0]) << 32UL) |
+ (((unsigned long)buid_vals[1]) & 0xffffffff);
+ phb->first_busno += (phb->global_number << 8);
+ phb->last_busno += (phb->global_number << 8);
+ }
/* Dump PHB information for Debug */
PPCDBGCALL(PPCDBG_PHBINIT,dumpPci_Controller(phb) );
@@ -699,8 +526,7 @@
void
fixup_resources(struct pci_dev *dev) {
int i;
- unsigned long size;
- struct pci_controller* phb = (struct pci_controller *)dev->sysdata;
+ struct pci_controller* phb = PCI_GET_PHB_PTR(dev);
PPCDBG(PPCDBG_PHBINIT, "fixup_resources:\n");
PPCDBG(PPCDBG_PHBINIT, "\tphb = 0x%016LX\n", phb);
@@ -712,7 +538,7 @@
if(phb == NULL) return;
- for (i = 0; i < 6; ++i) {
+ for (i = 0; i < DEVICE_COUNT_RESOURCE; ++i) {
PPCDBG(PPCDBG_PHBINIT, "\tdevice %x.%x[%d] (flags %x) [%lx..%lx]\n",
dev->bus->number, dev->devfn, i,
dev->resource[i].flags,
@@ -724,20 +550,20 @@
}
if (dev->resource[i].flags & IORESOURCE_IO) {
- dev->resource[i].start += phb->pci_io_offset;
- dev->resource[i].end += phb->pci_io_offset;
- size = dev->resource[i].end - dev->resource[i].start;
- dev->resource[i].start =
- ((unsigned long) ioremap(dev->resource[i].start,
- size)) - isa_io_base;
- dev->resource[i].end = dev->resource[i].start + size;
-
+ unsigned long offset = (unsigned long) phb->io_base_virt - isa_io_base;
+ dev->resource[i].start += offset;
+ dev->resource[i].end += offset;
PPCDBG(PPCDBG_PHBINIT, "\t\t-> now [%lx (%lx) .. %lx (%lx)]\n",
- dev->resource[i].start, ___pa(dev->resource[i].start + isa_io_base),
- dev->resource[i].end, ___pa(dev->resource[i].end + isa_io_base));
+ dev->resource[i].start, 0/*___pa(dev->resource[i].start + isa_io_base)*/,
+ dev->resource[i].end, 0/* ___pa(dev->resource[i].end + isa_io_base)*/);
} else if (dev->resource[i].flags & IORESOURCE_MEM) {
- dev->resource[i].start += phb->pci_mem_offset;
- dev->resource[i].end += phb->pci_mem_offset;
+ if (dev->resource[i].start == 0) {
+ /* Bogus. Probably an unused bridge. */
+ dev->resource[i].end = 0;
+ } else {
+ dev->resource[i].start += phb->pci_mem_offset;
+ dev->resource[i].end += phb->pci_mem_offset;
+ }
PPCDBG(PPCDBG_PHBINIT, "\t\t-> now [%lx..%lx]\n",
dev->resource[i].start, dev->resource[i].end);
@@ -760,6 +586,7 @@
pci_assign_all_busses = 0;
pci_for_each_dev(dev) {
+ pci_read_irq_line(dev);
PPCDBGCALL(PPCDBG_PHBINIT, dumpPci_Dev(dev) );
}
@@ -787,89 +614,6 @@
return NULL;
}
-/***********************************************************************
- *
- * scan_OF_childs_for_device
- *
- * The function is a helper function for the pci_device_to_OF_node. It
- * walks down the passed node, looking for a node entry that matches the
- * requested bus and device function. NOTE: If a bridge is found in the
- * scan, it will recurse this the function to to scan that bridge looking
- * for a match. If none found, the return will continue down the orginal
- * tree.
- *
- * Return:
- * Node matching the bus and devfn passed or NULL.
- ***********************************************************************/
-static struct device_node*
-scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn)
-{
- struct device_node* CurrentNode; /* Current node being scanned. */
- struct device_node* DeviceNode; /* Node of Device */
- u32* Register; /* Pointer to Register Array */
- u32* Class_Code; /* Pointer to ClassCode property */
- CurrentNode = node;
- DeviceNode = NULL;
- while(CurrentNode != NULL && DeviceNode == NULL) {
- u32 IoaAddress;
- u8 IoaBus, IoaDevFn;
-
- Register = (unsigned int *) get_property(CurrentNode,"reg", 0);
- if(Register != NULL) {
- /* 1st register entry is the Ioa Address = 00BBSS00 */
- IoaAddress = Register[0];
- IoaBus = (IoaAddress & 0x00FF0000) >> 16;
- IoaDevFn = (IoaAddress & 0x0000FF00) >> 8;
- if( (IoaBus == bus) && (IoaDevFn == dev_fn ) ) {
- DeviceNode = CurrentNode;
- return DeviceNode;
- }
- }
- /***************************************************************
- * check for a bridge, if so scan the branch of the tree for a match.
- ***************************************************************/
- Class_Code = (unsigned int*) get_property(CurrentNode,"class-code", 0);
- if(Class_Code != NULL) {
- u32 PciClassCode = ((*Class_Code)&0x00FFFF00)>>8;
-
- if(( PciClassCode == PCI_CLASS_BRIDGE_PCI) ||
- ( PciClassCode == PCI_CLASS_BRIDGE_CARDBUS) ) {
-
- PPCDBG(PPCDBG_BUSWALK,"\tScan OF behind bridge\n");
- DeviceNode = scan_OF_childs_for_device(CurrentNode->child, bus, dev_fn);
- if(DeviceNode != NULL) {
- return DeviceNode;
- }
- }
- }
- /***************************************************************
- * Try the next node.
- ***************************************************************/
- CurrentNode = CurrentNode->sibling;
- }
- return NULL;
-}
-/***********************************************************************
- * pci_device_to_OF_node
- *
- * This function Finds the Open Firmware node for the passed in pci_dev.
- * It starts at the Phb's node for the device and calls the
- * scan_OF_childs_for_device to looking for the matching entry.
- *
- * Return:
- * Node matching the device or NULL if it was not found.
- ***********************************************************************/
-struct device_node*
-pci_device_to_OF_node(struct pci_dev* Pci_Dev)
-{
- struct pci_controller* Phb;
- struct device_node* PhbNode;
- struct device_node* DeviceNode;
- Phb = PCI_GET_PHB_PTR(Pci_Dev);
- PhbNode = (struct device_node *) Phb->arch_data;
- DeviceNode = scan_OF_childs_for_device(PhbNode->child, PCI_GET_BUS_NUMBER(Pci_Dev), Pci_Dev->devfn);
- return DeviceNode;
-}
/***********************************************************************
* find_floppy(void)
*
@@ -882,20 +626,15 @@
* and maybe that is okay.
***********************************************************************/
struct pci_dev*
-find_floppy() {
- struct device_node *FloppyParent, *FloppyNode;
- struct pci_dev *floppy_dev = NULL;
- int *Register;
-
- FloppyNode = find_type_devices("fdc");
- if(FloppyNode != NULL && FloppyNode->parent != NULL) {
- FloppyParent = FloppyNode->parent;
- Register = (unsigned int *)get_property(FloppyParent,"reg", 0);
- if(Register != NULL) {
- u8 IoaBus = (Register[0] & 0x00FF0000) >> 16;
- u8 IoaDevFn = (Register[0] & 0x0000FF00) >> 8;
- floppy_dev = pci_find_slot(IoaBus, IoaDevFn);
- }
+find_floppy(void) {
+ struct device_node *floppy_dn;
+ struct pci_dev *floppy_dev = NULL;
+ int *reg;
+
+ floppy_dn = find_type_devices("fdc");
+ if(floppy_dn && floppy_dn->parent) {
+ if ((reg = (unsigned int *)get_property(floppy_dn->parent,"reg", 0)) != NULL)
+ floppy_dev = pci_find_slot((reg[0] & 0x00ff0000) >> 16, (reg[0] & 0x0000ff00) >> 8);
}
PPCDBG(PPCDBG_BUSWALK,"\tFloppy pci_dev\n");
PPCDBGCALL(PPCDBG_BUSWALK, dumpPci_Dev(floppy_dev) );
@@ -912,18 +651,21 @@
pSeries_pcibios_init(void) {
PPCDBG(PPCDBG_PHBINIT, "\tppc64_pcibios_init Entry.\n");
- if(get_property(find_path_device("/rtas"),"read-pc-config",NULL) != NULL) {
- PPCDBG(PPCDBG_PHBINIT, "\tFound: read-pc-config\n");
- }
- else PPCDBG(PPCDBG_PHBINIT, "\tNOT Found: read-pc-config\n");
-
-
- if(get_property(find_path_device("/rtas"),"ibm,read-pc-config",NULL) != NULL) {
- PPCDBG(PPCDBG_PHBINIT, "\tFound: ibm,read-pc-config\n");
- Pci_Set_IOA_Address = 1;
- }
if(get_property(find_path_device("/rtas"),"ibm,fw-phb-id",NULL) != NULL) {
PPCDBG(PPCDBG_PHBINIT, "\tFound: ibm,fw-phb-id\n");
Pci_Large_Bus_System = 1;
}
+}
+
+/*
+ * This is called very early before the page table is setup.
+ */
+void
+pSeries_pcibios_init_early(void) {
+ ppc_md.pcibios_read_config_byte = rtas_read_config_byte;
+ ppc_md.pcibios_read_config_word = rtas_read_config_word;
+ ppc_md.pcibios_read_config_dword = rtas_read_config_dword;
+ ppc_md.pcibios_write_config_byte = rtas_write_config_byte;
+ ppc_md.pcibios_write_config_word = rtas_write_config_word;
+ ppc_md.pcibios_write_config_dword = rtas_write_config_dword;
}
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/pacaData.c linuxppc64_2_4/arch/ppc64/kernel/pacaData.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/pacaData.c Tue Oct 16 16:54:41 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/pacaData.c Thu Sep 13 11:54:36 2001
@@ -31,49 +31,35 @@
* processor (not thread).
*/
#define PACAINITDATA(number,start,lpq,asrr,asrv) \
-{ (struct ItLpPaca *)(((char *)(&xPaca[number]))+offsetof(struct Paca, xLpPaca)), \
- (struct ItLpRegSave *)(((char *)(&xPaca[number]))+offsetof(struct Paca, xRegSav)), \
- 0, /* Current */ \
- 0, /* R21 Save */ \
- 0, /* R22 Save */ \
- 0, /* Kernel stack addr save */ \
- (number), /* Paca Index */ \
- 0, /* HW Proc Number */ \
- 0, /* CCR Save */ \
- 0, /* MSR Save */ \
- 0, /* LR Save */ \
- 0, /* Pointer to thread */ \
- {(asrr), /* Real pointer to segment table */ \
- (asrv), /* Virt pointer to segment table */ \
- REGION_COUNT-1}, /* Round robin index */ \
- {0,0,0,0,0,0,0,0},/* Segment cache */ \
- 0, /* Kernel TOC address */ \
- 0, /* R1 Save */ \
- (lpq), /* &xItLpQueue, */ \
- {0,0,0,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, SPIN_LOCK_UNLOCKED, 0}, /*xRtas */ \
- (start), /* Processor start */ \
- {0,0,0}, /* Resv */ \
- 0, /* Default Decrementer */ \
- 0, /* next_jiffy_update_tb */ \
- {0,0,0,0,0,0,0,0,0,0,0,0}, /* Resv */ \
- { /* LpPaca */ \
- xDesc: 0xd397d781, /* "LpPa" */ \
- xSize: sizeof(struct ItLpPaca), /* */ \
- xFPRegsInUse: 1, \
- xDynProcStatus: 2, \
- xEndOfQuantum: 0xffffffffffffffff /* */ \
- }, \
- { /* LpRegSave */ \
- 0xd397d9e2, /* "LpRS" */ \
- sizeof(struct ItLpRegSave) /* */ \
- }, \
- 0, /* pvr */ \
- 0, /* pgd_cache */ \
- 0, /* pmd_cache */ \
- 0, /* pte_cache */ \
- 0, /* pgtable_cache_sz */ \
- 0, /* prof_multiplier */ \
- 0 /* prof_counter */ \
+{ \
+ xLpPacaPtr: &xPaca[number].xLpPaca, \
+ xLpRegSavePtr: &xPaca[number].xRegSav, \
+ xPacaIndex: (number), /* Paca Index */ \
+ default_decr: 0x00ff0000, /* Initial Decr */ \
+ xStab_data: { \
+ real: (asrr), /* Real pointer to segment table */ \
+ virt: (asrv), /* Virt pointer to segment table */ \
+ next_round_robin: 1 /* Round robin index */ \
+ }, \
+ lpQueuePtr: (lpq), /* &xItLpQueue, */ \
+ xRtas: { \
+ lock: SPIN_LOCK_UNLOCKED \
+ }, \
+ xProcStart: (start), /* Processor start */ \
+ xLpPaca: { \
+ xDesc: 0xd397d781, /* "LpPa" */ \
+ xSize: sizeof(struct ItLpPaca), \
+ xFPRegsInUse: 1, \
+ xDynProcStatus: 2, \
+ xDecrVal: 0x00ff0000, \
+ xEndOfQuantum: 0xffffffffffffffff \
+ }, \
+ xRegSav: { \
+ xDesc: 0xd397d9e2, /* "LpRS" */ \
+ xSize: sizeof(struct ItLpRegSave) \
+ }, \
+ exception_sp: \
+ &xPaca[number].exception_stack[N_EXC_STACK*EXC_FRAME_SIZE], \
}
struct Paca xPaca[maxPacas] __page_aligned = {
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/pci.c linuxppc64_2_4/arch/ppc64/kernel/pci.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/pci.c Tue Oct 16 16:54:41 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/pci.c Wed Oct 3 11:04:13 2001
@@ -34,6 +34,17 @@
#include "pci.h"
+/* isa_io_limit -- only I/O ports above this addr are recognized by inb/outb.
+ * We fake failure below this limit without trashing the system.
+ * This is zero when an ISA bus exists, else PAGE_SIZE.
+ */
+unsigned long isa_io_limit = PAGE_SIZE;
+/* isa_io_base -- the base address from which io bars are offsets.
+ * This is the lowest I/O base address (so bar values are always positive),
+ * and it *must* be the start of ISA space if an ISA bus exists because
+ * ISA drivers use hard coded offsets. If no ISA bus exists a dummy
+ * page is mapped and isa_io_limit prevents access to it.
+ */
unsigned long isa_io_base = 0;
unsigned long isa_mem_base = 0;
unsigned long pci_dram_offset = 0;
@@ -41,10 +52,14 @@
/******************************************************************
* Forward declare of prototypes
******************************************************************/
-void pcibios_fixup_resources(struct pci_dev* dev);
-void fixup_resources(struct pci_dev* dev); /* In brand pci code */
+static void pcibios_fixup_resources(struct pci_dev* dev);
+static void fixup_broken_pcnet32(struct pci_dev* dev);
+void fixup_resources(struct pci_dev* dev);
struct pci_dev *find_floppy(void);
+void iSeries_pcibios_init(void);
+void pSeries_pcibios_init(void);
+
extern struct Naca *naca;
@@ -53,6 +68,19 @@
struct pci_controller* hose_head;
struct pci_controller** hose_tail = &hose_head;
+/*******************************************************************
+ * Counters and control flags.
+ *******************************************************************/
+long Pci_Io_Read_Count = 0;
+long Pci_Io_Write_Count = 0;
+long Pci_Cfg_Read_Count = 0;
+long Pci_Cfg_Write_Count= 0;
+long Pci_Error_Count = 0;
+
+int Pci_Retry_Max = 7;
+int Pci_Error_Flag = 0;
+int Pci_Trace_Flag = 0;
+
/******************************************************************
*
******************************************************************/
@@ -67,10 +95,20 @@
struct pci_dev *ppc64_floppy_dev = NULL;
struct pci_fixup pcibios_fixups[] = {
+ { PCI_FIXUP_HEADER, PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32 },
{ PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources },
{ 0 }
};
+static void fixup_broken_pcnet32(struct pci_dev* dev)
+{
+ if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
+ dev->vendor = PCI_VENDOR_ID_AMD;
+ pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
+ pci_name_device(dev);
+ }
+}
+
void pcibios_fixup_pbus_ranges(struct pci_bus *pbus,
struct pbus_set_ranges_data *pranges)
{
@@ -83,7 +121,7 @@
{
u32 new, check;
int reg;
- struct pci_controller* hose = dev->sysdata;
+ struct pci_controller* hose = PCI_GET_PHB_PTR(dev);
new = res->start;
if (hose && res->flags & IORESOURCE_MEM)
@@ -186,22 +224,29 @@
{
struct list_head *ln;
struct pci_bus *bus;
- struct pci_dev *dev;
- int idx;
- struct resource *r, *pr;
+ int i;
+ struct resource *res, *pr;
/* Depth-First Search on bus tree */
for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
bus = pci_bus_b(ln);
- if ((dev = bus->self)) {
- for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
- r = &dev->resource[idx];
- if (!r->start)
- continue;
- pr = pci_find_parent_resource(dev, r);
- if (!pr || request_resource(pr, r) < 0)
- printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, dev->slot_name);
- }
+ for (i = 0; i < 4; ++i) {
+ if ((res = bus->resource[i]) == NULL || !res->flags)
+ continue;
+ if (bus->parent == NULL)
+ pr = (res->flags & IORESOURCE_IO)?
+ &ioport_resource: &iomem_resource;
+ else
+ pr = pci_find_parent_resource(bus->self, res);
+
+ if (pr == res)
+ continue; /* transparent bus or undefined */
+ if (pr && request_resource(pr, res) == 0)
+ continue;
+ printk(KERN_ERR "PCI: Cannot allocate resource region "
+ "%d of PCI bridge %x\n", i, bus->number);
+ printk(KERN_ERR "PCI: resource is %lx..%lx (%lx), parent %p\n",
+ res->start, res->end, res->flags, pr);
}
pcibios_allocate_bus_resources(&bus->children);
}
@@ -388,7 +433,9 @@
int next_busno;
#ifndef CONFIG_PPC_ISERIES
- pSeries_pcibios_init();
+ pSeries_pcibios_init();
+#else
+ iSeries_pcibios_init();
#endif
printk("PCI: Probing PCI hardware\n");
@@ -398,14 +445,13 @@
/* Scan all of the recorded PCI controllers. */
for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
hose->last_busno = 0xff;
- bus = pci_scan_bus(hose->first_busno, hose->ops, hose);
+ bus = pci_scan_bus(hose->first_busno, hose->ops, hose->arch_data);
hose->bus = bus;
hose->last_busno = bus->subordinate;
if (pci_assign_all_busses || next_busno <= hose->last_busno)
next_busno = hose->last_busno+1;
}
pci_bus_count = next_busno;
-
/* Call machine dependant fixup */
if (ppc_md.pcibios_fixup) {
@@ -415,24 +461,18 @@
/* Generic fixups */
pcibios_generic_fixup();
+#ifndef CONFIG_PPC_ISERIES
/* Allocate and assign resources */
pcibios_allocate_bus_resources(&pci_root_buses);
- if(naca->io_subsystem == IOS_OPEN_PIC) {
- pcibios_allocate_resources(0); // DRENG Condor removed. This will have to be reviewed!!!
- }
- if(naca->io_subsystem == IOS_OPEN_PIC) {
- pcibios_allocate_resources(1); // DRENG Condor removed. This will have to be reviewed!!!
- }
+ pcibios_allocate_resources(0);
+ pcibios_allocate_resources(1);
pcibios_assign_resources();
- /*
- * Set up TCE tables for each PHB.
- */
- for (hose = hose_head; hose; hose = hose->next) {
- create_pci_bus_tce_table(hose->global_number,
- (unsigned long)hose);
- }
+ pci_fix_bus_sysdata();
+ create_tce_tables();
+ PPCDBG(PPCDBG_BUSWALK,"pSeries create_tce_tables()\n");
+#endif
ppc64_floppy_dev = find_floppy();
printk("PCI: Probing PCI hardware done\n");
@@ -454,8 +494,55 @@
void __init pcibios_fixup_bus(struct pci_bus *bus)
{
- pci_read_bridge_bases(bus);
-
+ struct pci_controller *phb = PCI_GET_PHB_PTR(bus);
+ struct resource *res;
+ unsigned long io_offset;
+ int i;
+
+#ifndef CONFIG_PPC_ISERIES
+ io_offset = (unsigned long)phb->io_base_virt - isa_io_base;
+
+ if (bus->parent == NULL) {
+ /* This is a host bridge - fill in its resources */
+ phb->bus = bus;
+ bus->resource[0] = res = &phb->io_resource;
+ if (!res->flags)
+ BUG(); /* No I/O resource for this PHB? */
+
+ for (i = 0; i < 3; ++i) {
+ res = &phb->mem_resources[i];
+ if (!res->flags) {
+ if (i == 0)
+ BUG(); /* No memory resource for this PHB? */
+ }
+ bus->resource[i+1] = res;
+ }
+ } else {
+ /* This is a subordinate bridge */
+ pci_read_bridge_bases(bus);
+
+ for (i = 0; i < 4; ++i) {
+ if ((res = bus->resource[i]) == NULL)
+ continue;
+ if (!res->flags)
+ continue;
+ if (res == pci_find_parent_resource(bus->self, res)) {
+ /* Transparent resource -- don't try to "fix" it. */
+ continue;
+ }
+ if (res->flags & IORESOURCE_IO) {
+ res->start += io_offset;
+ res->end += io_offset;
+ } else if (phb->pci_mem_offset
+ && (res->flags & IORESOURCE_MEM)) {
+ if (res->start < phb->pci_mem_offset) {
+ res->start += phb->pci_mem_offset;
+ res->end += phb->pci_mem_offset;
+ }
+ }
+ }
+ }
+#endif
if ( ppc_md.pcibios_fixup_bus )
ppc_md.pcibios_fixup_bus(bus);
}
@@ -471,6 +558,7 @@
int idx;
struct resource *r;
+ PPCDBG(PPCDBG_BUSWALK,"PCI: "__FUNCTION__" for device %s \n",dev->slot_name);
if (ppc_md.pcibios_enable_device_hook)
if (ppc_md.pcibios_enable_device_hook(dev, 0))
return -EINVAL;
@@ -546,7 +634,7 @@
*/
int pci_controller_num(struct pci_dev *dev)
{
- struct pci_controller *hose = (struct pci_controller *) dev->sysdata;
+ struct pci_controller *hose = PCI_GET_PHB_PTR(dev);
return hose->global_number;
}
@@ -572,7 +660,7 @@
__pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state)
{
- struct pci_controller *hose = (struct pci_controller *) dev->sysdata;
+ struct pci_controller *hose = PCI_GET_PHB_PTR(dev);
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
unsigned long io_offset = 0;
int i, res_bit;
@@ -794,11 +882,12 @@
* Dump Device information for Debug
*****************************************************/
void dumpPci_Dev(struct pci_dev* Pci_Dev) {
- int i;
- udbg_printf("\tpci_dev = 0x%016LX \n",Pci_Dev);
- if( Pci_Dev == NULL ) return;
- udbg_printf("\tname = %s\n",Pci_Dev->name);
- udbg_printf("\tpci_dev phb = 0x%016LX \n",PCI_GET_PHB_PTR(Pci_Dev) );
+ int i;
+ udbg_printf("\tpci_dev* = 0x%pb\n",Pci_Dev);
+ if( Pci_Dev == NULL ) return;
+ udbg_printf("\tname = %s \n",Pci_Dev->name);
+ udbg_printf("\tbus* = 0x%p\n",Pci_Dev->bus);
+ udbg_printf("\tsysdata* = 0x%p\n",Pci_Dev->sysdata);
udbg_printf("\tDevice = 0x%4X%02X:%02X.%02X 0x%04X:%04X\n",
PCI_GET_PHB_NUMBER(Pci_Dev),
PCI_GET_BUS_NUMBER(Pci_Dev),
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/pci.h linuxppc64_2_4/arch/ppc64/kernel/pci.h
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/pci.h Tue Oct 16 16:54:41 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/pci.h Fri Sep 21 09:24:50 2001
@@ -9,8 +9,6 @@
#ifndef __PPC_KERNEL_PCI_H__
#define __PPC_KERNEL_PCI_H__
-/* Include these to prevent strange compile warnings if user forgets
- * to include them in their .c file. */
#include
#include
@@ -29,27 +27,59 @@
extern struct pci_controller* pci_alloc_pci_controller(char *model, enum phb_types controller_type);
extern struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node);
+extern struct pci_controller* hose_head;
+extern struct pci_controller** hose_tail;
+
/*******************************************************************
* Platform functions that are brand specific implementation.
*******************************************************************/
extern unsigned long find_and_init_phbs(void);
-extern int pci_read_irq_line(struct pci_dev* PciDev);
-extern int pci_read_bar_registers(struct pci_dev* PciDev, int Count, int RomFlag);
-
extern void fixup_resources(struct pci_dev *dev);
extern void ppc64_pcibios_init(void);
extern int pci_reset_device(struct pci_dev*);
extern int pci_get_location(struct pci_dev*, char*, int);
-extern struct pci_dev* find_floppy(void);
extern struct pci_dev *ppc64_floppy_dev;
+
+/*******************************************************************
+ * PCI device_node operations
+ *******************************************************************/
+struct device_node;
+typedef void *(*traverse_func)(struct device_node *me, void *data);
+void *traverse_pci_devices(struct device_node *start, traverse_func pre, traverse_func post, void *data);
+void *traverse_all_pci_devices(traverse_func pre);
+
+void pci_devs_phb_init(void);
+void pci_fix_bus_sysdata(void);
+struct device_node *fetch_dev_dn(struct pci_dev *dev);
+
+void iSeries_pcibios_init_early(void);
+void pSeries_pcibios_init_early(void);
+void pSeries_pcibios_init(void);
+
+/* Get a device_node from a pci_dev. This code must be fast except in the case
+ * where the sysdata is incorrect and needs to be fixed up (hopefully just once)
+ */
+static inline struct device_node *pci_device_to_OF_node(struct pci_dev *dev)
+{
+ struct device_node *dn = (struct device_node *)(dev->sysdata);
+ if (dn->devfn == dev->devfn && dn->busno == dev->bus->number)
+ return dn; /* fast path. sysdata is good */
+ else
+ return fetch_dev_dn(dev);
+}
+/* Use this macro after the PCI bus walk for max performance when it
+ * is known that sysdata is correct.
+ */
+#define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata))
+
+
/*******************************************************************
* Platform configuration flags.. (Live in pci.c)
*******************************************************************/
extern int Pci_Large_Bus_System; /* System has > 256 buses */
-extern int Pci_Set_IOA_Address; /* Set IOA BARs from OF */
extern int Pci_Manage_Phb_Space; /* Manage Phb Space for IOAs*/
/*******************************************************************
@@ -58,9 +88,9 @@
* PCI_GET_PHB_NUMBER(struct pci_dev*) returns the Phb number.
* PCI_GET_BUS_NUMBER(struct pci_dev*) returns the bus number.
*******************************************************************/
-#define PCI_GET_PHB_PTR(PCIDEV) ((struct pci_controller*)##PCIDEV##->sysdata)
-#define PCI_GET_PHB_NUMBER(PCIDEV) ((##PCIDEV##->bus->number&0x00FFFF00)>>8)
-#define PCI_GET_BUS_NUMBER(PCIDEV) ( ##PCIDEV##->bus->number&0x0000FF)
+#define PCI_GET_PHB_PTR(dev) (((struct device_node *)(dev)->sysdata)->phb)
+#define PCI_GET_PHB_NUMBER(dev) (((dev)->bus->number&0x00FFFF00)>>8)
+#define PCI_GET_BUS_NUMBER(dev) ((dev)->bus->number&0x0000FF)
/*******************************************************************
* Pci Flight Recorder support.
diff -uNr --exclude=CVS ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/pci_dma.c linuxppc64_2_4/arch/ppc64/kernel/pci_dma.c
--- ../tue/linux-2.4.10-ac12/arch/ppc64/kernel/pci_dma.c Tue Oct 16 16:54:41 2001
+++ linuxppc64_2_4/arch/ppc64/kernel/pci_dma.c Sat Oct 6 15:14:17 2001
@@ -39,7 +39,11 @@
#include
#include
-#define DEBUG_TCE 1
+#include
+
+#include "pci.h"
+
+// #define DEBUG_TCE 1
/* Initialize so this guy does not end up in the BSS section.
* Only used to pass OF initialization data set in prom.c into the main
@@ -47,47 +51,61 @@
*/
extern struct _of_tce_table of_tce_table[];
-struct TceTable virtBusTceTable; /* Tce table for virtual bus */
+extern struct pci_controller* hose_head;
+extern struct pci_controller** hose_tail;
+
+struct TceTable virtBusVethTceTable; /* Tce table for virtual ethernet */
+struct TceTable virtBusVioTceTable; /* Tce table for virtual I/O */
+
+struct device_node iSeries_veth_dev_node = { tce_table: &virtBusVethTceTable };
+struct device_node iSeries_vio_dev_node = { tce_table: &virtBusVioTceTable };
+
+struct pci_dev iSeries_veth_dev_st = { sysdata: &iSeries_veth_dev_node };
+struct pci_dev iSeries_vio_dev_st = { sysdata: &iSeries_vio_dev_node };
+
+struct pci_dev * iSeries_veth_dev = &iSeries_veth_dev_st;
+struct pci_dev * iSeries_vio_dev = &iSeries_vio_dev_st;
struct TceTable * tceTables[256]; /* Tce tables for 256 busses
* Bus 255 is the virtual bus
* zero indicates no bus defined
*/
- /* allocates a contiguous range of tces (power-of-2 size) */
-static long alloc_tce_range( struct TceTable *,
+/* allocates a contiguous range of tces (power-of-2 size) */
+static inline long alloc_tce_range(struct TceTable *,
unsigned order );
- /* allocates a contiguous range of tces (power-of-2 size)
- * assumes lock already held
- */
-static long alloc_tce_range_nolock( struct TceTable *,
- unsigned order );
- /* frees a contiguous range of tces (power-of-2 size) */
-static void free_tce_range( struct TceTable *,
- long tcenum,
- unsigned order );
- /* frees a contiguous rnage of tces (power-of-2 size)
- * assumes lock already held
- */
-static void free_tce_range_nolock( struct TceTable *,
- long tcenum,
- unsigned order );
- /* allocates a range of tces and sets them to the pages */
-static dma_addr_t get_tces( struct TceTable *,
- unsigned order,
- void *page,
- unsigned numPages,
- int tceType,
- int direction );
-static void free_tces( struct TceTable *,
- dma_addr_t tce,
- unsigned order,
- unsigned numPages );
-static long test_tce_range( struct TceTable *,
+
+/* allocates a contiguous range of tces (power-of-2 size)
+ * assumes lock already held
+ */
+static long alloc_tce_range_nolock(struct TceTable *,
+ unsigned order );
+
+/* frees a contiguous range of tces (power-of-2 size) */
+static inline void free_tce_range(struct TceTable *,
long tcenum,
unsigned order );
-static unsigned fill_scatterlist_sg( struct scatterlist *sg, int nents,
- dma_addr_t dma_addr, unsigned long numTces );
+/* frees a contiguous rnage of tces (power-of-2 size)
+ * assumes lock already held
+ */
+void free_tce_range_nolock(struct TceTable *,
+ long tcenum,
+ unsigned order );
+
+/* allocates a range of tces and sets them to the pages */
+static inline dma_addr_t get_tces( struct TceTable *,
+ unsigned order,
+ void *page,
+ unsigned numPages,
+ int direction );
+
+static long test_tce_range( struct TceTable *,
+ long tcenum,
+ unsigned order );
+
+static unsigned fill_scatterlist_sg(struct scatterlist *sg, int nents,
+ dma_addr_t dma_addr,
+ unsigned long numTces );
static unsigned long num_tces_sg( struct scatterlist *sg,
int nents );
@@ -96,93 +114,111 @@
struct scatterlist *sg,
int nents,
unsigned numTces,
- int tceType,
int direction );
-static void getTceTableParms( struct pci_controller *phb,
- struct TceTable *tce_table_parms );
-
-
-static unsigned long setTce( unsigned long base,
- unsigned long tce_num,
- unsigned long tce_data);
+static void getTceTableParmsPSeries( struct pci_controller *phb,
+ struct device_node *dn,
+ struct TceTable *tce_table_parms );
+
+static void getTceTableParmsPSeriesLP(struct pci_controller *phb,
+ struct device_node *dn,
+ struct TceTable *newTceTable );
-static long resv_tce_range_top_level( struct TceTable *tbl,
- unsigned long dma_addr,
- unsigned size );
+void create_pci_bus_tce_table( unsigned long token );
u8 iSeries_Get_Bus( struct pci_dev * dv )
{
return 0;
}
-/*
- * Given a pci device, return which tce table is assigned to it.
- */
-unsigned long get_tce_table_index( struct pci_dev *dev) {
- unsigned long index =
- ((struct pci_controller *)dev->sysdata)->global_number;
- PPCDBG(PPCDBG_TCE, "get_tce_table_index:\n");
- PPCDBG(PPCDBG_TCE, "\tdev = 0x%lx, index = 0x%lx\n", dev, index);
- return(index);
+static inline struct TceTable *get_tce_table(struct pci_dev *dev) {
+
+ if ( ( _machine == _MACH_iSeries ) && ( dev->bus ) )
+ return tceTables[dev->bus->number];
+
+ return PCI_GET_DN(dev)->tce_table;
}
-static unsigned __inline__ count_leading_zeros32( unsigned long x )
+static unsigned long __inline__ count_leading_zeros64( unsigned long x )
{
- unsigned lz;
- asm("cntlzw %0,%1" : "=r"(lz) : "r"(x));
+ unsigned long lz;
+ asm("cntlzd %0,%1" : "=r"(lz) : "r"(x));
return lz;
}
-static void __inline__ build_tce( struct TceTable * tbl, long tcenum,
- unsigned long uaddr, int tceType, int direction )
+static void tce_build_iSeries(struct TceTable *tbl, long tcenum,
+ unsigned long uaddr, int direction )
{
u64 setTceRc;
union Tce tce;
PPCDBG(PPCDBG_TCE, "build_tce: uaddr = 0x%lx\n", uaddr);
+ PPCDBG(PPCDBG_TCE, "\ttcenum = 0x%lx, tbl = 0x%lx, index=%lx\n",
+ tcenum, tbl, tbl->index);
+
tce.wholeTce = 0;
tce.tceBits.rpn = (virt_to_absolute(uaddr)) >> PAGE_SHIFT;
+
/* If for virtual bus */
- if ( tceType == TCE_VB ) {
+ if ( tbl->tceType == TCE_VB ) {
tce.tceBits.valid = 1;
tce.tceBits.allIo = 1;
if ( direction != PCI_DMA_TODEVICE )
tce.tceBits.readWrite = 1;
- }
- /* If for PCI bus */
- else {
+ } else {
+ /* If for PCI bus */
tce.tceBits.readWrite = 1; // Read allowed
if ( direction != PCI_DMA_TODEVICE )
tce.tceBits.pciWrite = 1;
}
-#ifdef CONFIG_PPC_ISERIES
- setTceRc = HvCallXm_setTce( (u64)tbl->index, (u64)tcenum, tce.wholeTce );
-#else
- setTceRc = setTce( (u64)tbl->base, (u64)tcenum, tce.wholeTce );
-#endif
+ setTceRc = HvCallXm_setTce((u64)tbl->index,
+ (u64)tcenum,
+ tce.wholeTce );
- if ( setTceRc ) {
- PPCDBG(PPCDBG_TCE, "build_tce: HvCallXm_setTce failed, rc=%ld, index=%ld, tcenum=%0lx, tce=%016lx\n",
- (u64)tbl->index, (u64)tcenum, tce.wholeTce );
+ if(setTceRc) {
+ PPCDBG(PPCDBG_TCE, "setTce failed. rc=%ld\n", setTceRc);
+ PPCDBG(PPCDBG_TCE, "\tindex = 0x%lx\n", (u64)tbl->index);
+ PPCDBG(PPCDBG_TCE, "\ttce num = 0x%lx\n", (u64)tcenum);
+ PPCDBG(PPCDBG_TCE, "\ttce val = 0x%lx\n", tce.wholeTce );
}
-
}
+static void tce_build_pSeries(struct TceTable *tbl, long tcenum,
+ unsigned long uaddr, int direction )
+{
+ union Tce tce;
+ union Tce *tce_addr;
+
+ PPCDBG(PPCDBG_TCE, "build_tce: uaddr = 0x%lx\n", uaddr);
+ PPCDBG(PPCDBG_TCE, "\ttcenum = 0x%lx, tbl = 0x%lx, index=%lx\n",
+ tcenum, tbl, tbl->index);
+ tce.wholeTce = 0;
+ tce.tceBits.rpn = (virt_to_absolute(uaddr)) >> PAGE_SHIFT;
+
+ tce.tceBits.readWrite = 1; // Read allowed
+ if ( direction != PCI_DMA_TODEVICE ) tce.tceBits.pciWrite = 1;
+
+ tce_addr = ((union Tce *)tbl->base) + tcenum;
+ *tce_addr = (union Tce)tce.wholeTce;
+
+ /* Make sure the update is visible to hardware. */
+ __asm__ __volatile__ ("sync" : : : "memory");
+}
/*
* Build a TceTable structure. This contains a multi-level bit map which
* is used to manage allocation of the tce space.
*/
-struct TceTable * build_tce_table( struct TceTable * tbl )
+static struct TceTable *build_tce_table( struct TceTable * tbl )
{
unsigned long bits, bytes, totalBytes;
unsigned long numBits[NUM_TCE_LEVELS], numBytes[NUM_TCE_LEVELS];
unsigned i, k, m;
unsigned char * pos, * p, b;
+ PPCDBG(PPCDBG_TCEINIT, "build_tce_table: tbl = 0x%lx\n", tbl);
spin_lock_init( &(tbl->lock) );
tbl->mlbm.maxLevel = 0;
@@ -194,14 +230,14 @@
bits = tbl->size * (PAGE_SIZE / sizeof( union Tce ));
for ( i=0; i> m;
- PPCDBG(PPCDBG_TCE, "build_tce_table: level %d last bit %x\n", i, 0x80>>m );
+ PPCDBG(PPCDBG_TCEINIT, "build_tce_table: level %d last bit %x\n", i, 0x80>>m );
}
}
else
@@ -232,7 +268,6 @@
pos += numBytes[i];
tbl->mlbm.level[i].numBits = numBits[i];
tbl->mlbm.level[i].numBytes = numBytes[i];
-
}
/* For the highest level, turn on all the bits */
@@ -240,14 +275,14 @@
i = tbl->mlbm.maxLevel;
p = tbl->mlbm.level[i].map;
m = numBits[i];
- PPCDBG(PPCDBG_TCE, "build_tce_table: highest level (%d) has all bits set\n", i);
+ PPCDBG(PPCDBG_TCEINIT, "build_tce_table: highest level (%d) has all bits set\n", i);
for (k=0; k= 8 ) {
/* handle full bytes */
*p++ = 0xff;
m -= 8;
}
- else {
+ else if(m>0) {
/* handle the last partial byte */
b = 0x80;
*p = 0;
@@ -256,15 +291,15 @@
b >>= 1;
--m;
}
+ } else {
+ break;
}
}
-
return tbl;
-
}
-static long alloc_tce_range( struct TceTable *tbl, unsigned order )
+static inline long alloc_tce_range( struct TceTable *tbl, unsigned order )
{
long retval;
unsigned long flags;
@@ -281,50 +316,50 @@
return retval;
}
-
-
static long alloc_tce_range_nolock( struct TceTable *tbl, unsigned order )
{
unsigned long numBits, numBytes;
unsigned long i, bit, block, mask;
long tcenum;
- unsigned char * map;
+ u64 * map;
/* If the order (power of 2 size) requested is larger than our
* biggest, indicate failure
*/
- if ( order > tbl->mlbm.maxLevel ) {
- PPCDBG(PPCDBG_TCE, "alloc_tce_range_nolock: invalid order requested, order = %d\n",
- order );
+ if(order >= NUM_TCE_LEVELS) {
+ PPCDBG(PPCDBG_TCE,
+ "alloc_tce_range_nolock: invalid order: %d\n", order );
return -1;
}
numBits = tbl->mlbm.level[order].numBits;
numBytes = tbl->mlbm.level[order].numBytes;
- map = tbl->mlbm.level[order].map;
+ map = (u64 *)tbl->mlbm.level[order].map;
/* Initialize return value to -1 (failure) */
tcenum = -1;
/* Loop through the bytes of the bitmap */
- for (i=0; i> bit);
- *map &= mask;
+ mask = 0x1UL << (63 - bit);
+ *map &= ~mask;
+
/* compute the index into our tce table for
* the first tce in the block
*/
PPCDBG(PPCDBG_TCE, "alloc_tce_range_nolock: allocating block %ld, (byte=%ld, bit=%ld) order %d\n", block, i, bit, order );
tcenum = block << order;
- break;
+ return tcenum;
}
++map;
}
@@ -343,7 +378,7 @@
* size bigger. If one of those is found, return the second
* half of the block to freespace and keep the first half
*/
- if ( ( tcenum == -1 ) && ( order < tbl->mlbm.maxLevel ) ) {
+ if((tcenum == -1) && (order < (NUM_TCE_LEVELS - 1))) {
tcenum = alloc_tce_range_nolock( tbl, order+1 );
if ( tcenum != -1 ) {
free_tce_range_nolock( tbl, tcenum+(1< tbl->mlbm.maxLevel ) {
- PPCDBG(PPCDBG_TCE, "free_tce_range: order too large, order = %d, tcenum = %d\n", order, tcenum );
+
+ if (order >= NUM_TCE_LEVELS) {
+ PPCDBG(PPCDBG_TCE,
+ "free_tce_range: invalid order: %d, tcenum = %d\n",
+ order, tcenum );
return;
}
-
+
block = tcenum >> order;
+
+#ifdef DEBUG_TCE
if ( tcenum != (block << order ) ) {
- PPCDBG(PPCDBG_TCE, "free_tce_range: tcenum %lx is not on appropriate boundary for order %x\n", tcenum, order );
+ PPCDBG(PPCDBG_TCE,
+ "free_tce_range: tcenum %lx misaligned for order %x\n",
+ tcenum, order );
return;
}
+
+
if ( block >= tbl->mlbm.level[order].numBits ) {
- PPCDBG(PPCDBG_TCE, "free_tce_range: tcenum %lx is outside the range of this map (order %x, numBits %lx\n", tcenum, order, tbl->mlbm.level[order].numBits );
+ PPCDBG(PPCDBG_TCE,
+ "free_tce_range: tcenum %lx is outside the range of this map (order %x, numBits %lx\n",
+ tcenum, order, tbl->mlbm.level[order].numBits );
return;
}
-#ifdef DEBUG_TCE
+
+
if ( test_tce_range( tbl, tcenum, order ) ) {
- PPCDBG(PPCDBG_TCE, "free_tce_range: freeing range not completely allocated.\n");
- PPCDBG(PPCDBG_TCE, "free_tce_range: TceTable %p, tcenum %lx, order %x\n", tbl, tcenum, order );
+ PPCDBG(PPCDBG_TCE,
+ "free_tce_range: freeing range not allocated.\n");
+ PPCDBG(PPCDBG_TCE,
+ "\tTceTable %p, tcenum %lx, order %x\n",
+ tbl, tcenum, order );
}
#endif
+
map = tbl->mlbm.level[order].map;
byte = block / 8;
bit = block % 8;
mask = 0x80 >> bit;
bytep = map + byte;
+
#ifdef DEBUG_TCE
- PPCDBG(PPCDBG_TCE, "free_tce_range_nolock: freeing block %ld (byte=%d, bit=%d) of order %d\n",block, byte, bit, order);
+ PPCDBG(PPCDBG_TCE,
+ "free_tce_range_nolock: freeing block %ld (byte=%d, bit=%d) of order %d\n",
+ block, byte, bit, order);
if ( *bytep & mask )
- PPCDBG(PPCDBG_TCE, "free_tce_range: already free: TceTable %p, tcenum %lx, order %x\n", tbl, tcenum, order );
+ PPCDBG(PPCDBG_TCE,
+ "free_tce_range: already free: TceTable %p, tcenum %lx, order %x\n",
+ tbl, tcenum, order );
#endif
+
*bytep |= mask;
/* If there is a higher level in the bit map than this we may be
@@ -415,11 +473,11 @@
* If this is the highest level we can't buddy up
* If this level has an odd number of bits and
* we are freeing the last block we can't buddy up
+ * Don't buddy up if it's in the first 1/4 of the level
*/
- if ( ( order < tbl->mlbm.maxLevel ) &&
- ( ( 0 == ( tbl->mlbm.level[order].numBits & 1 ) ) ||
- ( block < tbl->mlbm.level[order].numBits-1 ) ) ) {
-
+ if (( block > (tbl->mlbm.level[order].numBits/4) ) &&
+ (( block < tbl->mlbm.level[order].numBits-1 ) ||
+ ( 0 == ( tbl->mlbm.level[order].numBits & 1)))) {
/* See if we can buddy up the block we just freed */
bit &= 6; /* get to the first of the buddy bits */
mask = 0xc0 >> bit; /* build two bit mask */
@@ -430,13 +488,15 @@
block = ( byte * 8 ) + bit; /* block of first of buddies */
tcenum = block << order;
/* free the buddied block */
- PPCDBG(PPCDBG_TCE, "free_tce_range: buddying up block %ld and block %ld\n", block, block+1);
+ PPCDBG(PPCDBG_TCE,
+ "free_tce_range: buddying blocks %ld & %ld\n",
+ block, block+1);
free_tce_range_nolock( tbl, tcenum, order+1 );
}
}
}
-static long test_tce_range( struct TceTable *tbl, long tcenum, unsigned order )
+static long test_tce_range( struct TceTable *tbl, long tcenum, unsigned order )
{
unsigned long block;
unsigned byte, bit, mask, b;
@@ -468,7 +528,7 @@
return retval;
}
-static dma_addr_t get_tces( struct TceTable *tbl, unsigned order, void *page, unsigned numPages, int tceType, int direction )
+static inline dma_addr_t get_tces( struct TceTable *tbl, unsigned order, void *page, unsigned numPages, int direction )
{
long tcenum;
unsigned long uaddr;
@@ -485,7 +545,7 @@
retTce = tcenum << PAGE_SHIFT; /* Set the return dma address */
/* Setup a tce for each page */
for (i=0; istartOffset;
if ( tcenum > maxTcenum ) {
- PPCDBG(PPCDBG_TCE, "free_tces: tcenum > maxTcenum, tcenum = %ld, maxTcenum = %ld\n",
- tcenum, maxTcenum );
- PPCDBG(PPCDBG_TCE, "free_tces: TCE Table at %16lx\n", (unsigned long)tbl );
- PPCDBG(PPCDBG_TCE, "free_tces: bus# %lu\n", (unsigned long)tbl->busNumber );
- PPCDBG(PPCDBG_TCE, "free_tces: size %lu\n", (unsigned long)tbl->size );
- PPCDBG(PPCDBG_TCE, "free_tces: startOff %lu\n", (unsigned long)tbl->startOffset );
- PPCDBG(PPCDBG_TCE, "free_tces: index %lu\n", (unsigned long)tbl->index );
+ PPCDBG(PPCDBG_TCE, "free_tces: tcenum > maxTcenum\n");
+ PPCDBG(PPCDBG_TCE, "\ttcenum = 0x%lx\n", tcenum);
+ PPCDBG(PPCDBG_TCE, "\tmaxTcenum = 0x%lx\n", maxTcenum);
+ PPCDBG(PPCDBG_TCE, "\tTCE Table = 0x%lx\n", (u64)tbl);
+ PPCDBG(PPCDBG_TCE, "\tbus# = 0x%lx\n",
+ (u64)tbl->busNumber );
+ PPCDBG(PPCDBG_TCE, "\tsize = 0x%lx\n", (u64)tbl->size);
+ PPCDBG(PPCDBG_TCE, "\tstartOff = 0x%lx\n",
+ (u64)tbl->startOffset );
+ PPCDBG(PPCDBG_TCE, "\tindex = 0x%lx\n", (u64)tbl->index);
return;
}
@@ -522,22 +586,68 @@
for (i=0; iindex, (u64)tcenum, tce.wholeTce );
-#else
- setTceRc = setTce( (u64)tbl->base, (u64)tcenum, tce.wholeTce );
-#endif
+ setTceRc = HvCallXm_setTce((u64)tbl->index,
+ (u64)tcenum,
+ tce.wholeTce );
if ( setTceRc ) {
- PPCDBG(PPCDBG_TCE, "free_tces: HvCallXm_setTce failed, rc=%ld, index=%ld, tcenum=%0lx, tce=%016lx\n",
- (u64)tbl->index, (u64)tcenum, tce.wholeTce );
+ PPCDBG(PPCDBG_TCE, "tce_free: setTce failed\n");
+ PPCDBG(PPCDBG_TCE, "\trc = 0x%lx\n", setTceRc);
+ PPCDBG(PPCDBG_TCE, "\tindex = 0x%lx\n",
+ (u64)tbl->index);
+ PPCDBG(PPCDBG_TCE, "\ttce num = 0x%lx\n", (u64)tcenum);
+ PPCDBG(PPCDBG_TCE, "\ttce val = 0x%lx\n",
+ tce.wholeTce );
}
++tcenum;
}
free_tce_range( tbl, freeTce, order );
+}
+
+static void tce_free_pSeries(struct TceTable *tbl, dma_addr_t dma_addr,
+ unsigned order, unsigned numPages)
+{
+ long tcenum, freeTce, maxTcenum;
+ unsigned i;
+ union Tce tce;
+ union Tce *tce_addr;
+
+ maxTcenum = (tbl->size * (PAGE_SIZE / sizeof(union Tce))) - 1;
+
+ tcenum = dma_addr >> PAGE_SHIFT;
+ // tcenum -= tbl->startOffset;
+
+ freeTce = tcenum - tbl->startOffset;
+
+ if ( freeTce > maxTcenum ) {
+ PPCDBG(PPCDBG_TCE, "free_tces: tcenum > maxTcenum\n");
+ PPCDBG(PPCDBG_TCE, "\ttcenum = 0x%lx\n", tcenum);
+ PPCDBG(PPCDBG_TCE, "\tmaxTcenum = 0x%lx\n", maxTcenum);
+ PPCDBG(PPCDBG_TCE, "\tTCE Table = 0x%lx\n", (u64)tbl);
+ PPCDBG(PPCDBG_TCE, "\tbus# = 0x%lx\n",
+ (u64)tbl->busNumber );
+ PPCDBG(PPCDBG_TCE, "\tsize = 0x%lx\n", (u64)tbl->size);
+ PPCDBG(PPCDBG_TCE, "\tstartOff = 0x%lx\n",
+ (u64)tbl->startOffset );
+ PPCDBG(PPCDBG_TCE, "\tindex = 0x%lx\n", (u64)tbl->index);
+ return;
+ }
+
+ for (i=0; i