summaryrefslogtreecommitdiffstats
path: root/include/asm-m68k
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-m68k')
-rw-r--r--include/asm-m68k/amigahw.h2
-rw-r--r--include/asm-m68k/apollodma.h248
-rw-r--r--include/asm-m68k/apollohw.h54
-rw-r--r--include/asm-m68k/bootinfo.h32
-rw-r--r--include/asm-m68k/bvme6000hw.h1
-rw-r--r--include/asm-m68k/cache.h12
-rw-r--r--include/asm-m68k/div64.h35
-rw-r--r--include/asm-m68k/dma.h13
-rw-r--r--include/asm-m68k/entry.h10
-rw-r--r--include/asm-m68k/fcntl.h2
-rw-r--r--include/asm-m68k/hardirq.h4
-rw-r--r--include/asm-m68k/mmu_context.h1
-rw-r--r--include/asm-m68k/movs.h28
-rw-r--r--include/asm-m68k/mvme147hw.h3
-rw-r--r--include/asm-m68k/mvme16xhw.h1
-rw-r--r--include/asm-m68k/page.h78
-rw-r--r--include/asm-m68k/page_offset.h9
-rw-r--r--include/asm-m68k/pci.h38
-rw-r--r--include/asm-m68k/pgalloc.h399
-rw-r--r--include/asm-m68k/pgtable.h524
-rw-r--r--include/asm-m68k/poll.h1
-rw-r--r--include/asm-m68k/semaphore.h175
-rw-r--r--include/asm-m68k/setup.h3
-rw-r--r--include/asm-m68k/siginfo.h16
-rw-r--r--include/asm-m68k/stat.h38
-rw-r--r--include/asm-m68k/system.h65
-rw-r--r--include/asm-m68k/termios.h3
-rw-r--r--include/asm-m68k/uaccess.h59
-rw-r--r--include/asm-m68k/virtconvert.h17
29 files changed, 1243 insertions, 628 deletions
diff --git a/include/asm-m68k/amigahw.h b/include/asm-m68k/amigahw.h
index 39dd49979..d63ceca32 100644
--- a/include/asm-m68k/amigahw.h
+++ b/include/asm-m68k/amigahw.h
@@ -281,7 +281,7 @@ struct CIA {
#define CHIP_PHYSADDR (0x000000)
#define chipaddr ((unsigned long)(zTwoBase + CHIP_PHYSADDR))
void amiga_chip_init (void);
-void *amiga_chip_alloc (long size);
+void *amiga_chip_alloc (long size, const char *name);
void amiga_chip_free (void *);
unsigned long amiga_chip_avail( void ); /*MILAN*/
diff --git a/include/asm-m68k/apollodma.h b/include/asm-m68k/apollodma.h
new file mode 100644
index 000000000..3abef61cb
--- /dev/null
+++ b/include/asm-m68k/apollodma.h
@@ -0,0 +1,248 @@
+/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $
+ * linux/include/asm/dma.h: Defines for using and allocating dma channels.
+ * Written by Hennus Bergman, 1992.
+ * High DMA channel support & info by Hannu Savolainen
+ * and John Boyd, Nov. 1992.
+ */
+
+#ifndef _ASM_APOLLO_DMA_H
+#define _ASM_APOLLO_DMA_H
+
+#include <asm/apollohw.h> /* need byte IO */
+#include <asm/spinlock.h> /* And spinlocks */
+#include <linux/delay.h>
+
+
+#define dma_outb(val,addr) (*((volatile unsigned char *)(addr+IO_BASE)) = (val))
+#define dma_inb(addr) (*((volatile unsigned char *)(addr+IO_BASE)))
+
+/*
+ * NOTES about DMA transfers:
+ *
+ * controller 1: channels 0-3, byte operations, ports 00-1F
+ * controller 2: channels 4-7, word operations, ports C0-DF
+ *
+ * - ALL registers are 8 bits only, regardless of transfer size
+ * - channel 4 is not used - cascades 1 into 2.
+ * - channels 0-3 are byte - addresses/counts are for physical bytes
+ * - channels 5-7 are word - addresses/counts are for physical words
+ * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
+ * - transfer count loaded to registers is 1 less than actual count
+ * - controller 2 offsets are all even (2x offsets for controller 1)
+ * - page registers for 5-7 don't use data bit 0, represent 128K pages
+ * - page registers for 0-3 use bit 0, represent 64K pages
+ *
+ * DMA transfers are limited to the lower 16MB of _physical_ memory.
+ * Note that addresses loaded into registers must be _physical_ addresses,
+ * not logical addresses (which may differ if paging is active).
+ *
+ * Address mapping for channels 0-3:
+ *
+ * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses)
+ * | ... | | ... | | ... |
+ * | ... | | ... | | ... |
+ * | ... | | ... | | ... |
+ * P7 ... P0 A7 ... A0 A7 ... A0
+ * | Page | Addr MSB | Addr LSB | (DMA registers)
+ *
+ * Address mapping for channels 5-7:
+ *
+ * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses)
+ * | ... | \ \ ... \ \ \ ... \ \
+ * | ... | \ \ ... \ \ \ ... \ (not used)
+ * | ... | \ \ ... \ \ \ ... \
+ * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0
+ * | Page | Addr MSB | Addr LSB | (DMA registers)
+ *
+ * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
+ * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
+ * the hardware level, so odd-byte transfers aren't possible).
+ *
+ * Transfer count (_not # bytes_) is limited to 64K, represented as actual
+ * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more,
+ * and up to 128K bytes may be transferred on channels 5-7 in one operation.
+ *
+ */
+
+#define MAX_DMA_CHANNELS 8
+
+/* The maximum address that we can perform a DMA transfer to on this platform */#define MAX_DMA_ADDRESS (PAGE_OFFSET+0x1000000)
+
+/* 8237 DMA controllers */
+#define IO_DMA1_BASE 0x10C00 /* 8 bit slave DMA, channels 0..3 */
+#define IO_DMA2_BASE 0x10D00 /* 16 bit master DMA, ch 4(=slave input)..7 */
+
+/* DMA controller registers */
+#define DMA1_CMD_REG (IO_DMA1_BASE+0x08) /* command register (w) */
+#define DMA1_STAT_REG (IO_DMA1_BASE+0x08) /* status register (r) */
+#define DMA1_REQ_REG (IO_DMA1_BASE+0x09) /* request register (w) */
+#define DMA1_MASK_REG (IO_DMA1_BASE+0x0A) /* single-channel mask (w) */
+#define DMA1_MODE_REG (IO_DMA1_BASE+0x0B) /* mode register (w) */
+#define DMA1_CLEAR_FF_REG (IO_DMA1_BASE+0x0C) /* clear pointer flip-flop (w) */
+#define DMA1_TEMP_REG (IO_DMA1_BASE+0x0D) /* Temporary Register (r) */
+#define DMA1_RESET_REG (IO_DMA1_BASE+0x0D) /* Master Clear (w) */
+#define DMA1_CLR_MASK_REG (IO_DMA1_BASE+0x0E) /* Clear Mask */
+#define DMA1_MASK_ALL_REG (IO_DMA1_BASE+0x0F) /* all-channels mask (w) */
+
+#define DMA2_CMD_REG (IO_DMA2_BASE+0x10) /* command register (w) */
+#define DMA2_STAT_REG (IO_DMA2_BASE+0x10) /* status register (r) */
+#define DMA2_REQ_REG (IO_DMA2_BASE+0x12) /* request register (w) */
+#define DMA2_MASK_REG (IO_DMA2_BASE+0x14) /* single-channel mask (w) */
+#define DMA2_MODE_REG (IO_DMA2_BASE+0x16) /* mode register (w) */
+#define DMA2_CLEAR_FF_REG (IO_DMA2_BASE+0x18) /* clear pointer flip-flop (w) */
+#define DMA2_TEMP_REG (IO_DMA2_BASE+0x1A) /* Temporary Register (r) */
+#define DMA2_RESET_REG (IO_DMA2_BASE+0x1A) /* Master Clear (w) */
+#define DMA2_CLR_MASK_REG (IO_DMA2_BASE+0x1C) /* Clear Mask */
+#define DMA2_MASK_ALL_REG (IO_DMA2_BASE+0x1E) /* all-channels mask (w) */
+
+#define DMA_ADDR_0 (IO_DMA1_BASE+0x00) /* DMA address registers */
+#define DMA_ADDR_1 (IO_DMA1_BASE+0x02)
+#define DMA_ADDR_2 (IO_DMA1_BASE+0x04)
+#define DMA_ADDR_3 (IO_DMA1_BASE+0x06)
+#define DMA_ADDR_4 (IO_DMA2_BASE+0x00)
+#define DMA_ADDR_5 (IO_DMA2_BASE+0x04)
+#define DMA_ADDR_6 (IO_DMA2_BASE+0x08)
+#define DMA_ADDR_7 (IO_DMA2_BASE+0x0C)
+
+#define DMA_CNT_0 (IO_DMA1_BASE+0x01) /* DMA count registers */
+#define DMA_CNT_1 (IO_DMA1_BASE+0x03)
+#define DMA_CNT_2 (IO_DMA1_BASE+0x05)
+#define DMA_CNT_3 (IO_DMA1_BASE+0x07)
+#define DMA_CNT_4 (IO_DMA2_BASE+0x02)
+#define DMA_CNT_5 (IO_DMA2_BASE+0x06)
+#define DMA_CNT_6 (IO_DMA2_BASE+0x0A)
+#define DMA_CNT_7 (IO_DMA2_BASE+0x0E)
+
+#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
+#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
+#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */
+
+#define DMA_AUTOINIT 0x10
+
+#define DMA_8BIT 0
+#define DMA_16BIT 1
+#define DMA_BUSMASTER 2
+
+extern spinlock_t dma_spin_lock;
+
+static __inline__ unsigned long claim_dma_lock(void)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&dma_spin_lock, flags);
+ return flags;
+}
+
+static __inline__ void release_dma_lock(unsigned long flags)
+{
+ spin_unlock_irqrestore(&dma_spin_lock, flags);
+}
+
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+ if (dmanr<=3)
+ dma_outb(dmanr, DMA1_MASK_REG);
+ else
+ dma_outb(dmanr & 3, DMA2_MASK_REG);
+}
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+ if (dmanr<=3)
+ dma_outb(dmanr | 4, DMA1_MASK_REG);
+ else
+ dma_outb((dmanr & 3) | 4, DMA2_MASK_REG);
+}
+
+/* Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while holding the DMA lock ! ---
+ */
+static __inline__ void clear_dma_ff(unsigned int dmanr)
+{
+ if (dmanr<=3)
+ dma_outb(0, DMA1_CLEAR_FF_REG);
+ else
+ dma_outb(0, DMA2_CLEAR_FF_REG);
+}
+
+/* set mode (above) for a specific DMA channel */
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+{
+ if (dmanr<=3)
+ dma_outb(mode | dmanr, DMA1_MODE_REG);
+ else
+ dma_outb(mode | (dmanr&3), DMA2_MODE_REG);
+}
+
+/* Set transfer address & page bits for specific DMA channel.
+ * Assumes dma flipflop is clear.
+ */
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+ if (dmanr <= 3) {
+ dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+ dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+ } else {
+ dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+ dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+ }
+}
+
+
+/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
+ * a specific DMA channel.
+ * You must ensure the parameters are valid.
+ * NOTE: from a manual: "the number of transfers is one more
+ * than the initial word count"! This is taken into account.
+ * Assumes dma flip-flop is clear.
+ * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+ count--;
+ if (dmanr <= 3) {
+ dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+ dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+ } else {
+ dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+ dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+ }
+}
+
+
+/* Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * If called before the channel has been used, it may return 1.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ *
+ * Assumes DMA flip-flop is clear.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+ unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
+ : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
+
+ /* using short to get 16-bit wrap around */
+ unsigned short count;
+
+ count = 1 + dma_inb(io_port);
+ count += dma_inb(io_port) << 8;
+
+ return (dmanr<=3)? count : (count<<1);
+}
+
+
+/* These are in kernel/dma.c: */
+extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
+extern void free_dma(unsigned int dmanr); /* release it again */
+
+/* These are in arch/m68k/apollo/dma.c: */
+extern unsigned short dma_map_page(unsigned long phys_addr,int count,int type);
+extern void dma_unmap_page(unsigned short dma_addr);
+
+#endif /* _ASM_APOLLO_DMA_H */
diff --git a/include/asm-m68k/apollohw.h b/include/asm-m68k/apollohw.h
index 54177aa3d..e12a638ca 100644
--- a/include/asm-m68k/apollohw.h
+++ b/include/asm-m68k/apollohw.h
@@ -3,6 +3,18 @@
#ifndef _ASMm68k_APOLLOHW_H_
#define _ASMm68k_APOLLOHW_H_
+/*
+ apollo models
+*/
+
+extern u_long apollo_model;
+
+#define APOLLO_UNKNOWN (0)
+#define APOLLO_DN3000 (1)
+#define APOLLO_DN3010 (2)
+#define APOLLO_DN3500 (3)
+#define APOLLO_DN4000 (4)
+#define APOLLO_DN4500 (5)
/*
see scn2681 data sheet for more info.
@@ -52,16 +64,42 @@ struct mc146818 {
unsigned char month, year;
};
+
#define IO_BASE 0x80000000
-#define SIO01_PHYSADDR 0x10400
-#define SIO23_PHYSADDR 0x10500
-#define RTC_PHYSADDR 0x10900
-#define PICA 0x11000
-#define PICB 0x11100
-#define sio01 ((*(volatile struct SCN2681 *)(IO_BASE + SIO01_PHYSADDR)))
-#define sio23 ((*(volatile struct SCN2681 *)(IO_BASE + SIO01_PHYSADDR)))
-#define rtc (((volatile struct mc146818 *)(IO_BASE + RTC_PHYSADDR)))
+extern u_long sio01_physaddr;
+extern u_long sio23_physaddr;
+extern u_long rtc_physaddr;
+extern u_long pica_physaddr;
+extern u_long picb_physaddr;
+extern u_long cpuctrl_physaddr;
+extern u_long timer_physaddr;
+
+#define SAU7_SIO01_PHYSADDR 0x10400
+#define SAU7_SIO23_PHYSADDR 0x10500
+#define SAU7_RTC_PHYSADDR 0x10900
+#define SAU7_PICA 0x11000
+#define SAU7_PICB 0x11100
+#define SAU7_CPUCTRL 0x10100
+#define SAU7_TIMER 0x010800
+
+#define SAU8_SIO01_PHYSADDR 0x8400
+#define SAU8_RTC_PHYSADDR 0x8900
+#define SAU8_PICA 0x9400
+#define SAU8_PICB 0x9500
+#define SAU8_CPUCTRL 0x8100
+#define SAU8_TIMER 0x8800
+
+#define sio01 ((*(volatile struct SCN2681 *)(IO_BASE + sio01_physaddr)))
+#define sio23 ((*(volatile struct SCN2681 *)(IO_BASE + sio23_physaddr)))
+#define rtc (((volatile struct mc146818 *)(IO_BASE + rtc_physaddr)))
+#define cpuctrl (*(volatile unsigned int *)(IO_BASE + cpuctrl_physaddr))
+#define pica (IO_BASE + pica_physaddr)
+#define picb (IO_BASE + picb_physaddr)
+#define timer (IO_BASE + timer_physaddr)
+#define addr_xlat_map ((unsigned short *)(IO_BASE + 0x17000))
+
+#define isaIO2mem(x) (((((x) & 0x3f8) << 7) | (((x) & 0xfc00) >> 6) | ((x) & 0x7)) + 0x40000 + IO_BASE)
#define inb(addr) (*((volatile unsigned char *)(addr)))
#define outb(val,addr) (*((volatile unsigned char *)(addr)) = (val))
diff --git a/include/asm-m68k/bootinfo.h b/include/asm-m68k/bootinfo.h
index 871d051fe..19f340b5c 100644
--- a/include/asm-m68k/bootinfo.h
+++ b/include/asm-m68k/bootinfo.h
@@ -103,6 +103,30 @@ struct bi_record {
#define ATARI_MACH_AB40 3 /* Afterburner040 on Falcon */
/*
+ * VME-specific tags
+ */
+
+#define BI_VME_TYPE 0x8000 /* VME sub-architecture (u_long) */
+#define BI_VME_BRDINFO 0x8001 /* VME board information (struct) */
+
+/* BI_VME_TYPE codes */
+#define VME_TYPE_TP34V 0x0034 /* Tadpole TP34V */
+#define VME_TYPE_MVME147 0x0147 /* Motorola MVME147 */
+#define VME_TYPE_MVME162 0x0162 /* Motorola MVME162 */
+#define VME_TYPE_MVME166 0x0166 /* Motorola MVME166 */
+#define VME_TYPE_MVME167 0x0167 /* Motorola MVME167 */
+#define VME_TYPE_MVME172 0x0172 /* Motorola MVME172 */
+#define VME_TYPE_MVME177 0x0177 /* Motorola MVME177 */
+#define VME_TYPE_BVME4000 0x4000 /* BVM Ltd. BVME4000 */
+#define VME_TYPE_BVME6000 0x6000 /* BVM Ltd. BVME6000 */
+
+/* BI_VME_BRDINFO is a 32 byte struct as returned by the Bug code on
+ * Motorola VME boards. Contains board number, Bug version, board
+ * configuration options, etc. See include/asm/mvme16xhw.h for details.
+ */
+
+
+ /*
* Macintosh-specific tags (all u_long)
*/
@@ -184,6 +208,14 @@ extern struct mac_booter_data
#endif
/*
+ * Apollo-specific tags
+ */
+
+#define BI_APOLLO_MODEL 0x8000 /* model (u_long) */
+
+
+
+ /*
* Stuff for bootinfo interface versioning
*
* At the start of kernel code, a 'struct bootversion' is located.
diff --git a/include/asm-m68k/bvme6000hw.h b/include/asm-m68k/bvme6000hw.h
index 853120a04..28a859b03 100644
--- a/include/asm-m68k/bvme6000hw.h
+++ b/include/asm-m68k/bvme6000hw.h
@@ -95,6 +95,7 @@ typedef struct {
#define BVME_SCC_A_ADDR 0xffb0000b
#define BVME_SCC_B_ADDR 0xffb00003
+#define BVME_SCC_RTxC 7372800
#define BVME_CONFIG_REG 0xff500003
diff --git a/include/asm-m68k/cache.h b/include/asm-m68k/cache.h
index 9e009ce18..52262e891 100644
--- a/include/asm-m68k/cache.h
+++ b/include/asm-m68k/cache.h
@@ -7,16 +7,4 @@
/* bytes per L1 cache line */
#define L1_CACHE_BYTES 16
-#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
-
-#define SMP_CACHE_BYTES L1_CACHE_BYTES
-
-#ifdef MODULE
-#define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES)))
-#else
-#define __cacheline_aligned \
- __attribute__((__aligned__(L1_CACHE_BYTES), \
- __section__(".data.cacheline_aligned")))
-#endif
-
#endif
diff --git a/include/asm-m68k/div64.h b/include/asm-m68k/div64.h
new file mode 100644
index 000000000..16bf1f88d
--- /dev/null
+++ b/include/asm-m68k/div64.h
@@ -0,0 +1,35 @@
+#ifndef _M68K_DIV64_H
+#define _M68K_DIV64_H
+
+/* n = n / base; return rem; */
+
+#if 1
+#define do_div(n, base) ({ \
+ union { \
+ unsigned long n32[2]; \
+ unsigned long long n64; \
+ } __n; \
+ unsigned long __rem, __upper; \
+ \
+ __n.n64 = (n); \
+ if ((__upper = __n.n32[0])) { \
+ asm ("divul.l %2,%1:%0" \
+ : "=d" (__n.n32[0]), "=d" (__upper) \
+ : "d" (base), "0" (__n.n32[0])); \
+ } \
+ asm ("divu.l %2,%1:%0" \
+ : "=d" (__n.n32[1]), "=d" (__rem) \
+ : "d" (base), "1" (__upper), "0" (__n.n32[1])); \
+ (n) = __n.n64; \
+ __rem; \
+})
+#else
+#define do_div(n,base) ({ \
+ int __res; \
+ __res = ((unsigned long) n) % (unsigned) base; \
+ n = ((unsigned long) n) / (unsigned) base; \
+ __res; \
+})
+#endif
+
+#endif /* _M68K_DIV64_H */
diff --git a/include/asm-m68k/dma.h b/include/asm-m68k/dma.h
index af73a0f6f..d5266a886 100644
--- a/include/asm-m68k/dma.h
+++ b/include/asm-m68k/dma.h
@@ -1,12 +1,21 @@
#ifndef _M68K_DMA_H
#define _M68K_DMA_H 1
-/* Don't define MAX_DMA_ADDRESS; it's useless on the m68k and any
- occurrence should be flagged as an error. */
+#include <linux/config.h>
+
+/* it's useless on the m68k, but unfortunately needed by the new
+ bootmem allocator (but this should do it for this) */
+#define MAX_DMA_ADDRESS PAGE_OFFSET
#define MAX_DMA_CHANNELS 8
extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
extern void free_dma(unsigned int dmanr); /* release it again */
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#else
+#define isa_dma_bridge_buggy (0)
+#endif
+
#endif /* _M68K_DMA_H */
diff --git a/include/asm-m68k/entry.h b/include/asm-m68k/entry.h
index 56ab0dcf8..3575894b5 100644
--- a/include/asm-m68k/entry.h
+++ b/include/asm-m68k/entry.h
@@ -34,10 +34,6 @@
* the whole kernel.
*/
-#ifdef __ASSEMBLY__
-
-#define curptr a2
-
/* the following macro is used when enabling interrupts */
#if defined(MACH_ATARI_ONLY) && !defined(CONFIG_HADES)
/* block out HSYNC on the atari */
@@ -49,6 +45,10 @@
#define MAX_NOINT_IPL 0
#endif /* machine compilation types */
+#ifdef __ASSEMBLY__
+
+#define curptr a2
+
LFLUSH_I_AND_D = 0x00000808
LSIGTRAP = 5
@@ -162,7 +162,7 @@ PF_DTRACE_BIT = 5
#endif
#define GET_CURRENT(tmp) \
"movel %%sp,"#tmp"\n\t" \
- "andw #-KTHREAD_SIZE,"#tmp"\n\t" \
+ "andw #-"STR(KTHREAD_SIZE)","#tmp"\n\t" \
"movel "#tmp",%%a2"
#endif
diff --git a/include/asm-m68k/fcntl.h b/include/asm-m68k/fcntl.h
index 2235bd5bb..b5780416f 100644
--- a/include/asm-m68k/fcntl.h
+++ b/include/asm-m68k/fcntl.h
@@ -18,6 +18,8 @@
#define FASYNC 020000 /* fcntl, for BSD compatibility */
#define O_DIRECTORY 040000 /* must be a directory */
#define O_NOFOLLOW 0100000 /* don't follow links */
+#define O_DIRECT 0200000 /* direct disk access hint - currently ignored */
+#define O_LARGEFILE 0400000
#define F_DUPFD 0 /* dup */
#define F_GETFD 1 /* get f_flags */
diff --git a/include/asm-m68k/hardirq.h b/include/asm-m68k/hardirq.h
index 6e8e0d4ac..0e3cd0c6f 100644
--- a/include/asm-m68k/hardirq.h
+++ b/include/asm-m68k/hardirq.h
@@ -10,8 +10,8 @@ extern unsigned int local_irq_count[NR_CPUS];
#define hardirq_trylock(cpu) (local_irq_count[cpu] == 0)
#define hardirq_endlock(cpu) do { } while (0)
-#define hardirq_enter(cpu) (local_irq_count[cpu]++)
-#define hardirq_exit(cpu) (local_irq_count[cpu]--)
+#define irq_enter(cpu) (local_irq_count[cpu]++)
+#define irq_exit(cpu) (local_irq_count[cpu]--)
#define synchronize_irq() barrier()
diff --git a/include/asm-m68k/mmu_context.h b/include/asm-m68k/mmu_context.h
index a8a1dfc61..f54fbfa17 100644
--- a/include/asm-m68k/mmu_context.h
+++ b/include/asm-m68k/mmu_context.h
@@ -7,6 +7,7 @@
#include <asm/setup.h>
#include <asm/page.h>
+#include <asm/pgalloc.h>
extern inline void
init_new_context(struct task_struct *tsk, struct mm_struct *mm)
diff --git a/include/asm-m68k/movs.h b/include/asm-m68k/movs.h
index 67dbea369..540d3e60e 100644
--- a/include/asm-m68k/movs.h
+++ b/include/asm-m68k/movs.h
@@ -10,46 +10,46 @@
/* Set DFC register value */
#define SET_DFC(x) \
- __asm__ __volatile__ (" movec %0,%/dfc" : : "d" (x));
+ __asm__ __volatile__ ("movec %0,%%dfc" : : "r" (x))
/* Get DFC register value */
#define GET_DFC(x) \
- __asm__ __volatile__ (" movec %/dfc, %0" : "=d" (x) : );
+ __asm__ __volatile__ ("movec %%dfc,%0" : "=r" (x))
/* Set SFC register value */
#define SET_SFC(x) \
- __asm__ __volatile__ (" movec %0,%/sfc" : : "d" (x));
+ __asm__ __volatile__ ("movec %0,%%sfc" : : "r" (x))
/* Get SFC register value */
#define GET_SFC(x) \
- __asm__ __volatile__ (" movec %/sfc, %0" : "=d" (x) : );
+ __asm__ __volatile__ ("movec %%sfc,%0" : "=r" (x))
#define SET_VBR(x) \
- __asm__ __volatile__ (" movec %0,%/vbr" : : "r" (x));
+ __asm__ __volatile__ ("movec %0,%%vbr" : : "r" (x))
#define GET_VBR(x) \
- __asm__ __volatile__ (" movec %/vbr, %0" : "=g" (x) : );
+ __asm__ __volatile__ ("movec %%vbr,%0" : "=r" (x))
-/* Set a byte using the "movs" instruction */
+/* Set a byte using the "moves" instruction */
#define SET_CONTROL_BYTE(addr,value) \
- __asm__ __volatile__ (" movsb %0, %1@" : : "d" (value), "a" (addr));
+ __asm__ __volatile__ ("movesb %1,%0" : "=m" (addr) : "d" (value))
-/* Get a byte using the "movs" instruction */
+/* Get a byte using the "moves" instruction */
#define GET_CONTROL_BYTE(addr,value) \
- __asm__ __volatile__ (" movsb %1@, %0" : "=d" (value) : "a" (addr));
+ __asm__ __volatile__ ("movesb %1,%0" : "=d" (value) : "m" (addr))
-/* Set a (long)word using the "movs" instruction */
+/* Set a (long)word using the "moves" instruction */
#define SET_CONTROL_WORD(addr,value) \
- __asm__ __volatile__ (" movsl %0, %1@" : : "d" (value), "a" (addr));
+ __asm__ __volatile__ ("movesl %1,%0" : "=m" (addr) : "r" (value))
-/* Get a (long)word using the "movs" instruction */
+/* Get a (long)word using the "moves" instruction */
#define GET_CONTROL_WORD(addr,value) \
- __asm__ __volatile__ (" movsl %1@, %0" : "=d" (value) : "a" (addr));
+ __asm__ __volatile__ ("movesl %1,%0" : "=d" (value) : "m" (addr))
#endif
diff --git a/include/asm-m68k/mvme147hw.h b/include/asm-m68k/mvme147hw.h
index f57216b9e..195a50893 100644
--- a/include/asm-m68k/mvme147hw.h
+++ b/include/asm-m68k/mvme147hw.h
@@ -85,11 +85,12 @@ struct pcc_regs {
#define M147_SCC_A_ADDR 0xfffe3002
#define M147_SCC_B_ADDR 0xfffe3000
+#define M147_SCC_PCLK 5000000
#define MVME147_IRQ_SCSI_PORT 0x45
#define MVME147_IRQ_SCSI_DMA 0x46
-/* SCC interrupts, for MVME162 */
+/* SCC interrupts, for MVME147 */
#define MVME147_IRQ_TYPE_PRIO 0
#define MVME147_IRQ_SCC_BASE 0x60
diff --git a/include/asm-m68k/mvme16xhw.h b/include/asm-m68k/mvme16xhw.h
index 75a21d8a4..4102460fb 100644
--- a/include/asm-m68k/mvme16xhw.h
+++ b/include/asm-m68k/mvme16xhw.h
@@ -62,6 +62,7 @@ typedef struct {
#define MVME_SCC_A_ADDR 0xfff45005
#define MVME_SCC_B_ADDR 0xfff45001
+#define MVME_SCC_PCLK 10000000
#define MVME162_IRQ_TYPE_PRIO 0
diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h
index 6a3d9df66..23dd731c8 100644
--- a/include/asm-m68k/page.h
+++ b/include/asm-m68k/page.h
@@ -25,16 +25,14 @@
#ifndef __ASSEMBLY__
-#define STRICT_MM_TYPECHECKS
-
-#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
+#define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
#define free_user_page(page, addr) free_page(addr)
/*
* We don't need to check for alignment etc.
*/
#ifdef CPU_M68040_OR_M68060_ONLY
-static inline void copy_page(unsigned long to, unsigned long from)
+static inline void copy_page(void *to, void *from)
{
unsigned long tmp;
@@ -49,11 +47,10 @@ static inline void copy_page(unsigned long to, unsigned long from)
);
}
-static inline void clear_page(unsigned long page)
+static inline void clear_page(void *page)
{
- unsigned long data, sp, tmp;
-
- sp = page;
+ unsigned long data, tmp;
+ void *sp = page;
data = 0;
@@ -75,11 +72,10 @@ static inline void clear_page(unsigned long page)
}
#else
-#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
-#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+#define clear_page(page) memset((page), 0, PAGE_SIZE)
+#define copy_page(to,from) memcpy((to), (from), PAGE_SIZE)
#endif
-#ifdef STRICT_MM_TYPECHECKS
/*
* These are used to make use of C type-checking..
*/
@@ -98,55 +94,29 @@ typedef struct { unsigned long pgprot; } pgprot_t;
#define __pgd(x) ((pgd_t) { (x) } )
#define __pgprot(x) ((pgprot_t) { (x) } )
-#else
-/*
- * .. while these make it easier on the compiler
- */
-typedef unsigned long pte_t;
-typedef struct { unsigned long pmd[16]; } pmd_t;
-typedef unsigned long pgd_t;
-typedef unsigned long pgprot_t;
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
-#define pte_val(x) (x)
-#define pmd_val(x) ((&x)->pmd[0])
-#define pgd_val(x) (x)
-#define pgprot_val(x) (x)
+#endif /* !__ASSEMBLY__ */
-#define __pte(x) (x)
-#define __pmd(x) ((pmd_t) { (x) } )
-#define __pgd(x) (x)
-#define __pgprot(x) (x)
+#include <asm/page_offset.h>
-#endif
+#define PAGE_OFFSET (PAGE_OFFSET_RAW)
-/* to align the pointer to the (next) page boundary */
-#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
+#ifndef __ASSEMBLY__
-/* This handles the memory map.. */
#ifndef CONFIG_SUN3
-#define PAGE_OFFSET 0
+
+#ifdef CONFIG_SINGLE_MEMORY_CHUNK
+extern unsigned long m68k_memoffset;
+
+#define __pa(vaddr) ((unsigned long)(vaddr)+m68k_memoffset)
+#define __va(paddr) ((void *)((unsigned long)(paddr)-m68k_memoffset))
#else
-#define PAGE_OFFSET 0x0E000000
+#define __pa(vaddr) virt_to_phys((void *)vaddr)
+#define __va(paddr) phys_to_virt((unsigned long)paddr)
#endif
-#ifndef CONFIG_SUN3
-#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
-/*
- * A hacky workaround for the problems with mmap() of frame buffer
- * memory in the lower 16MB physical memoryspace.
- *
- * This is a short term solution, we will have to deal properly
- * with this in 2.3.x.
- */
-extern inline void *__va(unsigned long physaddr)
-{
-#ifdef CONFIG_AMIGA
- if (MACH_IS_AMIGA && (physaddr < 16*1024*1024))
- return (void *)0xffffffff;
- else
-#endif
- return (void *)(physaddr+PAGE_OFFSET);
-}
#else /* !CONFIG_SUN3 */
/* This #define is a horrible hack to suppress lots of warnings. --m */
#define __pa(x) ___pa((unsigned long)x)
@@ -172,9 +142,7 @@ static inline void *__va(unsigned long x)
}
#endif /* CONFIG_SUN3 */
-#define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT)
-
-#endif /* !__ASSEMBLY__ */
+#define MAP_NR(addr) (((unsigned long)(addr)-PAGE_OFFSET) >> PAGE_SHIFT)
#ifndef CONFIG_SUN3
#define BUG() do { \
@@ -192,6 +160,8 @@ static inline void *__va(unsigned long x)
BUG(); \
} while (0)
+#endif /* __ASSEMBLY__ */
+
#endif /* __KERNEL__ */
#endif /* _M68K_PAGE_H */
diff --git a/include/asm-m68k/page_offset.h b/include/asm-m68k/page_offset.h
new file mode 100644
index 000000000..39e30499c
--- /dev/null
+++ b/include/asm-m68k/page_offset.h
@@ -0,0 +1,9 @@
+#include <linux/config.h>
+
+/* This handles the memory map.. */
+#ifndef CONFIG_SUN3
+#define PAGE_OFFSET_RAW 0x00000000
+#else
+#define PAGE_OFFSET_RAW 0x0E000000
+#endif
+
diff --git a/include/asm-m68k/pci.h b/include/asm-m68k/pci.h
new file mode 100644
index 000000000..76915264d
--- /dev/null
+++ b/include/asm-m68k/pci.h
@@ -0,0 +1,38 @@
+#ifndef _ASM_M68K_PCI_H
+#define _ASM_M68K_PCI_H
+
+/*
+ * asm-m68k/pci_m68k.h - m68k specific PCI declarations.
+ *
+ * Written by Wout Klaren.
+ */
+
+struct pci_ops;
+
+/*
+ * Structure with hardware dependent information and functions of the
+ * PCI bus.
+ */
+
+struct pci_bus_info
+{
+ /*
+ * Resources of the PCI bus.
+ */
+
+ struct resource mem_space;
+ struct resource io_space;
+
+ /*
+ * System dependent functions.
+ */
+
+ struct pci_ops *m68k_pci_ops;
+
+ void (*fixup)(int pci_modify);
+ void (*conf_device)(unsigned char bus, unsigned char device_fn);
+};
+
+#define pcibios_assign_all_busses() 0
+
+#endif /* _ASM_M68K_PCI_H */
diff --git a/include/asm-m68k/pgalloc.h b/include/asm-m68k/pgalloc.h
new file mode 100644
index 000000000..3d2a2b87d
--- /dev/null
+++ b/include/asm-m68k/pgalloc.h
@@ -0,0 +1,399 @@
+#ifndef _M68K_PGALLOC_H
+#define _M68K_PGALLOC_H
+
+#include <asm/setup.h>
+#include <asm/virtconvert.h>
+
+extern struct pgtable_cache_struct {
+ unsigned long *pmd_cache;
+ unsigned long *pte_cache;
+/* This counts in units of pointer tables, of which can be eight per page. */
+ unsigned long pgtable_cache_sz;
+} quicklists;
+
+#define pgd_quicklist ((unsigned long *)0)
+#define pmd_quicklist (quicklists.pmd_cache)
+#define pte_quicklist (quicklists.pte_cache)
+/* This isn't accurate because of fragmentation of allocated pages for
+ pointer tables, but that should not be a problem. */
+#define pgtable_cache_size ((quicklists.pgtable_cache_sz+7)/8)
+
+extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset);
+extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset);
+
+extern pmd_t *get_pointer_table(void);
+extern int free_pointer_table(pmd_t *);
+
+extern inline pte_t *get_pte_fast(void)
+{
+ unsigned long *ret;
+
+ ret = pte_quicklist;
+ if (ret) {
+ pte_quicklist = (unsigned long *)*ret;
+ ret[0] = 0;
+ quicklists.pgtable_cache_sz -= 8;
+ }
+ return (pte_t *)ret;
+}
+
+extern inline void free_pte_fast(pte_t *pte)
+{
+ *(unsigned long *)pte = (unsigned long)pte_quicklist;
+ pte_quicklist = (unsigned long *)pte;
+ quicklists.pgtable_cache_sz += 8;
+}
+
+extern inline void free_pte_slow(pte_t *pte)
+{
+ cache_page((unsigned long)pte);
+ free_page((unsigned long) pte);
+}
+
+extern inline pmd_t *get_pmd_fast(void)
+{
+ unsigned long *ret;
+
+ ret = pmd_quicklist;
+ if (ret) {
+ pmd_quicklist = (unsigned long *)*ret;
+ ret[0] = 0;
+ quicklists.pgtable_cache_sz--;
+ }
+ return (pmd_t *)ret;
+}
+
+extern inline void free_pmd_fast(pmd_t *pmd)
+{
+ *(unsigned long *)pmd = (unsigned long)pmd_quicklist;
+ pmd_quicklist = (unsigned long *) pmd;
+ quicklists.pgtable_cache_sz++;
+}
+
+extern inline int free_pmd_slow(pmd_t *pmd)
+{
+ return free_pointer_table(pmd);
+}
+
+/* The pgd cache is folded into the pmd cache, so these are dummy routines. */
+extern inline pgd_t *get_pgd_fast(void)
+{
+ return (pgd_t *)0;
+}
+
+extern inline void free_pgd_fast(pgd_t *pgd)
+{
+}
+
+extern inline void free_pgd_slow(pgd_t *pgd)
+{
+}
+
+extern void __bad_pte(pmd_t *pmd);
+extern void __bad_pmd(pgd_t *pgd);
+
+extern inline void pte_free(pte_t *pte)
+{
+ free_pte_fast(pte);
+}
+
+extern inline pte_t *pte_alloc(pmd_t *pmd, unsigned long address)
+{
+ address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+ if (pmd_none(*pmd)) {
+ pte_t *page = get_pte_fast();
+
+ if (!page)
+ return get_pte_slow(pmd, address);
+ pmd_set(pmd,page);
+ return page + address;
+ }
+ if (pmd_bad(*pmd)) {
+ __bad_pte(pmd);
+ return NULL;
+ }
+ return (pte_t *)__pmd_page(*pmd) + address;
+}
+
+extern inline void pmd_free(pmd_t *pmd)
+{
+ free_pmd_fast(pmd);
+}
+
+extern inline pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address)
+{
+ address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
+ if (pgd_none(*pgd)) {
+ pmd_t *page = get_pmd_fast();
+
+ if (!page)
+ return get_pmd_slow(pgd, address);
+ pgd_set(pgd, page);
+ return page + address;
+ }
+ if (pgd_bad(*pgd)) {
+ __bad_pmd(pgd);
+ return NULL;
+ }
+ return (pmd_t *)__pgd_page(*pgd) + address;
+}
+
+extern inline void pte_free_kernel(pte_t *pte)
+{
+ free_pte_fast(pte);
+}
+
+extern inline pte_t *pte_alloc_kernel(pmd_t *pmd, unsigned long address)
+{
+ return pte_alloc(pmd, address);
+}
+
+extern inline void pmd_free_kernel(pmd_t *pmd)
+{
+ free_pmd_fast(pmd);
+}
+
+extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address)
+{
+ return pmd_alloc(pgd, address);
+}
+
+extern inline void pgd_free(pgd_t *pgd)
+{
+ free_pmd_fast((pmd_t *)pgd);
+}
+
+extern inline pgd_t *pgd_alloc(void)
+{
+ pgd_t *pgd = (pgd_t *)get_pmd_fast();
+ if (!pgd)
+ pgd = (pgd_t *)get_pointer_table();
+ return pgd;
+}
+
+extern int do_check_pgt_cache(int, int);
+
+extern inline void set_pgdir(unsigned long address, pgd_t entry)
+{
+}
+
+
+/*
+ * Cache handling functions
+ */
+
+#define flush_icache() \
+({ \
+ if (CPU_IS_040_OR_060) \
+ __asm__ __volatile__("nop\n\t" \
+ ".chip 68040\n\t" \
+ "cinva %%ic\n\t" \
+ ".chip 68k" : ); \
+ else { \
+ unsigned long _tmp; \
+ __asm__ __volatile__("movec %%cacr,%0\n\t" \
+ "orw %1,%0\n\t" \
+ "movec %0,%%cacr" \
+ : "=&d" (_tmp) \
+ : "id" (FLUSH_I)); \
+ } \
+})
+
+/*
+ * invalidate the cache for the specified memory range.
+ * It starts at the physical address specified for
+ * the given number of bytes.
+ */
+extern void cache_clear(unsigned long paddr, int len);
+/*
+ * push any dirty cache in the specified memory range.
+ * It starts at the physical address specified for
+ * the given number of bytes.
+ */
+extern void cache_push(unsigned long paddr, int len);
+
+/*
+ * push and invalidate pages in the specified user virtual
+ * memory range.
+ */
+extern void cache_push_v(unsigned long vaddr, int len);
+
+/* cache code */
+#define FLUSH_I_AND_D (0x00000808)
+#define FLUSH_I (0x00000008)
+
+/* This is needed whenever the virtual mapping of the current
+ process changes. */
+#define __flush_cache_all() \
+({ \
+ if (CPU_IS_040_OR_060) \
+ __asm__ __volatile__("nop\n\t" \
+ ".chip 68040\n\t" \
+ "cpusha %dc\n\t" \
+ ".chip 68k"); \
+ else { \
+ unsigned long _tmp; \
+ __asm__ __volatile__("movec %%cacr,%0\n\t" \
+ "orw %1,%0\n\t" \
+ "movec %0,%%cacr" \
+ : "=&d" (_tmp) \
+ : "di" (FLUSH_I_AND_D)); \
+ } \
+})
+
+#define __flush_cache_030() \
+({ \
+ if (CPU_IS_020_OR_030) { \
+ unsigned long _tmp; \
+ __asm__ __volatile__("movec %%cacr,%0\n\t" \
+ "orw %1,%0\n\t" \
+ "movec %0,%%cacr" \
+ : "=&d" (_tmp) \
+ : "di" (FLUSH_I_AND_D)); \
+ } \
+})
+
+#define flush_cache_all() __flush_cache_all()
+
+extern inline void flush_cache_mm(struct mm_struct *mm)
+{
+ if (mm == current->mm)
+ __flush_cache_030();
+}
+
+extern inline void flush_cache_range(struct mm_struct *mm,
+ unsigned long start,
+ unsigned long end)
+{
+ if (mm == current->mm)
+ __flush_cache_030();
+}
+
+extern inline void flush_cache_page(struct vm_area_struct *vma,
+ unsigned long vmaddr)
+{
+ if (vma->vm_mm == current->mm)
+ __flush_cache_030();
+}
+
+/* Push the page at kernel virtual address and clear the icache */
+#define flush_page_to_ram(page) __flush_page_to_ram(page_address(page))
+extern inline void __flush_page_to_ram(unsigned long address)
+{
+ if (CPU_IS_040_OR_060) {
+ __asm__ __volatile__("nop\n\t"
+ ".chip 68040\n\t"
+ "cpushp %%dc,(%0)\n\t"
+ "cinvp %%ic,(%0)\n\t"
+ ".chip 68k"
+ : : "a" (__pa((void *)address)));
+ } else {
+ unsigned long _tmp;
+ __asm__ __volatile__("movec %%cacr,%0\n\t"
+ "orw %1,%0\n\t"
+ "movec %0,%%cacr"
+ : "=&d" (_tmp)
+ : "di" (FLUSH_I));
+ }
+}
+
+/* Push n pages at kernel virtual address and clear the icache */
+extern inline void flush_icache_range (unsigned long address,
+ unsigned long endaddr)
+{
+ if (CPU_IS_040_OR_060) {
+ short n = (endaddr - address + PAGE_SIZE - 1) / PAGE_SIZE;
+
+ while (--n >= 0) {
+ __asm__ __volatile__("nop\n\t"
+ ".chip 68040\n\t"
+ "cpushp %%dc,(%0)\n\t"
+ "cinvp %%ic,(%0)\n\t"
+ ".chip 68k"
+ : : "a" (virt_to_phys((void *)address)));
+ address += PAGE_SIZE;
+ }
+ } else {
+ unsigned long tmp;
+ __asm__ __volatile__("movec %%cacr,%0\n\t"
+ "orw %1,%0\n\t"
+ "movec %0,%%cacr"
+ : "=&d" (tmp)
+ : "di" (FLUSH_I));
+ }
+}
+
+
+/*
+ * flush all user-space atc entries.
+ */
+static inline void __flush_tlb(void)
+{
+ if (CPU_IS_040_OR_060)
+ __asm__ __volatile__(".chip 68040\n\t"
+ "pflushan\n\t"
+ ".chip 68k");
+ else
+ __asm__ __volatile__("pflush #0,#4");
+}
+
+static inline void __flush_tlb_one(unsigned long addr)
+{
+ if (CPU_IS_040_OR_060) {
+ __asm__ __volatile__(".chip 68040\n\t"
+ "pflush (%0)\n\t"
+ ".chip 68k"
+ : : "a" (addr));
+ } else
+ __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr));
+}
+
+#define flush_tlb() __flush_tlb()
+
+/*
+ * flush all atc entries (both kernel and user-space entries).
+ */
+static inline void flush_tlb_all(void)
+{
+ if (CPU_IS_040_OR_060)
+ __asm__ __volatile__(".chip 68040\n\t"
+ "pflusha\n\t"
+ ".chip 68k");
+ else
+ __asm__ __volatile__("pflusha");
+}
+
+static inline void flush_tlb_mm(struct mm_struct *mm)
+{
+ if (mm == current->mm)
+ __flush_tlb();
+}
+
+static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+ if (vma->vm_mm == current->mm)
+ __flush_tlb_one(addr);
+}
+
+static inline void flush_tlb_range(struct mm_struct *mm,
+ unsigned long start, unsigned long end)
+{
+ if (mm == current->mm)
+ __flush_tlb();
+}
+
+extern inline void flush_tlb_kernel_page(unsigned long addr)
+{
+ if (CPU_IS_040_OR_060) {
+ mm_segment_t old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ __asm__ __volatile__(".chip 68040\n\t"
+ "pflush (%0)\n\t"
+ ".chip 68k"
+ : : "a" (addr));
+ set_fs(old_fs);
+ } else
+ __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
+}
+
+#endif /* _M68K_PGALLOC_H */
diff --git a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h
index c94acfc38..9df773f9f 100644
--- a/include/asm-m68k/pgtable.h
+++ b/include/asm-m68k/pgtable.h
@@ -15,226 +15,6 @@
#include <asm/virtconvert.h>
-/*
- * Cache handling functions
- */
-
-#define flush_icache() \
-do { \
- if (CPU_IS_040_OR_060) \
- asm __volatile__ ("nop\n\t" \
- ".chip 68040\n\t" \
- "cinva %%ic\n\t" \
- ".chip 68k" : ); \
- else { \
- unsigned long _tmp; \
- asm __volatile__ ("movec %%cacr,%0\n\t" \
- "orw %1,%0\n\t" \
- "movec %0,%%cacr" \
- : "=&d" (_tmp) \
- : "id" (FLUSH_I)); \
- } \
-} while (0)
-
-/*
- * invalidate the cache for the specified memory range.
- * It starts at the physical address specified for
- * the given number of bytes.
- */
-extern void cache_clear (unsigned long paddr, int len);
-/*
- * push any dirty cache in the specified memory range.
- * It starts at the physical address specified for
- * the given number of bytes.
- */
-extern void cache_push (unsigned long paddr, int len);
-
-/*
- * push and invalidate pages in the specified user virtual
- * memory range.
- */
-extern void cache_push_v (unsigned long vaddr, int len);
-
-/* cache code */
-#define FLUSH_I_AND_D (0x00000808)
-#define FLUSH_I (0x00000008)
-
-/* This is needed whenever the virtual mapping of the current
- process changes. */
-#define __flush_cache_all() \
- do { \
- if (CPU_IS_040_OR_060) \
- __asm__ __volatile__ ("nop\n\t" \
- ".chip 68040\n\t" \
- "cpusha %dc\n\t" \
- ".chip 68k"); \
- else { \
- unsigned long _tmp; \
- __asm__ __volatile__ ("movec %%cacr,%0\n\t" \
- "orw %1,%0\n\t" \
- "movec %0,%%cacr" \
- : "=&d" (_tmp) \
- : "di" (FLUSH_I_AND_D)); \
- } \
- } while (0)
-
-#define __flush_cache_030() \
- do { \
- if (CPU_IS_020_OR_030) { \
- unsigned long _tmp; \
- __asm__ __volatile__ ("movec %%cacr,%0\n\t" \
- "orw %1,%0\n\t" \
- "movec %0,%%cacr" \
- : "=&d" (_tmp) \
- : "di" (FLUSH_I_AND_D)); \
- } \
- } while (0)
-
-#define flush_cache_all() __flush_cache_all()
-
-extern inline void flush_cache_mm(struct mm_struct *mm)
-{
- if (mm == current->mm)
- __flush_cache_030();
-}
-
-extern inline void flush_cache_range(struct mm_struct *mm,
- unsigned long start,
- unsigned long end)
-{
- if (mm == current->mm)
- __flush_cache_030();
-}
-
-extern inline void flush_cache_page(struct vm_area_struct *vma,
- unsigned long vmaddr)
-{
- if (vma->vm_mm == current->mm)
- __flush_cache_030();
-}
-
-/* Push the page at kernel virtual address and clear the icache */
-extern inline void flush_page_to_ram (unsigned long address)
-{
- if (CPU_IS_040_OR_060) {
- __asm__ __volatile__ ("nop\n\t"
- ".chip 68040\n\t"
- "cpushp %%dc,(%0)\n\t"
- "cinvp %%ic,(%0)\n\t"
- ".chip 68k"
- : : "a" (virt_to_phys((void *)address)));
- }
- else {
- unsigned long _tmp;
- __asm volatile ("movec %%cacr,%0\n\t"
- "orw %1,%0\n\t"
- "movec %0,%%cacr"
- : "=&d" (_tmp)
- : "di" (FLUSH_I));
- }
-}
-
-/* Push n pages at kernel virtual address and clear the icache */
-extern inline void flush_icache_range (unsigned long address,
- unsigned long endaddr)
-{
- if (CPU_IS_040_OR_060) {
- short n = (endaddr - address + PAGE_SIZE - 1) / PAGE_SIZE;
-
- while (n--) {
- __asm__ __volatile__ ("nop\n\t"
- ".chip 68040\n\t"
- "cpushp %%dc,(%0)\n\t"
- "cinvp %%ic,(%0)\n\t"
- ".chip 68k"
- : : "a" (virt_to_phys((void *)address)));
- address += PAGE_SIZE;
- }
- }
- else {
- unsigned long _tmp;
- __asm volatile ("movec %%cacr,%0\n\t"
- "orw %1,%0\n\t"
- "movec %0,%%cacr"
- : "=&d" (_tmp)
- : "di" (FLUSH_I));
- }
-}
-
-
-/*
- * flush all user-space atc entries.
- */
-static inline void __flush_tlb(void)
-{
- if (CPU_IS_040_OR_060)
- __asm__ __volatile__(".chip 68040\n\t"
- "pflushan\n\t"
- ".chip 68k");
- else
- __asm__ __volatile__("pflush #0,#4");
-}
-
-static inline void __flush_tlb_one(unsigned long addr)
-{
- if (CPU_IS_040_OR_060) {
- __asm__ __volatile__(".chip 68040\n\t"
- "pflush (%0)\n\t"
- ".chip 68k"
- : : "a" (addr));
- } else
- __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr));
-}
-
-#define flush_tlb() __flush_tlb()
-
-/*
- * flush all atc entries (both kernel and user-space entries).
- */
-static inline void flush_tlb_all(void)
-{
- if (CPU_IS_040_OR_060)
- __asm__ __volatile__(".chip 68040\n\t"
- "pflusha\n\t"
- ".chip 68k");
- else
- __asm__ __volatile__("pflusha");
-}
-
-static inline void flush_tlb_mm(struct mm_struct *mm)
-{
- if (mm == current->mm)
- __flush_tlb();
-}
-
-static inline void flush_tlb_page(struct vm_area_struct *vma,
- unsigned long addr)
-{
- if (vma->vm_mm == current->mm)
- __flush_tlb_one(addr);
-}
-
-static inline void flush_tlb_range(struct mm_struct *mm,
- unsigned long start, unsigned long end)
-{
- if (mm == current->mm)
- __flush_tlb();
-}
-
-extern inline void flush_tlb_kernel_page(unsigned long addr)
-{
- if (CPU_IS_040_OR_060) {
- mm_segment_t old_fs = get_fs();
- set_fs(KERNEL_DS);
- __asm__ __volatile__(".chip 68040\n\t"
- "pflush (%0)\n\t"
- ".chip 68k"
- : : "a" (addr));
- set_fs(old_fs);
- } else
- __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
-}
-
/* Certain architectures need to do special things when pte's
* within a page table are directly modified. Thus, the following
* hook is made available.
@@ -391,7 +171,7 @@ extern pte_t * __bad_pagetable(void);
#define BAD_PAGETABLE __bad_pagetable()
#define BAD_PAGE __bad_page()
-#define ZERO_PAGE(vaddr) empty_zero_page
+#define ZERO_PAGE(vaddr) (mem_map + MAP_NR(empty_zero_page))
/* number of bits that fit into a memory pointer */
#define BITS_PER_PTR (8*sizeof(unsigned long))
@@ -403,67 +183,78 @@ extern pte_t * __bad_pagetable(void);
/* 64-bit machines, beware! SRB. */
#define SIZEOF_PTR_LOG2 2
-/* to find an entry in a page-table */
-#define PAGE_PTR(address) \
-((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
-
/*
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*/
-#define mk_pte(page, pgprot) \
-({ pte_t __pte; pte_val(__pte) = virt_to_phys((void *)page) + pgprot_val(pgprot); __pte; })
+#define __mk_pte(page, pgprot) \
+({ \
+ pte_t __pte; \
+ \
+ pte_val(__pte) = __pa((void *)page) + pgprot_val(pgprot); \
+ __pte; \
+})
+#define mk_pte(page, pgprot) __mk_pte(page_address(page), (pgprot))
#define mk_pte_phys(physpage, pgprot) \
-({ pte_t __pte; pte_val(__pte) = (unsigned long)physpage + pgprot_val(pgprot); __pte; })
+({ \
+ pte_t __pte; \
+ \
+ pte_val(__pte) = (physpage) + pgprot_val(pgprot); \
+ __pte; \
+})
extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
{
- int i;
- unsigned long ptbl;
- ptbl = virt_to_phys(ptep) | _PAGE_TABLE | _PAGE_ACCESSED;
- for (i = 0; i < 16; i++, ptbl += (sizeof(pte_t)*PTRS_PER_PTE/16))
- pmdp->pmd[i] = ptbl;
+ unsigned long ptbl = virt_to_phys(ptep) | _PAGE_TABLE | _PAGE_ACCESSED;
+ unsigned long *ptr = pmdp->pmd;
+ short i = 16;
+ while (--i >= 0) {
+ *ptr++ = ptbl;
+ ptbl += (sizeof(pte_t)*PTRS_PER_PTE/16);
+ }
}
extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
-{ pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | virt_to_phys(pmdp); }
-
-extern inline unsigned long pte_page(pte_t pte)
-{ return (unsigned long)phys_to_virt(pte_val(pte) & PAGE_MASK); }
-
-extern inline unsigned long pmd_page2(pmd_t *pmd)
-{ return (unsigned long)phys_to_virt(pmd_val(*pmd) & _TABLE_MASK); }
-#define pmd_page(pmd) pmd_page2(&(pmd))
-
-extern inline unsigned long pgd_page(pgd_t pgd)
-{ return (unsigned long)phys_to_virt(pgd_val(pgd) & _TABLE_MASK); }
-
-extern inline int pte_none(pte_t pte) { return !pte_val(pte); }
-extern inline int pte_present(pte_t pte) { return pte_val(pte) & (_PAGE_PRESENT | _PAGE_FAKE_SUPER); }
-extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; }
-
-extern inline int pmd_none2(pmd_t *pmd) { return !pmd_val(*pmd); }
-#define pmd_none(pmd) pmd_none2(&(pmd))
-extern inline int pmd_bad2(pmd_t *pmd) { return (pmd_val(*pmd) & _DESCTYPE_MASK) != _PAGE_TABLE; }
-#define pmd_bad(pmd) pmd_bad2(&(pmd))
-extern inline int pmd_present2(pmd_t *pmd) { return pmd_val(*pmd) & _PAGE_TABLE; }
-#define pmd_present(pmd) pmd_present2(&(pmd))
-extern inline void pmd_clear(pmd_t * pmdp)
-{
- short i;
-
- for (i = 15; i >= 0; i--)
- pmdp->pmd[i] = 0;
-}
-
-extern inline int pgd_none(pgd_t pgd) { return !pgd_val(pgd); }
-extern inline int pgd_bad(pgd_t pgd) { return (pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE; }
-extern inline int pgd_present(pgd_t pgd) { return pgd_val(pgd) & _PAGE_TABLE; }
-
-extern inline void pgd_clear(pgd_t * pgdp) { pgd_val(*pgdp) = 0; }
+{ pgd_val(*pgdp) = _PAGE_TABLE | _PAGE_ACCESSED | __pa(pmdp); }
+
+#define __pte_page(pte) ((unsigned long)__va(pte_val(pte) & PAGE_MASK))
+#define __pmd_page(pmd) ((unsigned long)__va(pmd_val(pmd) & _TABLE_MASK))
+#define __pgd_page(pgd) ((unsigned long)__va(pgd_val(pgd) & _TABLE_MASK))
+
+#define pte_none(pte) (!pte_val(pte))
+#define pte_present(pte) (pte_val(pte) & (_PAGE_PRESENT | _PAGE_FAKE_SUPER))
+#define pte_clear(ptep) ({ pte_val(*(ptep)) = 0; })
+#define pte_pagenr(pte) ((__pte_page(pte) - PAGE_OFFSET) >> PAGE_SHIFT)
+
+#define pmd_none(pmd) (!pmd_val(pmd))
+#define pmd_bad(pmd) ((pmd_val(pmd) & _DESCTYPE_MASK) != _PAGE_TABLE)
+#define pmd_present(pmd) (pmd_val(pmd) & _PAGE_TABLE)
+#define pmd_clear(pmdp) ({ \
+ unsigned long *__ptr = pmdp->pmd; \
+ short __i = 16; \
+ while (--__i >= 0) \
+ *__ptr++ = 0; \
+})
+
+#define pgd_none(pgd) (!pgd_val(pgd))
+#define pgd_bad(pgd) ((pgd_val(pgd) & _DESCTYPE_MASK) != _PAGE_TABLE)
+#define pgd_present(pgd) (pgd_val(pgd) & _PAGE_TABLE)
+#define pgd_clear(pgdp) ({ pgd_val(*pgdp) = 0; })
+
+/* Permanent address of a page. */
+#define page_address(page) ({ if (!(page)->virtual) BUG(); (page)->virtual; })
+#define __page_address(page) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
+#define pte_page(pte) (mem_map+pte_pagenr(pte))
+
+#define pte_ERROR(e) \
+ printk("%s:%d: bad pte %p(%08lx).\n", __FILE__, __LINE__, &(e), pte_val(e))
+#define pmd_ERROR(e) \
+ printk("%s:%d: bad pmd %p(%08lx).\n", __FILE__, __LINE__, &(e), pmd_val(e))
+#define pgd_ERROR(e) \
+ printk("%s:%d: bad pgd %p(%08lx).\n", __FILE__, __LINE__, &(e), pgd_val(e))
/*
* The following only work if pte_present() is true.
@@ -512,13 +303,13 @@ extern inline pgd_t * pgd_offset_k(unsigned long address)
/* Find an entry in the second-level page table.. */
extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
{
- return (pmd_t *) pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1));
+ return (pmd_t *)__pgd_page(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1));
}
/* Find an entry in the third-level page table.. */
extern inline pte_t * pte_offset(pmd_t * pmdp, unsigned long address)
{
- return (pte_t *) pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
+ return (pte_t *)__pmd_page(*pmdp) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
}
/*
@@ -559,178 +350,6 @@ static inline void cache_page (unsigned long vaddr)
}
}
-extern struct pgtable_cache_struct {
- unsigned long *pmd_cache;
- unsigned long *pte_cache;
-/* This counts in units of pointer tables, of which can be eight per page. */
- unsigned long pgtable_cache_sz;
-} quicklists;
-
-#define pgd_quicklist ((unsigned long *)0)
-#define pmd_quicklist (quicklists.pmd_cache)
-#define pte_quicklist (quicklists.pte_cache)
-/* This isn't accurate because of fragmentation of allocated pages for
- pointer tables, but that should not be a problem. */
-#define pgtable_cache_size ((quicklists.pgtable_cache_sz+7)/8)
-
-extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset);
-extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset);
-
-extern pmd_t *get_pointer_table(void);
-extern int free_pointer_table(pmd_t *);
-
-extern __inline__ pte_t *get_pte_fast(void)
-{
- unsigned long *ret;
-
- ret = pte_quicklist;
- if (ret) {
- pte_quicklist = (unsigned long *)*ret;
- ret[0] = 0;
- quicklists.pgtable_cache_sz -= 8;
- }
- return (pte_t *)ret;
-}
-
-extern __inline__ void free_pte_fast(pte_t *pte)
-{
- *(unsigned long *)pte = (unsigned long)pte_quicklist;
- pte_quicklist = (unsigned long *)pte;
- quicklists.pgtable_cache_sz += 8;
-}
-
-extern __inline__ void free_pte_slow(pte_t *pte)
-{
- cache_page((unsigned long)pte);
- free_page((unsigned long) pte);
-}
-
-extern __inline__ pmd_t *get_pmd_fast(void)
-{
- unsigned long *ret;
-
- ret = pmd_quicklist;
- if (ret) {
- pmd_quicklist = (unsigned long *)*ret;
- ret[0] = 0;
- quicklists.pgtable_cache_sz--;
- }
- return (pmd_t *)ret;
-}
-
-extern __inline__ void free_pmd_fast(pmd_t *pmd)
-{
- *(unsigned long *)pmd = (unsigned long)pmd_quicklist;
- pmd_quicklist = (unsigned long *) pmd;
- quicklists.pgtable_cache_sz++;
-}
-
-extern __inline__ int free_pmd_slow(pmd_t *pmd)
-{
- return free_pointer_table(pmd);
-}
-
-/* The pgd cache is folded into the pmd cache, so these are dummy routines. */
-extern __inline__ pgd_t *get_pgd_fast(void)
-{
- return (pgd_t *)0;
-}
-
-extern __inline__ void free_pgd_fast(pgd_t *pgd)
-{
-}
-
-extern __inline__ void free_pgd_slow(pgd_t *pgd)
-{
-}
-
-extern void __bad_pte(pmd_t *pmd);
-extern void __bad_pmd(pgd_t *pgd);
-
-extern inline void pte_free(pte_t * pte)
-{
- free_pte_fast(pte);
-}
-
-extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
-{
- address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
- if (pmd_none(*pmd)) {
- pte_t * page = get_pte_fast();
-
- if (!page)
- return get_pte_slow(pmd, address);
- pmd_set(pmd,page);
- return page + address;
- }
- if (pmd_bad(*pmd)) {
- __bad_pte(pmd);
- return NULL;
- }
- return (pte_t *) pmd_page(*pmd) + address;
-}
-
-extern inline void pmd_free(pmd_t * pmd)
-{
- free_pmd_fast(pmd);
-}
-
-extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
-{
- address = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
- if (pgd_none(*pgd)) {
- pmd_t *page = get_pmd_fast();
-
- if (!page)
- return get_pmd_slow(pgd, address);
- pgd_set(pgd, page);
- return page + address;
- }
- if (pgd_bad(*pgd)) {
- __bad_pmd(pgd);
- return NULL;
- }
- return (pmd_t *) pgd_page(*pgd) + address;
-}
-
-extern inline void pte_free_kernel(pte_t * pte)
-{
- free_pte_fast(pte);
-}
-
-extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
-{
- return pte_alloc(pmd, address);
-}
-
-extern inline void pmd_free_kernel(pmd_t * pmd)
-{
- free_pmd_fast(pmd);
-}
-
-extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address)
-{
- return pmd_alloc(pgd, address);
-}
-
-extern inline void pgd_free(pgd_t * pgd)
-{
- free_pmd_fast((pmd_t *)pgd);
-}
-
-extern inline pgd_t * pgd_alloc(void)
-{
- pgd_t *pgd = (pgd_t *)get_pmd_fast();
- if (!pgd)
- pgd = (pgd_t *)get_pointer_table();
- return pgd;
-}
-
-extern int do_check_pgt_cache(int, int);
-
-extern inline void set_pgdir(unsigned long address, pgd_t entry)
-{
-}
/*
* Check if the addr/len goes up to the end of a physical
@@ -760,21 +379,12 @@ extern inline void update_mmu_cache(struct vm_area_struct * vma,
{
}
-/*
- * I don't know what is going on here, but since these were changed,
- * swapping hasn't been working on the 68040.
- */
-/* With the new handling of PAGE_NONE the old definitions definitely
- don't work any more. */
-
-#define SWP_TYPE(entry) (((entry) >> 2) & 0x7f)
-#if 0
-#define SWP_OFFSET(entry) ((entry) >> 9)
-#define SWP_ENTRY(type,offset) (((type) << 2) | ((offset) << 9))
-#else
-#define SWP_OFFSET(entry) ((entry) >> PAGE_SHIFT)
-#define SWP_ENTRY(type,offset) (((type) << 2) | ((offset) << PAGE_SHIFT))
-#endif
+/* Encode and de-code a swap entry (must be !pte_none(e) && !pte_present(e)) */
+#define SWP_TYPE(x) (((x).val >> 1) & 0xff)
+#define SWP_OFFSET(x) ((x).val >> 10)
+#define SWP_ENTRY(type, offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 10) })
+#define pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
+#define swp_entry_to_pte(x) ((pte_t) { (x).val })
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-m68k/poll.h b/include/asm-m68k/poll.h
index f66153a74..32dcf6490 100644
--- a/include/asm-m68k/poll.h
+++ b/include/asm-m68k/poll.h
@@ -11,6 +11,7 @@
#define POLLWRNORM POLLOUT
#define POLLRDBAND 128
#define POLLWRBAND 256
+#define POLLMSG 0x0400
struct pollfd {
int fd;
diff --git a/include/asm-m68k/semaphore.h b/include/asm-m68k/semaphore.h
index cb4f38230..16ab57862 100644
--- a/include/asm-m68k/semaphore.h
+++ b/include/asm-m68k/semaphore.h
@@ -1,6 +1,8 @@
#ifndef _M68K_SEMAPHORE_H
#define _M68K_SEMAPHORE_H
+#ifndef __ASSEMBLY__
+
#include <linux/linkage.h>
#include <linux/wait.h>
#include <linux/spinlock.h>
@@ -9,13 +11,14 @@
#include <asm/atomic.h>
/*
- * SMP- and interrupt-safe semaphores..
+ * Interrupt-safe semaphores..
*
* (C) Copyright 1996 Linus Torvalds
*
* m68k version by Andreas Schwab
*/
+
struct semaphore {
atomic_t count;
atomic_t waking;
@@ -180,4 +183,174 @@ extern inline void up(struct semaphore * sem)
: "memory");
}
+
+/* rw mutexes (should that be mutices? =) -- throw rw
+ * spinlocks and semaphores together, and this is what we
+ * end up with...
+ *
+ * m68k version by Roman Zippel
+ */
+
+struct rw_semaphore {
+ atomic_t count;
+ volatile unsigned char write_bias_granted;
+ volatile unsigned char read_bias_granted;
+ volatile unsigned char pad1;
+ volatile unsigned char pad2;
+ wait_queue_head_t wait;
+ wait_queue_head_t write_bias_wait;
+#if WAITQUEUE_DEBUG
+ long __magic;
+ atomic_t readers;
+ atomic_t writers;
+#endif
+};
+#endif /* __ASSEMBLY__ */
+
+#define RW_LOCK_BIAS 0x01000000
+
+#ifndef __ASSEMBLY__
+
+extern inline void down_read(struct rw_semaphore *sem)
+{
+ register struct rw_semaphore *__sem __asm__ ("%a1") = sem;
+
+#if WAITQUEUE_DEBUG
+ if (sem->__magic != (long)&sem->__magic)
+ BUG();
+#endif
+ __asm__ __volatile__(
+ "| atomic down_read operation\n\t"
+ "subql #1,%0@\n\t"
+ "jmi 2f\n"
+ "1:\n"
+ ".section .text.lock,\"ax\"\n"
+ ".even\n"
+ "2:\n\t"
+ "pea 1b\n\t"
+ "jbra __down_read_failed\n"
+ ".previous"
+ : /* no outputs */
+ : "a" (__sem)
+ : "memory");
+#if WAITQUEUE_DEBUG
+ if (sem->write_bias_granted)
+ BUG();
+ if (atomic_read(&sem->writers))
+ BUG();
+ atomic_inc(&sem->readers);
+#endif
+}
+
+extern inline void down_write(struct rw_semaphore *sem)
+{
+ register struct rw_semaphore *__sem __asm__ ("%a1") = sem;
+
+#if WAITQUEUE_DEBUG
+ if (sem->__magic != (long)&sem->__magic)
+ BUG();
+#endif
+ __asm__ __volatile__(
+ "| atomic down_write operation\n\t"
+ "subl %1,%0@\n\t"
+ "jne 2f\n"
+ "1:\n"
+ ".section .text.lock,\"ax\"\n"
+ ".even\n"
+ "2:\n\t"
+ "pea 1b\n\t"
+ "jbra __down_write_failed\n"
+ ".previous"
+ : /* no outputs */
+ : "a" (__sem), "id" (RW_LOCK_BIAS)
+ : "memory");
+#if WAITQUEUE_DEBUG
+ if (atomic_read(&sem->writers))
+ BUG();
+ if (atomic_read(&sem->readers))
+ BUG();
+ if (sem->read_bias_granted)
+ BUG();
+ if (sem->write_bias_granted)
+ BUG();
+ atomic_inc(&sem->writers);
+#endif
+}
+
+/* When a reader does a release, the only significant
+ * case is when there was a writer waiting, and we've
+ * bumped the count to 0: we must wake the writer up.
+ */
+extern inline void __up_read(struct rw_semaphore *sem)
+{
+ register struct rw_semaphore *__sem __asm__ ("%a1") = sem;
+
+ __asm__ __volatile__(
+ "| atomic up_read operation\n\t"
+ "addql #1,%0@\n\t"
+ "jeq 2f\n"
+ "1:\n"
+ ".section .text.lock,\"ax\"\n"
+ ".even\n"
+ "2:\n\t"
+ "pea 1b\n\t"
+ "jbra __rwsem_wake\n"
+ ".previous"
+ : /* no outputs */
+ : "a" (__sem)
+ : "memory");
+}
+
+extern inline void up_read(struct rw_semaphore *sem)
+{
+#if WAITQUEUE_DEBUG
+ if (sem->write_bias_granted)
+ BUG();
+ if (atomic_read(&sem->writers))
+ BUG();
+ atomic_dec(&sem->readers);
+#endif
+ __up_read(sem);
+}
+
+/* releasing the writer is easy -- just release it and
+ * wake up any sleepers.
+ */
+extern inline void __up_write(struct rw_semaphore *sem)
+{
+ register struct rw_semaphore *__sem __asm__ ("%a1") = sem;
+
+ __asm__ __volatile__(
+ "| atomic up_write operation\n\t"
+ "addl %1,%0@\n\t"
+ "jcs 2f\n"
+ "1:\n"
+ ".section .text.lock,\"ax\"\n"
+ ".even\n"
+ "2:\n\t"
+ "pea 1b\n\t"
+ "jbra __rwsem_wake\n"
+ ".previous"
+ : /* no outputs */
+ : "a" (__sem), "id" (RW_LOCK_BIAS)
+ : "memory");
+}
+
+extern inline void up_write(struct rw_semaphore *sem)
+{
+#if WAITQUEUE_DEBUG
+ if (sem->read_bias_granted)
+ BUG();
+ if (sem->write_bias_granted)
+ BUG();
+ if (atomic_read(&sem->readers))
+ BUG();
+ if (atomic_read(&sem->writers) != 1)
+ BUG();
+ atomic_dec(&sem->writers);
+#endif
+ __up_write(sem);
+}
+#endif /* __ASSEMBLY__ */
+
#endif
diff --git a/include/asm-m68k/setup.h b/include/asm-m68k/setup.h
index b2b11ed76..6d198bc5f 100644
--- a/include/asm-m68k/setup.h
+++ b/include/asm-m68k/setup.h
@@ -246,6 +246,9 @@ extern unsigned long m68k_machtype;
extern unsigned long m68k_cputype;
extern unsigned long m68k_fputype;
extern unsigned long m68k_mmutype; /* Not really used yet */
+#ifdef CONFIG_VME
+extern unsigned long vme_brdtype;
+#endif
/*
* m68k_is040or060 is != 0 for a '040 or higher;
diff --git a/include/asm-m68k/siginfo.h b/include/asm-m68k/siginfo.h
index 2dac2b063..4061e6f72 100644
--- a/include/asm-m68k/siginfo.h
+++ b/include/asm-m68k/siginfo.h
@@ -24,8 +24,7 @@ typedef struct siginfo {
/* kill() */
struct {
pid_t _pid; /* sender's pid */
- old_uid_t _uid; /* backwards compatibility */
- uid_t _uid32; /* sender's uid */
+ uid_t _uid; /* sender's uid */
} _kill;
/* POSIX.1b timers */
@@ -37,19 +36,17 @@ typedef struct siginfo {
/* POSIX.1b signals */
struct {
pid_t _pid; /* sender's pid */
- old_uid_t _uid; /* backwards compatibility */
+ uid_t _uid; /* sender's uid */
sigval_t _sigval;
- uid_t _uid32; /* sender's uid */
} _rt;
/* SIGCHLD */
struct {
pid_t _pid; /* which child */
- old_uid_t _uid; /* backwards compatibility */
+ uid_t _uid; /* sender's uid */
int _status; /* exit code */
clock_t _utime;
clock_t _stime;
- uid_t _uid32; /* sender's uid */
} _sigchld;
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
@@ -65,18 +62,11 @@ typedef struct siginfo {
} _sifields;
} siginfo_t;
-#define UID16_SIGINFO_COMPAT_NEEDED
-
/*
* How these fields are to be accessed.
*/
#define si_pid _sifields._kill._pid
-#ifdef __KERNEL__
-#define si_uid _sifields._kill._uid32
-#define si_uid16 _sifields._kill._uid
-#else
#define si_uid _sifields._kill._uid
-#endif /* __KERNEL__ */
#define si_status _sifields._sigchld._status
#define si_utime _sifields._sigchld._utime
#define si_stime _sifields._sigchld._stime
diff --git a/include/asm-m68k/stat.h b/include/asm-m68k/stat.h
index c2145c33d..b28ce37c5 100644
--- a/include/asm-m68k/stat.h
+++ b/include/asm-m68k/stat.h
@@ -38,8 +38,40 @@ struct stat {
unsigned long __unused5;
};
-/* stat64 struct goes here -- someone please make
- * it mesh with whatever glibc does in userland on
- * m68k's.
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
*/
+struct stat64 {
+ unsigned short st_dev;
+ unsigned char __pad0[10];
+
+ unsigned long st_ino;
+ unsigned int st_mode;
+ unsigned int st_nlink;
+
+ unsigned long st_uid;
+ unsigned long st_gid;
+
+ unsigned short st_rdev;
+ unsigned char __pad3[10];
+
+ long long st_size;
+ unsigned long st_blksize;
+
+ unsigned long st_blocks; /* Number 512-byte blocks allocated. */
+ unsigned long __pad4; /* future possible st_blocks high bits */
+
+ unsigned long st_atime;
+ unsigned long __pad5;
+
+ unsigned long st_mtime;
+ unsigned long __pad6;
+
+ unsigned long st_ctime;
+ unsigned long __pad7; /* will be high 32 bits of ctime someday */
+
+ unsigned long __unused1;
+ unsigned long __unused2;
+};
+
#endif /* _M68K_STAT_H */
diff --git a/include/asm-m68k/system.h b/include/asm-m68k/system.h
index 7d1afa286..7b6ae7d16 100644
--- a/include/asm-m68k/system.h
+++ b/include/asm-m68k/system.h
@@ -4,6 +4,7 @@
#include <linux/config.h> /* get configuration macros */
#include <linux/linkage.h>
#include <asm/segment.h>
+#include <asm/entry.h>
#define prepare_to_switch() do { } while(0)
@@ -44,36 +45,52 @@ asmlinkage void resume(void);
(last) = _last; \
}
+
+/* interrupt control.. */
+#if 0
+#define __sti() asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory")
+#else
+#include <asm/hardirq.h>
+#define __sti() ({ \
+ if (!local_irq_count[smp_processor_id()]) \
+ asm volatile ("andiw %0,%%sr": : "i" (ALLOWINT) : "memory"); \
+})
+#endif
+#define __cli() asm volatile ("oriw #0x0700,%%sr": : : "memory")
+#define __save_flags(x) asm volatile ("movew %%sr,%0":"=d" (x) : : "memory")
+#define __restore_flags(x) asm volatile ("movew %0,%%sr": :"d" (x) : "memory")
+
+/* For spinlocks etc */
+#define local_irq_save(x) ({ __save_flags(x); __cli(); })
+#define local_irq_restore(x) __restore_flags(x)
+#define local_irq_disable() __cli()
+#define local_irq_enable() __sti()
+
+#define cli() __cli()
+#define sti() __sti()
+#define save_flags(x) __save_flags(x)
+#define restore_flags(x) __restore_flags(x)
+
+
+/*
+ * Force strict CPU ordering.
+ * Not really required on m68k...
+ */
+#define nop() asm volatile ("nop"::)
+#define mb() asm volatile ("" : : :"memory")
+#define rmb() asm volatile ("" : : :"memory")
+#define wmb() asm volatile ("" : : :"memory")
+#define set_rmb(var, value) do { xchg(&var, value); } while (0)
+#define set_mb(var, value) set_rmb(var, value)
+#define set_wmb(var, value) do { var = value; wmb(); } while (0)
+
+
#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
#define tas(ptr) (xchg((ptr),1))
struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((volatile struct __xchg_dummy *)(x))
-#if defined(MACH_ATARI_ONLY) && !defined(CONFIG_HADES)
-/* block out HSYNC on the atari */
-#define __sti() __asm__ __volatile__ ("andiw #0xfbff,%/sr": : : "memory")
-#else /* portable version */
-#define __sti() __asm__ __volatile__ ("andiw #0xf8ff,%/sr": : : "memory")
-#endif /* machine compilation types */
-#define __cli() __asm__ __volatile__ ("oriw #0x0700,%/sr": : : "memory")
-#define nop() __asm__ __volatile__ ("nop"::)
-#define mb() __asm__ __volatile__ ("" : : :"memory")
-#define rmb() __asm__ __volatile__ ("" : : :"memory")
-#define wmb() __asm__ __volatile__ ("" : : :"memory")
-
-#define __save_flags(x) \
-__asm__ __volatile__("movew %/sr,%0":"=d" (x) : /* no input */ :"memory")
-
-#define __restore_flags(x) \
-__asm__ __volatile__("movew %0,%/sr": /* no outputs */ :"d" (x) : "memory")
-
-#define cli() __cli()
-#define sti() __sti()
-#define save_flags(x) __save_flags(x)
-#define restore_flags(x) __restore_flags(x)
-#define save_and_cli(flags) do { save_flags(flags); cli(); } while(0)
-
#ifndef CONFIG_RMW_INSNS
static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{
diff --git a/include/asm-m68k/termios.h b/include/asm-m68k/termios.h
index 07f6b8585..0f127c134 100644
--- a/include/asm-m68k/termios.h
+++ b/include/asm-m68k/termios.h
@@ -43,6 +43,9 @@ struct termio {
#define TIOCM_DSR 0x100
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG
+#define TIOCM_OUT1 0x2000
+#define TIOCM_OUT2 0x4000
+#define TIOCM_LOOP 0x8000
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
diff --git a/include/asm-m68k/uaccess.h b/include/asm-m68k/uaccess.h
index 548ce9ede..82897ade9 100644
--- a/include/asm-m68k/uaccess.h
+++ b/include/asm-m68k/uaccess.h
@@ -799,33 +799,46 @@ strncpy_from_user(char *dst, const char *src, long count)
/*
* Return the size of a string (including the ending 0)
*
- * Return 0 for error
+ * Return 0 on exception, a value greater than N if too long
*/
-static inline long strlen_user(const char * src)
+static inline long strnlen_user(const char *src, long n)
{
- long res = -(long) src;
- __asm__ __volatile__
- ("1: movesb (%1)+,%%d0\n"
- "12:tstb %%d0\n"
- " jne 1b\n"
- " addl %1,%0\n"
- "2:\n"
- ".section .fixup,\"ax\"\n"
- " .even\n"
- "3: moveq %2,%0\n"
- " jra 2b\n"
- ".previous\n"
- ".section __ex_table,\"a\"\n"
- " .align 4\n"
- " .long 1b,3b\n"
- " .long 12b,3b\n"
- ".previous"
- : "=d"(res), "=a"(src)
- : "i"(0), "0"(res), "1"(src)
- : "d0");
- return res;
+ long res;
+
+ res = -(long)src;
+ __asm__ __volatile__
+ ("1:\n"
+ " tstl %2\n"
+ " jeq 3f\n"
+ "2: movesb (%1)+,%%d0\n"
+ "22:\n"
+ " subql #1,%2\n"
+ " tstb %%d0\n"
+ " jne 1b\n"
+ " jra 4f\n"
+ "3:\n"
+ " addql #1,%0\n"
+ "4:\n"
+ " addl %1,%0\n"
+ "5:\n"
+ ".section .fixup,\"ax\"\n"
+ " .even\n"
+ "6: moveq %3,%0\n"
+ " jra 5b\n"
+ ".previous\n"
+ ".section __ex_table,\"a\"\n"
+ " .align 4\n"
+ " .long 2b,6b\n"
+ " .long 22b,6b\n"
+ ".previous"
+ : "=d"(res), "=a"(src), "=d"(n)
+ : "i"(0), "0"(res), "1"(src), "2"(n)
+ : "d0");
+ return res;
}
+#define strlen_user(str) strnlen_user(str, 32767)
+
/*
* Zero Userspace
*/
diff --git a/include/asm-m68k/virtconvert.h b/include/asm-m68k/virtconvert.h
index 302308d88..4841264ab 100644
--- a/include/asm-m68k/virtconvert.h
+++ b/include/asm-m68k/virtconvert.h
@@ -9,6 +9,7 @@
#include <linux/config.h>
#include <asm/setup.h>
+#include <asm/page.h>
#ifdef CONFIG_AMIGA
#include <asm/amigahw.h>
@@ -34,22 +35,22 @@ extern inline unsigned long mm_ptov(unsigned long paddr)
#endif
#ifdef CONFIG_SINGLE_MEMORY_CHUNK
-extern inline unsigned long virt_to_phys(volatile void * address)
+extern inline unsigned long virt_to_phys(volatile void *vaddr)
{
- unsigned long voff = (unsigned long) address;
+ unsigned long voff = (unsigned long)vaddr - PAGE_OFFSET;
if (voff < m68k_memory[0].size)
- return m68k_memory[0].addr + voff;
- else
- return mm_vtop_fallback(voff);
+ return voff + m68k_memory[0].addr;
+ return mm_vtop_fallback((unsigned long)vaddr);
}
extern inline void * phys_to_virt(unsigned long paddr)
{
- unsigned long base = m68k_memory[0].addr;
+ unsigned long poff = paddr - m68k_memory[0].addr;
+
+ if (poff < m68k_memory[0].size)
+ return (void *)(poff + PAGE_OFFSET);
- if ((paddr >= base) && (paddr < (base + m68k_memory[0].size)))
- return (void *)(paddr - base);
#ifdef CONFIG_AMIGA
/*
* if on an amiga and address is in first 16M, move it