diff -urN -X bkexcl linux-2.4.22/Documentation/Configure.help linuxppc-2.4/Documentation/Configure.help
--- linux-2.4.22/Documentation/Configure.help 2003-08-26 14:24:57.000000000 +1000
+++ linuxppc-2.4/Documentation/Configure.help 2003-08-26 11:57:10.000000000 +1000
@@ -109,6 +109,15 @@
like MGA monitors that you are very unlikely to see on today's
systems.
+Prompt for advanced kernel configuration options
+CONFIG_ADVANCED_OPTIONS
+ This option will enable prompting for a variety of advanced kernel
+ configuration options. These options can cause the kernel to not
+ work if they are set incorrectly, but can be used to optimize certain
+ aspects of kernel memory management.
+
+ Unless you know what you are doing you *should not* enable this option.
+
Symmetric Multi-Processing support
CONFIG_SMP
This enables support for systems with more than one CPU. If you have
@@ -5194,6 +5203,16 @@
If you plan to use the LCD display with your SA-1100 system, say
Y here.
+IBM Beech LCD Controller Support
+CONFIG_FB_IBMLCDC
+ This is a framebuffer device for the IBM 405LP/Beech LCD Controller.
+ See for information on framebuffer
+ devices.
+
+ If you plan to use the LCD display with your 405LP/Beech system, say
+ Y here. You must also enable generic framebuffer support under the
+ Console configuration tab.
+
Advanced low level driver options
CONFIG_FBCON_ADVANCED
The frame buffer console uses character drawing routines that are
@@ -22970,6 +22989,14 @@
CONFIG_WALNUT
Select Walnut if you have an IBM 405GP "Walnut" Evaluation Board.
+Beech
+CONFIG_BEECH
+ Select Beech if you have an IBM 405LP "Beech" Evaluation Board.
+
+Xilinx-ML300
+CONFIG_XILINX_ML300
+ Select Xilinx-ML300 if you have a Xilinx ML300 evaluation board.
+
Workarounds for PPC601 bugs
CONFIG_PPC601_SYNC_FIX
Some versions of the PPC601 (the first PowerPC chip) have bugs which
@@ -23085,6 +23112,12 @@
More information is available at:
.
+IBM Spruce Baud Clock Support
+CONFIG_SPRUCE_BAUD_33M
+ IBM Spruce reference platforms are equipped with either a 30Mhz or
+ 33Mhz CPC700 input oscillator. Enable this option only if you
+ have the 33Mhz oscillator.
+
AltiVec kernel support
CONFIG_ALTIVEC
This option enables kernel support for the Altivec extensions to the
@@ -23468,6 +23501,38 @@
/proc/sys/dev/mac_hid/mouse_button2_keycode
/proc/sys/dev/mac_hid/mouse_button3_keycode
+Set high memory pool address
+CONFIG_HIGHMEM_START_BOOL
+ Unless you know what you are doing you *should not* set this option.
+
+ It can be used to override the default PKMAP_BASE address which
+ is the location of the high memory pool. This can be useful in
+ optimizing virtual memory usage in a system.
+
+Set maximum low memory
+CONFIG_LOWMEM_SIZE_BOOL
+ Unless you know what you are doing you *should not* set this option.
+
+ It can be used to override the standard calculated value of
+ MAX_LOW_MEM. This can be useful in optimizing virtual memory usage
+ in a system.
+
+Set custom kernel base address
+CONFIG_KERNEL_START_BOOL
+ Unless you know what you are doing you *should not* set this option.
+
+ It can be used to override the standard PAGE_OFFSET/KERNELBASE
+ value used by the kernel. This can be useful in controlling
+ amount of virtual address space available to the kernel.
+
+Set custom user task size
+CONFIG_TASK_SIZE_BOOL
+ Unless you know what you are doing you *should not* set this option.
+
+ It can be used to override the standard TASK_SIZE value used
+ by the kernel. This can be useful in controlling amount of
+ virtual address space available to user tasks.
+
Enhanced Real Time Clock Support (/dev/rtc)
CONFIG_PPC_RTC
If you say Y here and create a character special file /dev/rtc with
@@ -26405,6 +26470,101 @@
To use this option, you have to check that the "/proc file system
support" (CONFIG_PROC_FS) is enabled, too.
+Use MDIO for PHY configuration
+CONFIG_USE_MDIO
+ This option specifies whether to use MII autoconfiguration in the
+ FCC Ethernet driver or not.
+
+PPC4xx DMA controller support
+CONFIG_PPC4xx_DMA
+ Select this to enable support for the PPC4xx general purpose DMA
+ controller.
+
+ttyS0 device
+CONFIG_UART0_TTYS0
+ This option reverses the mapping between the hardware UART and software
+ device. Selecting UART0 gives the normal mapping of UART0=ttyS0 and
+ UART1=ttyS1. Selecting UART1 gives the reverse mapping of UART0=ttyS1
+ and UART1=ttyS0. Most people will use UART0.
+
+PowerPC 405 on-chip ethernet
+CONFIG_IBM_OCP_ENET
+ If you want to use the 405 built-in ethernet select this.
+
+CONFIG_IBM_OCP_ENET_ERROR_MSG
+ Enable this option to print verbose debug messages for troubleshooting.
+
+PowerPC 405 on-chip ethernet -- Number of receive buffers
+CONFIG_IBM_OCP_ENET_RX_BUFF
+ Number of ethernet receive (read) buffers. Unless you know what you
+ are doing the default should be fine.
+
+PowerPC 405 on-chip ethernet -- Number of transmit buffers
+CONFIG_IBM_OCP_ENET_TX_BUFF
+ Number of ethernet transmit (write) buffers. Unless you know what
+ you are doing the default should be fine.
+
+PowerPC 405 on-chip ethernet -- Amount of bytes to Reserve on a skb
+CONFIG_IBM_OCP_ENET_SKB_RES
+ Many standard ethernet drivers need to reserve 2 bytes of data
+ on the skb before giving the data ptr to the hardware. This is
+ so the IP data will be 16-byte aligned when it goes up the stack.
+ This is a requirement for some processors and it can cause major
+ slow downs on others. The 405GP dose not have problems with the
+ misaligned data so the default is 0. If you need to route the
+ incoming ethernet packets to another device that has alignment
+ requirements this can help remove a data copy. A value of 2 can
+ help at getting 16-byte aligned IP data for another device. A
+ larger value can be used when routing to a IP tunnel device.
+ Make sure XXX_DESC_SIZE - XXX_SKB_RES >= 1514, or larger if VLANS
+ are used.
+
+PPC 405 I2C Algorithm
+CONFIG_PPC405_I2C_ALGO
+ Enable this option to use the built-in I2C on your 405.
+
+PPC 405 I2C Adapter
+CONFIG_PPC405_I2C_ADAP
+ Enable this option to use the built-in I2C on your 405.
+
+BM PPC 405 Watchdog Timer
+CONFIG_PPC405_WDT
+ Enable this option to use the built-in watch dog timer on your 405.
+
+Xilinx Virtex-II Pro on-chip ethernet
+CONFIG_XILINX_ENET
+ If you want to use the Xilinx built-in ethernet select this.
+
+Xilinx Virtex-II Pro TFT display frame buffer
+CONFIG_FB_XILINX
+ If you want to use the Xilinx built-in TFT display select this.
+
+Rotate display
+CONFIG_FB_XILINX_ROTATE
+ Say Y here to rotate the TFT output 180 degrees.
+
+Xilinx Virtex-II Pro I2C
+CONFIG_I2C_XILINX
+ If you want to use the Xilinx built-in I2C select this.
+
+Xilinx Virtex-II Pro GPIO
+CONFIG_XILINX_GPIO
+ If you want to use the Xilinx built-in GPIO select this.
+
+Xilinx Virtex-II Pro System ACE
+CONFIG_XILINX_SYSACE
+ Xilinx has a piece of hardware called the System ACE. It interfaces
+ the processor, the JTAG chain and a CompactFlash. When the system
+ is reset, System ACE reads a file from the CompactFlash that is used
+ to initialize the system via the JTAG interface. After the system is
+ up, the System ACE can be used to give the processor access to the
+ CompactFlash and JTAG chain. If you want Linux to use the
+ CompactFlash as a block device, select this.
+
+Xilinx Virtex-II Pro Touchscreen
+CONFIG_XILINX_TS
+ If you want to use the Xilinx built-in touchscreen select this.
+
/proc/efi/vars support
CONFIG_EFI_VARS
If you say Y here, you are able to get EFI (Extensible Firmware
diff -urN -X bkexcl linux-2.4.22/Documentation/powerpc/405LP-sleep.txt linuxppc-2.4/Documentation/powerpc/405LP-sleep.txt
--- linux-2.4.22/Documentation/powerpc/405LP-sleep.txt 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/Documentation/powerpc/405LP-sleep.txt 2003-06-02 14:37:41.000000000 +1000
@@ -0,0 +1,237 @@
+Hollis Blanchard, IBM Linux Technology Center
+6 Jan 2003
+
+Bishop Brock, IBM Low-Power Computing Research Center
+Revised May, 2003
+
+Linux Sleep on the PowerPC 405LP
+--------------------------------
+
+The IBM 405LP embedded CPU supports three different sleep modes, controlled by
+a unit called "APM0". These three hardware modes have been used to specify
+six different types of sleep. Not all hardware platforms will necessarily
+support all modes of sleep.
+
+APM has four wakeup interrupt lines which it cascades onto the UIC as irq
+24. These "wakeups" function similar to other interrupt sources when the 405LP
+is executing normally. When the 405LP enters a sleep mode, however, the only
+things that can wake it are these four wakeup lines, and the APM (master) reset
+signal. One wakeup line is connected to the RTC interrupt line, allowing wakeup
+when an RTC alarm goes off. The other three wakeups are more-or-less
+programmable and board-dependent. On both Beech and Arctic2 one of the wakeups
+is connected to a physical pushbutton to provide a soft power switch.
+
+Sleep Modes
+-----------
+
+1. In "clock-suspend" mode the output of the PLL is stopped. No units are
+powered down, and so no state is lost. SDRAM must held in self refresh to avoid
+losing SDRAM contents. On wakeup, the PLL continues and processing resumes
+exactly where it left off.
+
+2. In "power-down" mode, APM signals the power supply to drop power to the CPU
+and integrated peripherals. The Linux implementation subdivides this hardware
+mode into four different types of power-down sleep. In simple power-down
+mode, all system state is lost, and the system simply reboots when
+awakened or reset. Linux also supports a "failsafe-power-down" mode similar to
+power-down, except that the APM wakeup mechanism is disabled before going to
+sleep. This mode requires a master reset to restart and reboot the system.
+
+The power-down state can also be used to implement laptop-like suspend modes.
+In these modes all important state, including GPRs, SPRs, and DCRs must be
+saved by software before entering the sleep mode, and restored after wakeup.
+In "suspend" mode SDRAM is not powered off, so state can be saved there as long
+as SDRAM is put into self-refresh mode prior to the sleep. In "hibernate" mode
+the SDRAM contents are copied to non-volatile storage, and then the entire
+system can be powered down. [ This mode has not yet been fully implemented. ]
+
+When a wakeup from power-down occurs, the chip (CPU and integrated peripherals)
+is reset, returning control to the firmware. The firmware must determine
+whether this is a wakeup from a normal power-down, leading to a reboot, or
+wakeup from a suspend or hibernate, requiring restoration of the system
+context. The mechanism used to communicate the sleep mode to the firmware is
+discussed further below.
+
+3. The "standby" mode is a specialized clock-suspend mode unique to the 405LP.
+In "standby" mode, APM first freezes the PLL. It then transfers all chip state
+(excluding CPU core state and peripheral arrays such as the LCD palette) over
+the i2c bus to a nonvolatile storage device (such as an EEPROM). Once that
+process is complete, APM signals the power supply to drop power to the CPU and
+integrated peripherals. To the external system, standby mode appears to be a
+clock stop mode, so , for example, SDRAM must be held in self refresh.
+
+When a wakeup occurs, APM transfers the saved chip state back over the i2c bus.
+The CPU core is reset but held frozen. APM then releases the PLL and processing
+continues from the reset vector, returning control to the firmware. The
+firmware must determine that this is a wakeup from a standby state by by polling
+the APM0_CFG and APM0_SR registers, and taking the appropriate action.
+
+Firmware Interaction with Linux
+-------------------------------
+
+Note that because the CPU is reset on wakeup in both power-down and standby
+modes, the firmware *must* be made APM-aware. Otherwise, a wakeup will simply
+reset the chip, losing all state.
+
+The clock-suspend mode does not require firmware interaction. Linux handles
+the clock-stop, and the clock is restarted exactly at the point where Linux
+stopped the system.
+
+On wake from standby, suspend or hibernate, the firmware must know how to
+transfer control back to Linux (which is still resident in RAM). The following
+structure is used:
+
+struct wakeup_info {
+ void (*wakeup_func_phys)(u32 apm0_cfg, u32 apm0_sr); /* physical addr */
+ u32 magic;
+ ...
+}
+
+Firmware is aware only of the first two fields. Linux creates and populates
+this structure in memory, and writes the pointer to a well-known location
+(currently 0xfc physical) for the firmware to read. (Unfortunately there are
+no "scratch" registers provided by the APM unit, requiring used of a
+predetermined absolute physical address.) The magic number is intended to be a
+simple validator ensuring that the contents of SDRAM have not been corrupted.
+
+Currently Linux also saves one other value in the wakeup_info structure: the
+(physical) stack pointer.
+
+The contents of the APM0_CFG[SM] field are sufficient to identify a standby
+sleep. In order to disambiguate power-down, sleep and hibernate, Linux writes
+a flag value in the RTC0_CEN DCR (RTC century register) before initiating the
+sleep. If firmware detects the resumption from a power-down sleep, it takes
+action based on the flag value it finds in RTC0_CEN.
+
+Linux Sleep Procedure
+---------------------
+
+This is a high-level summary; the code is well-documented. Note that entry into
+all sleep modes is completely handled by Linux.
+
+For clock-suspend mode:
+
+ The power-management callbacks of all devices registered with LDM are
+ invoked.
+
+ Since this is a simple clock-suspend, no CPU or DCR state is saved, and
+ the clocks are simply stopped after placing SDRAM in self-refresh.
+
+For power-down and failsafe-power-down mode:
+
+ Since this is a simple power-down, no CPU or DCR state is saved, and
+ APM is commanded to power-down the system.
+
+For suspend and standby modes:
+
+ The power-management callbacks of all devices registered with LDM are
+ invoked.
+
+ For suspend mode, Linux marks the mode for the firmware by a flag in
+ RTC0_CEN.
+
+ One page is allocated in which to save some CPU registers and selected
+ DCRs required by the mode. For suspend mode, some system-level DCRs
+ not associated with a specific device driver (e.g., EBC, UIC) are
+ saved. In standby mode all registers external to the CPU are saved and
+ restored by the hardware mechanism, and only the APM_CFG and APM0_SR
+ registers and the SDRAM_CFG register will be touched by the firmware on
+ wakeup.
+
+ The non-volatile GPRs, all 64 TLB entries, and quite a few SPRs like LR,
+ MSR, and EVPR are saved to the stack in an assembly routine. The registers
+ saved here are those that must be restored before returning into C code on
+ wakeup; i.e. they cannot be saved and restored in C.
+
+ SDRAM is placed in self-refresh before initiating power-down.
+
+
+The final code is touched into the I-cache so that SDRAM can be put into
+self-refresh. The sleep command is written to the APM unit, and then the
+processor spins in a bdnz loop until either:
+1. the APM unit freezes the processor
+2. the CTR register decrements to zero, indicating sleep did not take place.
+This could happen if the wakeup were already asserted at the time the sleep
+command was issued.
+
+Firmware/Linux Wakeup Procedure
+-------------------------------
+
+If the firmware detects the resumption from a standby sleep, the firmware
+should only bring the SDRAM out of self-refresh, and then restart Linux as
+explained below. If firmware detects the resumption from a suspend sleep, the
+firmware should perform the normal board setup (including establishing the
+default operating point) up to re-enabling the SDRAM controller, and then
+resume Linux as explained below. In any other case the firmware reboots the
+system.
+
+To restart Linux, after validating the magic number the firmware jumps to the
+address specified by wakeup_info->wakeup_func_phys . The processor *must* be
+in untranslated mode (MSR:IR/DR = 0) at this point.
+
+Back in Linux, the stack pointer is immediately restored from
+wakeup_info->wakeup_sp_phys so that SPRs can be loaded and restored from the
+stack. Finally, the non-volatile GPRs are restored, and control returns via an
+rfi to the C function executed before sleep, returning to translated mode
+(MSR:IR/DR = 1). The C function continues to restore non-essential registers
+which were not handled in assembly.
+
+The RTC remains active during sleep, but the timebase does not, and obviously
+jiffies has not been incremented. To restore the timebase, the pre-sleep RTC
+time is subtracted from the current RTC time to get the difference in seconds,
+and then the timebase is incremented by
+
+(seconds elapsed) * HZ * tb_ticks_per_jiffy
+
+
+User Interfaces
+---------------
+
+One of the interfaces to the sleep code is via sysctl (and its /proc
+interface). The following /proc items are present under /proc/sys/sleep :
+ suspend: (write-only)
+ triggers sleep
+ mode: (string)
+ contains one of "clock-suspend", "power-down",
+ "failsafe-power-down", "suspend", "hibernate" or "standby",
+ indicating the sleep mode to be used.
+ pm_alarm: (string)
+ See below.
+ cdiv: (integer, for debugging only)
+ allows the user to override the "cdiv" field of APM0_CFG, which
+ controls the speed at which CPU state is transferred over the i2c bus.
+ watchdog: (integer, for debugging only)
+ allows user to disable the APM watchdog. Defaults to 1 (meaning the
+ watchdog is enabled).
+
+
+The pm_alarm entry can be used to program a wakeup using the RTC alarm
+mechanism. If enabled at system shutdown, this alarm will wake up the
+processor from any of the sleep modes except failsafe-power-down. To program an
+alarm, write an 8-character string of the form hh:mm:ss (using a 24-hour clock)
+to /proc/sys/sleep/pm_alarm. To indicate a don't-care value use an illegal
+value, e.g., 99. For example, writing "09:30:99" sets the alarm for 9:30 AM.
+Write the string "clear" to clear the alarm. Reading the /proc file will
+return the current alarm time followed by either "clear", "armed" or "expired".
+This alarm mechanism only guarantees that the system will be awake when the
+alarm goes off. NB: The RTC and system clocks may not be in sync; see 'man
+hwclock'.
+
+A generic button driver for a soft power switch connected to an APM wakeup
+input is also provided. Pressing and releasing the button will initiate sleep
+using the current 'mode'. If the button is pressed and held continuously for 5
+seconds the failsafe-power-down mode is entered. Pressing the button on a
+sleeping system will wake it up (unless it was forced off using the
+failsafe-power-down mode).
+
+
+Other Issues
+------------
+
+Standby mode can only be safely entered and exited in a
+well-constructed PLL bypass operating point that must be supplied by
+board support code. If this state is not defined then "clocksuspend"
+mode is substituted for "standby". We assume that the EEPROM is
+properly programmed for standby mode.
+
+
diff -urN -X bkexcl linux-2.4.22/arch/ppc/8xx_io/commproc.c linuxppc-2.4/arch/ppc/8xx_io/commproc.c
--- linux-2.4.22/arch/ppc/8xx_io/commproc.c 2003-02-15 08:07:09.000000000 +1100
+++ linuxppc-2.4/arch/ppc/8xx_io/commproc.c 2003-03-21 08:08:33.000000000 +1100
@@ -53,7 +53,8 @@
};
static struct cpm_action cpm_vecs[CPMVEC_NR];
static void cpm_interrupt(int irq, void * dev, struct pt_regs * regs);
-static void cpm_error_interrupt(int irq, void *, struct pt_regs * regs);
+static void cpm_error_interrupt(int irq, void *dev, struct pt_regs *regs);
+static void alloc_host_memory(void);
/* Define a table of names to identify CPM interrupt handlers in
* /proc/interrupts.
@@ -104,7 +105,7 @@
};
void
-m8xx_cpm_reset(uint host_page_addr)
+m8xx_cpm_reset()
{
volatile immap_t *imp;
volatile cpm8xx_t *commproc;
@@ -130,7 +131,7 @@
* this is what we realy want for some applications, but the
* manual recommends it.
* Bit 25, FAM can also be set to use FEC aggressive mode (860T).
- */
+ */
imp->im_siu_conf.sc_sdcr = 1;
/* Reclaim the DP memory for our use.
@@ -138,25 +139,23 @@
dp_alloc_base = CPM_DATAONLY_BASE;
dp_alloc_top = dp_alloc_base + CPM_DATAONLY_SIZE;
- /* Set the host page for allocation.
+ /* Tell everyone where the comm processor resides.
*/
- host_buffer = host_page_addr; /* Host virtual page address */
- host_end = host_page_addr + PAGE_SIZE;
+ cpmp = (cpm8xx_t *)commproc;
+}
- /* We need to get this page early, so I have to do it the
- * hard way.
- */
- if (get_pteptr(&init_mm, host_page_addr, &pte)) {
- pte_val(*pte) |= _PAGE_NO_CACHE;
- flush_tlb_page(init_mm.mmap, host_buffer);
- }
- else {
- panic("Huh? No CPM host page?");
- }
+/* We used to do this earlier, but have to postpone as long as possible
+ * to ensure the kernel VM is now running.
+ */
+static void
+alloc_host_memory()
+{
+ uint physaddr;
- /* Tell everyone where the comm processor resides.
+ /* Set the host page for allocation.
*/
- cpmp = (cpm8xx_t *)commproc;
+ host_buffer = (uint)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &physaddr);
+ host_end = host_buffer + PAGE_SIZE;
}
/* This is called during init_IRQ. We used to do it above, but this
@@ -321,6 +320,9 @@
{
uint retloc;
+ if (host_buffer == 0)
+ alloc_host_memory();
+
if ((host_buffer + size) >= host_end)
return(0);
diff -urN -X bkexcl linux-2.4.22/arch/ppc/8xx_io/enet.c linuxppc-2.4/arch/ppc/8xx_io/enet.c
--- linux-2.4.22/arch/ppc/8xx_io/enet.c 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/8xx_io/enet.c 2003-07-25 02:06:49.000000000 +1000
@@ -137,6 +137,11 @@
cbd_t *cur_rx, *cur_tx; /* The next free ring entry */
cbd_t *dirty_tx; /* The ring entries to be free()ed. */
scc_t *sccp;
+
+ /* Virtual addresses for the receive buffers because we can't
+ * do a __va() on them anymore.
+ */
+ unsigned char *rx_vaddr[RX_RING_SIZE];
struct net_device_stats stats;
uint tx_free;
spinlock_t lock;
@@ -498,7 +503,7 @@
skb->dev = dev;
skb_put(skb,pkt_len-4); /* Make room */
eth_copy_and_sum(skb,
- (unsigned char *)__va(bdp->cbd_bufaddr),
+ cep->rx_vaddr[bdp - cep->rx_bd_base],
pkt_len-4, 0);
skb->protocol=eth_type_trans(skb,dev);
netif_rx(skb);
@@ -632,10 +637,9 @@
{
struct net_device *dev;
struct scc_enet_private *cep;
- int i, j;
- unsigned char *eap;
- unsigned long mem_addr;
- pte_t *pte;
+ int i, j, k;
+ unsigned char *eap, *ba;
+ dma_addr_t mem_addr;
bd_t *bd;
volatile cbd_t *bdp;
volatile cpm8xx_t *cp;
@@ -826,24 +830,21 @@
bdp->cbd_sc |= BD_SC_WRAP;
bdp = cep->rx_bd_base;
+ k = 0;
for (i=0; icbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR;
- bdp->cbd_bufaddr = __pa(mem_addr);
+ bdp->cbd_bufaddr = mem_addr;
+ cep->rx_vaddr[k++] = ba;
mem_addr += CPM_ENET_RX_FRSIZE;
+ ba += CPM_ENET_RX_FRSIZE;
bdp++;
}
}
diff -urN -X bkexcl linux-2.4.22/arch/ppc/8xx_io/fec.c linuxppc-2.4/arch/ppc/8xx_io/fec.c
--- linux-2.4.22/arch/ppc/8xx_io/fec.c 2003-07-30 23:33:24.000000000 +1000
+++ linuxppc-2.4/arch/ppc/8xx_io/fec.c 2003-08-05 09:59:45.000000000 +1000
@@ -161,7 +161,12 @@
cbd_t *tx_bd_base;
cbd_t *cur_rx, *cur_tx; /* The next free ring entry */
cbd_t *dirty_tx; /* The ring entries to be free()ed. */
- scc_t *sccp;
+
+ /* Virtual addresses for the receive buffers because we can't
+ * do a __va() on them anymore.
+ */
+ unsigned char *rx_vaddr[RX_RING_SIZE];
+
struct net_device_stats stats;
uint tx_free;
spinlock_t lock;
@@ -587,7 +592,7 @@
fep->stats.rx_packets++;
pkt_len = bdp->cbd_datlen;
fep->stats.rx_bytes += pkt_len;
- data = (__u8*)__va(bdp->cbd_bufaddr);
+ data = fep->rx_vaddr[bdp - fep->rx_bd_base];
/* This does 16 byte alignment, exactly what we need.
* The packet length includes FCS, but we don't want to
@@ -602,9 +607,7 @@
} else {
skb->dev = dev;
skb_put(skb,pkt_len-4); /* Make room */
- eth_copy_and_sum(skb,
- (unsigned char *)__va(bdp->cbd_bufaddr),
- pkt_len-4, 0);
+ eth_copy_and_sum(skb, data, pkt_len-4, 0);
skb->protocol=eth_type_trans(skb,dev);
netif_rx(skb);
}
@@ -1700,10 +1703,9 @@
{
struct net_device *dev;
struct fec_enet_private *fep;
- int i, j;
- unsigned char *eap, *iap;
+ int i, j, k;
+ unsigned char *eap, *iap, *ba;
unsigned long mem_addr;
- pte_t *pte;
volatile cbd_t *bdp;
cbd_t *cbd_base;
volatile immap_t *immap;
@@ -1774,14 +1776,7 @@
printk("FEC initialization failed.\n");
return 1;
}
- mem_addr = __get_free_page(GFP_KERNEL);
- cbd_base = (cbd_t *)mem_addr;
-
- /* Make it uncached.
- */
- pte = va_to_pte(mem_addr);
- pte_val(*pte) |= _PAGE_NO_CACHE;
- flush_tlb_page(init_mm.mmap, mem_addr);
+ cbd_base = (cbd_t *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr);
/* Set receive and transmit descriptor base.
*/
@@ -1793,24 +1788,21 @@
/* Initialize the receive buffer descriptors.
*/
bdp = fep->rx_bd_base;
+ k = 0;
for (i=0; icbd_sc = BD_ENET_RX_EMPTY;
- bdp->cbd_bufaddr = __pa(mem_addr);
+ bdp->cbd_bufaddr = mem_addr;
+ fep->rx_vaddr[k++] = ba;
mem_addr += FEC_ENET_RX_FRSIZE;
+ ba += FEC_ENET_RX_FRSIZE;
bdp++;
}
}
@@ -1974,8 +1966,8 @@
/* Set receive and transmit descriptor base.
*/
- fecp->fec_r_des_start = __pa((uint)(fep->rx_bd_base));
- fecp->fec_x_des_start = __pa((uint)(fep->tx_bd_base));
+ fecp->fec_r_des_start = iopa((uint)(fep->rx_bd_base));
+ fecp->fec_x_des_start = iopa((uint)(fep->tx_bd_base));
fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
fep->tx_free = TX_RING_SIZE;
diff -urN -X bkexcl linux-2.4.22/arch/ppc/8xx_io/uart.c linuxppc-2.4/arch/ppc/8xx_io/uart.c
--- linux-2.4.22/arch/ppc/8xx_io/uart.c 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/8xx_io/uart.c 2003-07-25 02:06:49.000000000 +1000
@@ -218,6 +218,12 @@
cbd_t *rx_cur;
cbd_t *tx_bd_base;
cbd_t *tx_cur;
+
+ /* Virtual addresses for the FIFOs because we can't __va() a
+ * physical address anymore.
+ */
+ unsigned char *rx_va_base;
+ unsigned char *tx_va_base;
} ser_info_t;
static struct console sercons = {
@@ -394,7 +400,7 @@
/* Get the number of characters and the buffer pointer.
*/
i = bdp->cbd_datlen;
- cp = (unsigned char *)__va(bdp->cbd_bufaddr);
+ cp = info->rx_va_base + ((bdp - info->rx_bd_base) * RX_BUF_SIZE);
status = bdp->cbd_sc;
#ifdef CONFIG_KGDB
@@ -1042,6 +1048,7 @@
{
ser_info_t *info = (ser_info_t *)tty->driver_data;
volatile cbd_t *bdp;
+ unsigned char *cp;
if (serial_paranoia_check(info, tty->device, "rs_put_char"))
return;
@@ -1052,7 +1059,8 @@
bdp = info->tx_cur;
while (bdp->cbd_sc & BD_SC_READY);
- *((char *)__va(bdp->cbd_bufaddr)) = ch;
+ cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
+ *cp = ch;
bdp->cbd_datlen = 1;
bdp->cbd_sc |= BD_SC_READY;
@@ -1073,6 +1081,7 @@
int c, ret = 0;
ser_info_t *info = (ser_info_t *)tty->driver_data;
volatile cbd_t *bdp;
+ unsigned char *cp;
#ifdef CONFIG_KGDB_CONSOLE
/* Try to let stub handle output. Returns true if it did. */
@@ -1099,14 +1108,15 @@
break;
}
+ cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
if (from_user) {
- if (copy_from_user(__va(bdp->cbd_bufaddr), buf, c)) {
+ if (copy_from_user((void *)cp, buf, c)) {
if (!ret)
ret = -EFAULT;
break;
}
} else {
- memcpy(__va(bdp->cbd_bufaddr), buf, c);
+ memcpy((void *)cp, buf, c);
}
bdp->cbd_datlen = c;
@@ -1181,6 +1191,7 @@
static void rs_8xx_send_xchar(struct tty_struct *tty, char ch)
{
volatile cbd_t *bdp;
+ unsigned char *cp;
ser_info_t *info = (ser_info_t *)tty->driver_data;
@@ -1190,7 +1201,8 @@
bdp = info->tx_cur;
while (bdp->cbd_sc & BD_SC_READY);
- *((char *)__va(bdp->cbd_bufaddr)) = ch;
+ cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
+ *cp = ch;
bdp->cbd_datlen = 1;
bdp->cbd_sc |= BD_SC_READY;
@@ -2217,6 +2229,11 @@
#ifdef CONFIG_SERIAL_CONSOLE
+/* I need this just so I can store the virtual addresses and have
+ * common functions for the early console printing.
+ */
+static ser_info_t consinfo;
+
/*
* Print a string to the serial port trying not to disturb any possible
* real use of the port...
@@ -2249,6 +2266,8 @@
/* Get the address of the host memory buffer.
*/
bdp = bdbase = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
+
+ info = &consinfo;
}
/*
@@ -2276,7 +2295,7 @@
if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR)
cp = (u_char *)(bdp->cbd_bufaddr);
else
- cp = __va(bdp->cbd_bufaddr);
+ cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
*cp = *s;
bdp->cbd_datlen = 1;
@@ -2290,7 +2309,7 @@
/* if a LF, also do CR... */
if (*s == 10) {
while (bdp->cbd_sc & BD_SC_READY);
- cp = __va(bdp->cbd_bufaddr);
+ cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
*cp = 13;
bdp->cbd_datlen = 1;
bdp->cbd_sc |= BD_SC_READY;
@@ -2358,10 +2377,13 @@
* If the port has been initialized for general use, we must
* use information from the port structure.
*/
- if ((info = (ser_info_t *)ser->info))
+ if ((info = (ser_info_t *)ser->info)) {
bdp = info->rx_cur;
- else
+ }
+ else {
bdp = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase];
+ info = &consinfo;
+ }
/*
* We need to gracefully shut down the receiver, disable
@@ -2383,7 +2405,7 @@
if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR)
cp = (u_char *)(bdp->cbd_bufaddr);
else
- cp = __va(bdp->cbd_bufaddr);
+ cp = info->rx_va_base + ((bdp - info->rx_bd_base) * RX_BUF_SIZE);
if (obuf) {
i = c = bdp->cbd_datlen;
@@ -2704,6 +2726,7 @@
/* Allocate space for FIFOs in the host memory.
*/
mem_addr = m8xx_cpm_hostalloc(RX_NUM_FIFO * RX_BUF_SIZE);
+ info->rx_va_base = (unsigned char *)mem_addr;
/* Set the physical address of the host memory
* buffers in the buffer descriptors, and the
@@ -2713,12 +2736,12 @@
info->rx_cur = info->rx_bd_base = (cbd_t *)bdp;
for (j=0; j<(RX_NUM_FIFO-1); j++) {
- bdp->cbd_bufaddr = __pa(mem_addr);
+ bdp->cbd_bufaddr = iopa(mem_addr);
bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
mem_addr += RX_BUF_SIZE;
bdp++;
}
- bdp->cbd_bufaddr = __pa(mem_addr);
+ bdp->cbd_bufaddr = iopa(mem_addr);
bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
idx = PORT_NUM(info->state->smc_scc_num);
@@ -2738,6 +2761,7 @@
/* Allocate space for FIFOs in the host memory.
*/
mem_addr = m8xx_cpm_hostalloc(TX_NUM_FIFO * TX_BUF_SIZE);
+ info->tx_va_base = (unsigned char *)mem_addr;
/* Set the physical address of the host memory
* buffers in the buffer descriptors, and the
@@ -2747,12 +2771,12 @@
info->tx_cur = info->tx_bd_base = (cbd_t *)bdp;
for (j=0; j<(TX_NUM_FIFO-1); j++) {
- bdp->cbd_bufaddr = __pa(mem_addr);
+ bdp->cbd_bufaddr = iopa(mem_addr);
bdp->cbd_sc = BD_SC_INTRPT;
mem_addr += TX_BUF_SIZE;
bdp++;
}
- bdp->cbd_bufaddr = __pa(mem_addr);
+ bdp->cbd_bufaddr = iopa(mem_addr);
bdp->cbd_sc = (BD_SC_WRAP | BD_SC_INTRPT);
if (PORT_IS_SCC(info->state->smc_scc_num)) {
@@ -2959,20 +2983,28 @@
* from dual port ram, and a character buffer area from host mem.
*/
+ /* Allocate space for two FIFOs. We can't allocate from host
+ * memory yet because vm allocator isn't initialized
+ * during this early console init.
+ */
+ dp_addr = m8xx_cpm_dpalloc(8);
+ mem_addr = (uint)(&cpmp->cp_dpmem[dp_addr]);
+
/* Allocate space for two buffer descriptors in the DP ram.
*/
dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * 2);
- /* Allocate space for two 2 byte FIFOs in the host memory.
- */
- mem_addr = m8xx_cpm_hostalloc(8);
-
/* Set the physical address of the host memory buffers in
* the buffer descriptors.
*/
bdp = (cbd_t *)&cp->cp_dpmem[dp_addr];
- bdp->cbd_bufaddr = __pa(mem_addr);
- (bdp+1)->cbd_bufaddr = __pa(mem_addr+4);
+ bdp->cbd_bufaddr = iopa(mem_addr);
+ (bdp+1)->cbd_bufaddr = iopa(mem_addr+4);
+
+ consinfo.rx_va_base = mem_addr;
+ consinfo.rx_bd_base = bdp;
+ consinfo.tx_va_base = mem_addr + 4;
+ consinfo.tx_bd_base = bdp+1;
/* For the receive, set empty and wrap.
* For transmit, set wrap.
diff -urN -X bkexcl linux-2.4.22/arch/ppc/Makefile linuxppc-2.4/arch/ppc/Makefile
--- linux-2.4.22/arch/ppc/Makefile 2003-06-25 20:56:52.000000000 +1000
+++ linuxppc-2.4/arch/ppc/Makefile 2003-08-02 07:10:51.000000000 +1000
@@ -14,7 +14,7 @@
#
# Be sure to change PAGE_OFFSET in include/asm-ppc/page.h to match
-KERNELLOAD =0xc0000000
+KERNELLOAD =$(CONFIG_KERNEL_START)
LINKFLAGS = -T arch/ppc/vmlinux.lds -Ttext $(KERNELLOAD) -Bstatic
CPPFLAGS := $(CPPFLAGS) -I$(TOPDIR)/arch/$(ARCH)
@@ -45,12 +45,16 @@
ifdef CONFIG_40x
HEAD := arch/ppc/kernel/head_4xx.o
else
- ifdef CONFIG_8xx
- HEAD := arch/ppc/kernel/head_8xx.o
+ ifdef CONFIG_440
+ HEAD := arch/ppc/kernel/head_440.o
else
- HEAD := arch/ppc/kernel/head.o
- ifdef CONFIG_6xx
- HEAD += arch/ppc/kernel/idle_6xx.o
+ ifdef CONFIG_8xx
+ HEAD := arch/ppc/kernel/head_8xx.o
+ else
+ HEAD := arch/ppc/kernel/head.o
+ ifdef CONFIG_6xx
+ HEAD += arch/ppc/kernel/idle_6xx.o
+ endif
endif
endif
endif
diff -urN -X bkexcl linux-2.4.22/arch/ppc/boot/common/crt0.S linuxppc-2.4/arch/ppc/boot/common/crt0.S
--- linux-2.4.22/arch/ppc/boot/common/crt0.S 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/boot/common/crt0.S 2003-07-25 02:06:49.000000000 +1000
@@ -66,7 +66,7 @@
bdnz 1b # If we are not done yet, keep clearing
2:
-#ifdef CONFIG_4xx
+#ifdef CONFIG_40x
## Set up the stack
lis r9,_start@h # r9 = &_start (text section entry)
diff -urN -X bkexcl linux-2.4.22/arch/ppc/boot/common/misc-simple.c linuxppc-2.4/arch/ppc/boot/common/misc-simple.c
--- linux-2.4.22/arch/ppc/boot/common/misc-simple.c 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/boot/common/misc-simple.c 2003-07-25 02:06:49.000000000 +1000
@@ -75,14 +75,6 @@
extern void gunzip(void *, int, unsigned char *, int *);
extern void serial_fixups(void);
-/* Allow decompress_kernel to be hooked into. This is the default. */
-void * __attribute__ ((weak))
-load_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
- void *bp)
-{
- return decompress_kernel(load_addr, num_words, cksum, bp);
-}
-
struct bi_record *
decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
{
@@ -271,3 +263,10 @@
return (struct bi_record *)rec_loc;
}
+
+/* Allow decompress_kernel to be hooked into. This is the default. */
+struct bi_record * __attribute__ ((weak))
+load_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
+{
+ return decompress_kernel(load_addr, num_words, cksum);
+}
diff -urN -X bkexcl linux-2.4.22/arch/ppc/boot/common/util.S linuxppc-2.4/arch/ppc/boot/common/util.S
--- linux-2.4.22/arch/ppc/boot/common/util.S 2003-02-27 08:13:38.000000000 +1100
+++ linuxppc-2.4/arch/ppc/boot/common/util.S 2003-03-28 08:48:01.000000000 +1100
@@ -160,9 +160,22 @@
blr
+/* udelay (on non-601 processors) needs to know the period of the
+ * timebase in nanoseconds. This used to be hardcoded to be 60ns
+ * (period of 66MHz/4). Now a variable is used that is initialized to
+ * 60 for backward compatibility, but it can be overridden as necessary
+ * with code something like this:
+ * extern unsigned long timebase_period_ns;
+ * timebase_period_ns = 1000000000 / bd->bi_tbfreq;
+ */
+ .data
+ .globl timebase_period_ns
+timebase_period_ns:
+ .long 60
+
+ .text
/*
* Delay for a number of microseconds
- * -- Use the BUS timer (assumes 66MHz)
*/
.globl udelay
udelay:
@@ -180,8 +193,13 @@
.udelay_not_601:
mulli r4,r3,1000 /* nanoseconds */
- addi r4,r4,59
- li r5,60
+ /* Change r4 to be the number of ticks using:
+ * (nanoseconds + (timebase_period_ns - 1 )) / timebase_period_ns
+ * timebase_period_ns defaults to 60 (16.6MHz) */
+ lis r5,timebase_period_ns@h
+ lwz r5,timebase_period_ns@l(r5)
+ addi r4,r4,r5
+ addi r4,r4,-1
divw r4,r4,r5 /* BUS ticks */
1: mftbu r5
mftb r6
diff -urN -X bkexcl linux-2.4.22/arch/ppc/boot/simple/Makefile linuxppc-2.4/arch/ppc/boot/simple/Makefile
--- linux-2.4.22/arch/ppc/boot/simple/Makefile 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/boot/simple/Makefile 2003-07-25 02:06:49.000000000 +1000
@@ -22,6 +22,22 @@
# Normally, we use the 'misc-simple.c' file for decompress_kernel and
# whatnot. Sometimes we need to override this however.
MISC := ../common/misc-simple.o
+ifeq ($(CONFIG_ARCTIC2),y)
+ZIMAGE := zImage-TREE
+ZIMAGEINITRD := zImage.initrd-TREE
+ZNETBOOT := zImage.treeboot
+ZNETBOOTRD := zImage.initrd.treeboot
+TFTPIMAGE := /tftpboot/zImage.embedded
+MISC := misc-embedded.o
+endif
+ifeq ($(CONFIG_IBM_OPENBIOS),y)
+ZIMAGE := zImage-TREE
+ZIMAGEINITRD := zImage.initrd-TREE
+ZNETBOOT := zImage.treeboot
+ZNETBOOTRD := zImage.initrd.treeboot
+TFTPIMAGE := /tftpboot/zImage.embedded
+MISC := misc-embedded.o
+endif
ifeq ($(CONFIG_EMBEDDEDBOOT),y)
ZIMAGE := zImage-EMBEDDED
ZIMAGEINITRD := zImage.initrd-EMBEDDED
@@ -33,6 +49,14 @@
ZIMAGEINITRD := zImage.initrd-SMON
TFTPIMAGE := /tftpboot/zImage.gemini
endif
+ifeq ($(CONFIG_EBONY),y)
+ZIMAGE := zImage-EBONY
+ZIMAGEINITRD := zImage.initrd-EBONY
+EXTRA := misc-ebony.o
+ZNETBOOT := zImage.ebony
+ZNETBOOTRD := zImage.initrd.ebony
+TFTPIMAGE := /tftpboot/zImage.ebony
+endif
# kbuild-2.4 'feature', only one of these will ever by 'y' at a time.
# The rest will be unset.
ifeq ($(CONFIG_LOPEC)$(CONFIG_PPLUS),y)
@@ -68,9 +92,12 @@
ifdef CONFIG_8xx
LD_ARGS := -T ../ld.script -Ttext 0x00180000 -Bstatic
endif
-ifeq ($(CONFIG_8260)$(CONFIG_4xx),y)
+ifeq ($(CONFIG_8260)$(CONFIG_40x),y)
LD_ARGS := -T ../ld.script -Ttext 0x00400000 -Bstatic
endif
+ifdef CONFIG_440
+LD_ARGS := -T ../ld.script -Ttext 0x01000000 -Bstatic
+endif
OBJCOPY_ARGS := -O elf32-powerpc
# head.o and ../common/relocate.o must be at the start.
@@ -140,6 +167,12 @@
cp ../images/zImage.* $(TFTPIMAGE)
endif
+zImage-EBONY: zvmlinux
+ $(MKTREE) zvmlinux ../images/zImage.ebony 0x1000000
+
+zImage.initrd-EBONY: zvmlinux.initrd
+ $(MKTREE) zvmlinux.initrd ../images/zImage.initrd.ebony 0x1000000
+
zImage-EMBEDDED: zvmlinux
mv zvmlinux ../images/zImage.embedded
@@ -167,7 +200,7 @@
dd if=zvmlinux.initrd of=../images/zImage.initrd.gemini skip=64 bs=1k
zImage-TREE: zvmlinux
- $(MKTREE) zvmlinux ../images/zImage.$(END) $(ENTRYPOINT)
+ $(MKTREE) zvmlinux ../images/zImage.treeboot
zImage.initrd-TREE: zvmlinux.initrd
$(MKTREE) zvmlinux.initrd ../images/zImage.initrd.$(END) $(ENTRYPOINT)
diff -urN -X bkexcl linux-2.4.22/arch/ppc/boot/simple/embed_config.c linuxppc-2.4/arch/ppc/boot/simple/embed_config.c
--- linux-2.4.22/arch/ppc/boot/simple/embed_config.c 2003-07-30 23:33:24.000000000 +1000
+++ linuxppc-2.4/arch/ppc/boot/simple/embed_config.c 2003-08-05 09:59:45.000000000 +1000
@@ -9,6 +9,7 @@
#include
#include
+#include
#ifdef CONFIG_8xx
#include
#endif
@@ -16,12 +17,8 @@
#include
#include
#endif
-#ifdef CONFIG_4xx
#include
-#endif
-#if defined(CONFIG_405GP) || defined(CONFIG_NP405H) || defined(CONFIG_NP405L)
-#include
-#endif
+extern unsigned long timebase_period_ns;
/* For those boards that don't provide one.
*/
@@ -640,7 +637,7 @@
}
#endif /* WILLOW */
-#ifdef CONFIG_TREEBOOT
+#ifdef CONFIG_IBM_OPENBIOS
/* This could possibly work for all treeboot roms.
*/
#define BOARD_INFO_VECTOR 0xFFFE0B50
@@ -654,16 +651,12 @@
bd_t *(*get_board_info)(void) =
(bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR);
#if !defined(CONFIG_STB03xxx)
- volatile emac_t *emacp;
- emacp = (emac_t *)EMAC0_BASE; /* assume 1st emac - armin */
-
/* shut down the Ethernet controller that the boot rom
* sometimes leaves running.
*/
- mtdcr(DCRN_MALCR, MALCR_MMSR); /* 1st reset MAL */
- while (mfdcr(DCRN_MALCR) & MALCR_MMSR) {}; /* wait for the reset */
- emacp->em0mr0 = 0x20000000; /* then reset EMAC */
- eieio();
+ mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); /* 1st reset MAL */
+ while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; /* wait for the reset */
+ out_be32((u32 *)EMAC0_BASE,0x20000000); /* then reset EMAC */
#endif
bd = &bdinfo;
@@ -707,13 +700,85 @@
}
#endif
+#ifdef CONFIG_ARCTIC2
+/* Several bootloaders have been used on the Arctic. We assume either
+ * SSX or PIBS */
+
+#define SSX_BIOS_ADDR 0xFFFF0000
+#define SSX_BIOS_GET_BOARD_INFO 0
+#define PIBS_BOARD_INFO_VECTOR 0xFFF62004
+
+struct ssx_bios_id {
+ unsigned int boot_branch; /* Branch to bootcode */
+ char ssx_bios[8]; /* "SSX BIOS" (no \0) */
+ void (*bios_entry_point)(unsigned int, bd_t *); /* Call bios_entry_point(cmd, &data) */
+};
+
+extern int memcmp(const void *s1, const void *s2, size_t n);
+
+static void get_board_info(bd_t **bdp)
+{
+ struct ssx_bios_id *ssx = (struct ssx_bios_id *)SSX_BIOS_ADDR;
+
+ /* Check for SSX signature */
+
+ if (memcmp(&ssx->ssx_bios, "SSX BIOS", 8) == 0) {
+ ssx->bios_entry_point(SSX_BIOS_GET_BOARD_INFO, *bdp);
+ } else {
+ /* It's not SSX, so assume PIBS */
+ typedef void (*PFV)(bd_t *bd);
+ ((PFV)(*(unsigned long *)PIBS_BOARD_INFO_VECTOR))(*bdp);
+ }
+}
+
+void embed_config(bd_t **bdp)
+{
+ *bdp = &bdinfo;
+ get_board_info(bdp);
+#if 0
+ /* Enable RefClk/4 mode for both UARTs */
+ mtdcr(DCRN_CPC0_CR0, mfdcr(DCRN_CPC0_CR0) | 0x30000000);
+#endif
+ timebase_period_ns = 1000000000 / bdinfo.bi_tbfreq;
+}
+
+#endif
+
#ifdef CONFIG_EP405
+#include
+
void
embed_config(bd_t **bdp)
{
+ u32 chcr0;
u_char *cp;
bd_t *bd;
+ /* Different versions of the PlanetCore firmware vary in how
+ they set up the serial port - in particular whether they
+ use the internal or external serial clock for UART0. Make
+ sure the UART is in a known state. */
+ /* FIXME: We should use the board's 11.0592MHz external serial
+ clock - it will be more accurate for serial rates. For
+ now, however the baud rates in ep405.h are for the internal
+ clock. */
+ chcr0 = mfdcr(DCRN_CHCR0);
+ if ( (chcr0 & 0x1fff) != 0x103e ) {
+ mtdcr(DCRN_CHCR0, (chcr0 & 0xffffe000) | 0x103e);
+ /* The following tricks serial_init() into resetting
+ * the baud rate */
+ writeb(0, UART0_IO_BASE + UART_LCR);
+ }
+
+ /* We haven't seen actual problems with the EP405 leaving the
+ * EMAC running (as we have on Walnut). But the registers
+ * suggest it may not be left completely quiescent. Reset it
+ * just to be sure. */
+ mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); /* 1st reset MAL */
+ while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR)
+ ; /* wait for the reset */
+ out_be32((u32 *)EMAC0_BASE,0x20000000); /* then reset EMAC */
+
bd = &bdinfo;
*bdp = bd;
#if 1
diff -urN -X bkexcl linux-2.4.22/arch/ppc/boot/simple/head.S linuxppc-2.4/arch/ppc/boot/simple/head.S
--- linux-2.4.22/arch/ppc/boot/simple/head.S 2003-02-27 08:13:38.000000000 +1100
+++ linuxppc-2.4/arch/ppc/boot/simple/head.S 2003-03-28 08:48:01.000000000 +1100
@@ -35,8 +35,8 @@
.globl start
start:
bl start_
-#ifdef CONFIG_TREEBOOT
- /* The IBM "Tree" bootrom knows that the address of the bootrom
+#ifdef CONFIG_IBM_OPENBIOS
+ /* The IBM OpenBIOS bootroms know that the address of the bootrom
* read only structure is 4 bytes after _start.
*/
.long 0x62726f6d # structure ID - "brom"
diff -urN -X bkexcl linux-2.4.22/arch/ppc/boot/simple/misc-ebony.c linuxppc-2.4/arch/ppc/boot/simple/misc-ebony.c
--- linux-2.4.22/arch/ppc/boot/simple/misc-ebony.c 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/boot/simple/misc-ebony.c 2003-03-28 08:48:01.000000000 +1100
@@ -0,0 +1,34 @@
+/*
+ * arch/ppc/simple/misc-ebony.c
+ *
+ * Misc. bootloader code for IBM Ebony reference platform
+ *
+ * based on code by Matt Porter
+ *
+ * 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
+
+extern unsigned long timebase_period_ns;
+extern struct bi_record *decompress_kernel(unsigned long load_addr,
+ int num_words, unsigned long cksum);
+
+struct bi_record *
+load_kernel(unsigned long load_addr, int num_words, unsigned long cksum)
+{
+ timebase_period_ns = 3;
+
+ mtdcr(DCRN_MALCR(DCRN_MAL_BASE), MALCR_MMSR); /* reset MAL */
+ while (mfdcr(DCRN_MALCR(DCRN_MAL_BASE)) & MALCR_MMSR) {}; /* wait for reset */
+ *(volatile unsigned long *)EBONY_EMAC0_MR0 = 0x20000000; /* reset EMAC */
+ __asm__ __volatile__("eieio"); /* enforce ordering */
+
+ return decompress_kernel(load_addr, num_words, cksum);
+}
+
diff -urN -X bkexcl linux-2.4.22/arch/ppc/boot/simple/misc-embedded.c linuxppc-2.4/arch/ppc/boot/simple/misc-embedded.c
--- linux-2.4.22/arch/ppc/boot/simple/misc-embedded.c 2003-03-26 10:50:43.000000000 +1100
+++ linuxppc-2.4/arch/ppc/boot/simple/misc-embedded.c 2003-03-31 18:46:11.000000000 +1000
@@ -16,6 +16,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff -urN -X bkexcl linux-2.4.22/arch/ppc/config.in linuxppc-2.4/arch/ppc/config.in
--- linux-2.4.22/arch/ppc/config.in 2003-08-26 14:24:58.000000000 +1000
+++ linuxppc-2.4/arch/ppc/config.in 2003-08-02 07:10:51.000000000 +1000
@@ -12,6 +12,7 @@
mainmenu_option next_comment
comment 'Code maturity level options'
bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+bool 'Prompt for advanced kernel configuration options' CONFIG_ADVANCED_OPTIONS
endmenu
mainmenu_option next_comment
@@ -30,11 +31,12 @@
choice 'Processor Type' \
"6xx/7xx/74xx/8260 CONFIG_6xx \
40x CONFIG_40x \
- POWER3 CONFIG_POWER3 \
- POWER4 CONFIG_POWER4 \
+ 440 CONFIG_440 \
+ POWER3 CONFIG_POWER3 \
+ POWER4 CONFIG_POWER4 \
8xx CONFIG_8xx" 6xx
-if [ "$CONFIG_40x" = "y" ]; then
+if [ "$CONFIG_40x" = "y" -o "$CONFIG_440" = "y" ]; then
define_bool CONFIG_4xx y
fi
@@ -60,8 +62,38 @@
if [ "$CONFIG_40x" = "y" ]; then
choice 'Machine Type' \
- "Oak CONFIG_OAK \
- Walnut CONFIG_WALNUT" Walnut
+ "Arctic-II CONFIG_ARCTIC2 \
+ Ash CONFIG_ASH \
+ Ceder CONFIG_CEDER \
+ Beech CONFIG_BEECH \
+ CPCI405 CONFIG_CPCI405 \
+ EP405/EP405PC CONFIG_EP405 \
+ 405EP-eval CONFIG_EVB405EP \
+ Oak CONFIG_OAK \
+ Rainier CONFIG_RAINIER \
+ Redwood-4 CONFIG_REDWOOD_4 \
+ Redwood-5 CONFIG_REDWOOD_5 \
+ Redwood-6 CONFIG_REDWOOD_6 \
+ Sycamore CONFIG_SYCAMORE \
+ Tivo CONFIG_TIVO \
+ Walnut CONFIG_WALNUT \
+ Xilinx-ML300 CONFIG_XILINX_ML300" Walnut
+
+ if [ "$CONFIG_EP405" = "y" ]; then
+ bool 'EP405PC Support' CONFIG_EP405PC
+ fi
+fi
+
+if [ "$CONFIG_440" = "y" ]; then
+ define_bool CONFIG_BOOKE y
+ define_bool CONFIG_NOT_COHERENT_CACHE y
+ define_bool CONFIG_IBM_OCP y
+ define_bool CONFIG_GEN550 y
+ define_bool CONFIG_PIN_TLB y
+ define_int CONFIG_IBM_OCP_MAL_CNT 1
+
+ choice 'Machine Type' \
+ "Ebony CONFIG_EBONY" Ebony
fi
if [ "$CONFIG_8xx" = "y" ]; then
@@ -143,10 +175,60 @@
# It's often necessary to know the specific 4xx processor type.
# Fortunately, it is impled (so far) from the board type, so we
# don't need to ask more redundant questions.
+ if [ "$CONFIG_ASH" = "y" ]; then
+ define_bool CONFIG_NP405H y
+ define_bool CONFIG_IBM_OPENBIOS y
+ define_bool CONFIG_BIOS_FIXUP y
+ define_bool CONFIG_IBM405_ERR77 y
+ define_bool CONFIG_IBM_OCP y
+ fi
+ if [ "$CONFIG_CEDER" = "y" ]; then
+ define_bool CONFIG_NP405L y
+ define_bool CONFIG_IBM_OPENBIOS y
+ define_bool CONFIG_IBM405_ERR77 y
+ define_bool CONFIG_IBM_OCP y
+ fi
+ if [ "$CONFIG_CPCI405" = "y" ]; then
+ define_bool CONFIG_405GP y
+ define_bool CONFIG_IBM405_ERR77 y
+ define_bool CONFIG_IBM_OCP y
+ fi
+ if [ "$CONFIG_EP405" = "y" ]; then
+ define_bool CONFIG_405GP y
+ define_bool CONFIG_BIOS_FIXUP y
+ define_bool CONFIG_EMBEDDEDBOOT y
+ define_bool CONFIG_IBM405_ERR77 y
+ define_bool CONFIG_IBM_OCP y
+ fi
+ if [ "$CONFIG_EVB405EP" = "y" ]; then
+ define_bool CONFIG_405EP y
+ define_bool CONFIG_BIOS_FIXUP y
+ define_bool CONFIG_IBM_OPENBIOS y
+ define_bool CONFIG_IBM_OCP y
+ fi
+ if [ "$CONFIG_RAINIER" = "y" ]; then
+ define_bool CONFIG_NP405GS y
+ define_bool CONFIG_EMBEDDEDBOOT y
+ define_bool CONFIG_IBM405_ERR77 y
+ define_bool CONFIG_IBM_OCP y
+ fi
+ if [ "$CONFIG_XILINX_ML300" = "y" ]; then
+ define_bool CONFIG_VIRTEX_II_PRO y
+ define_bool CONFIG_EMBEDDEDBOOT y
+ define_bool CONFIG_IBM405_ERR77 y
+ define_bool CONFIG_XILINX_OCP y
+ fi
if [ "$CONFIG_OAK" = "y" -o "$CONFIG_TIVO" = "y" ]; then
define_bool CONFIG_403GCX y
define_bool CONFIG_IBM_OPENBIOS y
fi
+ if [ "$CONFIG_REDWOOD_4" = "y" -o "$CONFIG_REDWOOD_5" = "y" \
+ -o "$CONFIG_REDWOOD_6" = "y" ]; then
+ define_bool CONFIG_STB03xxx y
+ define_bool CONFIG_IBM_OPENBIOS y
+ define_bool CONFIG_IBM405_ERR77 y
+ define_bool CONFIG_IBM_OCP y
+ fi
if [ "$CONFIG_WALNUT" = "y" ]; then
define_bool CONFIG_405GP y
define_bool CONFIG_BIOS_FIXUP y
@@ -154,15 +236,53 @@
define_bool CONFIG_IBM405_ERR77 y
define_bool CONFIG_IBM_OCP y
fi
+ if [ "$CONFIG_BEECH" = "y" ]; then
+ define_bool CONFIG_405LP y
+ define_bool CONFIG_IBM_OPENBIOS y
+ define_bool CONFIG_IBM405_ERR77 y
+ define_bool CONFIG_IBM_OCP y
+ fi
+ if [ "$CONFIG_ARCTIC2" = "y" ]; then
+ define_bool CONFIG_405LP y
+ define_bool CONFIG_IBM405_ERR77 y
+ define_bool CONFIG_IBM_OCP y
+ fi
+ if [ "$CONFIG_SYCAMORE" = "y" ]; then
+ define_bool CONFIG_405GPR y
+ define_bool CONFIG_BIOS_FIXUP y
+ define_bool CONFIG_IBM_OPENBIOS y
+ define_bool CONFIG_IBM405_ERR77 y
+ define_bool CONFIG_IBM_OCP y
+ fi
+
+ dep_bool 'Power Management support (experimental)' CONFIG_PM $CONFIG_EXPERIMENTAL
+
if [ "$CONFIG_40x" = "y" ]; then
choice 'TTYS0 device and default console' \
"UART0 CONFIG_UART0_TTYS0 \
UART1 CONFIG_UART0_TTYS1" UART0
fi
-
+
+ define_bool CONFIG_GEN550 y
define_bool CONFIG_IBM405_ERR51 y
define_bool CONFIG_NOT_COHERENT_CACHE y
fi
+
+if [ "$CONFIG_4xx" = "y" ]; then
+ bool 'PPC4xx DMA controller support' CONFIG_PPC4xx_DMA
+ if [ "$CONFIG_PPC4xx_DMA" = "y" ]; then
+ if [ "$CONFIG_405GP" = "y" -o "$CONFIG_NP405L" = "y" \
+ -o "$CONFIG_NP405H" = "y" -o "$CONFIG_NP405GS" = "y" \
+ -o "$CONFIG_440" = "y" -o "$CONFIG_405LP" = "y" \
+ -o "$CONFIG_405EP" = "y" ]; then
+ define_bool CONFIG_PPC4xx_EDMA y
+ fi
+ if [ "$CONFIG_STB03xxx" = "y" ]; then
+ define_bool CONFIG_STBXXX_DMA y
+ fi
+ fi
+fi
+
if [ "$CONFIG_8xx" = "y" -o "$CONFIG_8260" = "y" ]; then
define_bool CONFIG_EMBEDDEDBOOT y
fi
@@ -172,6 +292,49 @@
comment 'General setup'
bool 'High memory support (experimental)' CONFIG_HIGHMEM
+if [ "$CONFIG_ADVANCED_OPTIONS" = "y" ]; then
+ if [ "$CONFIG_HIGHMEM" = "y" ]; then
+ bool " Set high memory pool address" CONFIG_HIGHMEM_START_BOOL
+ if [ "$CONFIG_HIGHMEM_START_BOOL" = "y" ]; then
+ hex " Virtual start address of high memory pool" CONFIG_HIGHMEM_START 0xfe000000
+ fi
+ bool " Set maximum low memory" CONFIG_LOWMEM_SIZE_BOOL
+ if [ "$CONFIG_LOWMEM_SIZE_BOOL" = "y" ]; then
+ hex " Maximum low memory size in bytes" CONFIG_LOWMEM_SIZE 0x20000000
+ fi
+ fi
+
+ bool "Set custom kernel base address" CONFIG_KERNEL_START_BOOL
+ if [ "$CONFIG_KERNEL_START_BOOL" = "y" ]; then
+ hex " Virtual address of kernel base" CONFIG_KERNEL_START 0xc0000000
+ fi
+ bool "Set custom user task size" CONFIG_TASK_SIZE_BOOL
+ if [ "$CONFIG_TASK_SIZE_BOOL" = "y" ]; then
+ hex " Size of user task space" CONFIG_TASK_SIZE 0x80000000
+ fi
+ if [ "$CONFIG_8xx" = "y" ]; then
+ bool "Pinned Kernel TLBs (860 ONLY)" CONFIG_PIN_TLB
+ fi
+ if [ "$CONFIG_40x" = "y" ]; then
+ bool "Pinned Kernel TLBs" CONFIG_PIN_TLB
+ fi
+fi
+
+if [ "$CONFIG_HIGHMEM_START_BOOL" != "y" ]; then
+ define_hex CONFIG_HIGHMEM_START 0xfe000000
+fi
+
+if [ "$CONFIG_LOWMEM_SIZE_BOOL" != "y" ]; then
+ define_hex CONFIG_LOWMEM_SIZE 0x30000000
+fi
+
+if [ "$CONFIG_KERNEL_START_BOOL" != "y" ]; then
+ define_hex CONFIG_KERNEL_START 0xc0000000
+fi
+
+if [ "$CONFIG_TASK_SIZE_BOOL" != "y" ]; then
+ define_hex CONFIG_TASK_SIZE 0x80000000
+fi
define_bool CONFIG_ISA n
define_bool CONFIG_EISA n
@@ -433,6 +596,27 @@
source arch/ppc/8260_io/Config.in
fi
+if [ "$CONFIG_40x" = "y" ]; then
+ mainmenu_option next_comment
+ comment 'IBM 4xx options'
+ if [ "$CONFIG_STB03xxx" = "y" ]; then
+ bool 'STB IR Keyboard' CONFIG_STB_KB
+ bool 'SICC Serial port' CONFIG_SERIAL_SICC
+ if [ "$CONFIG_SERIAL_SICC" = "y" -a "$CONFIG_UART0_TTYS1" = "y" ]; then
+ define_bool CONFIG_UART1_DFLT_CONSOLE y
+ define_bool CONFIG_SERIAL_SICC_CONSOLE y
+ fi
+ fi
+
+ if [ "$CONFIG_BEECH" = "y" ]; then
+ dep_bool 'Use pushbutton U63 for suspend/resume?' CONFIG_405LP_PM_BUTTON $CONFIG_PM
+ fi
+ if [ "$CONFIG_ARCTIC2" = "y" ]; then
+ dep_bool 'Use power button for suspend/resume?' CONFIG_405LP_PM_BUTTON $CONFIG_PM
+ fi
+ endmenu
+fi
+
source drivers/usb/Config.in
source net/bluetooth/Config.in
diff -urN -X bkexcl linux-2.4.22/arch/ppc/configs/ebony_defconfig linuxppc-2.4/arch/ppc/configs/ebony_defconfig
--- linux-2.4.22/arch/ppc/configs/ebony_defconfig 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/configs/ebony_defconfig 2003-04-18 12:42:42.000000000 +1000
@@ -0,0 +1,498 @@
+#
+# 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_HAVE_DEC_LOCK=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_PPC32=y
+# CONFIG_6xx is not set
+# CONFIG_40x is not set
+CONFIG_440=y
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
+# CONFIG_8xx is not set
+CONFIG_4xx=y
+# CONFIG_PPC_STD_MMU is not set
+CONFIG_BOOKE=y
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_IBM_OCP=y
+CONFIG_GEN550=y
+CONFIG_PIN_TLB=y
+CONFIG_IBM_OCP_MAL_CNT=1
+CONFIG_EBONY=y
+# CONFIG_ALL_PPC is not set
+# CONFIG_SMP is not set
+# CONFIG_MATH_EMULATION is not set
+# CONFIG_PPC4xx_DMA is not set
+
+#
+# General setup
+#
+CONFIG_HIGHMEM=y
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_PCI=y
+# CONFIG_PC_KEYBOARD is not set
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="ip=on"
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP 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_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_STATS is not set
+
+#
+# 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_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_FILTER=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK 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
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI 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 is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 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_R8169 is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+
+#
+# Backplane Networking
+#
+# CONFIG_NPNET is not set
+
+#
+# On-chip net devices
+#
+CONFIG_IBM_OCP_ENET=y
+# CONFIG_IBM_OCP_ENET_ERROR_MSG is not set
+CONFIG_IBM_OCP_ENET_RX_BUFF=64
+CONFIG_IBM_OCP_ENET_TX_BUFF=8
+CONFIG_IBM_OCP_ENET_GAP=8
+CONFIG_IBM_OCP_ENET_SKB_RES=0
+CONFIG_OCP_NET=y
+CONFIG_IBM_OCP_MAL_CNT=1
+CONFIG_IBM_OCP_ZMII=y
+# 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 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 is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+
+#
+# Macintosh device drivers
+#
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# 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
+
+#
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_IPMI_PANIC_EVENT is not set
+# CONFIG_IPMI_DEVICE_INTERFACE is not set
+# CONFIG_IPMI_KCS is not set
+# CONFIG_IPMI_WATCHDOG is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_SCx200_GPIO is not set
+# CONFIG_AMD_PM768 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
+# CONFIG_IBM_OCP_GPIO is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# 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_BEFS_FS is not set
+# CONFIG_BEFS_DEBUG is not set
+# CONFIG_BFS_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 is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_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 is not set
+# CONFIG_EXT2_FS is not set
+# 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 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
diff -urN -X bkexcl linux-2.4.22/arch/ppc/configs/walnut_defconfig linuxppc-2.4/arch/ppc/configs/walnut_defconfig
--- linux-2.4.22/arch/ppc/configs/walnut_defconfig 2003-06-25 20:56:52.000000000 +1000
+++ linuxppc-2.4/arch/ppc/configs/walnut_defconfig 2003-06-25 21:30:07.000000000 +1000
@@ -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
@@ -10,6 +10,7 @@
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
+# CONFIG_ADVANCED_OPTIONS is not set
#
# Loadable module support
@@ -25,13 +26,28 @@
CONFIG_PPC32=y
# CONFIG_6xx is not set
CONFIG_40x=y
+# CONFIG_440 is not set
# CONFIG_POWER3 is not set
# CONFIG_POWER4 is not set
# CONFIG_8xx is not set
CONFIG_4xx=y
# CONFIG_PPC_STD_MMU is not set
+# CONFIG_ARCTIC2 is not set
+# CONFIG_ASH is not set
+# CONFIG_CEDER is not set
+# CONFIG_BEECH is not set
+# CONFIG_CPCI405 is not set
+# CONFIG_EP405 is not set
+# CONFIG_EVB405EP is not set
# CONFIG_OAK is not set
+# CONFIG_RAINIER is not set
+# CONFIG_REDWOOD_4 is not set
+# CONFIG_REDWOOD_5 is not set
+# CONFIG_REDWOOD_6 is not set
+# CONFIG_SYCAMORE is not set
+# CONFIG_TIVO is not set
CONFIG_WALNUT=y
+# CONFIG_XILINX_ML300 is not set
# CONFIG_ALL_PPC is not set
# CONFIG_SMP is not set
# CONFIG_MATH_EMULATION is not set
@@ -40,8 +56,14 @@
CONFIG_IBM_OPENBIOS=y
CONFIG_IBM405_ERR77=y
CONFIG_IBM_OCP=y
+# CONFIG_PM is not set
+CONFIG_UART0_TTYS0=y
+# CONFIG_UART0_TTYS1 is not set
+CONFIG_GEN550=y
CONFIG_IBM405_ERR51=y
CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC4xx_DMA=y
+CONFIG_PPC4xx_EDMA=y
#
# General setup
@@ -51,7 +73,8 @@
# CONFIG_EISA is not set
# CONFIG_SBUS is not set
# CONFIG_MCA is not set
-# CONFIG_PCI is not set
+CONFIG_PCI=y
+# CONFIG_PC_KEYBOARD is not set
CONFIG_NET=y
CONFIG_SYSCTL=y
CONFIG_SYSVIPC=y
@@ -60,6 +83,7 @@
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
# CONFIG_BINFMT_MISC is not set
+# CONFIG_PCI_NAMES is not set
# CONFIG_HOTPLUG is not set
# CONFIG_PCMCIA is not set
@@ -67,7 +91,6 @@
# Parallel port support
#
# CONFIG_PARPORT is not set
-CONFIG_GEN_RTC=y
# CONFIG_CMDLINE_BOOL is not set
#
@@ -136,10 +159,6 @@
# CONFIG_KHTTPD is not set
# CONFIG_ATM is not set
# CONFIG_VLAN_8021Q is not set
-
-#
-#
-#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
@@ -181,6 +200,11 @@
# CONFIG_SCSI is not set
#
+# IEEE 1394 (FireWire) support (EXPERIMENTAL)
+#
+# CONFIG_IEEE1394 is not set
+
+#
# Network device support
#
CONFIG_NETDEVICES=y
@@ -203,6 +227,7 @@
# CONFIG_BMAC is not set
# CONFIG_GMAC is not set
# CONFIG_SUNLANCE is not set
+# CONFIG_HAPPYMEAL is not set
# CONFIG_SUNBMAC is not set
# CONFIG_SUNQE is not set
# CONFIG_SUNGEM is not set
@@ -210,6 +235,7 @@
# 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 is not set
# CONFIG_NET_POCKET is not set
@@ -227,6 +253,22 @@
# CONFIG_R8169 is not set
# CONFIG_SK98LIN is not set
# CONFIG_TIGON3 is not set
+
+#
+# Backplane Networking
+#
+# CONFIG_NPNET is not set
+
+#
+# On-chip net devices
+#
+CONFIG_IBM_OCP_ENET=y
+CONFIG_IBM_OCP_ENET_ERROR_MSG=y
+CONFIG_IBM_OCP_ENET_RX_BUFF=64
+CONFIG_IBM_OCP_ENET_TX_BUFF=8
+CONFIG_IBM_OCP_ENET_GAP=8
+CONFIG_IBM_OCP_ENET_SKB_RES=0
+CONFIG_OCP_NET=y
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PLIP is not set
@@ -310,6 +352,7 @@
CONFIG_I2C=y
# CONFIG_I2C_ALGOBIT is not set
# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_IBM_IIC is not set
# CONFIG_I2C_CHARDEV is not set
# CONFIG_I2C_PROC is not set
@@ -323,14 +366,6 @@
# Joysticks
#
# CONFIG_INPUT_GAMEPORT is not set
-
-#
-# Input core support is needed for gameports
-#
-
-#
-# Input core support is needed for joysticks
-#
# CONFIG_QIC02_TAPE is not set
# CONFIG_IPMI_HANDLER is not set
# CONFIG_IPMI_PANIC_EVENT is not set
@@ -349,6 +384,7 @@
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
+CONFIG_IBM_OCP_GPIO=y
#
# Ftape, the floppy tape device driver
@@ -466,6 +502,10 @@
# CONFIG_SOUND is not set
#
+# IBM 4xx options
+#
+
+#
# USB support
#
# CONFIG_USB is not set
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/Makefile linuxppc-2.4/arch/ppc/kernel/Makefile
--- linux-2.4.22/arch/ppc/kernel/Makefile 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/Makefile 2003-07-25 02:06:49.000000000 +1000
@@ -24,13 +24,16 @@
HEAD-y := head.o
HEAD-$(CONFIG_6xx) += idle_6xx.o
HEAD-$(CONFIG_40x) := head_4xx.o
+HEAD-$(CONFIG_440) := head_440.o
HEAD-$(CONFIG_8xx) := head_8xx.o
all: $(HEAD-y) kernel.o
O_TARGET := kernel.o
-export-objs := ppc_ksyms.o time.o ocp.o ppc4xx_setup.o
+export-objs := ppc_ksyms.o time.o ocp.o \
+ ppc4xx_dma.o ppc4xx_sgdma.o \
+ ppc4xx_stbdma.o ppc4xx_setup.o
obj-y := entry.o traps.o irq.o idle.o time.o misc.o \
process.o signal.o ptrace.o align.o \
@@ -51,12 +54,25 @@
obj-$(CONFIG_KGDB) += gen550_kgdb.o gen550_dbg.o
obj-$(CONFIG_SERIAL_TEXT_DEBUG) += gen550_dbg.o
endif
-obj-$(CONFIG_4xx) += todc_time.o
+
+ifeq ($(CONFIG_4xx),y)
+obj-$(CONFIG_4xx) += todc_time.o idle_4xx.o
obj-$(CONFIG_40x) += ppc4xx_setup.o ocp.o
+ifeq ($(CONFIG_XILINX_OCP),y)
+obj-$(CONFIG_40x) += xilinx_pic.o
+else
obj-$(CONFIG_40x) += ppc4xx_pic.o
+endif
+obj-$(CONFIG_440) += ppc4xx_pic.o ocp.o
+obj-$(CONFIG_PPC4xx_EDMA) += ppc4xx_sgdma.o
+obj-$(CONFIG_STBXXX_DMA) += ppc4xx_stbdma.o
+obj-$(CONFIG_PPC4xx_DMA) += ppc4xx_dma.o
ifeq ($(CONFIG_PCI),y)
obj-$(CONFIG_40x) += ppc405_pci.o indirect_pci.o pci_auto.o
+obj-$(CONFIG_440) += indirect_pci.o pci_auto.o
+endif
endif
+
obj-$(CONFIG_8xx) += m8xx_setup.o ppc8xx_pic.o
ifeq ($(CONFIG_8xx),y)
obj-$(CONFIG_PCI) += qspan_pci.o
@@ -64,6 +80,7 @@
obj-y += softemu8xx.o
endif
endif
+
obj-$(CONFIG_MBX) += i8259.o
obj-$(CONFIG_ALL_PPC) += prom_init.o prom.o open_pic.o \
indirect_pci.o i8259.o
@@ -84,6 +101,7 @@
l2cr.o: l2cr.S ppc_defs.h
head.o: head.S ppc_defs.h
head_4xx.o: head_4xx.S ppc_defs.h
+head_440.o: head_440.S ppc_defs.h
head_8xx.o: head_8xx.S ppc_defs.h
idle_6xx.o: idle_6xx.S ppc_defs.h
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/checks.c linuxppc-2.4/arch/ppc/kernel/checks.c
--- linux-2.4.22/arch/ppc/kernel/checks.c 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/checks.c 2003-07-25 02:06:49.000000000 +1000
@@ -16,6 +16,8 @@
#include
#include
+int printf(const char *, ...);
+
/*
* Do various before compile checks of data structures
* -- Cort
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/cputable.c linuxppc-2.4/arch/ppc/kernel/cputable.c
--- linux-2.4.22/arch/ppc/kernel/cputable.c 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/cputable.c 2003-07-25 02:06:49.000000000 +1000
@@ -357,19 +357,99 @@
},
{ /* 405GP */
0xffff0000, 0x40110000, "405GP",
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_DOZE,
PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
32, 32,
0, /*__setup_cpu_405 */
},
+ { /* 405GPr */
+ 0xffff0000, 0x50910000, "405GPr",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_DOZE,
+ PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 32, 32,
+ 0, /*__setup_cpu_405 */
+ },
+ { /* 405EP */
+ 0xffff0000, 0x51210000, "405EP",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_DOZE,
+ PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 32, 32,
+ 0, /*__setup_cpu_405 */
+ },
{ /* STB 03xxx */
0xffff0000, 0x40130000, "STB03xxx",
- CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB,
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_DOZE,
+ PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 32, 32,
+ 0, /*__setup_cpu_405 */
+ },
+ { /* STB 04xxx */
+ 0xffff0000, 0x41810000, "STB04xxx",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_DOZE,
+ PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 32, 32,
+ 0, /*__setup_cpu_405 */
+ },
+ { /* NP405L */
+ 0xffff0000, 0x41610000, "NP405L",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_DOZE,
+ PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 32, 32,
+ 0, /*__setup_cpu_405 */
+ },
+ { /* NP4GS3 */
+ 0xffff0000, 0x40B10000, "NP4GS3",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB,
PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
32, 32,
0, /*__setup_cpu_405 */
},
-#endif /* CONFIG_4xx */
+ { /* NP405H */
+ 0xffff0000, 0x41410000, "NP405H",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_DOZE,
+ PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 32, 32,
+ 0, /*__setup_cpu_405 */
+ },
+ { /* STBx25xx */
+ 0xffff0000, 0x51510000, "STBx25xx",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_DOZE,
+ PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 32, 32,
+ 0, /*__setup_cpu_405 */
+ },
+ { /* 405LP */
+ 0xffff0000, 0x41F10000, "405LP",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_DOZE,
+ PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+ 32, 32,
+ 0, /*__setup_cpu_405 */
+ },
+ { /* Xilinx Virtex-II Pro */
+ 0xffff0000, 0x20010000, "Virtex-II Pro",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_CAN_DOZE,
+ PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
+ 32, 32,
+ 0, /*__setup_cpu_405 */
+ },
+
+#endif /* CONFIG_40x */
+#ifdef CONFIG_440
+ { /* 440GP Rev. B */
+ 0xf0000fff, 0x40000440, "440GP Rev. B",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB,
+ PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+ 32, 32,
+ 0, /*__setup_cpu_440 */
+ },
+ { /* 440GP Rev. C */
+ 0xf0000fff, 0x40000481, "440GP Rev. C",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB,
+ PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU,
+ 32, 32,
+ 0, /*__setup_cpu_440 */
+ },
+#endif /* CONFIG_440 */
#if !CLASSIC_PPC
{ /* default match */
0x00000000, 0x00000000, "(generic PPC)",
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/head_440.S linuxppc-2.4/arch/ppc/kernel/head_440.S
--- linux-2.4.22/arch/ppc/kernel/head_440.S 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/head_440.S 2003-05-26 09:40:53.000000000 +1000
@@ -0,0 +1,1064 @@
+/*
+ * arch/ppc/kernel/head_440.S
+ *
+ * Kernel execution entry point code.
+ *
+ * Matt Porter
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "ppc_defs.h"
+
+/*
+ * Preprocessor Defines
+ */
+
+#define STND_EXC 0
+#define CRIT_EXC 1
+
+/*
+ * Macros
+ */
+
+#define SET_IVOR(vector_number, vector_label) \
+ li r26,vector_label@l; \
+ mtspr SPRN_IVOR##vector_number,r26; \
+ sync
+
+/* As with the other PowerPC ports, it is expected that when code
+ * execution begins here, the following registers contain valid, yet
+ * optional, information:
+ *
+ * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
+ * r4 - Starting address of the init RAM disk
+ * r5 - Ending address of the init RAM disk
+ * r6 - Start of kernel command line string (e.g. "mem=128")
+ * r7 - End of kernel command line string
+ *
+ */
+ .text
+_GLOBAL(_stext)
+_GLOBAL(_start)
+ /*
+ * Reserve a word at a fixed location to store the address
+ * of abatron_pteptrs
+ */
+ nop
+ /* To accomodate some SMP systems that overwrite the first few
+ * locations before cpu 0 starts, the bootloader starts us at 0xc.
+ */
+ nop
+ nop
+/*
+ * Save parameters we are passed
+ */
+ mr r31,r3
+ mr r30,r4
+ mr r29,r5
+ mr r28,r6
+ mr r27,r7
+ li r24,0 /* CPU number */
+
+/*
+ * Set up the initial MMU state
+ *
+ * We are still executing code at the virtual address
+ * mappings set by the firmware for the base of RAM.
+ *
+ * We first invalidate all TLB entries but the one
+ * we are running from. We then load the KERNELBASE
+ * mappings so we can begin to use kernel addresses
+ * natively and so the interrupt vector locations are
+ * permanently pinned (necessary since Book E
+ * implementations always have translation enabled).
+ *
+ * TODO: Use the known TLB entry we are running from to
+ * determine which physical region we are located
+ * in. This can be used to determine where in RAM
+ * (on a shared CPU system) or PCI memory space
+ * (on a DRAMless system) we are located.
+ * For now, we assume a perfect world which means
+ * we are located at the base of DRAM (physical 0).
+ */
+
+/*
+ * Search TLB for entry that we are currently using.
+ * Invalidate all entries but the one we are using.
+ */
+ /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */
+ mfspr r3,SPRN_MMUCR /* Get MMUCR */
+ lis r4,PPC440_MMUCR_STS@h
+ ori r4,r4,PPC440_MMUCR_TID@l /* Create mask */
+ andc r3,r3,r4 /* Clear out TID/STS bits */
+ mfspr r4,SPRN_PID /* Get PID */
+ or r3,r3,r4 /* Set TID bits */
+ mfmsr r5 /* Get MSR */
+ andi. r5,r5,MSR_IS@l /* TS=1? */
+ beq wmmucr /* If not, leave STS=0 */
+ oris r3,r3,PPC440_MMUCR_STS@h /* Set STS=1 */
+wmmucr: mtspr SPRN_MMUCR,r3 /* Put MMUCR */
+ sync
+
+ bl invstr /* Find our address */
+invstr: mflr r5 /* Make it accessible */
+ tlbsx r23,0,r5 /* Find entry we are in */
+ li r4,0 /* Start at TLB entry 0 */
+ li r3,0 /* Set PAGEID inval value */
+1: cmpw r23,r4 /* Is this our entry? */
+ beq skpinv /* If so, skip the inval */
+ tlbwe r3,r4,PPC440_TLB_PAGEID /* If not, inval the entry */
+skpinv: addi r4,r4,1 /* Increment */
+ cmpwi r4,64 /* Are we done? */
+ bne 1b /* If not, repeat */
+ isync /* If so, context change */
+
+/*
+ * Configure and load pinned entries into TLB slots 62 and 63.
+ */
+
+ lis r3,KERNELBASE@h /* Load the kernel virtual address */
+ ori r3,r3,KERNELBASE@l
+
+ /* Kernel is at the base of RAM */
+ li r4, 0 /* Load the kernel physical address */
+
+ /* Load the kernel PID = 0 */
+ li r0,0
+ mtspr SPRN_PID,r0
+ sync
+
+ /* Load the kernel TID = 0 */
+ mfspr r5,SPRN_MMUCR
+ lis r6, PPC440_MMUCR_TID@h
+ ori r6,r6,PPC440_MMUCR_TID@l
+ andc r5,r5,r6
+ mtspr SPRN_MMUCR,r5
+ sync
+
+ /* pageid fields */
+ clrrwi r3,r3,10 /* Mask off the effective page number */
+ ori r3,r3,(PPC440_TLB_VALID | PPC440_TLB_PAGESZ(PPC440_PAGESZ_16M))
+
+ /* xlat fields */
+ clrrwi r4,r4,10 /* Mask off the real page number */
+ /* ERPN is 0 for first 4GB page */
+
+ /* attrib fields */
+ /* Added guarded bit to protect against speculative loads/stores */
+ li r5,0
+ ori r5,r5,(PPC440_TLB_SW | PPC440_TLB_SR | PPC440_TLB_SX | PPC440_TLB_G)
+
+ li r0,62 /* TLB slot 62 */
+
+ tlbwe r3,r0,PPC440_TLB_PAGEID /* Load the pageid fields */
+ tlbwe r4,r0,PPC440_TLB_XLAT /* Load the translation fields */
+ tlbwe r5,r0,PPC440_TLB_ATTRIB /* Load the attrib/access fields */
+
+ /* Force context change */
+ mfmsr r0
+ mtspr SRR1, r0
+ lis r0,3f@h
+ ori r0,r0,3f@l
+ mtspr SRR0,r0
+ sync
+ rfi
+
+ /* If necessary, invalidate original entry we used */
+3: cmpwi r23,62
+ beq 4f
+ li r6,0
+ tlbwe r6,r23,PPC440_TLB_PAGEID
+ sync
+
+4: ori r3,r3,PPC440_TLB_TS /* TS = 1 */
+
+ li r0,63 /* TLB slot 63 */
+
+ tlbwe r3,r0,PPC440_TLB_PAGEID /* Load the pageid fields */
+ tlbwe r4,r0,PPC440_TLB_XLAT /* Load the translation fields */
+ tlbwe r5,r0,PPC440_TLB_ATTRIB /* Load the attrib/access fields */
+
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+ /*
+ * Add temporary UART mapping for early debug. This
+ * mapping must be identical to that used by the early
+ * bootloader code since the same asm/serial.h parameters
+ * are used for polled operation.
+ */
+ /* pageid fields */
+ lis r3,0xe000
+ ori r3,r3,(PPC440_TLB_VALID | PPC440_TLB_PAGESZ(PPC440_PAGESZ_256M))
+
+ /* xlat fields */
+ lis r4,0x4000 /* RPN is 0x40000000 */
+ ori r4,r4,0x0001 /* ERPN is 1 for second 4GB page */
+
+ /* attrib fields */
+ li r5,0
+ ori r5,r5,(PPC440_TLB_SW | PPC440_TLB_SR | PPC440_TLB_I | PPC440_TLB_G)
+
+ li r0,60 /* TLB slot 60 */
+
+ tlbwe r3,r0,PPC440_TLB_PAGEID /* Load the pageid fields */
+ tlbwe r4,r0,PPC440_TLB_XLAT /* Load the translation fields */
+ tlbwe r5,r0,PPC440_TLB_ATTRIB /* Load the attrib/access fields */
+
+ ori r3,r3,PPC440_TLB_TS /* Translation state 1 */
+
+ li r0,61 /* TLB slot 61 */
+
+ tlbwe r3,r0,PPC440_TLB_PAGEID /* Load the pageid fields */
+ tlbwe r4,r0,PPC440_TLB_XLAT /* Load the translation fields */
+ tlbwe r5,r0,PPC440_TLB_ATTRIB /* Load the attrib/access fields */
+#endif /* CONFIG_SERIAL_TEXT_DEBUG */
+
+ /* Force context change */
+ isync
+
+ /* Establish the interrupt vector offsets */
+ SET_IVOR(0, CriticalInput);
+ SET_IVOR(1, MachineCheck);
+ SET_IVOR(2, DataStorage);
+ SET_IVOR(3, InstructionStorage);
+ SET_IVOR(4, ExternalInput);
+ SET_IVOR(5, Alignment);
+ SET_IVOR(6, Program);
+ SET_IVOR(7, FloatingPointUnavailable);
+ SET_IVOR(8, SystemCall);
+ SET_IVOR(9, AuxillaryProcessorUnavailable);
+ SET_IVOR(10, Decrementer);
+ SET_IVOR(11, FixedIntervalTimer);
+ SET_IVOR(12, WatchdogTimer);
+ SET_IVOR(13, DataTLBError);
+ SET_IVOR(14, InstructionTLBError);
+ SET_IVOR(15, Debug);
+
+ /* Establish the interrupt vector base */
+ lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */
+ mtspr SPRN_IVPR,r4
+
+ /*
+ * This is where the main kernel code starts.
+ */
+
+ /* ptr to current */
+ lis r2,init_task_union@h
+ ori r2,r2,init_task_union@l
+
+ /* ptr to current thread */
+ addi r4,r2,THREAD /* init task's THREAD */
+ mtspr SPRG3,r4
+ li r3,0
+ mtspr SPRG2,r3 /* 0 => r1 has kernel sp */
+
+ /* stack */
+ addi r1,r2,TASK_UNION_SIZE
+ li r0,0
+ stwu r0,-STACK_FRAME_OVERHEAD(r1)
+
+ bl early_init
+
+/*
+ * Decide what sort of machine this is and initialize the MMU.
+ */
+ mr r3,r31
+ mr r4,r30
+ mr r5,r29
+ mr r6,r28
+ mr r7,r27
+ bl machine_init
+ bl MMU_init
+
+ /* Setup PTE pointers for the Abatron bdiGDB */
+ lis r6, swapper_pg_dir@h
+ ori r6, r6, swapper_pg_dir@l
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ lis r4, KERNELBASE@h
+ ori r4, r4, KERNELBASE@l
+ stw r5, 0(r4) /* Save abatron_pteptrs at a fixed location */
+ stw r6, 0(r5)
+
+ /* Let's move on */
+ lis r4,start_kernel@h
+ ori r4,r4,start_kernel@l
+ li r3,MSR_KERNEL
+ mtspr SRR0,r4
+ mtspr SRR1,r3
+ rfi /* change context and jump to start_kernel */
+
+/*
+ * Interrupt vector entry code
+ *
+ * The Book E MMUs are always on so we don't need to handle
+ * interrupts in real mode as with previous PPC processors. In
+ * this case we handle interrupts in the kernel virtual address
+ * space.
+ *
+ * Interrupt vectors are dynamically placed relative to the
+ * interrupt prefix as determined by the address of interrupt_base.
+ * The interrupt vectors offsets are programmed using the labels
+ * for each interrupt vector entry.
+ *
+ * Interrupt vectors must be aligned on a 16 byte boundary.
+ * We align on a 32 byte cache line boundary for good measure.
+ */
+
+#define COMMON_PROLOG \
+0: mtspr SPRN_SPRG0,r20; /* We need r20, move it to SPRG0 */\
+ mtspr SPRN_SPRG1,r21; /* We need r21, move it to SPRG1 */\
+ mfcr r20; /* We need the CR, move it to r20 */\
+ mfspr r21,SPRN_SPRG2; /* Exception stack to use */\
+ cmpwi cr0,r21,0; /* From user mode or RTAS? */\
+ bne 1f; /* Not RTAS, branch */\
+ mr r21, r1; /* Move vka in r1 to r21 */\
+ subi r21,r21,INT_FRAME_SIZE; /* Allocate an exception frame */\
+1: stw r20,_CCR(r21); /* Save CR on the stack */\
+ stw r22,GPR22(r21); /* Save r22 on the stack */\
+ stw r23,GPR23(r21); /* r23 Save on the stack */\
+ mfspr r20,SPRN_SPRG0; /* Get r20 back out of SPRG0 */\
+ stw r20,GPR20(r21); /* Save r20 on the stack */\
+ mfspr r22,SPRN_SPRG1; /* Get r21 back out of SPRG0 */\
+ stw r22,GPR21(r21); /* Save r21 on the stack */\
+ mflr r20; \
+ stw r20,_LINK(r21); /* Save LR on the stack */\
+ mfctr r22; \
+ stw r22,_CTR(r21); /* Save CTR on the stack */\
+ mfspr r20,XER; \
+ stw r20,_XER(r21); /* Save XER on the stack */
+
+#define COMMON_EPILOG \
+ stw r0,GPR0(r21); /* Save r0 on the stack */\
+ stw r1,GPR1(r21); /* Save r1 on the stack */\
+ stw r2,GPR2(r21); /* Save r2 on the stack */\
+ stw r1,0(r21); \
+ mr r1,r21; /* Set-up new kernel stack pointer */\
+ SAVE_4GPRS(3, r21); /* Save r3 through r6 on the stack */\
+ SAVE_GPR(7, r21); /* Save r7 on the stack */
+
+#define STND_EXCEPTION_PROLOG \
+ COMMON_PROLOG; \
+ mfspr r22,SPRN_SRR0; /* Faulting instruction address */\
+ lis r20,MSR_WE@h; \
+ mfspr r23,SPRN_SRR1; /* MSR at the time of fault */\
+ andc r23,r23,r20; /* disable processor wait state */\
+ COMMON_EPILOG;
+
+#define CRIT_EXCEPTION_PROLOG \
+ COMMON_PROLOG; \
+ mfspr r22,SPRN_CSRR0; /* Faulting instruction address */\
+ lis r20,MSR_WE@h; \
+ mfspr r23,SPRN_CSRR1; /* MSR at the time of fault */\
+ andc r23,r23,r20; /* disable processor wait state */\
+ COMMON_EPILOG;
+
+#define START_EXCEPTION(label) \
+ .align 5; \
+label:
+
+#define FINISH_EXCEPTION(n, func) \
+ bl transfer_to_handler; \
+ .long func; \
+ .long ret_from_except; \
+ .long n
+
+#define STND_EXCEPTION(n, label, func) \
+ START_EXCEPTION(label) \
+ STND_EXCEPTION_PROLOG; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ li r7,STND_EXC; \
+ li r20,MSR_KERNEL; \
+ FINISH_EXCEPTION(n, func)
+
+#define CRIT_EXCEPTION(n, label, func) \
+ START_EXCEPTION(label) \
+ CRIT_EXCEPTION_PROLOG; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ li r7,CRIT_EXC; \
+ li r20,MSR_KERNEL; \
+ FINISH_EXCEPTION(n, func)
+
+interrupt_base:
+
+ /* Critical Input Interrupt */
+ CRIT_EXCEPTION(0x100, CriticalInput,UnknownException);
+
+ /* Machine Check Interrupt */
+ /* TODO: provide bus error register status */
+ CRIT_EXCEPTION(0x200, MachineCheck,MachineCheckException);
+
+ /* Data Storage Interrupt */
+ START_EXCEPTION(DataStorage)
+ mtspr SPRG0, r20 /* Save some working registers */
+ mtspr SPRG1, r21
+ mtspr SPRG4W, r22
+ mtspr SPRG5W, r23
+ mtspr SPRG6W, r24
+ mfcr r21
+ mtspr SPRG7W, r21
+
+ /*
+ * Check if it was a store fault, if not then bail
+ * because a user tried to access a kernel or
+ * read-protected page. Otherwise, get the
+ * offending address and handle it.
+ */
+ mfspr r20, SPRN_ESR
+ andis. r20, r20, ESR_ST@h
+ beq 2f
+
+ mfspr r20, SPRN_DEAR /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ andis. r21, r20, 0x8000
+ beq 3f
+ lis r21, swapper_pg_dir@h
+ ori r21, r21, swapper_pg_dir@l
+
+ mfspr r22,SPRN_MMUCR /* Set TID to 0 */
+ li r23,PPC440_MMUCR_TID@l
+ andc r22,r22,r23
+ mtspr SPRN_MMUCR,r22
+
+ b 4f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r21,SPRG3
+ lwz r21,PGDIR(r21)
+
+ /* Load MMUCR with our PID and STS= */
+ mfspr r22,SPRN_MMUCR /* Get MMUCR */
+ lis r23,PPC440_MMUCR_STS@h
+ ori r23,r23,PPC440_MMUCR_TID@l /* Create mask */
+ andc r22,r22,r23 /* Clear out TID/STS bits */
+ mfspr r23,SPRN_PID /* Get PID */
+ or r22,r22,r23 /* Set TID bits */
+ mfspr r24,SPRN_SRR1 /* Get SRR1 */
+ andi. r24,r24,MSR_IS@l /* TS=1? */
+ beq 4f /* If not, leave STS=0 */
+ oris r22,r22,PPC440_MMUCR_STS@h /* Set STS=1 */
+ mtspr SPRN_MMUCR,r22
+4:
+ rlwinm r22, r20, 13, 19, 29 /* Compute pgdir/pmd offset */
+ lwzx r21, r22, r21 /* Get pgd/pmd entry */
+ rlwinm. r22, r21, 0, 0, 20 /* Extract pt base address */
+ beq 2f /* Bail if no table */
+
+ rlwimi r22, r20, 23, 20, 28 /* Compute pte address */
+ lwz r21, 4(r22) /* Get pte entry */
+
+ andi. r23, r21, _PAGE_RW /* Is it writeable? */
+ beq 2f /* Bail if not */
+
+ /* Update 'changed'.
+ */
+ ori r21, r21, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
+ stw r21, 4(r22) /* Update Linux page table */
+
+ /* FIXME: Staticly setting some permissions */
+ li r23, 0x003f /* Set UX,UW,UR,SX,SW,SR */
+ andi. r21,r21,0xffff /* Clear MS 16 bits */
+ /* FIXME: Force attributes */
+ ori r21,r21, 0x0100 /* Set G */
+ /* FIXME: Already set in PTE */
+ rlwimi r21,r23,0,26,31 /* Insert static perms */
+
+ lis r23,0xffff
+ ori r23,r23,0x0fff /* Set U0-U3 mask */
+ and r21,r21,r23 /* Clear U0-U3 */
+
+ /* find the TLB index that caused the fault. It has to be here. */
+ tlbsx r24, 0, r20
+
+ tlbwe r21, r24, PPC440_TLB_ATTRIB /* Write ATTRIB */
+
+ /* Done...restore registers and get out of here.
+ */
+ mfspr r21, SPRG7R
+ mtcr r21
+ mfspr r24, SPRG6R
+ mfspr r23, SPRG5R
+ mfspr r22, SPRG4R
+
+ mfspr r21, SPRG1
+ mfspr r20, SPRG0
+ PPC405_ERR77_SYNC
+ rfi /* Force context change */
+
+2:
+ /*
+ * The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r21, SPRG7R
+ mtcr r21
+ mfspr r24, SPRG6R
+ mfspr r23, SPRG5R
+ mfspr r22, SPRG4R
+
+ mfspr r21, SPRG1
+ mfspr r20, SPRG0
+ b data_access
+
+ /* Instruction Storage Interrupt */
+ START_EXCEPTION(InstructionStorage)
+ STND_EXCEPTION_PROLOG
+ mfspr r5,SPRN_ESR /* Grab the ESR, save it */
+ stw r5,_ESR(r21)
+ mr r4,r22 /* Pass SRR0 as arg2 */
+ li r5,0 /* Pass zero as arg3 */
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r7,STND_EXC
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 /* Copy EE bit from the saved MSR */
+ FINISH_EXCEPTION(0x400, do_page_fault)/* do_page_fault(regs, SRR0, SRR1) */
+
+ /* External Input Interrupt */
+ START_EXCEPTION(ExternalInput)
+ STND_EXCEPTION_PROLOG
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r7,STND_EXC
+ li r20,MSR_KERNEL
+ li r4,0
+ bl transfer_to_handler
+_GLOBAL(do_IRQ_intercept)
+ .long do_IRQ
+ .long ret_from_intercept
+ .long 0x500
+
+ /* Alignment Interrupt */
+ START_EXCEPTION(Alignment)
+ STND_EXCEPTION_PROLOG
+ mfspr r4,SPRN_DEAR /* Grab the DEAR and save it */
+ stw r4,_DEAR(r21)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r7,STND_EXC
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 /* Copy EE bit from the saved MSR */
+ FINISH_EXCEPTION(0x600, AlignmentException)
+
+ /* Program Interrupt */
+ START_EXCEPTION(Program)
+ STND_EXCEPTION_PROLOG
+ mfspr r4,SPRN_ESR /* Grab the ESR, save it */
+ stw r4,_ESR(r21)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r7,STND_EXC
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 /* Copy EE bit from the saved MSR */
+ FINISH_EXCEPTION(0x700, ProgramCheckException)
+
+ /* Floating Point Unavailable Interrupt */
+ STND_EXCEPTION(0x2010, FloatingPointUnavailable,UnknownException);
+
+ /* System Call Interrupt */
+ START_EXCEPTION(SystemCall)
+ STND_EXCEPTION_PROLOG
+ stw r3,ORIG_GPR3(r21)
+ li r7,STND_EXC
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 /* Copy EE bit from the saved MSR */
+ FINISH_EXCEPTION(0xc00, DoSyscall)
+
+ /* Auxillary Processor Unavailable */
+ STND_EXCEPTION(0x2020, AuxillaryProcessorUnavailable,UnknownException);
+
+ /* Decrementer Interrupt */
+ START_EXCEPTION(Decrementer)
+ STND_EXCEPTION_PROLOG
+ lis r0,TSR_DIS@h /* Setup the DEC interrupt mask */
+ mtspr SPRN_TSR,r0 /* Clear the DEC interrupt */
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r7,STND_EXC
+ li r20,MSR_KERNEL
+ bl transfer_to_handler
+_GLOBAL(timer_interrupt_intercept)
+ .long timer_interrupt
+ .long ret_from_intercept
+ .long 0x1000
+
+ /* Fixed Internal Timer Interrupt */
+ /* TODO: Add FIT support */
+ STND_EXCEPTION(0x1010, FixedIntervalTimer,UnknownException);
+
+ /* Watchdog Timer Interrupt */
+ /* TODO: Add watchdog support */
+ CRIT_EXCEPTION(0x1020, WatchdogTimer,UnknownException);
+
+ /* Data TLB Error Interrupt */
+ START_EXCEPTION(DataTLBError)
+ mtspr SPRG0, r20 /* Save some working registers */
+ mtspr SPRG1, r21
+ mtspr SPRG4W, r22
+ mtspr SPRG5W, r23
+ mtspr SPRG6W, r24
+ mfcr r21
+ mtspr SPRG7W, r21
+ mfspr r20, SPRN_DEAR /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ andis. r21, r20, 0x8000
+ beq 3f
+ lis r21, swapper_pg_dir@h
+ ori r21, r21, swapper_pg_dir@l
+
+ mfspr r22,SPRN_MMUCR /* Set TID to 0 */
+ li r23,PPC440_MMUCR_TID@l
+ andc r22,r22,r23
+ mtspr SPRN_MMUCR,r22
+
+ b 4f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r21,SPRG3
+ lwz r21,PGDIR(r21)
+
+ /* Load PID into MMUCR TID */
+ li r23,PPC440_MMUCR_TID@l /* Create mask */
+ andc r22,r22,r23 /* Clear out TID/STS bits */
+ mfspr r23,SPRN_PID /* Get PID */
+ or r22,r22,r23
+ mtspr SPRN_MMUCR,r22
+4:
+ rlwinm r22, r20, 13, 19, 29 /* Compute pgdir/pmd offset */
+ lwzx r21, r22, r21 /* Get pgd/pmd entry */
+ rlwinm. r22, r21, 0, 0, 20 /* Extract pt base address */
+ beq 2f /* Bail if no table */
+
+ rlwimi r22, r20, 23, 20, 28 /* Compute pte address */
+ lwz r21, 4(r22) /* Get pte entry */
+ andi. r23, r21, _PAGE_PRESENT /* Is the page present? */
+ beq 2f /* Bail if not present */
+
+ ori r21, r21, _PAGE_ACCESSED
+ stw r21, 4(r22)
+
+ /* Jump to common tlb load */
+ b finish_tlb_load
+
+2:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r21, SPRG7R
+ mtcr r21
+ mfspr r24, SPRG6R
+ mfspr r23, SPRG5R
+ mfspr r22, SPRG4R
+ mfspr r21, SPRG1
+ mfspr r20, SPRG0
+ b data_access
+
+ /* Instruction TLB Error Interrupt */
+ /*
+ * Nearly the same as above, except we get our
+ * information from different registers and bailout
+ * to a different point.
+ */
+ START_EXCEPTION(InstructionTLBError)
+ mtspr SPRG0, r20 /* Save some working registers */
+ mtspr SPRG1, r21
+ mtspr SPRG4W, r22
+ mtspr SPRG5W, r23
+ mtspr SPRG6W, r24
+ mfcr r21
+ mtspr SPRG7W, r21
+ mfspr r20, SRR0 /* Get faulting address */
+
+ /* If we are faulting a kernel address, we have to use the
+ * kernel page tables.
+ */
+ andis. r21, r20, 0x8000
+ beq 3f
+ lis r21, swapper_pg_dir@h
+ ori r21, r21, swapper_pg_dir@l
+
+ mfspr r22,SPRN_MMUCR /* Set TID to 0 */
+ li r23,PPC440_MMUCR_TID@l
+ andc r22,r22,r23
+ mtspr SPRN_MMUCR,r22
+
+ b 4f
+
+ /* Get the PGD for the current thread */
+3:
+ mfspr r21,SPRG3
+ lwz r21,PGDIR(r21)
+
+ /* Load PID into MMUCR TID */
+ li r23,PPC440_MMUCR_TID@l /* Create mask */
+ andc r22,r23,r23 /* Clear out TID/STS bits */
+ mfspr r23,SPRN_PID /* Get PID */
+ or r22,r22,r23
+ mtspr SPRN_MMUCR,r22
+
+4:
+ rlwinm r22, r20, 13, 19, 29 /* Compute pgdir/pmd offset */
+ lwzx r21, r22, r21 /* Get pgd/pmd entry */
+ rlwinm. r22, r21, 0, 0, 20 /* Extract pt base address */
+ beq 2f /* Bail if no table */
+
+ rlwimi r22, r20, 23, 20, 28 /* Compute pte address */
+ lwz r21, 4(r22) /* Get pte entry */
+ andi. r23, r21, _PAGE_PRESENT /* Is the page present? */
+ beq 2f /* Bail if not present */
+
+ ori r21, r21, _PAGE_ACCESSED
+ stw r21, 4(r22)
+
+ /* Jump to common TLB load point */
+ b finish_tlb_load
+
+2:
+ /* The bailout. Restore registers to pre-exception conditions
+ * and call the heavyweights to help us out.
+ */
+ mfspr r21, SPRG7R
+ mtcr r21
+ mfspr r24, SPRG6R
+ mfspr r23, SPRG5R
+ mfspr r22, SPRG4R
+ mfspr r21, SPRG1
+ mfspr r20, SPRG0
+ b InstructionStorage
+
+/* Check for a single step debug exception while in an exception
+ * handler before state has been saved. This is to catch the case
+ * where an instruction that we are trying to single step causes
+ * an exception (eg ITLB/DTLB miss) and thus the first instruction of
+ * the exception handler generates a single step debug exception.
+ *
+ * If we get a debug trap on the first instruction of an exception handler,
+ * we reset the MSR_DE in the _exception handlers_ MSR (the debug trap is
+ * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR).
+ * The exception handler was handling a non-critical interrupt, so it will
+ * save (and later restore) the MSR via SPRN_SRR1, which will still have
+ * the MSR_DE bit set.
+ */
+ /* Debug Interrupt */
+ START_EXCEPTION(Debug)
+ /* This first instruction was already executed by the exception
+ * handler and must be the first instruction of every exception
+ * handler.
+ */
+ mtspr SPRN_SPRG0,r20 /* Save some working registers... */
+ mtspr SPRN_SPRG1,r21
+ mtspr SPRN_SPRG4W,r22
+ mfcr r20 /* ..and the cr because we change it */
+
+ mfspr r21,SPRN_CSRR1 /* MSR at the time of fault */
+ andi. r21,r21,MSR_PR
+ bne+ 2f /* trapped from problem state */
+
+ mfspr r21,SPRN_CSRR0 /* Faulting instruction address */
+ lis r22, KERNELBASE@h
+ ori r22, r22, KERNELBASE@l
+ cmplw r21,r22
+ blt+ 2f /* addr below exception vectors */
+
+ lis r22, Debug@h
+ ori r22, r22, Debug@l
+ cmplw r21,r22
+ bgt+ 2f /* addr above TLB exception vectors */
+
+ lis r21,DBSR_IC@h /* Remove the trap status */
+ mtspr SPRN_DBSR,r21
+
+ mfspr r21,SPRN_CSRR1
+ rlwinm r21,r21,0,23,21 /* clear MSR_DE */
+ mtspr SPRN_CSRR1, r21 /* restore MSR at rcfi without DE */
+
+ mtcrf 0xff,r20 /* restore registers */
+ mfspr r22,SPRN_SPRG4R
+ mfspr r21,SPRN_SPRG1
+ mfspr r20,SPRN_SPRG0
+
+ sync
+ rfci /* return to the exception handler */
+ b . /* prevent prefetch past rfci */
+
+2:
+ mtcrf 0xff,r20 /* restore registers */
+ mfspr r22,SPRN_SPRG4R
+ mfspr r21,SPRN_SPRG1
+ mfspr r20,SPRN_SPRG0
+
+ CRIT_EXCEPTION_PROLOG
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r7,CRIT_EXC;
+ li r20,MSR_KERNEL
+ FINISH_EXCEPTION(0x2000, DebugException)
+
+/*
+ * Local functions
+ */
+
+ /*
+ * Data TLB exceptions will bail out to this point
+ * if they can't resolve the lightweight TLB fault.
+ */
+data_access:
+ STND_EXCEPTION_PROLOG
+ mfspr r5,SPRN_ESR /* Grab the ESR, save it, pass arg3 */
+ stw r5,_ESR(r21)
+ mfspr r4,SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */
+ stw r4,_DEAR(r21)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r7,STND_EXC
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 /* Copy EE bit from the saved MSR */
+ FINISH_EXCEPTION(0x800, do_page_fault) /* do_page_fault(regs, ESR, DEAR) */
+
+/*
+ * Both the instruction and data TLB miss get to this
+ * point to load the TLB.
+ * r20 - EA of fault
+ * r21 - LS word of the PTE
+ * r22 - Pointer to our 64-bit PTE
+ * r23 - available to use
+ * r24 - available to use
+ * MMUCR - loaded with proper value when we get here
+ * Upon exit, we reload everything and RFI.
+ */
+finish_tlb_load:
+ /*
+ * We set execute, because we don't have the granularity to
+ * properly set this at the page level (Linux problem).
+ * If shared is set, we cause a zero PID->TID load.
+ * Many of these bits are software only. Bits we don't set
+ * here we (properly should) assume have the appropriate value.
+ */
+
+ /* Load the next available TLB index */
+ lis r23, tlb_4xx_index@h
+ ori r23, r23, tlb_4xx_index@l
+ lwz r24, 0(r23)
+ /* Increment, rollover, and store TLB index */
+ addi r24, r24, 1
+ cmpwi 0, r24, 61 /* reserve entries 62-63 for kernel */
+ ble 7f
+ li r24, 0
+7:
+ stw r24, 0(r23)
+
+6:
+ lwz r23, 0(r22) /* Get MS word of PTE */
+ rlwimi r23, r21, 0, 0 , 19 /* Insert RPN */
+ tlbwe r23, r24, PPC440_TLB_XLAT /* Write XLAT */
+
+ /*
+ * Create PAGEID. This is the faulting address plus
+ * a set of static bits. The static bits are page
+ * size and valid. Bits 20 and 21 should be zero
+ * for a page size of 4KB.
+ */
+ li r22, 0x0210 /* Set size and valid */
+ mfspr r23, SPRN_SRR1 /* Get SRR1 */
+ andi. r23, r23, MSR_IS@l
+ beq 7f
+ ori r22, r22, PPC440_TLB_TS@l /* Set TS=1 */
+7: rlwimi r20, r22, 0, 20, 31 /* Insert statics */
+ tlbwe r20, r24, PPC440_TLB_PAGEID /* Write PAGEID */
+
+ /* FIXME: Staticly setting some permissions */
+ li r23, 0x002d /* Set UX,UR,SX,SR */
+ andi. r21, r21, 0xffff /* Clear MS 16 bits */
+ andi. r22, r21, 0x0002 /* _PAGE_HWWRITE? */
+ beq 8f
+ ori r23, r23, 0x0002 /* Set SW */
+ /* FIXME: Force attributes */
+8: ori r21, r21, 0x0100 /* Set G */
+ /* FIXME: Already set in PTE */
+ rlwimi r21, r23, 0, 26, 31 /* Insert static perms */
+
+ lis r23,0xffff
+ ori r23,r23,0x0fff /* Set U0-U3 mask */
+ and r21,r21,r23 /* Clear U0-U3 */
+ tlbwe r21, r24, PPC440_TLB_ATTRIB /* Write ATTRIB */
+
+ /* Done...restore registers and get out of here.
+ */
+ mfspr r21, SPRG7R
+ mtcr r21
+ mfspr r24, SPRG6R
+ mfspr r23, SPRG5R
+ mfspr r22, SPRG4R
+ mfspr r21, SPRG1
+ mfspr r20, SPRG0
+ rfi /* Force context change */
+
+/*
+ * Global functions
+ */
+
+/*
+ * extern void giveup_altivec(struct task_struct *prev)
+ *
+ * The 440 core does not have an AltiVec unit.
+ */
+_GLOBAL(giveup_altivec)
+ blr
+
+/*
+ * extern void giveup_fpu(struct task_struct *prev)
+ *
+ * The 440 core does not have an FPU.
+ */
+_GLOBAL(giveup_fpu)
+ blr
+
+/*
+ * extern void abort(void)
+ *
+ * At present, this routine just applies a system reset.
+ */
+_GLOBAL(abort)
+ mfspr r13,SPRN_DBCR0
+ oris r13,r13,DBCR_RST(DBCR_RST_SYSTEM)@h
+ mtspr SPRN_DBCR0,r13
+
+_GLOBAL(set_context)
+
+#ifdef CONFIG_BDI_SWITCH
+ /* Context switch the PTE pointer for the Abatron BDI2000.
+ * The PGDIR is the second parameter.
+ */
+ lis r5, abatron_pteptrs@h
+ ori r5, r5, abatron_pteptrs@l
+ stw r4, 0x4(r5)
+#endif
+ mtspr SPRN_PID,r3
+ isync /* Force context change */
+ blr
+
+/*
+ * This code finishes saving the registers to the exception frame
+ * and jumps to the appropriate handler for the exception, turning
+ * on address translation.
+ */
+_GLOBAL(transfer_to_handler)
+ stw r22,_NIP(r21) /* Save the faulting IP on the stack */
+ stw r23,_MSR(r21) /* Save the exception MSR on stack */
+ SAVE_4GPRS(8, r21) /* Save r8 through r11 on the stack */
+ SAVE_8GPRS(12, r21) /* Save r12 through r19 on the stack */
+ SAVE_8GPRS(24, r21) /* Save r24 through r31 on the stack */
+ andi. r23,r23,MSR_PR /* Is this from user space? */
+ mfspr r23,SPRN_SPRG3 /* If from user, fix up THREAD.regs */
+ beq 2f /* No, it is from the kernel; branch. */
+ mfspr r24,SPRN_DBCR0
+ stw r24,THREAD_DBCR0(r23) /* Save Debug Control in thread_struct */
+ addi r24,r1,STACK_FRAME_OVERHEAD
+ stw r24,PT_REGS(r23)
+2: addi r2,r23,-THREAD /* Set r2 to current thread */
+ mflr r23
+ lwz r24,8(r23) /* Emulate classic PPC vectors */
+ stw r24,TRAP(r21)
+ li r22,RESULT
+ /* No need to put an erratum #77 workaround here
+ because interrupts are currently disabled */
+ stwcx. r22,r22,r21 /* Clear the reservation */
+ li r22,0
+ stw r22,RESULT(r21)
+ mtspr SPRN_SPRG2,r22 /* r1 is now the kernel stack pointer */
+ addi r24,r2,TASK_STRUCT_SIZE /* Check for kernel stack overflow */
+ cmplw cr0,r1,r2
+ cmplw cr1,r1,r24
+ crand cr1,cr1,cr4
+ bgt- stack_ovf /* If r2 < r1 < r2 + TASK_STRUCT_SIZE */
+ lwz r24,0(r23) /* Virtual address of the handler */
+ lwz r23,4(r23) /* Handler return pointer */
+ cmpwi cr0,r7,STND_EXC /* What type of exception is this? */
+ bne 3f /* It is a critical exception... */
+
+ /* Standard exception jump path
+ */
+
+ /* We have to recover r7 from the register save stack.
+ * It was used to indicate standard/critical exception. In
+ * the case of a standard exception that is the system call
+ * trap, it may have originally contained one of the syscall
+ * parameters and we have to get it back now.
+ */
+ lwz r7,GPR7(r21)
+ mtspr SPRN_SRR0,r24 /* Set up the instruction pointer */
+ mtspr SPRN_SRR1,r20 /* Set up the machine state register */
+ mtlr r23 /* Set up the return pointer */
+ SYNC
+ /* We shouldn't need a 405 erratum #77 workaround here, because we're not
+ * actually returning to the interrupted instruction yet. */
+ rfi
+
+ /* Critical exception jump path
+ */
+
+3: mtspr SPRN_CSRR0,r24 /* Set up the instruction pointer */
+ mtspr SPRN_CSRR1,r20 /* Set up the machine state register */
+ mtlr r23 /* Set up the return pointer */
+ SYNC
+ rfci
+
+/* On kernel stack overlow, load up an initial stack pointer and call
+ * StackOverflow(regs), which should NOT return.
+ */
+
+stack_ovf:
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ lis r1,init_task_union@ha
+ addi r1,r1,init_task_union@l
+ addi r1,r1,TASK_UNION_SIZE - STACK_FRAME_OVERHEAD
+ lis r24,StackOverflow@ha
+ addi r24,r24,StackOverflow@l
+ li r20,MSR_KERNEL
+ mtspr SPRN_SRR0,r24
+ mtspr SPRN_SRR1,r20
+ SYNC
+ rfi
+
+/*
+ * We put a few things here that have to be page-aligned. This stuff
+ * goes at the beginning of the data segment, which is page-aligned.
+ */
+ .data
+_GLOBAL(sdata)
+_GLOBAL(empty_zero_page)
+ .space 4096
+
+/*
+ * To support >32-bit physical addresses, we use an 8KB pgdir.
+ */
+_GLOBAL(swapper_pg_dir)
+ .space 8192
+
+/*
+ * This space gets a copy of optional info passed to us by the bootstrap
+ * which is used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */
+_GLOBAL(cmd_line)
+ .space 512
+
+/*
+ * Room for two PTE pointers, usually the kernel and current user pointers
+ * to their respective root page table.
+ */
+abatron_pteptrs:
+ .space 8
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/head_8xx.S linuxppc-2.4/arch/ppc/kernel/head_8xx.S
--- linux-2.4.22/arch/ppc/kernel/head_8xx.S 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/head_8xx.S 2003-07-25 02:06:49.000000000 +1000
@@ -21,9 +21,9 @@
*
*/
+#include
#include
#include
-#include
#include
#include
#include
@@ -817,16 +817,31 @@
* kernel initialization. This maps the first 8 MBytes of memory 1:1
* virtual to physical. Also, set the cache mode since that is defined
* by TLB entries and perform any additional mapping (like of the IMMR).
+ * If configured to pin some TLBs, we pin the first 8 Mbytes of kernel,
+ * 24 Mbytes of data, and the 8M IMMR space. Anything not covered by
+ * these mappings is mapped by page tables.
*/
initial_mmu:
tlbia /* Invalidate all TLB entries */
+#ifdef CONFIG_PIN_TLB
+ lis r8, MI_RSV4I@h
+ ori r8, r8, 0x1c00
+#else
li r8, 0
- mtspr MI_CTR, r8 /* Set instruction control to zero */
- lis r8, MD_RESETVAL@h
+#endif
+ mtspr MI_CTR, r8 /* Set instruction MMU control */
+
+#ifdef CONFIG_PIN_TLB
+ lis r10, (MD_RSV4I | MD_RESETVAL)@h
+ ori r10, r10, 0x1c00
+ mr r8, r10
+#else
+ lis r10, MD_RESETVAL@h
+#endif
#ifndef CONFIG_8xx_COPYBACK
- oris r8, r8, MD_WTDEF@h
+ oris r10, r10, MD_WTDEF@h
#endif
- mtspr MD_CTR, r8 /* Set data TLB control */
+ mtspr MD_CTR, r10 /* Set data TLB control */
/* Now map the lower 8 Meg into the TLBs. For this quick hack,
* we can load the instruction and data TLB registers with the
@@ -850,6 +865,10 @@
/* Map another 8 MByte at the IMMR to get the processor
* internal registers (among other things).
*/
+#ifdef CONFIG_PIN_TLB
+ addi r10, r10, 0x0100
+ mtspr MD_CTR, r10
+#endif
mfspr r9, 638 /* Get current IMMR */
andis. r9, r9, 0xff80 /* Get 8Mbyte boundary */
@@ -863,6 +882,30 @@
ori r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
mtspr MD_RPN, r8
+#ifdef CONFIG_PIN_TLB
+ /* Map two more 8M kernel data pages.
+ */
+ addi r10, r10, 0x0100
+ mtspr MD_CTR, r10
+
+ lis r8, KERNELBASE@h /* Create vaddr for TLB */
+ addis r8, r8, 0x0080 /* Add 8M */
+ ori r8, r8, MI_EVALID /* Mark it valid */
+ mtspr MD_EPN, r8
+ li r9, MI_PS8MEG /* Set 8M byte page */
+ ori r9, r9, MI_SVALID /* Make it valid */
+ mtspr MD_TWC, r9
+ li r11, MI_BOOTINIT /* Create RPN for address 0 */
+ addis r11, r11, 0x0080 /* Add 8M */
+ mtspr MD_RPN, r8
+
+ addis r8, r8, 0x0080 /* Add 8M */
+ mtspr MD_EPN, r8
+ mtspr MD_TWC, r9
+ addis r11, r11, 0x0080 /* Add 8M */
+ mtspr MD_RPN, r8
+#endif
+
/* Since the cache is enabled according to the information we
* just loaded into the TLB, invalidate and enable the caches here.
* We should probably check/set other modes....later.
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/idle_4xx.c linuxppc-2.4/arch/ppc/kernel/idle_4xx.c
--- linux-2.4.22/arch/ppc/kernel/idle_4xx.c 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/idle_4xx.c 2003-03-14 20:46:44.000000000 +1100
@@ -0,0 +1,41 @@
+/*
+ * This is the old power_save() function from idle.c:
+ *
+ * Written by Cort Dougan (cort@cs.nmt.edu)
+ *
+ * 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
+
+void power_save_4xx(void)
+{
+ /* Make sure the CPU has the DOZE feature set. */
+ if (!(cur_cpu_spec[smp_processor_id()]->cpu_features
+ & CPU_FTR_CAN_DOZE))
+ return;
+ /*
+ * Disable interrupts to prevent a lost wakeup
+ * when going to sleep. This is necessary even with
+ * RTLinux since we are not guaranteed an interrupt
+ * didn't come in and is waiting for a __sti() before
+ * emulating one. This way, we really do hard disable.
+ *
+ * We assume that we're sti-ed when we come in here. We
+ * are in the idle loop so if we're cli-ed then it's a bug
+ * anyway.
+ * -- Cort
+ */
+ _nmask_and_or_msr(MSR_EE, 0);
+ if (!current->need_resched) {
+ /* set the POW bit in the MSR, and enable interrupts
+ * so we wake up sometime! */
+ _nmask_and_or_msr(0, MSR_POW | MSR_EE);
+ }
+ _nmask_and_or_msr(0, MSR_EE);
+}
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/m8xx_setup.c linuxppc-2.4/arch/ppc/kernel/m8xx_setup.c
--- linux-2.4.22/arch/ppc/kernel/m8xx_setup.c 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/m8xx_setup.c 2003-07-25 02:06:49.000000000 +1000
@@ -336,7 +336,7 @@
io_block_mapping(_IO_BASE,_IO_BASE,_IO_BASE_SIZE, _PAGE_IO);
#endif
#endif
-#ifdef CONFIG_HTDMSOUND
+#if defined(CONFIG_HTDMSOUND) || defined(CONFIG_RPXTOUCH) || defined(CONFIG_FB_RPX)
io_block_mapping(HIOX_CSR_ADDR, HIOX_CSR_ADDR, HIOX_CSR_SIZE, _PAGE_IO);
#endif
#ifdef CONFIG_FADS
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/misc.S linuxppc-2.4/arch/ppc/kernel/misc.S
--- linux-2.4.22/arch/ppc/kernel/misc.S 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/misc.S 2003-07-25 02:06:49.000000000 +1000
@@ -361,6 +361,15 @@
cmpwi 0, r3, 61 /* reserve last two entries */
ble 1b
isync
+#elif defined(CONFIG_440)
+ lis r3,0
+ sync
+1:
+ tlbwe r3,r3,PPC440_TLB_PAGEID
+ addi r3,r3,1
+ cmpwi 0,r3,61
+ ble 1b
+ isync
#else
#if defined(CONFIG_SMP)
mfmsr r10
@@ -406,6 +415,30 @@
tlbwe r3, r3, TLB_TAG
isync
10:
+#elif defined(CONFIG_440)
+ mfspr r4,SPRN_MMUCR /* Get MMUCR */
+ lis r5,PPC440_MMUCR_STS@h
+ ori r5,r5,PPC440_MMUCR_TID@l /* Create mask */
+ andc r4,r4,r5 /* Clear out TID/STS bits */
+ mfspr r5,SPRN_PID /* Get PID */
+ or r4,r4,r5 /* Set TID bits */
+ mfmsr r6 /* Get MSR */
+ andi. r6,r6,MSR_IS@l /* TS=1? */
+ beq 11f /* If not, leave STS=0 */
+ oris r4,r4,PPC440_MMUCR_STS@h /* Set STS=1 */
+11: mtspr SPRN_MMUCR, r4 /* Put MMUCR */
+
+ tlbsx. r3, 0, r3
+ bne 10f
+ sync
+ /* There are only 64 TLB entries, so r3 < 64,
+ * which means bit 22, is clear. Since 22 is
+ * the V bit in the TLB_PAGEID, loading this
+ * value will invalidate the TLB entry.
+ */
+ tlbwe r3, r3, PPC440_TLB_PAGEID
+ isync
+10:
#else
#if defined(CONFIG_SMP)
mfmsr r10
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/mk_defs.c linuxppc-2.4/arch/ppc/kernel/mk_defs.c
--- linux-2.4.22/arch/ppc/kernel/mk_defs.c 2003-06-25 20:56:52.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/mk_defs.c 2003-06-25 21:30:07.000000000 +1000
@@ -25,6 +25,10 @@
#include
#include
+#ifdef CONFIG_405LP
+#include
+#endif /* CONFIG_405LP */
+
#define DEFINE(sym, val) \
asm volatile("\n#define\t" #sym "\t%0" : : "i" (val))
@@ -109,7 +113,7 @@
DEFINE(_XER, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, xer));
DEFINE(_DAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
- /* The PowerPC 400-class processors have neither the DAR nor the DSISR
+ /* The PowerPC 400-class & Book-E processors have neither the DAR nor the DSISR
* SPRs. Hence, we overload them to hold the similar DEAR and ESR SPRs
* for such processors.
*/
@@ -129,5 +133,12 @@
DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
+
+#ifdef CONFIG_405LP
+ DEFINE(WAKEUP_FUNC_OFFSET, offsetof(struct ibm405lp_wakeup_info, wakeup_func_phys));
+ DEFINE(WAKEUP_MAGIC_OFFSET, offsetof(struct ibm405lp_wakeup_info, magic));
+ DEFINE(WAKEUP_SP_OFFSET, offsetof(struct ibm405lp_wakeup_info, wakeup_stack_phys));
+#endif /* CONFIG_405LP */
+
return 0;
}
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/pci-dma.c linuxppc-2.4/arch/ppc/kernel/pci-dma.c
--- linux-2.4.22/arch/ppc/kernel/pci-dma.c 2003-02-15 08:07:09.000000000 +1100
+++ linuxppc-2.4/arch/ppc/kernel/pci-dma.c 2003-03-14 20:46:44.000000000 +1100
@@ -22,11 +22,18 @@
if (hwdev == NULL || hwdev->dma_mask != 0xffffffff)
gfp |= GFP_DMA;
+
+#ifdef CONFIG_NOT_COHERENT_CACHE
+ ret = consistent_alloc(gfp, size, dma_handle);
+#else
ret = (void *)__get_free_pages(gfp, get_order(size));
+#endif
if (ret != NULL) {
memset(ret, 0, size);
+#ifndef CONFIG_NOT_COHERENT_CACHE
*dma_handle = virt_to_bus(ret);
+#endif
}
return ret;
}
@@ -34,5 +41,9 @@
void pci_free_consistent(struct pci_dev *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
+#ifdef CONFIG_NOT_COHERENT_CACHE
+ consistent_free(vaddr);
+#else
free_pages((unsigned long)vaddr, get_order(size));
+#endif
}
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/ppc-stub.c linuxppc-2.4/arch/ppc/kernel/ppc-stub.c
--- linux-2.4.22/arch/ppc/kernel/ppc-stub.c 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/ppc-stub.c 2003-08-26 11:57:12.000000000 +1000
@@ -135,7 +135,7 @@
/* typedef void (*trapfunc_t)(void); */
static void kgdb_fault_handler(struct pt_regs *regs);
-static void handle_exception (struct pt_regs *regs);
+static int handle_exception (struct pt_regs *regs);
#if 0
/* Install an exception handler for kgdb */
@@ -387,14 +387,12 @@
int kgdb_bpt(struct pt_regs *regs)
{
- handle_exception(regs);
- return 1;
+ return handle_exception(regs);
}
int kgdb_sstep(struct pt_regs *regs)
{
- handle_exception(regs);
- return 1;
+ return handle_exception(regs);
}
void kgdb(struct pt_regs *regs)
@@ -404,16 +402,14 @@
int kgdb_iabr_match(struct pt_regs *regs)
{
- printk("kgdb doesn't support iabr, what?!?\n");
- handle_exception(regs);
- return 1;
+ printk(KERN_ERR "kgdb doesn't support iabr, what?!?\n");
+ return handle_exception(regs);
}
int kgdb_dabr_match(struct pt_regs *regs)
{
- printk("kgdb doesn't support dabr, what?!?\n");
- handle_exception(regs);
- return 1;
+ printk(KERN_ERR "kgdb doesn't support dabr, what?!?\n");
+ return handle_exception(regs);
}
/* Convert the SPARC hardware trap type code to a unix signal number. */
@@ -459,7 +455,7 @@
/*
* This function does all command processing for interfacing to gdb.
*/
-static void
+static int
handle_exception (struct pt_regs *regs)
{
int sigval;
@@ -468,14 +464,19 @@
char *ptr;
unsigned int msr;
+ /* We don't handle user-mode breakpoints. */
+ if (user_mode(regs))
+ return 0;
+
if (debugger_fault_handler) {
debugger_fault_handler(regs);
panic("kgdb longjump failed!\n");
}
if (kgdb_active) {
- printk("interrupt while in kgdb, returning\n");
- return;
+ printk(KERN_ERR "interrupt while in kgdb, returning\n");
+ return 0;
}
+
kgdb_active = 1;
kgdb_started = 1;
@@ -677,14 +678,14 @@
kgdb_interruptible(1);
unlock_kernel();
kgdb_active = 0;
- return;
+ return 1;
case 's':
kgdb_flush_cache_all();
regs->msr |= MSR_SE;
unlock_kernel();
kgdb_active = 0;
- return;
+ return 1;
case 'r': /* Reset (if user process..exit ???)*/
panic("kgdb reset.");
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/ppc4xx_dma.c linuxppc-2.4/arch/ppc/kernel/ppc4xx_dma.c
--- linux-2.4.22/arch/ppc/kernel/ppc4xx_dma.c 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/ppc4xx_dma.c 2003-05-26 09:40:53.000000000 +1000
@@ -0,0 +1,852 @@
+/*
+ * arch/ppc/kernel/ppc4xx_dma.c
+ *
+ * IBM PPC4xx DMA engine core library
+ *
+ * Copyright 2000-2003 MontaVista Software Inc.
+ *
+ * Cleaned by Matt Porter
+ *
+ * Original code by Armin Kuster
+ * and Pete Popov
+ *
+ * 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.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+ppc_dma_ch_t dma_channels[MAX_PPC4xx_DMA_CHANNELS];
+
+int
+ppc4xx_get_dma_status(void)
+{
+ return (mfdcr(DCRN_DMASR));
+}
+
+void
+ppc4xx_set_src_addr(int dmanr, phys_addr_t src_addr)
+{
+ switch (dmanr) {
+ case 0:
+#ifdef PPC4xx_DMA_64BIT
+ mtdcr(DCRN_DMASAH0, (u32)(src_addr >> 32));
+#endif
+ mtdcr(DCRN_DMASA0, (u32)src_addr);
+ break;
+ case 1:
+#ifdef PPC4xx_DMA_64BIT
+ mtdcr(DCRN_DMASAH1, (u32)(src_addr >> 32));
+#endif
+ mtdcr(DCRN_DMASA1, (u32)src_addr);
+ break;
+ case 2:
+#ifdef PPC4xx_DMA_64BIT
+ mtdcr(DCRN_DMASAH2, (u32)(src_addr >> 32));
+#endif
+ mtdcr(DCRN_DMASA2, (u32)src_addr);
+ break;
+ case 3:
+#ifdef PPC4xx_DMA_64BIT
+ mtdcr(DCRN_DMASAH3, (u32)(src_addr >> 32));
+#endif
+ mtdcr(DCRN_DMASA3, (u32)src_addr);
+ break;
+ default:
+ if (dmanr >= MAX_PPC4xx_DMA_CHANNELS)
+ printk("set_src_addr: bad channel: %d\n", dmanr);
+ }
+}
+
+void
+ppc4xx_set_dst_addr(int dmanr, phys_addr_t dst_addr)
+{
+ switch (dmanr) {
+ case 0:
+#ifdef PPC4xx_DMA_64BIT
+ mtdcr(DCRN_DMADAH0, (u32)(dst_addr >> 32));
+#endif
+ mtdcr(DCRN_DMADA0, (u32)dst_addr);
+ break;
+ case 1:
+#ifdef PPC4xx_DMA_64BIT
+ mtdcr(DCRN_DMADAH1, (u32)(dst_addr >> 32));
+#endif
+ mtdcr(DCRN_DMADA1, (u32)dst_addr);
+ break;
+ case 2:
+#ifdef PPC4xx_DMA_64BIT
+ mtdcr(DCRN_DMADAH2, (u32)(dst_addr >> 32));
+#endif
+ mtdcr(DCRN_DMADA2, (u32)dst_addr);
+ break;
+ case 3:
+#ifdef PPC4xx_DMA_64BIT
+ mtdcr(DCRN_DMADAH3, (u32)(dst_addr >> 32));
+#endif
+ mtdcr(DCRN_DMADA3, (u32)dst_addr);
+ break;
+ default:
+ if (dmanr >= MAX_PPC4xx_DMA_CHANNELS)
+ printk("set_dst_addr: bad channel: %d\n", dmanr);
+ }
+}
+
+
+void
+ppc4xx_enable_dma(unsigned int dmanr)
+{
+ unsigned int control;
+ ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
+ unsigned int status_bits[] = { DMA_CS0 | DMA_TS0 | DMA_CH0_ERR,
+ DMA_CS1 | DMA_TS1 | DMA_CH1_ERR,
+ DMA_CS2 | DMA_TS2 | DMA_CH2_ERR,
+ DMA_CS3 | DMA_TS3 | DMA_CH3_ERR};
+
+ if (p_dma_ch->in_use) {
+ printk("enable_dma: channel %d in use\n", dmanr);
+ return;
+ }
+
+ if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
+ printk("enable_dma: bad channel: %d\n", dmanr);
+ return;
+ }
+
+ if (p_dma_ch->mode == DMA_MODE_READ) {
+ /* peripheral to memory */
+ ppc4xx_set_src_addr(dmanr, 0);
+ ppc4xx_set_dst_addr(dmanr, p_dma_ch->addr);
+ } else if (p_dma_ch->mode == DMA_MODE_WRITE) {
+ /* memory to peripheral */
+ ppc4xx_set_src_addr(dmanr, p_dma_ch->addr);
+ ppc4xx_set_dst_addr(dmanr, 0);
+ }
+
+ /* for other xfer modes, the addresses are already set */
+ switch (dmanr) {
+ case 0:
+ control = mfdcr(DCRN_DMACR0);
+ break;
+ case 1:
+ control = mfdcr(DCRN_DMACR1);
+ break;
+ case 2:
+ control = mfdcr(DCRN_DMACR2);
+ break;
+ case 3:
+ control = mfdcr(DCRN_DMACR3);
+ break;
+ default:
+ printk("enable_dma: bad channel: %d\n", dmanr);
+ }
+
+ control &= ~(DMA_TM_MASK | DMA_TD); /* clear all mode bits */
+ if (p_dma_ch->mode == DMA_MODE_MM) {
+ /* software initiated memory to memory */
+ control |= DMA_ETD_OUTPUT | DMA_TCE_ENABLE;
+ }
+
+ switch (dmanr) {
+ case 0:
+ mtdcr(DCRN_DMACR0, control);
+ break;
+ case 1:
+ mtdcr(DCRN_DMACR1, control);
+ break;
+ case 2:
+ mtdcr(DCRN_DMACR2, control);
+ break;
+ case 3:
+ mtdcr(DCRN_DMACR3, control);
+ break;
+ default:
+ printk("enable_dma: bad channel: %d\n", dmanr);
+ }
+
+ /*
+ * Clear the CS, TS, RI bits for the channel from DMASR. This
+ * has been observed to happen correctly only after the mode and
+ * ETD/DCE bits in DMACRx are set above. Must do this before
+ * enabling the channel.
+ */
+
+ mtdcr(DCRN_DMASR, status_bits[dmanr]);
+
+ /*
+ * For device-paced transfers, Terminal Count Enable apparently
+ * must be on, and this must be turned on after the mode, etc.
+ * bits are cleared above (at least on Redwood-6).
+ */
+
+ if ((p_dma_ch->mode == DMA_MODE_MM_DEVATDST) ||
+ (p_dma_ch->mode == DMA_MODE_MM_DEVATSRC))
+ control |= DMA_TCE_ENABLE;
+
+ /*
+ * Now enable the channel.
+ */
+
+ control |= (p_dma_ch->mode | DMA_CE_ENABLE);
+
+ switch (dmanr) {
+ case 0:
+ mtdcr(DCRN_DMACR0, control);
+ break;
+ case 1:
+ mtdcr(DCRN_DMACR1, control);
+ break;
+ case 2:
+ mtdcr(DCRN_DMACR2, control);
+ break;
+ case 3:
+ mtdcr(DCRN_DMACR3, control);
+ break;
+ default:
+ printk("enable_dma: bad channel: %d\n", dmanr);
+ }
+
+ p_dma_ch->in_use = 1;
+}
+
+void
+ppc4xx_disable_dma(unsigned int dmanr)
+{
+ unsigned int control;
+ ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
+
+ if (!p_dma_ch->in_use) {
+ printk("disable_dma: channel %d not in use\n", dmanr);
+ return;
+ }
+
+ if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
+ printk("disable_dma: bad channel: %d\n", dmanr);
+ return;
+ }
+
+ switch (dmanr) {
+ case 0:
+ control = mfdcr(DCRN_DMACR0);
+ control &= ~DMA_CE_ENABLE;
+ mtdcr(DCRN_DMACR0, control);
+ break;
+ case 1:
+ control = mfdcr(DCRN_DMACR1);
+ control &= ~DMA_CE_ENABLE;
+ mtdcr(DCRN_DMACR1, control);
+ break;
+ case 2:
+ control = mfdcr(DCRN_DMACR2);
+ control &= ~DMA_CE_ENABLE;
+ mtdcr(DCRN_DMACR2, control);
+ break;
+ case 3:
+ control = mfdcr(DCRN_DMACR3);
+ control &= ~DMA_CE_ENABLE;
+ mtdcr(DCRN_DMACR3, control);
+ break;
+ default:
+ printk("disable_dma: bad channel: %d\n", dmanr);
+ }
+
+ p_dma_ch->in_use = 0;
+}
+
+/*
+ * Sets the dma mode for single DMA transfers only.
+ * For scatter/gather transfers, the mode is passed to the
+ * alloc_dma_handle() function as one of the parameters.
+ *
+ * The mode is simply saved and used later. This allows
+ * the driver to call set_dma_mode() and set_dma_addr() in
+ * any order.
+ *
+ * Valid mode values are:
+ *
+ * DMA_MODE_READ peripheral to memory
+ * DMA_MODE_WRITE memory to peripheral
+ * DMA_MODE_MM memory to memory
+ * DMA_MODE_MM_DEVATSRC device-paced memory to memory, device at src
+ * DMA_MODE_MM_DEVATDST device-paced memory to memory, device at dst
+ */
+int
+ppc4xx_set_dma_mode(unsigned int dmanr, unsigned int mode)
+{
+ ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
+
+ if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
+ printk("set_dma_mode: bad channel 0x%x\n", dmanr);
+ return DMA_STATUS_BAD_CHANNEL;
+ }
+
+ p_dma_ch->mode = mode;
+
+ return DMA_STATUS_GOOD;
+}
+
+/*
+ * Sets the DMA Count register. Note that 'count' is in bytes.
+ * However, the DMA Count register counts the number of "transfers",
+ * where each transfer is equal to the bus width. Thus, count
+ * MUST be a multiple of the bus width.
+ */
+void
+ppc4xx_set_dma_count(unsigned int dmanr, unsigned int count)
+{
+ ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
+
+#ifdef DEBUG_4xxDMA
+ {
+ int error = 0;
+ switch (p_dma_ch->pwidth) {
+ case PW_8:
+ break;
+ case PW_16:
+ if (count & 0x1)
+ error = 1;
+ break;
+ case PW_32:
+ if (count & 0x3)
+ error = 1;
+ break;
+ case PW_64:
+ if (count & 0x7)
+ error = 1;
+ break;
+ default:
+ printk("set_dma_count: invalid bus width: 0x%x\n",
+ p_dma_ch->pwidth);
+ return;
+ }
+ if (error)
+ printk
+ ("Warning: set_dma_count count 0x%x bus width %d\n",
+ count, p_dma_ch->pwidth);
+ }
+#endif
+
+ count = count >> p_dma_ch->shift;
+ switch (dmanr) {
+ case 0:
+ mtdcr(DCRN_DMACT0, count);
+ break;
+ case 1:
+ mtdcr(DCRN_DMACT1, count);
+ break;
+ case 2:
+ mtdcr(DCRN_DMACT2, count);
+ break;
+ case 3:
+ mtdcr(DCRN_DMACT3, count);
+ break;
+ default:
+ printk("ppc4xx_set_dma_count: bad channel: %d\n", dmanr);
+ }
+}
+
+/*
+ * Returns the number of bytes left to be transfered.
+ * After a DMA transfer, this should return zero.
+ * Reading this while a DMA transfer is still in progress will return
+ * unpredictable results.
+ */
+int
+ppc4xx_get_dma_residue(unsigned int dmanr)
+{
+ unsigned int count;
+ ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
+
+ switch (dmanr) {
+ case 0:
+ count = mfdcr(DCRN_DMACT0);
+ break;
+ case 1:
+ count = mfdcr(DCRN_DMACT1);
+ break;
+ case 2:
+ count = mfdcr(DCRN_DMACT2);
+ break;
+ case 3:
+ count = mfdcr(DCRN_DMACT3);
+ break;
+ default:
+ printk("ppc4xx_get_dma_residue: bad channel: %d\n", dmanr);
+ return 0;
+ }
+
+ return (count << p_dma_ch->shift);
+}
+
+/*
+ * Sets the DMA address for a memory to peripheral or peripheral
+ * to memory transfer. The address is just saved in the channel
+ * structure for now and used later in enable_dma().
+ */
+void
+ppc4xx_set_dma_addr(unsigned int dmanr, phys_addr_t addr)
+{
+ ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
+
+ if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
+ printk("ppc4xx_set_dma_addr: bad channel: %d\n", dmanr);
+ return;
+ }
+
+#ifdef DEBUG_4xxDMA
+ {
+ int error = 0;
+ switch (p_dma_ch->pwidth) {
+ case PW_8:
+ break;
+ case PW_16:
+ if ((unsigned) addr & 0x1)
+ error = 1;
+ break;
+ case PW_32:
+ if ((unsigned) addr & 0x3)
+ error = 1;
+ break;
+ case PW_64:
+ if ((unsigned) addr & 0x7)
+ error = 1;
+ break;
+ default:
+ printk("ppc4xx_set_dma_addr: invalid bus width: 0x%x\n",
+ p_dma_ch->pwidth);
+ return;
+ }
+ if (error)
+ printk("Warning: ppc4xx_set_dma_addr addr 0x%x bus width %d\n",
+ addr, p_dma_ch->pwidth);
+ }
+#endif
+
+ /* save dma address and program it later after we know the xfer mode */
+ p_dma_ch->addr = addr;
+}
+
+/*
+ * Sets both DMA addresses for a memory to memory transfer.
+ * For memory to peripheral or peripheral to memory transfers
+ * the function set_dma_addr() should be used instead.
+ */
+void
+ppc4xx_set_dma_addr2(unsigned int dmanr, phys_addr_t src_dma_addr,
+ phys_addr_t dst_dma_addr)
+{
+#ifdef DEBUG_4xxDMA
+ {
+ ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
+ int error = 0;
+ switch (p_dma_ch->pwidth) {
+ case PW_8:
+ break;
+ case PW_16:
+ if (((unsigned) src_dma_addr & 0x1) ||
+ ((unsigned) dst_dma_addr & 0x1)
+ )
+ error = 1;
+ break;
+ case PW_32:
+ if (((unsigned) src_dma_addr & 0x3) ||
+ ((unsigned) dst_dma_addr & 0x3)
+ )
+ error = 1;
+ break;
+ case PW_64:
+ if (((unsigned) src_dma_addr & 0x7) ||
+ ((unsigned) dst_dma_addr & 0x7)
+ )
+ error = 1;
+ break;
+ default:
+ printk("ppc4xx_set_dma_addr2: invalid bus width: 0x%x\n",
+ p_dma_ch->pwidth);
+ return;
+ }
+ if (error)
+ printk
+ ("Warning: ppc4xx_set_dma_addr2 src 0x%x dst 0x%x bus width %d\n",
+ src_dma_addr, dst_dma_addr, p_dma_ch->pwidth);
+ }
+#endif
+
+ if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
+ printk("ppc4xx_set_dma_addr2: bad channel: %d\n", dmanr);
+ }
+ else {
+ ppc4xx_set_src_addr(dmanr, src_dma_addr);
+ ppc4xx_set_dst_addr(dmanr, dst_dma_addr);
+ }
+}
+
+/*
+ * Enables the channel interrupt.
+ *
+ * If performing a scatter/gatter transfer, this function
+ * MUST be called before calling alloc_dma_handle() and building
+ * the sgl list. Otherwise, interrupts will not be enabled, if
+ * they were previously disabled.
+ */
+int
+ppc4xx_enable_dma_interrupt(unsigned int dmanr)
+{
+ unsigned int control;
+ ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
+
+ p_dma_ch->int_enable = 1;
+ switch (dmanr) {
+ case 0:
+ control = mfdcr(DCRN_DMACR0);
+ control |= DMA_CIE_ENABLE; /* Channel Interrupt Enable */
+ mtdcr(DCRN_DMACR0, control);
+ break;
+ case 1:
+ control = mfdcr(DCRN_DMACR1);
+ control |= DMA_CIE_ENABLE;
+ mtdcr(DCRN_DMACR1, control);
+ break;
+ case 2:
+ control = mfdcr(DCRN_DMACR2);
+ control |= DMA_CIE_ENABLE;
+ mtdcr(DCRN_DMACR2, control);
+ break;
+ case 3:
+ control = mfdcr(DCRN_DMACR3);
+ control |= DMA_CIE_ENABLE;
+ mtdcr(DCRN_DMACR3, control);
+ break;
+ default:
+ printk("ppc4xx_enable_dma_interrupt: bad channel: %d\n", dmanr);
+ return DMA_STATUS_BAD_CHANNEL;
+ }
+ return DMA_STATUS_GOOD;
+}
+
+/*
+ * Disables the channel interrupt.
+ *
+ * If performing a scatter/gatter transfer, this function
+ * MUST be called before calling alloc_dma_handle() and building
+ * the sgl list. Otherwise, interrupts will not be disabled, if
+ * they were previously enabled.
+ */
+int
+ppc4xx_disable_dma_interrupt(unsigned int dmanr)
+{
+ unsigned int control;
+ ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
+
+ p_dma_ch->int_enable = 0;
+ switch (dmanr) {
+ case 0:
+ control = mfdcr(DCRN_DMACR0);
+ control &= ~DMA_CIE_ENABLE; /* Channel Interrupt Enable */
+ mtdcr(DCRN_DMACR0, control);
+ break;
+ case 1:
+ control = mfdcr(DCRN_DMACR1);
+ control &= ~DMA_CIE_ENABLE;
+ mtdcr(DCRN_DMACR1, control);
+ break;
+ case 2:
+ control = mfdcr(DCRN_DMACR2);
+ control &= ~DMA_CIE_ENABLE;
+ mtdcr(DCRN_DMACR2, control);
+ break;
+ case 3:
+ control = mfdcr(DCRN_DMACR3);
+ control &= ~DMA_CIE_ENABLE;
+ mtdcr(DCRN_DMACR3, control);
+ break;
+ default:
+ printk("ppc4xx_disable_dma_interrupt: bad channel: %d\n", dmanr);
+ return DMA_STATUS_BAD_CHANNEL;
+ }
+ return DMA_STATUS_GOOD;
+}
+
+/*
+ * Configures a DMA channel, including the peripheral bus width, if a
+ * peripheral is attached to the channel, the polarity of the DMAReq and
+ * DMAAck signals, etc. This information should really be setup by the boot
+ * code, since most likely the configuration won't change dynamically.
+ * If the kernel has to call this function, it's recommended that it's
+ * called from platform specific init code. The driver should not need to
+ * call this function.
+ */
+int
+ppc4xx_init_dma_channel(unsigned int dmanr, ppc_dma_ch_t * p_init)
+{
+ unsigned int polarity;
+ uint32_t control = 0;
+ ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
+
+ DMA_MODE_READ = (unsigned long) DMA_TD; /* Peripheral to Memory */
+ DMA_MODE_WRITE = 0; /* Memory to Peripheral */
+
+ if (!p_init) {
+ printk("ppc4xx_init_dma_channel: NULL p_init\n");
+ return DMA_STATUS_NULL_POINTER;
+ }
+
+ if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
+ printk("ppc4xx_init_dma_channel: bad channel %d\n", dmanr);
+ return DMA_STATUS_BAD_CHANNEL;
+ }
+
+#if DCRN_POL > 0
+ polarity = mfdcr(DCRN_POL);
+#else
+ polarity = 0;
+#endif
+
+ /* Setup the control register based on the values passed to
+ * us in p_init. Then, over-write the control register with this
+ * new value.
+ */
+ control |= SET_DMA_CONTROL;
+
+ switch (dmanr) {
+ case 0:
+ /* clear all polarity signals and then "or" in new signal levels */
+ polarity &= ~GET_DMA_POLARITY(0);
+ polarity |= p_dma_ch->polarity;
+#if DCRN_POL > 0
+ mtdcr(DCRN_POL, polarity);
+#endif
+ mtdcr(DCRN_DMACR0, control);
+ break;
+ case 1:
+ polarity &= ~GET_DMA_POLARITY(1);
+ polarity |= p_dma_ch->polarity;
+#if DCRN_POL > 0
+ mtdcr(DCRN_POL, polarity);
+#endif
+ mtdcr(DCRN_DMACR1, control);
+ break;
+ case 2:
+ polarity &= ~GET_DMA_POLARITY(2);
+ polarity |= p_dma_ch->polarity;
+#if DCRN_POL > 0
+ mtdcr(DCRN_POL, polarity);
+#endif
+ mtdcr(DCRN_DMACR2, control);
+ break;
+ case 3:
+ polarity &= ~GET_DMA_POLARITY(3);
+ polarity |= p_dma_ch->polarity;
+#if DCRN_POL > 0
+ mtdcr(DCRN_POL, polarity);
+#endif
+ mtdcr(DCRN_DMACR3, control);
+ break;
+ default:
+ return DMA_STATUS_BAD_CHANNEL;
+ }
+
+ /* save these values in our dma channel structure */
+ memcpy(p_dma_ch, p_init, sizeof (ppc_dma_ch_t));
+
+ /*
+ * The peripheral width values written in the control register are:
+ * PW_8 0
+ * PW_16 1
+ * PW_32 2
+ * PW_64 3
+ *
+ * Since the DMA count register takes the number of "transfers",
+ * we need to divide the count sent to us in certain
+ * functions by the appropriate number. It so happens that our
+ * right shift value is equal to the peripheral width value.
+ */
+ p_dma_ch->shift = p_init->pwidth;
+
+ /*
+ * Save the control word for easy access.
+ */
+ p_dma_ch->control = control;
+
+ mtdcr(DCRN_DMASR, 0xffffffff); /* clear status register */
+ return DMA_STATUS_GOOD;
+}
+
+/*
+ * This function returns the channel configuration.
+ */
+int
+ppc4xx_get_channel_config(unsigned int dmanr, ppc_dma_ch_t * p_dma_ch)
+{
+ unsigned int polarity;
+ unsigned int control;
+
+#if DCRN_POL > 0
+ polarity = mfdcr(DCRN_POL);
+#else
+ polarity = 0;
+#endif
+
+ switch (dmanr) {
+ case 0:
+ p_dma_ch->polarity = polarity & GET_DMA_POLARITY(0);
+ control = mfdcr(DCRN_DMACR0);
+ break;
+ case 1:
+ p_dma_ch->polarity = polarity & GET_DMA_POLARITY(1);
+ control = mfdcr(DCRN_DMACR1);
+ break;
+ case 2:
+ p_dma_ch->polarity = polarity & GET_DMA_POLARITY(2);
+ control = mfdcr(DCRN_DMACR2);
+ break;
+ case 3:
+ p_dma_ch->polarity = polarity & GET_DMA_POLARITY(3);
+ control = mfdcr(DCRN_DMACR3);
+ break;
+ default:
+ return DMA_STATUS_BAD_CHANNEL;
+ }
+
+ p_dma_ch->cp = GET_DMA_PRIORITY(control);
+ p_dma_ch->pwidth = GET_DMA_PW(control);
+ p_dma_ch->psc = GET_DMA_PSC(control);
+ p_dma_ch->pwc = GET_DMA_PWC(control);
+ p_dma_ch->phc = GET_DMA_PHC(control);
+ p_dma_ch->ce = GET_DMA_CE_ENABLE(control);
+ p_dma_ch->int_enable = GET_DMA_CIE_ENABLE(control);
+ p_dma_ch->shift = GET_DMA_PW(control);
+
+#ifdef CONFIG_PPC4xx_EDMA
+ p_dma_ch->pf = GET_DMA_PREFETCH(control);
+#else
+ p_dma_ch->ch_enable = GET_DMA_CH(control);
+ p_dma_ch->ece_enable = GET_DMA_ECE(control);
+ p_dma_ch->tcd_disable = GET_DMA_TCD(control);
+#endif
+ return DMA_STATUS_GOOD;
+}
+
+/*
+ * Sets the priority for the DMA channel dmanr.
+ * Since this is setup by the hardware init function, this function
+ * can be used to dynamically change the priority of a channel.
+ *
+ * Acceptable priorities:
+ *
+ * PRIORITY_LOW
+ * PRIORITY_MID_LOW
+ * PRIORITY_MID_HIGH
+ * PRIORITY_HIGH
+ *
+ */
+int
+ppc4xx_set_channel_priority(unsigned int dmanr, unsigned int priority)
+{
+ unsigned int control;
+
+ if ((priority != PRIORITY_LOW) &&
+ (priority != PRIORITY_MID_LOW) &&
+ (priority != PRIORITY_MID_HIGH) && (priority != PRIORITY_HIGH)) {
+ printk("ppc4xx_set_channel_priority: bad priority: 0x%x\n", priority);
+ }
+
+ switch (dmanr) {
+ case 0:
+ control = mfdcr(DCRN_DMACR0);
+ control |= SET_DMA_PRIORITY(priority);
+ mtdcr(DCRN_DMACR0, control);
+ break;
+ case 1:
+ control = mfdcr(DCRN_DMACR1);
+ control |= SET_DMA_PRIORITY(priority);
+ mtdcr(DCRN_DMACR1, control);
+ break;
+ case 2:
+ control = mfdcr(DCRN_DMACR2);
+ control |= SET_DMA_PRIORITY(priority);
+ mtdcr(DCRN_DMACR2, control);
+ break;
+ case 3:
+ control = mfdcr(DCRN_DMACR3);
+ control |= SET_DMA_PRIORITY(priority);
+ mtdcr(DCRN_DMACR3, control);
+ break;
+ default:
+ printk("ppc4xx_set_channel_priority: bad channel: %d\n", dmanr);
+ return DMA_STATUS_BAD_CHANNEL;
+ }
+ return DMA_STATUS_GOOD;
+}
+
+/*
+ * Returns the width of the peripheral attached to this channel. This assumes
+ * that someone who knows the hardware configuration, boot code or some other
+ * init code, already set the width.
+ *
+ * The return value is one of:
+ * PW_8
+ * PW_16
+ * PW_32
+ * PW_64
+ *
+ * The function returns 0 on error.
+ */
+unsigned int
+ppc4xx_get_peripheral_width(unsigned int dmanr)
+{
+ unsigned int control;
+
+ switch (dmanr) {
+ case 0:
+ control = mfdcr(DCRN_DMACR0);
+ break;
+ case 1:
+ control = mfdcr(DCRN_DMACR1);
+ break;
+ case 2:
+ control = mfdcr(DCRN_DMACR2);
+ break;
+ case 3:
+ control = mfdcr(DCRN_DMACR3);
+ break;
+ default:
+ printk("ppc4xx_get_peripheral_width: bad channel: %d\n", dmanr);
+ return 0;
+ }
+ return (GET_DMA_PW(control));
+}
+
+
+EXPORT_SYMBOL(ppc4xx_init_dma_channel);
+EXPORT_SYMBOL(ppc4xx_get_channel_config);
+EXPORT_SYMBOL(ppc4xx_set_channel_priority);
+EXPORT_SYMBOL(ppc4xx_get_peripheral_width);
+EXPORT_SYMBOL(dma_channels);
+EXPORT_SYMBOL(ppc4xx_set_src_addr);
+EXPORT_SYMBOL(ppc4xx_set_dst_addr);
+EXPORT_SYMBOL(ppc4xx_set_dma_addr);
+EXPORT_SYMBOL(ppc4xx_set_dma_addr2);
+EXPORT_SYMBOL(ppc4xx_enable_dma);
+EXPORT_SYMBOL(ppc4xx_disable_dma);
+EXPORT_SYMBOL(ppc4xx_set_dma_mode);
+EXPORT_SYMBOL(ppc4xx_set_dma_count);
+EXPORT_SYMBOL(ppc4xx_get_dma_residue);
+EXPORT_SYMBOL(ppc4xx_enable_dma_interrupt);
+EXPORT_SYMBOL(ppc4xx_disable_dma_interrupt);
+EXPORT_SYMBOL(ppc4xx_get_dma_status);
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/ppc4xx_sgdma.c linuxppc-2.4/arch/ppc/kernel/ppc4xx_sgdma.c
--- linux-2.4.22/arch/ppc/kernel/ppc4xx_sgdma.c 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/ppc4xx_sgdma.c 2003-05-26 09:40:53.000000000 +1000
@@ -0,0 +1,559 @@
+/*
+ * arch/ppc/kernel/ppc4xx_sgdma.c
+ *
+ * IBM PPC4xx DMA engine scatter/gather library
+ *
+ * Copyright 2002-2003 MontaVista Software Inc.
+ *
+ * Cleaned by Matt Porter
+ *
+ * Original code by Armin Kuster
+ * and Pete Popov
+ *
+ * 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.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+static __inline__ void
+ppc4xx_set_sg_addr(int dmanr, phys_addr_t sg_addr)
+{
+ switch (dmanr) {
+ case 0:
+#ifdef PPC4xx_DMA_64BIT
+ mtdcr(DCRN_ASGH0, (u32)(sg_addr >> 32));
+#endif
+ mtdcr(DCRN_ASG0, (u32)sg_addr);
+ break;
+ case 1:
+#ifdef PPC4xx_DMA_64BIT
+ mtdcr(DCRN_ASGH1, (u32)(sg_addr >> 32));
+#endif
+ mtdcr(DCRN_ASG1, (u32)sg_addr);
+ break;
+ case 2:
+#ifdef PPC4xx_DMA_64BIT
+ mtdcr(DCRN_ASGH2, (u32)(sg_addr >> 32));
+#endif
+ mtdcr(DCRN_ASG2, sg_addr);
+ break;
+ case 3:
+#ifdef PPC4xx_DMA_64BIT
+ mtdcr(DCRN_ASGH3, (u32)(sg_addr >> 32));
+#endif
+ mtdcr(DCRN_ASG3, (u32)sg_addr);
+ break;
+ }
+}
+
+
+/*
+ * Add a new sgl descriptor to the end of a scatter/gather list
+ * which was created by alloc_dma_handle().
+ *
+ * For a memory to memory transfer, both dma addresses must be
+ * valid. For a peripheral to memory transfer, one of the addresses
+ * must be set to NULL, depending on the direction of the transfer:
+ * memory to peripheral: set dst_addr to NULL,
+ * peripheral to memory: set src_addr to NULL.
+ */
+static __inline__ int
+ppc4xx_add_dma_sgl(sgl_handle_t handle, phys_addr_t src_addr, phys_addr_t dst_addr,
+ unsigned int count)
+{
+ sgl_list_info_t *psgl = (sgl_list_info_t *) handle;
+ ppc_dma_ch_t *p_dma_ch;
+
+ if (!handle) {
+ printk("ppc4xx_add_dma_sgl: null handle\n");
+ return DMA_STATUS_BAD_HANDLE;
+ }
+
+ if (psgl->dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
+ printk("ppc4xx_add_dma_sgl: bad channel: %d\n", psgl->dmanr);
+ return DMA_STATUS_BAD_CHANNEL;
+ }
+
+ p_dma_ch = &dma_channels[psgl->dmanr];
+
+#ifdef DEBUG_4xxDMA
+ {
+ int error = 0;
+ unsigned int aligned =
+ (unsigned) src_addr | (unsigned) dst_addr | count;
+ switch (p_dma_ch->pwidth) {
+ case PW_8:
+ break;
+ case PW_16:
+ if (aligned & 0x1)
+ error = 1;
+ break;
+ case PW_32:
+ if (aligned & 0x3)
+ error = 1;
+ break;
+ case PW_64:
+ if (aligned & 0x7)
+ error = 1;
+ break;
+ default:
+ printk("ppc4xx_add_dma_sgl: invalid bus width: 0x%x\n",
+ p_dma_ch->pwidth);
+ return DMA_STATUS_GENERAL_ERROR;
+ }
+ if (error)
+ printk
+ ("Alignment warning: ppc4xx_add_dma_sgl src 0x%x dst 0x%x count 0x%x bus width var %d\n",
+ src_addr, dst_addr, count, p_dma_ch->pwidth);
+
+ }
+#endif
+
+ if ((unsigned) (psgl->ptail + 1) >= ((unsigned) psgl + SGL_LIST_SIZE)) {
+ printk("sgl handle out of memory \n");
+ return DMA_STATUS_OUT_OF_MEMORY;
+ }
+
+ if (!psgl->ptail) {
+ psgl->phead = (ppc_sgl_t *)
+ ((unsigned) psgl + sizeof (sgl_list_info_t));
+ psgl->ptail = psgl->phead;
+ } else {
+ psgl->ptail->next = virt_to_bus(psgl->ptail + 1);
+ psgl->ptail++;
+ }
+
+ psgl->ptail->control = psgl->control;
+ psgl->ptail->src_addr = src_addr;
+ psgl->ptail->dst_addr = dst_addr;
+ psgl->ptail->control_count = (count >> p_dma_ch->shift) |
+ psgl->sgl_control;
+ psgl->ptail->next = (uint32_t) NULL;
+
+ return DMA_STATUS_GOOD;
+}
+
+/*
+ * Enable (start) the DMA described by the sgl handle.
+ */
+static __inline__ void
+ppc4xx_enable_dma_sgl(sgl_handle_t handle)
+{
+ sgl_list_info_t *psgl = (sgl_list_info_t *) handle;
+ ppc_dma_ch_t *p_dma_ch;
+ uint32_t sg_command;
+
+ if (!handle) {
+ printk("ppc4xx_enable_dma_sgl: null handle\n");
+ return;
+ } else if (psgl->dmanr > (MAX_PPC4xx_DMA_CHANNELS - 1)) {
+ printk("ppc4xx_enable_dma_sgl: bad channel in handle %d\n",
+ psgl->dmanr);
+ return;
+ } else if (!psgl->phead) {
+ printk("ppc4xx_enable_dma_sgl: sg list empty\n");
+ return;
+ }
+
+ p_dma_ch = &dma_channels[psgl->dmanr];
+ psgl->ptail->control_count &= ~SG_LINK; /* make this the last dscrptr */
+ sg_command = mfdcr(DCRN_ASGC);
+
+ ppc4xx_set_sg_addr(psgl->dmanr, virt_to_bus(psgl->phead));
+
+ switch (psgl->dmanr) {
+ case 0:
+ sg_command |= SSG0_ENABLE;
+ break;
+ case 1:
+ sg_command |= SSG1_ENABLE;
+ break;
+ case 2:
+ sg_command |= SSG2_ENABLE;
+ break;
+ case 3:
+ sg_command |= SSG3_ENABLE;
+ break;
+ default:
+ printk("ppc4xx_enable_dma_sgl: bad channel: %d\n", psgl->dmanr);
+ }
+
+#if 0 /* debug */
+ printk("\n\nppc4xx_enable_dma_sgl at dma_addr 0x%x\n",
+ virt_to_bus(psgl->phead));
+ {
+ ppc_sgl_t *pnext, *sgl_addr;
+
+ pnext = psgl->phead;
+ while (pnext) {
+ printk("dma descriptor at 0x%x, dma addr 0x%x\n",
+ (unsigned) pnext, (unsigned) virt_to_bus(pnext));
+ printk
+ ("control 0x%x src 0x%x dst 0x%x c_count 0x%x, next 0x%x\n",
+ (unsigned) pnext->control,
+ (unsigned) pnext->src_addr,
+ (unsigned) pnext->dst_addr,
+ (unsigned) pnext->control_count,
+ (unsigned) pnext->next);
+
+ (unsigned) pnext = bus_to_virt(pnext->next);
+ }
+ printk("sg_command 0x%x\n", sg_command);
+ }
+#endif
+ mtdcr(DCRN_ASGC, sg_command); /* start transfer */
+}
+
+/*
+ * Halt an active scatter/gather DMA operation.
+ */
+static __inline__ void
+ppc4xx_disable_dma_sgl(sgl_handle_t handle)
+{
+ sgl_list_info_t *psgl = (sgl_list_info_t *) handle;
+ uint32_t sg_command;
+
+ if (!handle) {
+ printk("ppc4xx_enable_dma_sgl: null handle\n");
+ return;
+ } else if (psgl->dmanr > (MAX_PPC4xx_DMA_CHANNELS - 1)) {
+ printk("ppc4xx_enable_dma_sgl: bad channel in handle %d\n",
+ psgl->dmanr);
+ return;
+ }
+
+ sg_command = mfdcr(DCRN_ASGC);
+ switch (psgl->dmanr) {
+ case 0:
+ sg_command &= ~SSG0_ENABLE;
+ break;
+ case 1:
+ sg_command &= ~SSG1_ENABLE;
+ break;
+ case 2:
+ sg_command &= ~SSG2_ENABLE;
+ break;
+ case 3:
+ sg_command &= ~SSG3_ENABLE;
+ break;
+ default:
+ printk("ppc4xx_enable_dma_sgl: bad channel: %d\n", psgl->dmanr);
+ }
+
+ mtdcr(DCRN_ASGC, sg_command); /* stop transfer */
+}
+
+/*
+ * Returns number of bytes left to be transferred from the entire sgl list.
+ * *src_addr and *dst_addr get set to the source/destination address of
+ * the sgl descriptor where the DMA stopped.
+ *
+ * An sgl transfer must NOT be active when this function is called.
+ */
+static __inline__ int
+ppc4xx_get_dma_sgl_residue(sgl_handle_t handle, phys_addr_t * src_addr,
+ phys_addr_t * dst_addr)
+{
+ sgl_list_info_t *psgl = (sgl_list_info_t *) handle;
+ ppc_dma_ch_t *p_dma_ch;
+ ppc_sgl_t *pnext, *sgl_addr;
+ uint32_t count_left;
+
+ if (!handle) {
+ printk("ppc4xx_get_dma_sgl_residue: null handle\n");
+ return DMA_STATUS_BAD_HANDLE;
+ } else if (psgl->dmanr > (MAX_PPC4xx_DMA_CHANNELS - 1)) {
+ printk("ppc4xx_get_dma_sgl_residue: bad channel in handle %d\n",
+ psgl->dmanr);
+ return DMA_STATUS_BAD_CHANNEL;
+ }
+
+ switch (psgl->dmanr) {
+ case 0:
+ sgl_addr = (ppc_sgl_t *) bus_to_virt(mfdcr(DCRN_ASG0));
+ count_left = mfdcr(DCRN_DMACT0);
+ break;
+ case 1:
+ sgl_addr = (ppc_sgl_t *) bus_to_virt(mfdcr(DCRN_ASG1));
+ count_left = mfdcr(DCRN_DMACT1);
+ break;
+ case 2:
+ sgl_addr = (ppc_sgl_t *) bus_to_virt(mfdcr(DCRN_ASG2));
+ count_left = mfdcr(DCRN_DMACT2);
+ break;
+ case 3:
+ sgl_addr = (ppc_sgl_t *) bus_to_virt(mfdcr(DCRN_ASG3));
+ count_left = mfdcr(DCRN_DMACT3);
+ break;
+ default:
+ printk("ppc4xx_get_dma_sgl_residue: bad channel %d\n", psgl->dmanr);
+ goto error;
+ }
+
+ if (!sgl_addr) {
+ printk("ppc4xx_get_dma_sgl_residue: sgl addr register is null\n");
+ goto error;
+ }
+
+ pnext = psgl->phead;
+ while (pnext &&
+ ((unsigned) pnext < ((unsigned) psgl + SGL_LIST_SIZE) &&
+ (pnext != sgl_addr))
+ ) {
+ pnext++;
+ }
+
+ if (pnext == sgl_addr) { /* found the sgl descriptor */
+
+ *src_addr = pnext->src_addr;
+ *dst_addr = pnext->dst_addr;
+
+ /*
+ * Now search the remaining descriptors and add their count.
+ * We already have the remaining count from this descriptor in
+ * count_left.
+ */
+ pnext++;
+
+ while ((pnext != psgl->ptail) &&
+ ((unsigned) pnext < ((unsigned) psgl + SGL_LIST_SIZE))
+ ) {
+ count_left += pnext->control_count & SG_COUNT_MASK;
+ }
+
+ if (pnext != psgl->ptail) { /* should never happen */
+ printk
+ ("ppc4xx_get_dma_sgl_residue error (1) psgl->ptail 0x%x handle 0x%x\n",
+ (unsigned int) psgl->ptail, (unsigned int) handle);
+ goto error;
+ }
+
+ /* success */
+ p_dma_ch = &dma_channels[psgl->dmanr];
+ return (count_left << p_dma_ch->shift); /* count in bytes */
+
+ } else {
+ /* this shouldn't happen */
+ printk
+ ("get_dma_sgl_residue, unable to match current address 0x%x, handle 0x%x\n",
+ (unsigned int) sgl_addr, (unsigned int) handle);
+
+ }
+
+ error:
+ *src_addr = (phys_addr_t) NULL;
+ *dst_addr = (phys_addr_t) NULL;
+ return 0;
+}
+
+/*
+ * Returns the address(es) of the buffer(s) contained in the head element of
+ * the scatter/gather list. The element is removed from the scatter/gather
+ * list and the next element becomes the head.
+ *
+ * This function should only be called when the DMA is not active.
+ */
+static __inline__ int
+ppc4xx_delete_dma_sgl_element(sgl_handle_t handle, phys_addr_t * src_dma_addr,
+ phys_addr_t * dst_dma_addr)
+{
+ sgl_list_info_t *psgl = (sgl_list_info_t *) handle;
+
+ if (!handle) {
+ printk("ppc4xx_delete_sgl_element: null handle\n");
+ return DMA_STATUS_BAD_HANDLE;
+ } else if (psgl->dmanr > (MAX_PPC4xx_DMA_CHANNELS - 1)) {
+ printk("ppc4xx_delete_sgl_element: bad channel in handle %d\n",
+ psgl->dmanr);
+ return DMA_STATUS_BAD_CHANNEL;
+ }
+
+ if (!psgl->phead) {
+ printk("ppc4xx_delete_sgl_element: sgl list empty\n");
+ *src_dma_addr = (phys_addr_t) NULL;
+ *dst_dma_addr = (phys_addr_t) NULL;
+ return DMA_STATUS_SGL_LIST_EMPTY;
+ }
+
+ *src_dma_addr = (phys_addr_t) psgl->phead->src_addr;
+ *dst_dma_addr = (phys_addr_t) psgl->phead->dst_addr;
+
+ if (psgl->phead == psgl->ptail) {
+ /* last descriptor on the list */
+ psgl->phead = NULL;
+ psgl->ptail = NULL;
+ } else {
+ psgl->phead++;
+ }
+
+ return DMA_STATUS_GOOD;
+}
+
+
+/*
+ * Create a scatter/gather list handle. This is simply a structure which
+ * describes a scatter/gather list.
+ *
+ * A handle is returned in "handle" which the driver should save in order to
+ * be able to access this list later. A chunk of memory will be allocated
+ * to be used by the API for internal management purposes, including managing
+ * the sg list and allocating memory for the sgl descriptors. One page should
+ * be more than enough for that purpose. Perhaps it's a bit wasteful to use
+ * a whole page for a single sg list, but most likely there will be only one
+ * sg list per channel.
+ *
+ * Interrupt notes:
+ * Each sgl descriptor has a copy of the DMA control word which the DMA engine
+ * loads in the control register. The control word has a "global" interrupt
+ * enable bit for that channel. Interrupts are further qualified by a few bits
+ * in the sgl descriptor count register. In order to setup an sgl, we have to
+ * know ahead of time whether or not interrupts will be enabled at the completion
+ * of the transfers. Thus, enable_dma_interrupt()/disable_dma_interrupt() MUST
+ * be called before calling alloc_dma_handle(). If the interrupt mode will never
+ * change after powerup, then enable_dma_interrupt()/disable_dma_interrupt()
+ * do not have to be called -- interrupts will be enabled or disabled based
+ * on how the channel was configured after powerup by the hw_init_dma_channel()
+ * function. Each sgl descriptor will be setup to interrupt if an error occurs;
+ * however, only the last descriptor will be setup to interrupt. Thus, an
+ * interrupt will occur (if interrupts are enabled) only after the complete
+ * sgl transfer is done.
+ */
+int
+ppc4xx_alloc_dma_handle(sgl_handle_t * phandle, unsigned int mode, unsigned int dmanr)
+{
+ sgl_list_info_t *psgl;
+ dma_addr_t dma_addr;
+ ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
+ uint32_t sg_command;
+ void *ret;
+
+ if (dmanr >= MAX_PPC4xx_DMA_CHANNELS) {
+ printk("ppc4xx_alloc_dma_handle: invalid channel 0x%x\n", dmanr);
+ return DMA_STATUS_BAD_CHANNEL;
+ }
+
+ if (!phandle) {
+ printk("ppc4xx_alloc_dma_handle: null handle pointer\n");
+ return DMA_STATUS_NULL_POINTER;
+ }
+
+ /* Get a page of memory, which is zeroed out by consistent_alloc() */
+ ret = consistent_alloc(GFP_KERNEL, DMA_PPC4xx_SIZE, &dma_addr);
+ if (ret != NULL) {
+ memset(ret, 0, DMA_PPC4xx_SIZE);
+ psgl = (sgl_list_info_t *) ret;
+ }
+
+ if (psgl == NULL) {
+ *phandle = (sgl_handle_t) NULL;
+ return DMA_STATUS_OUT_OF_MEMORY;
+ }
+
+ psgl->dma_addr = dma_addr;
+ psgl->dmanr = dmanr;
+
+ /*
+ * Modify and save the control word. These words will be
+ * written to each sgl descriptor. The DMA engine then
+ * loads this control word into the control register
+ * every time it reads a new descriptor.
+ */
+ psgl->control = p_dma_ch->control;
+ /* Clear all mode bits */
+ psgl->control &= ~(DMA_TM_MASK | DMA_TD);
+ /* Save control word and mode */
+ psgl->control |= (mode | DMA_CE_ENABLE);
+
+ /* In MM mode, we must set ETD/TCE */
+ if (mode == DMA_MODE_MM)
+ psgl->control |= DMA_ETD_OUTPUT | DMA_TCE_ENABLE;
+
+ if (p_dma_ch->int_enable) {
+ /* Enable channel interrupt */
+ psgl->control |= DMA_CIE_ENABLE;
+ } else {
+ psgl->control &= ~DMA_CIE_ENABLE;
+ }
+
+ sg_command = mfdcr(DCRN_ASGC);
+ switch (dmanr) {
+ case 0:
+ sg_command |= SSG0_MASK_ENABLE;
+ break;
+ case 1:
+ sg_command |= SSG1_MASK_ENABLE;
+ break;
+ case 2:
+ sg_command |= SSG2_MASK_ENABLE;
+ break;
+ case 3:
+ sg_command |= SSG3_MASK_ENABLE;
+ break;
+ default:
+ printk("ppc4xx_alloc_dma_handle: bad channel: %d\n", dmanr);
+ ppc4xx_free_dma_handle((sgl_handle_t) psgl);
+ *phandle = (sgl_handle_t) NULL;
+ return DMA_STATUS_BAD_CHANNEL;
+ }
+
+ /* Enable SGL control access */
+ mtdcr(DCRN_ASGC, sg_command);
+ psgl->sgl_control = SG_ERI_ENABLE | SG_LINK;
+
+ if (p_dma_ch->int_enable) {
+ if (p_dma_ch->tce_enable)
+ psgl->sgl_control |= SG_TCI_ENABLE;
+ else
+ psgl->sgl_control |= SG_ETI_ENABLE;
+ }
+
+ *phandle = (sgl_handle_t) psgl;
+ return DMA_STATUS_GOOD;
+}
+
+/*
+ * Destroy a scatter/gather list handle that was created by alloc_dma_handle().
+ * The list must be empty (contain no elements).
+ */
+void
+ppc4xx_free_dma_handle(sgl_handle_t handle)
+{
+ sgl_list_info_t *psgl = (sgl_list_info_t *) handle;
+
+ if (!handle) {
+ printk("ppc4xx_free_dma_handle: got NULL\n");
+ return;
+ } else if (psgl->phead) {
+ printk("ppc4xx_free_dma_handle: list not empty\n");
+ return;
+ } else if (!psgl->dma_addr) { /* should never happen */
+ printk("ppc4xx_free_dma_handle: no dma address\n");
+ return;
+ }
+
+ consistent_free((void *) psgl);
+}
+
+EXPORT_SYMBOL(ppc4xx_alloc_dma_handle);
+EXPORT_SYMBOL(ppc4xx_free_dma_handle);
+EXPORT_SYMBOL(ppc4xx_add_dma_sgl);
+EXPORT_SYMBOL(ppc4xx_delete_dma_sgl_element);
+EXPORT_SYMBOL(ppc4xx_enable_dma_sgl);
+EXPORT_SYMBOL(ppc4xx_disable_dma_sgl);
+EXPORT_SYMBOL(ppc4xx_get_dma_sgl_residue);
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/ppc4xx_stbdma.c linuxppc-2.4/arch/ppc/kernel/ppc4xx_stbdma.c
--- linux-2.4.22/arch/ppc/kernel/ppc4xx_stbdma.c 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/ppc4xx_stbdma.c 2003-05-26 09:40:53.000000000 +1000
@@ -0,0 +1,134 @@
+/*
+ * arch/ppc/kernel/ppc4xx_stbdma.c
+ *
+ * BRIEF MODULE DESCRIPTION
+ * IBM PPC4xx STBxxxx DMA Controller Functions
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * Armin Kuster
+ *
+ * Based on ppc4xx_dma.c by
+ * ppopov@mvista.com or source@mvista.
+ *
+ * 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.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+int
+ppc4xx_clr_dma_status(unsigned int dmanr)
+{
+ unsigned int control;
+ ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
+
+ p_dma_ch->int_enable = 1;
+
+ switch (dmanr) {
+ case 0:
+ control = DMA_CS0 | DMA_CH0_ERR | DMA_CT0;
+ break;
+ case 1:
+ control = DMA_CS1 | DMA_CH1_ERR | DMA_CT1;
+ break;
+ case 2:
+ control = DMA_CS2 | DMA_CH2_ERR | DMA_CT2;
+ break;
+ case 3:
+ control = DMA_CS3 | DMA_CH3_ERR | DMA_CT3;
+ break;
+ default:
+#ifdef DEBUG_4xxDMA
+ printk("ppc4xx_clr_dma_status: bad channel: %d\n", dmanr);
+#endif
+ return DMA_STATUS_BAD_CHANNEL;
+ }
+ mtdcr(DCRN_DMASR, control);
+ return DMA_STATUS_GOOD;
+}
+
+/*
+ * Maps a given port to a one of the dma
+ * channels
+ */
+int
+ppc4xx_map_dma_port(unsigned int dmanr, unsigned int ocp_dma,short dma_chan)
+{
+ unsigned int map;
+ int connect_port_to_chan, select;
+
+ ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
+
+ connect_port_to_chan = ((ocp_dma & 0x7)*4);
+
+ select = ocp_dma >> 3;
+ switch (select) {
+ case 0:
+ map = mfdcr(DCRN_DMAS1);
+ map |= (connect_port_to_chan << dma_chan); /* */
+ mtdcr(DCRN_DMAS1, map);
+ break;
+ case 1:
+ map = mfdcr(DCRN_DMAS2);
+ map |= (connect_port_to_chan << dma_chan);
+ mtdcr(DCRN_DMAS2, map);
+ break;
+ default:
+#ifdef DEBUG_4xxDMA
+ printk("map_dma_port: bad channel: %d\n", dmanr);
+#endif
+ return DMA_STATUS_BAD_CHANNEL;
+ }
+ return DMA_STATUS_GOOD;
+}
+
+int
+ppc4xx_disable_dma_port(unsigned int dmanr, unsigned int ocp_dma,short dma_chan)
+{
+ unsigned int map;
+ int connect_port_to_chan, select;
+
+ ppc_dma_ch_t *p_dma_ch = &dma_channels[dmanr];
+
+ connect_port_to_chan = ((ocp_dma & 0x7)*4);
+
+ select = ocp_dma >> 3;
+ switch (select) {
+ case 0:
+ map = mfdcr(DCRN_DMAS1);
+ map &= ~(connect_port_to_chan << dma_chan); /* */
+ mtdcr(DCRN_DMAS1, map);
+ break;
+ case 1:
+ map = mfdcr(DCRN_DMAS2);
+ map &= ~(connect_port_to_chan << dma_chan);
+ mtdcr(DCRN_DMAS2, map);
+ break;
+ default:
+#ifdef DEBUG_4xxDMA
+ printk("disable_dma_port: bad channel: %d\n", dmanr);
+#endif
+ return DMA_STATUS_BAD_CHANNEL;
+ }
+ return DMA_STATUS_GOOD;
+}
+
+EXPORT_SYMBOL(ppc4xx_disable_dma_port);
+EXPORT_SYMBOL(ppc4xx_map_dma_port);
+EXPORT_SYMBOL(ppc4xx_clr_dma_status);
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/ppc_ksyms.c linuxppc-2.4/arch/ppc/kernel/ppc_ksyms.c
--- linux-2.4.22/arch/ppc/kernel/ppc_ksyms.c 2003-08-01 00:48:03.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/ppc_ksyms.c 2003-08-05 09:59:45.000000000 +1000
@@ -159,11 +159,14 @@
EXPORT_SYMBOL(_outsw_ns);
EXPORT_SYMBOL(_insl_ns);
EXPORT_SYMBOL(_outsl_ns);
+EXPORT_SYMBOL(iopa);
+EXPORT_SYMBOL(mm_ptov);
EXPORT_SYMBOL(ioremap);
+#ifdef CONFIG_440
+EXPORT_SYMBOL(ioremap64);
+#endif
EXPORT_SYMBOL(__ioremap);
EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(iopa);
-EXPORT_SYMBOL(mm_ptov);
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) \
|| defined(CONFIG_USB_STORAGE) || defined(CONFIG_USB_STORAGE_MODULE)
@@ -178,6 +181,14 @@
EXPORT_SYMBOL(pci_free_consistent);
#endif /* CONFIG_PCI */
+#ifdef CONFIG_NOT_COHERENT_CACHE
+EXPORT_SYMBOL(consistent_alloc);
+EXPORT_SYMBOL(consistent_free);
+EXPORT_SYMBOL(consistent_sync);
+EXPORT_SYMBOL(consistent_sync_page);
+EXPORT_SYMBOL(flush_dcache_all);
+#endif
+
EXPORT_SYMBOL(start_thread);
EXPORT_SYMBOL(kernel_thread);
@@ -338,8 +349,10 @@
EXPORT_SYMBOL(debugger_fault_handler);
#endif
-#ifdef CONFIG_8xx
+#if defined(CONFIG_8xx) || defined(CONFIG_4xx)
EXPORT_SYMBOL(__res);
+#endif
+#ifdef CONFIG_8xx
EXPORT_SYMBOL(cpm_install_handler);
EXPORT_SYMBOL(cpm_free_handler);
EXPORT_SYMBOL(m8xx_cpm_hostalloc);
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/setup.c linuxppc-2.4/arch/ppc/kernel/setup.c
--- linux-2.4.22/arch/ppc/kernel/setup.c 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/setup.c 2003-08-26 11:57:12.000000000 +1000
@@ -566,12 +566,10 @@
#if defined(CONFIG_KGDB)
kgdb_map_scc();
set_debug_traps();
- if (strstr(cmd_line, "nokgdb"))
- printk("kgdb default breakpoint deactivated on command line\n");
- else {
+ if (strstr(cmd_line, "gdb")) {
if (ppc_md.progress)
ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000);
- printk("kgdb default breakpoint activated\n");
+ printk("kgdb breakpoint activated\n");
breakpoint();
}
#endif
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/syscalls.c linuxppc-2.4/arch/ppc/kernel/syscalls.c
--- linux-2.4.22/arch/ppc/kernel/syscalls.c 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/syscalls.c 2003-07-25 02:06:49.000000000 +1000
@@ -167,6 +167,16 @@
return error;
}
+#ifndef CONFIG_40x
+#define allow_mmap_address(addr) 1
+#else
+/* Blech. On 40x allowing mmap() (MAP_FIXED) at the first few pages
+ * of (any process's) virtual memory is a security hole due to chip
+ * erratum #67 (and possibly also due to the (documented) bizarre
+ * prefetch behaviour around 'sc' see S3.8.2.1 of the user manual). */
+#define allow_mmap_address(addr) ((((addr) & PAGE_MASK) >= 0x2100) || suser())
+#endif
+
static inline unsigned long
do_mmap2(unsigned long addr, size_t len,
unsigned long prot, unsigned long flags,
@@ -181,6 +191,10 @@
goto out;
}
+ ret = -EINVAL;
+ if ((! allow_mmap_address(addr)) && (flags & MAP_FIXED))
+ goto out;
+
down_write(¤t->mm->mmap_sem);
ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
up_write(¤t->mm->mmap_sem);
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/traps.c linuxppc-2.4/arch/ppc/kernel/traps.c
--- linux-2.4.22/arch/ppc/kernel/traps.c 2003-06-25 20:56:52.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/traps.c 2003-08-26 11:57:12.000000000 +1000
@@ -457,7 +457,7 @@
}
#endif /* CONFIG_8xx */
-#if defined(CONFIG_4xx)
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
void DebugException(struct pt_regs *regs)
{
@@ -484,7 +484,7 @@
_exception(SIGTRAP, regs, 0, 0);
}
}
-#endif /* CONFIG_4xx */
+#endif /* CONFIG_4xx || CONFIG_BOOKE */
#if !defined(CONFIG_TAU_INT)
void
diff -urN -X bkexcl linux-2.4.22/arch/ppc/kernel/xilinx_pic.c linuxppc-2.4/arch/ppc/kernel/xilinx_pic.c
--- linux-2.4.22/arch/ppc/kernel/xilinx_pic.c 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/kernel/xilinx_pic.c 2003-07-05 10:55:27.000000000 +1000
@@ -0,0 +1,151 @@
+/*
+ * xilinx_pic.c
+ *
+ * Interrupt controller driver for Xilinx Virtex-II Pro.
+ *
+ * Author: MontaVista Software, Inc.
+ * source@mvista.com
+ *
+ * 2002 (c) MontaVista, Software, Inc. This file is licensed under the terms
+ * of the GNU General Public License version 2. This program is licensed
+ * "as is" without any warranty of any kind, whether express or implied.
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#define ACKNOWLEDGE_AFTER /* SAATODO: Figure out the "right" answer */
+
+/* No one else should require these constants, so define them locally here. */
+#define ISR 0 /* Interrupt Status Register */
+#define IPR 1 /* Interrupt Pending Register */
+#define IER 2 /* Interrupt Enable Register */
+#define IAR 3 /* Interrupt Acknowledge Register */
+#define SIE 4 /* Set Interrupt Enable bits */
+#define CIE 5 /* Clear Interrupt Enable bits */
+#define IVR 6 /* Interrupt Vector Register */
+#define MER 7 /* Master Enable Register */
+
+#if XPAR_XINTC_USE_DCR == 0
+static volatile u32 *intc;
+#define intc_out_be32(addr, mask) out_be32((addr), (mask))
+#define intc_in_be32(addr) in_be32((addr))
+#else
+#define intc XPAR_INTC_0_BASEADDR
+#define intc_out_be32(addr, mask) mtdcr((addr), (mask))
+#define intc_in_be32(addr) mfdcr((addr))
+#endif
+
+/* Global Variables */
+struct hw_interrupt_type *ppc4xx_pic;
+
+static void
+xilinx_intc_enable(unsigned int irq)
+{
+ unsigned long mask = (0x80000000 >> (irq & 31));
+ // printk(KERN_INFO "enable: %d\n", irq);
+ intc_out_be32(intc + SIE, mask);
+}
+
+static void
+xilinx_intc_disable(unsigned int irq)
+{
+ unsigned long mask = (0x80000000 >> (irq & 31));
+ // printk(KERN_INFO "disable: %d\n", irq);
+ intc_out_be32(intc + CIE, mask);
+}
+
+static void
+xilinx_intc_disable_and_ack(unsigned int irq)
+{
+ unsigned long mask = (0x80000000 >> (irq & 31));
+ // printk(KERN_INFO "disable_and_ack: %d\n", irq);
+ intc_out_be32(intc + CIE, mask);
+#if !defined(ACKNOWLEDGE_AFTER)
+ intc_out_be32(intc + IAR, mask); /* Don't ack until xilinx_intc_end. */
+#endif
+}
+
+static void
+xilinx_intc_end(unsigned int irq)
+{
+ unsigned long mask = (0x80000000 >> (irq & 31));
+
+ // printk(KERN_INFO "end: %d\n", irq);
+ if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+ intc_out_be32(intc + SIE, mask);
+#if defined(ACKNOWLEDGE_AFTER)
+ intc_out_be32(intc + IAR, mask);
+#endif
+ }
+}
+
+static struct hw_interrupt_type xilinx_intc = {
+ "Xilinx Interrupt Controller",
+ NULL,
+ NULL,
+ xilinx_intc_enable,
+ xilinx_intc_disable,
+ xilinx_intc_disable_and_ack,
+ xilinx_intc_end,
+ 0
+};
+
+int
+xilinx_pic_get_irq(struct pt_regs *regs)
+{
+ int irq;
+
+ /*
+ * NOTE: This function is the one that needs to be improved in
+ * order to handle multiple interrupt controllers. It currently
+ * is hardcoded to check for interrupts only on the first INTC.
+ */
+
+ /*
+ * The Interrupt Vector Register returns the vector
+ * corresponding to the highest priority (most significant or
+ * lowest numbered bit) interrupt pending (enabled and active).
+ * To convert this to an interrupt number, we just need to shift
+ * it two places to the right.
+ */
+ irq = intc_in_be32(intc + IVR);
+ if (irq != -1)
+ irq = 31 - irq;
+
+ // printk(KERN_INFO "get_irq: %d\n", irq);
+
+ return (irq);
+}
+
+void __init
+ppc4xx_pic_init(void)
+{
+#if XPAR_XINTC_USE_DCR == 0
+ intc = ioremap(XPAR_INTC_0_BASEADDR, 32);
+
+ printk(KERN_INFO "Xilinx INTC #0 at 0x%08lX mapped to 0x%08lX\n",
+ (unsigned long) XPAR_INTC_0_BASEADDR, (unsigned long) intc);
+#else
+ printk(KERN_INFO "Xilinx INTC #0 at 0x%08lX (DCR)\n",
+ (unsigned long) XPAR_INTC_0_BASEADDR);
+#endif
+
+ /*
+ * Disable all external interrupts until they are
+ * explicity requested.
+ */
+ intc_out_be32(intc + IER, 0);
+
+ /* Acknowledge any pending interrupts just in case. */
+ intc_out_be32(intc + IAR, ~(u32) 0);
+
+ /* Turn on the Master Enable. */
+ intc_out_be32(intc + MER, 0x3UL);
+
+ ppc4xx_pic = &xilinx_intc;
+ ppc_md.get_irq = xilinx_pic_get_irq;
+}
diff -urN -X bkexcl linux-2.4.22/arch/ppc/mm/440_mmu.c linuxppc-2.4/arch/ppc/mm/440_mmu.c
--- linux-2.4.22/arch/ppc/mm/440_mmu.c 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/mm/440_mmu.c 2003-03-14 20:46:44.000000000 +1100
@@ -0,0 +1,68 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ */
+/*
+ * This file contains the routines for initializing the MMU
+ * on the 4xx series of chips.
+ * -- paulus
+ *
+ * Derived from arch/ppc/mm/init.c:
+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
+ *
+ * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
+ * and Cort Dougan (PReP) (cort@cs.nmt.edu)
+ * Copyright (C) 1996 Paul Mackerras
+ * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *
+ * Derived from "arch/i386/mm/init.c"
+ * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* Used by the 4xx TLB replacement exception handler.
+ * Just needed it declared someplace (and initialized to zero).
+ */
+unsigned int tlb_4xx_index;
+
+/*
+ * MMU_init_hw does the chip-specific initialization of the MMU hardware.
+ */
+void __init MMU_init_hw(void)
+{
+ flush_instruction_cache();
+}
diff -urN -X bkexcl linux-2.4.22/arch/ppc/mm/Makefile linuxppc-2.4/arch/ppc/mm/Makefile
--- linux-2.4.22/arch/ppc/mm/Makefile 2003-06-25 20:56:52.000000000 +1000
+++ linuxppc-2.4/arch/ppc/mm/Makefile 2003-06-25 21:30:07.000000000 +1000
@@ -19,6 +19,7 @@
obj-$(CONFIG_PPC_STD_MMU) += hashtable.o ppc_mmu.o tlb.o
obj-$(CONFIG_40x) += 4xx_mmu.o
+obj-$(CONFIG_440) += 440_mmu.o
obj-$(CONFIG_NOT_COHERENT_CACHE) += cachemap.o
include $(TOPDIR)/Rules.make
diff -urN -X bkexcl linux-2.4.22/arch/ppc/mm/cachemap.c linuxppc-2.4/arch/ppc/mm/cachemap.c
--- linux-2.4.22/arch/ppc/mm/cachemap.c 2003-02-15 08:07:09.000000000 +1100
+++ linuxppc-2.4/arch/ppc/mm/cachemap.c 2003-03-14 20:46:44.000000000 +1100
@@ -11,6 +11,7 @@
* is the virtual address and 'dma_handle' is the physical address.
* Mostly stolen from the ARM port, with some changes for PowerPC.
* -- Dan
+ * Modified for 36-bit support. -Matt
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -48,14 +49,24 @@
#include
#include
-extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep);
+#include "mmu_decl.h"
+extern int map_page(unsigned long va, phys_addr_t pa, int flags);
+
+/* This function will allocate the requested contiguous pages and
+ * map them into the kernel's vmalloc() space. This is done so we
+ * get unique mapping for these pages, outside of the kernel's 1:1
+ * virtual:physical mapping. This is necessary so we can cover large
+ * portions of the kernel with single large page TLB entries, and
+ * still get unique uncached pages for consistent DMA.
+ */
void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
{
- int order, rsize;
- unsigned long page;
- void *ret;
- pte_t *pte;
+ int order, err, i;
+ unsigned long page, va, flags;
+ phys_addr_t pa;
+ struct vm_struct *area;
+ void *ret;
if (in_interrupt())
BUG();
@@ -77,23 +88,41 @@
*/
invalidate_dcache_range(page, page + size);
- ret = (void *)page;
- *dma_handle = virt_to_bus(ret);
+ /* Allocate some common virtual space to map the new pages.
+ */
+ area = get_vm_area(size, VM_ALLOC);
+ if (area == 0) {
+ free_pages(page, order);
+ return NULL;
+ }
+ va = VMALLOC_VMADDR(area->addr);
+ ret = (void *)va;
- /* Chase down all of the PTEs and mark them uncached.
+ /* This gives us the real physical address of the first page.
*/
- rsize = (int)size;
- while (rsize > 0) {
- if (get_pteptr(&init_mm, page, &pte)) {
- pte_val(*pte) |= _PAGE_NO_CACHE | _PAGE_GUARDED;
- flush_tlb_page(find_vma(&init_mm,page),page);
- }
- else {
- BUG();
- return NULL;
- }
- page += PAGE_SIZE;
- rsize -= PAGE_SIZE;
+ *dma_handle = pa = virt_to_bus((void *)page);
+
+ flags = _PAGE_KERNEL | _PAGE_NO_CACHE;
+
+ /*
+ * Set refcount=1 on all pages in an order>0
+ * allocation so that vfree() will actually
+ * free all pages that were allocated.
+ */
+ if (order > 0)
+ {
+ struct page *rpage = virt_to_page(page);
+ for (i = 1; i < (1 << order); i++)
+ set_page_count(rpage+i, 1);
+ }
+
+ err = 0;
+ for (i = 0; i < size && err == 0; i += PAGE_SIZE)
+ err = map_page(va+i, pa+i, flags);
+
+ if (err) {
+ vfree((void *)va);
+ return NULL;
}
return ret;
@@ -101,42 +130,12 @@
/*
* free page(s) as defined by the above mapping.
- * The caller has to tell us the size so we can free the proper number
- * of pages. We can't vmalloc() a new space for these pages and simply
- * call vfree() like some other architectures because we could end up
- * with aliased cache lines (or at least a cache line with the wrong
- * attributes). This can happen when the PowerPC speculative loads
- * across page boundaries.
*/
-void consistent_free(void *vaddr, size_t size)
+void consistent_free(void *vaddr)
{
- int order, rsize;
- unsigned long addr;
- pte_t *pte;
-
if (in_interrupt())
BUG();
-
- size = PAGE_ALIGN(size);
- order = get_order(size);
-
- /* Chase down all of the PTEs and mark them cached again.
- */
- addr = (unsigned long)vaddr;
- rsize = (int)size;
- while (rsize > 0) {
- if (get_pteptr(&init_mm, addr, &pte)) {
- pte_val(*pte) &= ~(_PAGE_NO_CACHE | _PAGE_GUARDED);
- flush_tlb_page(find_vma(&init_mm,addr),addr);
- }
- else {
- BUG();
- return;
- }
- addr += PAGE_SIZE;
- rsize -= PAGE_SIZE;
- }
- free_pages((unsigned long)vaddr, order);
+ vfree(vaddr);
}
/*
@@ -161,3 +160,17 @@
break;
}
}
+
+/*
+ * consistent_sync_page make a page are consistent. identical
+ * to consistent_sync, but takes a struct page instead of a virtual address
+ */
+
+void consistent_sync_page(struct page *page, unsigned long offset,
+size_t size, int direction)
+{
+ void *start;
+
+ start = page_address(page) + offset;
+ consistent_sync(start, size, direction);
+}
diff -urN -X bkexcl linux-2.4.22/arch/ppc/mm/fault.c linuxppc-2.4/arch/ppc/mm/fault.c
--- linux-2.4.22/arch/ppc/mm/fault.c 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/mm/fault.c 2003-07-25 02:06:49.000000000 +1000
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
#include
#include
@@ -51,6 +52,7 @@
extern void die_if_kernel(char *, struct pt_regs *, long);
void bad_page_fault(struct pt_regs *, unsigned long, int sig);
void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
+extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep);
/*
* Check whether the instruction at regs->nip is a store using
@@ -100,7 +102,7 @@
struct mm_struct *mm = current->mm;
siginfo_t info;
int code = SEGV_MAPERR;
-#if defined(CONFIG_4xx)
+#if defined(CONFIG_4xx) || defined (CONFIG_BOOKE)
int is_write = error_code & ESR_DST;
#else
int is_write = 0;
@@ -115,14 +117,14 @@
error_code &= 0x48200000;
else
is_write = error_code & 0x02000000;
-#endif /* CONFIG_4xx */
+#endif /* CONFIG_4xx || CONFIG_BOOKE */
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
if (debugger_fault_handler && regs->trap == 0x300) {
debugger_fault_handler(regs);
return;
}
-#if !defined(CONFIG_4xx)
+#ifndef CONFIG_4xx
if (error_code & 0x00400000) {
/* DABR match */
if (debugger_dabr_match(regs))
@@ -202,6 +204,36 @@
if (is_write) {
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
+#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+ /* an exec - 4xx/BookE allows for per-page execute permission */
+ } else if (regs->trap == 0x400) {
+ pte_t *ptep;
+
+#if 0
+ /* It would be nice to actually enforce the VM execute
+ permission on CPUs which can do so, but far too
+ much stuff in userspace doesn't get the permissions
+ right, so we let any page be executed for now. */
+ if (! (vma->vm_flags & VM_EXEC))
+ goto bad_area;
+#endif
+
+ /* Since 4xx supports per-page execute permission,
+ * we lazily flush dcache to icache. */
+ if (get_pteptr(mm, address, &ptep) && pte_present(*ptep)) {
+ struct page *page = pte_page(*ptep);
+
+ if (! test_bit(PG_arch_1, &page->flags)) {
+ __flush_dcache_icache(kmap(page));
+ kunmap(page);
+ set_bit(PG_arch_1, &page->flags);
+ }
+ pte_update(ptep, 0, _PAGE_HWEXEC);
+ _tlbie(address);
+ up_read(&mm->mmap_sem);
+ return;
+ }
+#endif
/* a read */
} else {
/* protection fault */
diff -urN -X bkexcl linux-2.4.22/arch/ppc/mm/init.c linuxppc-2.4/arch/ppc/mm/init.c
--- linux-2.4.22/arch/ppc/mm/init.c 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/mm/init.c 2003-07-25 02:06:49.000000000 +1000
@@ -6,6 +6,7 @@
* and Cort Dougan (PReP) (cort@cs.nmt.edu)
* Copyright (C) 1996 Paul Mackerras
* Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ * PPC440/36-bit changes by Matt Porter (mporter@mvista.com)
*
* Derived from "arch/i386/mm/init.c"
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
@@ -408,6 +409,15 @@
free_bootmem(phys_avail.regions[i].address,
phys_avail.regions[i].size);
+#ifdef CONFIG_440
+ /*
+ * Reserve space in the pinned TLB area (ZONE_DMA).
+ * Assume all 44x systems have >16MB RAM and any
+ * initrd is located outside of our pinned TLB area.
+ */
+ reserve_bootmem(0x00800000, 0x00800000);
+#endif
+
init_bootmem_done = 1;
}
@@ -429,9 +439,23 @@
/*
* All pages are DMA-able so we put them all in the DMA zone.
*/
+#ifndef CONFIG_440
zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT;
+
for (i = 1; i < MAX_NR_ZONES; i++)
zones_size[i] = 0;
+#else
+ /*
+ * On 440, we highjack the DMA zone to provide a zone
+ * which limits allocations to our pinned TLB region.
+ */
+ zones_size[ZONE_DMA] = PPC440_PIN_SIZE >> PAGE_SHIFT;
+ zones_size[ZONE_NORMAL] = (total_lowmem - PPC440_PIN_SIZE) >> PAGE_SHIFT;
+
+ for (i = 2; i < MAX_NR_ZONES; i++)
+ zones_size[i] = 0;
+#endif
+
#ifdef CONFIG_HIGHMEM
zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT;
@@ -457,6 +481,12 @@
high_memory = (void *) __va(PPC_MEMSTART + total_lowmem);
num_physpages = max_mapnr; /* RAM is assumed contiguous */
+#ifdef CONFIG_440
+ /* Free reserved space in the pinned TLB area (ZONE_DMA) */
+ if (total_lowmem > PPC440_PIN_SIZE)
+ free_bootmem(0x00800000, 0x00800000);
+#endif
+
totalram_pages += free_all_bootmem();
#ifdef CONFIG_BLK_DEV_INITRD
diff -urN -X bkexcl linux-2.4.22/arch/ppc/mm/mem_pieces.c linuxppc-2.4/arch/ppc/mm/mem_pieces.c
--- linux-2.4.22/arch/ppc/mm/mem_pieces.c 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/mm/mem_pieces.c 2003-07-25 02:06:49.000000000 +1000
@@ -42,7 +42,7 @@
a = (a + align - 1) & -align;
if (a + size <= e) {
mem_pieces_remove(mp, a, size, 1);
- return __va(a);
+ return (void *) __va(a);
}
}
panic("Couldn't find %u bytes at %u alignment\n", size, align);
diff -urN -X bkexcl linux-2.4.22/arch/ppc/mm/mmu_decl.h linuxppc-2.4/arch/ppc/mm/mmu_decl.h
--- linux-2.4.22/arch/ppc/mm/mmu_decl.h 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/mm/mmu_decl.h 2003-07-25 02:06:49.000000000 +1000
@@ -9,6 +9,7 @@
* and Cort Dougan (PReP) (cort@cs.nmt.edu)
* Copyright (C) 1996 Paul Mackerras
* Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ * PPC440-36-bit changes by Matt Porter (mporter@mvista.com)
*
* Derived from "arch/i386/mm/init.c"
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
@@ -25,7 +26,7 @@
extern void mapin_ram(void);
extern void bat_mapin_ram(unsigned long bat2, unsigned long bat3);
extern void adjust_total_lowmem(void);
-extern int map_page(unsigned long va, unsigned long pa, int flags);
+extern int map_page(unsigned long va, phys_addr_t pa, int flags);
extern void setbat(int index, unsigned long virt, unsigned long phys,
unsigned int size, int flags);
extern void reserve_phys_mem(unsigned long start, unsigned long size);
diff -urN -X bkexcl linux-2.4.22/arch/ppc/mm/pgtable.c linuxppc-2.4/arch/ppc/mm/pgtable.c
--- linux-2.4.22/arch/ppc/mm/pgtable.c 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/mm/pgtable.c 2003-08-02 07:10:51.000000000 +1000
@@ -9,6 +9,7 @@
* and Cort Dougan (PReP) (cort@cs.nmt.edu)
* Copyright (C) 1996 Paul Mackerras
* Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ * PPC440/36-bit changes by Matt Porter (mporter@mvista.com)
*
* Derived from "arch/i386/mm/init.c"
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
@@ -40,7 +41,7 @@
/* Maximum 768Mb of lowmem. On SMP, this value will be
* trimmed down to whatever can be covered by BATs though.
*/
-#define MAX_LOW_MEM 0x30000000
+#define MAX_LOW_MEM CONFIG_LOWMEM_SIZE
#ifndef CONFIG_SMP
struct pgtable_cache_struct quicklists;
@@ -67,16 +68,34 @@
#define p_mapped_by_bats(x) (0UL)
#endif /* HAVE_BATS */
+#ifndef CONFIG_440
void *
-ioremap(unsigned long addr, unsigned long size)
+ioremap(phys_addr_t addr, unsigned long size)
+{
+ return __ioremap(addr, size, _PAGE_NO_CACHE);
+}
+#else /* CONFIG_440 */
+void *
+ioremap64(unsigned long long addr, unsigned long size)
{
return __ioremap(addr, size, _PAGE_NO_CACHE);
}
void *
-__ioremap(unsigned long addr, unsigned long size, unsigned long flags)
+ioremap(phys_addr_t addr, unsigned long size)
{
- unsigned long p, v, i;
+ phys_addr_t addr64 = fixup_bigphys_addr(addr, size);
+
+ return ioremap64(addr64, size);
+}
+#endif /* !CONFIG_440 */
+
+void *
+__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
+{
+ unsigned long v, i;
+ phys_addr_t p;
+
int err;
/*
@@ -101,8 +120,13 @@
*/
if ( mem_init_done && (p < virt_to_phys(high_memory)) )
{
+#ifndef CONFIG_440
printk("__ioremap(): phys addr %0lx is RAM lr %p\n", p,
__builtin_return_address(0));
+#else
+ printk("__ioremap(): phys addr %0Lx is RAM lr %p\n", p,
+ __builtin_return_address(0));
+#endif /* CONFIG_440 */
return NULL;
}
@@ -152,7 +176,7 @@
}
out:
- return (void *) (v + (addr & ~PAGE_MASK));
+ return (void *) (v + ((unsigned long)addr & ~PAGE_MASK));
}
void iounmap(void *addr)
@@ -168,7 +192,7 @@
}
int
-map_page(unsigned long va, unsigned long pa, int flags)
+map_page(unsigned long va, phys_addr_t pa, int flags)
{
pmd_t *pd;
pte_t *pg;
@@ -265,7 +289,8 @@
*/
void __init mapin_ram(void)
{
- unsigned long v, p, s, f;
+ unsigned long v, s, f;
+ phys_addr_t p;
#ifdef HAVE_BATS
if (!__map_without_bats)
@@ -279,6 +304,10 @@
* don't get ASID compares on kernel space.
*/
f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED | _PAGE_HWEXEC;
+#ifdef CONFIG_440
+ /* Prevent bogus speculative cycles */
+ f |= _PAGE_GUARDED;
+#endif
#if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || defined(CONFIG_BDI_SWITCH)
/* Allows stub to set breakpoints everywhere */
f |= _PAGE_WRENABLE;
@@ -308,7 +337,7 @@
* virt, phys, size must all be page-aligned.
* This should only be called before ioremap is called.
*/
-void __init io_block_mapping(unsigned long virt, unsigned long phys,
+void __init io_block_mapping(unsigned long virt, phys_addr_t phys,
unsigned int size, int flags)
{
int i;
diff -urN -X bkexcl linux-2.4.22/arch/ppc/platforms/Makefile linuxppc-2.4/arch/ppc/platforms/Makefile
--- linux-2.4.22/arch/ppc/platforms/Makefile 2003-07-18 09:24:47.000000000 +1000
+++ linuxppc-2.4/arch/ppc/platforms/Makefile 2003-07-25 02:06:49.000000000 +1000
@@ -26,9 +26,29 @@
O_TARGET := platform.o
-export-objs := prep_setup.o
+export-objs := prep_setup.o beech.o ibm405lp.o arctic2.o ibm440gp.o
+obj-$(CONFIG_CEDER) += ceder.o ibmnp405l.o
+obj-$(CONFIG_CPCI405) += cpci405.o ibm405gp.o
+obj-$(CONFIG_EVB405EP) += evb405ep.o ibm405ep.o
+obj-$(CONFIG_EP405) += ep405.o ibm405gp.o
+obj-$(CONFIG_XILINX_ML300) += xilinx_ml300.o
+subdir-$(CONFIG_XILINX_OCP) += xilinx_ocp
+obj-$(CONFIG_XILINX_OCP) += xilinx_ocp/xilinx_ocp.o
+obj-$(CONFIG_REDWOOD_4) += redwood.o ibmstb3.o
+obj-$(CONFIG_REDWOOD_5) += redwood5.o ibmstb4.o
+obj-$(CONFIG_REDWOOD_6) += redwood6.o ibmstbx25.o
obj-$(CONFIG_WALNUT) += walnut.o ibm405gp.o
+obj-$(CONFIG_ASH) += ash.o ibmnp405h.o
+obj-$(CONFIG_RAINIER) += rainier.o ibmnp4gs.o
+obj-$(CONFIG_BEECH) += beech.o ibm405lp.o
+obj-$(CONFIG_ARCTIC2) += arctic2.o subzero.o ibm405lp.o
+ifeq ($(CONFIG_405LP),y)
+obj-$(CONFIG_PM) += ibm405lp_pm.o ibm405lp_pmasm.o
+endif
+obj-$(CONFIG_SYCAMORE) += sycamore.o ibm405gpr.o
+
+obj-$(CONFIG_EBONY) += ebony.o ibm440gp.o
obj-$(CONFIG_APUS) += apus_setup.o
ifeq ($(CONFIG_APUS),y)
diff -urN -X bkexcl linux-2.4.22/arch/ppc/platforms/arctic2.c linuxppc-2.4/arch/ppc/platforms/arctic2.c
--- linux-2.4.22/arch/ppc/platforms/arctic2.c 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/platforms/arctic2.c 2003-06-25 21:15:52.000000000 +1000
@@ -0,0 +1,230 @@
+/*
+ * arch/ppc/platforms/arctic2.c Platform setup for the IBM Arctic-2 reference platform
+ * with the Subzero core card and Beech personality card
+ * Based on beech.c by Bishop Brock
+ *
+ * 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
+ *
+ * Copyright (C) 2002, International Business Machines Corporation
+ * All Rights Reserved.
+ *
+ * Ken Inoue
+ * IBM Thomas J. Watson Research Center
+ * keninoue@us.ibm.com
+ *
+ * David Gibson
+ * IBM Ozlabs, Canberra, Australia
+ * arctic@gibson.dropbear.id.au
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+/* Virtual address of the PCCF macro, which needs to be ioremap()ed
+ * and initialized by the board setup code. */
+volatile u16 *pccf_4xx_macro_vaddr;
+unsigned long pccf_4xx_io_base;
+unsigned long pccf_4xx_mem_base;
+EXPORT_SYMBOL(pccf_4xx_macro_vaddr);
+EXPORT_SYMBOL(pccf_4xx_io_base);
+EXPORT_SYMBOL(pccf_4xx_mem_base);
+
+volatile u8 *arctic2_fpga_regs;
+EXPORT_SYMBOL(arctic2_fpga_regs);
+
+/* Different Arctic2 versions have different capabilities in terms of dynamic
+ and static power control. Older units do not support the APM peripheral or
+ voltage scaling. The unit's capabilities are determined at boot and recorded
+ in these variables. Run-time rather than compile-time control is used to
+ simplify kernel distribution. */
+
+int arctic2_supports_apm = 0;
+int arctic2_supports_dvs = 0;
+
+#define GPIO0_OR ((u32 *)(GPIO0_BASE + 0))
+#define GPIO0_TCR ((u32 *)(GPIO0_BASE + 4))
+#define GPIO0_ODR ((u32 *)(GPIO0_BASE + 8))
+#define GPIO0_IR ((u32 *)(GPIO0_BASE + 12))
+
+void __init
+board_setup_arch(void)
+{
+}
+
+void __init
+board_io_mapping(void)
+{
+ ibm405lp_setup_pccf(&pccf_4xx_macro_vaddr, &pccf_4xx_io_base,
+ &pccf_4xx_mem_base);
+}
+
+void __init
+board_setup_irq(void)
+{
+ ibm405lp_setup_apm_pic();
+
+ /*
+ * Set USB interrupt edge-triggered polarity=rising edge.
+ */
+
+ mtdcr(DCRN_UIC0_TR, mfdcr(DCRN_UIC0_TR) | (1 << (31 - UIC_IRQ_EIR0)));
+ mtdcr(DCRN_UIC0_PR, mfdcr(DCRN_UIC0_PR) | (1 << (31 - UIC_IRQ_EIR0)));
+}
+
+void
+arctic2_poweroff(void)
+{
+ if (! arctic2_fpga_regs)
+ BUG();
+
+ __cli();
+
+ writeb(1, ARCTIC2_FPGA_POWERDOWN);
+ eieio();
+
+ while (1)
+ ;
+}
+
+void __init
+board_init(void)
+{
+ cpc0_cgcr1_t cgcr1;
+ u32 cfg;
+
+#ifdef CONFIG_PPC_RTC
+ ppc_md.time_init = ibm405lp_time_init;
+ ppc_md.set_rtc_time = ibm405lp_set_rtc_time;
+ ppc_md.get_rtc_time = ibm405lp_get_rtc_time;
+#endif
+ ppc_md.power_off = arctic2_poweroff;
+
+ /* Set up the EBC, then Disable the LCD controller, which may have been
+ left on by the BIOS. */
+
+ subzero_core_ebc_setup();
+
+ /* Turn on PerClk, so that the SDIO chip works */
+ /* FIXME: This is bad for power usage - this will want to be
+ * fixed to turn the clock on "on demand" when we merge with
+ * the DPM code. */
+ cgcr1.reg=mfdcr(DCRN_CPC0_CGCR1);
+ cgcr1.fields.csel=CPC0_CGCR1_CSEL_PERCLK;
+ mtdcr(DCRN_CPC0_CGCR1, cgcr1.reg);
+
+ /* Configure the Arctic-II specific EBC banks */
+
+ /* Bank 1: 16-bit FPGA peripherals (ethernet data, SDIO, USB, DOC)
+ * 1MB, RW, 16-bit at 0xf9000000-0xf90fffff */
+ /* The access parameters are programmed assuming a 33Mhz EBC
+ clock, which is true for nearly all the operating points we
+ have defined:
+ BME=0, TWT=5, CSN=0, OEN=1, WBN=1, WBF=1 TH=4
+ RE=1, SOR=0, BEM=0, PEN=0
+ */
+ mtdcri(DCRN_EBC0, BnAP(1), 0x02815900);
+ mtdcri(DCRN_EBC0, BnCR(1), ARCTIC2_FPGA16_PADDR | 0x1a000);
+
+ /* Bank 2: 8-bit FPGA peripherals (switch/control, ethernet regs, TCPA)
+ * 1MB, RW, 8-bit at 0xf8000000-0xf80fffff */
+ mtdcri(DCRN_EBC0, BnAP(2), 0x02815580);
+ mtdcri(DCRN_EBC0, BnCR(2), ARCTIC2_FPGA8_PADDR | 0x18000);
+
+ mtdcri(DCRN_LCD0, DER, 0);
+
+ /* Data access of the Arctic2 debug sled ethernet chip will time out
+ under certain conditions unless the EBC ready wait is extended. The
+ data sheet doesn't give a bound on this, so we allow a generous
+ amount of time. Note that this problem is normally masked by the
+ PCMCIA setup, which sets an even longer timeout. */
+
+ cfg = mfdcri(DCRN_EBC0, CFG);
+ if ((cfg & EBC_CFG_RTC) < EBC_CFG_RTC_128)
+ mtdcri(DCRN_EBC0, CFG, (cfg & ~EBC_CFG_RTC) | EBC_CFG_RTC_128);
+}
+
+void
+arctic2_set_lcdpower(int on)
+{
+ iobarrier_rw();
+ if (on)
+ out_be32(GPIO0_TCR, in_be32(GPIO0_TCR) | 0x80000000 );
+ else
+ out_be32(GPIO0_TCR, in_be32(GPIO0_TCR) & ~0x80000000);
+ iobarrier_rw();
+ udelay(100); /* KI guard time */
+}
+
+EXPORT_SYMBOL(arctic2_poweroff);
+EXPORT_SYMBOL(arctic2_set_lcdpower);
+
+/* Units that support APM/DVS pull GPIO3 low as a strap. On older units this
+ GPIO is pulled high. After boot this can be used as a trace/debug signal, as
+ it has no other purpose on the board. */
+
+static void __init
+check_apm_dvs_support(void)
+{
+ u32 gpio3 = 0x10000000;
+
+ iobarrier_rw();
+ out_be32(GPIO0_TCR, in_be32(GPIO0_TCR) & ~gpio3);
+ out_be32(GPIO0_ODR, in_be32(GPIO0_ODR) & ~gpio3);
+ iobarrier_rw();
+ arctic2_supports_apm = ((in_be32(GPIO0_IR) & gpio3) == 0);
+ arctic2_supports_dvs = arctic2_supports_apm;
+}
+
+int __init
+arctic2_init(void)
+{
+ if (! request_mem_region(ARCTIC2_FPGA8_PADDR,
+ ARCTIC2_FPGA_REGS_EXTENT,
+ "Arctic-2 FPGA Control Registers"))
+ BUG(); /* If someone's grabbed these addresses
+ * already, something's seriously wrong */
+
+ arctic2_fpga_regs = ioremap(ARCTIC2_FPGA8_PADDR,
+ ARCTIC2_FPGA_REGS_EXTENT);
+ if (!arctic2_fpga_regs)
+ BUG();
+
+ check_apm_dvs_support();
+
+ return 0;
+}
+
+__initcall(arctic2_init);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End: */
diff -urN -X bkexcl linux-2.4.22/arch/ppc/platforms/arctic2.h linuxppc-2.4/arch/ppc/platforms/arctic2.h
--- linux-2.4.22/arch/ppc/platforms/arctic2.h 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/platforms/arctic2.h 2003-06-25 21:15:52.000000000 +1000
@@ -0,0 +1,148 @@
+/*
+ * arch/ppc/platforms/arctic2.h Platform definitions for the IBM Arctic-II
+ * based on beech.h by Bishop Brock
+ *
+ * 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
+ *
+ * Copyright (C) 2002, International Business Machines Corporation
+ * All Rights Reserved.
+ *
+ * Ken Inoue
+ * IBM Thomas J. Watson Research Center
+ * keninoue@us.ibm.com
+ *
+ * David Gibson
+ * IBM Ozlabs, Canberra, Australia
+ * arctic@gibson.dropbear.id.au
+ *
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_ARCTIC2_H__
+#define __ASM_ARCTIC2_H__
+
+#include
+
+#ifndef __ASSEMBLY__
+
+/* Physical address for the 8-bit peripheral bank */
+#define ARCTIC2_FPGA8_PADDR (0xf8000000)
+
+/* Physical address for the 16-bit peripheral bank */
+#define ARCTIC2_FPGA16_PADDR (0xf9000000)
+
+/* Virtual address of the FPGA control registers */
+extern volatile u8 *arctic2_fpga_regs;
+
+#define ARCTIC2_FPGA_REGS_EXTENT (0xf)
+#define ARCTIC2_FPGA_POWERDOWN (arctic2_fpga_regs + 0x0)
+#define ARCTIC2_FPGA_BUTTONS (arctic2_fpga_regs + 0x1)
+#define ARCTIC2_FPGA_MULTIWAY (arctic2_fpga_regs + 0x2)
+#define ARCTIC2_FPGA_IRQ_ENABLE (arctic2_fpga_regs + 0x3)
+#define ARCTIC2_FPGA_PCCF_POWER (arctic2_fpga_regs + 0x4)
+#define ARCTIC2_FPGA_JACKET (arctic2_fpga_regs + 0x5)
+#define ARCTIC2_FPGA_SDIO_CTRL (arctic2_fpga_regs + 0x6)
+#define ARCTIC2_FPGA_USB_CTRL (arctic2_fpga_regs + 0x7)
+#define ARCTIC2_FPGA_MDOC_CTRL (arctic2_fpga_regs + 0x8)
+#define ARCTIC2_FPGA_CHARGER (arctic2_fpga_regs + 0x9)
+#define ARCTIC2_FPGA_CRYO (arctic2_fpga_regs + 0xa)
+#define ARCTIC2_FPGA_LED_DATA_HI (arctic2_fpga_regs + 0xc)
+#define ARCTIC2_FPGA_LED_DATA_LOW (arctic2_fpga_regs + 0xd)
+#define ARCTIC2_FPGA_LED_ADDR (arctic2_fpga_regs + 0xe)
+#define ARCTIC2_FPGA_LED_CTRL (arctic2_fpga_regs + 0xf)
+
+#define ARCTIC2_FPGA_BTN_PWR 0x20
+#define ARCTIC2_FPGA_BTN_MIC 0x10
+
+#define ARCTIC2_FPGA_MULTIWAY_PUSH 0x01
+#define ARCTIC2_FPGA_MULTIWAY_NE 0x02
+#define ARCTIC2_FPGA_MULTIWAY_SE 0x04
+#define ARCTIC2_FPGA_MULTIWAY_SW 0x08
+#define ARCTIC2_FPGA_MULTIWAY_NW 0x10
+
+#define ARCTIC2_FPGA_MULTIWAY_N 0x12
+#define ARCTIC2_FPGA_MULTIWAY_E 0x06
+#define ARCTIC2_FPGA_MULTIWAY_S 0x0c
+#define ARCTIC2_FPGA_MULTIWAY_W 0x18
+
+#define ARCTIC2_FPGA_IRQ_PWR 0x10
+#define ARCTIC2_FPGA_IRQ_TCPA 0x08
+#define ARCTIC2_FPGA_IRQ_JACKET 0x04
+#define ARCTIC2_FPGA_IRQ_MIC 0x02
+#define ARCTIC2_FPGA_IRQ_BTN 0x01
+
+#define ARCTIC2_FPGA_PCCF_POWER_5V 0x01
+
+/* Arctic II uses the internal clock for UART. Note that the OPB
+ frequency must be more than 2x the UART clock frequency. At OPB
+ frequencies less than this the serial port will not function due to
+ the way that SerClk is sampled. We use 11.1111MHz as the frequency
+ because it can be generated from a wide range of OPB frequencies we
+ want to use. */
+
+#define PPC4xx_SERCLK_FREQ 11111111
+
+#define BASE_BAUD (PPC4xx_SERCLK_FREQ / 16)
+
+#define RTC_DVBITS RTC_DVBITS_33KHZ /* 33kHz RTC */
+
+#define PPC4xx_MACHINE_NAME "IBM Arctic II"
+
+#include
+#define _IO_BASE (pccf_4xx_io_base)
+#define _ISA_MEM_BASE (pccf_4xx_mem_base)
+
+void arctic2_poweroff(void) __attribute__ ((noreturn));
+void arctic2_set_lcdpower(int on);
+
+extern int arctic2_supports_apm;
+extern int arctic2_supports_dvs;
+
+/*****************************************************************************
+ * Serial port definitions
+ *****************************************************************************/
+
+/*
+ * Arctic UART1 is touchscreen handled by separate driver, not included in
+ * standard serial defines.
+ */
+
+#define UART0_INT UIC_IRQ_U0
+#define UART1_INT UIC_IRQ_U1
+#define UART0_IO_BASE 0xEF600300
+#define UART1_IO_BASE 0xEF600400
+
+#define RS_TABLE_SIZE 2
+
+#define STD_UART_OP(num) \
+ { 0, BASE_BAUD, 0, UART##num##_INT, \
+ (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
+ iomem_base:(u8 *) UART##num##_IO_BASE, \
+ io_type: SERIAL_IO_MEM},
+
+#define SERIAL_DEBUG_IO_BASE UART0_IO_BASE
+#define SERIAL_PORT_DFNS \
+ STD_UART_OP(0)
+
+/* PM Button support */
+
+#ifdef CONFIG_405LP_PM_BUTTON
+#define IBM405LP_PM_IRQ APM0_IRQ_WUI0
+#define IBM405LP_PM_POLARITY 1
+#endif
+
+#endif /* !__ASSEMBLY__ */
+#endif /* __ASM_ARCTIC2_H__ */
+#endif /* __KERNEL__ */
diff -urN -X bkexcl linux-2.4.22/arch/ppc/platforms/ash.c linuxppc-2.4/arch/ppc/platforms/ash.c
--- linux-2.4.22/arch/ppc/platforms/ash.c 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/platforms/ash.c 2003-03-14 20:46:44.000000000 +1100
@@ -0,0 +1,250 @@
+/*
+ *
+ * Copyright 2001-2002 MontaVista Software Inc.
+ *
+ * IBM NP405H ash eval board
+ *
+ * V 0.2 04/18/02 - Armin
+ * fixed board info debug
+ * V 0.3 06/12/02 - Armin
+ * added bios_fixup.
+ * V 0.4 06/17/02 - Armin /Todd
+ * fixed bios fixup, order
+ *
+ * Please read the COPYING file for all license details.
+ */
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+void *ash_rtc_base;
+
+/* Some IRQs unique to Walnut.
+ * Used by the generic 405 PCI setup functions in ppc4xx_pci.c
+ */
+int __init
+ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+ static char pci_irq_table[][4] =
+ /*
+ * PCI IDSEL/INTPIN->INTLINE
+ * A B C D
+ */
+ {
+ {24, 24, 24, 24}, /* IDSEL 1 - PCI slot 1 */
+ {25, 25, 25, 25}, /* IDSEL 2 - PCI slot 2 */
+ {26, 26, 26, 26}, /* IDSEL 3 - PCI slot 3 */
+ {27, 27, 27, 27}, /* IDSEL 4 - PCI slot 4 */
+ };
+
+ const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
+ return PCI_IRQ_TABLE_LOOKUP;
+}
+
+void __init
+board_setup_arch(void)
+{
+
+ bd_t *bip = (bd_t *) __res;
+
+#ifdef CONFIG_DEBUG_BRINGUP
+ int i;
+ printk("\n");
+ printk("machine\t: %s\n", PPC4xx_MACHINE_NAME);
+ printk("\n");
+ printk("bi_s_version\t %s\n", bip->bi_s_version);
+ printk("bi_r_version\t %s\n", bip->bi_r_version);
+ printk("bi_memsize\t 0x%8.8x\t %dMBytes\n", bip->bi_memsize,
+ bip->bi_memsize / (1024 * 1000));
+ for (i = 0; i < EMAC_NUMS; i++) {
+ printk("bi_enetaddr %d\t %2.2x%2.2x%2.2x-%2.2x%2.2x%2.2x\n", i,
+ bip->bi_enetaddr[i][0], bip->bi_enetaddr[i][1],
+ bip->bi_enetaddr[i][2], bip->bi_enetaddr[i][3],
+ bip->bi_enetaddr[i][4], bip->bi_enetaddr[i][5]);
+ }
+ printk("bi_pci_enetaddr %d\t %2.2x%2.2x%2.2x-%2.2x%2.2x%2.2x\n", 0,
+ bip->bi_pci_enetaddr[0], bip->bi_pci_enetaddr[1],
+ bip->bi_pci_enetaddr[2], bip->bi_pci_enetaddr[3],
+ bip->bi_pci_enetaddr[4], bip->bi_pci_enetaddr[5]);
+
+ printk("bi_intfreq\t 0x%8.8x\t clock:\t %dMhz\n",
+ bip->bi_intfreq, bip->bi_intfreq / 1000000);
+
+ printk("bi_busfreq\t 0x%8.8x\t plb bus clock:\t %dMHz\n",
+ bip->bi_busfreq, bip->bi_busfreq / 1000000);
+ printk("bi_pci_busfreq\t 0x%8.8x\t pci bus clock:\t %dMHz\n",
+ bip->bi_pci_busfreq, bip->bi_pci_busfreq / 1000000);
+
+ printk("\n");
+#endif
+ /* RTC step for ash */
+ ash_rtc_base = (void *) ASH_RTC_VADDR;
+ TODC_INIT(TODC_TYPE_DS1743, ash_rtc_base, ash_rtc_base, ash_rtc_base,
+ 8);
+
+}
+
+void __init
+bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
+{
+
+ unsigned int bar_response, bar;
+ /*
+ * Expected PCI mapping:
+ *
+ * PLB addr PCI memory addr
+ * --------------------- ---------------------
+ * 0000'0000 - 7fff'ffff <--- 0000'0000 - 7fff'ffff
+ * 8000'0000 - Bfff'ffff ---> 8000'0000 - Bfff'ffff
+ *
+ * PLB addr PCI io addr
+ * --------------------- ---------------------
+ * e800'0000 - e800'ffff ---> 0000'0000 - 0001'0000
+ *
+ * The following code is simplified by assuming that the bootrom
+ * has been well behaved in following this mapping.
+ */
+
+#ifdef DEBUG
+ int i;
+
+ printk("ioremap PCLIO_BASE = 0x%x\n", pcip);
+ printk("PCI bridge regs before fixup \n");
+ for (i = 0; i <= 2; i++) {
+ printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma)));
+ printk(" pmm%dla\t0x%x\n", i, in_le32(&(pcip->pmm[i].la)));
+ printk(" pmm%dpcila\t0x%x\n", i,
+ in_le32(&(pcip->pmm[i].pcila)));
+ printk(" pmm%dpciha\t0x%x\n", i,
+ in_le32(&(pcip->pmm[i].pciha)));
+ }
+ printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms)));
+ printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la)));
+ printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms)));
+ printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la)));
+ for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) {
+ early_read_config_dword(hose, hose->first_busno,
+ PCI_FUNC(hose->first_busno), bar,
+ &bar_response);
+ DBG("BUS %d, device %d, Function %d bar 0x%8.8x is 0x%8.8x\n",
+ hose->first_busno, PCI_SLOT(hose->first_busno),
+ PCI_FUNC(hose->first_busno), bar, bar_response);
+ }
+
+#endif
+ if (ppc_md.progress)
+ ppc_md.progress("bios_fixup(): enter", 0x800);
+
+ /* added for IBM boot rom version 1.15 bios bar changes -AK */
+
+ /* Disable region first */
+ out_le32((void *) &(pcip->pmm[0].ma), 0x00000000);
+ /* PLB starting addr, PCI: 0x80000000 */
+ out_le32((void *) &(pcip->pmm[0].la), 0x80000000);
+ /* PCI start addr, 0x80000000 */
+ out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE);
+ /* 512MB range of PLB to PCI */
+ out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000);
+ /* Enable no pre-fetch, enable region */
+ out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff -
+ (PPC405_PCI_UPPER_MEM -
+ PPC405_PCI_MEM_BASE)) | 0x01));
+
+ /* Disable region one */
+ out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
+ out_le32((void *) &(pcip->pmm[1].la), 0x00000000);
+ out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000);
+ out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000);
+ out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
+
+ /* Disable region two */
+ out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
+ out_le32((void *) &(pcip->pmm[2].la), 0x00000000);
+ out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000);
+ out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000);
+ out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
+
+ /* Enable PTM1 and PTM2, mapped to PLB address 0. */
+
+ out_le32((void *) &(pcip->ptm1la), 0x00000000);
+ out_le32((void *) &(pcip->ptm1ms), 0x00000001);
+ out_le32((void *) &(pcip->ptm2la), 0x00000000);
+ out_le32((void *) &(pcip->ptm2ms), 0x00000001);
+
+ /* Write zero to PTM1 BAR. */
+
+ early_write_config_dword(hose, hose->first_busno,
+ PCI_FUNC(hose->first_busno),
+ PCI_BASE_ADDRESS_1,
+ 0x00000000);
+
+ /* Disable PTM2 (unused) */
+
+ out_le32((void *) &(pcip->ptm2la), 0x00000000);
+ out_le32((void *) &(pcip->ptm2ms), 0x00000000);
+
+ /* end work arround */
+ if (ppc_md.progress)
+ ppc_md.progress("bios_fixup(): done", 0x800);
+
+#ifdef DEBUG
+ printk("PCI bridge regs after fixup \n");
+ for (i = 0; i <= 2; i++) {
+ printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma)));
+ printk(" pmm%dla\t0x%x\n", i, in_le32(&(pcip->pmm[i].la)));
+ printk(" pmm%dpcila\t0x%x\n", i,
+ in_le32(&(pcip->pmm[i].pcila)));
+ printk(" pmm%dpciha\t0x%x\n", i,
+ in_le32(&(pcip->pmm[i].pciha)));
+ }
+ printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms)));
+ printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la)));
+ printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms)));
+ printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la)));
+
+ for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) {
+ early_read_config_dword(hose, hose->first_busno,
+ PCI_FUNC(hose->first_busno), bar,
+ &bar_response);
+ DBG("BUS %d, device %d, Function %d bar 0x%8.8x is 0x%8.8x\n",
+ hose->first_busno, PCI_SLOT(hose->first_busno),
+ PCI_FUNC(hose->first_busno), bar, bar_response);
+ }
+
+
+#endif
+}
+
+void __init
+board_io_mapping(void)
+{
+ io_block_mapping(ASH_RTC_VADDR, ASH_RTC_PADDR, ASH_RTC_SIZE, _PAGE_IO);
+}
+
+void __init
+board_setup_irq(void)
+{
+
+}
+
+void __init
+board_init(void)
+{
+ ppc_md.time_init = todc_time_init;
+ ppc_md.set_rtc_time = todc_set_rtc_time;
+ ppc_md.get_rtc_time = todc_get_rtc_time;
+ ppc_md.nvram_read_val = todc_direct_read_val;
+ ppc_md.nvram_write_val = todc_direct_write_val;
+}
diff -urN -X bkexcl linux-2.4.22/arch/ppc/platforms/ash.h linuxppc-2.4/arch/ppc/platforms/ash.h
--- linux-2.4.22/arch/ppc/platforms/ash.h 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/platforms/ash.h 2003-07-25 02:00:01.000000000 +1000
@@ -0,0 +1,88 @@
+/*
+ *
+ *
+ * Copyright 2000-2002 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * akuster@mvista.com or source@mvista.com
+ *
+ * Module name: ash.h
+ *
+ * Description:
+ * Macros, definitions, and data structures specific to the IBM PowerPC
+ * Ash eval board.
+ *
+ * Please read the COPYING file for all license details.
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_ASH_H__
+#define __ASM_ASH_H__
+#include
+#include
+
+#ifndef __ASSEMBLY__
+/*
+ * Data structure defining board information maintained by the boot
+ * ROM on IBM's "Ash" evaluation board. An effort has been made to
+ * keep the field names consistent with the 8xx 'bd_t' board info
+ * structures.
+ */
+
+typedef struct board_info {
+ unsigned char bi_s_version[4]; /* Version of this structure */
+ unsigned char bi_r_version[30]; /* Version of the IBM ROM */
+ unsigned int bi_memsize; /* DRAM installed, in bytes */
+ unsigned char bi_enetaddr[4][6]; /* Local Ethernet MAC address */
+ unsigned char bi_pci_enetaddr[6];
+ unsigned int bi_intfreq; /* Processor speed, in Hz */
+ unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
+ unsigned int bi_pci_busfreq; /* PCI speed in Hz */
+ unsigned int bi_opb_busfreq; /* OPB Bus speed, in Hz */
+ int bi_iic_fast[1]; /* Use fast i2c mode */
+} bd_t;
+
+/* Some 4xx parts use a different timebase frequency from the internal clock.
+*/
+#define bi_tbfreq bi_intfreq
+
+/* Memory map for the IBM "Ash" NP405H evaluation board.
+ */
+
+extern void *ash_rtc_base;
+#define ASH_RTC_PADDR ((uint)0xf0000000)
+#define ASH_RTC_VADDR ASH_RTC_PADDR
+#define ASH_RTC_SIZE ((uint)8*1024)
+
+
+/* Early initialization address mapping for block_io.
+ * Standard 405GP map.
+ */
+#define PPC4xx_PCI_IO_PADDR ((uint)PPC405_PCI_PHY_IO_BASE)
+#define PPC4xx_PCI_IO_VADDR PPC4xx_PCI_IO_PADDR
+#define PPC4xx_PCI_IO_SIZE ((uint)64*1024)
+#define PPC4xx_PCI_CFG_PADDR ((uint)PPC405_PCI_CONFIG_ADDR)
+#define PPC4xx_PCI_CFG_VADDR PPC4xx_PCI_CFG_PADDR
+#define PPC4xx_PCI_CFG_SIZE ((uint)4*1024)
+#define PPC4xx_PCI_LCFG_PADDR ((uint)0xef400000)
+#define PPC4xx_PCI_LCFG_VADDR PPC4xx_PCI_LCFG_PADDR
+#define PPC4xx_PCI_LCFG_SIZE ((uint)4*1024)
+#define PPC4xx_ONB_IO_PADDR ((uint)0xef600000)
+#define PPC4xx_ONB_IO_VADDR PPC4xx_ONB_IO_PADDR
+#define PPC4xx_ONB_IO_SIZE ((uint)4*1024)
+
+#define NR_BOARD_IRQS 32
+
+#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK
+#define BASE_BAUD 201600
+#else
+#define BASE_BAUD 691200
+#endif
+
+#define PPC4xx_MACHINE_NAME "IBM NP405H Ash"
+
+extern char pci_irq_table[][4];
+
+
+#endif /* !__ASSEMBLY__ */
+#endif /* __ASM_ASH_H__ */
+#endif /* __KERNEL__ */
diff -urN -X bkexcl linux-2.4.22/arch/ppc/platforms/beech.c linuxppc-2.4/arch/ppc/platforms/beech.c
--- linux-2.4.22/arch/ppc/platforms/beech.c 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/platforms/beech.c 2003-06-02 14:37:41.000000000 +1000
@@ -0,0 +1,297 @@
+/*
+ * arch/ppc/platforms/beech.c Platform setup for the IBM Beech board
+ *
+ * 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
+ *
+ * Copyright (C) 2002, International Business Machines Corporation
+ * All Rights Reserved
+ *
+ * Bishop Brock
+ * IBM Research, Austin Center for Low-Power Computing
+ * bcbrock@us.ibm.com
+ * March, 2002
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+static void beech_ebc_setup(void);
+static void beech_fpga_setup(void);
+
+volatile u8 *beech_fpga_reg_0 = NULL;
+volatile u8 *beech_fpga_reg_2 = NULL;
+volatile u8 *beech_fpga_reg_4 = NULL;
+
+EXPORT_SYMBOL(beech_fpga_reg_0);
+EXPORT_SYMBOL(beech_fpga_reg_2);
+EXPORT_SYMBOL(beech_fpga_reg_4);
+
+/* Virtual address of the PCCF macro, which needs to be ioremap()ed
+ * and initialized by the board setup code. */
+volatile u16 *pccf_4xx_macro_vaddr;
+unsigned long pccf_4xx_io_base;
+unsigned long pccf_4xx_mem_base;
+EXPORT_SYMBOL(pccf_4xx_macro_vaddr);
+EXPORT_SYMBOL(pccf_4xx_io_base);
+EXPORT_SYMBOL(pccf_4xx_mem_base);
+
+/*
+ Beech board physical memory map:
+
+ Main Memory (Initialized by the BIOS)
+ =======================================================================
+
+ SDRAM (64 MB) 0x00000000 - 0x04000000
+
+ OPB Space: (Mapped virtual = physical in ppc4xx_setup.c)
+ =======================================================================
+
+ UART0 0xEF600300
+ UART1 0xEF600400
+ IIC 0xEF600500
+ OPB Arbiter 0xEF600600
+ GPIO Controller 0xEF600700
+ CODEC Interface 0xEF600900
+ Touch Panel Controller 0xEF600A00
+ DES Controller 0xEF600B00
+
+
+ EBC Space: (Mapped virtual = physical in board_io_mapping(); EBC setup
+ for PCMCIA left to 4xx_pccf)
+ Space EBC Bank Physical Addresses EBC Base Address
+ =========================================================================
+
+ PCMCIA (32 MB) x F0000000 - F1FFFFFF F0000000
+
+ Expansion 2 F8000000 - F8FFFFFF F8000000
+ Linux Flash (16 MB) F9000000 - F9FFFFFF
+
+ NVRAM (32 KB) 1 FFE00000 - FFE07FFF FFE00000
+
+
+ Ethernet(I/O) 1 FFE20300 - FFE2030F FFE00000
+ (MEM) FFE40000 - FFE40FFF
+
+ FPGA_REG_4 1 FFE60000 - FFE60000 FFE00000
+ FPGA_REG_0 1 FFE80000 - FFE80000 FFE00000
+ FPGA_REG_1 1 FFEA0000 - FFEA0000 FFE00000
+ FPGA_REG_2 1 FFEC0000 - FFEC0000 FFE00000
+ FPGA_REG_3 1 FFEE0000 - FFEE0000 FFE00000
+
+ SRAM (512 KB) 0 FFF00000 - FFF7FFFF FFF00000
+
+ Boot Flash (512 KB) 0 FFF80000 - FFFFFFFF FFF00000
+
+ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ NB: On Beech 1, address ranges for Bank 2 were reversed
+
+*/
+
+void __init
+board_setup_arch(void)
+{
+ /* Set up Beech FPGA. */
+
+ beech_fpga_setup();
+}
+
+void __init
+board_io_mapping(void)
+{
+ ibm405lp_setup_pccf(&pccf_4xx_macro_vaddr, &pccf_4xx_io_base,
+ &pccf_4xx_mem_base);
+}
+
+void __init
+board_setup_irq(void)
+{
+ ibm405lp_setup_apm_pic();
+}
+
+/* The 405LP on Beech does not control the board power supply. All it can
+ really do is power down the CPU core supply, but this is still useful for
+ test and development. Note that when the core is powered down as part of a
+ suspend-to-RAM or hibernate, the poweroff sequence is executed from power
+ management code. The APM0_CFG[CDIV] field is used as a non-volatile
+ register to communicate the suspend/resume mode to the BIOS. */
+
+static void
+beech_poweroff(void)
+{
+ apm0_cfg_t cfg;
+
+ __cli();
+
+ cfg.reg = mfdcr(DCRN_APM0_CFG);
+ cfg.fields.sm = APM0_CFG_SM_POWER_DOWN;
+ cfg.fields.cdiv = IBM405LP_POWERDOWN_REBOOT;
+ cfg.fields.isp = 1;
+ mtdcr_interlock(DCRN_APM0_CFG, cfg.reg, APM0_CFG_MASK);
+ while (1);
+}
+
+void __init
+board_init(void)
+{
+ ppc_md.time_init = ibm405lp_time_init;
+ ppc_md.set_rtc_time = ibm405lp_set_rtc_time;
+ ppc_md.get_rtc_time = ibm405lp_get_rtc_time;
+
+ ppc_md.power_off = beech_poweroff;
+
+ /* Disable the LCD controller, which may have been left on by the
+ BIOS. Then do initialization of the EBC. */
+
+ mtdcri(DCRN_LCD0, DER, 0);
+ beech_ebc_setup();
+}
+
+/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ + Non-standard board support follows
+ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+
+/****************************************************************************
+ * EBC Setup
+ ****************************************************************************/
+
+/* The EBC is set up for Beech. This may simply replicate the setup already
+ done by the IBM BIOS for Beech (possibly with some address map changes), or
+ may be the first initialization if the board is booting from another BIOS.
+ Virtually all that is required to boot Linux on Beech is that the BIOS
+ enable the memory controller, load a Linux image from flash, and run it.
+
+ For optimal dynamic frequency scaling the EBC settings will also vary as the
+ frequency varies.
+*/
+
+static void __init
+beech_ebc_setup(void)
+{
+ ebc0_bnap_t ap;
+ ebc0_bncr_t cr;
+
+ /* Set EBC bank 0 for the SRAM and boot flash.
+
+ Access parameters assume 120ns AMD flash @ 66.66 MHz maximum bus
+ speed = 8 cycle access with 2 turnaround cycles (30 ns).
+
+ These parameters will work for the SRAM as well, which is a 70 ns
+ part.
+
+ NB: IBM BIOS sets this bank to burst, however bursting will never
+ happen in Linux because this region is mapped non-cacheable and
+ guarded, so it is set non-burst here. */
+
+ cr.reg = (BEECH_BANK0_PADDR & 0xfff00000) |
+ (mfdcri(DCRN_EBC0, BnCR(0)) & EBC0_BnCR_MASK);
+ cr.fields.bs = BEECH_BANK0_EBC_SIZE;
+ cr.fields.bu = EBC0_BnCR_BU_RW;
+ cr.fields.bw = EBC0_BnCR_BW_16;
+ mtdcri(DCRN_EBC0, BnCR(0), cr.reg);
+
+ ap.reg = mfdcri(DCRN_EBC0, BnAP(0)) & EBC0_BnAP_MASK;
+ ap.fields.twt = 8;
+ ap.fields.th = 2;
+ mtdcri(DCRN_EBC0, BnAP(0), ap.reg);
+
+ /* EBC bank 1 is used for many purposes: NVRAM, Ethernet, and FPGA
+ registers. This is a 1 MB, 16-bit bank. The access parameters must
+ handle the worst case of all of the devices.
+
+ The Ethernet chip needs 20 ns setup of the addresses to the I/O
+ write signal (generated from the chip select), a minimum 150 ns
+ cycle, and 30 ns of turnaround. These settings will work for the
+ other devices as well.
+ */
+
+ cr.reg = (BEECH_BANK1_PADDR & 0xfff00000) |
+ (mfdcri(DCRN_EBC0, BnCR(1)) & EBC0_BnCR_MASK);
+ cr.fields.bs = BEECH_BANK1_EBC_SIZE;
+ cr.fields.bu = EBC0_BnCR_BU_RW;
+ cr.fields.bw = EBC0_BnCR_BW_16;
+ mtdcri(DCRN_EBC0, BnCR(1), cr.reg);
+
+ ap.reg = mfdcri(DCRN_EBC0, BnAP(1)) & EBC0_BnAP_MASK;
+ ap.fields.twt = 10;
+ ap.fields.csn = 2;
+ ap.fields.th = 2;
+ mtdcri(DCRN_EBC0, BnAP(1), ap.reg);
+
+ /* Set EBC bank 2 for the big (Linux) flash. There is 16 MB of flash,
+ but the CPLD decodes a 32 MB region.
+
+ Access parameters assume 90ns AMD flash @ 66.66 MHz maximum bus
+ speed = 6 cycle access with 2 turnaround cycles (30 ns).
+
+ NB: IBM BIOS sets this bank to burst, however bursting will never
+ happen in Linux because this region is mapped non-cacheable and
+ guarded, so it is set non-burst here. */
+
+ cr.reg = (BEECH_BANK2_PADDR & 0xfff00000) |
+ (mfdcri(DCRN_EBC0, BnCR(2)) & EBC0_BnCR_MASK);
+ cr.fields.bs = BEECH_BANK2_EBC_SIZE;
+ cr.fields.bu = EBC0_BnCR_BU_RW;
+ cr.fields.bw = EBC0_BnCR_BW_8;
+ mtdcri(DCRN_EBC0, BnCR(2), cr.reg);
+
+ ap.reg = mfdcri(DCRN_EBC0, BnAP(2)) & EBC0_BnAP_MASK;
+ ap.fields.twt = 6;
+ ap.fields.th = 2;
+ mtdcri(DCRN_EBC0, BnAP(2), ap.reg);
+}
+
+/****************************************************************************
+ * FPGA Setup
+ ****************************************************************************/
+
+/* The Beech FPGA is set up for Linux. */
+
+static void __init
+beech_fpga_setup(void)
+{
+ beech_fpga_reg_0 = (volatile u8 *)
+ ioremap(BEECH_FPGA_REG_0_PADDR, BEECH_FPGA_REG_0_SIZE);
+ beech_fpga_reg_2 = (volatile u8 *)
+ ioremap(BEECH_FPGA_REG_2_PADDR, BEECH_FPGA_REG_2_SIZE);
+ beech_fpga_reg_4 = (volatile u8 *)
+ ioremap(BEECH_FPGA_REG_4_PADDR, BEECH_FPGA_REG_4_SIZE);
+
+ /* Set RTS/CTS mode for UART 1 */
+
+ *beech_fpga_reg_2 |= FPGA_REG_2_DEFAULT_UART1_N;
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
+
diff -urN -X bkexcl linux-2.4.22/arch/ppc/platforms/beech.h linuxppc-2.4/arch/ppc/platforms/beech.h
--- linux-2.4.22/arch/ppc/platforms/beech.h 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/platforms/beech.h 2003-07-25 02:00:01.000000000 +1000
@@ -0,0 +1,245 @@
+/*
+ * include/asm-ppc/platforms/beech.h Platform definitions for the IBM Beech
+ * board
+ *
+ * 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
+ *
+ * Copyright (C) 2002, International Business Machines Corporation
+ * All Rights Reserved.
+ *
+ * Bishop Brock
+ * IBM Research, Austin Center for Low-Power Computing
+ * bcbrock@us.ibm.com
+ * March, 2002
+ *
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_BEECH_H__
+#define __ASM_BEECH_H__
+
+#include
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Data structure defining board information maintained by the standard boot
+ * ROM on the IBM Beech board. An effort has been made to
+ * keep the field names consistent with the 8xx 'bd_t' board info
+ * structures.
+ */
+
+typedef struct board_info {
+ unsigned char bi_s_version[4]; /* Version of this structure */
+ unsigned long bi_tbfreq; /* Frequency of SysTmrClk */
+ unsigned char bi_r_version[30]; /* Version of the IBM ROM */
+ unsigned int bi_memsize; /* DRAM installed, in bytes */
+ unsigned long sysclock_period; /* SysClk period in ns */
+ unsigned long sys_speed; /* SysCLk frequency in Hz */
+ unsigned long bi_intfreq; /* Processor speed, in Hz */
+ unsigned long vco_speed; /* PLL VCO speed, in Hz */
+ unsigned long bi_busfreq; /* PLB Bus speed, in Hz */
+ unsigned int bi_opb_busfreq; /* OPB Bus speed, in Hz */
+ unsigned long bi_ebc_busfreq; /* EBC Bus speed, in Hz */
+ int bi_iic_fast[1]; /* Use fast i2c mode */
+} bd_t;
+
+/* EBC Bank 0 controls the boot flash and SRAM */
+
+#define BEECH_BANK0_PADDR ((uint)0xfff00000)
+#define BEECH_BANK0_EBC_SIZE EBC0_BnCR_BS_1MB
+
+#define BEECH_SRAM_PADDR BEECH_BANK0_PADDR
+#define BEECH_SRAM_SIZE ((uint)(512 * 1024))
+
+#define BEECH_BOOTFLASH_PADDR (BEECH_BANK0_PADDR + (512 * 1024))
+#define BEECH_BOOTFLASH_SIZE ((uint)(512 * 1024))
+
+/* EBC bank 1 controls the NVRAM, Ethernet and CPLD registers. The different
+ areas are mapped in as small an area as possible to help catch any kernel
+ addressing errors.
+
+ NVRAM is improperly connected on Beech Pass 1. Only every other location is
+ accessible. This is a 32 KB NVRAM.
+
+ The Ethernet chip maps 13 address lines. We only map the "I/O" space used by
+ the current driver.
+
+ The FPGA "registers" are decoded on 128 KB boundarys. Each is mapped in a
+ separate page. */
+
+#define BEECH_BANK1_PADDR ((uint)0xffe00000)
+#define BEECH_BANK1_EBC_SIZE EBC0_BnCR_BS_1MB
+
+#define BEECH_NVRAM_PADDR BEECH_BANK1_PADDR
+#define BEECH_NVRAM_SIZE ((uint) (32 * 1024))
+
+#define BEECH_ETHERNET_PADDR (BEECH_BANK1_PADDR + 0x00020000)
+#define BEECH_ETHERNET_SIZE ((uint) (8 * 1024))
+
+#define BEECH_FPGA_REG_0_PADDR (BEECH_BANK1_PADDR + 0x00080000)
+#define BEECH_FPGA_REG_0_SIZE PAGE_SIZE
+
+#define BEECH_FPGA_REG_1_PADDR (BEECH_BANK1_PADDR + 0x000A0000)
+#define BEECH_FPGA_REG_1_SIZE PAGE_SIZE
+
+#define BEECH_FPGA_REG_2_PADDR (BEECH_BANK1_PADDR + 0x000C0000)
+#define BEECH_FPGA_REG_2_SIZE PAGE_SIZE
+
+#define BEECH_FPGA_REG_3_PADDR (BEECH_BANK1_PADDR + 0x000E0000)
+#define BEECH_FPGA_REG_3_SIZE PAGE_SIZE
+
+#define BEECH_FPGA_REG_4_PADDR (BEECH_BANK1_PADDR + 0x00060000)
+#define BEECH_FPGA_REG_4_SIZE PAGE_SIZE
+
+/* FPGA Register Bits (From IBM BIOS) [ May not be valid for Beech Pass 1 ]*/
+
+#define FPGA_REG_0_FLASH_N 0x01
+#define FPGA_REG_0_FLASH_ONBD_N 0x02
+#define FPGA_REG_0_HITA_TOSH_N 0x04 /* New in Pass 2 */
+#define FPGA_REG_0_STAT_OC 0x20
+#define FPGA_REG_0_AC_SOURCE_SEL_N 0x40
+#define FPGA_REG_0_AC_ACTIVE_N 0x80
+
+#define FPGA_REG_1_USB_ACTIVE 0x01 /* New in Pass 2 */
+#define FPGA_REG_1_CLK_VARIABLE 0x02
+#define FPGA_REG_1_CLK_TEST 0x04
+#define FPGA_REG_1_CLK_SS 0x08
+#define FPGA_REG_1_EXT_IRQ_N 0x10
+#define FPGA_REG_1_SMI_MODE_N 0x20
+#define FPGA_REG_1_BATT_LOW_N 0x40
+#define FPGA_REG_1_PCMCIA_PWR_FAULT_N 0x80
+
+#define FPGA_REG_2_DEFAULT_UART1_N 0x01
+#define FPGA_REG_2_EN_1_8V_PLL_N 0x02
+#define FPGA_REG_2_PC_BUF_EN_N 0x08
+#define FPGA_REG_2_CODEC_RESET_N 0x10 /* New in Pass 2 */
+#define FPGA_REG_2_TP_JSTICK_N 0x20 /* New in Pass 2 */
+
+#define FPGA_REG_3_GAS_GAUGE_IO 0x01
+
+#define FPGA_REG_4_SDRAM_CLK3_ENAB 0x01
+#define FPGA_REG_4_SDRAM_CLK2_ENAB 0x02
+#define FPGA_REG_4_SDRAM_CLK1_ENAB 0x04
+#define FPGA_REG_4_SDRAM_CLK0_ENAB 0x08
+#define FPGA_REG_4_PCMCIA_5V 0x10 /* New in Pass 2 */
+#define FPGA_REG_4_IRQ3 0x20 /* New in Pass 2 */
+
+/* EBC Bank 2 contains the 16 MB "Linux" flash. The FPGA decodes a 32 MB
+ bank. The lower 16 MB are available for expansion devices. The upper 16 MB
+ are used for the "Linux" flash.
+
+ Partitioning information is for the benefit of the MTD driver. See
+ drivers/mtd/maps/ibm4xx.c. We currently allocate the lower 1 MB for a
+ kernel, and the other 15 MB for a filesystem.
+
+*/
+
+/* Bank 2 mappings changed between Beech Pass 1 and Pass 2 */
+
+#ifdef CONFIG_BEECH_PASS1
+#define BEECH_BIGFLASH_OFFSET 0
+#else
+#define BEECH_BIGFLASH_OFFSET (16 * 1024 * 1024)
+#endif
+
+#define BEECH_BANK2_PADDR ((uint)0xf8000000)
+#define BEECH_BANK2_EBC_SIZE EBC0_BnCR_BS_32MB
+
+#define BEECH_BIGFLASH_PADDR (BEECH_BANK2_PADDR + BEECH_BIGFLASH_OFFSET)
+#define BEECH_BIGFLASH_SIZE (16 * 1024 * 1024)
+
+#define BEECH_KERNEL_OFFSET 0
+#define BEECH_KERNEL_SIZE (1 * 1024 * 1024)
+
+#define BEECH_FREE_AREA_OFFSET BEECH_KERNEL_SIZE
+#define BEECH_FREE_AREA_SIZE (BEECH_BIGFLASH_SIZE - BEECH_KERNEL_SIZE)
+
+/* We do not currently support the internal clock mode for the UART. This
+ limits the minimum OPB frequency to just over 2X the UART oscillator
+ frequency. At OPB frequencies less than this the serial port will not
+ function due to the way that SerClk is sampled. */
+
+#define PPC4xx_SERCLK_FREQ 11059200
+#define BASE_BAUD (PPC4xx_SERCLK_FREQ / 16)
+
+#define RTC_DVBITS RTC_DVBITS_1MHZ /* 1MHz RTC */
+
+#define PPC4xx_MACHINE_NAME "IBM 405LP Beech"
+
+#define PCI_DRAM_OFFSET 0
+
+#include
+#define _IO_BASE (pccf_4xx_io_base)
+#define _ISA_MEM_BASE (pccf_4xx_mem_base)
+
+
+/*****************************************************************************
+ * Serial port definitions
+ *****************************************************************************/
+
+#ifdef CONFIG_SERIAL_MANY_PORTS
+#define RS_TABLE_SIZE 64
+#else
+#define RS_TABLE_SIZE 4
+#endif
+
+#define UART0_INT UIC_IRQ_U0
+#define UART1_INT UIC_IRQ_U1
+#define UART0_IO_BASE 0xEF600300
+#define UART1_IO_BASE 0xEF600400
+
+#define STD_UART_OP(num) \
+ { 0, BASE_BAUD, 0, UART##num##_INT, \
+ (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
+ iomem_base:(u8 *) UART##num##_IO_BASE, \
+ io_type: SERIAL_IO_MEM},
+
+#if defined(CONFIG_UART0_TTYS0)
+#define SERIAL_DEBUG_IO_BASE UART0_IO_BASE
+#define SERIAL_PORT_DFNS \
+ STD_UART_OP(0) \
+ STD_UART_OP(1)
+#endif
+
+#if defined(CONFIG_UART0_TTYS1)
+#define SERIAL_DEBUG_IO_BASE UART1_IO_BASE
+#define SERIAL_PORT_DFNS \
+ STD_UART_OP(1) \
+ STD_UART_OP(0)
+#endif
+
+/****************************************************************************
+ * Non-standard board support follows
+ ****************************************************************************/
+
+extern volatile u8 *beech_fpga_reg_0;
+extern volatile u8 *beech_fpga_reg_2;
+extern volatile u8 *beech_fpga_reg_4;
+
+extern int beech_sram_free(void *p);
+extern int ibm405lp_set_pixclk(unsigned pixclk_low, unsigned pixclk_high);
+extern void *beech_sram_alloc(size_t size);
+
+/* PM Button support */
+
+#ifdef CONFIG_405LP_PM_BUTTON
+#define IBM405LP_PM_IRQ APM0_IRQ_WUI2
+#define IBM405LP_PM_POLARITY 1
+#endif
+
+#endif /* !__ASSEMBLY__ */
+#endif /* __ASM_BEECH_H__ */
+#endif /* __KERNEL__ */
diff -urN -X bkexcl linux-2.4.22/arch/ppc/platforms/ceder.c linuxppc-2.4/arch/ppc/platforms/ceder.c
--- linux-2.4.22/arch/ppc/platforms/ceder.c 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/platforms/ceder.c 2003-03-14 20:46:44.000000000 +1100
@@ -0,0 +1,84 @@
+/*
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ * IBM NP405L ceder eval board
+ *
+ * Please read the COPYING file for all license details.
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+
+void *ceder_rtc_base;
+
+void __init
+board_setup_arch(void)
+{
+
+ bd_t *bip = (bd_t *) __res;
+
+ /* RTC step for the walnut */
+ ceder_rtc_base = (void *) CEDER_RTC_VADDR;
+ TODC_INIT(TODC_TYPE_DS1743, ceder_rtc_base, ceder_rtc_base,
+ ceder_rtc_base, 8);
+
+#ifdef CONFIG_DEBUG_BRINGUP
+ printk("\n");
+ printk("machine\t: %s\n", PPC4xx_MACHINE_NAME);
+ printk("\n");
+ printk("bi_s_version\t %s\n", bip->bi_s_version);
+ printk("bi_r_version\t %s\n", bip->bi_r_version);
+ printk("bi_memsize\t 0x%8.8x\t %dMBytes\n", bip->bi_memsize,
+ bip->bi_memsize / (1024 * 1000));
+ printk("bi_enetaddr %d\t %2.2x%2.2x%2.2x-%2.2x%2.2x%2.2x\n", 0,
+ bip->bi_enetaddr[0][0], bip->bi_enetaddr[0][1],
+ bip->bi_enetaddr[0][2], bip->bi_enetaddr[0][3],
+ bip->bi_enetaddr[0][4], bip->bi_enetaddr[0][5]);
+
+ printk("bi_enetaddr %d\t %2.2x%2.2x%2.2x-%2.2x%2.2x%2.2x\n", 1,
+ bip->bi_enetaddr[1][0], bip->bi_enetaddr[1][1],
+ bip->bi_enetaddr[1][2], bip->bi_enetaddr[1][3],
+ bip->bi_enetaddr[1][4], bip->bi_enetaddr[1][5]);
+
+ printk("bi_intfreq\t 0x%8.8x\t clock:\t %dMhz\n",
+ bip->bi_intfreq, bip->bi_intfreq / 1000000);
+
+ printk("bi_busfreq\t 0x%8.8x\t plb bus clock:\t %dMHz\n",
+ bip->bi_busfreq, bip->bi_busfreq / 1000000);
+ printk("bi_pci_busfreq\t 0x%8.8x\t pci bus clock:\t %dMHz\n",
+ bip->bi_pci_busfreq, bip->bi_pci_busfreq / 1000000);
+
+ printk("\n");
+#endif
+
+ /* Identify the system */
+ printk
+ ("IBM Ceder port (C) 2002 MontaVista Software, Inc. (source@mvista.com)\n");
+
+}
+
+void __init
+board_io_mapping(void)
+{
+ io_block_mapping(CEDER_RTC_VADDR,
+ CEDER_RTC_PADDR, CEDER_RTC_SIZE, _PAGE_IO);
+}
+
+void __init
+board_setup_irq(void)
+{
+}
+
+void __init
+board_init(void)
+{
+ ppc_md.time_init = todc_time_init;
+ ppc_md.set_rtc_time = todc_set_rtc_time;
+ ppc_md.get_rtc_time = todc_get_rtc_time;
+ ppc_md.nvram_read_val = todc_direct_read_val;
+ ppc_md.nvram_write_val = todc_direct_write_val;
+}
diff -urN -X bkexcl linux-2.4.22/arch/ppc/platforms/ceder.h linuxppc-2.4/arch/ppc/platforms/ceder.h
--- linux-2.4.22/arch/ppc/platforms/ceder.h 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/platforms/ceder.h 2003-07-25 02:00:01.000000000 +1000
@@ -0,0 +1,77 @@
+/*
+ *
+ *
+ * Copyright 2000 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * akuster@mvista.com or source@mvista.com
+ *
+ * Module name: ceder.h
+ *
+ * Description:
+ * Macros, definitions, and data structures specific to the IBM PowerPC
+ * Ceder eval board.
+ *
+ * Please read the COPYING file for all license details.
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_CEDER_H__
+#define __ASM_CEDER_H__
+#include
+
+#ifndef __ASSEMBLY__
+/*
+ * Data structure defining board information maintained by the boot
+ * ROM on IBM's "Ceder" evaluation board. An effort has been made to
+ * keep the field names consistent with the 8xx 'bd_t' board info
+ * structures.
+ */
+
+typedef struct board_info {
+ unsigned char bi_s_version[4]; /* Version of this structure */
+ unsigned char bi_r_version[30]; /* Version of the IBM ROM */
+ unsigned int bi_memsize; /* DRAM installed, in bytes */
+ unsigned char bi_enetaddr[2][6]; /* Local Ethernet MAC address */
+ unsigned char bi_pci_mac[6];
+ unsigned int bi_intfreq; /* Processor speed, in Hz */
+ unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
+ unsigned int bi_pci_busfreq; /* PCI speed in Hz */
+ unsigned int bi_opb_busfreq; /* OPB Bus speed, in Hz */
+ int bi_iic_fast[1]; /* Use fast i2c mode */
+} bd_t;
+
+/* Some 4xx parts use a different timebase frequency from the internal clock.
+*/
+#define bi_tbfreq bi_intfreq
+
+/* Memory map for the IBM "Ceder" NP405 evaluation board.
+ */
+
+extern void *ceder_rtc_base;
+#define CEDER_RTC_PADDR ((uint)0xf0000000)
+#define CEDER_RTC_VADDR CEDER_RTC_PADDR
+#define CEDER_RTC_SIZE ((uint)8*1024)
+
+
+/* Early initialization address mapping for block_io.
+ * Standard 405GP map.
+ */
+#define PPC4xx_ONB_IO_PADDR ((uint)0xef600000)
+#define PPC4xx_ONB_IO_VADDR PPC4xx_ONB_IO_PADDR
+#define PPC4xx_ONB_IO_SIZE ((uint)4*1024)
+
+
+#ifdef CONFIG_PPC405GP_INTERNAL_CLOCK
+#define BASE_BAUD 201600
+#else
+#define BASE_BAUD 691200
+#endif
+
+#define PPC4xx_MACHINE_NAME "IBM NP405L Ceder"
+
+
+
+
+#endif /* !__ASSEMBLY__ */
+#endif /* __ASM_CEDER_H__ */
+#endif /* __KERNEL__ */
diff -urN -X bkexcl linux-2.4.22/arch/ppc/platforms/cpci405.c linuxppc-2.4/arch/ppc/platforms/cpci405.c
--- linux-2.4.22/arch/ppc/platforms/cpci405.c 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/platforms/cpci405.c 2003-03-31 18:46:11.000000000 +1000
@@ -0,0 +1,141 @@
+/*
+ * arch/ppc/platforms/cpci405.c
+ *
+ * Board setup routines for the esd CPCI-405 cPCI Board.
+ *
+ * Author: Stefan Roese
+ * stefan.roese@esd-electronics.com
+ *
+ * Copyright 2001-2003 esd electronic system design - hannover germany
+ *
+ * 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.
+ *
+ * History: 11/09/2001 - armin
+ * added board_init to add in additional instuctions needed during platfrom_init
+ *
+ * : 03/26/03 - stefan
+ * Added cpci405_early_serial_map (cloned from evb405ep) to generate
+ * BASE_BAUD dynamically from the UDIV settings (configured by U-Boot).
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+void *cpci405_nvram;
+
+/*
+ * Some IRQs unique to CPCI-405.
+ */
+int __init
+ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+ static char pci_irq_table[][4] =
+ /*
+ * PCI IDSEL/INTPIN->INTLINE
+ * A B C D
+ */
+ {
+ {28, 28, 28, 28}, /* IDSEL 15 - cPCI slot 8 */
+ {29, 29, 29, 29}, /* IDSEL 16 - cPCI slot 7 */
+ {30, 30, 30, 30}, /* IDSEL 17 - cPCI slot 6 */
+ {27, 27, 27, 27}, /* IDSEL 18 - cPCI slot 5 */
+ {28, 28, 28, 28}, /* IDSEL 19 - cPCI slot 4 */
+ {29, 29, 29, 29}, /* IDSEL 20 - cPCI slot 3 */
+ {30, 30, 30, 30}, /* IDSEL 21 - cPCI slot 2 */
+ };
+ const long min_idsel = 15, max_idsel = 21, irqs_per_slot = 4;
+ return PCI_IRQ_TABLE_LOOKUP;
+};
+
+/* The serial clock for the chip is an internal clock determined by
+ * different clock speeds/dividers.
+ * Calculate the proper input baud rate and setup the serial driver.
+ */
+static void __init
+cpci405_early_serial_map(void)
+{
+ u32 uart_div;
+ int serial_baud_405;
+ bd_t *bip = (bd_t *) __res;
+ struct serial_struct serialreq = {0};
+
+ /* Calculate the serial clock input frequency
+ *
+ * The base baud is the PLL OUTA (provided in the board info
+ * structure) divided by the external UART Divisor, divided
+ * by 16.
+ */
+ uart_div = ((mfdcr(DCRN_CHCR_BASE) & CHR0_UDIV) >> 1) + 1;
+ serial_baud_405 = bip->bi_procfreq / uart_div / 16;
+
+ /* Update the serial port attributes */
+ serialreq.baud_base = serial_baud_405;
+ serialreq.flags = (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST);
+ serialreq.io_type = SERIAL_IO_MEM;
+
+ serialreq.line = 0;
+ serialreq.port = 0;
+ serialreq.irq = ACTING_UART0_INT;
+ serialreq.iomem_base = (void*)ACTING_UART0_IO_BASE;
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+ /* Configure debug serial access */
+ gen550_init(0, &serialreq);
+#endif
+
+ if (early_serial_setup(&serialreq) != 0) {
+ printk("Early serial init of port 0 failed\n");
+ }
+
+ serialreq.line = 1;
+ serialreq.port = 1;
+ serialreq.irq = ACTING_UART1_INT;
+ serialreq.iomem_base = (void*)ACTING_UART1_IO_BASE;
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+ /* Configure debug serial access */
+ gen550_init(1, &serialreq);
+#endif
+
+ if (early_serial_setup(&serialreq) != 0) {
+ printk("Early serial init of port 1 failed\n");
+ }
+}
+
+void __init
+board_setup_arch(void)
+{
+ cpci405_early_serial_map();
+ TODC_INIT(TODC_TYPE_MK48T35, cpci405_nvram, cpci405_nvram, cpci405_nvram, 8);
+}
+
+void __init
+board_io_mapping(void)
+{
+ cpci405_nvram = ioremap(CPCI405_NVRAM_PADDR, CPCI405_NVRAM_SIZE);
+}
+
+void __init
+board_setup_irq(void)
+{
+}
+
+void __init
+board_init(void)
+{
+ ppc_md.time_init = todc_time_init;
+ ppc_md.set_rtc_time = todc_set_rtc_time;
+ ppc_md.get_rtc_time = todc_get_rtc_time;
+ ppc_md.nvram_read_val = todc_direct_read_val;
+ ppc_md.nvram_write_val = todc_direct_write_val;
+}
diff -urN -X bkexcl linux-2.4.22/arch/ppc/platforms/cpci405.h linuxppc-2.4/arch/ppc/platforms/cpci405.h
--- linux-2.4.22/arch/ppc/platforms/cpci405.h 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/platforms/cpci405.h 2003-03-31 18:46:12.000000000 +1000
@@ -0,0 +1,52 @@
+/*
+ * CPCI-405 board specific definitions
+ *
+ * Copyright (c) 2001 Stefan Roese (stefan.roese@esd-electronics.com)
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_CPCI405_H__
+#define __ASM_CPCI405_H__
+
+#include
+
+/* We have a 405GP core */
+#include
+
+#include
+
+#ifndef __ASSEMBLY__
+/* Some 4xx parts use a different timebase frequency from the internal clock.
+*/
+#define bi_tbfreq bi_intfreq
+
+/* Map for the NVRAM space */
+#define CPCI405_NVRAM_PADDR ((uint)0xf0200000)
+#define CPCI405_NVRAM_SIZE ((uint)32*1024)
+
+#if defined(CONFIG_UART0_TTYS0)
+#define ACTING_UART0_IO_BASE UART0_IO_BASE
+#define ACTING_UART1_IO_BASE UART1_IO_BASE
+#define ACTING_UART0_INT UART0_INT
+#define ACTING_UART1_INT UART1_INT
+#else
+#define ACTING_UART0_IO_BASE UART1_IO_BASE
+#define ACTING_UART1_IO_BASE UART0_IO_BASE
+#define ACTING_UART0_INT UART1_INT
+#define ACTING_UART1_INT UART0_INT
+#endif
+
+/* The UART clock is based off an internal clock -
+ * define BASE_BAUD based on the internal clock and divider(s).
+ * Since BASE_BAUD must be a constant, we will initialize it
+ * using clock/divider values which U-Boot initializes
+ * for typical configurations at various CPU speeds.
+ * The base baud is calculated as (FWDA / EXT UART DIV / 16)
+ */
+#define BASE_BAUD 0
+
+#define PPC4xx_MACHINE_NAME "esd CPCI-405"
+
+#endif /* !__ASSEMBLY__ */
+#endif /* __ASM_CPCI405_H__ */
+#endif /* __KERNEL__ */
diff -urN -X bkexcl linux-2.4.22/arch/ppc/platforms/ebony.c linuxppc-2.4/arch/ppc/platforms/ebony.c
--- linux-2.4.22/arch/ppc/platforms/ebony.c 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/platforms/ebony.c 2003-07-25 02:00:01.000000000 +1000
@@ -0,0 +1,538 @@
+/*
+ * arch/ppc/platforms/ebony.c
+ *
+ * Ebony board specific routines
+ *
+ * Matt Porter
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
+extern int pckbd_getkeycode(unsigned int scancode);
+extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
+ char raw_mode);
+extern void gen550_progress(char *, unsigned short);
+extern void gen550_init(int, struct serial_struct *);
+
+/*
+ * Ebony IRQ triggering/polarity settings
+ */
+static u_char ebony_IRQ_initsenses[] __initdata = {
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 0: UART 0 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 1: UART 1 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 2: IIC 0 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 3: IIC 1 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 4: PCI Inb Mess */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 5: PCI Cmd Wrt */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 6: PCI PM */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 7: PCI MSI 0 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 8: PCI MSI 1 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 9: PCI MSI 2 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 10: MAL TX EOB */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 11: MAL RX EOB */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 12: DMA Chan 0 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 13: DMA Chan 1 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 14: DMA Chan 2 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 15: DMA Chan 3 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 16: Reserved */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 17: Reserved */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 18: GPT Timer 0 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 19: GPT Timer 1 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 20: GPT Timer 2 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 21: GPT Timer 3 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 22: GPT Timer 4 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 23: Ext Int 0 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 24: Ext Int 1 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 25: Ext Int 2 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 26: Ext Int 3 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 27: Ext Int 4 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_NEGATIVE), /* 28: Ext Int 5 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 29: Ext Int 6 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 30: UIC1 NC Int */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 31: UIC1 Crit Int */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 32: MAL SERR */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 33: MAL TXDE */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 34: MAL RXDE */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 35: ECC Unc Err */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 36: ECC Corr Err */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 37: Ext Bus Ctrl */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 38: Ext Bus Mstr */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 39: OPB->PLB */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 40: PCI MSI 3 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 41: PCI MSI 4 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 42: PCI MSI 5 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 43: PCI MSI 6 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 44: PCI MSI 7 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 45: PCI MSI 8 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 46: PCI MSI 9 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 47: PCI MSI 10 */
+ (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* 48: PCI MSI 11 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 49: PLB Perf Mon */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 50: Ext Int 7 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 51: Ext Int 8 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 52: Ext Int 9 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 53: Ext Int 10 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 54: Ext Int 11 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* 55: Ext Int 12 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 56: Ser ROM Err */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 57: Reserved */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 58: Reserved */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 59: PCI Async Err */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 60: EMAC 0 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 61: EMAC 0 WOL */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 62: EMAC 1 */
+ (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* 63: EMAC 1 WOL */
+};
+
+extern void abort(void);
+
+/* Global Variables */
+unsigned char __res[sizeof (bd_t)];
+
+static void __init
+ebony_calibrate_decr(void)
+{
+ unsigned int freq;
+
+ /*
+ * Determine system clock speed
+ *
+ * If we are on Rev. B silicon, then use
+ * default external system clock. If we are
+ * on Rev. C silicon then errata forces us to
+ * use the internal clock.
+ */
+ switch (PVR_REV(mfspr(PVR))) {
+ case PVR_REV(PVR_440GP_RB):
+ freq = EBONY_440GP_RB_SYSCLK;
+ break;
+ case PVR_REV(PVR_440GP_RC1):
+ default:
+ freq = EBONY_440GP_RC_SYSCLK;
+ break;
+ }
+
+ tb_ticks_per_jiffy = freq / HZ;
+ tb_to_us = mulhwu_scale_factor(freq, 1000000);
+
+ /* Set the time base to zero */
+ mtspr(SPRN_TBWL, 0);
+ mtspr(SPRN_TBWU, 0);
+
+ /* Clear any pending timer interrupts */
+ mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
+
+ /* Enable decrementer interrupt */
+ mtspr(SPRN_TCR, TCR_DIE);
+}
+
+static int
+ebony_show_cpuinfo(struct seq_file *m)
+{
+ seq_printf(m, "vendor\t\t: IBM\n");
+ seq_printf(m, "machine\t\t: Ebony\n");
+
+ return 0;
+}
+
+static inline int
+ebony_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+ static char pci_irq_table[][4] =
+ /*
+ * PCI IDSEL/INTPIN->INTLINE
+ * A B C D
+ */
+ {
+ { 23, 23, 23, 23 }, /* IDSEL 1 - PCI Slot 0 */
+ { 24, 24, 24, 24 }, /* IDSEL 2 - PCI Slot 1 */
+ { 25, 25, 25, 25 }, /* IDSEL 3 - PCI Slot 2 */
+ { 26, 26, 26, 26 }, /* IDSEL 4 - PCI Slot 3 */
+ };
+
+ const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
+ return PCI_IRQ_TABLE_LOOKUP;
+}
+
+#define PCIX_WRITEL(value, offset) \
+ (writel(value, (u32)pcix_reg_base+offset))
+
+/*
+ * FIXME: This is only here to "make it work". This will move
+ * to a ibm_pcix.c which will contain a generic IBM PCIX bridge
+ * configuration library. -Matt
+ */
+static void __init
+ebony_setup_pcix(void)
+{
+ void *pcix_reg_base;
+
+ pcix_reg_base = ioremap64(PCIX0_REG_BASE, PCIX0_REG_SIZE);
+
+ /* Disable all windows */
+ PCIX_WRITEL(0, PCIX0_POM0SA);
+ PCIX_WRITEL(0, PCIX0_POM1SA);
+ PCIX_WRITEL(0, PCIX0_POM2SA);
+ PCIX_WRITEL(0, PCIX0_PIM0SA);
+ PCIX_WRITEL(0, PCIX0_PIM1SA);
+ PCIX_WRITEL(0, PCIX0_PIM2SA);
+
+ /* Setup 2GB PLB->PCI outbound mem window (3_8000_0000->0_8000_0000) */
+ PCIX_WRITEL(0x00000003, PCIX0_POM0LAH);
+ PCIX_WRITEL(0x80000000, PCIX0_POM0LAL);
+ PCIX_WRITEL(0x00000000, PCIX0_POM0PCIAH);
+ PCIX_WRITEL(0x80000000, PCIX0_POM0PCIAL);
+ PCIX_WRITEL(0x80000001, PCIX0_POM0SA);
+
+ /* Setup 2GB PCI->PLB inbound memory window at 0, enable MSIs */
+ PCIX_WRITEL(0x00000000, PCIX0_PIM0LAH);
+ PCIX_WRITEL(0x00000000, PCIX0_PIM0LAL);
+ PCIX_WRITEL(0x80000007, PCIX0_PIM0SA);
+
+ eieio();
+}
+
+static void __init
+ebony_setup_hose(void)
+{
+ struct pci_controller *hose;
+
+ /* Configure windows on the PCI-X host bridge */
+ ebony_setup_pcix();
+
+ hose = pcibios_alloc_controller();
+
+ if (!hose)
+ return;
+
+ hose->first_busno = 0;
+ hose->last_busno = 0xff;
+
+ hose->pci_mem_offset = EBONY_PCI_MEM_OFFSET;
+
+ pci_init_resource(&hose->io_resource,
+ EBONY_PCI_LOWER_IO,
+ EBONY_PCI_UPPER_IO,
+ IORESOURCE_IO,
+ "PCI host bridge");
+
+ pci_init_resource(&hose->mem_resources[0],
+ EBONY_PCI_LOWER_MEM,
+ EBONY_PCI_UPPER_MEM,
+ IORESOURCE_MEM,
+ "PCI host bridge");
+
+ hose->io_space.start = EBONY_PCI_LOWER_IO;
+ hose->io_space.end = EBONY_PCI_UPPER_IO;
+ hose->mem_space.start = EBONY_PCI_LOWER_MEM;
+ hose->mem_space.end = EBONY_PCI_UPPER_MEM;
+ isa_io_base =
+ (unsigned long)ioremap64(EBONY_PCI_IO_BASE, EBONY_PCI_IO_SIZE);
+ hose->io_base_virt = (void *)isa_io_base;
+
+ setup_indirect_pci(hose,
+ EBONY_PCI_CFGA_PLB32,
+ EBONY_PCI_CFGD_PLB32);
+ hose->set_cfg_type = 1;
+
+ hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
+
+ ppc_md.pci_swizzle = common_swizzle;
+ ppc_md.pci_map_irq = ebony_map_irq;
+}
+
+TODC_ALLOC();
+
+static void __init
+ebony_early_serial_map(void)
+{
+ struct serial_struct serial_req;
+
+ /* Setup ioremapped serial port access */
+ memset(&serial_req, 0, sizeof(serial_req));
+ serial_req.line = 0;
+ serial_req.baud_base = BASE_BAUD;
+ serial_req.port = 0;
+ serial_req.irq = 0;
+ serial_req.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+ serial_req.io_type = SERIAL_IO_MEM;
+ serial_req.iomem_base = ioremap64(PPC440GP_UART0_ADDR, 8);
+ serial_req.iomem_reg_shift = 0;
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+ /* Configure debug serial access */
+ gen550_init(0, &serial_req);
+#endif
+
+ if (early_serial_setup(&serial_req) != 0) {
+ printk("Early serial init of port 0 failed\n");
+ }
+
+ /* Assume early_serial_setup() doesn't modify serial_req */
+ serial_req.line = 1;
+ serial_req.port = 1;
+ serial_req.irq = 1;
+ serial_req.iomem_base = ioremap64(PPC440GP_UART1_ADDR, 8);
+
+#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB)
+ /* Configure debug serial access */
+ gen550_init(1, &serial_req);
+#endif
+
+ if (early_serial_setup(&serial_req) != 0) {
+ printk("Early serial init of port 1 failed\n");
+ }
+}
+
+static void __init
+ebony_setup_arch(void)
+{
+ bd_t *bip = (bd_t *)__res;
+ unsigned char * vpd_base;
+ struct ibm440gp_clocks clocks;
+
+#if !defined(CONFIG_BDI_SWITCH)
+ /*
+ * The Abatron BDI JTAG debugger does not tolerate others
+ * mucking with the debug registers.
+ */
+ mtspr(SPRN_DBCR0, (DBCR0_TDE | DBCR0_IDM));
+#endif
+
+ /* Retrieve MAC addresses */
+ vpd_base = ioremap64(EBONY_VPD_BASE, EBONY_VPD_SIZE);
+ memcpy(bip->bi_enetaddr[0],EBONY_NA0_ADDR(vpd_base),6);
+ memcpy(bip->bi_enetaddr[1],EBONY_NA1_ADDR(vpd_base),6);
+
+ /*
+ * Determine various clocks.
+ * To be completely correct we should get SysClk
+ * from FPGA, because it can be changed by on-board switches
+ * --ebs
+ */
+ ibm440gp_get_clocks(&clocks, 33333333, 6 * 1843200);
+ bip->bi_opb_busfreq = clocks.opb;
+
+ /* Use IIC in standard (100 kHz) mode */
+ bip->bi_iic_fast[0] = bip->bi_iic_fast[1] = 0;
+
+#ifdef CONFIG_PPC_RTC
+ /* Setup TODC access */
+ TODC_INIT(TODC_TYPE_DS1743,
+ 0,
+ 0,
+ ioremap64(EBONY_RTC_ADDR, EBONY_RTC_SIZE),
+ 8);
+#endif /* CONFIG_PPC_RTC */
+
+ /* init to some ~sane value until calibrate_delay() runs */
+ loops_per_jiffy = 50000000/HZ;
+
+ /* Setup PCI host bridge */
+ ebony_setup_hose();
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_start)
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */
+ else
+#endif
+#ifdef CONFIG_ROOT_NFS
+ ROOT_DEV = to_kdev_t(0x00FF); /* /dev/nfs pseudo device */
+#else
+ ROOT_DEV = to_kdev_t(0x1601); /* /dev/hdc1 */
+#endif
+
+#ifdef CONFIG_DUMMY_CONSOLE
+ conswitchp = &dummy_con;
+#endif
+
+ ebony_early_serial_map();
+
+ ibm4xxPIC_InitSenses = ebony_IRQ_initsenses;
+ ibm4xxPIC_NumInitSenses = sizeof(ebony_IRQ_initsenses);
+
+ /* Identify the system */
+ printk("IBM Ebony port (C) 2002 MontaVista Software, Inc. (source@mvista.com)\n");
+}
+
+static void
+ebony_restart(char *cmd)
+{
+ __cli();
+ abort();
+}
+
+static void
+ebony_power_off(void)
+{
+ __cli();
+ for(;;);
+}
+
+static void
+ebony_halt(void)
+{
+ __cli();
+ for(;;);
+}
+
+/*
+ * Read the 440GP memory controller to get size of system memory.
+ */
+static unsigned long __init
+ebony_find_end_of_memory(void)
+{
+ u32 i, bank_config;
+ u32 mem_size = 0;
+
+ for (i=0; i<4; i++)
+ {
+ switch (i)
+ {
+ case 0:
+ mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B0CR);
+ break;
+ case 1:
+ mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B1CR);
+ break;
+ case 2:
+ mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B2CR);
+ break;
+ case 3:
+ mtdcr(DCRN_SDRAM0_CFGADDR, SDRAM0_B3CR);
+ break;
+ }
+
+ bank_config = mfdcr(DCRN_SDRAM0_CFGDATA);
+
+ if (!(bank_config & SDRAM_CONFIG_BANK_ENABLE))
+ continue;
+ switch (SDRAM_CONFIG_BANK_SIZE(bank_config))
+ {
+ case SDRAM_CONFIG_SIZE_8M:
+ mem_size += PPC440_MEM_SIZE_8M;
+ break;
+ case SDRAM_CONFIG_SIZE_16M:
+ mem_size += PPC440_MEM_SIZE_16M;
+ break;
+ case SDRAM_CONFIG_SIZE_32M:
+ mem_size += PPC440_MEM_SIZE_32M;
+ break;
+ case SDRAM_CONFIG_SIZE_64M:
+ mem_size += PPC440_MEM_SIZE_64M;
+ break;
+ case SDRAM_CONFIG_SIZE_128M:
+ mem_size += PPC440_MEM_SIZE_128M;
+ break;
+ case SDRAM_CONFIG_SIZE_256M:
+ mem_size += PPC440_MEM_SIZE_256M;
+ break;
+ case SDRAM_CONFIG_SIZE_512M:
+ mem_size += PPC440_MEM_SIZE_512M;
+ break;
+ }
+ }
+ return mem_size;
+}
+
+static void __init
+ebony_init_irq(void)
+{
+ int i;
+
+ ppc4xx_pic_init();
+
+ for (i = 0; i < NR_IRQS; i++)
+ irq_desc[i].handler = ppc4xx_pic;
+}
+
+void __init platform_init(unsigned long r3, unsigned long r4,
+ unsigned long r5, unsigned long r6, unsigned long r7)
+{
+ parse_bootinfo((struct bi_record *) (r3 + KERNELBASE));
+
+ ppc_md.setup_arch = ebony_setup_arch;
+ ppc_md.show_cpuinfo = ebony_show_cpuinfo;
+ ppc_md.init_IRQ = ebony_init_irq;
+ ppc_md.get_irq = NULL; /* Set in ppc4xx_pic_init() */
+
+ ppc_md.find_end_of_memory = ebony_find_end_of_memory;
+ ppc_md.setup_io_mappings = NULL;
+
+ ppc_md.restart = ebony_restart;
+ ppc_md.power_off = ebony_power_off;
+ ppc_md.halt = ebony_halt;
+
+ ppc_md.calibrate_decr = ebony_calibrate_decr;
+#ifdef CONFIG_PPC_RTC
+ ppc_md.time_init = todc_time_init;
+ ppc_md.set_rtc_time = todc_set_rtc_time;
+ ppc_md.get_rtc_time = todc_get_rtc_time;
+
+ ppc_md.nvram_read_val = todc_direct_read_val;
+ ppc_md.nvram_write_val = todc_direct_write_val;
+#endif /* CONFIG_PPC_RTC */
+
+#ifdef CONFIG_SERIAL_TEXT_DEBUG
+ ppc_md.progress = gen550_progress;
+#endif /* CONFIG_SERIAL_TEXT_DEBUG */
+#ifdef CONFIG_KGDB
+ ppc_md.early_serial_map = ebony_early_serial_map;
+#endif
+#ifdef CONFIG_VT
+ /* USB keyboard support */
+ ppc_md.kbd_setkeycode = pckbd_setkeycode;
+ ppc_md.kbd_getkeycode = pckbd_getkeycode;
+ ppc_md.kbd_translate = pckbd_translate;
+#endif
+
+ /*
+ * Fill PHY id map, actually, default settings will do just
+ * fine, provided that emac_probe is called for EMAC0 and
+ * _then_ for EMAC1. I added it as an example. -ebs
+ *
+ * This mapping corresponds to the Ebony factory configuration (RMII):
+ * J33 2-3, J40 1-2, J34 2-3, J77 1-2
+ * EMAC0 <-> PHY 0x8
+ * EMAC1 <-> PHY 0x9
+ */
+ emac_phy_map[0] = ~(1 << 8);
+ emac_phy_map[1] = ~(1 << 9);
+}
diff -urN -X bkexcl linux-2.4.22/arch/ppc/platforms/ebony.h linuxppc-2.4/arch/ppc/platforms/ebony.h
--- linux-2.4.22/arch/ppc/platforms/ebony.h 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/platforms/ebony.h 2003-04-18 12:42:42.000000000 +1000
@@ -0,0 +1,106 @@
+/*
+ * arch/ppc/platforms/ebony.h
+ *
+ * Ebony board definitions
+ *
+ * Matt Porter
+ *
+ * Copyright 2002 MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * 05/07/02 - Armin
+ * removed IIC_PORT_DFNS
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_EBONY_H__
+#define __ASM_EBONY_H__
+
+#include
+#include
+
+/* F/W TLB mapping used in bootloader glue to reset EMAC */
+#define EBONY_EMAC0_MR0 0xE0000800
+
+/* Macros to get at Ebony VPD info */
+#define EBONY_VPD_BASE 0x00000001fffffe00
+#define EBONY_VPD_SIZE 0x24
+#define EBONY_NA0_OFFSET 0x0c
+#define EBONY_NA1_OFFSET 0x18
+#define EBONY_NA0_ADDR(base) (base + EBONY_NA0_OFFSET)
+#define EBONY_NA1_ADDR(base) (base + EBONY_NA1_OFFSET)
+
+/* Default clock rates for Rev. B and Rev. C silicon */
+#define EBONY_440GP_RB_SYSCLK 33000000
+#define EBONY_440GP_RC_SYSCLK 400000000
+
+/* RTC/NVRAM location */
+#define EBONY_RTC_ADDR 0x0000000148000000
+#define EBONY_RTC_SIZE 0x2000
+
+/* Flash */
+#define EBONY_FPGA_ADDR 0x0000000148300000
+#define EBONY_BOOT_SMALL_FLASH(x) (x & 0x20)
+#define EBONY_ONBRD_FLASH_EN(x) (x & 0x02)
+#define EBONY_FLASH_SEL(x) (x & 0x01)
+#define EBONY_SMALL_FLASH_LOW1 0x00000001ff800000
+#define EBONY_SMALL_FLASH_LOW2 0x00000001ff880000
+#define EBONY_SMALL_FLASH_HIGH1 0x00000001fff00000
+#define EBONY_SMALL_FLASH_HIGH2 0x00000001fff80000
+#define EBONY_SMALL_FLASH_SIZE 0x80000
+#define EBONY_LARGE_FLASH_LOW 0x00000001ff800000
+#define EBONY_LARGE_FLASH_HIGH 0x00000001ffc00000
+#define EBONY_LARGE_FLASH_SIZE 0x400000
+
+#define EBONY_SMALL_FLASH_BASE 0x00000001fff80000
+#define EBONY_LARGE_FLASH_BASE 0x00000001ff800000
+
+/*
+ * Serial port defines
+ */
+#define RS_TABLE_SIZE 2
+
+/* OpenBIOS defined UART mappings, used before early_serial_setup */
+#define UART0_IO_BASE (u8 *) 0xE0000200
+#define UART1_IO_BASE (u8 *) 0xE0000300
+
+#define BASE_BAUD 33000000/3/16
+#define UART0_INT 0
+#define UART1_INT 1
+
+#define STD_UART_OP(num) \
+ { 0, BASE_BAUD, 0, UART##num##_INT, \
+ (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST), \
+ iomem_base: UART##num##_IO_BASE, \
+ io_type: SERIAL_IO_MEM},
+
+#define SERIAL_PORT_DFNS \
+ STD_UART_OP(0) \
+ STD_UART_OP(1)
+
+/* USB keyboard support */
+#define kbd_read_input() 0
+#define kbd_read_status() 0
+#define kbd_write_output(val) {}
+#define kbd_write_command(val) {}
+
+/* PCI support */
+#define EBONY_PCI_LOWER_IO 0x00000000
+#define EBONY_PCI_UPPER_IO 0x0000ffff
+#define EBONY_PCI_LOWER_MEM 0x80002000
+#define EBONY_PCI_UPPER_MEM 0xffffefff
+
+#define EBONY_PCI_CFGREGS_BASE 0x000000020ec00000
+#define EBONY_PCI_CFGA_PLB32 0x0ec00000
+#define EBONY_PCI_CFGD_PLB32 0x0ec00004
+
+#define EBONY_PCI_IO_BASE 0x0000000208000000
+#define EBONY_PCI_IO_SIZE 0x00010000
+#define EBONY_PCI_MEM_OFFSET 0x00000000
+
+#endif /* __ASM_EBONY_H__ */
+#endif /* __KERNEL__ */
diff -urN -X bkexcl linux-2.4.22/arch/ppc/platforms/ep405.c linuxppc-2.4/arch/ppc/platforms/ep405.c
--- linux-2.4.22/arch/ppc/platforms/ep405.c 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/platforms/ep405.c 2003-03-14 20:46:44.000000000 +1100
@@ -0,0 +1,194 @@
+/*
+ * BK Id: %F% %I% %G% %U% %#%
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ *
+ *
+ * Not much needed for the Embedded Planet 405gp board
+ *
+ * History: 11/09/2001 - armin
+ * added board_init to add in additional instuctions needed during platfrom_init
+ * cleaned up map_irq.
+ *
+ * 1/22/2002 - Armin
+ * converted pci to ocp
+ *
+ * Please read the COPYING file for all license details.
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+u8 *ep405_bcsr;
+u8 *ep405_nvram;
+
+static struct {
+ u8 cpld_xirq_select;
+ int pci_idsel;
+ int irq;
+} ep405_devtable[] = {
+#ifdef CONFIG_EP405PC
+ {0x07, 0x0E, 25}, /* EP405PC: USB */
+#endif
+};
+#define EP405_DEVTABLE_SIZE (sizeof(ep405_devtable)/sizeof(ep405_devtable[0]))
+
+int __init
+ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+ int i;
+
+ /* AFAICT this is only called a few times during PCI setup, so
+ performance is not critical */
+ for (i = 0; i < EP405_DEVTABLE_SIZE; i++) {
+ if (idsel == ep405_devtable[i].pci_idsel)
+ return ep405_devtable[i].irq;
+ }
+ return -1;
+};
+
+void __init
+board_setup_arch(void)
+{
+ bd_t *bip = (bd_t *) __res;
+
+ if (bip->bi_nvramsize == 512*1024) {
+ /* FIXME: we should properly handle NVRTCs of different sizes */
+ TODC_INIT(TODC_TYPE_DS1557, ep405_nvram, ep405_nvram, ep405_nvram, 8);
+ }
+}
+
+void __init
+bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
+{
+ unsigned int bar_response, bar;
+ /*
+ * Expected PCI mapping:
+ *
+ * PLB addr PCI memory addr
+ * --------------------- ---------------------
+ * 0000'0000 - 7fff'ffff <--- 0000'0000 - 7fff'ffff
+ * 8000'0000 - Bfff'ffff ---> 8000'0000 - Bfff'ffff
+ *
+ * PLB addr PCI io addr
+ * --------------------- ---------------------
+ * e800'0000 - e800'ffff ---> 0000'0000 - 0001'0000
+ *
+ */
+
+ /* Disable region zero first */
+ out_le32((void *) &(pcip->pmm[0].ma), 0x00000000);
+ /* PLB starting addr, PCI: 0x80000000 */
+ out_le32((void *) &(pcip->pmm[0].la), 0x80000000);
+ /* PCI start addr, 0x80000000 */
+ out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE);
+ /* 512MB range of PLB to PCI */
+ out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000);
+ /* Enable no pre-fetch, enable region */
+ out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff -
+ (PPC405_PCI_UPPER_MEM -
+ PPC405_PCI_MEM_BASE)) | 0x01));
+
+ /* Disable region one */
+ out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
+ out_le32((void *) &(pcip->pmm[1].la), 0x00000000);
+ out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000);
+ out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000);
+ out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
+ out_le32((void *) &(pcip->ptm1ms), 0x00000000);
+
+ /* Disable region two */
+ out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
+ out_le32((void *) &(pcip->pmm[2].la), 0x00000000);
+ out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000);
+ out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000);
+ out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
+ out_le32((void *) &(pcip->ptm2ms), 0x00000000);
+
+ /* Configure PTM (PCI->PLB) region 1 */
+ out_le32((void *) &(pcip->ptm1la), 0x00000000); /* PLB base address */
+ /* Disable PTM region 2 */
+ out_le32((void *) &(pcip->ptm2ms), 0x00000000);
+
+ /* Zero config bars */
+ for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) {
+ early_write_config_dword(hose, hose->first_busno,
+ PCI_FUNC(hose->first_busno), bar,
+ 0x00000000);
+ early_read_config_dword(hose, hose->first_busno,
+ PCI_FUNC(hose->first_busno), bar,
+ &bar_response);
+ DBG("BUS %d, device %d, Function %d bar 0x%8.8x is 0x%8.8x\n",
+ hose->first_busno, PCI_SLOT(hose->first_busno),
+ PCI_FUNC(hose->first_busno), bar, bar_response);
+ }
+ /* end work arround */
+}
+
+void __init
+board_io_mapping(void)
+{
+ bd_t *bip = (bd_t *) __res;
+
+ ep405_bcsr = ioremap(EP405_BCSR_PADDR, EP405_BCSR_SIZE);
+
+ if (bip->bi_nvramsize > 0) {
+ ep405_nvram = ioremap(EP405_NVRAM_PADDR, bip->bi_nvramsize);
+ }
+}
+
+void __init
+board_setup_irq(void)
+{
+ int i;
+
+ /* Workaround for a bug in the firmware it incorrectly sets
+ the IRQ polarities for XIRQ0 and XIRQ1 */
+ mtdcr(DCRN_UIC_PR(DCRN_UIC0_BASE), 0xffffff80); /* set the polarity */
+ mtdcr(DCRN_UIC_SR(DCRN_UIC0_BASE), 0x00000060); /* clear bogus interrupts */
+
+ /* Activate the XIRQs from the CPLD */
+ writeb(0xf0, ep405_bcsr+10);
+
+ /* Set up IRQ routing */
+ for (i = 0; i < EP405_DEVTABLE_SIZE; i++) {
+ if ( (ep405_devtable[i].irq >= 25)
+ && (ep405_devtable[i].irq) <= 31) {
+ writeb(ep405_devtable[i].cpld_xirq_select, ep405_bcsr+5);
+ writeb(ep405_devtable[i].irq - 25, ep405_bcsr+6);
+ }
+ }
+}
+
+void __init
+board_init(void)
+{
+ bd_t *bip = (bd_t *) __res;
+
+#ifdef CONFIG_PPC_RTC
+ /* FIXME: we should be able to access the NVRAM even if PPC_RTC is not configured */
+ ppc_md.nvram_read_val = todc_direct_read_val;
+ ppc_md.nvram_write_val = todc_direct_write_val;
+
+ if (bip->bi_nvramsize == 512*1024) {
+ ppc_md.time_init = todc_time_init;
+ ppc_md.set_rtc_time = todc_set_rtc_time;
+ ppc_md.get_rtc_time = todc_get_rtc_time;
+ } else {
+ printk("EP405: NVRTC size is not 512k (not a DS1557). Not sure what to do with it\n");
+ }
+
+#endif
+}
diff -urN -X bkexcl linux-2.4.22/arch/ppc/platforms/ep405.h linuxppc-2.4/arch/ppc/platforms/ep405.h
--- linux-2.4.22/arch/ppc/platforms/ep405.h 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/platforms/ep405.h 2003-07-25 02:00:01.000000000 +1000
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000 MontaVista Software Inc.
+ * http://www.mvista.com
+ *
+ *
+ * Embedded Planet 405GP board
+ * http://www.embeddedplanet.com
+ *
+ * Please read the COPYING file for all license details.
+ */
+
+#ifdef __KERNEL__
+#ifndef __ASM_EP405_H__
+#define __ASM_EP405_H__
+
+/* We have a 405GP core */
+#include
+
+#ifndef __ASSEMBLY__
+typedef struct board_info {
+ unsigned int bi_memsize; /* DRAM installed, in bytes */
+ unsigned char bi_enetaddr[6]; /* Local Ethernet MAC address */
+ unsigned int bi_intfreq; /* Processor speed, in Hz */
+ unsigned int bi_busfreq; /* PLB Bus speed, in Hz */
+ unsigned int bi_pci_busfreq; /* PCI Bus speed, in Hz */
+ unsigned int bi_nvramsize; /* Size of the NVRAM/RTC */
+ unsigned int bi_opb_busfreq; /* OPB Bus speed, in Hz */
+ int bi_iic_fast[1]; /* Use fast i2c mode */
+} bd_t;
+
+/* Some 4xx parts use a different timebase frequency from the internal clock.
+*/
+#define bi_tbfreq bi_intfreq
+
+extern u8 *ep405_bcsr;
+extern u8 *ep405_nvram;
+
+/* Map for the BCSR and NVRAM space */
+#define EP405_BCSR_PADDR ((uint)0xf4000000)
+#define EP405_BCSR_SIZE ((uint)16)
+#define EP405_NVRAM_PADDR ((uint)0xf4200000)
+
+/* serial defines */
+#define BASE_BAUD 399193
+
+#define PPC4xx_MACHINE_NAME "Embedded Planet 405GP"
+
+#endif /* !__ASSEMBLY__ */
+#endif /* __ASM_EP405_H__ */
+#endif /* __KERNEL__ */
diff -urN -X bkexcl linux-2.4.22/arch/ppc/platforms/evb405ep.c linuxppc-2.4/arch/ppc/platforms/evb405ep.c
--- linux-2.4.22/arch/ppc/platforms/evb405ep.c 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/platforms/evb405ep.c 2003-03-14 20:46:44.000000000 +1100
@@ -0,0 +1,276 @@
+/*
+ * arch/ppc/platforms/evb405ep.c
+ *
+ * Support for IBM PPC 405EP evaluation board ("Elvis").
+ *
+ * Author: SAW (IBM), derived from walnut.c.
+ * Maintained by MontaVista Software
+ *
+ * 2003 (c) MontaVista Softare Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef CONFIG_PPC_RTC
+#include
+#endif
+
+#include
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+
+void *evb405ep_rtc_base;
+
+/* Some IRQs unique to the board
+ * Used by the generic 405 PCI setup functions in ppc4xx_pci.c
+ */
+int __init
+ppc405_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+ static char pci_irq_table[][4] =
+ /*
+ * PCI IDSEL/INTPIN->INTLINE
+ * A B C D
+ */
+ {
+ {28, 28, 28, 28}, /* IDSEL 1 - PCI slot 1 */
+ {29, 29, 29, 29}, /* IDSEL 2 - PCI slot 2 */
+ {30, 30, 30, 30}, /* IDSEL 3 - PCI slot 3 */
+ {31, 31, 31, 31}, /* IDSEL 4 - PCI slot 4 */
+ };
+
+ const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4;
+ return PCI_IRQ_TABLE_LOOKUP;
+};
+
+/* The serial clock for the chip is an internal clock determined by
+ * different clock speeds/dividers.
+ * Calculate the proper input baud rate and setup the serial driver.
+ */
+void __init
+setup_serial(void)
+{
+
+ u32 uart_div;
+ int serial_baud_405ep;
+ bd_t *bip = (bd_t *) __res;
+ struct serial_struct serialreq = {0};
+
+ /* Calculate the serial clock input frequency
+ *
+ * The base baud is the PLL OUTA (provided in the board info
+ * structure) divided by the external UART Divisor, divided
+ * by 16.
+ */
+ uart_div = (mfdcr(DCRN_CPC0_UCR_BASE) & DCRN_CPC0_UCR_U0DIV);
+ serial_baud_405ep = bip->bi_pllouta_freq / uart_div / 16;
+
+
+ /* Update the serial port attributes */
+ serialreq.baud_base = serial_baud_405ep;
+ serialreq.flags = (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST);
+ serialreq.io_type = SERIAL_IO_MEM;
+
+ serialreq.line = 0;
+ serialreq.port = 0;
+ serialreq.irq = ACTING_UART0_INT;
+ serialreq.iomem_base = (void*)ACTING_UART0_IO_BASE;
+
+ if (early_serial_setup(&serialreq) != 0) {
+ printk("Early serial init of port 0 failed\n");
+ }
+
+ serialreq.line = 1;
+ serialreq.port = 1;
+ serialreq.irq = ACTING_UART1_INT;
+ serialreq.iomem_base = (void*)ACTING_UART1_IO_BASE;
+
+ if (early_serial_setup(&serialreq) != 0) {
+ printk("Early serial init of port 1 failed\n");
+ }
+}
+
+
+void __init
+board_setup_arch(void)
+{
+#define EVB405EP_FPGA_BASE 0xF0300000
+
+ void *fpga_reg0;
+ void *fpga_reg1;
+
+ setup_serial();
+ fpga_reg0 = ioremap(EVB405EP_FPGA_BASE, 8);
+ if (!fpga_reg0) {
+ printk(KERN_CRIT
+ "evb405ep_setup_arch() fpga_reg0 ioremap failed\n");
+ return;
+ }
+
+ fpga_reg1 = fpga_reg0 + 1;
+
+#ifdef CONFIG_PPC_RTC
+ /* RTC step for the evb405ep */
+ evb405ep_rtc_base = (void *) EVB405EP_RTC_VADDR;
+ TODC_INIT(TODC_TYPE_DS1743, evb405ep_rtc_base, evb405ep_rtc_base,
+ evb405ep_rtc_base, 8);
+#endif /* CONFIG_PPC_RTC */
+ /* Identify the system */
+ printk("IBM 405EP Evaluation Board port (C) 2003 MontaVista Software, Inc. (source@mvista.com)\n");
+
+
+}
+
+void __init
+bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
+{
+
+ unsigned int bar_response, bar;
+ /*
+ * Expected PCI mapping:
+ *
+ * PLB addr PCI memory addr
+ * --------------------- ---------------------
+ * 0000'0000 - 7fff'ffff <--- 0000'0000 - 7fff'ffff
+ * 8000'0000 - Bfff'ffff ---> 8000'0000 - Bfff'ffff
+ *
+ * PLB addr PCI io addr
+ * --------------------- ---------------------
+ * e800'0000 - e800'ffff ---> 0000'0000 - 0001'0000
+ *
+ * The following code is simplified by assuming that the bootrom
+ * has been well behaved in following this mapping.
+ */
+
+#ifdef DEBUG
+ int i;
+
+ printk("ioremap PCLIO_BASE = 0x%x\n", pcip);
+ printk("PCI bridge regs before fixup \n");
+ for (i = 0; i <= 3; i++) {
+ printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma)));
+ printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la)));
+ printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila)));
+ printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha)));
+ }
+ printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms)));
+ printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la)));
+ printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms)));
+ printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la)));
+
+#endif
+
+ /* added for IBM boot rom version 1.15 bios bar changes -AK */
+
+ /* Disable region first */
+ out_le32((void *) &(pcip->pmm[0].ma), 0x00000000);
+ /* PLB starting addr, PCI: 0x80000000 */
+ out_le32((void *) &(pcip->pmm[0].la), 0x80000000);
+ /* PCI start addr, 0x80000000 */
+ out_le32((void *) &(pcip->pmm[0].pcila), PPC405_PCI_MEM_BASE);
+ /* 512MB range of PLB to PCI */
+ out_le32((void *) &(pcip->pmm[0].pciha), 0x00000000);
+ /* Enable no pre-fetch, enable region */
+ out_le32((void *) &(pcip->pmm[0].ma), ((0xffffffff -
+ (PPC405_PCI_UPPER_MEM -
+ PPC405_PCI_MEM_BASE)) | 0x01));
+
+ /* Disable region one */
+ out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
+ out_le32((void *) &(pcip->pmm[1].la), 0x00000000);
+ out_le32((void *) &(pcip->pmm[1].pcila), 0x00000000);
+ out_le32((void *) &(pcip->pmm[1].pciha), 0x00000000);
+ out_le32((void *) &(pcip->pmm[1].ma), 0x00000000);
+ out_le32((void *) &(pcip->ptm1ms), 0x00000001);
+
+ /* Disable region two */
+ out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
+ out_le32((void *) &(pcip->pmm[2].la), 0x00000000);
+ out_le32((void *) &(pcip->pmm[2].pcila), 0x00000000);
+ out_le32((void *) &(pcip->pmm[2].pciha), 0x00000000);
+ out_le32((void *) &(pcip->pmm[2].ma), 0x00000000);
+ out_le32((void *) &(pcip->ptm2ms), 0x00000000);
+ out_le32((void *) &(pcip->ptm2la), 0x00000000);
+
+ /* Zero config bars */
+ for (bar = PCI_BASE_ADDRESS_1; bar <= PCI_BASE_ADDRESS_2; bar += 4) {
+ early_write_config_dword(hose, hose->first_busno,
+ PCI_FUNC(hose->first_busno), bar,
+ 0x00000000);
+ early_read_config_dword(hose, hose->first_busno,
+ PCI_FUNC(hose->first_busno), bar,
+ &bar_response);
+ DBG("BUS %d, device %d, Function %d bar 0x%8.8x is 0x%8.8x\n",
+ hose->first_busno, PCI_SLOT(hose->first_busno),
+ PCI_FUNC(hose->first_busno), bar, bar_response);
+ }
+ /* end work arround */
+
+#ifdef DEBUG
+ printk("PCI bridge regs after fixup \n");
+ for (i = 0; i <= 3; i++) {
+ printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].ma)));
+ printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].la)));
+ printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pcila)));
+ printk(" pmm%dma\t0x%x\n", i, in_le32(&(pcip->pmm[i].pciha)));
+ }
+ printk(" ptm1ms\t0x%x\n", in_le32(&(pcip->ptm1ms)));
+ printk(" ptm1la\t0x%x\n", in_le32(&(pcip->ptm1la)));
+ printk(" ptm2ms\t0x%x\n", in_le32(&(pcip->ptm2ms)));
+ printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la)));
+
+#endif
+}
+
+void __init
+board_io_mapping(void)
+{
+ io_block_mapping(EVB405EP_RTC_VADDR,
+ EVB405EP_RTC_PADDR, EVB405EP_RTC_SIZE, _PAGE_IO);
+}
+
+void __init
+board_setup_irq(void)
+{
+}
+
+void __init
+board_init(void)
+{
+#ifdef CONFIG_PPC_RTC
+ ppc_md.time_init = todc_time_init;
+ ppc_md.set_rtc_time = todc_set_rtc_time;
+ ppc_md.get_rtc_time = todc_get_rtc_time;
+ ppc_md.nvram_read_val = todc_direct_read_val;
+ ppc_md.nvram_write_val = todc_direct_write_val;
+#endif
+}
diff -urN -X bkexcl linux-2.4.22/arch/ppc/platforms/evb405ep.h linuxppc-2.4/arch/ppc/platforms/evb405ep.h
--- linux-2.4.22/arch/ppc/platforms/evb405ep.h 1970-01-01 10:00:00.000000000 +1000
+++ linuxppc-2.4/arch/ppc/platforms/evb405ep.h 2003-07-25 02:00:01.000000000 +1000
@@ -0,0 +1,72 @@
+/*
+ * arch/ppc/platforms/evb405ep.h
+ *
+ * Support for IBM PPC 405EP evaluation board ("Elvis").
+ *
+ * Author: SAW (IBM), derived from walnut.h.
+ * Maintained by MontaVista Software