diff options
Diffstat (limited to 'include/asm-arm')
113 files changed, 2415 insertions, 2937 deletions
diff --git a/include/asm-arm/a.out.h b/include/asm-arm/a.out.h index 489d76eb5..ae967b0a6 100644 --- a/include/asm-arm/a.out.h +++ b/include/asm-arm/a.out.h @@ -26,7 +26,9 @@ struct exec #define M_ARM 103 +#ifdef __KERNEL__ #include <asm/arch/a.out.h> +#endif #ifndef LIBRARY_START_TEXT #define LIBRARY_START_TEXT (0x00c00000) diff --git a/include/asm-arm/arch-arc/a.out.h b/include/asm-arm/arch-arc/a.out.h index e00511463..0c13102d0 100644 --- a/include/asm-arm/arch-arc/a.out.h +++ b/include/asm-arm/arch-arc/a.out.h @@ -1,16 +1,14 @@ /* * linux/include/asm-arm/arch-arc/a.out.h * - * Copyright (C) 1996 Russell King - * - * Acorn Archimedes/A5000 a.out.h specs + * Copyright (C) 1996-1999 Russell King */ #ifndef __ASM_ARCH_A_OUT_H #define __ASM_ARCH_A_OUT_H -#ifdef __KERNEL__ -#define STACK_TOP (0x01a00000) -#endif +#include <asm/arch/memory.h> + +#define STACK_TOP TASK_SIZE #endif diff --git a/include/asm-arm/arch-arc/hardware.h b/include/asm-arm/arch-arc/hardware.h index c59007f3c..33b4659f8 100644 --- a/include/asm-arm/arch-arc/hardware.h +++ b/include/asm-arm/arch-arc/hardware.h @@ -1,7 +1,7 @@ /* * linux/include/asm-arm/arch-arc/hardware.h * - * Copyright (C) 1996 Russell King. + * Copyright (C) 1996-1999 Russell King. * * This file contains the hardware definitions of the * Acorn Archimedes/A5000 machines. @@ -9,21 +9,20 @@ * Modifications: * 04-04-1998 PJB/RMK Merged arc and a5k versions */ - #ifndef __ASM_ARCH_HARDWARE_H #define __ASM_ARCH_HARDWARE_H #include <linux/config.h> +#include <asm/arch/memory.h> + /* * What hardware must be present - these can be tested by the kernel * source. */ #define HAS_IOC -#include <asm/ioc.h> #define HAS_MEMC #include <asm/memc.h> -#define HAS_MEMC1A #define HAS_VIDC /* @@ -56,6 +55,12 @@ * for use with inb/outb */ #define IO_VIDC_BASE 0x80100000 +#ifdef CONFIG_ARCH_A5K +#define IOEB_VID_CTL 0x800d4012 +#define IOEB_PRESENT 0x800d4014 +#define IOEB_PSCLR 0x800d4016 +#define IOEB_MONTYPE 0x800d401c +#endif #ifdef CONFIG_ARCH_ARC #define LATCHAADDR 0x80094010 #define LATCHBADDR 0x80094006 @@ -66,6 +71,14 @@ #define IO_EC_IOC_BASE 0x80090000 #define IO_EC_MEMC_BASE 0x80000000 +#ifdef CONFIG_ARCH_ARC +/* A680 hardware */ +#define WD1973_BASE 0x03290000 +#define WD1973_LATCH 0x03350000 +#define Z8530_BASE 0x032b0008 +#define SCSI_BASE 0x03100000 +#endif + /* * IO definitions */ @@ -77,11 +90,8 @@ /* * RAM definitions */ -#define MAPTOPHYS(a) (((unsigned long)a & 0x007fffff) + PAGE_OFFSET) -#define KERNTOPHYS(a) ((((unsigned long)(&a)) & 0x007fffff) + PAGE_OFFSET) #define GET_MEMORY_END(p) (PAGE_OFFSET + (p->u1.s.page_size) * (p->u1.s.nr_pages)) #define PARAMS_BASE (PAGE_OFFSET + 0x7c000) -#define KERNEL_BASE (PAGE_OFFSET + 0x80000) #else diff --git a/include/asm-arm/arch-arc/irq.h b/include/asm-arm/arch-arc/irq.h index 0faabaf4d..97d3722bd 100644 --- a/include/asm-arm/arch-arc/irq.h +++ b/include/asm-arm/arch-arc/irq.h @@ -10,6 +10,9 @@ * 11-01-1998 RMK Added mask_and_ack_irq * 22-08-1998 RMK Restructured IRQ routines */ +#include <asm/ioc.h> + +#define fixup_irq(x) (x) static void arc_mask_irq_ack_a(unsigned int irq) { @@ -108,10 +111,17 @@ static __inline__ void irq_init_irq(void) outb(0, IOC_FIQMASK); for (irq = 0; irq < NR_IRQS; irq++) { - switch (irq & 0xf8) { + switch (irq) { case 0 ... 6: irq_desc[irq].probe_ok = 1; + irq_desc[irq].valid = 1; + irq_desc[irq].mask_ack = arc_mask_irq_ack_a; + irq_desc[irq].mask = arc_mask_irq_a; + irq_desc[irq].unmask = arc_unmask_irq_a; + break; + case 7: + irq_desc[irq].noautoenable = 1; irq_desc[irq].valid = 1; irq_desc[irq].mask_ack = arc_mask_irq_ack_a; irq_desc[irq].mask = arc_mask_irq_a; diff --git a/include/asm-arm/arch-arc/keyboard.h b/include/asm-arm/arch-arc/keyboard.h index 388014703..1f57b9757 100644 --- a/include/asm-arm/arch-arc/keyboard.h +++ b/include/asm-arm/arch-arc/keyboard.h @@ -11,7 +11,6 @@ #define NR_SCANCODES 128 -extern int a5kkbd_translate(unsigned char scancode, unsigned char *keycode_p, char *up_flag_p); extern void a5kkbd_leds(unsigned char leds); extern void a5kkbd_init_hw(void); extern unsigned char a5kkbd_sysrq_xlate[NR_SCANCODES]; @@ -19,16 +18,7 @@ extern unsigned char a5kkbd_sysrq_xlate[NR_SCANCODES]; #define kbd_setkeycode(sc,kc) (-EINVAL) #define kbd_getkeycode(sc) (-EINVAL) -/* Prototype: int kbd_pretranslate(scancode, raw_mode) - * Returns : 0 to ignore scancode - */ -#define kbd_pretranslate(sc,rm) (1) - -/* Prototype: int kbd_translate(scancode, *keycode, *up_flag, raw_mode) - * Returns : 0 to ignore scancode, *keycode set to keycode, *up_flag - * set to 0200 if scancode indicates release - */ -#define kbd_translate(sc, kcp, ufp, rm) a5kkbd_translate(sc, kcp, ufp) +#define kbd_translate(sc, kcp, rm) ({ *(kcp) = (sc); 1; }) #define kbd_unexpected_up(kc) (0200) #define kbd_leds(leds) a5kkbd_leds(leds) #define kbd_init_hw() a5kkbd_init_hw() diff --git a/include/asm-arm/arch-arc/mmu.h b/include/asm-arm/arch-arc/memory.h index 1e54d9863..8741f6222 100644 --- a/include/asm-arm/arch-arc/mmu.h +++ b/include/asm-arm/arch-arc/memory.h @@ -1,13 +1,25 @@ /* - * linux/include/asm-arm/arch-arc/mmu.h + * linux/include/asm-arm/arch-arc/memory.h * - * Copyright (c) 1996 Russell King. + * Copyright (c) 1996-1999 Russell King. * * Changelog: - * 22-11-1996 RMK Created + * 22-Nov-1996 RMK Created + * 21-Mar-1999 RMK Renamed to memory.h + * RMK Moved PAGE_OFFSET and TASK_SIZE here */ -#ifndef __ASM_ARCH_MMU_H -#define __ASM_ARCH_MMU_H +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +/* + * User space: 26MB + */ +#define TASK_SIZE (0x01a00000UL) + +/* + * Page offset: 32MB + */ +#define PAGE_OFFSET (0x02000000UL) #define __virt_to_phys__is_a_macro #define __virt_to_phys(vpage) vpage diff --git a/include/asm-arm/arch-arc/oldlatches.h b/include/asm-arm/arch-arc/oldlatches.h index 3252e1109..42f4c22f4 100644 --- a/include/asm-arm/arch-arc/oldlatches.h +++ b/include/asm-arm/arch-arc/oldlatches.h @@ -34,6 +34,8 @@ void oldlatch_bupdate(unsigned char mask,unsigned char newdata); /* newval=(oldval & mask)|newdata */ void oldlatch_aupdate(unsigned char mask,unsigned char newdata); +void oldlatch_init(void); + #elif defined(CONFIG_ARCH_A5K) #ifdef __need_oldlatches diff --git a/include/asm-arm/arch-arc/processor.h b/include/asm-arm/arch-arc/processor.h index cb63936e4..acc587961 100644 --- a/include/asm-arm/arch-arc/processor.h +++ b/include/asm-arm/arch-arc/processor.h @@ -1,15 +1,18 @@ /* * linux/include/asm-arm/arch-arc/processor.h * - * Copyright (c) 1996 Russell King. + * Copyright (c) 1996-1999 Russell King. * * Changelog: - * 10-09-1996 RMK Created + * 10-Sep-1996 RMK Created + * 21-Mar-1999 RMK Added asm/arch/memory.h */ #ifndef __ASM_ARCH_PROCESSOR_H #define __ASM_ARCH_PROCESSOR_H +#include <asm/arch/memory.h> + /* * Bus types */ @@ -18,17 +21,9 @@ #define MCA_bus 0 #define MCA_bus__is_a_macro /* for versions in ksyms.c */ -/* - * User space: 26MB - */ -#define TASK_SIZE (0x01a00000UL) - /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ #define TASK_UNMAPPED_BASE (TASK_SIZE / 3) -#define INIT_MMAP \ -{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } - #endif diff --git a/include/asm-arm/arch-arc/time.h b/include/asm-arm/arch-arc/time.h index 6df347484..c02ac8df5 100644 --- a/include/asm-arm/arch-arc/time.h +++ b/include/asm-arm/arch-arc/time.h @@ -8,6 +8,9 @@ * 10-Oct-1996 RMK Brought up to date with arch-sa110eval * 04-Dec-1997 RMK Updated for new arch/arm/time.c */ +#include <asm/ioc.h> + +static long last_rtc_update = 0; /* last time the cmos clock got updated */ extern __inline__ unsigned long gettimeoffset (void) { @@ -51,46 +54,140 @@ extern __inline__ unsigned long gettimeoffset (void) return offset; } -/* - * No need to reset the timer at every irq - */ -#define reset_timer() 1 +extern int iic_control (unsigned char, int, char *, int); -/* - * Updating of the RTC. We don't currently write the time to the - * CMOS clock. - */ -#define update_rtc() +static int set_rtc_time(unsigned long nowtime) +{ + char buf[5], ctrl; + + if (iic_control(0xa1, 0, &ctrl, 1) != 0) + printk("RTC: failed to read control reg\n"); + + /* + * Reset divider + */ + ctrl |= 0x80; + + if (iic_control(0xa0, 0, &ctrl, 1) != 0) + printk("RTC: failed to stop the clock\n"); + + /* + * We only set the time - we don't set the date. + * This means that there is the possibility once + * a day for the correction to disrupt the date. + * We really ought to write the time and date, or + * nothing at all. + */ + buf[0] = 0; + buf[1] = nowtime % 60; nowtime /= 60; + buf[2] = nowtime % 60; nowtime /= 60; + buf[3] = nowtime % 24; + + BIN_TO_BCD(buf[1]); + BIN_TO_BCD(buf[2]); + BIN_TO_BCD(buf[3]); + + if (iic_control(0xa0, 1, buf, 4) != 0) + printk("RTC: Failed to set the time\n"); + + /* + * Re-enable divider + */ + ctrl &= ~0x80; + + if (iic_control(0xa0, 0, &ctrl, 1) != 0) + printk("RTC: failed to start the clock\n"); + + return 0; +} + +extern __inline__ unsigned long get_rtc_time(void) +{ + unsigned int year, i; + char buf[8]; + + /* + * The year is not part of the RTC counter + * registers, and is stored in RAM. This + * means that it will not be automatically + * updated. + */ + if (iic_control(0xa1, 0xc0, buf, 1) != 0) + printk("RTC: failed to read the year\n"); + + /* + * If the year is before 1970, then the year + * is actually 100 in advance. This gives us + * a year 2070 bug... + */ + year = 1900 + buf[0]; + if (year < 1970) + year += 100; + + /* + * Read the time and date in one go - this + * will ensure that we don't get any effects + * due to carry (the RTC latches the counters + * during a read). + */ + if (iic_control(0xa1, 2, buf, 5) != 0) { + printk("RTC: failed to read the time and date\n"); + memset(buf, 0, sizeof(buf)); + } + + /* + * The RTC combines years with date and weekday + * with month. We need to mask off this extra + * information before converting the date to + * binary. + */ + buf[4] &= 0x1f; + buf[3] &= 0x3f; + + for (i = 0; i < 5; i++) + BCD_TO_BIN(buf[i]); + + return mktime(year, buf[4], buf[3], buf[2], buf[1], buf[0]); +} + +static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + do_timer(regs); + + /* If we have an externally synchronized linux clock, then update + * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be + * called as close as possible to 500 ms before the new second starts. + */ + if ((time_status & STA_UNSYNC) == 0 && + xtime.tv_sec > last_rtc_update + 660 && + xtime.tv_usec >= 50000 - (tick >> 1) && + xtime.tv_usec < 50000 + (tick >> 1)) { + if (set_rtc_time(xtime.tv_sec) == 0) + last_rtc_update = xtime.tv_sec; + else + last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ + } +} + +static struct irqaction timerirq = { + timer_interrupt, + 0, + 0, + "timer", + NULL, + NULL +}; /* * Set up timer interrupt, and return the current time in seconds. */ -extern __inline__ unsigned long setup_timer (void) +extern __inline__ void setup_timer(void) { - extern int iic_control (unsigned char, int, char *, int); - unsigned int year, mon, day, hour, min, sec; - char buf[8]; - outb(LATCH & 255, IOC_T0LTCHL); outb(LATCH >> 8, IOC_T0LTCHH); outb(0, IOC_T0GO); - iic_control (0xa0, 0xc0, buf, 1); - year = buf[0]; - if ((year += 1900) < 1970) - year += 100; + xtime.tv_sec = get_rtc_time(); - iic_control (0xa0, 2, buf, 5); - mon = buf[4] & 0x1f; - day = buf[3] & 0x3f; - hour = buf[2]; - min = buf[1]; - sec = buf[0]; - BCD_TO_BIN(mon); - BCD_TO_BIN(day); - BCD_TO_BIN(hour); - BCD_TO_BIN(min); - BCD_TO_BIN(sec); - - return mktime(year, mon, day, hour, min, sec); + setup_arm_irq(IRQ_TIMER, &timerirq); } diff --git a/include/asm-arm/arch-arc/uncompress.h b/include/asm-arm/arch-arc/uncompress.h index f8c274f86..d9b46f1af 100644 --- a/include/asm-arm/arch-arc/uncompress.h +++ b/include/asm-arm/arch-arc/uncompress.h @@ -5,8 +5,6 @@ */ #define VIDMEM ((char *)0x02000000) -#include "../arch/arm/drivers/char/font.h" - int video_num_columns, video_num_lines, video_size_row; int white, bytes_per_char_h; extern unsigned long con_charconvtable[256]; diff --git a/include/asm-arm/arch-ebsa110/a.out.h b/include/asm-arm/arch-ebsa110/a.out.h index 2746584c8..71fcffe8e 100644 --- a/include/asm-arm/arch-ebsa110/a.out.h +++ b/include/asm-arm/arch-ebsa110/a.out.h @@ -1,15 +1,16 @@ /* * linux/include/asm-arm/arch-ebsa110/a.out.h * - * Copyright (C) 1996 Russell King + * Copyright (C) 1996-1999 Russell King */ - #ifndef __ASM_ARCH_A_OUT_H #define __ASM_ARCH_A_OUT_H -#ifdef __KERNEL__ -#define STACK_TOP ((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000) -#endif +#include <asm/arch/memory.h> + +#define STACK_TOP \ + ((current->personality == PER_LINUX_32BIT) ? \ + TASK_SIZE : 0x04000000) #endif diff --git a/include/asm-arm/arch-ebsa110/hardware.h b/include/asm-arm/arch-ebsa110/hardware.h index e502b0fc6..5cad83502 100644 --- a/include/asm-arm/arch-ebsa110/hardware.h +++ b/include/asm-arm/arch-ebsa110/hardware.h @@ -1,19 +1,13 @@ /* * linux/include/asm-arm/arch-ebsa110/hardware.h * - * Copyright (C) 1996,1997,1998 Russell King. + * Copyright (C) 1996-1999 Russell King. * * This file contains the hardware definitions of the EBSA-110. */ - #ifndef __ASM_ARCH_HARDWARE_H #define __ASM_ARCH_HARDWARE_H -/* - * What hardware must be present - */ -#define HAS_PCIO - #ifndef __ASSEMBLER__ /* @@ -23,28 +17,28 @@ #define PIT_T2 ((volatile unsigned char *)0xf2000009) #define PIT_T1 ((volatile unsigned char *)0xf2000005) #define PIT_T0 ((volatile unsigned char *)0xf2000001) -#define PCIO_BASE 0xf0000000 /* * Mapping areas */ #define IO_BASE 0xe0000000 -#define IO_SIZE 0x20000000 -#define IO_START 0xe0000000 /* * RAM definitions */ -#define MAPTOPHYS(a) ((unsigned long)(a) - PAGE_OFFSET) -#define KERNTOPHYS(a) ((unsigned long)(&a)) -#define KERNEL_BASE (0xc0008000) #define FLUSH_BASE_PHYS 0x40000000 #else -#define PCIO_BASE 0xf0000000 #define IO_BASE 0 #endif + +#define IO_SIZE 0x20000000 +#define IO_START 0xe0000000 + +#define FLUSH_BASE 0xdf000000 +#define PCIO_BASE 0xf0000000 + #endif diff --git a/include/asm-arm/arch-ebsa110/irq.h b/include/asm-arm/arch-ebsa110/irq.h index 2f8b804d5..d26e93c76 100644 --- a/include/asm-arm/arch-ebsa110/irq.h +++ b/include/asm-arm/arch-ebsa110/irq.h @@ -11,6 +11,8 @@ #define IRQ_MSET ((volatile unsigned char *)0xf2c00000) #define IRQ_MASK ((volatile unsigned char *)0xf2c00000) +#define fixup_irq(x) (x) + static void ebsa110_mask_and_ack_irq(unsigned int irq) { *IRQ_MCLR = 1 << irq; diff --git a/include/asm-arm/arch-ebsa110/memory.h b/include/asm-arm/arch-ebsa110/memory.h new file mode 100644 index 000000000..67fa3a917 --- /dev/null +++ b/include/asm-arm/arch-ebsa110/memory.h @@ -0,0 +1,35 @@ +/* + * linux/include/asm-arm/arch-ebsa110/memory.h + * + * Copyright (c) 1996-1999 Russell King. + * + * Changelog: + * 20-Oct-1996 RMK Created + * 31-Dec-1997 RMK Fixed definitions to reduce warnings + * 21-Mar-1999 RMK Renamed to memory.h + * RMK Moved TASK_SIZE and PAGE_OFFSET here + */ +#ifndef __ASM_ARCH_MEMORY_H +#define __ASM_ARCH_MEMORY_H + +/* + * Task size: 3GB + */ +#define TASK_SIZE (0xc0000000UL) + +/* + * Page offset: 3GB + */ +#define PAGE_OFFSET (0xc0000000UL) + +#define __virt_to_phys__is_a_macro +#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET) +#define __phys_to_virt__is_a_macro +#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET) + +#define __virt_to_bus__is_a_macro +#define __virt_to_bus(x) __virt_to_phys(x) +#define __bus_to_virt__is_a_macro +#define __bus_to_virt(x) __phys_to_virt(x) + +#endif diff --git a/include/asm-arm/arch-ebsa110/mm-init.h b/include/asm-arm/arch-ebsa110/mm-init.h deleted file mode 100644 index c6937abd0..000000000 --- a/include/asm-arm/arch-ebsa110/mm-init.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * linux/include/asm-arm/arch-ebsa110/mmap.h - * - * Copyright (C) 1996,1997,1998 Russell King - */ diff --git a/include/asm-arm/arch-ebsa110/mmu.h b/include/asm-arm/arch-ebsa110/mmu.h deleted file mode 100644 index 97776045d..000000000 --- a/include/asm-arm/arch-ebsa110/mmu.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * linux/include/asm-arm/arch-ebsa110/mmu.h - * - * Copyright (c) 1996,1997,1998 Russell King. - * - * Changelog: - * 20-10-1996 RMK Created - * 31-12-1997 RMK Fixed definitions to reduce warnings - */ -#ifndef __ASM_ARCH_MMU_H -#define __ASM_ARCH_MMU_H - -#define __virt_to_phys__is_a_macro -#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET) -#define __phys_to_virt__is_a_macro -#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET) - -#define __virt_to_bus__is_a_macro -#define __virt_to_bus(x) __virt_to_phys(x) -#define __bus_to_virt__is_a_macro -#define __bus_to_virt(x) __phys_to_virt(x) - -#endif diff --git a/include/asm-arm/arch-ebsa110/oldlatches.h b/include/asm-arm/arch-ebsa110/oldlatches.h deleted file mode 100644 index 8ff6ebd67..000000000 --- a/include/asm-arm/arch-ebsa110/oldlatches.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Dummy oldlatches.h - * - * Copyright (C) 1996 Russell King - */ - -#ifdef __need_oldlatches -#error "Old latches not present in this (rpc) machine" -#endif diff --git a/include/asm-arm/arch-ebsa110/processor.h b/include/asm-arm/arch-ebsa110/processor.h index e98d1ff33..bd99869af 100644 --- a/include/asm-arm/arch-ebsa110/processor.h +++ b/include/asm-arm/arch-ebsa110/processor.h @@ -1,12 +1,17 @@ /* * linux/include/asm-arm/arch-ebsa110/processor.h * - * Copyright (C) 1996,1997,1998 Russell King + * Copyright (C) 1996-1999 Russell King + * + * Changelog: + * 21-Mar-1999 RMK Added asm/arch/memory.h */ #ifndef __ASM_ARCH_PROCESSOR_H #define __ASM_ARCH_PROCESSOR_H +#include <asm/arch/memory.h> + /* * Bus types */ @@ -15,17 +20,9 @@ #define MCA_bus 0 #define MCA_bus__is_a_macro /* for versions in ksyms.c */ -/* - * User space: 3GB - */ -#define TASK_SIZE (0xc0000000UL) - /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ #define TASK_UNMAPPED_BASE (TASK_SIZE / 3) -#define INIT_MMAP \ -{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } - #endif diff --git a/include/asm-arm/arch-ebsa110/time.h b/include/asm-arm/arch-ebsa110/time.h index 1f21a02e6..21728e469 100644 --- a/include/asm-arm/arch-ebsa110/time.h +++ b/include/asm-arm/arch-ebsa110/time.h @@ -38,63 +38,67 @@ extern __inline__ unsigned long gettimeoffset (void) return 0; } -#ifndef DIVISOR -extern __inline__ int reset_timer (void) +static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { *PIT_T1 = (PIT1_COUNT) & 0xff; *PIT_T1 = (PIT1_COUNT) >> 8; - return 1; -} -#else -extern __inline__ int reset_timer (void) -{ - static unsigned int divisor; -#ifdef CONFIG_LEDS - static int count = 50; -#endif - - *PIT_T1 = (PIT1_COUNT) & 0xff; - *PIT_T1 = (PIT1_COUNT) >> 8; #ifdef CONFIG_LEDS - if (--count == 0) { - count = 50; - leds_event(led_timer); + { + static int count = 50; + if (--count == 0) { + count = 50; + leds_event(led_timer); + } } #endif - if (divisor == 0) { - divisor = DIVISOR - 1; - return 1; + { +#ifdef DIVISOR + static unsigned int divisor; + + if (divisor-- == 0) { + divisor = DIVISOR - 1; +#else + { +#endif + do_timer(regs); + } } - divisor -= 1; - return 0; } -#endif -/* - * We don't have a RTC to update! - */ -#define update_rtc() +static struct irqaction timerirq = { + timer_interrupt, + 0, + 0, + "timer", + NULL, + NULL +}; /* * Set up timer interrupt, and return the current time in seconds. */ -extern __inline__ unsigned long setup_timer (void) +extern __inline__ void setup_timer(void) { /* * Timer 1, mode 0, 16-bit, autoreload */ *PIT_CTRL = 0x70; + /* * Refresh counter clocked at 47.8MHz/7 = 146.4ns * We want centi-second interrupts */ - reset_timer (); + *PIT_T1 = (PIT1_COUNT) & 0xff; + *PIT_T1 = (PIT1_COUNT) >> 8; + /* * Default the date to 1 Jan 1970 0:0:0 * You will have to run a time daemon to set the * clock correctly at bootup */ - return mktime(1970, 1, 1, 0, 0, 0); + xtime.tv_sec = mktime(1970, 1, 1, 0, 0, 0); + + setup_arm_irq(IRQ_TIMER, &timerirq); } diff --git a/include/asm-arm/arch-ebsa285/a.out.h b/include/asm-arm/arch-ebsa285/a.out.h index 2746584c8..71fcffe8e 100644 --- a/include/asm-arm/arch-ebsa285/a.out.h +++ b/include/asm-arm/arch-ebsa285/a.out.h @@ -1,15 +1,16 @@ /* * linux/include/asm-arm/arch-ebsa110/a.out.h * - * Copyright (C) 1996 Russell King + * Copyright (C) 1996-1999 Russell King */ - #ifndef __ASM_ARCH_A_OUT_H #define __ASM_ARCH_A_OUT_H -#ifdef __KERNEL__ -#define STACK_TOP ((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000) -#endif +#include <asm/arch/memory.h> + +#define STACK_TOP \ + ((current->personality == PER_LINUX_32BIT) ? \ + TASK_SIZE : 0x04000000) #endif diff --git a/include/asm-arm/arch-ebsa285/dma.h b/include/asm-arm/arch-ebsa285/dma.h index 28c093aec..8b74a7f84 100644 --- a/include/asm-arm/arch-ebsa285/dma.h +++ b/include/asm-arm/arch-ebsa285/dma.h @@ -3,8 +3,8 @@ * * Architecture DMA routines * - * Copyright (C) 1998 Russell King - * Copyright (C) 1998 Philip Blundell + * Copyright (C) 1998,1999 Russell King + * Copyright (C) 1998,1999 Philip Blundell */ #ifndef __ASM_ARCH_DMA_H #define __ASM_ARCH_DMA_H @@ -15,12 +15,16 @@ #define MAX_DMA_ADDRESS 0xffffffff /* - * The 21285 has two internal DMA channels; we call these 0 and 1. + * The 21285 has two internal DMA channels; we call these 8 and 9. * On CATS hardware we have an additional eight ISA dma channels - * numbered 2..9. + * numbered 0..7. */ +#define _ISA_DMA(x) (0+(x)) +#define _DC21285_DMA(x) (8+(x)) + #define MAX_DMA_CHANNELS 10 -#define DMA_ISA_BASE 2 -#define DMA_FLOPPY (DMA_ISA_BASE + 2) + +#define DMA_FLOPPY _ISA_DMA(2) +#define DMA_ISA_CASCADE _ISA_DMA(4) #endif /* _ASM_ARCH_DMA_H */ diff --git a/include/asm-arm/arch-ebsa285/hardware.h b/include/asm-arm/arch-ebsa285/hardware.h index e08c5b823..c989e0f09 100644 --- a/include/asm-arm/arch-ebsa285/hardware.h +++ b/include/asm-arm/arch-ebsa285/hardware.h @@ -1,47 +1,135 @@ /* * linux/include/asm-arm/arch-ebsa285/hardware.h * - * Copyright (C) 1998 Russell King. + * Copyright (C) 1998-1999 Russell King. * * This file contains the hardware definitions of the EBSA-285. */ +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H +#include <linux/config.h> +#include <asm/arch/memory.h> -/* Logical Physical +#ifdef CONFIG_HOST_FOOTBRIDGE +/* Virtual Physical * 0xfff00000 0x40000000 X-Bus - * 0xffe00000 0x7c000000 PCI I/O space + * 0xff000000 0x7c000000 PCI I/O space * * 0xfe000000 0x42000000 CSR * 0xfd000000 0x78000000 Outbound write flush * 0xfc000000 0x79000000 PCI IACK/special space * - * 0xf9000000 0x7a010000 PCI Config type 1 - * 0xf8000000 0x7b010000 PCI Config type 0 + * 0xf9000000 0x7a000000 PCI Config type 1 + * 0xf8000000 0x7b000000 PCI Config type 0 * */ +#define XBUS_SIZE 0x00100000 +#define XBUS_BASE 0xfff00000 -#include <asm/dec21285.h> - -#define IO_BASE 0xe0000000 -#define PCIO_BASE 0xffe00000 -#define PCI_IACK 0xfc000000 +#define PCIO_SIZE 0x00100000 +#define PCIO_BASE 0xff000000 -#define XBUS_LEDS ((volatile unsigned char *)0xfff12000) +#define ARMCSR_SIZE 0x01000000 +#define ARMCSR_BASE 0xfe000000 + +#define WFLUSH_SIZE 0x01000000 +#define WFLUSH_BASE 0xfd000000 + +#define PCIIACK_SIZE 0x01000000 +#define PCIIACK_BASE 0xfc000000 + +#define PCICFG1_SIZE 0x01000000 +#define PCICFG1_BASE 0xf9000000 + +#define PCICFG0_SIZE 0x01000000 +#define PCICFG0_BASE 0xf8000000 + +#define PCIMEM_SIZE 0x18000000 +#define PCIMEM_BASE 0xe0000000 + +#define FLUSH_SIZE 0x00100000 +#define FLUSH_BASE 0xdf000000 + +#define FLASH_SIZE 0x00400000 +#define FLASH_BASE 0xd8000000 + +#elif defined(CONFIG_ARCH_CO285) + +#define PCIMEM_SIZE 0x80000000 +#define PCIMEM_BASE 0x80000000 + +#define FLASH_SIZE 0x01000000 +#define FLASH_BASE 0x7f000000 + +#define FLUSH_SIZE 0x00100000 +#define FLUSH_BASE 0x7e000000 + +#define WFLUSH_SIZE 0x01000000 +#define WFLUSH_BASE 0x7d000000 + +#define ARMCSR_SIZE 0x00100000 +#define ARMCSR_BASE 0x7cf00000 + +#define XBUS_SIZE 0x00020000 +#define XBUS_BASE 0x7cee0000 + +#define PCIO_SIZE 0x00010000 +#define PCIO_BASE 0x7ced0000 + +#else + +#error Add your add-in architecture here + +#endif + +#define XBUS_LEDS ((volatile unsigned char *)(XBUS_BASE + 0x12000)) #define XBUS_LED_AMBER (1 << 0) #define XBUS_LED_GREEN (1 << 1) #define XBUS_LED_RED (1 << 2) #define XBUS_LED_TOGGLE (1 << 8) -#define XBUS_SWITCH ((volatile unsigned char *)0xfff12000) +#define XBUS_SWITCH ((volatile unsigned char *)(XBUS_BASE + 0x12000)) #define XBUS_SWITCH_SWITCH ((*XBUS_SWITCH) & 15) #define XBUS_SWITCH_J17_13 ((*XBUS_SWITCH) & (1 << 4)) #define XBUS_SWITCH_J17_11 ((*XBUS_SWITCH) & (1 << 5)) #define XBUS_SWITCH_J17_9 ((*XBUS_SWITCH) & (1 << 6)) -#define KERNTOPHYS(a) ((unsigned long)(&a)) - #define PARAMS_OFFSET 0x0100 #define PARAMS_BASE (PAGE_OFFSET + PARAMS_OFFSET) #define FLUSH_BASE_PHYS 0x50000000 + +/* PIC irq control */ +#define PIC_LO 0x20 +#define PIC_MASK_LO 0x21 +#define PIC_HI 0xA0 +#define PIC_MASK_HI 0xA1 + +/* GPIO pins */ +#define GPIO_CCLK 0x800 +#define GPIO_DSCLK 0x400 +#define GPIO_E2CLK 0x200 +#define GPIO_IOLOAD 0x100 +#define GPIO_RED_LED 0x080 +#define GPIO_WDTIMER 0x040 +#define GPIO_DATA 0x020 +#define GPIO_IOCLK 0x010 +#define GPIO_DONE 0x008 +#define GPIO_FAN 0x004 +#define GPIO_GREEN_LED 0x002 +#define GPIO_RESET 0x001 + +/* CPLD pins */ +#define CPLD_DSRESET 8 +#define CPLD_UNMUTE 2 + +#ifndef __ASSEMBLY__ +extern void gpio_modify_op(int mask, int set); +extern void gpio_modify_io(int mask, int in); +extern int gpio_read(void); +extern void cpld_modify(int mask, int set); +#endif + +#endif diff --git a/include/asm-arm/arch-ebsa285/io.h b/include/asm-arm/arch-ebsa285/io.h index 1be73879d..b23ee6863 100644 --- a/include/asm-arm/arch-ebsa285/io.h +++ b/include/asm-arm/arch-ebsa285/io.h @@ -16,34 +16,37 @@ * has the constant-optimised IO */ #undef ARCH_IO_DELAY +#define ARCH_READWRITE /* * Dynamic IO functions - let the compiler * optimize the expressions */ -#define DECLARE_DYN_OUT(fnsuffix,instr,typ) \ -extern __inline__ void __out##fnsuffix (unsigned int value, unsigned int port) \ -{ \ - __asm__ __volatile__( \ - "str%?" ##instr## " %0, [%1, %2] @ out"###fnsuffix \ - : \ - : "r" (value), "r" (PCIO_BASE), typ (port)); \ +#define DECLARE_DYN_OUT(fnsuffix,instr,typ) \ +extern __inline__ void \ +__out##fnsuffix (unsigned int value, unsigned int port) \ +{ \ + __asm__ __volatile__( \ + "str%?" ##instr## " %0, [%1, %2] @ out"###fnsuffix \ + : \ + : "r" (value), "r" (PCIO_BASE), typ (port)); \ } -#define DECLARE_DYN_IN(sz,fnsuffix,instr,typ) \ -extern __inline__ unsigned sz __in##fnsuffix (unsigned int port) \ -{ \ - unsigned long value; \ - __asm__ __volatile__( \ - "ldr%?" ##instr## " %0, [%1, %2] @ in"###fnsuffix \ - : "=&r" (value) \ - : "r" (PCIO_BASE), typ (port)); \ - return (unsigned sz)value; \ +#define DECLARE_DYN_IN(sz,fnsuffix,instr,typ) \ +extern __inline__ unsigned sz \ +__in##fnsuffix (unsigned int port) \ +{ \ + unsigned long value; \ + __asm__ __volatile__( \ + "ldr%?" ##instr## " %0, [%1, %2] @ in"###fnsuffix \ + : "=&r" (value) \ + : "r" (PCIO_BASE), typ (port)); \ + return (unsigned sz)value; \ } -extern __inline__ unsigned int __ioaddr (unsigned int port) \ -{ \ - return (unsigned int)(PCIO_BASE + port); \ +extern __inline__ unsigned int __ioaddr (unsigned int port) \ +{ \ + return (unsigned int)(PCIO_BASE + port); \ } #define DECLARE_IO(sz,fnsuffix,instr,typ) \ @@ -64,65 +67,65 @@ DECLARE_IO(long,l,"","Jr") * These have to be macros for the 'J' constraint to work - * +/-4096 immediate operand. */ -#define __outbc(value,port) \ -({ \ - __asm__ __volatile__( \ - "str%?b %0, [%1, %2] @ outbc" \ - : \ - : "r" (value), "r" (PCIO_BASE), "Jr" (port)); \ +#define __outbc(value,port) \ +({ \ + __asm__ __volatile__( \ + "str%?b %0, [%1, %2] @ outbc" \ + : \ + : "r" (value), "r" (PCIO_BASE), "Jr" (port)); \ }) -#define __inbc(port) \ -({ \ - unsigned char result; \ - __asm__ __volatile__( \ - "ldr%?b %0, [%1, %2] @ inbc" \ - : "=r" (result) \ - : "r" (PCIO_BASE), "Jr" (port)); \ - result; \ +#define __inbc(port) \ +({ \ + unsigned char result; \ + __asm__ __volatile__( \ + "ldr%?b %0, [%1, %2] @ inbc" \ + : "=r" (result) \ + : "r" (PCIO_BASE), "Jr" (port)); \ + result; \ }) -#define __outwc(value,port) \ -({ \ - __asm__ __volatile__( \ - "str%?h %0, [%1, %2] @ outwc" \ - : \ - : "r" (value), "r" (PCIO_BASE), "r" (port)); \ +#define __outwc(value,port) \ +({ \ + __asm__ __volatile__( \ + "str%?h %0, [%1, %2] @ outwc" \ + : \ + : "r" (value), "r" (PCIO_BASE), "r" (port)); \ }) -#define __inwc(port) \ -({ \ - unsigned short result; \ - __asm__ __volatile__( \ - "ldr%?h %0, [%1, %2] @ inwc" \ - : "=r" (result) \ - : "r" (PCIO_BASE), "r" (port)); \ - result & 0xffff; \ +#define __inwc(port) \ +({ \ + unsigned short result; \ + __asm__ __volatile__( \ + "ldr%?h %0, [%1, %2] @ inwc" \ + : "=r" (result) \ + : "r" (PCIO_BASE), "r" (port)); \ + result & 0xffff; \ }) -#define __outlc(value,port) \ -({ \ - __asm__ __volatile__( \ - "str%? %0, [%1, %2] @ outlc" \ - : \ - : "r" (value), "r" (PCIO_BASE), "Jr" (port)); \ +#define __outlc(value,port) \ +({ \ + __asm__ __volatile__( \ + "str%? %0, [%1, %2] @ outlc" \ + : \ + : "r" (value), "r" (PCIO_BASE), "Jr" (port)); \ }) -#define __inlc(port) \ -({ \ - unsigned long result; \ - __asm__ __volatile__( \ - "ldr%? %0, [%1, %2] @ inlc" \ - : "=r" (result) \ - : "r" (PCIO_BASE), "Jr" (port)); \ - result; \ +#define __inlc(port) \ +({ \ + unsigned long result; \ + __asm__ __volatile__( \ + "ldr%? %0, [%1, %2] @ inlc" \ + : "=r" (result) \ + : "r" (PCIO_BASE), "Jr" (port)); \ + result; \ }) -#define __ioaddrc(port) \ -({ \ - unsigned long addr; \ - addr = PCIO_BASE + port; \ - addr; \ +#define __ioaddrc(port) \ +({ \ + unsigned long addr; \ + addr = PCIO_BASE + port; \ + addr; \ }) /* @@ -130,20 +133,22 @@ DECLARE_IO(long,l,"","Jr") * * IO address has already been translated to a virtual address */ -#define outb_t(v,p) \ +#define outb_t(v,p) \ (*(volatile unsigned char *)(p) = (v)) -#define inb_t(p) \ +#define inb_t(p) \ (*(volatile unsigned char *)(p)) -#define outl_t(v,p) \ +#define outl_t(v,p) \ (*(volatile unsigned long *)(p) = (v)) -#define inl_t(p) \ +#define inl_t(p) \ (*(volatile unsigned long *)(p)) /* - * ioremap support + * ioremap support - validate a PCI memory address, + * and convert a PCI memory address to a physical + * address for the page tables. */ #define valid_ioaddr(iomem,size) ((iomem) < 0x80000000 && (iomem) + (size) <= 0x80000000) #define io_to_phys(iomem) ((iomem) + DC21285_PCI_MEM) @@ -153,58 +158,48 @@ DECLARE_IO(long,l,"","Jr") * is using read*() and so on with addresses they didn't get from ioremap * this can go away. */ -#define IO_FUDGE_FACTOR 0xe0000000 +#define IO_FUDGE_FACTOR PCIMEM_BASE -extern inline void *ioremap(unsigned long iomem_addr, unsigned long size) -{ - unsigned long phys_addr; - - if (!valid_ioaddr(iomem_addr, size)) - return NULL; - - phys_addr = io_to_phys(iomem_addr & PAGE_MASK); - - return (void *)((unsigned long)__ioremap(phys_addr, size, 0) - - IO_FUDGE_FACTOR); -} +/* + * ioremap takes a PCI memory address, as specified in + * linux/Documentation/IO-mapping.txt + */ +#define ioremap(iomem_addr,size) \ +({ \ + unsigned long _addr = (iomem_addr), _size = (size); \ + void *_ret = NULL; \ + if (valid_ioaddr(_addr, _size)) { \ + _addr = io_to_phys(_addr); \ + _ret = __ioremap(_addr, _size, 0) - IO_FUDGE_FACTOR; \ + } \ + _ret; }) #define ioremap_nocache(iomem_addr,size) ioremap((iomem_addr),(size)) extern void iounmap(void *addr); -/* - * We'd probably be better off with these as macros rather than functions. - * Firstly that would be more efficient and secondly we could do with the - * ability to stop GCC whinging about type conversions. --philb - */ -static inline void writeb(unsigned char b, unsigned int addr) -{ - *(volatile unsigned char *)(IO_FUDGE_FACTOR + (addr)) = b; -} - -static inline unsigned char readb(unsigned int addr) -{ - return *(volatile unsigned char *)(IO_FUDGE_FACTOR + (addr)); +#define DECLARE_PCI_WRITE(typ,fnsuffix) \ +static inline void write##fnsuffix(unsigned typ val, unsigned int addr) \ +{ \ + *(volatile unsigned typ *)(IO_FUDGE_FACTOR + addr) = val; \ } -static inline void writew(unsigned short b, unsigned int addr) -{ - *(volatile unsigned short *)(IO_FUDGE_FACTOR + (addr)) = b; +#define DECLARE_PCI_READ(typ,fnsuffix) \ +static inline unsigned typ read##fnsuffix (unsigned int addr) \ +{ \ + return *(volatile unsigned typ *)(IO_FUDGE_FACTOR + addr); \ } -static inline unsigned short readw(unsigned int addr) -{ - return *(volatile unsigned short *)(IO_FUDGE_FACTOR + (addr)); -} +#define DECLARE_PCI(typ,fnsuffix) \ + DECLARE_PCI_WRITE(typ,fnsuffix) \ + DECLARE_PCI_READ(typ,fnsuffix) -static inline void writel(unsigned long b, unsigned int addr) -{ - *(volatile unsigned long *)(IO_FUDGE_FACTOR + (addr)) = b; -} +DECLARE_PCI(char,b) +DECLARE_PCI(short,w) +DECLARE_PCI(long,l) -static inline unsigned short readl(unsigned int addr) -{ - return *(volatile unsigned long *)(IO_FUDGE_FACTOR + (addr)); -} +#undef DECLARE_PCI +#undef DECLARE_PCI_READ +#undef DECLARE_PCI_WRITE #endif diff --git a/include/asm-arm/arch-ebsa285/irq.h b/include/asm-arm/arch-ebsa285/irq.h index 74bc33c58..ca1a55cdb 100644 --- a/include/asm-arm/arch-ebsa285/irq.h +++ b/include/asm-arm/arch-ebsa285/irq.h @@ -4,136 +4,206 @@ * Copyright (C) 1996-1998 Russell King * * Changelog: - * 22-08-1998 RMK Restructured IRQ routines - * 03-09-1998 PJB Merged CATS support + * 22-Aug-1998 RMK Restructured IRQ routines + * 03-Sep-1998 PJB Merged CATS support + * 20-Jan-1998 RMK Started merge of EBSA286, CATS and NetWinder + * 26-Jan-1999 PJB Don't use IACK on CATS + * 16-Mar-1999 RMK Added autodetect of ISA PICs */ #include <linux/config.h> +#include <asm/hardware.h> +#include <asm/dec21285.h> +#include <asm/irq.h> -static void ebsa285_mask_irq(unsigned int irq) +/* + * Footbridge IRQ translation table + * Converts from our IRQ numbers into FootBridge masks + */ +static int dc21285_irq_mask[] = { + IRQ_MASK_UART_RX, /* 0 */ + IRQ_MASK_UART_TX, /* 1 */ + IRQ_MASK_TIMER1, /* 2 */ + IRQ_MASK_TIMER2, /* 3 */ + IRQ_MASK_TIMER3, /* 4 */ + IRQ_MASK_IN0, /* 5 */ + IRQ_MASK_IN1, /* 6 */ + IRQ_MASK_IN2, /* 7 */ + IRQ_MASK_IN3, /* 8 */ + IRQ_MASK_DOORBELLHOST, /* 9 */ + IRQ_MASK_DMA1, /* 10 */ + IRQ_MASK_DMA2, /* 11 */ + IRQ_MASK_PCI, /* 12 */ + IRQ_MASK_SDRAMPARITY, /* 13 */ + IRQ_MASK_I2OINPOST, /* 14 */ + IRQ_MASK_PCI_ERR /* 15 */ +}; + +static int isa_irq = -1; + +static inline int fixup_irq(unsigned int irq) { - *CSR_IRQ_DISABLE = 1 << irq; +#ifdef CONFIG_HOST_FOOTBRIDGE + if (irq == isa_irq) + irq = *(unsigned char *)PCIIACK_BASE; +#endif + + return irq; } -static void ebsa285_unmask_irq(unsigned int irq) +static void dc21285_mask_irq(unsigned int irq) { - *CSR_IRQ_ENABLE = 1 << irq; + *CSR_IRQ_DISABLE = dc21285_irq_mask[irq & 15]; } -#ifdef CONFIG_CATS +static void dc21285_unmask_irq(unsigned int irq) +{ + *CSR_IRQ_ENABLE = dc21285_irq_mask[irq & 15]; +} -/* - * This contains the irq mask for both 8259A irq controllers, - */ -static unsigned int isa_irq_mask = 0xffff; +static void isa_mask_pic_lo_irq(unsigned int irq) +{ + unsigned int mask = 1 << (irq & 7); + + outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO); +} -#define cached_21 (isa_irq_mask & 0xff) -#define cached_A1 ((isa_irq_mask >> 8) & 0xff) +static void isa_mask_ack_pic_lo_irq(unsigned int irq) +{ + unsigned int mask = 1 << (irq & 7); -#define update_8259(_irq) \ - if ((_irq) & 8) \ - outb(cached_A1, 0xa1); \ - else \ - outb(cached_21, 0x21); + outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO); + outb(0x20, PIC_LO); +} -static void isa_interrupt(int irq, void *h, struct pt_regs *regs) +static void isa_unmask_pic_lo_irq(unsigned int irq) { - asmlinkage void do_IRQ(int irq, struct pt_regs * regs); - unsigned int irqbits = inb(0x20) | (inb(0xa0) << 8), irqnr = 0; - irqbits &= ~(1<<2); /* don't try to service the cascade */ - while (irqbits) { - if (irqbits & 1) - do_IRQ(32 + irqnr, regs); - irqbits >>= 1; - irqnr++; - } + unsigned int mask = 1 << (irq & 7); + + outb(inb(PIC_MASK_LO) & ~mask, PIC_MASK_LO); } -static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { } +static void isa_mask_pic_hi_irq(unsigned int irq) +{ + unsigned int mask = 1 << (irq & 7); -static struct irqaction irq_isa = - { isa_interrupt, SA_INTERRUPT, 0, "ISA PIC", NULL, NULL }; -static struct irqaction irq_cascade = - { no_action, 0, 0, "cascade", NULL, NULL }; + outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI); +} -static void cats_mask_and_ack_isa_irq(unsigned int irq) +static void isa_mask_ack_pic_hi_irq(unsigned int irq) { - isa_irq_mask |= (1 << (irq - 32)); - update_8259(irq); - if (irq & 8) { - inb(0xA1); /* DUMMY */ - outb(cached_A1,0xA1); - outb(0x62,0x20); /* Specific EOI to cascade */ - outb(0x20,0xA0); - } else { - inb(0x21); /* DUMMY */ - outb(cached_21,0x21); - outb(0x20,0x20); - } + unsigned int mask = 1 << (irq & 7); + + outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI); + outb(0x62, PIC_LO); + outb(0x20, PIC_HI); } -static void cats_mask_isa_irq(unsigned int irq) +static void isa_unmask_pic_hi_irq(unsigned int irq) { - isa_irq_mask |= (1 << (irq - 32)); - update_8259(irq); + unsigned int mask = 1 << (irq & 7); + + outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI); } -static void cats_unmask_isa_irq(unsigned int irq) +static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { - isa_irq_mask &= ~(1 << (irq - 32)); - update_8259(irq); } - -#endif + +static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL }; static __inline__ void irq_init_irq(void) { int irq; + /* + * setup DC21285 IRQs + */ *CSR_IRQ_DISABLE = -1; *CSR_FIQ_DISABLE = -1; - for (irq = 0; irq < NR_IRQS; irq++) { + for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(16); irq++) { irq_desc[irq].valid = 1; irq_desc[irq].probe_ok = 1; -#ifdef CONFIG_CATS - if (machine_is_cats() && IRQ_IS_ISA(irq)) { - irq_desc[irq].mask_ack = cats_mask_and_ack_isa_irq; - irq_desc[irq].mask = cats_mask_isa_irq; - irq_desc[irq].unmask = cats_unmask_isa_irq; + irq_desc[irq].mask_ack = dc21285_mask_irq; + irq_desc[irq].mask = dc21285_mask_irq; + irq_desc[irq].unmask = dc21285_unmask_irq; + } + + /* + * Determine the ISA settings for + * the machine we're running on. + */ + switch (machine_arch_type) { + default: + isa_irq = -1; + break; + + case MACH_TYPE_EBSA285: + /* The following is dependent on which slot + * you plug the Southbridge card into. We + * currently assume that you plug it into + * the right-hand most slot. + */ + isa_irq = IRQ_PCI; + break; + + case MACH_TYPE_CATS: + isa_irq = IRQ_IN2; + break; + + case MACH_TYPE_NETWINDER: + isa_irq = IRQ_IN3; + break; + } + + if (isa_irq != -1) { + /* + * Setup, and then probe for an ISA PIC + */ + outb(0x11, PIC_LO); + outb(_ISA_IRQ(0), PIC_MASK_LO); /* IRQ number */ + outb(0x04, PIC_MASK_LO); /* Slave on Ch2 */ + outb(0x01, PIC_MASK_LO); /* x86 */ + outb(0xf5, PIC_MASK_LO); /* pattern: 11110101 */ + + outb(0x11, PIC_HI); + outb(_ISA_IRQ(8), PIC_MASK_HI); /* IRQ number */ + outb(0x02, PIC_MASK_HI); /* Slave on Ch1 */ + outb(0x01, PIC_MASK_HI); /* x86 */ + outb(0xfa, PIC_MASK_HI); /* pattern: 11111010 */ + +// outb(0x68, PIC_LO); /* enable special mode */ +// outb(0x68, PIC_HI); /* enable special mode */ + outb(0x0b, PIC_LO); + outb(0x0b, PIC_HI); + + if (inb(PIC_MASK_LO) == 0xf5 && inb(PIC_MASK_HI) == 0xfa) { + outb(0xff, PIC_MASK_LO);/* mask all IRQs */ + outb(0xff, PIC_MASK_HI);/* mask all IRQs */ } else -#endif - { - irq_desc[irq].mask_ack = ebsa285_mask_irq; - irq_desc[irq].mask = ebsa285_mask_irq; - irq_desc[irq].unmask = ebsa285_unmask_irq; - } + isa_irq = -1; } -#ifdef CONFIG_CATS - if (machine_is_cats()) { - request_region(0x20, 2, "pic1"); - request_region(0xa0, 2, "pic2"); - - /* set up master 8259 */ - outb(0x11, 0x20); - outb(0, 0x21); - outb(1<<2, 0x21); - outb(0x1, 0x21); - outb(0xff, 0x21); - outb(0x68, 0x20); - outb(0xa, 0x20); - - /* set up slave 8259 */ - outb(0x11, 0xa0); - outb(0, 0xa1); - outb(2, 0xa1); - outb(0x1, 0xa1); - outb(0xff, 0xa1); - outb(0x68, 0xa0); - outb(0xa, 0xa0); - - setup_arm_irq(IRQ_ISA_PIC, &irq_isa); + if (isa_irq != -1) { + for (irq = _ISA_IRQ(0); irq < _ISA_IRQ(8); irq++) { + irq_desc[irq].valid = 1; + irq_desc[irq].probe_ok = 1; + irq_desc[irq].mask_ack = isa_mask_ack_pic_lo_irq; + irq_desc[irq].mask = isa_mask_pic_lo_irq; + irq_desc[irq].unmask = isa_unmask_pic_lo_irq; + } + + for (irq = _ISA_IRQ(8); irq < _ISA_IRQ(16); irq++) { + irq_desc[irq].valid = 1; + irq_desc[irq].probe_ok = 1; + irq_desc[irq].mask_ack = isa_mask_ack_pic_hi_irq; + irq_desc[irq].mask = isa_mask_pic_hi_irq; + irq_desc[irq].unmask = isa_unmask_pic_hi_irq; + } + + request_region(PIC_LO, 2, "pic1"); + request_region(PIC_HI, 2, "pic2"); setup_arm_irq(IRQ_ISA_CASCADE, &irq_cascade); + setup_arm_irq(isa_irq, &irq_cascade); } -#endif } diff --git a/include/asm-arm/arch-ebsa285/irqs.h b/include/asm-arm/arch-ebsa285/irqs.h index 6021bee6e..afb2e379d 100644 --- a/include/asm-arm/arch-ebsa285/irqs.h +++ b/include/asm-arm/arch-ebsa285/irqs.h @@ -3,55 +3,85 @@ * * Copyright (C) 1998 Russell King * Copyright (C) 1998 Phil Blundell + * + * Changelog: + * 20-Jan-1998 RMK Started merge of EBSA286, CATS and NetWinder + * 01-Feb-1999 PJB ISA IRQs start at 0 not 16 */ -#define NR_IRQS 48 +#define NR_IRQS 32 +#define NR_DC21285_IRQS 16 + +#define _ISA_IRQ(x) (0 + (x)) +#define _DC21285_IRQ(x) (16 + (x)) /* * This is a list of all interrupts that the 21285 - * can generate + * can generate and we handle. */ -#define IRQ_RESERVED 0 -#define IRQ_SOFTIRQ 1 -#define IRQ_CONRX 2 -#define IRQ_CONTX 3 -#define IRQ_TIMER1 4 -#define IRQ_TIMER2 5 -#define IRQ_TIMER3 6 -#define IRQ_TIMER4 7 -#define IRQ_IN0 8 -#define IRQ_IN1 9 -#define IRQ_IN2 10 -#define IRQ_IN3 11 -#define IRQ_XCS0 12 -#define IRQ_XCS1 13 -#define IRQ_XCS2 14 -#define IRQ_DOORBELLHOST 15 -#define IRQ_DMA1 16 -#define IRQ_DMA2 17 -#define IRQ_PCI 18 -#define IRQ_BIST 22 -#define IRQ_SERR 23 -#define IRQ_SDRAMPARITY 24 -#define IRQ_I2OINPOST 25 -#define IRQ_DISCARDTIMER 27 -#define IRQ_PCIDATAPARITY 28 -#define IRQ_PCIMASTERABORT 29 -#define IRQ_PCITARGETABORT 30 -#define IRQ_PCIPARITY 31 - -/* IRQs 32-47 are the 16 ISA interrupts on a CATS board. */ -#define IRQ_ISA_PIC IRQ_IN2 -#define IRQ_IS_ISA(_x) (((_x) >= 32) && ((_x) <= 47)) -#define IRQ_ISA(_x) ((_x) + 0x20) -#define IRQ_ISA_CASCADE IRQ_ISA(2) +#define IRQ_CONRX _DC21285_IRQ(0) +#define IRQ_CONTX _DC21285_IRQ(1) +#define IRQ_TIMER1 _DC21285_IRQ(2) +#define IRQ_TIMER2 _DC21285_IRQ(3) +#define IRQ_TIMER3 _DC21285_IRQ(4) +#define IRQ_IN0 _DC21285_IRQ(5) +#define IRQ_IN1 _DC21285_IRQ(6) +#define IRQ_IN2 _DC21285_IRQ(7) +#define IRQ_IN3 _DC21285_IRQ(8) +#define IRQ_DOORBELLHOST _DC21285_IRQ(9) +#define IRQ_DMA1 _DC21285_IRQ(10) +#define IRQ_DMA2 _DC21285_IRQ(11) +#define IRQ_PCI _DC21285_IRQ(12) +#define IRQ_SDRAMPARITY _DC21285_IRQ(13) +#define IRQ_I2OINPOST _DC21285_IRQ(14) +#define IRQ_PCI_ERR _DC21285_IRQ(15) + +#define IRQ_ISA_TIMER _ISA_IRQ(0) +#define IRQ_ISA_KEYBOARD _ISA_IRQ(1) +#define IRQ_ISA_CASCADE _ISA_IRQ(2) +#define IRQ_ISA_UART2 _ISA_IRQ(3) +#define IRQ_ISA_UART _ISA_IRQ(4) +#define IRQ_ISA_FLOPPY _ISA_IRQ(6) +#define IRQ_ISA_PRINTER _ISA_IRQ(7) +#define IRQ_ISA_RTC_ALARM _ISA_IRQ(8) +#define IRQ_ISA_2 _ISA_IRQ(9) +#define IRQ_ISA_PS2MOUSE _ISA_IRQ(12) +#define IRQ_ISA_HARDDISK1 _ISA_IRQ(14) +#define IRQ_ISA_HARDDISK2 _ISA_IRQ(15) + +#define IRQ_MASK_UART_RX (1 << 2) +#define IRQ_MASK_UART_TX (1 << 3) +#define IRQ_MASK_TIMER1 (1 << 4) +#define IRQ_MASK_TIMER2 (1 << 5) +#define IRQ_MASK_TIMER3 (1 << 6) +#define IRQ_MASK_IN0 (1 << 8) +#define IRQ_MASK_IN1 (1 << 9) +#define IRQ_MASK_IN2 (1 << 10) +#define IRQ_MASK_IN3 (1 << 11) +#define IRQ_MASK_DOORBELLHOST (1 << 15) +#define IRQ_MASK_DMA1 (1 << 16) +#define IRQ_MASK_DMA2 (1 << 17) +#define IRQ_MASK_PCI (1 << 18) +#define IRQ_MASK_SDRAMPARITY (1 << 24) +#define IRQ_MASK_I2OINPOST (1 << 25) +#define IRQ_MASK_PCI_ERR ((1 <<23) | (1 << 27) | (1 << 28) | (1 << 29) | (1 << 30) | (1 << 31)) /* - * Now map them to the Linux interrupts + * Netwinder interrupt allocations */ -#define IRQ_TIMER IRQ_TIMER1 -#define IRQ_FLOPPYDISK IRQ_ISA(6) -#define IRQ_HARDDISK IRQ_ISA(14) -#define IRQ_HARDDISK_SECONDARY IRQ_ISA(15) +#define IRQ_NETWINDER_ETHER10 IRQ_IN0 +#define IRQ_NETWINDER_ETHER100 IRQ_IN1 +#define IRQ_NETWINDER_VIDCOMP IRQ_IN2 +#define IRQ_NETWINDER_PS2MOUSE _ISA_IRQ(5) +#define IRQ_NETWINDER_IR _ISA_IRQ(6) +#define IRQ_NETWINDER_BUTTON _ISA_IRQ(10) +#define IRQ_NETWINDER_VGA _ISA_IRQ(11) +#define IRQ_NETWINDER_SOUND _ISA_IRQ(12) + +#undef RTC_IRQ +#define RTC_IRQ IRQ_ISA_RTC_ALARM +#undef AUX_IRQ +#define AUX_IRQ (machine_is_netwinder() ? IRQ_NETWINDER_PS2MOUSE : IRQ_ISA_PS2MOUSE) +#define IRQ_FLOPPYDISK IRQ_ISA_FLOPPY -#define irq_cannonicalize(_i) (((_i) == IRQ_ISA_CASCADE) ? IRQ_ISA(9) : _i) +#define irq_cannonicalize(_i) (((_i) == IRQ_ISA_CASCADE) ? IRQ_ISA_2 : _i) diff --git a/include/asm-arm/arch-ebsa285/keyboard.h b/include/asm-arm/arch-ebsa285/keyboard.h index ad6eb0e5a..dcc7b49f9 100644 --- a/include/asm-arm/arch-ebsa285/keyboard.h +++ b/include/asm-arm/arch-ebsa285/keyboard.h @@ -6,20 +6,13 @@ * (C) 1998 Russell King * (C) 1998 Phil Blundell */ - -#include <linux/config.h> #include <asm/irq.h> #include <asm/system.h> -#define NR_SCANCODES 128 - -#ifdef CONFIG_CATS - -#define KEYBOARD_IRQ IRQ_ISA(1) +extern int have_isa_bridge; extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); extern int pckbd_getkeycode(unsigned int scancode); -extern int pckbd_pretranslate(unsigned char scancode, char raw_mode); extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode); extern char pckbd_unexpected_up(unsigned char keycode); @@ -27,46 +20,52 @@ extern void pckbd_leds(unsigned char leds); extern void pckbd_init_hw(void); extern unsigned char pckbd_sysrq_xlate[128]; -#define kbd_setkeycode pckbd_setkeycode -#define kbd_getkeycode pckbd_getkeycode -#define kbd_pretranslate pckbd_pretranslate -#define kbd_translate(sc, kcp, ufp, rm) ({ *ufp = sc & 0200; \ - pckbd_translate(sc & 0x7f, kcp, rm);}) +#define KEYBOARD_IRQ IRQ_ISA_KEYBOARD -#define kbd_unexpected_up pckbd_unexpected_up -#define kbd_leds pckbd_leds -#define kbd_init_hw() \ - do { if (machine_is_cats()) pckbd_init_hw(); } while (0) -#define kbd_sysrq_xlate pckbd_sysrq_xlate -#define kbd_disable_irq() -#define kbd_enable_irq() +#define NR_SCANCODES 128 -#define SYSRQ_KEY 0x54 +#define kbd_setkeycode(sc,kc) \ + ({ \ + int __ret; \ + if (have_isa_bridge) \ + __ret = pckbd_setkeycode(sc,kc);\ + else \ + __ret = -EINVAL; \ + __ret; \ + }) -#else +#define kbd_getkeycode(sc) \ + ({ \ + int __ret; \ + if (have_isa_bridge) \ + __ret = pckbd_getkeycode(sc); \ + else \ + __ret = -EINVAL; \ + __ret; \ + }) -/* Dummy keyboard definitions */ +#define kbd_translate(sc, kcp, rm) \ + ({ \ + pckbd_translate(sc, kcp, rm); \ + }) -#define kbd_setkeycode(sc,kc) (-EINVAL) -#define kbd_getkeycode(sc) (-EINVAL) +#define kbd_unexpected_up pckbd_unexpected_up -/* Prototype: int kbd_pretranslate(scancode, raw_mode) - * Returns : 0 to ignore scancode - */ -#define kbd_pretranslate(sc,rm) (1) +#define kbd_leds(leds) \ + do { \ + if (have_isa_bridge) \ + pckbd_leds(leds); \ + } while (0) + +#define kbd_init_hw() \ + do { \ + if (have_isa_bridge) \ + pckbd_init_hw(); \ + } while (0) + +#define kbd_sysrq_xlate pckbd_sysrq_xlate -/* Prototype: int kbd_translate(scancode, *keycode, *up_flag, raw_mode) - * Returns : 0 to ignore scancode, *keycode set to keycode, *up_flag - * set to 0200 if scancode indicates release - */ -#define kbd_translate(sc, kcp, ufp, rm) (1) -#define kbd_unexpected_up(kc) (0200) -#define kbd_leds(leds) -#define kbd_init_hw() -//#define kbd_sysrq_xlate ps2kbd_sysrq_xlate #define kbd_disable_irq() #define kbd_enable_irq() -#define SYSRQ_KEY 13 - -#endif +#define SYSRQ_KEY 0x54 diff --git a/include/asm-arm/arch-ebsa285/memory.h b/include/asm-arm/arch-ebsa285/memory.h new file mode 100644 index 000000000..a03cea639 --- /dev/null +++ b/include/asm-arm/arch-ebsa285/memory.h @@ -0,0 +1,74 @@ +/* + * linux/include/asm-arm/arch-ebsa285/memory.h + * + * Copyright (c) 1996-1999 Russell King. + * + * Changelog: + * 20-Oct-1996 RMK Created + * 31-Dec-1997 RMK Fixed definitions to reduce warnings. + * 17-May-1998 DAG Added __virt_to_bus and __bus_to_virt functions. + * 21-Nov-1998 RMK Changed __virt_to_bus and __bus_to_virt to macros. + * 21-Mar-1999 RMK Added PAGE_OFFSET for co285 architecture. + * Renamed to memory.h + * Moved PAGE_OFFSET and TASK_SIZE here + */ +#ifndef __ASM_ARCH_MMU_H +#define __ASM_ARCH_MMU_H + +#include <linux/config.h> + +#if defined(CONFIG_HOST_FOOTBRIDGE) + +/* + * Task size: 3GB + */ +#define TASK_SIZE (0xc0000000UL) + +/* + * Page offset: 3GB + */ +#define PAGE_OFFSET (0xc0000000UL) + +#define __virt_to_bus__is_a_macro +#define __virt_to_bus(x) ((x) - 0xe0000000) +#define __bus_to_virt__is_a_macro +#define __bus_to_virt(x) ((x) + 0xe0000000) + +#elif defined(CONFIG_ADDIN_FOOTBRIDGE) + +#if defined(CONFIG_ARCH_CO285) + +/* + * Task size: 1.5GB + */ +#define TASK_SIZE (0x60000000UL) + +/* + * Page offset: 1.5GB + */ +#define PAGE_OFFSET (0x60000000UL) + +#else + +#error Add in your architecture here + +#endif + +#ifndef __ASSEMBLY__ +extern unsigned long __virt_to_bus(unsigned long); +extern unsigned long __bus_to_virt(unsigned long); +#endif + +#endif + +/* + * On Footbridge machines, the dram is contiguous. + * On Host Footbridge, these conversions are constant. + * On an add-in footbridge, these depend on register settings. + */ +#define __virt_to_phys__is_a_macro +#define __virt_to_phys(vpage) ((unsigned long)(vpage) - PAGE_OFFSET) +#define __phys_to_virt__is_a_macro +#define __phys_to_virt(ppage) ((unsigned long)(ppage) + PAGE_OFFSET) + +#endif diff --git a/include/asm-arm/arch-ebsa285/mm-init.h b/include/asm-arm/arch-ebsa285/mm-init.h deleted file mode 100644 index c6937abd0..000000000 --- a/include/asm-arm/arch-ebsa285/mm-init.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * linux/include/asm-arm/arch-ebsa110/mmap.h - * - * Copyright (C) 1996,1997,1998 Russell King - */ diff --git a/include/asm-arm/arch-ebsa285/mmu.h b/include/asm-arm/arch-ebsa285/mmu.h deleted file mode 100644 index b26aa8f66..000000000 --- a/include/asm-arm/arch-ebsa285/mmu.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * linux/include/asm-arm/arch-ebsa285/mmu.h - * - * Copyright (c) 1996,1997,1998 Russell King. - * - * Changelog: - * 20-10-1996 RMK Created - * 31-12-1997 RMK Fixed definitions to reduce warnings - * 17-05-1998 DAG Added __virt_to_bus and __bus_to_virt functions. - * 21-11-1998 RMK Changed __virt_to_bus and __bus_to_virt to macros. - */ -#ifndef __ASM_ARCH_MMU_H -#define __ASM_ARCH_MMU_H - -/* - * On ebsa285, the dram is contiguous - */ -#define __virt_to_phys__is_a_macro -#define __virt_to_phys(vpage) ((unsigned long)(vpage) - PAGE_OFFSET) -#define __phys_to_virt__is_a_macro -#define __phys_to_virt(ppage) ((unsigned long)(ppage) + PAGE_OFFSET) - -#define __virt_to_bus__is_a_macro -#define __virt_to_bus(x) ((x) - 0xe0000000) -#define __bus_to_virt__is_a_macro -#define __bus_to_virt(x) ((x) + 0xe0000000) - -#endif diff --git a/include/asm-arm/arch-ebsa285/oldlatches.h b/include/asm-arm/arch-ebsa285/oldlatches.h deleted file mode 100644 index 8ff6ebd67..000000000 --- a/include/asm-arm/arch-ebsa285/oldlatches.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Dummy oldlatches.h - * - * Copyright (C) 1996 Russell King - */ - -#ifdef __need_oldlatches -#error "Old latches not present in this (rpc) machine" -#endif diff --git a/include/asm-arm/arch-ebsa285/processor.h b/include/asm-arm/arch-ebsa285/processor.h index e98d1ff33..bd99869af 100644 --- a/include/asm-arm/arch-ebsa285/processor.h +++ b/include/asm-arm/arch-ebsa285/processor.h @@ -1,12 +1,17 @@ /* * linux/include/asm-arm/arch-ebsa110/processor.h * - * Copyright (C) 1996,1997,1998 Russell King + * Copyright (C) 1996-1999 Russell King + * + * Changelog: + * 21-Mar-1999 RMK Added asm/arch/memory.h */ #ifndef __ASM_ARCH_PROCESSOR_H #define __ASM_ARCH_PROCESSOR_H +#include <asm/arch/memory.h> + /* * Bus types */ @@ -15,17 +20,9 @@ #define MCA_bus 0 #define MCA_bus__is_a_macro /* for versions in ksyms.c */ -/* - * User space: 3GB - */ -#define TASK_SIZE (0xc0000000UL) - /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ #define TASK_UNMAPPED_BASE (TASK_SIZE / 3) -#define INIT_MMAP \ -{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } - #endif diff --git a/include/asm-arm/arch-ebsa285/serial.h b/include/asm-arm/arch-ebsa285/serial.h index c874f9dfa..63a699e66 100644 --- a/include/asm-arm/arch-ebsa285/serial.h +++ b/include/asm-arm/arch-ebsa285/serial.h @@ -10,8 +10,6 @@ #ifndef __ASM_ARCH_SERIAL_H #define __ASM_ARCH_SERIAL_H -#include <linux/config.h> - #include <asm/irq.h> /* @@ -23,13 +21,8 @@ */ #define BASE_BAUD (1843200 / 16) -#ifdef CONFIG_CATS -#define _SER_IRQ0 IRQ_ISA(4) -#define _SER_IRQ1 IRQ_ISA(3) -#else -#define _SER_IRQ0 0 -#define _SER_IRQ1 0 -#endif +#define _SER_IRQ0 IRQ_ISA_UART +#define _SER_IRQ1 IRQ_ISA_UART2 #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) diff --git a/include/asm-arm/arch-ebsa285/system.h b/include/asm-arm/arch-ebsa285/system.h index 40d540dba..a8f94c198 100644 --- a/include/asm-arm/arch-ebsa285/system.h +++ b/include/asm-arm/arch-ebsa285/system.h @@ -3,6 +3,8 @@ * * Copyright (c) 1996,1997,1998 Russell King. */ +#include <asm/dec21285.h> +#include <asm/io.h> #include <asm/hardware.h> #include <asm/leds.h> @@ -16,14 +18,37 @@ extern __inline__ void arch_reset(char mode) mov r0, #0x130 mcr p15, 0, r0, c1, c0 @ MMU off mcr p15, 0, ip, c7, c7 @ flush caches - mov pc, lr"); + mov pc, lr" : : : "cc"); } else { - /* To reboot, we set up the 21285 watchdog and enable it. - * We then wait for it to timeout. - */ - *CSR_TIMER4_LOAD = 0x8000; - *CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16; - *CSR_SA110_CNTL |= 1 << 13; + if (machine_is_ebsa285() || machine_is_co285()) { + /* To reboot, we set up the 21285 watchdog and + * enable it. We then wait for it to timeout. + */ + *CSR_TIMER4_LOAD = 0x8000; + *CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE | + TIMER_CNTL_AUTORELOAD | + TIMER_CNTL_DIV16; + *CSR_SA110_CNTL |= 1 << 13; + } else if (machine_is_netwinder()) { + /* open up the SuperIO chip + */ + outb(0x87, 0x370); + outb(0x87, 0x370); + + /* aux function group 1 (logical device 7) + */ + outb(0x07, 0x370); + outb(0x07, 0x371); + + /* set GP16 for WD-TIMER output + */ + outb(0xe6, 0x370); + outb(0x00, 0x371); + + /* set a RED LED and toggle WD_TIMER for rebooting + */ + outb(0xc4, 0x338); + } } } diff --git a/include/asm-arm/arch-ebsa285/time.h b/include/asm-arm/arch-ebsa285/time.h index 342e9528f..ed70ecf25 100644 --- a/include/asm-arm/arch-ebsa285/time.h +++ b/include/asm-arm/arch-ebsa285/time.h @@ -10,116 +10,346 @@ * 21-Mar-1998 RMK Created * 27-Aug-1998 PJB CATS support * 28-Dec-1998 APH Made leds optional + * 20-Jan-1999 RMK Started merge of EBSA285, CATS and NetWinder + * 16-Mar-1999 RMK More support for EBSA285-like machines with RTCs in */ -#define RTC_PORT(x) (0x72+(x)) -#define RTC_ALWAYS_BCD 1 +#define RTC_PORT(x) (rtc_base+(x)) +#define RTC_ALWAYS_BCD 0 #include <linux/config.h> +#include <linux/mc146818rtc.h> + +#include <asm/dec21285.h> #include <asm/leds.h> #include <asm/system.h> -#include <linux/mc146818rtc.h> -extern __inline__ unsigned long gettimeoffset (void) +static int rtc_base; +static unsigned long (*gettimeoffset)(void); +static int (*set_rtc_mmss)(unsigned long nowtime); +static long last_rtc_update = 0; /* last time the cmos clock got updated */ + +#ifdef CONFIG_LEDS +static void do_leds(void) +{ + static unsigned int count = 50; + static int last_pid; + + if (current->pid != last_pid) { + last_pid = current->pid; + if (last_pid) + leds_event(led_idle_end); + else + leds_event(led_idle_start); + } + + if (--count == 0) { + count = 50; + leds_event(led_timer); + } +} +#else +#define do_leds() +#endif + +#define mSEC_10_from_14 ((14318180 + 100) / 200) + +static unsigned long isa_gettimeoffset(void) +{ + int count; + + static int count_p = (mSEC_10_from_14/6); /* for the first call after boot */ + static unsigned long jiffies_p = 0; + + /* + * cache volatile jiffies temporarily; we have IRQs turned off. + */ + unsigned long jiffies_t; + + /* timer count may underflow right here */ + outb_p(0x00, 0x43); /* latch the count ASAP */ + + count = inb_p(0x40); /* read the latched count */ + + /* + * We do this guaranteed double memory access instead of a _p + * postfix in the previous port access. Wheee, hackady hack + */ + jiffies_t = jiffies; + + count |= inb_p(0x40) << 8; + + /* Detect timer underflows. If we haven't had a timer tick since + the last time we were called, and time is apparently going + backwards, the counter must have wrapped during this routine. */ + if ((jiffies_t == jiffies_p) && (count > count_p)) + count -= (mSEC_10_from_14/6); + else + jiffies_p = jiffies_t; + + count_p = count; + + count = (((mSEC_10_from_14/6)-1) - count) * tick; + count = (count + (mSEC_10_from_14/6)/2) / (mSEC_10_from_14/6); + + return count; +} + +static void isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + if (machine_is_netwinder()) + do_leds(); + + do_timer(regs); + + /* If we have an externally synchronized linux clock, then update + * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be + * called as close as possible to 500 ms before the new second starts. + */ + if ((time_status & STA_UNSYNC) == 0 && + xtime.tv_sec > last_rtc_update + 660 && + xtime.tv_usec > 50000 - (tick >> 1) && + xtime.tv_usec < 50000 + (tick >> 1)) { + if (set_rtc_mmss(xtime.tv_sec) == 0) + last_rtc_update = xtime.tv_sec; + else + last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ + } +} + +static struct irqaction isa_timer_irq = { + isa_timer_interrupt, + 0, + 0, + "timer", + NULL, + NULL +}; + +__initfunc(static unsigned long +get_isa_cmos_time(void)) +{ + unsigned int year, mon, day, hour, min, sec; + int i; + + // check to see if the RTC makes sense..... + if ((CMOS_READ(RTC_VALID) & RTC_VRT) == 0) + return mktime(1970, 1, 1, 0, 0, 0); + + /* The Linux interpretation of the CMOS clock register contents: + * When the Update-In-Progress (UIP) flag goes from 1 to 0, the + * RTC registers show the second which has precisely just started. + * Let's hope other operating systems interpret the RTC the same way. + */ + /* read RTC exactly on falling edge of update flag */ + for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ + if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) + break; + + for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ + if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) + break; + + do { /* Isn't this overkill ? UIP above should guarantee consistency */ + sec = CMOS_READ(RTC_SECONDS); + min = CMOS_READ(RTC_MINUTES); + hour = CMOS_READ(RTC_HOURS); + day = CMOS_READ(RTC_DAY_OF_MONTH); + mon = CMOS_READ(RTC_MONTH); + year = CMOS_READ(RTC_YEAR); + } while (sec != CMOS_READ(RTC_SECONDS)); + + if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + } + if ((year += 1900) < 1970) + year += 100; + return mktime(year, mon, day, hour, min, sec); +} + +static int +set_isa_cmos_time(unsigned long nowtime) +{ + int retval = 0; + int real_seconds, real_minutes, cmos_minutes; + unsigned char save_control, save_freq_select; + + save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ + CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); + + save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ + CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); + + cmos_minutes = CMOS_READ(RTC_MINUTES); + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) + BCD_TO_BIN(cmos_minutes); + + /* + * since we're only adjusting minutes and seconds, + * don't interfere with hour overflow. This avoids + * messing with unknown time zones but requires your + * RTC not to be off by more than 15 minutes + */ + real_seconds = nowtime % 60; + real_minutes = nowtime / 60; + if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) + real_minutes += 30; /* correct for half hour time zone */ + real_minutes %= 60; + + if (abs(real_minutes - cmos_minutes) < 30) { + if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { + BIN_TO_BCD(real_seconds); + BIN_TO_BCD(real_minutes); + } + CMOS_WRITE(real_seconds,RTC_SECONDS); + CMOS_WRITE(real_minutes,RTC_MINUTES); + } else + retval = -1; + + /* The following flags have to be released exactly in this order, + * otherwise the DS12887 (popular MC146818A clone with integrated + * battery and quartz) will not reset the oscillator and will not + * update precisely 500 ms later. You won't find this mentioned in + * the Dallas Semiconductor data sheets, but who believes data + * sheets anyway ... -- Markus Kuhn + */ + CMOS_WRITE(save_control, RTC_CONTROL); + CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); + + return retval; +} + + + +static unsigned long __ebsa285_text timer1_gettimeoffset (void) { unsigned long value = LATCH - *CSR_TIMER1_VALUE; return (tick * value) / LATCH; } -extern __inline__ int reset_timer (void) +static void __ebsa285_text timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs) { *CSR_TIMER1_CLR = 0; -#ifdef CONFIG_LEDS - /* - * Do the LEDs thing on EBSA-285 hardware. + /* Do the LEDs things on non-CATS hardware. */ - if (!machine_is_cats()) { - static unsigned int count = 50; - static int last_pid; - - if (current->pid != last_pid) { - last_pid = current->pid; - if (last_pid) - leds_event(led_idle_end); - else - leds_event(led_idle_start); - } - - if (--count == 0) { - count = 50; - leds_event(led_timer); - } + if (!machine_is_cats()) + do_leds(); + + do_timer(regs); + + /* If we have an externally synchronized linux clock, then update + * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be + * called as close as possible to 500 ms before the new second starts. + */ + if ((time_status & STA_UNSYNC) == 0 && + xtime.tv_sec > last_rtc_update + 660 && + xtime.tv_usec > 50000 - (tick >> 1) && + xtime.tv_usec < 50000 + (tick >> 1)) { + if (set_rtc_mmss(xtime.tv_sec) == 0) + last_rtc_update = xtime.tv_sec; + else + last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ } -#endif - - return 1; } -/* - * We don't have a RTC to update! - */ -#define update_rtc() +static struct irqaction __ebsa285_data timer1_irq = { + timer1_interrupt, + 0, + 0, + "timer", + NULL, + NULL +}; + +static int +set_dummy_time(unsigned long secs) +{ + return 1; +} /* * Set up timer interrupt, and return the current time in seconds. */ -extern __inline__ unsigned long setup_timer (void) +extern __inline__ void setup_timer(void) { - int year, mon, day, hour, min, sec; + switch(machine_arch_type) { + case MACH_TYPE_CO285: + /* + * Add-in 21285s shouldn't access the RTC + */ + rtc_base = 0; + break; - /* - * Default the date to 1 Jan 1970 0:0:0 - */ - year = 1970; mon = 1; day = 1; - hour = 0; min = 0; sec = 0; + default: + rtc_base = 0x70; + break; + } + + if (rtc_base) { + int reg_d, reg_b; - *CSR_TIMER1_CLR = 0; - *CSR_TIMER1_LOAD = LATCH; - *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16; + reg_d = CMOS_READ(RTC_REG_D); - if (machine_is_cats()) - { - int i; /* - * Read the real time from the Dallas chip. (Code borrowed - * from arch/i386/kernel/time.c). + * make sure the divider is set */ - - /* The Linux interpretation of the CMOS clock register contents: - * When the Update-In-Progress (UIP) flag goes from 1 to 0, the - * RTC registers show the second which has precisely just started. - * Let's hope other operating systems interpret the RTC the same way. + CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_REG_A); + + /* + * Set control reg B + * (24 hour mode, update enabled) */ + reg_b = CMOS_READ(RTC_REG_B) & 0x7f; + reg_b |= 2; + CMOS_WRITE(reg_b, RTC_REG_B); - /* read RTC exactly on falling edge of update flag */ - for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ - if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) - break; - for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ - if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) - break; - do { /* Isn't this overkill ? UIP above should guarantee consistency */ - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - } while (sec != CMOS_READ(RTC_SECONDS)); - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) - { - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - BCD_TO_BIN(day); - BCD_TO_BIN(mon); - BCD_TO_BIN(year); - } - if ((year += 1900) < 1970) - year += 100; + if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ && + CMOS_READ(RTC_REG_B) == reg_b) { + + /* + * Check the battery + */ + if ((reg_d & 0x80) == 0) + printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n"); + + xtime.tv_sec = get_isa_cmos_time(); + set_rtc_mmss = set_isa_cmos_time; + } else + rtc_base = 0; } - return mktime(year, mon, day, hour, min, sec); + if (!rtc_base) { + /* + * Default the date to 1 Jan 1970 0:0:0 + */ + xtime.tv_sec = mktime(1970, 1, 1, 0, 0, 0); + set_rtc_mmss = set_dummy_time; + } + + if (machine_is_ebsa285()) { + gettimeoffset = timer1_gettimeoffset; + + *CSR_TIMER1_CLR = 0; + *CSR_TIMER1_LOAD = LATCH; + *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16; + + setup_arm_irq(IRQ_TIMER1, &timer1_irq); + } else { + /* enable PIT timer */ + /* set for periodic (4) and LSB/MSB write (0x30) */ + outb(0x34, 0x43); + outb((mSEC_10_from_14/6) & 0xFF, 0x40); + outb((mSEC_10_from_14/6) >> 8, 0x40); + + gettimeoffset = isa_gettimeoffset; + + setup_arm_irq(IRQ_ISA_TIMER, &isa_timer_irq); + } } diff --git a/include/asm-arm/arch-ebsa285/timex.h b/include/asm-arm/arch-ebsa285/timex.h index 0a730a70e..de5bffba8 100644 --- a/include/asm-arm/arch-ebsa285/timex.h +++ b/include/asm-arm/arch-ebsa285/timex.h @@ -7,8 +7,8 @@ */ /* - * On the EBSA, the clock ticks at weird rates. - * This is therefore not used to calculate the - * divisor. + * On EBSA285 boards, the clock runs at 50MHz and is + * divided by a 4-bit prescaler. Other boards use an + * ISA derived timer, and this is unused. */ #define CLOCK_TICK_RATE (50000000 / 16) diff --git a/include/asm-arm/arch-ebsa285/uncompress.h b/include/asm-arm/arch-ebsa285/uncompress.h index 7f655745f..e72e4f362 100644 --- a/include/asm-arm/arch-ebsa285/uncompress.h +++ b/include/asm-arm/arch-ebsa285/uncompress.h @@ -1,9 +1,12 @@ /* - * linux/include/asm-arm/arch-ebsa110/uncompress.h + * linux/include/asm-arm/arch-ebsa285/uncompress.h * * Copyright (C) 1996,1997,1998 Russell King */ +/* + * Note! This could cause problems on the NetWinder + */ #define BASE 0x42000160 static __inline__ void putc(char c) diff --git a/include/asm-arm/arch-nexuspci/a.out.h b/include/asm-arm/arch-nexuspci/a.out.h index 4972f5f70..1cc4d571d 100644 --- a/include/asm-arm/arch-nexuspci/a.out.h +++ b/include/asm-arm/arch-nexuspci/a.out.h @@ -1,15 +1,16 @@ /* * linux/include/asm-arm/arch-nexuspci/a.out.h * - * Copyright (C) 1996 Russell King + * Copyright (C) 1996-1999 Russell King */ - #ifndef __ASM_ARCH_A_OUT_H #define __ASM_ARCH_A_OUT_H -#ifdef __KERNEL__ -#define STACK_TOP ((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000) -#endif +#include <asm/arch/memory.h> + +#define STACK_TOP \ + ((current->personality == PER_LINUX_32BIT) ? \ + TASK_SIZE : 0x04000000) #endif diff --git a/include/asm-arm/arch-nexuspci/hardware.h b/include/asm-arm/arch-nexuspci/hardware.h index 6141bbf4c..2d267d89a 100644 --- a/include/asm-arm/arch-nexuspci/hardware.h +++ b/include/asm-arm/arch-nexuspci/hardware.h @@ -1,10 +1,12 @@ /* * linux/include/asm-arm/arch-nexuspci/hardware.h * - * Copyright (C) 1998 Philip Blundell + * Copyright (C) 1998-1999 Philip Blundell * * This file contains the hardware definitions of the Nexus PCI card. */ +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H /* Logical Physical * 0xfff00000 0x10000000 SCC2691 DUART @@ -13,27 +15,17 @@ * 0xffc00000 0x60000000 PLX registers * 0xfe000000 0x70000000 PCI I/O */ - -#ifndef __ASM_ARCH_HARDWARE_H -#define __ASM_ARCH_HARDWARE_H - -/* - * What hardware must be present - */ - -#define HAS_PCIO -#define PCIO_BASE 0xfe000000 /* * Mapping areas */ -#define IO_BASE 0xfe000000 +#define PCIO_BASE 0xfe000000 +#define FLUSH_BASE 0xdf000000 /* * RAM definitions */ #define RAM_BASE 0x40000000 -#define KERNTOPHYS(a) ((unsigned long)(&a)) #define FLUSH_BASE_PHYS 0x40000000 #endif diff --git a/include/asm-arm/arch-nexuspci/irq.h b/include/asm-arm/arch-nexuspci/irq.h index 7b03006dd..000e6e75f 100644 --- a/include/asm-arm/arch-nexuspci/irq.h +++ b/include/asm-arm/arch-nexuspci/irq.h @@ -9,6 +9,8 @@ #include <asm/io.h> +#define fixup_irq(x) (x) + #define INTCONT 0xffe00000 extern unsigned long soft_irq_mask; diff --git a/include/asm-arm/arch-nexuspci/mmu.h b/include/asm-arm/arch-nexuspci/memory.h index 9ecce067f..e721c040d 100644 --- a/include/asm-arm/arch-nexuspci/mmu.h +++ b/include/asm-arm/arch-nexuspci/memory.h @@ -1,13 +1,24 @@ /* - * linux/include/asm-arm/arch-nexuspci/mmu.h + * linux/include/asm-arm/arch-nexuspci/memory.h * * Copyright (c) 1997, 1998 Philip Blundell. + * Copyright (c) 1999 Russell King * */ #ifndef __ASM_ARCH_MMU_H #define __ASM_ARCH_MMU_H /* + * Task size: 3GB + */ +#define TASK_SIZE (0xc0000000UL) + +/* + * Page offset: 3GB + */ +#define PAGE_OFFSET (0xc0000000UL) + +/* * On NexusPCI, the DRAM is contiguous */ #define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET + 0x40000000) diff --git a/include/asm-arm/arch-nexuspci/mm-init.h b/include/asm-arm/arch-nexuspci/mm-init.h deleted file mode 100644 index 93887c95d..000000000 --- a/include/asm-arm/arch-nexuspci/mm-init.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * linux/include/asm-arm/arch-nexuspci/mmap.h - * - * Copyright (C) 1998 Philip Blundell - */ diff --git a/include/asm-arm/arch-nexuspci/processor.h b/include/asm-arm/arch-nexuspci/processor.h index f722be87c..8349d6d46 100644 --- a/include/asm-arm/arch-nexuspci/processor.h +++ b/include/asm-arm/arch-nexuspci/processor.h @@ -1,13 +1,18 @@ /* - * linux/include/asm-arm/arch-ebsa110/processor.h + * linux/include/asm-arm/arch-nexuspci/processor.h * from linux/include/asm-arm/arch-ebsa110/processor.h * - * Copyright (C) 1996,1997,1998 Russell King + * Copyright (C) 1996-1999 Russell King + * + * Changelog: + * 21-Mar-1999 RMK Added asm/arch/memory.h */ #ifndef __ASM_ARCH_PROCESSOR_H #define __ASM_ARCH_PROCESSOR_H +#include <asm/arch/memory.h> + /* * Bus types */ @@ -16,17 +21,9 @@ #define MCA_bus 0 #define MCA_bus__is_a_macro /* for versions in ksyms.c */ -/* - * User space: 3GB - */ -#define TASK_SIZE (0xc0000000UL) - /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ #define TASK_UNMAPPED_BASE (TASK_SIZE / 3) -#define INIT_MMAP \ -{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } - #endif diff --git a/include/asm-arm/arch-nexuspci/time.h b/include/asm-arm/arch-nexuspci/time.h index 1f3fa401f..17f0ae472 100644 --- a/include/asm-arm/arch-nexuspci/time.h +++ b/include/asm-arm/arch-nexuspci/time.h @@ -17,37 +17,53 @@ extern __inline__ unsigned long gettimeoffset (void) return 0; } -extern __inline__ int reset_timer (void) +static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { static int count = 50; + writeb(0x90, UART_BASE + 8); - if (--count == 0) - { + + if (--count == 0) { static int state = 1; state ^= 1; writeb(0x1a + state, INTCONT); count = 50; } + readb(UART_BASE + 0x14); readb(UART_BASE + 0x14); readb(UART_BASE + 0x14); readb(UART_BASE + 0x14); readb(UART_BASE + 0x14); readb(UART_BASE + 0x14); - return 1; + + do_timer(regs); } -extern __inline__ unsigned long setup_timer (void) +static struct irqaction timerirq = { + timer_interrupt, + 0, + 0, + "timer", + NULL, + NULL +}; + +extern __inline__ void setup_timer(void) { int tick = 3686400 / 16 / 2 / 100; + writeb(tick & 0xff, UART_BASE + 0x1c); writeb(tick >> 8, UART_BASE + 0x18); writeb(0x80, UART_BASE + 8); writeb(0x10, UART_BASE + 0x14); + /* * Default the date to 1 Jan 1970 0:0:0 * You will have to run a time daemon to set the * clock correctly at bootup */ - return mktime(1970, 1, 1, 0, 0, 0); + xtime.tv_sec = mktime(1970, 1, 1, 0, 0, 0); + + setup_arm_irq(IRQ_TIMER, &timerirq); } diff --git a/include/asm-arm/arch-rpc/a.out.h b/include/asm-arm/arch-rpc/a.out.h index 598614f23..56b2f4f7a 100644 --- a/include/asm-arm/arch-rpc/a.out.h +++ b/include/asm-arm/arch-rpc/a.out.h @@ -1,15 +1,16 @@ /* * linux/include/asm-arm/arch-rpc/a.out.h * - * Copyright (C) 1996 Russell King + * Copyright (C) 1996-1999 Russell King */ - #ifndef __ASM_ARCH_A_OUT_H #define __ASM_ARCH_A_OUT_H -#ifdef __KERNEL__ -#define STACK_TOP ((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000) -#endif +#include <asm/arch/memory.h> + +#define STACK_TOP \ + ((current->personality == PER_LINUX_32BIT) ? \ + TASK_SIZE : 0x04000000) #endif diff --git a/include/asm-arm/arch-rpc/hardware.h b/include/asm-arm/arch-rpc/hardware.h index 8ca6273ff..0e3002f85 100644 --- a/include/asm-arm/arch-rpc/hardware.h +++ b/include/asm-arm/arch-rpc/hardware.h @@ -1,19 +1,19 @@ /* * linux/include/asm-arm/arch-rpc/hardware.h * - * Copyright (C) 1996 Russell King. + * Copyright (C) 1996-1999 Russell King. * * This file contains the hardware definitions of the RiscPC series machines. */ - #ifndef __ASM_ARCH_HARDWARE_H #define __ASM_ARCH_HARDWARE_H +#include <asm/arch/memory.h> + /* * What hardware must be present */ #define HAS_IOMD -#include <asm/iomd.h> #define HAS_VIDC20 /* Hardware addresses of major areas. @@ -26,7 +26,7 @@ #define EASI_SIZE 0x08000000 /* EASI I/O */ #define EASI_START 0x08000000 -#define EASI_BASE 0xe8000000 +#define EASI_BASE 0xe5000000 #define IO_START 0x03000000 /* I/O */ #define IO_SIZE 0x01000000 @@ -38,6 +38,8 @@ #define SCREEN1_END 0xd8000000 #define SCREEN1_BASE 0xd0000000 +#define FLUSH_BASE 0xdf000000 + #ifndef __ASSEMBLER__ @@ -47,8 +49,9 @@ #define IO_VIDC_AUDIO_BASE 0x80140000 #define IO_VIDC_BASE 0x80100000 #define IO_IOMD_BASE 0x80080000 +#define IOC_BASE 0x80080000 -#define IO_EC_EASI_BASE 0x82000000 +#define IO_EC_EASI_BASE 0x81400000 #define IO_EC_IOC4_BASE 0x8009c000 #define IO_EC_IOC_BASE 0x80090000 #define IO_EC_MEMC8_BASE 0x8000ac00 @@ -59,7 +62,6 @@ */ #define EXPMASK_BASE ((volatile unsigned char *)0xe0360000) #define IOEB_BASE ((volatile unsigned char *)0xe0350050) -#define IOC_BASE ((volatile unsigned char *)0xe0200000) #define PCIO_FLOPPYDMABASE ((volatile unsigned char *)0xe002a000) #define PCIO_BASE 0xe0010000 @@ -67,23 +69,19 @@ * Offsets from RAM base */ #define PARAMS_OFFSET 0x0100 -#define KERNEL_OFFSET 0x8000 /* * RAM definitions */ -#define MAPTOPHYS(x) (x) -#define KERNTOPHYS(x) ((unsigned long)(&x)) #define GET_MEMORY_END(p) (PAGE_OFFSET + p->u1.s.page_size * \ (p->u1.s.pages_in_bank[0] + \ p->u1.s.pages_in_bank[1] + \ p->u1.s.pages_in_bank[2] + \ p->u1.s.pages_in_bank[3])) -#define KERNEL_BASE (PAGE_OFFSET + KERNEL_OFFSET) #define PARAMS_BASE (PAGE_OFFSET + PARAMS_OFFSET) #define Z_PARAMS_BASE (RAM_START + PARAMS_OFFSET) -#define SAFE_ADDR 0x00000000 /* ROM */ +#define FLUSH_BASE_PHYS 0x00000000 /* ROM */ #else diff --git a/include/asm-arm/arch-rpc/irq.h b/include/asm-arm/arch-rpc/irq.h index a65f487d4..ea284b9a5 100644 --- a/include/asm-arm/arch-rpc/irq.h +++ b/include/asm-arm/arch-rpc/irq.h @@ -7,6 +7,9 @@ * 10-10-1996 RMK Brought up to date with arch-sa110eval * 22-08-1998 RMK Restructured IRQ routines */ +#include <asm/iomd.h> + +#define fixup_irq(x) (x) static void rpc_mask_irq_ack_a(unsigned int irq) { diff --git a/include/asm-arm/arch-rpc/keyboard.h b/include/asm-arm/arch-rpc/keyboard.h index 6c04cf074..c083b08bb 100644 --- a/include/asm-arm/arch-rpc/keyboard.h +++ b/include/asm-arm/arch-rpc/keyboard.h @@ -10,8 +10,6 @@ #define NR_SCANCODES 128 -extern int ps2kbd_pretranslate(unsigned char scancode); -extern int ps2kbd_translate(unsigned char scancode, unsigned char *keycode_p, char *up_flag_p); extern void ps2kbd_leds(unsigned char leds); extern void ps2kbd_init_hw(void); extern unsigned char ps2kbd_sysrq_xlate[NR_SCANCODES]; @@ -19,20 +17,7 @@ extern unsigned char ps2kbd_sysrq_xlate[NR_SCANCODES]; #define kbd_setkeycode(sc,kc) (-EINVAL) #define kbd_getkeycode(sc) (-EINVAL) -/* Prototype: int kbd_pretranslate(scancode, raw_mode) - * Returns : 0 to ignore scancode - */ -#define kbd_pretranslate(sc,rm) ps2kbd_pretranslate(sc) - -/* Prototype: int kbd_translate(scancode, *keycode, *up_flag, raw_mode) - * Returns : 0 to ignore scancode, *keycode set to keycode, *up_flag - * set to 0200 if scancode indicates release - */ -#ifdef NEW_KEYBOARD -#define kbd_translate(sc, kcp, ufp, rm) ps2kbd_translate(sc, kcp, ufp) -#else -#define kbd_translate(sc, kcp, rm) ({ unsigned int up_flag; ps2kbd_translate(sc, kcp, &up_flag); }) -#endif +#define kbd_translate(sc, kcp, rm) ({ *(kcp) = (sc); 1; }) #define kbd_unexpected_up(kc) (0200) #define kbd_leds(leds) ps2kbd_leds(leds) #define kbd_init_hw() ps2kbd_init_hw() diff --git a/include/asm-arm/arch-rpc/mmu.h b/include/asm-arm/arch-rpc/memory.h index 7fca09aaa..6922cd0f3 100644 --- a/include/asm-arm/arch-rpc/mmu.h +++ b/include/asm-arm/arch-rpc/memory.h @@ -1,19 +1,33 @@ /* - * linux/include/asm-arm/arch-rpc/mmu.h + * linux/include/asm-arm/arch-rpc/memory.h * * Copyright (c) 1996,1997,1998 Russell King. * * Changelog: - * 20-10-1996 RMK Created - * 31-12-1997 RMK Fixed definitions to reduce warnings - * 11-01-1998 RMK Uninlined to reduce hits on cache - * 08-02-1998 RMK Added __virt_to_bus and __bus_to_virt + * 20-Oct-1996 RMK Created + * 31-Dec-1997 RMK Fixed definitions to reduce warnings + * 11-Jan-1998 RMK Uninlined to reduce hits on cache + * 08-Feb-1998 RMK Added __virt_to_bus and __bus_to_virt + * 21-Mar-1999 RMK Renamed to memory.h + * RMK Added TASK_SIZE and PAGE_OFFSET */ #ifndef __ASM_ARCH_MMU_H #define __ASM_ARCH_MMU_H +/* + * Task size: 3GB + */ +#define TASK_SIZE (0xc0000000UL) + +/* + * Page offset: 3GB + */ +#define PAGE_OFFSET (0xc0000000UL) + +#ifndef __ASSEMBLY__ extern unsigned long __virt_to_phys(unsigned long vpage); extern unsigned long __phys_to_virt(unsigned long ppage); +#endif /* * These are exactly the same on the RiscPC as the diff --git a/include/asm-arm/arch-rpc/oldlatches.h b/include/asm-arm/arch-rpc/oldlatches.h deleted file mode 100644 index 8ff6ebd67..000000000 --- a/include/asm-arm/arch-rpc/oldlatches.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Dummy oldlatches.h - * - * Copyright (C) 1996 Russell King - */ - -#ifdef __need_oldlatches -#error "Old latches not present in this (rpc) machine" -#endif diff --git a/include/asm-arm/arch-rpc/processor.h b/include/asm-arm/arch-rpc/processor.h index 2fd9155b2..b2b6aec12 100644 --- a/include/asm-arm/arch-rpc/processor.h +++ b/include/asm-arm/arch-rpc/processor.h @@ -1,15 +1,18 @@ /* * linux/include/asm-arm/arch-rpc/processor.h * - * Copyright (c) 1996 Russell King. + * Copyright (c) 1996-1999 Russell King. * * Changelog: - * 10-09-1996 RMK Created + * 10-Sep-1996 RMK Created + * 21-Mar-1999 RMK Added asm/arch/memory.h */ #ifndef __ASM_ARCH_PROCESSOR_H #define __ASM_ARCH_PROCESSOR_H +#include <asm/arch/memory.h> + /* * Bus types */ @@ -18,17 +21,9 @@ #define MCA_bus 0 #define MCA_bus__is_a_macro /* for versions in ksyms.c */ -/* - * User space: 3GB - */ -#define TASK_SIZE (0xc0000000UL) - /* This decides where the kernel will search for a free chunk of vm * space during mmap's. */ #define TASK_UNMAPPED_BASE (TASK_SIZE / 3) -#define INIT_MMAP \ -{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } - #endif diff --git a/include/asm-arm/arch-rpc/system.h b/include/asm-arm/arch-rpc/system.h index e0a16f61d..bb220ced4 100644 --- a/include/asm-arm/arch-rpc/system.h +++ b/include/asm-arm/arch-rpc/system.h @@ -6,7 +6,7 @@ #ifndef __ASM_ARCH_SYSTEM_H #define __ASM_ARCH_SYSTEM_H -#include <asm/proc-fns.h> +#include <asm/iomd.h> #define arch_reset(mode) { \ extern void ecard_reset (int card); \ diff --git a/include/asm-arm/arch-rpc/time.h b/include/asm-arm/arch-rpc/time.h index 3d0f742da..b28666b37 100644 --- a/include/asm-arm/arch-rpc/time.h +++ b/include/asm-arm/arch-rpc/time.h @@ -8,6 +8,9 @@ * 10-Oct-1996 RMK Brought up to date with arch-sa110eval * 04-Dec-1997 RMK Updated for new arch/arm/time.c */ +#include <asm/iomd.h> + +static long last_rtc_update = 0; /* last time the cmos clock got updated */ extern __inline__ unsigned long gettimeoffset (void) { @@ -51,46 +54,148 @@ extern __inline__ unsigned long gettimeoffset (void) return offset; } -/* - * No need to reset the timer at every irq - */ -#define reset_timer() 1 +extern int iic_control(unsigned char, int, char *, int); -/* - * Updating of the RTC. We don't currently write the time to the - * CMOS clock. - */ -#define update_rtc() +static int set_rtc_time(unsigned long nowtime) +{ + char buf[5], ctrl; + + if (iic_control(0xa1, 0, &ctrl, 1) != 0) + printk("RTC: failed to read control reg\n"); + + /* + * Reset divider + */ + ctrl |= 0x80; + + if (iic_control(0xa0, 0, &ctrl, 1) != 0) + printk("RTC: failed to stop the clock\n"); + + /* + * We only set the time - we don't set the date. + * This means that there is the possibility once + * a day for the correction to disrupt the date. + * We really ought to write the time and date, or + * nothing at all. + */ + buf[0] = 0; + buf[1] = nowtime % 60; nowtime /= 60; + buf[2] = nowtime % 60; nowtime /= 60; + buf[3] = nowtime % 24; + + BIN_TO_BCD(buf[1]); + BIN_TO_BCD(buf[2]); + BIN_TO_BCD(buf[3]); + + if (iic_control(0xa0, 1, buf, 4) != 0) + printk("RTC: Failed to set the time\n"); + + /* + * Re-enable divider + */ + ctrl &= ~0x80; + + if (iic_control(0xa0, 0, &ctrl, 1) != 0) + printk("RTC: failed to start the clock\n"); + + return 0; +} + +extern __inline__ unsigned long get_rtc_time(void) +{ + unsigned int year, i; + char buf[8]; + + /* + * The year is not part of the RTC counter + * registers, and is stored in RAM. This + * means that it will not be automatically + * updated. + */ + if (iic_control(0xa1, 0xc0, buf, 1) != 0) + printk("RTC: failed to read the year\n"); + + /* + * If the year is before 1970, then the year + * is actually 100 in advance. This gives us + * a year 2070 bug... + */ + year = 1900 + buf[0]; + if (year < 1970) + year += 100; + + /* + * Read the time and date in one go - this + * will ensure that we don't get any effects + * due to carry (the RTC latches the counters + * during a read). + */ + if (iic_control(0xa1, 2, buf, 5) != 0) { + printk("RTC: failed to read the time and date\n"); + memset(buf, 0, sizeof(buf)); + } + + /*FIXME: + * This doesn't seem to work. Does RISC OS + * actually use the RTC year? It doesn't + * seem to. In that case, how does it update + * the CMOS year? + */ + /*year += (buf[3] >> 6) & 3;*/ + + /* + * The RTC combines years with date and weekday + * with month. We need to mask off this extra + * information before converting the date to + * binary. + */ + buf[4] &= 0x1f; + buf[3] &= 0x3f; +printk("Year %4d mon %02X day %02X hour %02X min %02X sec %02X\n", year, buf[4], buf[3], buf[2], buf[1], buf[0]); + for (i = 0; i < 5; i++) + BCD_TO_BIN(buf[i]); + + return mktime(year, buf[4], buf[3], buf[2], buf[1], buf[0]); +} + +static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + do_timer(regs); + + /* If we have an externally synchronized linux clock, then update + * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be + * called as close as possible to 500 ms before the new second starts. + */ + if ((time_status & STA_UNSYNC) == 0 && + xtime.tv_sec > last_rtc_update + 660 && + xtime.tv_usec >= 50000 - (tick >> 1) && + xtime.tv_usec < 50000 + (tick >> 1)) { + if (set_rtc_time(xtime.tv_sec) == 0) + last_rtc_update = xtime.tv_sec; + else + last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ + } +} + +static struct irqaction timerirq = { + timer_interrupt, + 0, + 0, + "timer", + NULL, + NULL +}; /* * Set up timer interrupt, and return the current time in seconds. */ -extern __inline__ unsigned long setup_timer (void) +extern __inline__ void setup_timer(void) { - extern int iic_control (unsigned char, int, char *, int); - unsigned int year, mon, day, hour, min, sec; - char buf[8]; - outb(LATCH & 255, IOMD_T0LTCHL); outb(LATCH >> 8, IOMD_T0LTCHH); outb(0, IOMD_T0GO); - iic_control (0xa0, 0xc0, buf, 1); - year = buf[0]; - if ((year += 1900) < 1970) - year += 100; + xtime.tv_sec = get_rtc_time(); - iic_control (0xa0, 2, buf, 5); - mon = buf[4] & 0x1f; - day = buf[3] & 0x3f; - hour = buf[2]; - min = buf[1]; - sec = buf[0]; - BCD_TO_BIN(mon); - BCD_TO_BIN(day); - BCD_TO_BIN(hour); - BCD_TO_BIN(min); - BCD_TO_BIN(sec); - - return mktime(year, mon, day, hour, min, sec); + setup_arm_irq(IRQ_TIMER, &timerirq); } diff --git a/include/asm-arm/arch-rpc/uncompress.h b/include/asm-arm/arch-rpc/uncompress.h index 7740f0c3f..21701094a 100644 --- a/include/asm-arm/arch-rpc/uncompress.h +++ b/include/asm-arm/arch-rpc/uncompress.h @@ -5,7 +5,6 @@ */ #define VIDMEM ((char *)SCREEN_START) -#include "../arch/arm/drivers/char/font.h" #include <asm/hardware.h> #include <asm/io.h> diff --git a/include/asm-arm/arch-vnc/a.out.h b/include/asm-arm/arch-vnc/a.out.h deleted file mode 100644 index 011b08373..000000000 --- a/include/asm-arm/arch-vnc/a.out.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * linux/include/asm-arm/arch-ebsa110/a.out.h - * - * Copyright (C) 1996 Russell King - */ - -#ifndef __ASM_ARCH_A_OUT_H -#define __ASM_ARCH_A_OUT_H - -#ifdef __KERNEL__ -#define STACK_TOP ((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000) -#endif - -#endif diff --git a/include/asm-arm/arch-vnc/dma.h b/include/asm-arm/arch-vnc/dma.h deleted file mode 100644 index f205f0376..000000000 --- a/include/asm-arm/arch-vnc/dma.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * linux/include/asm-arm/arch-ebsa110/dma.h - * - * Architecture DMA routes - * - * Copyright (C) 1997.1998 Russell King - */ -#ifndef __ASM_ARCH_DMA_H -#define __ASM_ARCH_DMA_H - -/* - * This is the maximum DMA address that can be DMAd to. - * There should not be more than (0xd0000000 - 0xc0000000) - * bytes of RAM. - */ -#define MAX_DMA_ADDRESS 0xd0000000 -#define MAX_DMA_CHANNELS 8 - -#endif /* _ASM_ARCH_DMA_H */ diff --git a/include/asm-arm/arch-vnc/hardware.h b/include/asm-arm/arch-vnc/hardware.h deleted file mode 100644 index e95b1e7b6..000000000 --- a/include/asm-arm/arch-vnc/hardware.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * linux/include/asm-arm/arch-vnc/hardware.h - * - * Copyright (C) 1998 Corel Computer/Russell King. - * - * This file contains the hardware definitions of the VNC. - */ - -/* Logical Physical - * 0xffe00000 0x7c000000 PCI I/O space - * 0xfe000000 0x42000000 CSR - * 0xfd000000 0x78000000 Outbound write flush - * 0xfc000000 0x79000000 PCI IACK/special space - * 0xf9000000 0x7a000000 PCI Config type 1 - * 0xf8000000 0x7b000000 PCI Config type 0 - * - */ - -#include <asm/dec21285.h> - -#define IO_BASE_ARM_CSR 0xfe000000 -#define PCI_IACK 0xfc000000 - -/* LEDs */ -#define XBUS_LEDS ((volatile unsigned char *)0xfff12000) -#define XBUS_LED_AMBER (1 << 0) -#define XBUS_LED_GREEN (1 << 1) -#define XBUS_LED_RED (1 << 2) -#define XBUS_LED_TOGGLE (1 << 8) - -/* PIC irq control */ -#define PIC_LO 0x20 -#define PIC_MASK_LO 0x21 -#define PIC_HI 0xA0 -#define PIC_MASK_HI 0xA1 - -#define IO_END 0xffffffff -#define IO_BASE 0xe0000000 -#define IO_SIZE (IO_END - IO_BASE) - -#define HAS_PCIO -#define PCIO_BASE 0xffe00000 - -#define KERNTOPHYS(a) ((unsigned long)(&a)) - -//#define PARAMS_OFFSET 0x0100 -//#define PARAMS_BASE (PAGE_OFFSET + PARAMS_OFFSET) - -#define FLUSH_BASE_PHYS 0x50000000 - -/* GPIO pins */ -#define GPIO_CCLK 0x800 -#define GPIO_DSCLK 0x400 -#define GPIO_E2CLK 0x200 -#define GPIO_IOLOAD 0x100 -#define GPIO_RED_LED 0x080 -#define GPIO_WDTIMER 0x040 -#define GPIO_DATA 0x020 -#define GPIO_IOCLK 0x010 -#define GPIO_DONE 0x008 -#define GPIO_FAN 0x004 -#define GPIO_GREEN_LED 0x002 -#define GPIO_RESET 0x001 - -/* CPLD pins */ -#define CPLD_DSRESET 8 -#define CPLD_UNMUTE 2 - -#ifndef __ASSEMBLY__ -extern void gpio_modify_op(int mask, int set); -extern void gpio_modify_io(int mask, int in); -extern int gpio_read(void); -extern void cpld_modify(int mask, int set); -#endif diff --git a/include/asm-arm/arch-vnc/ide.h b/include/asm-arm/arch-vnc/ide.h deleted file mode 100644 index c3761ab90..000000000 --- a/include/asm-arm/arch-vnc/ide.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * linux/include/asm-arm/arch-vnc/ide.h - * - * Copyright (c) 1998 Russell King - * - * Modifications: - * 29-07-1998 RMK Major re-work of IDE architecture specific code - */ -#include <asm/irq.h> - -/* - * Set up a hw structure for a specified data port, control port and IRQ. - * This should follow whatever the default interface uses. - */ -static __inline__ void -ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port, int irq) -{ - ide_ioreg_t reg = (ide_ioreg_t) data_port; - int i; - - memset(hw, 0, sizeof(*hw)); - - for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { - hw->io_ports[i] = reg; - reg += 1; - } - hw->io_ports[IDE_CONTROL_OFFSET] = (ide_ioreg_t) ctrl_port; - hw->irq = irq; -} - -/* - * This registers the standard ports for this architecture with the IDE - * driver. - */ -static __inline__ void -ide_init_default_hwifs(void) -{ - hw_regs_t hw; - - ide_init_hwif_ports(&hw, 0x1f0, 0x3f6, IRQ_HARDDISK); - ide_register_hw(&hw, NULL); -} diff --git a/include/asm-arm/arch-vnc/io.h b/include/asm-arm/arch-vnc/io.h deleted file mode 100644 index da1b48599..000000000 --- a/include/asm-arm/arch-vnc/io.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - * linux/include/asm-arm/arch-ebsa110/io.h - * - * Copyright (C) 1997,1998 Russell King - * - * Modifications: - * 06-Dec-1997 RMK Created. - */ -#ifndef __ASM_ARM_ARCH_IO_H -#define __ASM_ARM_ARCH_IO_H - -/* - * This architecture does not require any delayed IO, and - * has the constant-optimised IO - */ -#undef ARCH_IO_DELAY - -/* - * Dynamic IO functions - let the compiler - * optimize the expressions - */ -#define DECLARE_DYN_OUT(fnsuffix,instr,typ) \ -extern __inline__ void __out##fnsuffix (unsigned int value, unsigned int port) \ -{ \ - __asm__ __volatile__( \ - "str%?" ##instr## " %0, [%1, %2] @ out"###fnsuffix \ - : \ - : "r" (value), "r" (PCIO_BASE), typ (port)); \ -} - -#define DECLARE_DYN_IN(sz,fnsuffix,instr,typ) \ -extern __inline__ unsigned sz __in##fnsuffix (unsigned int port) \ -{ \ - unsigned long value; \ - __asm__ __volatile__( \ - "ldr%?" ##instr## " %0, [%1, %2] @ in"###fnsuffix \ - : "=&r" (value) \ - : "r" (PCIO_BASE), typ (port)); \ - return (unsigned sz)value; \ -} - -extern __inline__ unsigned int __ioaddr (unsigned int port) \ -{ \ - return (unsigned int)(PCIO_BASE + port); \ -} - -#define DECLARE_IO(sz,fnsuffix,instr,typ) \ - DECLARE_DYN_OUT(fnsuffix,instr,typ) \ - DECLARE_DYN_IN(sz,fnsuffix,instr,typ) - -DECLARE_IO(char,b,"b","Jr") -DECLARE_IO(short,w,"h","r") -DECLARE_IO(long,l,"","Jr") - -#undef DECLARE_IO -#undef DECLARE_DYN_OUT -#undef DECLARE_DYN_IN - -/* - * Constant address IO functions - * - * These have to be macros for the 'J' constraint to work - - * +/-4096 immediate operand. - */ -#define __outbc(value,port) \ -({ \ - __asm__ __volatile__( \ - "strb %0, [%1, %2] @ outbc" \ - : \ - : "r" (value), "r" (PCIO_BASE), "Jr" (port)); \ -}) - -#define __inbc(port) \ -({ \ - unsigned char result; \ - __asm__ __volatile__( \ - "ldrb %0, [%1, %2] @ inbc" \ - : "=r" (result) \ - : "r" (PCIO_BASE), "Jr" (port)); \ - result; \ -}) - -#define __outwc(value,port) \ -({ \ - __asm__ __volatile__( \ - "strh %0, [%1, %2] @ outwc" \ - : \ - : "r" (value), "r" (PCIO_BASE), "r" (port)); \ -}) - -#define __inwc(port) \ -({ \ - unsigned short result; \ - __asm__ __volatile__( \ - "ldrh %0, [%1, %2] @ inwc" \ - : "=r" (result) \ - : "r" (PCIO_BASE), "r" (port)); \ - result & 0xffff; \ -}) - -#define __outlc(value,port) \ -({ \ - __asm__ __volatile__( \ - "str %0, [%1, %2] @ outlc" \ - : \ - : "r" (value), "r" (PCIO_BASE), "Jr" (port)); \ -}) - -#define __inlc(port) \ -({ \ - unsigned long result; \ - __asm__ __volatile__( \ - "ldr %0, [%1, %2] @ inlc" \ - : "=r" (result) \ - : "r" (PCIO_BASE), "Jr" (port)); \ - result; \ -}) - -#define __ioaddrc(port) \ -({ \ - unsigned long addr; \ - addr = PCIO_BASE + port; \ - addr; \ -}) - -/* - * Translated address IO functions - * - * IO address has already been translated to a virtual address - */ -#define outb_t(v,p) \ - (*(volatile unsigned char *)(p) = (v)) - -#define inb_t(p) \ - (*(volatile unsigned char *)(p)) - -#define outl_t(v,p) \ - (*(volatile unsigned long *)(p) = (v)) - -#define inl_t(p) \ - (*(volatile unsigned long *)(p)) - -/* - * This is not sufficient... (and it's a hack anyway) - */ -static inline void writeb(unsigned char b, unsigned int addr) -{ - *(volatile unsigned char *)(0xe0000000 + (addr)) = b; -} - -static inline unsigned char readb(unsigned int addr) -{ - return *(volatile unsigned char *)(0xe0000000 + (addr)); -} - -static inline void writew(unsigned short b, unsigned int addr) -{ - *(volatile unsigned short *)(0xe0000000 + (addr)) = b; -} - -static inline unsigned short readw(unsigned int addr) -{ - return *(volatile unsigned short *)(0xe0000000 + (addr)); -} - -static inline void writel(unsigned long b, unsigned int addr) -{ - *(volatile unsigned long *)(0xe0000000 + (addr)) = b; -} - -static inline unsigned long readl(unsigned int addr) -{ - return *(volatile unsigned long *)(0xe0000000 + (addr)); -} - -#endif diff --git a/include/asm-arm/arch-vnc/irq.h b/include/asm-arm/arch-vnc/irq.h deleted file mode 100644 index 10e4d0f9e..000000000 --- a/include/asm-arm/arch-vnc/irq.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * include/asm-arm/arch-vnc/irq.h - * - * Copyright (C) 1998 Russell King - * - * Changelog: - * 22-08-1998 RMK Restructured IRQ routines - */ - -#include <asm/dec21285.h> -#include <asm/irq.h> - -/* - * FootBridge IRQ translation table - * Converts form our IRQ numbers into FootBridge masks (defined in irqs.h) - */ -static int fb_irq_mask[16] = { - 0, - IRQ_MASK_SOFTIRQ, - IRQ_MASK_UART_DEBUG, - 0, - IRQ_MASK_TIMER0, - IRQ_MASK_TIMER1, - IRQ_MASK_TIMER2, - IRQ_MASK_WATCHDOG, - IRQ_MASK_ETHER10, - IRQ_MASK_ETHER100, - IRQ_MASK_VIDCOMP, - IRQ_MASK_EXTERN_IRQ, - IRQ_MASK_DMA1, - 0, - 0, - IRQ_MASK_PCI_ERR -}; - -static void vnc_mask_csr_irq(unsigned int irq) -{ - *CSR_IRQ_DISABLE = fb_irq_mask[irq]; -} - -static void vnc_unmask_csr_irq(unsigned int irq) -{ - *CSR_IRQ_ENABLE = fb_irq_mask[irq]; -} - -static void vnc_mask_pic_lo_irq(unsigned int irq) -{ - unsigned int mask = 1 << (irq & 7); - - outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO); -} - -static void vnc_mask_ack_pic_lo_irq(unsigned int irq) -{ - unsigned int mask = 1 << (irq & 7); - - outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO); - outb(0x20, PIC_LO); -} - -static void vnc_unmask_pic_lo_irq(unsigned int irq) -{ - unsigned int mask = ~(1 << (irq & 7)); - - outb(inb(PIC_MASK_LO) & mask, PIC_MASK_LO); -} - -static void vnc_mask_pic_hi_irq(unsigned int irq) -{ - unsigned int mask = 1 << (irq & 7); - - outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI); -} - -static void vnc_mask_ack_pic_hi_irq(unsigned int irq) -{ - unsigned int mask = 1 << (irq & 7); - - outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI); - outb(0x62, PIC_LO); - outb(0x20, PIC_HI); -} - -static void vnc_unmask_pic_hi_irq(unsigned int irq) -{ - unsigned int mask = 1 << (irq & 7); - - outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI); -} - -static void no_action(int irq, void *dev_id, struct pt_regs *regs) -{ -} - -static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL }; - -static __inline__ void irq_init_irq(void) -{ - unsigned int irq; - - outb(0x11, PIC_LO); - outb(0x10, PIC_MASK_LO); - outb(0x04, PIC_MASK_LO); - outb(1, PIC_MASK_LO); - - outb(0x11, PIC_HI); - outb(0x18, PIC_MASK_HI); - outb(0x02, PIC_MASK_HI); - outb(1, PIC_MASK_HI); - - *CSR_IRQ_DISABLE = ~IRQ_MASK_EXTERN_IRQ; - *CSR_IRQ_ENABLE = IRQ_MASK_EXTERN_IRQ; - *CSR_FIQ_DISABLE = -1; - - for (irq = 0; irq < NR_IRQS; irq++) { - irq_desc[irq].valid = 1; - irq_desc[irq].probe_ok = 1; - - if (irq < 16) { - irq_desc[irq].mask_ack = vnc_mask_csr_irq; - irq_desc[irq].mask = vnc_mask_csr_irq; - irq_desc[irq].unmask = vnc_unmask_csr_irq; - } else if (irq < 24) { -irq_desc[irq].probe_ok = 0; - irq_desc[irq].mask_ack = vnc_mask_ack_pic_lo_irq; - irq_desc[irq].mask = vnc_mask_pic_lo_irq; - irq_desc[irq].unmask = vnc_unmask_pic_lo_irq; - } else { -irq_desc[irq].probe_ok = 0; - irq_desc[irq].mask_ack = vnc_mask_ack_pic_hi_irq; - irq_desc[irq].mask = vnc_mask_pic_hi_irq; - irq_desc[irq].unmask = vnc_unmask_pic_hi_irq; - } - } - - irq_desc[0].probe_ok = 0; - irq_desc[IRQ_SOFTIRQ].probe_ok = 0; - irq_desc[IRQ_CONRX].probe_ok = 0; - irq_desc[IRQ_CONTX].probe_ok = 0; - irq_desc[IRQ_TIMER0].probe_ok = 0; - irq_desc[IRQ_TIMER1].probe_ok = 0; - irq_desc[IRQ_TIMER2].probe_ok = 0; - irq_desc[IRQ_WATCHDOG].probe_ok = 0; - irq_desc[IRQ_DMA1].probe_ok = 0; - irq_desc[13].probe_ok = 0; - irq_desc[14].probe_ok = 0; - irq_desc[IRQ_PCI_ERR].probe_ok = 0; - irq_desc[IRQ_PIC_HI].probe_ok = 0; - irq_desc[29].probe_ok = 0; - irq_desc[31].probe_ok = 0; - - outb(0xff, PIC_MASK_LO); - outb(0xff, PIC_MASK_HI); - - setup_arm_irq(IRQ_PIC_HI, &irq_cascade); -} diff --git a/include/asm-arm/arch-vnc/irqs.h b/include/asm-arm/arch-vnc/irqs.h deleted file mode 100644 index e9df93f5c..000000000 --- a/include/asm-arm/arch-vnc/irqs.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * linux/include/asm-arm/arch-vnc/irqs.h - * - * Copyright (C) 1998 Russell King - */ - -#define NR_IRQS 32 - -/* - * This is a list of all interrupts that the 21285 - * can generate - */ -#define IRQ_SOFTIRQ 1 /* from FB.1 */ -#define IRQ_CONRX 2 /* from FB.2 */ -#define IRQ_CONTX 3 /* from FB.3 */ -#define IRQ_TIMER0 4 /* from FB.4 */ -#define IRQ_TIMER1 5 /* from FB.5 */ -#define IRQ_TIMER2 6 /* from FB.6 */ -#define IRQ_WATCHDOG 7 /* from FB.7 */ -#define IRQ_ETHER10 8 /* from FB.8 */ -#define IRQ_ETHER100 9 /* from FB.9 */ -#define IRQ_VIDCOMP 10 /* from FB.10 */ -#define IRQ_EXTERN_IRQ 11 /* from FB.11: chain to IDE irq's */ -#define IRQ_DMA1 12 /* from future */ -#define IRQ_PCI_ERR 15 /* from FB.[28:31] */ - -#define IRQ_TIMER4 16 /* from 553.0 */ -#define IRQ_KEYBOARD 17 /* from 553.1 */ -#define IRQ_PIC_HI 18 /* from 533.2: chained to 553.[8:15] */ -#define IRQ_UART2 19 /* from 553.3 */ -#define IRQ_UART 20 /* from 553.4 */ -#define IRQ_MOUSE 21 /* from 553.5 */ -#define IRQ_UART_IR 22 /* from 553.6 */ -#define IRQ_PRINTER 23 /* from 553.7 */ -#define IRQ_RTC_ALARM 24 /* from 553.8 */ -#define IRQ_POWERLOW 26 /* from 553.10 */ -#define IRQ_VGA 27 /* from 553.11 */ -#define IRQ_SOUND 28 /* from 553.12 */ -#define IRQ_HARDDISK 30 /* from 553.14 */ - -/* These defines handle the translation from the above FB #defines - * into physical bits for the FootBridge IRQ registers - */ -#define IRQ_MASK_SOFTIRQ 0x00000002 -#define IRQ_MASK_UART_DEBUG 0x0000000C -#define IRQ_MASK_TIMER0 0x00000010 -#define IRQ_MASK_TIMER1 0x00000020 -#define IRQ_MASK_TIMER2 0x00000040 -#define IRQ_MASK_WATCHDOG 0x00000080 -#define IRQ_MASK_ETHER10 0x00000100 -#define IRQ_MASK_ETHER100 0x00000200 -#define IRQ_MASK_VIDCOMP 0x00000400 -#define IRQ_MASK_EXTERN_IRQ 0x00000800 -#define IRQ_MASK_DMA1 0x00030000 -#define IRQ_MASK_PCI_ERR 0xf8800000 - -/* - * Now map them to the Linux interrupts - */ -#undef IRQ_TIMER -#define IRQ_TIMER IRQ_TIMER0 -#undef RTC_IRQ -#define RTC_IRQ IRQ_RTC_ALARM -#undef AUX_IRQ -#define AUX_IRQ IRQ_MOUSE - -#define irq_cannonicalize(i) (i) diff --git a/include/asm-arm/arch-vnc/keyboard.h b/include/asm-arm/arch-vnc/keyboard.h deleted file mode 100644 index 2fa371ff9..000000000 --- a/include/asm-arm/arch-vnc/keyboard.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * linux/include/asm-arm/arch-vnc/keyboard.h - * - * Keyboard driver definitions for VNC architecture - * - * (C) 1998 Russell King - */ - -#include <asm/irq.h> - -#define NR_SCANCODES 128 - -#define KEYBOARD_IRQ IRQ_KEYBOARD - -extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); -extern int pckbd_getkeycode(unsigned int scancode); -extern int pckbd_pretranslate(unsigned char scancode, char raw_mode); -extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, - char raw_mode); -extern char pckbd_unexpected_up(unsigned char keycode); -extern void pckbd_leds(unsigned char leds); -extern void pckbd_init_hw(void); -extern unsigned char pckbd_sysrq_xlate[128]; - -#define kbd_setkeycode pckbd_setkeycode -#define kbd_getkeycode pckbd_getkeycode -#define kbd_pretranslate pckbd_pretranslate -#define kbd_translate(sc, kcp, ufp, rm) ({ *ufp = sc & 0200; \ - pckbd_translate(sc & 0x7f, kcp, rm);}) - -#define kbd_unexpected_up pckbd_unexpected_up -#define kbd_leds pckbd_leds -#define kbd_init_hw() pckbd_init_hw() -#define kbd_sysrq_xlate pckbd_sysrq_xlate -#define kbd_disable_irq() -#define kbd_enable_irq() - -#define SYSRQ_KEY 0x54 diff --git a/include/asm-arm/arch-vnc/mm-init.h b/include/asm-arm/arch-vnc/mm-init.h deleted file mode 100644 index c6937abd0..000000000 --- a/include/asm-arm/arch-vnc/mm-init.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * linux/include/asm-arm/arch-ebsa110/mmap.h - * - * Copyright (C) 1996,1997,1998 Russell King - */ diff --git a/include/asm-arm/arch-vnc/mmu.h b/include/asm-arm/arch-vnc/mmu.h deleted file mode 100644 index 64e334292..000000000 --- a/include/asm-arm/arch-vnc/mmu.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * linux/include/asm-arm/arch-ebsa110/mmu.h - * - * Copyright (c) 1996,1997,1998 Russell King. - * - * Changelog: - * 20-10-1996 RMK Created - * 31-12-1997 RMK Fixed definitions to reduce warnings - */ -#ifndef __ASM_ARCH_MMU_H -#define __ASM_ARCH_MMU_H - -/* - * On ebsa, the dram is contiguous - */ -#define __virt_to_phys__is_a_macro -#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET) -#define __phys_to_virt__is_a_macro -#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET) - -#define __virt_to_bus__is_a_macro -#define __virt_to_bus(x) (x - 0xe0000000) -#define __bus_to_virt__is_a_macro -#define __bus_to_virt(x) (x + 0xe0000000) - -#endif diff --git a/include/asm-arm/arch-vnc/oldlatches.h b/include/asm-arm/arch-vnc/oldlatches.h deleted file mode 100644 index 8ff6ebd67..000000000 --- a/include/asm-arm/arch-vnc/oldlatches.h +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Dummy oldlatches.h - * - * Copyright (C) 1996 Russell King - */ - -#ifdef __need_oldlatches -#error "Old latches not present in this (rpc) machine" -#endif diff --git a/include/asm-arm/arch-vnc/param.h b/include/asm-arm/arch-vnc/param.h deleted file mode 100644 index c86000125..000000000 --- a/include/asm-arm/arch-vnc/param.h +++ /dev/null @@ -1,8 +0,0 @@ -/* - * linux/include/asm-arm/arch-vnc/param.h - * - * Copyright (C) 1996 Russell King - * Copyright (C) 1998 Philip Blundell - */ - -#define HZ 100 diff --git a/include/asm-arm/arch-vnc/processor.h b/include/asm-arm/arch-vnc/processor.h deleted file mode 100644 index 5d84ad498..000000000 --- a/include/asm-arm/arch-vnc/processor.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * linux/include/asm-arm/arch-vnc/processor.h - * - * Copyright (C) 1996,1997,1998 Russell King - */ - -#ifndef __ASM_ARCH_PROCESSOR_H -#define __ASM_ARCH_PROCESSOR_H - -/* - * Bus types - */ -#define EISA_bus 0 -#define EISA_bus__is_a_macro /* for versions in ksyms.c */ -#define MCA_bus 0 -#define MCA_bus__is_a_macro /* for versions in ksyms.c */ - -/* - * User space: 3GB - */ -#define TASK_SIZE (0xc0000000UL) - -/* This decides where the kernel will search for a free chunk of vm - * space during mmap's. - */ -#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) - -#define INIT_MMAP \ -{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } - -#endif diff --git a/include/asm-arm/arch-vnc/serial.h b/include/asm-arm/arch-vnc/serial.h deleted file mode 100644 index 74fea49ce..000000000 --- a/include/asm-arm/arch-vnc/serial.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * linux/include/asm-arm/arch-vnc/serial.h - * - * Copyright (c) 1996 Russell King. - * - * Changelog: - * 15-10-1996 RMK Created - * 03-05-1998 RMK Modified for Corel Video NC - */ -#ifndef __ASM_ARCH_SERIAL_H -#define __ASM_ARCH_SERIAL_H - -#include <asm/irq.h> - -/* - * This assumes you have a 1.8432 MHz clock for your UART. - * - * It'd be nice if someone built a serial card with a 24.576 MHz - * clock, since the 16550A is capable of handling a top speed of 1.5 - * megabits/second; but this requires the faster clock. - */ -#define BASE_BAUD (1843200 / 16) - -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) - - /* UART CLK PORT IRQ FLAGS */ -#define SERIAL_PORT_DFNS \ - { 0, BASE_BAUD, 0x3F8, IRQ_UART , STD_COM_FLAGS }, /* ttyS0 */ \ - { 0, BASE_BAUD, 0x2F8, IRQ_UART2, STD_COM_FLAGS }, /* ttyS1 */ \ - { 0, BASE_BAUD, 0 , 0 , STD_COM_FLAGS }, /* ttyS2 */ \ - { 0, BASE_BAUD, 0 , 0 , STD_COM_FLAGS }, /* ttyS3 */ \ - { 0, BASE_BAUD, 0 , 0 , STD_COM_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0 , 0 , STD_COM_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0 , 0 , STD_COM_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0 , 0 , STD_COM_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0 , 0 , STD_COM_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0 , 0 , STD_COM_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0 , 0 , STD_COM_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0 , 0 , STD_COM_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0 , 0 , STD_COM_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0 , 0 , STD_COM_FLAGS }, /* ttyS13 */ - -#endif diff --git a/include/asm-arm/arch-vnc/shmparam.h b/include/asm-arm/arch-vnc/shmparam.h deleted file mode 100644 index 9c36489cb..000000000 --- a/include/asm-arm/arch-vnc/shmparam.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * linux/include/asm-arm/arch-ebsa110/shmparam.h - * - * Copyright (c) 1996 Russell King. - */ diff --git a/include/asm-arm/arch-vnc/system.h b/include/asm-arm/arch-vnc/system.h deleted file mode 100644 index dc21f08d8..000000000 --- a/include/asm-arm/arch-vnc/system.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * linux/include/asm-arm/arch-vnc/system.h - * - * Copyright (c) 1996,1997,1998 Russell King. - * Copyright (c) 1998 Corel Computer Corp. - */ -#include <asm/hardware.h> -#include <asm/dec21285.h> -#include <asm/leds.h> -#include <asm/io.h> - -extern __inline__ void arch_reset(char mode) -{ - cli(); - - /* open up the SuperIO chip - */ - outb(0x87, 0x370); - outb(0x87, 0x370); - - /* aux function group 1 (Logical Device 7) - */ - outb(0x07, 0x370); - outb(0x07, 0x371); - - /* set GP16 for WD-TIMER output - */ - outb(0xE6, 0x370); - outb(0x00, 0x371); - - /* set a RED LED and toggle WD_TIMER for rebooting... - */ - outb(0xC4, 0x338); -} - -#define arch_start_idle() leds_event(led_idle_start) -#define arch_end_idle() leds_event(led_idle_end) diff --git a/include/asm-arm/arch-vnc/time.h b/include/asm-arm/arch-vnc/time.h deleted file mode 100644 index c55000bdc..000000000 --- a/include/asm-arm/arch-vnc/time.h +++ /dev/null @@ -1,232 +0,0 @@ -/* - * linux/include/asm-arm/arch-vnc/time.h - * - * Copyright (c) 1997 Corel Computer Corp. - * Slight modifications to bring in line with ebsa285 port. - * -- Russell King. - * Added LED driver (based on the ebsa285 code) - Alex Holden 28/12/98. - */ - -#include <linux/config.h> -#include <linux/mc146818rtc.h> - -#include <asm/leds.h> -#include <asm/system.h> - -#undef IRQ_TIMER -#define IRQ_TIMER IRQ_TIMER4 - -#define mSEC_10_from_14 ((14318180 + 100) / 200) - -extern __inline__ unsigned long gettimeoffset (void) -{ - int count; - - static int count_p = (mSEC_10_from_14/6); /* for the first call after boot */ - static unsigned long jiffies_p = 0; - - /* - * cache volatile jiffies temporarily; we have IRQs turned off. - */ - unsigned long jiffies_t; - - /* timer count may underflow right here */ - outb_p(0x00, 0x43); /* latch the count ASAP */ - - count = inb_p(0x40); /* read the latched count */ - - /* - * We do this guaranteed double memory access instead of a _p - * postfix in the previous port access. Wheee, hackady hack - */ - jiffies_t = jiffies; - - count |= inb_p(0x40) << 8; - - /* Detect timer underflows. If we haven't had a timer tick since - the last time we were called, and time is apparently going - backwards, the counter must have wrapped during this routine. */ - if ((jiffies_t == jiffies_p) && (count > count_p)) - count -= (mSEC_10_from_14/6); - else - jiffies_p = jiffies_t; - - count_p = count; - - count = (((mSEC_10_from_14/6)-1) - count) * tick; - count = (count + (mSEC_10_from_14/6)/2) / (mSEC_10_from_14/6); - - return count; -} - -extern __inline__ int reset_timer (void) -{ -#ifdef CONFIG_LEDS - static unsigned int count = 50; - static int last_pid; - - if (current->pid != last_pid) { - last_pid = current->pid; - if (last_pid) - leds_event(led_idle_end); - else - leds_event(led_idle_start); - } - - if (--count == 0) { - count = 50; - leds_event(led_timer); - } -#endif - return 1; -} - -unsigned long set_rtc_mmss(unsigned long nowtime) -{ - int retval = 0; - int real_seconds, real_minutes, cmos_minutes; - unsigned char save_control, save_freq_select; - - save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */ - CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); - - save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */ - CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); - - cmos_minutes = CMOS_READ(RTC_MINUTES); - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) - BCD_TO_BIN(cmos_minutes); - - /* - * since we're only adjusting minutes and seconds, - * don't interfere with hour overflow. This avoids - * messing with unknown time zones but requires your - * RTC not to be off by more than 15 minutes - */ - real_seconds = nowtime % 60; - real_minutes = nowtime / 60; - if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) - real_minutes += 30; /* correct for half hour time zone */ - real_minutes %= 60; - - if (abs(real_minutes - cmos_minutes) < 30) { - if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(real_seconds); - BIN_TO_BCD(real_minutes); - } - CMOS_WRITE(real_seconds,RTC_SECONDS); - CMOS_WRITE(real_minutes,RTC_MINUTES); - } else - retval = -1; - - /* The following flags have to be released exactly in this order, - * otherwise the DS12887 (popular MC146818A clone with integrated - * battery and quartz) will not reset the oscillator and will not - * update precisely 500 ms later. You won't find this mentioned in - * the Dallas Semiconductor data sheets, but who believes data - * sheets anyway ... -- Markus Kuhn - */ - CMOS_WRITE(save_control, RTC_CONTROL); - CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); - - return retval; -} - -/* - * We don't have a RTC to update! - */ -extern __inline__ void update_rtc(void) -{ - static long last_rtc_update = 0; /* last time the cmos clock got updated */ - - /* If we have an externally synchronized linux clock, then update - * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be - * called as close as possible to 500 ms before the new second starts. - */ - if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 && - xtime.tv_usec > 50000 - (tick >> 1) && - xtime.tv_usec < 50000 + (tick >> 1)) { - if (set_rtc_mmss(xtime.tv_sec) == 0) - last_rtc_update = xtime.tv_sec; - else - last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */ - } -} - -extern __inline__ unsigned long get_cmos_time(void) -{ - unsigned int year, mon, day, hour, min, sec; - int i; - - // check to see if the RTC makes sense..... - if ((CMOS_READ(RTC_VALID) & RTC_VRT) == 0) - return mktime(1970, 1, 1, 0, 0, 0); - - /* The Linux interpretation of the CMOS clock register contents: - * When the Update-In-Progress (UIP) flag goes from 1 to 0, the - * RTC registers show the second which has precisely just started. - * Let's hope other operating systems interpret the RTC the same way. - */ - /* read RTC exactly on falling edge of update flag */ - for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */ - if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) - break; - - for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */ - if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)) - break; - - do { /* Isn't this overkill ? UIP above should guarantee consistency */ - sec = CMOS_READ(RTC_SECONDS); - min = CMOS_READ(RTC_MINUTES); - hour = CMOS_READ(RTC_HOURS); - day = CMOS_READ(RTC_DAY_OF_MONTH); - mon = CMOS_READ(RTC_MONTH); - year = CMOS_READ(RTC_YEAR); - } while (sec != CMOS_READ(RTC_SECONDS)); - - if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - BCD_TO_BIN(day); - BCD_TO_BIN(mon); - BCD_TO_BIN(year); - } - if ((year += 1900) < 1970) - year += 100; - return mktime(year, mon, day, hour, min, sec); -} - -/* - * Set up timer interrupt, and return the current time in seconds. - */ -extern __inline__ unsigned long setup_timer (void) -{ - unsigned int c; - - /* Turn on the RTC */ - outb(13, 0x70); - if ((inb(0x71) & 0x80) == 0) - printk("RTC: *** warning: CMOS battery bad\n"); - - outb(10, 0x70); /* select control reg */ - outb(32, 0x71); /* make sure the divider is set */ - outb(11, 0x70); /* select other control reg */ - c = inb(0x71) & 0xfb; /* read it */ - outb(11, 0x70); - outb(c | 2, 0x71); /* turn on BCD counting and 24 hour clock mode */ - - /* enable PIT timer */ - /* set for periodic (4) and LSB/MSB write (0x30) */ - outb(0x34, 0x43); - outb((mSEC_10_from_14/6) & 0xFF, 0x40); - outb((mSEC_10_from_14/6) >> 8, 0x40); - - /* - * Default the date to 1 Jan 1970 00:00:00 - * You will have to run a time daemon to set the - * clock correctly at bootup - */ - return get_cmos_time(); -} diff --git a/include/asm-arm/arch-vnc/timex.h b/include/asm-arm/arch-vnc/timex.h deleted file mode 100644 index c50f118ff..000000000 --- a/include/asm-arm/arch-vnc/timex.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * linux/include/asm-arm/arch-vnc/timex.h - * - * Corel Video NC architecture timex specifications - * - * Copyright (C) 1998 Corel Computer/Russell King - */ - -/* - * On the VNC, the clock runs at 66MHz and is divided - * by a 4-bit prescaler. - */ -#define CLOCK_TICK_RATE (66000000 / 16) diff --git a/include/asm-arm/arch-vnc/uncompress.h b/include/asm-arm/arch-vnc/uncompress.h deleted file mode 100644 index d6097d43f..000000000 --- a/include/asm-arm/arch-vnc/uncompress.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * linux/include/asm-arm/arch-ebsa110/uncompress.h - * - * Copyright (C) 1996,1997,1998 Russell King - */ - -/* - * This does not append a newline - */ -static void puts(const char *s) -{ - __asm__ __volatile__(" - ldrb %0, [%2], #1 - teq %0, #0 - beq 3f -1: strb %0, [%3] -2: ldrb %1, [%3, #0x14] - and %1, %1, #0x60 - teq %1, #0x60 - bne 2b - teq %0, #'\n' - moveq %0, #'\r' - beq 1b - ldrb %0, [%2], #1 - teq %0, #0 - bne 1b -3: " : : "r" (0), "r" (0), "r" (s), "r" (0xf0000be0) : "cc"); -} - -/* - * nothing to do - */ -#define arch_decomp_setup() -#define arch_decomp_wdog() diff --git a/include/asm-arm/cache.h b/include/asm-arm/cache.h index c5b3c6659..48a830351 100644 --- a/include/asm-arm/cache.h +++ b/include/asm-arm/cache.h @@ -6,5 +6,6 @@ #define L1_CACHE_BYTES 32 #define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)) +#define SMP_CACHE_BYTES L1_CACHE_BYTES #endif diff --git a/include/asm-arm/dec21285.h b/include/asm-arm/dec21285.h index 0facd0b7c..e7bfa21c4 100644 --- a/include/asm-arm/dec21285.h +++ b/include/asm-arm/dec21285.h @@ -15,17 +15,20 @@ #define DC21285_PCI_MEM 0x80000000 #ifndef __ASSEMBLY__ -#define DC21285_IO(x) ((volatile unsigned long *)(0xfe000000+(x))) +#include <asm/arch/hardware.h> +#define DC21285_IO(x) ((volatile unsigned long *)(ARMCSR_BASE+(x))) #else #define DC21285_IO(x) (x) #endif #define CSR_PCICMD DC21285_IO(0x0004) +#define CSR_CLASSREV DC21285_IO(0x0008) #define CSR_PCICACHELINESIZE DC21285_IO(0x000c) #define CSR_PCICSRBASE DC21285_IO(0x0010) #define CSR_PCICSRIOBASE DC21285_IO(0x0014) #define CSR_PCISDRAMBASE DC21285_IO(0x0018) #define CSR_PCIROMBASE DC21285_IO(0x0030) +#define CSR_ROMWRITEREG DC21285_IO(0x0068) #define CSR_CSRBASEMASK DC21285_IO(0x00f8) #define CSR_CSRBASEOFFSET DC21285_IO(0x00fc) #define CSR_SDRAMBASEMASK DC21285_IO(0x0100) @@ -44,6 +47,33 @@ #define CSR_I2O_OUTPOSTCOUNT DC21285_IO(0x0134) #define CSR_I2O_INPOSTCOUNT DC21285_IO(0x0138) #define CSR_SA110_CNTL DC21285_IO(0x013c) +#define SA110_CNTL_INITCMPLETE (1 << 0) +#define SA110_CNTL_ASSERTSERR (1 << 1) +#define SA110_CNTL_RXSERR (1 << 3) +#define SA110_CNTL_SA110DRAMPARITY (1 << 4) +#define SA110_CNTL_PCISDRAMPARITY (1 << 5) +#define SA110_CNTL_DMASDRAMPARITY (1 << 6) +#define SA110_CNTL_DISCARDTIMER (1 << 8) +#define SA110_CNTL_PCINRESET (1 << 9) +#define SA110_CNTL_I2O_256 (0 << 10) +#define SA110_CNTL_I20_512 (1 << 10) +#define SA110_CNTL_I2O_1024 (2 << 10) +#define SA110_CNTL_I2O_2048 (3 << 10) +#define SA110_CNTL_I2O_4096 (4 << 10) +#define SA110_CNTL_I2O_8192 (5 << 10) +#define SA110_CNTL_I2O_16384 (6 << 10) +#define SA110_CNTL_I2O_32768 (7 << 10) +#define SA110_CNTL_WATCHDOG (1 << 13) +#define SA110_CNTL_ROMWIDTH_UNDEF (0 << 14) +#define SA110_CNTL_ROMWIDTH_16 (1 << 14) +#define SA110_CNTL_ROMWIDTH_32 (2 << 14) +#define SA110_CNTL_ROMWIDTH_8 (3 << 14) +#define SA110_CNTL_ROMACCESSTIME(x) ((x)<<16) +#define SA110_CNTL_ROMBURSTTIME(x) ((x)<<20) +#define SA110_CNTL_ROMTRISTATETIME(x) ((x)<<24) +#define SA110_CNTL_XCSDIR(x) ((x)<<28) +#define SA110_CNTL_PCICFN (1 << 31) + #define CSR_PCIADDR_EXTN DC21285_IO(0x0140) #define CSR_PREFETCHMEMRANGE DC21285_IO(0x0144) #define CSR_XBUS_CYCLE DC21285_IO(0x0148) diff --git a/include/asm-arm/dma.h b/include/asm-arm/dma.h index 9fb7a0242..46d7cab05 100644 --- a/include/asm-arm/dma.h +++ b/include/asm-arm/dma.h @@ -6,20 +6,20 @@ typedef unsigned int dmach_t; #include <linux/config.h> #include <linux/kernel.h> #include <asm/irq.h> -#include <asm/system.h> #include <asm/spinlock.h> #include <asm/arch/dma.h> /* - * DMA modes - we have two, IN and OUT + * DMA modes */ typedef unsigned int dmamode_t; -#define DMA_MODE_MASK 1 +#define DMA_MODE_MASK 3 -#define DMA_MODE_READ 0 -#define DMA_MODE_WRITE 1 -#define DMA_AUTOINIT 2 +#define DMA_MODE_READ 0 +#define DMA_MODE_WRITE 1 +#define DMA_MODE_CASCADE 2 +#define DMA_AUTOINIT 4 typedef struct { unsigned long address; diff --git a/include/asm-arm/ecard.h b/include/asm-arm/ecard.h index 0f60505f9..56ae7ab35 100644 --- a/include/asm-arm/ecard.h +++ b/include/asm-arm/ecard.h @@ -47,6 +47,9 @@ #define MANU_ICS 0x003c #define PROD_ICS_IDE 0x00ae +#define MANU_ICS2 0x003d +#define PROD_ICS2_IDE 0x00ae + #define MANU_SERPORT 0x003f #define PROD_SERPORT_DSPORT 0x00b9 @@ -76,7 +79,7 @@ #define CONST const #endif -#define MAX_ECARDS 8 +#define MAX_ECARDS 9 typedef enum { /* Cards address space */ ECARD_IOC, @@ -116,14 +119,18 @@ typedef unsigned long *loader_t; typedef struct { /* Card handler routines */ void (*irqenable)(ecard_t *ec, int irqnr); void (*irqdisable)(ecard_t *ec, int irqnr); + int (*irqpending)(ecard_t *ec); void (*fiqenable)(ecard_t *ec, int fiqnr); void (*fiqdisable)(ecard_t *ec, int fiqnr); + int (*fiqpending)(ecard_t *ec); } expansioncard_ops_t; /* * This contains all the info needed on an expansion card */ struct expansion_card { + struct expansion_card *next; + /* Public data */ volatile unsigned char *irqaddr; /* address of IRQ register */ volatile unsigned char *fiqaddr; /* address of FIQ register */ @@ -135,10 +142,10 @@ struct expansion_card { void *fiq_data; /* Data for use for FIQ by card */ expansioncard_ops_t *ops; /* Enable/Disable Ops for card */ - CONST unsigned char slot_no; /* Slot number */ - CONST unsigned char dma; /* DMA number (for request_dma) */ - CONST unsigned char irq; /* IRQ number (for request_irq) */ - CONST unsigned char fiq; /* FIQ number (for request_irq) */ + CONST unsigned int slot_no; /* Slot number */ + CONST unsigned int dma; /* DMA number (for request_dma) */ + CONST unsigned int irq; /* IRQ number (for request_irq) */ + CONST unsigned int fiq; /* FIQ number (for request_irq) */ CONST card_type_t type; /* Type of card */ CONST struct in_ecid cid; /* Card Identification */ diff --git a/include/asm-arm/fiq.h b/include/asm-arm/fiq.h index 0516d115a..0e00841df 100644 --- a/include/asm-arm/fiq.h +++ b/include/asm-arm/fiq.h @@ -30,5 +30,6 @@ extern int claim_fiq(struct fiq_handler *f); extern void release_fiq(struct fiq_handler *f); extern void set_fiq_handler(void *start, unsigned int length); extern void set_fiq_regs(struct pt_regs *regs); +extern void get_fiq_regs(struct pt_regs *regs); #endif diff --git a/include/asm-arm/floppy.h b/include/asm-arm/floppy.h index 865e54035..784ca78c4 100644 --- a/include/asm-arm/floppy.h +++ b/include/asm-arm/floppy.h @@ -119,5 +119,20 @@ static int FDC2 = -1; #define FLOPPY_MOTOR_MASK 0xf0 #define CROSS_64KB(a,s) (0) + +/* + * This allows people to reverse the order of + * fd0 and fd1, in case their hardware is + * strangely connected (as some RiscPCs + * and A5000s seem to be). + */ +static void driveswap(int *ints, int dummy, int dummy2) +{ + floppy_selects[0][0] ^= floppy_selects[0][1]; + floppy_selects[0][1] ^= floppy_selects[0][0]; + floppy_selects[0][0] ^= floppy_selects[0][1]; +} + +#define EXTRA_FLOPPY_PARAMS ,{ "driveswap", &driveswap, NULL, 0, 0 } #endif diff --git a/include/asm-arm/hardware.h b/include/asm-arm/hardware.h index cd4528235..bc7854221 100644 --- a/include/asm-arm/hardware.h +++ b/include/asm-arm/hardware.h @@ -11,10 +11,6 @@ #include <asm/arch/hardware.h> -#ifndef FLUSH_BASE -#define FLUSH_BASE 0xdf000000 -#endif - #ifdef HAS_EXPMASK #ifndef __ASSEMBLER__ #define __EXPMASK(offset) (((volatile unsigned char *)EXPMASK_BASE)[offset]) diff --git a/include/asm-arm/init.h b/include/asm-arm/init.h index c0aa97f7f..66ccbecd3 100644 --- a/include/asm-arm/init.h +++ b/include/asm-arm/init.h @@ -5,7 +5,7 @@ /* C routines */ -#ifdef CONFIG_TEXT_INIT_SECTION +#ifdef CONFIG_TEXT_SECTIONS #define __init __attribute__ ((__section__ (".text.init"))) #define __initfunc(__arginit) \ diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h index e87744b71..35db8e667 100644 --- a/include/asm-arm/io.h +++ b/include/asm-arm/io.h @@ -8,12 +8,35 @@ * constant addresses and variable addresses. * 04-Dec-1997 RMK Moved a lot of this stuff to the new architecture * specific IO header files. + * 27-Mar-1999 PJB Second parameter of memcpy_toio is const.. + * 04-Apr-1999 PJB Added check_signature. */ #ifndef __ASM_ARM_IO_H #define __ASM_ARM_IO_H +#ifdef __KERNEL__ + +#ifndef NULL +#define NULL ((void *) 0) +#endif + +extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); + +/* + * String version of IO memory access ops: + */ +extern void _memcpy_fromio(void *, unsigned long, unsigned long); +extern void _memcpy_toio(unsigned long, const void *, unsigned long); +extern void _memset_io(unsigned long, int, unsigned long); + +#define memcpy_fromio(to,from,len) _memcpy_fromio((to),(unsigned long)(from),(len)) +#define memcpy_toio(to,from,len) _memcpy_toio((unsigned long)(to),(from),(len)) +#define memset_io(addr,c,len) _memset_io((unsigned long)(addr),(c),(len)) + +#endif + #include <asm/hardware.h> -#include <asm/arch/mmu.h> +#include <asm/arch/memory.h> #include <asm/arch/io.h> #include <asm/proc/io.h> @@ -168,25 +191,43 @@ __IO(l,"",long) #endif -#undef ARCH_IO_DELAY -#undef ARCH_IO_CONSTANT +#ifndef ARCH_READWRITE -#ifdef __KERNEL__ +/* for panic */ +#include <linux/kernel.h> -extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); +#define readb(p) (panic("readb called, but not implemented"),0) +#define readw(p) (panic("readw called, but not implemented"),0) +#define readl(p) (panic("readl called, but not implemented"),0) +#define writeb(v,p) panic("writeb called, but not implemented") +#define writew(v,p) panic("writew called, but not implemented") +#define writel(v,p) panic("writel called, but not implemented") + +#endif /* - * String version of IO memory access ops: + * This isn't especially architecture dependent so it seems like it + * might as well go here as anywhere. */ -extern void _memcpy_fromio(void *, unsigned long, unsigned long); -extern void _memcpy_toio(unsigned long, void *, unsigned long); -extern void _memset_io(unsigned long, int, unsigned long); - -#define memcpy_fromio(to,from,len) _memcpy_fromio((to),(unsigned long)(from),(len)) -#define memcpy_toio(to,from,len) _memcpy_toio((unsigned long)(to),(from),(len)) -#define memset_io(addr,c,len) _memset_io((unsigned long)(addr),(c),(len)) - -#endif +static inline int check_signature(unsigned long io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + +#undef ARCH_READWRITE +#undef ARCH_IO_DELAY +#undef ARCH_IO_CONSTANT #endif diff --git a/include/asm-arm/ioc.h b/include/asm-arm/ioc.h index 2b3d6062a..950046048 100644 --- a/include/asm-arm/ioc.h +++ b/include/asm-arm/ioc.h @@ -3,6 +3,8 @@ * read/write. */ +#ifndef IOC_CONTROL + #ifndef __ASSEMBLER__ #define __IOC(offset) (IOC_BASE + (offset >> 2)) #else @@ -54,3 +56,4 @@ #define IOC_T3GO __IOC(0x78) #define IOC_T3LATCH __IOC(0x7c) +#endif diff --git a/include/asm-arm/iomd.h b/include/asm-arm/iomd.h index 375c6fdf1..31be445da 100644 --- a/include/asm-arm/iomd.h +++ b/include/asm-arm/iomd.h @@ -125,6 +125,8 @@ #define DMA_ST_OFL 4 #define DMA_ST_INT 2 #define DMA_ST_AB 1 + +#ifndef IOC_CONTROL /* * IOC compatability */ @@ -155,6 +157,7 @@ #define IOC_T1LTCHH IOMD_T1LTCHH #define IOC_T1GO IOMD_T1GO #define IOC_T1LATCH IOMD_T1LATCH +#endif /* * DMA (MEMC) compatability diff --git a/include/asm-arm/irq.h b/include/asm-arm/irq.h index 0e8c4ad27..9bdd7e00e 100644 --- a/include/asm-arm/irq.h +++ b/include/asm-arm/irq.h @@ -16,9 +16,11 @@ * capability */ #ifndef NO_IRQ -#define NO_IRQ 255 +#define NO_IRQ ((unsigned int)(-1)) #endif +#define disable_irq_nosync(i) disable_irq(i) + extern void disable_irq(unsigned int); extern void enable_irq(unsigned int); diff --git a/include/asm-arm/leds.h b/include/asm-arm/leds.h index f69aa7fce..84a67f767 100644 --- a/include/asm-arm/leds.h +++ b/include/asm-arm/leds.h @@ -10,15 +10,32 @@ #ifndef ASM_ARM_LEDS_H #define ASM_ARM_LEDS_H +#include <linux/config.h> + typedef enum { led_idle_start, led_idle_end, led_timer, led_start, - led_stop + led_stop, + led_claim, /* override idle & timer leds */ + led_release, /* restore idle & timer leds */ + led_green_on, + led_green_off, + led_amber_on, + led_amber_off, + led_red_on, + led_red_off } led_event_t; /* Use this routine to handle LEDs */ -extern void leds_event(led_event_t); + +#ifdef CONFIG_LEDS +extern void (*leds_event)(led_event_t); +#define set_leds_event(r) leds_event = r +#else +#define leds_event(e) +#define set_leds_event(r) +#endif #endif diff --git a/include/asm-arm/memc.h b/include/asm-arm/memc.h index 820738a29..8eea08635 100644 --- a/include/asm-arm/memc.h +++ b/include/asm-arm/memc.h @@ -4,6 +4,9 @@ #define VDMA_START 1 #define VDMA_END 2 +#ifndef __ASSEMBLER__ +extern void memc_write(unsigned int reg, unsigned long val); + #define video_set_dma(start,end,offset) \ do { \ memc_write (VDMA_START, (start >> 2)); \ @@ -11,3 +14,4 @@ do { \ memc_write (VDMA_INIT, (offset >> 2)); \ } while (0) +#endif diff --git a/include/asm-arm/mm-init.h b/include/asm-arm/mm-init.h deleted file mode 100644 index 863e66259..000000000 --- a/include/asm-arm/mm-init.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * linux/include/asm-arm/mm-init.h - * - * Copyright (C) 1997,1998 Russell King - * - * Contained within are structures to describe how to set up the - * initial memory map. It includes both a processor-specific header - * for parsing these structures, and an architecture-specific header - * to fill out the structures. - */ -#ifndef __ASM_MM_INIT_H -#define __ASM_MM_INIT_H - -typedef enum { - // physical address is absolute - init_mem_map_absolute, - /* physical address is relative to start_mem - * as passed in paging_init - */ - init_mem_map_relative_start_mem -} init_memmap_type_t; - -typedef struct { - init_memmap_type_t type; - unsigned long physical_address; - unsigned long virtual_address; - unsigned long size; -} init_memmap_t; - -#define INIT_MEM_MAP_SENTINEL { init_mem_map_absolute, 0, 0, 0 } -#define INIT_MEM_MAP_ABSOLUTE(p,l,s) { init_mem_map_absolute,p,l,s } -#define INIT_MEM_MAP_RELATIVE(o,l,s) { init_mem_map_relative_start_mem,o,l,s } - -/* - * Within this file, initialise an array of init_mem_map_t's - * to describe your initial memory mapping structure. - */ -#include <asm/arch/mm-init.h> - -/* - * Contained within this file is code to read the array - * of init_mem_map_t's created above. - */ -#include <asm/proc/mm-init.h> - -#endif diff --git a/include/asm-arm/page.h b/include/asm-arm/page.h index 810aa479e..704b99b05 100644 --- a/include/asm-arm/page.h +++ b/include/asm-arm/page.h @@ -1,15 +1,15 @@ #ifndef _ASMARM_PAGE_H #define _ASMARM_PAGE_H -#include <asm/arch/mmu.h> +#include <asm/arch/memory.h> #include <asm/proc/page.h> #ifdef __KERNEL__ #define get_user_page(vaddr) __get_free_page(GFP_KERNEL) #define free_user_page(page, addr) free_page(addr) -#define clear_page(page) memzero((void *)(page), PAGE_SIZE) -#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) +#define clear_page(page) memzero((void *)(page), PAGE_SIZE) +#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) #endif diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h index 5512cdd4c..084999561 100644 --- a/include/asm-arm/pgtable.h +++ b/include/asm-arm/pgtable.h @@ -11,5 +11,6 @@ extern int do_check_pgt_cache(int, int); /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ #define PageSkip(page) (0) +#define kern_addr_valid(addr) (1) #endif /* _ASMARM_PGTABLE_H */ diff --git a/include/asm-arm/posix_types.h b/include/asm-arm/posix_types.h index 4c02ac5fe..102be60df 100644 --- a/include/asm-arm/posix_types.h +++ b/include/asm-arm/posix_types.h @@ -45,6 +45,8 @@ typedef struct { #endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ } __kernel_fsid_t; +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + #undef __FD_SET #define __FD_SET(fd, fdsetp) \ (((fd_set *)fdsetp)->fds_bits[fd >> 5] |= (1<<(fd & 31))) @@ -62,3 +64,5 @@ typedef struct { (memset (fdsetp, 0, sizeof (*(fd_set *)fdsetp))) #endif + +#endif diff --git a/include/asm-arm/proc-armo/mm-init-flat.h b/include/asm-arm/proc-armo/mm-init-flat.h deleted file mode 100644 index 919ef59a4..000000000 --- a/include/asm-arm/proc-armo/mm-init-flat.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * linux/include/asm-arm/proc-armo/mmap.h - * - * Copyright (C) 1996 Russell King - * - * This contains the code to setup the memory map on an ARM2/ARM250/ARM3 - * machine. This is both processor & architecture specific, and requires - * some more work to get it to fit into our separate processor and - * architecture structure. - */ - -static unsigned long phys_screen_end; -int page_nr; - -#define setup_processor_functions() - -/* - * This routine needs more work to make it dynamically release/allocate mem! - */ -unsigned long map_screen_mem(unsigned long log_start, unsigned long kmem, int update) -{ - static int updated = 0; - unsigned long address = SCREEN_START, i; - pgd_t *pg_dir; - pmd_t *pm_dir; - pte_t *pt_entry; - - if (updated) - return 0; - updated = update; - - pg_dir = swapper_pg_dir + (SCREEN1_BASE >> PGDIR_SHIFT); - pm_dir = pmd_offset(pg_dir, SCREEN1_BASE); - pt_entry = pte_offset(pm_dir, SCREEN1_BASE); - - for (i = SCREEN1_BASE; i < SCREEN1_END; i += PAGE_SIZE) { - if (i >= log_start) { - *pt_entry = mk_pte(address, __pgprot(_PAGE_PRESENT)); - address += PAGE_SIZE; - } else - *pt_entry = mk_pte(0, __pgprot(0)); - pt_entry++; - } - phys_screen_end = address; - if (update) - flush_tlb_all (); - return kmem; -} - -static inline unsigned long setup_pagetables(unsigned long start_mem, unsigned long end_mem) -{ - unsigned long address; - unsigned int spi; - - page_nr = MAP_NR(end_mem); - - /* Allocate zero page */ - address = PAGE_OFFSET + 480*1024; - for (spi = 0; spi < 32768 >> PAGE_SHIFT; spi++) { - pgd_val(swapper_pg_dir[spi]) = pte_val(mk_pte(address, PAGE_READONLY)); - address += PAGE_SIZE; - } - - while (spi < (PAGE_OFFSET >> PGDIR_SHIFT)) - pgd_val(swapper_pg_dir[spi++]) = 0; - - map_screen_mem (SCREEN1_END - 480*1024, 0, 0); - return start_mem; -} - -static inline void mark_usable_memory_areas(unsigned long *start_mem, unsigned long end_mem) -{ - unsigned long smem = PAGE_ALIGN(*start_mem); - - while (smem < end_mem) { - clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags); - smem += PAGE_SIZE; - } - - for (smem = phys_screen_end; smem < SCREEN2_END; smem += PAGE_SIZE) - clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags); -} diff --git a/include/asm-arm/proc-armo/mm-init.h b/include/asm-arm/proc-armo/mm-init.h index ba4db9e82..ce0fd84e6 100644 --- a/include/asm-arm/proc-armo/mm-init.h +++ b/include/asm-arm/proc-armo/mm-init.h @@ -8,8 +8,8 @@ * some more work to get it to fit into our separate processor and * architecture structure. */ -extern unsigned long phys_screen_end; -extern unsigned long map_screen_mem(unsigned long log_start, unsigned long kmem, int update); +#include <asm/arch/memory.h> + int page_nr; #define setup_processor_functions() @@ -20,10 +20,11 @@ static inline void setup_swapper_dir (int index, pte_t *ptep) set_pmd (pmd_offset (swapper_pg_dir + index, 0), mk_pmd (ptep)); } -static inline unsigned long setup_pagetables(unsigned long start_mem, unsigned long end_mem) +static inline unsigned long +setup_pagetables(unsigned long start_mem, unsigned long end_mem) { unsigned int i; - union {unsigned long l; pte_t *pte; } u; + union { unsigned long l; pte_t *pte; } u; page_nr = MAP_NR(end_mem); @@ -37,14 +38,11 @@ static inline unsigned long setup_pagetables(unsigned long start_mem, unsigned l for (i = 1; i < PTRS_PER_PGD; i++) pgd_val(swapper_pg_dir[i]) = 0; - /* now map screen mem in */ - phys_screen_end = SCREEN2_END; - map_screen_mem (SCREEN1_END - 480*1024, 0, 0); - return start_mem; } -static inline void mark_usable_memory_areas(unsigned long *start_mem, unsigned long end_mem) +static inline void +mark_usable_memory_areas(unsigned long *start_mem, unsigned long end_mem) { unsigned long smem; @@ -54,7 +52,4 @@ static inline void mark_usable_memory_areas(unsigned long *start_mem, unsigned l clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags); smem += PAGE_SIZE; } - - for (smem = phys_screen_end; smem < SCREEN2_END; smem += PAGE_SIZE) - clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags); } diff --git a/include/asm-arm/proc-armo/page.h b/include/asm-arm/proc-armo/page.h index 0e2b4501c..3768284a2 100644 --- a/include/asm-arm/proc-armo/page.h +++ b/include/asm-arm/proc-armo/page.h @@ -68,7 +68,6 @@ typedef unsigned long pgprot_t; #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) /* This handles the memory map.. */ -#define PAGE_OFFSET 0x02000000 #define MAP_NR(addr) (((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT) #endif /* __KERNEL__ */ diff --git a/include/asm-arm/proc-armo/pgtable-flat.h b/include/asm-arm/proc-armo/pgtable-flat.h deleted file mode 100644 index 994fa9f21..000000000 --- a/include/asm-arm/proc-armo/pgtable-flat.h +++ /dev/null @@ -1,307 +0,0 @@ -/* - * linux/include/asm-arm/proc-armo/pgtable.h - * - * Copyright (C) 1995, 1996 Russell King - */ -#ifndef __ASM_PROC_PGTABLE_H -#define __ASM_PROC_PGTABLE_H - -#include <asm/arch/mmu.h> - -#define LIBRARY_TEXT_START 0x0c000000 - -/* - * Cache flushing... - */ -#define flush_cache_all() do { } while (0) -#define flush_cache_mm(mm) do { } while (0) -#define flush_cache_range(mm,start,end) do { } while (0) -#define flush_cache_page(vma,vmaddr) do { } while (0) -#define flush_page_to_ram(page) do { } while (0) - -/* - * TLB flushing: - * - * - flush_tlb() flushes the current mm struct TLBs - * - flush_tlb_all() flushes all processes TLBs - * - flush_tlb_mm(mm) flushes the specified mm context TLB's - * - flush_tlb_page(vma, vmaddr) flushes one page - * - flush_tlb_range(mm, start, end) flushes a range of pages - */ - -#define flush_tlb() flush_tlb_mm(current->mm) - -extern __inline__ void flush_tlb_all(void) -{ - struct task_struct *p; - - p = &init_task; - do { - processor.u.armv2._update_map(p); - p = p->next_task; - } while (p != &init_task); - - processor.u.armv2._remap_memc (current); -} - -extern __inline__ void flush_tlb_mm(struct mm_struct *mm) -{ - struct task_struct *p; - - p = &init_task; - do { - if (p->mm == mm) - processor.u.armv2._update_map(p); - p = p->next_task; - } while (p != &init_task); - - if (current->mm == mm) - processor.u.armv2._remap_memc (current); -} - -#define flush_tlb_range(mm, start, end) flush_tlb_mm(mm) -#define flush_tlb_page(vma, vmaddr) flush_tlb_mm(vma->vm_mm) - -#define __flush_entry_to_ram(entry) - -/* Certain architectures need to do special things when pte's - * within a page table are directly modified. Thus, the following - * hook is made available. - */ -#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval)) - -/* PMD_SHIFT determines the size of the area a second-level page table can map */ -#define PMD_SHIFT PAGE_SHIFT -#define PMD_SIZE (1UL << PMD_SHIFT) -#define PMD_MASK (~(PMD_SIZE-1)) - -/* PGDIR_SHIFT determines what a third-level page table entry can map */ -#define PGDIR_SHIFT PAGE_SHIFT -#define PGDIR_SIZE (1UL << PGDIR_SHIFT) -#define PGDIR_MASK (~(PGDIR_SIZE-1)) - -/* - * entries per page directory level: the arm3 is one-level, so - * we don't really have any PMD or PTE directory physically. - */ -#define PTRS_PER_PTE 1 -#define PTRS_PER_PMD 1 -#define PTRS_PER_PGD 1024 - -/* Just any arbitrary offset to the start of the vmalloc VM area: the - * current 8MB value just means that there will be a 8MB "hole" after the - * physical memory until the kernel virtual memory starts. That means that - * any out-of-bounds memory accesses will hopefully be caught. - * The vmalloc() routines leaves a hole of 4kB between each vmalloced - * area for the same reason. ;) - */ -#define VMALLOC_START 0x01a00000 -#define VMALLOC_VMADDR(x) ((unsigned long)(x)) - -#define _PAGE_PRESENT 0x001 -#define _PAGE_RW 0x002 -#define _PAGE_USER 0x004 -#define _PAGE_PCD 0x010 -#define _PAGE_ACCESSED 0x020 -#define _PAGE_DIRTY 0x040 - -#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) -#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) - -#define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED) -#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) -#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) -#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) -#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) - -/* - * The arm can't do page protection for execute, and considers that the same are read. - * Also, write permissions imply read permissions. This is the closest we can get.. - */ -#define __P000 PAGE_NONE -#define __P001 PAGE_READONLY -#define __P010 PAGE_COPY -#define __P011 PAGE_COPY -#define __P100 PAGE_READONLY -#define __P101 PAGE_READONLY -#define __P110 PAGE_COPY -#define __P111 PAGE_COPY - -#define __S000 PAGE_NONE -#define __S001 PAGE_READONLY -#define __S010 PAGE_SHARED -#define __S011 PAGE_SHARED -#define __S100 PAGE_READONLY -#define __S101 PAGE_READONLY -#define __S110 PAGE_SHARED -#define __S111 PAGE_SHARED - -#undef TEST_VERIFY_AREA - -/* - * BAD_PAGE is used for a bogus page. - * - * ZERO_PAGE is a global shared page that is always zero: used - * for zero-mapped memory areas etc.. - */ -extern pte_t __bad_page(void); -extern unsigned long *empty_zero_page; - -#define BAD_PAGE __bad_page() -#define ZERO_PAGE ((unsigned long) empty_zero_page) - -/* number of bits that fit into a memory pointer */ -#define BYTES_PER_PTR (sizeof(unsigned long)) -#define BITS_PER_PTR (8*BYTES_PER_PTR) - -/* to align the pointer to a pointer address */ -#define PTR_MASK (~(sizeof(void*)-1)) - -/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */ -#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) - -/* to set the page-dir */ -#define SET_PAGE_DIR(tsk,pgdir) \ -do { \ - tsk->tss.memmap = (unsigned long)pgdir; \ - processor.u.armv2._update_map(tsk); \ - if ((tsk) == current) \ - processor.u.armv2._remap_memc (current); \ -} while (0) - -extern unsigned long physical_start; -extern unsigned long physical_end; - -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; } -extern inline void pte_clear(pte_t *ptep) { pte_val(*ptep) = 0; } - -extern inline int pmd_none(pmd_t pmd) { return 0; } -extern inline int pmd_bad(pmd_t pmd) { return 0; } -extern inline int pmd_present(pmd_t pmd) { return 1; } -extern inline void pmd_clear(pmd_t * pmdp) { } - -/* - * The "pgd_xxx()" functions here are trivial for a folded two-level - * setup: the pgd is never bad, and a pmd always exists (as it's folded - * into the pgd entry) - */ -extern inline int pgd_none(pgd_t pgd) { return 0; } -extern inline int pgd_bad(pgd_t pgd) { return 0; } -extern inline int pgd_present(pgd_t pgd) { return 1; } -extern inline void pgd_clear(pgd_t * pgdp) { } - -/* - * The following only work if pte_present() is true. - * Undefined behaviour if not.. - */ -extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; } -extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } -extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; } -extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } -extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -#define pte_cacheable(pte) 1 - -extern inline pte_t pte_nocache(pte_t pte) { return pte; } -extern inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_RW; return pte; } -extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; } -extern inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; } -extern inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~_PAGE_DIRTY; return pte; } -extern inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } -extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_RW; return pte; } -extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; } -extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; } -extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; return pte; } -extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } - -/* - * Conversion functions: convert a page and protection to a page entry, - * and a page entry and page directory to the page they refer to. - */ -extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot) -{ pte_t pte; pte_val(pte) = virt_to_phys(page) | pgprot_val(pgprot); return 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 unsigned long pte_page(pte_t pte) -{ return phys_to_virt(pte_val(pte) & PAGE_MASK); } - -extern inline unsigned long pmd_page(pmd_t pmd) -{ return phys_to_virt(pmd_val(pmd) & PAGE_MASK); } - -/* to find an entry in a page-table-directory */ -extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) -{ - return mm->pgd + (address >> PGDIR_SHIFT); -} - -/* Find an entry in the second-level page table.. */ -#define pmd_offset(dir, address) ((pmd_t *)(dir)) - -/* Find an entry in the third-level page table.. */ -#define pte_offset(dir, address) ((pte_t *)(dir)) - -/* - * Allocate and free page tables. The xxx_kernel() versions are - * used to allocate a kernel page table - this turns on ASN bits - * if any. - */ -extern inline void pte_free_kernel(pte_t * pte) -{ - pte_val(*pte) = 0; -} - -extern inline pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address) -{ - return (pte_t *) pmd; -} - -/* - * allocating and freeing a pmd is trivial: the 1-entry pmd is - * inside the pgd, so has no extra memory associated with it. - */ -#define pmd_free_kernel(pmdp) -#define pmd_alloc_kernel(pgd,address) ((pmd_t *)(pgd)) - -#define pte_free(ptep) -#define pte_alloc(pmd,address) ((pte_t *)(pmd)) - -/* - * allocating and freeing a pmd is trivial: the 1-entry pmd is - * inside the pgd, so has no extra memory associated with it. - */ -#define pmd_free(pmd) -#define pmd_alloc(pgd,address) ((pmd_t *)(pgd)) - -extern inline void pgd_free(pgd_t * pgd) -{ - extern void kfree(void *); - kfree((void *)pgd); -} - -extern inline pgd_t * pgd_alloc(void) -{ - pgd_t *pgd; - extern void *kmalloc(unsigned int, int); - - pgd = (pgd_t *) kmalloc(PTRS_PER_PGD * BYTES_PER_PTR, GFP_KERNEL); - if (pgd) - memset(pgd, 0, PTRS_PER_PGD * BYTES_PER_PTR); - return pgd; -} - -extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; - -#define update_mmu_cache(vma,address,pte) processor.u.armv2._update_mmu_cache(vma,address,pte) - -#define SWP_TYPE(entry) (((entry) >> 1) & 0x7f) -#define SWP_OFFSET(entry) ((entry) >> 8) -#define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8)) - -#endif /* __ASM_PROC_PAGE_H */ - diff --git a/include/asm-arm/proc-armo/pgtable.h b/include/asm-arm/proc-armo/pgtable.h index 934902052..04516e729 100644 --- a/include/asm-arm/proc-armo/pgtable.h +++ b/include/asm-arm/proc-armo/pgtable.h @@ -7,9 +7,9 @@ #ifndef __ASM_PROC_PGTABLE_H #define __ASM_PROC_PGTABLE_H -#include <asm/arch/mmu.h> +#include <linux/config.h> #include <linux/slab.h> -#include <asm/arch/processor.h> /* For TASK_SIZE */ +#include <asm/arch/memory.h> /* For TASK_SIZE */ #define LIBRARY_TEXT_START 0x0c000000 @@ -280,13 +280,17 @@ extern __inline__ unsigned long pte_page(pte_t pte) return __phys_to_virt(pte_val(pte) & PAGE_MASK); } -extern __inline__ pmd_t mk_pmd (pte_t *ptep) +extern __inline__ pmd_t mk_pmd(pte_t *ptep) { pmd_t pmd; pmd_val(pmd) = __virt_to_phys((unsigned long)ptep) | _PAGE_TABLE; return pmd; } +/* these are aliases for the above function */ +#define mk_user_pmd(ptep) mk_pmd(ptep) +#define mk_kernel_pmd(ptep) mk_pmd(ptep) + #define set_pmd(pmdp,pmd) ((*(pmdp)) = (pmd)) extern __inline__ unsigned long pmd_page(pmd_t pmd) @@ -319,6 +323,7 @@ extern __inline__ pte_t * pte_offset(pmd_t *dir, unsigned long address) */ #ifndef __SMP__ +#ifndef CONFIG_NO_PGT_CACHE extern struct pgtable_cache_struct { unsigned long *pgd_cache; unsigned long *pte_cache; @@ -329,13 +334,16 @@ extern struct pgtable_cache_struct { #define pte_quicklist (quicklists.pte_cache) #define pgd_quicklist (quicklists.pgd_cache) #define pgtable_cache_size (quicklists.pgtable_cache_sz) +#endif #else #error Pgtable caches have to be per-CPU, so that no locking is needed. #endif extern pgd_t *get_pgd_slow(void); +extern void free_table(void *table); +#ifndef CONFIG_NO_PGT_CACHE extern __inline__ pgd_t *get_pgd_fast(void) { unsigned long *ret; @@ -355,14 +363,17 @@ extern __inline__ void free_pgd_fast(pgd_t *pgd) pgd_quicklist = (unsigned long *) pgd; pgtable_cache_size++; } +#endif +/* keep this as an inline so we get type checking */ extern __inline__ void free_pgd_slow(pgd_t *pgd) { - kfree(pgd); + free_table((void *)pgd); } extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted); +#ifndef CONFIG_NO_PGT_CACHE extern __inline__ pte_t *get_pte_fast(void) { unsigned long *ret; @@ -381,10 +392,12 @@ extern __inline__ void free_pte_fast(pte_t *pte) pte_quicklist = (unsigned long *) pte; pgtable_cache_size++; } +#endif +/* keep this as an inline so we get type checking */ extern __inline__ void free_pte_slow(pte_t *pte) { - kfree(pte); + free_table((void *)pte); } /* We don't use pmd cache, so this is a dummy routine */ @@ -404,6 +417,26 @@ extern __inline__ void free_pmd_slow(pmd_t *pmd) extern void __bad_pmd(pmd_t *pmd); extern void __bad_pmd_kernel(pmd_t *pmd); +#ifdef CONFIG_NO_PGT_CACHE +#define pte_free_kernel(pte) free_pte_slow(pte) +#define pte_free(pte) free_pte_slow(pte) +#define pgd_free(pgd) free_pgd_slow(pgd) +#define pgd_alloc() get_pgd_slow() + +extern __inline__ pte_t *pte_alloc(pmd_t * pmd, unsigned long address) +{ + address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); + + if (pmd_none (*pmd)) { + return get_pte_slow(pmd, address); + } + if (pmd_bad (*pmd)) { + __bad_pmd(pmd); + return NULL; + } + return (pte_t *) pmd_page(*pmd) + address; +} +#else #define pte_free_kernel(pte) free_pte_fast(pte) #define pte_free(pte) free_pte_fast(pte) #define pgd_free(pgd) free_pgd_fast(pgd) @@ -427,6 +460,7 @@ extern __inline__ pte_t *pte_alloc(pmd_t * pmd, unsigned long address) } return (pte_t *) pmd_page(*pmd) + address; } +#endif /* * allocating and freeing a pmd is trivial: the 1-entry pmd is @@ -448,7 +482,6 @@ extern __inline__ pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address) extern __inline__ void set_pgdir(unsigned long address, pgd_t entry) { struct task_struct * p; - pgd_t *pgd; read_lock(&tasklist_lock); for_each_task(p) { @@ -457,8 +490,14 @@ extern __inline__ void set_pgdir(unsigned long address, pgd_t entry) *pgd_offset(p->mm,address) = entry; } read_unlock(&tasklist_lock); - for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) - pgd[address >> PGDIR_SHIFT] = entry; +#ifndef CONFIG_NO_PGT_CACHE + { + pgd_t *pgd; + for (pgd = (pgd_t *)pgd_quicklist; pgd; + pgd = (pgd_t *)*(unsigned long *)pgd) + pgd[address >> PGDIR_SHIFT] = entry; + } +#endif } extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; diff --git a/include/asm-arm/proc-armo/processor.h b/include/asm-arm/proc-armo/processor.h index 4a8b60d10..4cfd77955 100644 --- a/include/asm-arm/proc-armo/processor.h +++ b/include/asm-arm/proc-armo/processor.h @@ -14,8 +14,6 @@ #ifndef __ASM_PROC_PROCESSOR_H #define __ASM_PROC_PROCESSOR_H -#ifdef __KERNEL__ - #include <asm/assembler.h> #include <linux/string.h> @@ -32,6 +30,8 @@ struct context_save_struct { unsigned long pc; }; +#define INIT_CSS (struct context_save_struct){ 0, 0, 0, 0, 0, 0, 0, SVC26_MODE } + typedef struct { void (*put_byte)(void); /* Special calling convention */ void (*get_byte)(void); /* Special calling convention */ @@ -50,50 +50,13 @@ extern uaccess_t uaccess_user, uaccess_kernel; #define EXTRA_THREAD_STRUCT \ uaccess_t *uaccess; /* User access functions*/ \ - struct context_save_struct *save; \ - unsigned long memmap; \ unsigned long memcmap[256]; #define EXTRA_THREAD_STRUCT_INIT \ - &uaccess_kernel, \ - 0, \ - (unsigned long) swapper_pg_dir, \ + ,&uaccess_kernel, \ { 0, } -DECLARE_THREAD_STRUCT; - -/* - * Return saved PC of a blocked thread. - */ -extern __inline__ unsigned long thread_saved_pc (struct thread_struct *t) -{ - if (t->save) - return t->save->pc & ~PCMASK; - else - return 0; -} - -extern __inline__ unsigned long get_css_fp (struct thread_struct *t) -{ - if (t->save) - return t->save->fp; - else - return 0; -} - -asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call"); - -extern __inline__ void copy_thread_css (struct context_save_struct *save) -{ - save->r4 = - save->r5 = - save->r6 = - save->r7 = - save->r8 = - save->r9 = - save->fp = 0; - save->pc = ((unsigned long)ret_from_sys_call) | SVC26_MODE; -} +#define SWAPPER_PG_DIR ((unsigned long)swapper_pg_dir) #define start_thread(regs,pc,sp) \ ({ \ @@ -105,18 +68,16 @@ extern __inline__ void copy_thread_css (struct context_save_struct *save) regs->ARM_r2 = stack[2]; /* r2 (envp) */ \ regs->ARM_r1 = stack[1]; /* r1 (argv) */ \ regs->ARM_r0 = stack[0]; /* r0 (argc) */ \ - flush_tlb_mm(current->mm); \ }) /* Allocation and freeing of basic task resources. */ /* * NOTE! The task struct and the stack go together */ -#define alloc_task_struct() \ - ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) -#define free_task_struct(p) free_pages((unsigned long)(p),1) +extern unsigned long get_page_8k(int priority); +extern void free_page_8k(unsigned long page); - -#endif +#define ll_alloc_task_struct() ((struct task_struct *)get_page_8k(GFP_KERNEL)) +#define ll_free_task_struct(p) free_page_8k((unsigned long)(p)) #endif diff --git a/include/asm-arm/proc-armo/ptrace.h b/include/asm-arm/proc-armo/ptrace.h index 30a05ecdc..f53aa229d 100644 --- a/include/asm-arm/proc-armo/ptrace.h +++ b/include/asm-arm/proc-armo/ptrace.h @@ -68,8 +68,13 @@ struct pt_regs { /* Are the current registers suitable for user mode? * (used to maintain security in signal handlers) */ -#define valid_user_regs(regs) \ - (user_mode(regs) && ((regs)->ARM_sp & 3) == 0) +static inline int valid_user_regs(struct pt_regs *regs) +{ + if (!user_mode(regs) || regs->ARM_pc & (F_BIT | I_BIT)) + return 1; + + return 0; +} #endif diff --git a/include/asm-arm/proc-armo/semaphore.h b/include/asm-arm/proc-armo/semaphore.h index 483803217..9cd99cf50 100644 --- a/include/asm-arm/proc-armo/semaphore.h +++ b/include/asm-arm/proc-armo/semaphore.h @@ -13,17 +13,19 @@ extern inline void down(struct semaphore * sem) __asm__ __volatile__ (" @ atomic down operation mov r0, pc - orr r1, r0, #0x08000000 + orr lr, r0, #0x08000000 and r0, r0, #0x0c000003 - teqp r1, #0 - ldr r1, [%0] - subs r1, r1, #1 - str r1, [%0] - mov r1, pc, lsr #28 - teqp r0, r1, lsl #28 + teqp lr, #0 + ldr lr, [%0] + subs lr, lr, #1 + str lr, [%0] + mov lr, pc, lsr #28 + teqp r0, lr, lsl #28 movmi r0, %0 - blmi " SYMBOL_NAME_STR(__down) - : : "r" (sem) : "r0", "r1", "r2", "r3", "ip", "lr", "cc"); + blmi " SYMBOL_NAME_STR(__down_failed) + : + : "r" (sem) + : "r0", "lr", "cc"); } /* @@ -36,22 +38,47 @@ extern inline int down_interruptible (struct semaphore * sem) __asm__ __volatile__ (" @ atomic down operation mov r0, pc - orr r1, r0, #0x08000000 + orr lr, r0, #0x08000000 and r0, r0, #0x0c000003 - teqp r1, #0 - ldr r1, [%1] - subs r1, r1, #1 - str r1, [%1] - mov r1, pc, lsr #28 + teqp lr, #0 + ldr lr, [%1] + subs lr, lr, #1 + str lr, [%1] + mov lr, pc, lsr #28 orrmi r0, r0, #0x80000000 @ set N - teqp r0, r1, lsl #28 + teqp r0, lr, lsl #28 movmi r0, %1 movpl r0, #0 - blmi " SYMBOL_NAME_STR(__down_interruptible) " + blmi " SYMBOL_NAME_STR(__down_interruptible_failed) " mov %0, r0" : "=r" (result) : "r" (sem) - : "r0", "r1", "r2", "r3", "ip", "lr", "cc"); + : "r0", "lr", "cc"); + return result; +} + +extern inline int down_trylock(struct semaphore * sem) +{ + int result; + __asm__ __volatile__ (" + @ atomic down operation + mov r0, pc + orr lr, r0, #0x08000000 + and r0, r0, #0x0c000003 + teqp lr, #0 + ldr lr, [%1] + subs lr, lr, #1 + str lr, [%1] + mov lr, pc, lsr #28 + orrmi r0, r0, #0x80000000 @ set N + teqp r0, lr, lsl #28 + movmi r0, %1 + movpl r0, #0 + blmi " SYMBOL_NAME_STR(__down_trylock_failed) " + mov %0, r0" + : "=r" (result) + : "r" (sem) + : "r0", "lr", "cc"); return result; } @@ -66,18 +93,20 @@ extern inline void up(struct semaphore * sem) __asm__ __volatile__ (" @ atomic up operation mov r0, pc - orr r1, r0, #0x08000000 + orr lr, r0, #0x08000000 and r0, r0, #0x0c000003 - teqp r1, #0 - ldr r1, [%0] - adds r1, r1, #1 - str r1, [%0] - mov r1, pc, lsr #28 + teqp lr, #0 + ldr lr, [%0] + adds lr, lr, #1 + str lr, [%0] + mov lr, pc, lsr #28 orrls r0, r0, #0x80000000 @ set N - teqp r0, r1, lsl #28 + teqp r0, lr, lsl #28 movmi r0, %0 - blmi " SYMBOL_NAME_STR(__up) - : : "r" (sem) : "r0", "r1", "r2", "r3", "ip", "lr", "cc"); + blmi " SYMBOL_NAME_STR(__up_wakeup) + : + : "r" (sem) + : "r0", "lr", "cc"); } #endif diff --git a/include/asm-arm/proc-armv/io.h b/include/asm-arm/proc-armv/io.h index 461da303f..8afecd2a5 100644 --- a/include/asm-arm/proc-armv/io.h +++ b/include/asm-arm/proc-armv/io.h @@ -22,17 +22,14 @@ #include <asm/proc-fns.h> -extern inline void dma_cache_inv(unsigned long start, unsigned long size) -{ - processor.u.armv3v4._cache_purge_area(start, start + size); -} +#define dma_cache_inv(start, size) \ + do { processor.u.armv3v4._cache_purge_area((unsigned long)(start), \ + ((unsigned long)(start)+(size))); } while (0) -extern inline void dma_cache_wback(unsigned long start, unsigned long size) -{ - processor.u.armv3v4._cache_wback_area(start, start + size); -} +#define dma_cache_wback(start, size) \ + do { processor.u.armv3v4._cache_wback_area((unsigned long)(start), \ + ((unsigned long)(start)+(size))); } while (0) -extern inline void dma_cache_wback_inv(unsigned long start, unsigned long size) -{ - processor.u.armv3v4._flush_cache_area(start, start + size, 0); -} +#define dma_cache_wback_inv(start, size) \ + do { processor.u.armv3v4._flush_cache_area((unsigned long)(start), \ + ((unsigned long)(start)+(size)), 0); } while (0) diff --git a/include/asm-arm/proc-armv/mm-init.h b/include/asm-arm/proc-armv/mm-init.h index a3f5c327f..a07e9a50e 100644 --- a/include/asm-arm/proc-armv/mm-init.h +++ b/include/asm-arm/proc-armv/mm-init.h @@ -37,7 +37,7 @@ */ #include <asm/pgtable.h> -#define PTE_SIZE (PTRS_PER_PTE * 4) +#define PTE_SIZE (PTRS_PER_PTE * BYTES_PER_PTR) extern unsigned long setup_io_pagetables(unsigned long start_mem); @@ -79,7 +79,7 @@ static inline void alloc_init_page(unsigned long *mem, unsigned long virt, unsigned long phys, int domain, int prot) { pgd_t *pgdp; - pmd_t *pmdp, pmd; + pmd_t *pmdp; pte_t *ptep; pgdp = pgd_offset_k(virt); @@ -92,46 +92,41 @@ alloc_init_page(unsigned long *mem, unsigned long virt, unsigned long phys, int ptep = (pte_t *)memory; memzero(ptep, PTE_SIZE); + memory += PTE_SIZE; - pmd_val(pmd) = __virt_to_phys(memory) | PMD_TYPE_TABLE | PMD_DOMAIN(domain); - set_pmd(pmdp, pmd); + ptep = (pte_t *)memory; + memzero(ptep, PTE_SIZE); + + set_pmd(pmdp, __mk_pmd(ptep, PMD_TYPE_TABLE | PMD_DOMAIN(domain))); *mem = memory + PTE_SIZE; } ptep = pte_offset(pmdp, virt); - pte_val(*ptep) = phys | prot | PTE_TYPE_SMALL; + set_pte(ptep, mk_pte_phys(phys, __pgprot(prot))); } static inline unsigned long setup_pagetables(unsigned long start_mem, unsigned long end_mem) { - unsigned long address; - - /* - * map in zero page - */ - alloc_init_page(&start_mem, 0, __virt_to_phys(PAGE_OFFSET), DOMAIN_USER, PTE_CACHEABLE); - - /* - * ensure no mappings in user space - */ - for (address = PGDIR_SIZE; address < PAGE_OFFSET; address += PGDIR_SIZE) - free_init_section(address); - - /* - * map in physical ram & kernel - */ - for (address = PAGE_OFFSET; address < end_mem; address += PGDIR_SIZE) - alloc_init_section(&start_mem, address, __virt_to_phys(address), DOMAIN_KERNEL, - PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE | PMD_SECT_AP_WRITE); - - /* - * unmap everything else - */ - for (address = end_mem; address; address += PGDIR_SIZE) - free_init_section(address); + unsigned long address = 0; + + do { + if (address >= PAGE_OFFSET && address < end_mem) + /* + * map in physical ram & kernel + */ + alloc_init_section(&start_mem, address, __virt_to_phys(address), DOMAIN_KERNEL, + PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE | PMD_SECT_AP_WRITE); + else + /* + * unmap everything else + */ + free_init_section(address); + + address += PGDIR_SIZE; + } while (address != 0); /* * An area to invalidate the cache @@ -144,6 +139,12 @@ setup_pagetables(unsigned long start_mem, unsigned long end_mem) */ start_mem = setup_io_pagetables(start_mem); + /* + * map in zero page + */ + alloc_init_page(&start_mem, 0, __virt_to_phys(PAGE_OFFSET), + DOMAIN_USER, L_PTE_CACHEABLE | L_PTE_YOUNG | L_PTE_PRESENT); + flush_cache_all(); return start_mem; @@ -156,9 +157,21 @@ void mark_usable_memory_areas(unsigned long *start_mem, unsigned long end_mem) *start_mem = smem = PAGE_ALIGN(*start_mem); + /* + * Mark all of memory from the end of kernel to end of memory + */ while (smem < end_mem) { - clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags); - smem += PAGE_SIZE; + clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags); + smem += PAGE_SIZE; + } + + /* + * Mark memory from page 1 to start of the swapper page directory + */ + smem = PAGE_OFFSET + PAGE_SIZE; + while (smem < (unsigned long)&swapper_pg_dir) { + clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags); + smem += PAGE_SIZE; } } diff --git a/include/asm-arm/proc-armv/pgtable.h b/include/asm-arm/proc-armv/pgtable.h index f3f740373..fd93bdd29 100644 --- a/include/asm-arm/proc-armv/pgtable.h +++ b/include/asm-arm/proc-armv/pgtable.h @@ -3,14 +3,15 @@ * * Copyright (C) 1995, 1996, 1997 Russell King * - * 12-01-1997 RMK Altered flushing routines to use function pointers + * 12-Jan-1997 RMK Altered flushing routines to use function pointers * now possible to combine ARM6, ARM7 and StrongARM versions. + * 17-Apr-1999 RMK Now pass an area size to clean_cache_area and + * flush_icache_area. */ #ifndef __ASM_PROC_PGTABLE_H #define __ASM_PROC_PGTABLE_H -#include <asm/arch/mmu.h> -#include <asm/arch/processor.h> /* For TASK_SIZE */ +#include <asm/arch/memory.h> /* For TASK_SIZE */ #define LIBRARY_TEXT_START 0x0c000000 @@ -41,8 +42,23 @@ ((_vma)->vm_flags & VM_EXEC) ? 1 : 0); \ } while (0) +#define clean_cache_range(_start,_end) \ + do { \ + unsigned long _s, _sz; \ + _s = (unsigned long)_start; \ + _sz = (unsigned long)_end - _s; \ + processor.u.armv3v4._clean_cache_area(_s, _sz); \ + } while (0) + +#define clean_cache_area(_start,_size) \ + do { \ + unsigned long _s; \ + _s = (unsigned long)_start; \ + processor.u.armv3v4._clean_cache_area(_s, _size); \ + } while (0) + #define flush_icache_range(_start,_end) \ - processor.u.armv3v4._flush_icache_area((_start), (_end)) + processor.u.armv3v4._flush_icache_area((_start), (_end) - (_start)) /* * We don't have a MEMC chip... @@ -60,12 +76,6 @@ processor.u.armv3v4._flush_ram_page ((_page) & PAGE_MASK); /* - * Make the page uncacheable (must flush page beforehand). - */ -#define uncache_page(_page) \ - processor.u.armv3v4._flush_ram_page ((_page) & PAGE_MASK); - -/* * TLB flushing: * * - flush_tlb() flushes the current mm struct TLBs @@ -106,22 +116,15 @@ } while (0) /* - * Since the page tables are in cached memory, we need to flush the dirty - * data cached entries back before we flush the tlb... This is also useful - * to flush out the SWI instruction for signal handlers... + * PMD_SHIFT determines the size of the area a second-level page table can map */ -#define __flush_entry_to_ram(entry) \ - processor.u.armv3v4._flush_cache_entry((unsigned long)(entry)) - -#define __flush_pte_to_ram(entry) \ - processor.u.armv3v4._flush_cache_pte((unsigned long)(entry)) - -/* PMD_SHIFT determines the size of the area a second-level page table can map */ #define PMD_SHIFT 20 #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) -/* PGDIR_SHIFT determines what a third-level page table entry can map */ +/* + * PGDIR_SHIFT determines what a third-level page table entry can map + */ #define PGDIR_SHIFT 20 #define PGDIR_SIZE (1UL << PGDIR_SHIFT) #define PGDIR_MASK (~(PGDIR_SIZE-1)) @@ -135,6 +138,7 @@ #define PTRS_PER_PGD 4096 #define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) + /* Just any arbitrary offset to the start of the vmalloc VM area: the * current 8MB value just means that there will be a 8MB "hole" after the * physical memory until the kernel virtual memory starts. That means that @@ -147,87 +151,28 @@ #define VMALLOC_VMADDR(x) ((unsigned long)(x)) #define VMALLOC_END (PAGE_OFFSET + 0x10000000) -/* PMD types (actually level 1 descriptor) */ -#define PMD_TYPE_MASK 0x0003 -#define PMD_TYPE_FAULT 0x0000 -#define PMD_TYPE_TABLE 0x0001 -#define PMD_TYPE_SECT 0x0002 -#define PMD_UPDATABLE 0x0010 -#define PMD_SECT_CACHEABLE 0x0008 -#define PMD_SECT_BUFFERABLE 0x0004 -#define PMD_SECT_AP_WRITE 0x0400 -#define PMD_SECT_AP_READ 0x0800 -#define PMD_DOMAIN(x) ((x) << 5) -/* PTE types (actially level 2 descriptor) */ -#define PTE_TYPE_MASK 0x0003 -#define PTE_TYPE_FAULT 0x0000 -#define PTE_TYPE_LARGE 0x0001 -#define PTE_TYPE_SMALL 0x0002 -#define PTE_AP_READ 0x0aa0 -#define PTE_AP_WRITE 0x0550 -#define PTE_CACHEABLE 0x0008 -#define PTE_BUFFERABLE 0x0004 - -/* Domains */ +/* + * Domains + */ #define DOMAIN_USER 0 #define DOMAIN_KERNEL 1 #define DOMAIN_TABLE 1 #define DOMAIN_IO 2 -#define _PAGE_CHG_MASK (0xfffff00c | PTE_TYPE_MASK) -/* - * We define the bits in the page tables as follows: - * PTE_BUFFERABLE page is dirty - * PTE_AP_WRITE page is writable - * PTE_AP_READ page is a young (unsetting this causes faults for any access) - * PTE_CACHEABLE page is readable - * - * A page will not be made writable without the dirty bit set. - * It is not legal to have a writable non-dirty page though (it breaks). - * - * A readable page is marked as being cacheable. - * Youngness is indicated by hardware read. If the page is old, - * then we will fault and make the page young again. - */ -#define _PTE_YOUNG PTE_AP_READ -#define _PTE_DIRTY PTE_BUFFERABLE -#define _PTE_READ PTE_CACHEABLE -#define _PTE_WRITE PTE_AP_WRITE -#define PAGE_NONE __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG) -#define PAGE_SHARED __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG | _PTE_READ | _PTE_WRITE) -#define PAGE_COPY __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG | _PTE_READ) -#define PAGE_READONLY __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG | _PTE_READ) -#define PAGE_KERNEL __pgprot(PTE_TYPE_SMALL | _PTE_READ | _PTE_DIRTY | _PTE_WRITE) - -#define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_USER)) -#define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_KERNEL)) +#undef TEST_VERIFY_AREA /* - * The arm can't do page protection for execute, and considers that the same are read. - * Also, write permissions imply read permissions. This is the closest we can get.. + * The sa110 doesn't have any external MMU info: the kernel page + * tables contain all the necessary information. */ -#define __P000 PAGE_NONE -#define __P001 PAGE_READONLY -#define __P010 PAGE_COPY -#define __P011 PAGE_COPY -#define __P100 PAGE_READONLY -#define __P101 PAGE_READONLY -#define __P110 PAGE_COPY -#define __P111 PAGE_COPY - -#define __S000 PAGE_NONE -#define __S001 PAGE_READONLY -#define __S010 PAGE_SHARED -#define __S011 PAGE_SHARED -#define __S100 PAGE_READONLY -#define __S101 PAGE_READONLY -#define __S110 PAGE_SHARED -#define __S111 PAGE_SHARED +extern __inline__ void update_mmu_cache(struct vm_area_struct * vma, + unsigned long address, pte_t pte) +{ +} -#undef TEST_VERIFY_AREA /* * BAD_PAGETABLE is used when we need a bogus page-table, while @@ -240,97 +185,40 @@ extern pte_t __bad_page(void); extern pte_t * __bad_pagetable(void); extern unsigned long *empty_zero_page; -#define BAD_PAGETABLE __bad_pagetable() -#define BAD_PAGE __bad_page() -#define ZERO_PAGE ((unsigned long) empty_zero_page) +#define BAD_PAGETABLE __bad_pagetable() +#define BAD_PAGE __bad_page() +#define ZERO_PAGE ((unsigned long) empty_zero_page) /* number of bits that fit into a memory pointer */ -#define BYTES_PER_PTR (sizeof(unsigned long)) -#define BITS_PER_PTR (8*BYTES_PER_PTR) +#define BYTES_PER_PTR (sizeof(unsigned long)) +#define BITS_PER_PTR (8*BYTES_PER_PTR) /* to align the pointer to a pointer address */ -#define PTR_MASK (~(sizeof(void*)-1)) +#define PTR_MASK (~(sizeof(void*)-1)) /* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */ -#define SIZEOF_PTR_LOG2 2 +#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) -/* to set the page-dir */ +/* to set the page-dir + * Note that we need to flush the cache and TLBs + * if we are affecting the current task. + */ #define SET_PAGE_DIR(tsk,pgdir) \ do { \ tsk->tss.memmap = __virt_to_phys((unsigned long)pgdir); \ - if ((tsk) == current) \ + if ((tsk) == current) { \ + flush_cache_all(); \ __asm__ __volatile__( \ "mcr%? p15, 0, %0, c2, c0, 0\n" \ : : "r" (tsk->tss.memmap)); \ + flush_tlb_all(); \ + } \ } while (0) -extern __inline__ int pte_none(pte_t pte) -{ - return !pte_val(pte); -} - -#define pte_clear(ptep) set_pte(ptep, __pte(0)) - -extern __inline__ int pte_present(pte_t pte) -{ -#if 0 - /* This is what it really does, the else - part is just to make it easier for the compiler */ - switch (pte_val(pte) & PTE_TYPE_MASK) { - case PTE_TYPE_LARGE: - case PTE_TYPE_SMALL: - return 1; - default: - return 0; - } -#else - return ((pte_val(pte) + 1) & 2); -#endif -} - -extern __inline__ int pmd_none(pmd_t pmd) -{ - return !pmd_val(pmd); -} - -#define pmd_clear(pmdp) set_pmd(pmdp, __pmd(0)) - -extern __inline__ int pmd_bad(pmd_t pmd) -{ -#if 0 - /* This is what it really does, the else - part is just to make it easier for the compiler */ - switch (pmd_val(pmd) & PMD_TYPE_MASK) { - case PMD_TYPE_FAULT: - case PMD_TYPE_TABLE: - return 0; - default: - return 1; - } -#else - return pmd_val(pmd) & 2; -#endif -} - -extern __inline__ int pmd_present(pmd_t pmd) -{ -#if 0 - /* This is what it really does, the else - part is just to make it easier for the compiler */ - switch (pmd_val(pmd) & PMD_TYPE_MASK) { - case PMD_TYPE_TABLE: - return 1; - default: - return 0; - } -#else - return ((pmd_val(pmd) + 1) & 2); -#endif -} /* * The "pgd_xxx()" functions here are trivial for a folded two-level @@ -342,231 +230,224 @@ extern __inline__ int pmd_present(pmd_t pmd) #define pgd_present(pgd) (1) #define pgd_clear(pgdp) -/* - * The following only work if pte_present() is true. - * Undefined behaviour if not.. - */ -#define pte_read(pte) (1) -#define pte_exec(pte) (1) +/* to find an entry in a kernel page-table-directory */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) -extern __inline__ int pte_write(pte_t pte) +/* to find an entry in a page-table-directory */ +extern __inline__ pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) { - return pte_val(pte) & _PTE_WRITE; + return mm->pgd + (address >> PGDIR_SHIFT); } -extern __inline__ int pte_dirty(pte_t pte) -{ - return pte_val(pte) & _PTE_DIRTY; -} +extern unsigned long get_page_2k(int priority); +extern void free_page_2k(unsigned long page); -extern __inline__ int pte_young(pte_t pte) -{ - return pte_val(pte) & _PTE_YOUNG; -} +/* + * Allocate and free page tables. The xxx_kernel() versions are + * used to allocate a kernel page table - this turns on ASN bits + * if any. + */ -extern __inline__ pte_t pte_wrprotect(pte_t pte) -{ - pte_val(pte) &= ~_PTE_WRITE; - return pte; -} +#ifndef __SMP__ +extern struct pgtable_cache_struct { + unsigned long *pgd_cache; + unsigned long *pte_cache; + unsigned long pgtable_cache_sz; +} quicklists; -extern __inline__ pte_t pte_nocache(pte_t pte) -{ - pte_val(pte) &= ~PTE_CACHEABLE; - return pte; -} +#define pgd_quicklist (quicklists.pgd_cache) +#define pmd_quicklist ((unsigned long *)0) +#define pte_quicklist (quicklists.pte_cache) +#define pgtable_cache_size (quicklists.pgtable_cache_sz) +#else +#error Pgtable caches have to be per-CPU, so that no locking is needed. +#endif -extern __inline__ pte_t pte_mkclean(pte_t pte) -{ - pte_val(pte) &= ~_PTE_DIRTY; - return pte; -} +extern pgd_t *get_pgd_slow(void); -extern __inline__ pte_t pte_mkold(pte_t pte) +extern __inline__ pgd_t *get_pgd_fast(void) { - pte_val(pte) &= ~_PTE_YOUNG; - return pte; + unsigned long *ret; + + if((ret = pgd_quicklist) != NULL) { + pgd_quicklist = (unsigned long *)(*ret); + ret[0] = ret[1]; + clean_cache_area(ret, 4); + pgtable_cache_size--; + } else + ret = (unsigned long *)get_pgd_slow(); + return (pgd_t *)ret; } -extern __inline__ pte_t pte_mkwrite(pte_t pte) +extern __inline__ void free_pgd_fast(pgd_t *pgd) { - pte_val(pte) |= _PTE_WRITE; - return pte; + *(unsigned long *)pgd = (unsigned long) pgd_quicklist; + pgd_quicklist = (unsigned long *) pgd; + pgtable_cache_size++; } -extern __inline__ pte_t pte_mkdirty(pte_t pte) +extern __inline__ void free_pgd_slow(pgd_t *pgd) { - pte_val(pte) |= _PTE_DIRTY; - return pte; + free_pages((unsigned long) pgd, 2); } -extern __inline__ pte_t pte_mkyoung(pte_t pte) +#define pgd_free(pgd) free_pgd_fast(pgd) +#define pgd_alloc() get_pgd_fast() + +extern __inline__ void set_pgdir(unsigned long address, pgd_t entry) { - pte_val(pte) |= _PTE_YOUNG; - return pte; + struct task_struct * p; + pgd_t *pgd; + + read_lock(&tasklist_lock); + for_each_task(p) { + if (!p->mm) + continue; + *pgd_offset(p->mm,address) = entry; + } + read_unlock(&tasklist_lock); + for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) + pgd[address >> PGDIR_SHIFT] = entry; } -/* - * The following are unable to be implemented on this MMU - */ -#if 0 -extern __inline__ pte_t pte_rdprotect(pte_t pte) +extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; + +/**************** +* PMD functions * +****************/ + +/* PMD types (actually level 1 descriptor) */ +#define PMD_TYPE_MASK 0x0003 +#define PMD_TYPE_FAULT 0x0000 +#define PMD_TYPE_TABLE 0x0001 +#define PMD_TYPE_SECT 0x0002 +#define PMD_UPDATABLE 0x0010 +#define PMD_SECT_CACHEABLE 0x0008 +#define PMD_SECT_BUFFERABLE 0x0004 +#define PMD_SECT_AP_WRITE 0x0400 +#define PMD_SECT_AP_READ 0x0800 +#define PMD_DOMAIN(x) ((x) << 5) + +#define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_USER)) +#define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_KERNEL)) + +#define pmd_none(pmd) (!pmd_val(pmd)) +#define pmd_clear(pmdp) set_pmd(pmdp, __pmd(0)) +#define pmd_bad(pmd) (pmd_val(pmd) & 2) +#define mk_user_pmd(ptep) __mk_pmd(ptep, _PAGE_USER_TABLE) +#define mk_kernel_pmd(ptep) __mk_pmd(ptep, _PAGE_KERNEL_TABLE) +#define set_pmd(pmdp,pmd) processor.u.armv3v4._set_pmd(pmdp,pmd) + +/* Find an entry in the second-level page table.. */ +#define pmd_offset(dir, address) ((pmd_t *)(dir)) + +extern __inline__ int pmd_present(pmd_t pmd) { - pte_val(pte) &= ~(PTE_CACHEABLE|PTE_AP_READ); - return pte; + return ((pmd_val(pmd) + 1) & 2); } -extern __inline__ pte_t pte_exprotect(pte_t pte) +/* We don't use pmd cache, so this is a dummy routine */ +extern __inline__ pmd_t *get_pmd_fast(void) { - pte_val(pte) &= ~(PTE_CACHEABLE|PTE_AP_READ); - return pte; + return (pmd_t *)0; } -extern __inline__ pte_t pte_mkread(pte_t pte) +extern __inline__ void free_pmd_fast(pmd_t *pmd) { - pte_val(pte) |= PTE_CACHEABLE; - return pte; } -extern __inline__ pte_t pte_mkexec(pte_t pte) +extern __inline__ void free_pmd_slow(pmd_t *pmd) { - pte_val(pte) |= PTE_CACHEABLE; - return pte; } -#endif + +extern void __bad_pmd(pmd_t *pmd); +extern void __bad_pmd_kernel(pmd_t *pmd); /* - * Conversion functions: convert a page and protection to a page entry, - * and a page entry and page directory to the page they refer to. + * allocating and freeing a pmd is trivial: the 1-entry pmd is + * inside the pgd, so has no extra memory associated with it. */ -extern __inline__ pte_t mk_pte(unsigned long page, pgprot_t pgprot) +extern __inline__ void pmd_free(pmd_t *pmd) { - pte_t pte; - pte_val(pte) = __virt_to_phys(page) | pgprot_val(pgprot); - return pte; } -/* This takes a physical page address that is used by the remapping functions */ -extern __inline__ pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) +extern __inline__ pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address) { - pte_t pte; - pte_val(pte) = physpage + pgprot_val(pgprot); - return pte; + return (pmd_t *) pgd; } -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; -} +#define pmd_free_kernel pmd_free +#define pmd_alloc_kernel pmd_alloc -extern __inline__ void set_pte(pte_t *pteptr, pte_t pteval) +extern __inline__ pmd_t __mk_pmd(pte_t *ptep, unsigned long prot) { - *pteptr = pteval; - __flush_pte_to_ram(pteptr); -} + unsigned long pte_ptr = (unsigned long)ptep; + pmd_t pmd; -extern __inline__ unsigned long pte_page(pte_t pte) -{ - return __phys_to_virt(pte_val(pte) & PAGE_MASK); -} + pte_ptr -= PTRS_PER_PTE * BYTES_PER_PTR; -extern __inline__ pmd_t mk_user_pmd(pte_t *ptep) -{ - pmd_t pmd; - pmd_val(pmd) = __virt_to_phys((unsigned long)ptep) | _PAGE_USER_TABLE; - return pmd; -} + /* + * The pmd must be loaded with the physical + * address of the PTE table + */ + pmd_val(pmd) = __virt_to_phys(pte_ptr) | prot; -extern __inline__ pmd_t mk_kernel_pmd(pte_t *ptep) -{ - pmd_t pmd; - pmd_val(pmd) = __virt_to_phys((unsigned long)ptep) | _PAGE_KERNEL_TABLE; return pmd; } -#if 1 -#define set_pmd(pmdp,pmd) processor.u.armv3v4._set_pmd(pmdp,pmd) -#else -extern __inline__ void set_pmd(pmd_t *pmdp, pmd_t pmd) -{ - *pmdp = pmd; - __flush_pte_to_ram(pmdp); -} -#endif - extern __inline__ unsigned long pmd_page(pmd_t pmd) { - return __phys_to_virt(pmd_val(pmd) & 0xfffffc00); -} + unsigned long ptr; -/* to find an entry in a kernel page-table-directory */ -#define pgd_offset_k(address) pgd_offset(&init_mm, address) + ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * BYTES_PER_PTR - 1); -/* to find an entry in a page-table-directory */ -extern __inline__ pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address) -{ - return mm->pgd + (address >> PGDIR_SHIFT); + ptr += PTRS_PER_PTE * BYTES_PER_PTR; + + return __phys_to_virt(ptr); } -/* Find an entry in the second-level page table.. */ -#define pmd_offset(dir, address) ((pmd_t *)(dir)) -/* Find an entry in the third-level page table.. */ -extern __inline__ pte_t * pte_offset(pmd_t * dir, unsigned long address) -{ - return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); -} +/**************** +* PTE functions * +****************/ -extern unsigned long get_small_page(int priority); -extern void free_small_page(unsigned long page); +/* PTE types (actially level 2 descriptor) */ +#define PTE_TYPE_MASK 0x0003 +#define PTE_TYPE_FAULT 0x0000 +#define PTE_TYPE_LARGE 0x0001 +#define PTE_TYPE_SMALL 0x0002 +#define PTE_AP_READ 0x0aa0 +#define PTE_AP_WRITE 0x0550 +#define PTE_CACHEABLE 0x0008 +#define PTE_BUFFERABLE 0x0004 + +#define pte_none(pte) (!pte_val(pte)) +#define pte_clear(ptep) set_pte(ptep, __pte(0)) /* - * Allocate and free page tables. The xxx_kernel() versions are - * used to allocate a kernel page table - this turns on ASN bits - * if any. + * Conversion functions: convert a page and protection to a page entry, + * and a page entry and page directory to the page they refer to. */ - -#ifndef __SMP__ -extern struct pgtable_cache_struct { - unsigned long *pgd_cache; - unsigned long *pte_cache; - unsigned long pgtable_cache_sz; -} quicklists; - -#define pgd_quicklist (quicklists.pgd_cache) -#define pmd_quicklist ((unsigned long *)0) -#define pte_quicklist (quicklists.pte_cache) -#define pgtable_cache_size (quicklists.pgtable_cache_sz) -#else -#error Pgtable caches have to be per-CPU, so that no locking is needed. -#endif - -extern pgd_t *get_pgd_slow(void); - -extern __inline__ pgd_t *get_pgd_fast(void) +extern __inline__ pte_t mk_pte(unsigned long page, pgprot_t pgprot) { - unsigned long *ret; - - if((ret = pgd_quicklist) != NULL) { - pgd_quicklist = (unsigned long *)(*ret); - ret[0] = ret[1]; - pgtable_cache_size--; - } else - ret = (unsigned long *)get_pgd_slow(); - return (pgd_t *)ret; + pte_t pte; + pte_val(pte) = __virt_to_phys(page) | pgprot_val(pgprot); + return pte; } -extern __inline__ void free_pgd_fast(pgd_t *pgd) +/* This takes a physical page address that is used by the remapping functions */ +extern __inline__ pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) { - *(unsigned long *)pgd = (unsigned long) pgd_quicklist; - pgd_quicklist = (unsigned long *) pgd; - pgtable_cache_size++; + pte_t pte; + pte_val(pte) = physpage + pgprot_val(pgprot); + return pte; } -extern __inline__ void free_pgd_slow(pgd_t *pgd) +#define set_pte(ptep, pte) processor.u.armv3v4._set_pte(ptep,pte) + +extern __inline__ unsigned long pte_page(pte_t pte) { - free_pages((unsigned long) pgd, 2); + return __phys_to_virt(pte_val(pte) & PAGE_MASK); } extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted); @@ -579,6 +460,7 @@ extern __inline__ pte_t *get_pte_fast(void) if((ret = (unsigned long *)pte_quicklist) != NULL) { pte_quicklist = (unsigned long *)(*ret); ret[0] = ret[1]; + clean_cache_area(ret, 4); pgtable_cache_size--; } return (pte_t *)ret; @@ -593,31 +475,124 @@ extern __inline__ void free_pte_fast(pte_t *pte) extern __inline__ void free_pte_slow(pte_t *pte) { - free_small_page((unsigned long)pte); + free_page_2k((unsigned long)(pte - PTRS_PER_PTE)); } -/* We don't use pmd cache, so this is a dummy routine */ -extern __inline__ pmd_t *get_pmd_fast(void) -{ - return (pmd_t *)0; -} +#define pte_free_kernel(pte) free_pte_fast(pte) +#define pte_free(pte) free_pte_fast(pte) -extern __inline__ void free_pmd_fast(pmd_t *pmd) +/*############################################################################### + * New PageTableEntry stuff... + */ +/* We now keep two sets of ptes - the physical and the linux version. + * This gives us many advantages, and allows us greater flexibility. + * + * The Linux pte's contain: + * bit meaning + * 0 page present + * 1 young + * 2 bufferable - matches physical pte + * 3 cacheable - matches physical pte + * 4 user + * 5 write + * 6 execute + * 7 dirty + * 8-11 unused + * 12-31 virtual page address + * + * These are stored at the pte pointer; the physical PTE is at -1024bytes + */ +#define L_PTE_PRESENT (1 << 0) +#define L_PTE_YOUNG (1 << 1) +#define L_PTE_BUFFERABLE (1 << 2) +#define L_PTE_CACHEABLE (1 << 3) +#define L_PTE_USER (1 << 4) +#define L_PTE_WRITE (1 << 5) +#define L_PTE_EXEC (1 << 6) +#define L_PTE_DIRTY (1 << 7) + +/* + * The following macros handle the cache and bufferable bits... + */ +#define _L_PTE_DEFAULT L_PTE_PRESENT | L_PTE_YOUNG +#define _L_PTE_READ L_PTE_USER | L_PTE_CACHEABLE +#define _L_PTE_EXEC _L_PTE_READ | L_PTE_EXEC + +#define PAGE_NONE __pgprot(_L_PTE_DEFAULT) +#define PAGE_COPY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_BUFFERABLE) +#define PAGE_SHARED __pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_BUFFERABLE | L_PTE_WRITE) +#define PAGE_READONLY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ) +#define PAGE_KERNEL __pgprot(_L_PTE_DEFAULT | L_PTE_CACHEABLE | L_PTE_BUFFERABLE | L_PTE_DIRTY | L_PTE_WRITE) + +#define _PAGE_CHG_MASK (PAGE_MASK | L_PTE_DIRTY | L_PTE_YOUNG) + +/* + * The table below defines the page protection levels that we insert into our + * Linux page table version. These get translated into the best that the + * architecture can perform. Note that on most ARM hardware: + * 1) We cannot do execute protection + * 2) If we could do execute protection, then read is implied + * 3) write implies read permissions + */ +#define __P000 PAGE_NONE +#define __P001 PAGE_READONLY +#define __P010 PAGE_COPY +#define __P011 PAGE_COPY +#define __P100 PAGE_READONLY +#define __P101 PAGE_READONLY +#define __P110 PAGE_COPY +#define __P111 PAGE_COPY + +#define __S000 PAGE_NONE +#define __S001 PAGE_READONLY +#define __S010 PAGE_SHARED +#define __S011 PAGE_SHARED +#define __S100 PAGE_READONLY +#define __S101 PAGE_READONLY +#define __S110 PAGE_SHARED +#define __S111 PAGE_SHARED + + + +#define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT) + +/* + * The following only work if pte_present() is true. + * Undefined behaviour if not.. + */ +#define pte_read(pte) (pte_val(pte) & L_PTE_USER) +#define pte_write(pte) (pte_val(pte) & L_PTE_WRITE) +#define pte_exec(pte) (pte_val(pte) & L_PTE_EXEC) +#define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) +#define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) + +#define PTE_BIT_FUNC(fn,op) \ +extern inline pte_t fn##(pte_t pte) { pte_val(pte) op##; return pte; } + +//PTE_BIT_FUNC(pte_rdprotect, &= ~L_PTE_USER); +PTE_BIT_FUNC(pte_wrprotect, &= ~L_PTE_WRITE); +PTE_BIT_FUNC(pte_exprotect, &= ~L_PTE_EXEC); +PTE_BIT_FUNC(pte_mkclean, &= ~L_PTE_DIRTY); +PTE_BIT_FUNC(pte_mkold, &= ~L_PTE_YOUNG); +//PTE_BIT_FUNC(pte_mkread, |= L_PTE_USER); +PTE_BIT_FUNC(pte_mkwrite, |= L_PTE_WRITE); +PTE_BIT_FUNC(pte_mkexec, |= L_PTE_EXEC); +PTE_BIT_FUNC(pte_mkdirty, |= L_PTE_DIRTY); +PTE_BIT_FUNC(pte_mkyoung, |= L_PTE_YOUNG); +PTE_BIT_FUNC(pte_nocache, &= ~L_PTE_CACHEABLE); + +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 free_pmd_slow(pmd_t *pmd) +/* Find an entry in the third-level page table.. */ +extern __inline__ pte_t * pte_offset(pmd_t * dir, unsigned long address) { + return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); } -extern void __bad_pmd(pmd_t *pmd); -extern void __bad_pmd_kernel(pmd_t *pmd); - -#define pte_free_kernel(pte) free_pte_fast(pte) -#define pte_free(pte) free_pte_fast(pte) -#define pgd_free(pgd) free_pgd_fast(pgd) -#define pgd_alloc() get_pgd_fast() - extern __inline__ pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address) { address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); @@ -655,49 +630,6 @@ extern __inline__ pte_t * pte_alloc(pmd_t * pmd, unsigned long address) return (pte_t *) pmd_page(*pmd) + address; } -/* - * allocating and freeing a pmd is trivial: the 1-entry pmd is - * inside the pgd, so has no extra memory associated with it. - */ -extern __inline__ void pmd_free(pmd_t *pmd) -{ -} - -extern __inline__ pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address) -{ - return (pmd_t *) pgd; -} - -#define pmd_free_kernel pmd_free -#define pmd_alloc_kernel pmd_alloc - -extern __inline__ void set_pgdir(unsigned long address, pgd_t entry) -{ - struct task_struct * p; - pgd_t *pgd; - - read_lock(&tasklist_lock); - for_each_task(p) { - if (!p->mm) - continue; - *pgd_offset(p->mm,address) = entry; - } - read_unlock(&tasklist_lock); - for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) - pgd[address >> PGDIR_SHIFT] = entry; -} - -extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; - -/* - * The sa110 doesn't have any external MMU info: the kernel page - * tables contain all the necessary information. - */ -extern __inline__ void update_mmu_cache(struct vm_area_struct * vma, - unsigned long address, pte_t pte) -{ -} - #define SWP_TYPE(entry) (((entry) >> 2) & 0x7f) #define SWP_OFFSET(entry) ((entry) >> 9) #define SWP_ENTRY(type,offset) (((type) << 2) | ((offset) << 9)) diff --git a/include/asm-arm/proc-armv/processor.h b/include/asm-arm/proc-armv/processor.h index 88b277ea7..7186039f9 100644 --- a/include/asm-arm/proc-armv/processor.h +++ b/include/asm-arm/proc-armv/processor.h @@ -12,8 +12,6 @@ #ifndef __ASM_PROC_PROCESSOR_H #define __ASM_PROC_PROCESSOR_H -#ifdef __KERNEL__ - #define KERNEL_STACK_SIZE PAGE_SIZE struct context_save_struct { @@ -28,56 +26,18 @@ struct context_save_struct { unsigned long pc; }; -#define EXTRA_THREAD_STRUCT \ - struct context_save_struct *save; \ - unsigned long memmap; +#define INIT_CSS (struct context_save_struct){ SVC_MODE, 0, 0, 0, 0, 0, 0, 0, 0 } -#define EXTRA_THREAD_STRUCT_INIT \ - 0, \ - ((unsigned long) swapper_pg_dir) - PAGE_OFFSET - -DECLARE_THREAD_STRUCT; - -/* - * Return saved PC of a blocked thread. - */ -extern __inline__ unsigned long thread_saved_pc (struct thread_struct *t) -{ - if (t->save) - return t->save->pc; - else - return 0; -} - -extern __inline__ unsigned long get_css_fp (struct thread_struct *t) -{ - if (t->save) - return t->save->fp; - else - return 0; -} - -asmlinkage void ret_from_sys_call(void) __asm__ ("ret_from_sys_call"); - -extern __inline__ void copy_thread_css (struct context_save_struct *save) -{ - save->cpsr = SVC_MODE; - save->r4 = - save->r5 = - save->r6 = - save->r7 = - save->r8 = - save->r9 = - save->fp = 0; - save->pc = (unsigned long) ret_from_sys_call; -} +#define EXTRA_THREAD_STRUCT +#define EXTRA_THREAD_STRUCT_INIT +#define SWAPPER_PG_DIR (((unsigned long)swapper_pg_dir) - PAGE_OFFSET) #define start_thread(regs,pc,sp) \ ({ \ unsigned long *stack = (unsigned long *)sp; \ set_fs(USER_DS); \ memzero(regs->uregs, sizeof(regs->uregs)); \ - if (current->personality == PER_LINUX_32BIT) \ + if (current->personality & ADDR_LIMIT_32BIT) \ regs->ARM_cpsr = USR_MODE; \ else \ regs->ARM_cpsr = USR26_MODE; \ @@ -92,10 +52,7 @@ extern __inline__ void copy_thread_css (struct context_save_struct *save) /* * NOTE! The task struct and the stack go together */ -#define alloc_task_struct() \ - ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) -#define free_task_struct(p) free_pages((unsigned long)(p),1) - -#endif +#define ll_alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) +#define ll_free_task_struct(p) free_pages((unsigned long)(p),1) #endif diff --git a/include/asm-arm/proc-armv/ptrace.h b/include/asm-arm/proc-armv/ptrace.h index 213c17ce7..b24305bd4 100644 --- a/include/asm-arm/proc-armv/ptrace.h +++ b/include/asm-arm/proc-armv/ptrace.h @@ -52,9 +52,14 @@ struct pt_regs { #define CC_Z_BIT (1 << 30) #define CC_N_BIT (1 << 31) +#if 0 /* GCC/egcs should be able to optimise this, IMHO */ #define user_mode(regs) \ ((((regs)->ARM_cpsr & MODE_MASK) == USR_MODE) || \ (((regs)->ARM_cpsr & MODE_MASK) == USR26_MODE)) +#else +#define user_mode(regs) \ + (((regs)->ARM_cpsr & 0xf) == 0) +#endif #define processor_mode(regs) \ ((regs)->ARM_cpsr & MODE_MASK) @@ -74,8 +79,19 @@ struct pt_regs { /* Are the current registers suitable for user mode? * (used to maintain security in signal handlers) */ -#define valid_user_regs(regs) \ - (user_mode(regs) && ((regs)->ARM_sp & 3) == 0) +static inline int valid_user_regs(struct pt_regs *regs) +{ + if ((regs->ARM_cpsr & 0xf) == 0 || + (regs->ARM_cpsr & (F_BIT|I_BIT))) + return 1; + + /* + * Force CPSR to something logical... + */ + regs->ARM_cpsr &= (CC_V_BIT|CC_C_BIT|CC_Z_BIT|CC_N_BIT|0x10); + + return 0; +} #endif diff --git a/include/asm-arm/proc-armv/semaphore.h b/include/asm-arm/proc-armv/semaphore.h index 3da31f536..52098bc5c 100644 --- a/include/asm-arm/proc-armv/semaphore.h +++ b/include/asm-arm/proc-armv/semaphore.h @@ -60,6 +60,32 @@ extern inline int down_interruptible (struct semaphore * sem) return temp; } +extern inline int down_trylock(struct semaphore *sem) +{ + unsigned int cpsr, temp; + + __asm__ __volatile__ (" + @ atomic down try lock operation + mrs %0, cpsr + orr %1, %0, #128 @ disable IRQs + bic %0, %0, #0x80000000 @ clear N + msr cpsr, %1 + ldr %1, [%2] + subs %1, %1, #1 + orrmi %0, %0, #0x80000000 @ set N + str %1, [%2] + msr cpsr, %0 + movmi r0, %2 + movpl r0, #0 + blmi " SYMBOL_NAME_STR(__down_trylock_failed) " + mov %1, r0" + : "=&r" (cpsr), "=&r" (temp) + : "r" (sem) + : "r0", "lr", "cc"); + + return temp; +} + /* * Note! This is subtle. We jump to wake people up only if * the semaphore was negative (== somebody was waiting on it). diff --git a/include/asm-arm/proc-armv/uaccess.h b/include/asm-arm/proc-armv/uaccess.h index a8dce6739..a015a0738 100644 --- a/include/asm-arm/proc-armv/uaccess.h +++ b/include/asm-arm/proc-armv/uaccess.h @@ -133,6 +133,7 @@ extern __inline__ void set_fs (mm_segment_t fs) " .section .fixup,\"ax\"\n" \ " .align 2\n" \ "3: mvn %0, %3\n" \ + " mov %1, #0\n" \ " b 2b\n" \ " .previous\n" \ " .section __ex_table,\"a\"\n" \ @@ -153,6 +154,7 @@ extern __inline__ void set_fs (mm_segment_t fs) " .section .fixup,\"ax\"\n" \ " .align 2\n" \ "4: mvn %0, %5\n" \ + " mov %1, #0\n" \ " b 3b\n" \ " .previous\n" \ " .section __ex_table,\"a\"\n" \ @@ -173,6 +175,7 @@ extern __inline__ void set_fs (mm_segment_t fs) " .section .fixup,\"ax\"\n" \ " .align 2\n" \ "3: mvn %0, %3\n" \ + " mov %1, #0\n" \ " b 2b\n" \ " .previous\n" \ " .section __ex_table,\"a\"\n" \ diff --git a/include/asm-arm/proc-fns.h b/include/asm-arm/proc-fns.h index e3b35c9f2..81873a58c 100644 --- a/include/asm-arm/proc-fns.h +++ b/include/asm-arm/proc-fns.h @@ -9,6 +9,10 @@ #include <asm/page.h> #ifdef __KERNEL__ + +/* forward-decare task_struct */ +struct task_struct; + /* * Don't change this structure */ @@ -18,7 +22,7 @@ extern struct processor { * * flush caches for task switch */ - void (*_switch_to)(void *prev, void *next); + struct task_struct *(*_switch_to)(struct task_struct *prev, struct task_struct *next); /* * get data abort address/flags */ @@ -54,10 +58,10 @@ extern struct processor { */ void (*_flush_cache_entry)(unsigned long address); /* - * flush a virtual address used for a page table - * note D-cache only! + * clean a virtual address range from the + * D-cache without flushing the cache. */ - void (*_flush_cache_pte)(unsigned long address); + void (*_clean_cache_area)(unsigned long start, unsigned long size); /* * flush a page to RAM */ @@ -76,13 +80,17 @@ extern struct processor { */ void (*_set_pmd)(pmd_t *pmdp, pmd_t pmd); /* + * Set a PTE + */ + void (*_set_pte)(pte_t *ptep, pte_t pte); + /* * Special stuff for a reset */ unsigned long (*reset)(void); /* * flush an icached page */ - void (*_flush_icache_area)(unsigned long start, unsigned long end); + void (*_flush_icache_area)(unsigned long start, unsigned long size); /* * write back dirty cached data */ diff --git a/include/asm-arm/processor.h b/include/asm-arm/processor.h index f4c687089..a59e441a1 100644 --- a/include/asm-arm/processor.h +++ b/include/asm-arm/processor.h @@ -7,12 +7,14 @@ #ifndef __ASM_ARM_PROCESSOR_H #define __ASM_ARM_PROCESSOR_H +#define FP_SIZE 35 + struct fp_hard_struct { - unsigned int save[140/4]; /* as yet undefined */ + unsigned int save[FP_SIZE]; /* as yet undefined */ }; struct fp_soft_struct { - unsigned int save[140/4]; /* undefined information */ + unsigned int save[FP_SIZE]; /* undefined information */ }; union fp_state { @@ -22,28 +24,59 @@ union fp_state { typedef unsigned long mm_segment_t; /* domain register */ -#define NR_DEBUGS 5 +#ifdef __KERNEL__ -#define DECLARE_THREAD_STRUCT \ -struct thread_struct { \ - unsigned long address; /* Address of fault */ \ - unsigned long trap_no; /* Trap number */ \ - unsigned long error_code; /* Error code of trap */ \ - union fp_state fpstate; /* FPE save state */ \ - unsigned long debug[NR_DEBUGS]; /* Debug/ptrace */ \ - EXTRA_THREAD_STRUCT \ -} +#include <asm/assembler.h> + +#define NR_DEBUGS 5 #include <asm/arch/processor.h> #include <asm/proc/processor.h> -#define INIT_TSS { \ - 0, \ - 0, \ - 0, \ - { { { 0, }, }, }, \ - { 0, }, \ - EXTRA_THREAD_STRUCT_INIT \ +struct thread_struct { + unsigned long address; /* Address of fault */ + unsigned long trap_no; /* Trap number */ + unsigned long error_code; /* Error code of trap */ + union fp_state fpstate; /* FPE save state */ + unsigned long debug[NR_DEBUGS]; /* Debug/ptrace */ + struct context_save_struct *save; /* context save */ + unsigned long memmap; /* page tables */ + EXTRA_THREAD_STRUCT +}; + +#define INIT_MMAP \ +{ &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL } + +#define INIT_TSS { \ + 0, \ + 0, \ + 0, \ + { { { 0, }, }, }, \ + { 0, }, \ + (struct context_save_struct *)0, \ + SWAPPER_PG_DIR \ + EXTRA_THREAD_STRUCT_INIT \ +} + +/* + * Return saved PC of a blocked thread. + */ +extern __inline__ unsigned long thread_saved_pc(struct thread_struct *t) +{ + return t->save ? t->save->pc & ~PCMASK : 0; +} + +extern __inline__ unsigned long get_css_fp(struct thread_struct *t) +{ + return t->save ? t->save->fp : 0; +} + +asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call"); + +extern __inline__ void init_thread_css(struct context_save_struct *save) +{ + *save = INIT_CSS; + save->pc |= (unsigned long)ret_from_sys_call; } /* Forward declaration, a strange C thing */ @@ -57,7 +90,12 @@ extern void release_thread(struct task_struct *); #define release_segments(mm) do { } while (0) #define forget_segments() do { } while (0) +extern struct task_struct *alloc_task_struct(void); +extern void free_task_struct(struct task_struct *); + #define init_task (init_task_union.task) #define init_stack (init_task_union.stack) +#endif + #endif /* __ASM_ARM_PROCESSOR_H */ diff --git a/include/asm-arm/semaphore-helper.h b/include/asm-arm/semaphore-helper.h new file mode 100644 index 000000000..1d7f1987e --- /dev/null +++ b/include/asm-arm/semaphore-helper.h @@ -0,0 +1,84 @@ +#ifndef ASMARM_SEMAPHORE_HELPER_H +#define ASMARM_SEMAPHORE_HELPER_H + +/* + * These two _must_ execute atomically wrt each other. + */ +static inline void wake_one_more(struct semaphore * sem) +{ + unsigned long flags; + + spin_lock_irqsave(&semaphore_wake_lock, flags); + if (atomic_read(&sem->count) <= 0) + sem->waking++; + spin_unlock_irqrestore(&semaphore_wake_lock, flags); +} + +static inline int waking_non_zero(struct semaphore *sem) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&semaphore_wake_lock, flags); + if (sem->waking > 0) { + sem->waking--; + ret = 1; + } + spin_unlock_irqrestore(&semaphore_wake_lock, flags); + return ret; +} + +/* + * waking non zero interruptible + * 1 got the lock + * 0 go to sleep + * -EINTR interrupted + * + * We must undo the sem->count down_interruptible() increment while we are + * protected by the spinlock in order to make this atomic_inc() with the + * atomic_read() in wake_one_more(), otherwise we can race. -arca + */ +static inline int waking_non_zero_interruptible(struct semaphore *sem, + struct task_struct *tsk) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&semaphore_wake_lock, flags); + if (sem->waking > 0) { + sem->waking--; + ret = 1; + } else if (signal_pending(tsk)) { + atomic_inc(&sem->count); + ret = -EINTR; + } + spin_unlock_irqrestore(&semaphore_wake_lock, flags); + return ret; +} + +/* + * waking_non_zero_try_lock: + * 1 failed to lock + * 0 got the lock + * + * We must undo the sem->count down_interruptible() increment while we are + * protected by the spinlock in order to make this atomic_inc() with the + * atomic_read() in wake_one_more(), otherwise we can race. -arca + */ +static inline int waking_non_zero_trylock(struct semaphore *sem) +{ + unsigned long flags; + int ret = 1; + + spin_lock_irqsave(&semaphore_wake_lock, flags); + if (sem->waking <= 0) + atomic_inc(&sem->count); + else { + sem->waking--; + ret = 0; + } + spin_unlock_irqrestore(&semaphore_wake_lock, flags); + return ret; +} + +#endif diff --git a/include/asm-arm/semaphore.h b/include/asm-arm/semaphore.h index 287d8c263..a51b6f96e 100644 --- a/include/asm-arm/semaphore.h +++ b/include/asm-arm/semaphore.h @@ -19,50 +19,16 @@ struct semaphore { asmlinkage void __down_failed (void /* special register calling convention */); asmlinkage int __down_interruptible_failed (void /* special register calling convention */); +asmlinkage int __down_failed_trylock(void /* params in registers */); asmlinkage void __up_wakeup (void /* special register calling convention */); extern void __down(struct semaphore * sem); extern int __down_interruptible(struct semaphore * sem); +extern int __down_trylock(struct semaphore * sem); extern void __up(struct semaphore * sem); #define sema_init(sem, val) atomic_set(&((sem)->count), (val)) -/* - * These two _must_ execute atomically wrt each other. - * - * This is trivially done with load_locked/store_cond, - * but on the x86 we need an external synchronizer. - * Currently this is just the global interrupt lock, - * bah. Go for a smaller spinlock some day. - * - * (On the other hand this shouldn't be in any critical - * path, so..) - */ -static inline void wake_one_more(struct semaphore * sem) -{ - unsigned long flags; - - save_flags(flags); - cli(); - sem->waking++; - restore_flags(flags); -} - -static inline int waking_non_zero(struct semaphore *sem, struct task_struct *tsk) -{ - unsigned long flags; - int ret = 0; - - save_flags(flags); - cli(); - if (sem->waking > 0) { - sem->waking--; - ret = 1; - } - restore_flags(flags); - return ret; -} - #include <asm/proc/semaphore.h> #endif diff --git a/include/asm-arm/siginfo.h b/include/asm-arm/siginfo.h index 2dec6e080..c08847d32 100644 --- a/include/asm-arm/siginfo.h +++ b/include/asm-arm/siginfo.h @@ -138,7 +138,7 @@ typedef struct siginfo { */ #define TRAP_BRKPT 1 /* process breakpoint */ #define TRAP_TRACE 2 /* process trace trap */ -#define NSIGTRAP +#define NSIGTRAP 2 /* * SIGCHLD si_codes diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index 91c08d668..2874c4661 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h @@ -1,10 +1,26 @@ #ifndef __ASM_ARM_SYSTEM_H #define __ASM_ARM_SYSTEM_H +#include <linux/kernel.h> + +#ifdef __KERNEL__ + #include <linux/config.h> +#define __ebsa285_data __attribute__((__section__(".data.ebsa285"))) +#define __netwinder_data __attribute__((__section__(".data.netwinder"))) + +#ifdef CONFIG_TEXT_SECTIONS +#define __ebsa285_text __attribute__((__section__(".text.ebsa285"))) +#define __netwinder_text __attribute__((__section__(".text.netwinder"))) +#else +#define __ebsa285_text +#define __netwinder_text +#endif + /* The type of machine we're running on */ -extern unsigned int machine_type; +extern unsigned int __machine_arch_type; + #define MACH_TYPE_EBSA110 0 #define MACH_TYPE_RISCPC 1 #define MACH_TYPE_NEXUSPCI 3 @@ -12,31 +28,101 @@ extern unsigned int machine_type; #define MACH_TYPE_NETWINDER 5 #define MACH_TYPE_CATS 6 #define MACH_TYPE_TBOX 7 +#define MACH_TYPE_CO285 8 +#define MACH_TYPE_CLPS7110 9 +#define MACH_TYPE_ARCHIMEDES 10 +#define MACH_TYPE_A5K 11 + +/* + * Sort out a definition for machine_arch_type + * The rules basically are: + * 1. If one architecture is selected, then all machine_is_xxx() + * are constant. + * 2. If two or more architectures are selected, then the selected + * machine_is_xxx() are variable, and the unselected machine_is_xxx() + * are constant zero. + */ +#ifdef CONFIG_ARCH_EBSA110 +# ifdef machine_arch_type +# undef machine_arch_type +# define machine_arch_type __machine_arch_type +# else +# define machine_arch_type MACH_TYPE_EBSA110 +# endif +# define machine_is_ebsa110() (machine_arch_type == MACH_TYPE_EBSA110) +#else +# define machine_is_ebsa110() (0) +#endif + +#ifdef CONFIG_ARCH_RPC +# ifdef machine_arch_type +# undef machine_arch_type +# define machine_arch_type __machine_arch_type +# else +# define machine_arch_type MACH_TYPE_RISCPC +# endif +# define machine_is_riscpc() (machine_arch_type == MACH_TYPE_RISCPC) +#else +# define machine_is_riscpc() (0) +#endif #ifdef CONFIG_ARCH_EBSA285 -#define machine_is_ebsa285() (1) +# ifdef machine_arch_type +# undef machine_arch_type +# define machine_arch_type __machine_arch_type +# else +# define machine_arch_type MACH_TYPE_EBSA285 +# endif +# define machine_is_ebsa285() (machine_arch_type == MACH_TYPE_EBSA285) #else -#define machine_is_ebsa285() (0) +# define machine_is_ebsa285() (0) #endif -#ifdef CONFIG_ARCH_VNC -#define machine_is_netwinder() (1) +#ifdef CONFIG_ARCH_NETWINDER +# ifdef machine_arch_type +# undef machine_arch_type +# define machine_arch_type __machine_arch_type +# else +# define machine_arch_type MACH_TYPE_NETWINDER +# endif +# define machine_is_netwinder() (machine_arch_type == MACH_TYPE_NETWINDER) #else -#define machine_is_netwinder() (0) +# define machine_is_netwinder() (0) #endif -#if defined(CONFIG_CATS) -#define machine_is_cats() (machine_type == MACH_TYPE_CATS) +#ifdef CONFIG_CATS +# ifdef machine_arch_type +# undef machine_arch_type +# define machine_arch_type __machine_arch_type +# else +# define machine_arch_type MACH_TYPE_CATS +# endif +# define machine_is_cats() (machine_arch_type == MACH_TYPE_CATS) #else -#define machine_is_cats() (0) +# define machine_is_cats() (0) #endif -#if 0 -#define machine_is_ebsa285() (machine_type == MACH_TYPE_EBSA285) -#define machine_is_netwinder() (machine_type == MACH_TYPE_NETWINDER) +#ifdef CONFIG_ARCH_CO285 +# ifdef machine_arch_type +# undef machine_arch_type +# define machine_arch_type __machine_arch_type +# else +# define machine_arch_type MACH_TYPE_CO285 +# endif +# define machine_is_co285() (machine_arch_type == MACH_TYPE_CO285) +#else +# define machine_is_co285() (0) #endif -#include <linux/kernel.h> +#ifndef machine_arch_type +#define machine_arch_type __machine_arch_type +#endif + +/* + * task_struct isn't always declared - forward-declare it here. + */ +struct task_struct; + #include <asm/proc-fns.h> extern void arm_malalignedptr(const char *, void *, volatile void *); @@ -53,7 +139,7 @@ extern void arm_invalidptr(const char *, int); * * `next' and `prev' should be struct task_struct, but it isn't always defined */ -#define switch_to(prev,next) processor._switch_to(prev,next) +#define switch_to(prev,next,last) do { last = processor._switch_to(prev,next); } while (0) /* * Include processor dependent parts @@ -62,9 +148,12 @@ extern void arm_invalidptr(const char *, int); #include <asm/arch/system.h> #define mb() __asm__ __volatile__ ("" : : : "memory") -#define nop() __asm__ __volatile__("mov r0,r0\n\t"); +#define rmb() mb() +#define wmb() mb() +#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t"); extern asmlinkage void __backtrace(void); #endif +#endif diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h index 601af3b0a..86c0c2883 100644 --- a/include/asm-arm/unistd.h +++ b/include/asm-arm/unistd.h @@ -195,6 +195,9 @@ #define __NR_capset (__NR_SYSCALL_BASE+185) #define __NR_sigaltstack (__NR_SYSCALL_BASE+186) #define __NR_sendfile (__NR_SYSCALL_BASE+187) + /* 188 reserved */ + /* 189 reserved */ +#define __NR_vfork (__NR_SYSCALL_BASE+190) #define __sys2(x) #x #define __sys1(x) __sys2(x) @@ -364,7 +367,7 @@ static inline int close(int fd) static inline int _exit(int exitcode) { - extern int sys_exit(int); + extern int sys_exit(int) __attribute__((noreturn)); return sys_exit(exitcode); } @@ -393,37 +396,11 @@ static inline pid_t wait(int * wait_stat) static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp); /* - * This is the mechanism for creating a new kernel thread. - * - * NOTE! Only a kernel-only process(ie the swapper or direct descendants - * who haven't done an "execve()") should use this: it will work within - * a system call from a "real" process, but the process memory space will - * not be free'd until both the parent and the child have exited. + * Create a new kernel thread */ -static inline pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) -{ - long retval; - - __asm__ __volatile__(" - mov r0,%1 - mov r1,%2 - "__syscall(clone)" - teq r0, #0 - bne 1f - mov r0,%4 - mov lr, pc - mov pc, %3 - "__syscall(exit)" -1: mov %0,r0" - : "=r" (retval) - : "Ir" (flags | CLONE_VM), "Ir" (NULL), "r" (fn), "Ir" (arg) - : "r0","r1","r2","r3","lr"); - - return retval; -} +extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); #endif - #endif /* __ASM_ARM_UNISTD_H */ diff --git a/include/asm-arm/vga.h b/include/asm-arm/vga.h index 6a9278df9..19c454396 100644 --- a/include/asm-arm/vga.h +++ b/include/asm-arm/vga.h @@ -1,9 +1,10 @@ #ifndef ASMARM_VGA_H #define ASMARM_VGA_H +#include <asm/hardware.h> #include <asm/io.h> -#define VGA_MAP_MEM(x) (0xe0000000 + (x)) +#define VGA_MAP_MEM(x) (PCIMEM_BASE + (x)) #define vga_readb(x) (*(x)) #define vga_writeb(x,y) (*(y) = (x)) |