From 2262cfeef91458b01a1bfe3812ccbbfdf8b82807 Mon Sep 17 00:00:00 2001 From: wdenk Date: Mon, 18 Nov 2002 00:14:45 +0000 Subject: * Patch by Daniel Engström, 13 Nov 2002: Add support for i386 architecture and AMD SC520 board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Patch by Pierre Aubert, 12 Nov 2002: Add support for DOS filesystem and booting from DOS floppy disk --- include/asm-i386/bitops.h | 384 ++++++++++++++++++++++++++++++++++++++++ include/asm-i386/byteorder.h | 47 +++++ include/asm-i386/global_data.h | 60 +++++++ include/asm-i386/i8254.h | 56 ++++++ include/asm-i386/i8259.h | 88 +++++++++ include/asm-i386/ibmpc.h | 47 +++++ include/asm-i386/ic/ali512x.h | 54 ++++++ include/asm-i386/ic/sc520.h | 249 ++++++++++++++++++++++++++ include/asm-i386/io.h | 207 ++++++++++++++++++++++ include/asm-i386/pci.h | 31 ++++ include/asm-i386/posix_types.h | 80 +++++++++ include/asm-i386/ppcboot-i386.h | 53 ++++++ include/asm-i386/ptrace.h | 66 +++++++ include/asm-i386/realmode.h | 31 ++++ include/asm-i386/string.h | 30 ++++ include/asm-i386/types.h | 51 ++++++ include/asm-i386/u-boot.h | 58 ++++++ include/asm-i386/zimage.h | 75 ++++++++ 18 files changed, 1667 insertions(+) create mode 100644 include/asm-i386/bitops.h create mode 100644 include/asm-i386/byteorder.h create mode 100644 include/asm-i386/global_data.h create mode 100644 include/asm-i386/i8254.h create mode 100644 include/asm-i386/i8259.h create mode 100644 include/asm-i386/ibmpc.h create mode 100644 include/asm-i386/ic/ali512x.h create mode 100644 include/asm-i386/ic/sc520.h create mode 100644 include/asm-i386/io.h create mode 100644 include/asm-i386/pci.h create mode 100644 include/asm-i386/posix_types.h create mode 100644 include/asm-i386/ppcboot-i386.h create mode 100644 include/asm-i386/ptrace.h create mode 100644 include/asm-i386/realmode.h create mode 100644 include/asm-i386/string.h create mode 100644 include/asm-i386/types.h create mode 100644 include/asm-i386/u-boot.h create mode 100644 include/asm-i386/zimage.h (limited to 'include/asm-i386') diff --git a/include/asm-i386/bitops.h b/include/asm-i386/bitops.h new file mode 100644 index 000000000..a3063cacc --- /dev/null +++ b/include/asm-i386/bitops.h @@ -0,0 +1,384 @@ +#ifndef _I386_BITOPS_H +#define _I386_BITOPS_H + +/* + * Copyright 1992, Linus Torvalds. + */ + +#include + +/* + * These have to be done with inline assembly: that way the bit-setting + * is guaranteed to be atomic. All bit operations return 0 if the bit + * was cleared before the operation and != 0 if it was not. + * + * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). + */ + +#ifdef CONFIG_SMP +#define LOCK_PREFIX "lock ; " +#else +#define LOCK_PREFIX "" +#endif + +#define ADDR (*(volatile long *) addr) + +/** + * set_bit - Atomically set a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * This function is atomic and may not be reordered. See __set_bit() + * if you do not require the atomic guarantees. + * Note that @nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static __inline__ void set_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btsl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * __set_bit - Set a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * Unlike set_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +static __inline__ void __set_bit(int nr, volatile void * addr) +{ + __asm__( + "btsl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * clear_bit - Clears a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * clear_bit() is atomic and may not be reordered. However, it does + * not contain a memory barrier, so if it is used for locking purposes, + * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() + * in order to ensure changes are visible on other processors. + */ +static __inline__ void clear_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btrl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} +#define smp_mb__before_clear_bit() barrier() +#define smp_mb__after_clear_bit() barrier() + +/** + * __change_bit - Toggle a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * Unlike change_bit(), this function is non-atomic and may be reordered. + * If it's called on the same region of memory simultaneously, the effect + * may be that only one operation succeeds. + */ +static __inline__ void __change_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( + "btcl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * change_bit - Toggle a bit in memory + * @nr: Bit to clear + * @addr: Address to start counting from + * + * change_bit() is atomic and may not be reordered. + * Note that @nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + */ +static __inline__ void change_bit(int nr, volatile void * addr) +{ + __asm__ __volatile__( LOCK_PREFIX + "btcl %1,%0" + :"=m" (ADDR) + :"Ir" (nr)); +} + +/** + * test_and_set_bit - Set a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static __inline__ int test_and_set_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btsl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +/** + * __test_and_set_bit - Set a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is non-atomic and can be reordered. + * If two examples of this operation race, one can appear to succeed + * but actually fail. You must protect multiple accesses with a lock. + */ +static __inline__ int __test_and_set_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__( + "btsl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr)); + return oldbit; +} + +/** + * test_and_clear_bit - Clear a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static __inline__ int test_and_clear_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btrl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +/** + * __test_and_clear_bit - Clear a bit and return its old value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is non-atomic and can be reordered. + * If two examples of this operation race, one can appear to succeed + * but actually fail. You must protect multiple accesses with a lock. + */ +static __inline__ int __test_and_clear_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__( + "btrl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr)); + return oldbit; +} + +/* WARNING: non atomic and it can be reordered! */ +static __inline__ int __test_and_change_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( + "btcl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +/** + * test_and_change_bit - Change a bit and return its new value + * @nr: Bit to set + * @addr: Address to count from + * + * This operation is atomic and cannot be reordered. + * It also implies a memory barrier. + */ +static __inline__ int test_and_change_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( LOCK_PREFIX + "btcl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit),"=m" (ADDR) + :"Ir" (nr) : "memory"); + return oldbit; +} + +#if 0 /* Fool kernel-doc since it doesn't do macros yet */ +/** + * test_bit - Determine whether a bit is set + * @nr: bit number to test + * @addr: Address to start counting from + */ +static int test_bit(int nr, const volatile void * addr); +#endif + +static __inline__ int constant_test_bit(int nr, const volatile void * addr) +{ + return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; +} + +static __inline__ int variable_test_bit(int nr, volatile void * addr) +{ + int oldbit; + + __asm__ __volatile__( + "btl %2,%1\n\tsbbl %0,%0" + :"=r" (oldbit) + :"m" (ADDR),"Ir" (nr)); + return oldbit; +} + +#define test_bit(nr,addr) \ +(__builtin_constant_p(nr) ? \ + constant_test_bit((nr),(addr)) : \ + variable_test_bit((nr),(addr))) + +/** + * find_first_zero_bit - find the first zero bit in a memory region + * @addr: The address to start the search at + * @size: The maximum size to search + * + * Returns the bit-number of the first zero bit, not the number of the byte + * containing a bit. + */ +static __inline__ int find_first_zero_bit(void * addr, unsigned size) +{ + int d0, d1, d2; + int res; + + if (!size) + return 0; + /* This looks at memory. Mark it volatile to tell gcc not to move it around */ + __asm__ __volatile__( + "movl $-1,%%eax\n\t" + "xorl %%edx,%%edx\n\t" + "repe; scasl\n\t" + "je 1f\n\t" + "xorl -4(%%edi),%%eax\n\t" + "subl $4,%%edi\n\t" + "bsfl %%eax,%%edx\n" + "1:\tsubl %%ebx,%%edi\n\t" + "shll $3,%%edi\n\t" + "addl %%edi,%%edx" + :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2) + :"1" ((size + 31) >> 5), "2" (addr), "b" (addr)); + return res; +} + +/** + * find_next_zero_bit - find the first zero bit in a memory region + * @addr: The address to base the search on + * @offset: The bitnumber to start searching at + * @size: The maximum size to search + */ +static __inline__ int find_next_zero_bit (void * addr, int size, int offset) +{ + unsigned long * p = ((unsigned long *) addr) + (offset >> 5); + int set = 0, bit = offset & 31, res; + + if (bit) { + /* + * Look for zero in first byte + */ + __asm__("bsfl %1,%0\n\t" + "jne 1f\n\t" + "movl $32, %0\n" + "1:" + : "=r" (set) + : "r" (~(*p >> bit))); + if (set < (32 - bit)) + return set + offset; + set = 32 - bit; + p++; + } + /* + * No zero yet, search remaining full bytes for a zero + */ + res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); + return (offset + set + res); +} + +/** + * ffz - find first zero in word. + * @word: The word to search + * + * Undefined if no zero exists, so code should check against ~0UL first. + */ +static __inline__ unsigned long ffz(unsigned long word) +{ + __asm__("bsfl %1,%0" + :"=r" (word) + :"r" (~word)); + return word; +} + +#ifdef __KERNEL__ + +/** + * ffs - find first bit set + * @x: the word to search + * + * This is defined the same way as + * the libc and compiler builtin ffs routines, therefore + * differs in spirit from the above ffz (man ffs). + */ +static __inline__ int ffs(int x) +{ + int r; + + __asm__("bsfl %1,%0\n\t" + "jnz 1f\n\t" + "movl $-1,%0\n" + "1:" : "=r" (r) : "g" (x)); + return r+1; +} + +/** + * hweightN - returns the hamming weight of a N-bit word + * @x: the word to weigh + * + * The Hamming Weight of a number is the total number of bits set in it. + */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +#endif /* __KERNEL__ */ + +#ifdef __KERNEL__ + +#define ext2_set_bit __test_and_set_bit +#define ext2_clear_bit __test_and_clear_bit +#define ext2_test_bit test_bit +#define ext2_find_first_zero_bit find_first_zero_bit +#define ext2_find_next_zero_bit find_next_zero_bit + +/* Bitmap functions for the minix filesystem. */ +#define minix_test_and_set_bit(nr,addr) __test_and_set_bit(nr,addr) +#define minix_set_bit(nr,addr) __set_bit(nr,addr) +#define minix_test_and_clear_bit(nr,addr) __test_and_clear_bit(nr,addr) +#define minix_test_bit(nr,addr) test_bit(nr,addr) +#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) + +#endif /* __KERNEL__ */ + +#endif /* _I386_BITOPS_H */ diff --git a/include/asm-i386/byteorder.h b/include/asm-i386/byteorder.h new file mode 100644 index 000000000..bbfb629fa --- /dev/null +++ b/include/asm-i386/byteorder.h @@ -0,0 +1,47 @@ +#ifndef _I386_BYTEORDER_H +#define _I386_BYTEORDER_H + +#include + +#ifdef __GNUC__ + +/* For avoiding bswap on i386 */ +#ifdef __KERNEL__ +#include +#endif + +static __inline__ __const__ __u32 ___arch__swab32(__u32 x) +{ +#ifdef CONFIG_X86_BSWAP + __asm__("bswap %0" : "=r" (x) : "0" (x)); +#else + __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ + "rorl $16,%0\n\t" /* swap words */ + "xchgb %b0,%h0" /* swap higher bytes */ + :"=q" (x) + : "0" (x)); +#endif + return x; +} + +static __inline__ __const__ __u16 ___arch__swab16(__u16 x) +{ + __asm__("xchgb %b0,%h0" /* swap bytes */ \ + : "=q" (x) \ + : "0" (x)); \ + return x; +} + +#define __arch__swab32(x) ___arch__swab32(x) +#define __arch__swab16(x) ___arch__swab16(x) + +#if !defined(__STRICT_ANSI__) || defined(__KERNEL__) +# define __BYTEORDER_HAS_U64__ +# define __SWAB_64_THRU_32__ +#endif + +#endif /* __GNUC__ */ + +#include + +#endif /* _I386_BYTEORDER_H */ diff --git a/include/asm-i386/global_data.h b/include/asm-i386/global_data.h new file mode 100644 index 000000000..324b4357f --- /dev/null +++ b/include/asm-i386/global_data.h @@ -0,0 +1,60 @@ +/* + * (C) Copyright 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_GBL_DATA_H +#define __ASM_GBL_DATA_H +/* + * The following data structure is placed in some memory wich is + * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or + * some locked parts of the data cache) to allow for a minimum set of + * global variables during system initialization (until we have set + * up the memory controller so that we can use RAM). + * + * Keep it *SMALL* and remember to set CFG_GBL_DATA_SIZE > sizeof(gd_t) + */ + +typedef struct { + bd_t *bd; + unsigned long flags; + unsigned long baudrate; + unsigned long have_console; /* serial_init() was called */ + unsigned long reloc_off; /* Relocation Offset */ + unsigned long env_addr; /* Address of Environment struct */ + unsigned long env_valid; /* Checksum of Environment valid? */ + unsigned long cpu_clk; /* CPU clock in Hz! */ + unsigned long bus_clk; + unsigned long ram_size; /* RAM size */ + unsigned long reset_status; /* reset status register at boot */ +} gd_t; + +/* + * Global Data Flags + */ +#define GD_FLG_RELOC 0x00001 /* Code was relocated to RAM */ +#define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */ + +extern gd_t *global_data; + +#define DECLARE_GLOBAL_DATA_PTR gd_t *gd = global_data + +#endif /* __ASM_GBL_DATA_H */ diff --git a/include/asm-i386/i8254.h b/include/asm-i386/i8254.h new file mode 100644 index 000000000..e13f04e58 --- /dev/null +++ b/include/asm-i386/i8254.h @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +/* i8254.h Intel 8254 PIT registers */ + + +#ifndef _ASMI386_I8254_H_ +#define _ASMI386_I8954_H_ 1 + + + +#define PIT_T0 0x00 /* PIT channel 0 count/status */ +#define PIT_T1 0x01 /* PIT channel 1 count/status */ +#define PIT_T2 0x02 /* PIT channel 2 count/status */ +#define PIT_COMMAND 0x03 /* PIT mode control, latch and read back */ + +/* PIT Command Register Bit Definitions */ + +#define PIT_CMD_CTR0 0x00 /* Select PIT counter 0 */ +#define PIT_CMD_CTR1 0x40 /* Select PIT counter 1 */ +#define PIT_CMD_CTR2 0x80 /* Select PIT counter 2 */ + +#define PIT_CMD_LATCH 0x00 /* Counter Latch Command */ +#define PIT_CMD_LOW 0x10 /* Access counter bits 7-0 */ +#define PIT_CMD_HIGH 0x20 /* Access counter bits 15-8 */ +#define PIT_CMD_BOTH 0x30 /* Access counter bits 15-0 in two accesses */ + +#define PIT_CMD_MODE0 0x00 /* Select mode 0 */ +#define PIT_CMD_MODE1 0x02 /* Select mode 1 */ +#define PIT_CMD_MODE2 0x04 /* Select mode 2 */ +#define PIT_CMD_MODE3 0x06 /* Select mode 3 */ +#define PIT_CMD_MODE4 0x08 /* Select mode 4 */ +#define PIT_CMD_MODE5 0x0A /* Select mode 5 */ + +#endif diff --git a/include/asm-i386/i8259.h b/include/asm-i386/i8259.h new file mode 100644 index 000000000..0419e0e26 --- /dev/null +++ b/include/asm-i386/i8259.h @@ -0,0 +1,88 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* i8259.h i8259 PIC Registers */ + +#ifndef _ASMI386_I8259_H_ +#define _ASMI386_I8959_H_ 1 + + +/* PIC I/O mapped registers */ + +#define IRR 0x0 /* Interrupt Request Register */ +#define ISR 0x0 /* In-Service Register */ +#define ICW1 0x0 /* Initialization Control Word 1 */ +#define OCW2 0x0 /* Operation Control Word 2 */ +#define OCW3 0x0 /* Operation Control Word 3 */ +#define ICW2 0x1 /* Initialization Control Word 2 */ +#define ICW3 0x1 /* Initialization Control Word 3 */ +#define ICW4 0x1 /* Initialization Control Word 4 */ +#define IMR 0x1 /* Interrupt Mask Register */ + +/* bits for IRR, IMR, ISR and ICW3 */ +#define IR7 0x80 /* IR7 */ +#define IR6 0x40 /* IR6 */ +#define IR5 0x20 /* IR5 */ +#define IR4 0x10 /* IR4 */ +#define IR3 0x08 /* IR3 */ +#define IR2 0x04 /* IR2 */ +#define IR1 0x02 /* IR1 */ +#define IR0 0x01 /* IR0 */ + +/* bits for SEOI */ +#define SEOI_IR7 0x07 /* IR7 */ +#define SEOI_IR6 0x06 /* IR6 */ +#define SEOI_IR5 0x05 /* IR5 */ +#define SEOI_IR4 0x04 /* IR4 */ +#define SEOI_IR3 0x03 /* IR3 */ +#define SEOI_IR2 0x02 /* IR2 */ +#define SEOI_IR1 0x01 /* IR1 */ +#define SEOI_IR0 0x00 /* IR0 */ + +/* OCW2 bits */ +#define OCW2_RCLR 0x00 /* Rotate/clear */ +#define OCW2_NEOI 0x20 /* Non specific EOI */ +#define OCW2_NOP 0x40 /* NOP */ +#define OCW2_SEOI 0x60 /* Specific EOI */ +#define OCW2_RSET 0x80 /* Rotate/set */ +#define OCW2_REOI 0xA0 /* Rotate on non specific EOI */ +#define OCW2_PSET 0xC0 /* Priority Set Command */ +#define OCW2_RSEOI 0xE0 /* Rotate on specific EOI */ + +/* ICW1 bits */ +#define ICW1_SEL 0x10 /* Select ICW1 */ +#define ICW1_LTIM 0x08 /* Level-Triggered Interrupt Mode */ +#define ICW1_ADI 0x04 /* Address Interval */ +#define ICW1_SNGL 0x02 /* Single PIC */ +#define ICW1_EICW4 0x01 /* Expect initilization ICW4 */ + +/* ICW2 is the starting vector number */ + +/* ICW2 is bit-mask of present slaves for a master device, + * or the slave ID for a slave device */ + +/* ICW4 bits */ +#define ICW4_AEOI 0x02 /* Automatic EOI Mode */ +#define ICW4_PM 0x01 /* Microprocessor Mode */ + +#endif diff --git a/include/asm-i386/ibmpc.h b/include/asm-i386/ibmpc.h new file mode 100644 index 000000000..abdd1d762 --- /dev/null +++ b/include/asm-i386/ibmpc.h @@ -0,0 +1,47 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_IBMPC_H_ +#define __ASM_IBMPC_H_ 1 + +/* misc ports in an ibm compatible pc */ + +#define MASTER_PIC 0x20 +#define PIT_BASE 0x40 +#define KBDDATA 0x60 +#define SYSCTLB 0x62 +#define KBDCMD 0x64 +#define SYSCTLA 0x92 +#define SLAVE_PIC 0xa0 + +#if 1 +#define UART0_BASE 0x3f8 +#define UART1_BASE 0x2f8 +#else +/* FixMe: uarts swapped */ +#define UART0_BASE 0x2f8 +#define UART1_BASE 0x3f8 +#endif + + +#endif diff --git a/include/asm-i386/ic/ali512x.h b/include/asm-i386/ic/ali512x.h new file mode 100644 index 000000000..5bc1bd790 --- /dev/null +++ b/include/asm-i386/ic/ali512x.h @@ -0,0 +1,54 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB . + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_IC_ALI512X_H_ +#define __ASM_IC_ALI512X_H_ + +# define ALI_INDEX 0x3f0 +# define ALI_DATA 0x3f1 + +# define ALI_ENABLED 1 +# define ALI_DISABLED 0 + +# define ALI_UART1 0 +# define ALI_UART2 1 + +/* setup functions */ +void ali512x_init(void); +void ali512x_set_fdc(int enabled, u16 io, u8 irq, u8 dma_channel); +void ali512x_set_pp(int enabled, u16 io, u8 irq, u8 dma_channel); +void ali512x_set_uart(int enabled, int index, u16 io, u8 irq); +void ali512x_set_rtc(int enabled, u16 io, u8 irq); +void ali512x_set_kbc(int enabled, u8 kbc_irq, u8 mouse_irq); +void ali512x_set_cio(int enabled); + + +/* common I/O functions */ +void ali512x_cio_function(int pin, int special, int inv, int input); +void ali512x_cio_out(int pin, int value); +int ali512x_cio_in(int pin); + +/* misc features */ +void ali512x_set_uart2_irda(int enabled); + +#endif diff --git a/include/asm-i386/ic/sc520.h b/include/asm-i386/ic/sc520.h new file mode 100644 index 000000000..9708504e3 --- /dev/null +++ b/include/asm-i386/ic/sc520.h @@ -0,0 +1,249 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB . + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _ASM_IC_SC520_H_ +#define _ASM_IC_SC520_H_ 1 + +/* Memory mapped configuration registers, MMCR */ +#define SC520_REVID 0x0000 /* ElanSC520 Microcontroller Revision ID Register */ +#define SC520_CPUCTL 0x0002 /* Am5x86 CPU Control Register */ +#define SC520_DRCCTL 0x0010 /* SDRAM Control Register */ +#define SC520_DRCTMCTL 0x0012 /* SDRAM Timing Control Register */ +#define SC520_DRCCFG 0x0014 /* SDRAM Bank Configuration Register*/ +#define SC520_DRCBENDADR 0x0018 /* SDRAM Bank 0-3 Ending Address Register*/ +#define SC520_ECCCTL 0x0020 /* ECC Control Register */ +#define SC520_ECCSTA 0x0021 /* ECC Status Register */ +#define SC520_ECCCKBPOS 0x0022 /* ECC Check Bit Position Register */ +#define SC520_ECCSBADD 0x0024 /* ECC Single-Bit Error Address Register */ +#define SC520_DBCTL 0x0040 /* SDRAM Buffer Control Register */ +#define SC520_BOOTCSCTL 0x0050 /* /BOOTCS Control Register */ +#define SC520_ROMCS1CTL 0x0054 /* /ROMCS1 Control Register */ +#define SC520_ROMCS2CTL 0x0056 /* /ROMCS2 Control Register */ +#define SC520_HBCTL 0x0060 /* Host Bridge Control Register */ +#define SC520_HBTGTIRQCTL 0x0062 /* Host Bridge Target Interrupt Control Register */ +#define SC520_HBTGTIRQSTA 0x0064 /* Host Bridge Target Interrupt Status Register */ +#define SC520_HBMSTIRQCTL 0x0066 /* Host Bridge Target Interrupt Control Register */ +#define SC520_HBMSTIRQSTA 0x0068 /* Host Bridge Master Interrupt Status Register */ +#define SC520_MSTINTADD 0x006c /* Host Bridge Master Interrupt Address Register */ +#define SC520_SYSARBCTL 0x0070 /* System Arbiter Control Register */ +#define SC520_PCIARBSTA 0x0071 /* PCI Bus Arbiter Status Register */ +#define SC520_SYSARBMENB 0x0072 /* System Arbiter Master Enable Register */ +#define SC520_ARBPRICTL 0x0074 /* Arbiter Priority Control Register */ +#define SC520_ADDDECCTL 0x0080 /* Address Decode Control Register */ +#define SC520_WPVSTA 0x0082 /* Write-Protect Violation Status Register */ +#define SC520_PAR0 0x0088 /* Programmable Address Region 0 Register */ +#define SC520_PAR1 0x008c /* Programmable Address Region 1 Register */ +#define SC520_PAR2 0x0090 /* Programmable Address Region 2 Register */ +#define SC520_PAR3 0x0094 /* Programmable Address Region 3 Register */ +#define SC520_PAR4 0x0098 /* Programmable Address Region 4 Register */ +#define SC520_PAR5 0x009c /* Programmable Address Region 5 Register */ +#define SC520_PAR6 0x00a0 /* Programmable Address Region 6 Register */ +#define SC520_PAR7 0x00a4 /* Programmable Address Region 7 Register */ +#define SC520_PAR8 0x00a8 /* Programmable Address Region 8 Register */ +#define SC520_PAR9 0x00ac /* Programmable Address Region 9 Register */ +#define SC520_PAR10 0x00b0 /* Programmable Address Region 10 Register */ +#define SC520_PAR11 0x00b4 /* Programmable Address Region 11 Register */ +#define SC520_PAR12 0x00b8 /* Programmable Address Region 12 Register */ +#define SC520_PAR13 0x00bc /* Programmable Address Region 13 Register */ +#define SC520_PAR14 0x00c0 /* Programmable Address Region 14 Register */ +#define SC520_PAR15 0x00c4 /* Programmable Address Region 15 Register */ +#define SC520_GPECHO 0x0c00 /* GP Echo Mode Register */ +#define SC520_GPCSDW 0x0c01 /* GP Chip Select Data Width Register */ +#define SC520_GPCSQUAL 0x0c02 /* GP Chip Select Qualification Register */ +#define SC520_GPCSRT 0x0c08 /* GP Chip Select Recovery Time Register */ +#define SC520_GPCSPW 0x0c09 /* GP Chip Select Pulse Width Register */ +#define SC520_GPCSOFF 0x0c0a /* GP Chip Select Offset Register */ +#define SC520_GPRDW 0x0c0b /* GP Read Pulse Width Register */ +#define SC520_GPRDOFF 0x0c0c /* GP Read Offset Register */ +#define SC520_GPWRW 0x0c0d /* GP Write Pulse Width Register */ +#define SC520_GPWROFF 0x0c0e /* GP Write Offset Register */ +#define SC520_GPALEW 0x0c0f /* GP ALE Pulse Width Register */ +#define SC520_GPALEOFF 0x0c10 /* GP ALE Offset Register */ +#define SC520_PIOPFS15_0 0x0c20 /* PIO15-PIO0 Pin Function Select */ +#define SC520_PIOPFS31_16 0x0c22 /* PIO31-PIO16 Pin Function Select */ +#define SC520_CSPFS 0x0c24 /* Chip Select Pin Function Select */ +#define SC520_CLKSEL 0x0c26 /* Clock Select */ +#define SC520_DSCTL 0x0c28 /* Drive Strength Control */ +#define SC520_PIODIR15_0 0x0c2a /* PIO15-PIO0 Direction */ +#define SC520_PIODIR31_16 0x0c2c /* PIO31-PIO16 Direction */ +#define SC520_PIODATA15_0 0x0c30 /* PIO15-PIO0 Data */ +#define SC520_PIODATA31_16 0x0c32 /* PIO31-PIO16 Data */ +#define SC520_PIOSET15_0 0x0c34 /* PIO15-PIO0 Set */ +#define SC520_PIOSET31_16 0x0c36 /* PIO31-PIO16 Set */ +#define SC520_PIOCLR15_0 0x0c38 /* PIO15-PIO0 Clear */ +#define SC520_PIOCLR31_16 0x0c3a /* PIO31-PIO16 Clear */ +#define SC520_SWTMRMILLI 0x0c60 /* Software Timer Millisecond Count */ +#define SC520_SWTMRMICRO 0x0c62 /* Software Timer Microsecond Count */ +#define SC520_SWTMRCFG 0x0c64 /* Software Timer Configuration */ +#define SC520_GPTMRSTA 0x0c70 /* GP Timers Status Register */ +#define SC520_GPTMR0CTL 0x0c72 /* GP Timer 0 Mode/Control Register */ +#define SC520_GPTMR0CNT 0x0c74 /* GP Timer 0 Count Register */ +#define SC520_GPTMR0MAXCMPA 0x0c76 /* GP Timer 0 Maxcount Compare A Register */ +#define SC520_GPTMR0MAXCMPB 0x0c78 /* GP Timer 0 Maxcount Compare B Register */ +#define SC520_GPTMR1CTL 0x0c7a /* GP Timer 1 Mode/Control Register */ +#define SC520_GPTMR1CNT 0x0c7c /* GP Timer 1 Count Register */ +#define SC520_GPTMR1MAXCMPA 0x0c7e /* GP Timer 1 Maxcount Compare Register A */ +#define SC520_GPTMR1MAXCMPB 0x0c80 /* GP Timer 1 Maxcount Compare B Register */ +#define SC520_GPTMR2CTL 0x0c82 /* GP Timer 2 Mode/Control Register */ +#define SC520_GPTMR2CNT 0x0c84 /* GP Timer 2 Count Register */ +#define SC520_GPTMR2MAXCMPA 0x0c8e /* GP Timer 2 Maxcount Compare A Register */ +#define SC520_WDTMRCTL 0x0cb0 /* Watchdog Timer Control Register */ +#define SC520_WDTMRCNTL 0x0cb2 /* Watchdog Timer Count Low Register */ +#define SC520_WDTMRCNTH 0x0cb4 /* Watchdog Timer Count High Register */ +#define SC520_UART1CTL 0x0cc0 /* UART 1 General Control Register */ +#define SC520_UART1STA 0x0cc1 /* UART 1 General Status Register */ +#define SC520_UART1FCRSHAD 0x0cc2 /* UART 1 FIFO Control Shadow Register */ +#define SC520_UART2CTL 0x0cc4 /* UART 2 General Control Register */ +#define SC520_UART2STA 0x0cc5 /* UART 2 General Status Register */ +#define SC520_UART2FCRSHAD 0x0cc6 /* UART 2 FIFO Control Shadow Register */ +#define SC520_PICICR 0x0d00 /* Interrupt Control Register */ +#define SC520_MPICMODE 0x0d02 /* Master PIC Interrupt Mode Register */ +#define SC520_SL1PICMODE 0x0d03 /* Slave 1 PIC Interrupt Mode Register */ +#define SC520_SL2PICMODE 0x0d04 /* Slave 2 PIC Interrupt Mode Register */ +#define SC520_SWINT16_1 0x0d08 /* Software Interrupt 16-1 Control Register */ +#define SC520_SWINT22_17 0x0d0a /* Software Interrupt 22-17/NMI Control Register */ +#define SC520_INTPINPOL 0x0d10 /* Interrupt Pin Polarity Register */ +#define SC520_PCIHOSTMAP 0x0d14 /* PCI Host Bridge Interrupt Mappin Register */ +#define SC520_ECCMAP 0x0d18 /* ECC Interrupt Mapping Register */ +#define SC520_GPTMR0MAP 0x0d1a /* GP Timer 0 Interrupt Mapping Register */ +#define SC520_GPTMR1MAP 0x0d1b /* GP Timer 1 Interrupt Mapping Register */ +#define SC520_GPTMR2MAP 0x0d1c /* GP Timer 2 Interrupt Mapping Register */ +#define SC520_PIT0MAP 0x0d20 /* PIT0 Interrupt Mapping Register */ +#define SC520_PIT1MAP 0x0d21 /* PIT1 Interrupt Mapping Register */ +#define SC520_PIT2MAP 0x0d22 /* PIT2 Interrupt Mapping Register */ +#define SC520_UART1MAP 0x0d28 /* UART 1 Interrupt Mapping Register */ +#define SC520_UART2MAP 0x0d29 /* UART 2 Interrupt Mapping Register */ +#define SC520_PCIINTAMAP 0x0d30 /* PCI Interrupt A Mapping Register */ +#define SC520_PCIINTBMAP 0x0d31 /* PCI Interrupt B Mapping Register */ +#define SC520_PCIINTCMAP 0x0d32 /* PCI Interrupt C Mapping Register */ +#define SC520_PCIINTDMAP 0x0d33 /* PCI Interrupt D Mapping Register */ +#define SC520_DMABCINTMAP 0x0d40 /* DMA Buffer Chaining Interrupt Mapping Register */ +#define SC520_SSIMAP 0x0d41 /* SSI Interrupt Mapping Register */ +#define SC520_WDTMAP 0x0d42 /* Watchdog Timer Interrupt Mapping Register */ +#define SC520_RTCMAP 0x0d43 /* RTC Interrupt Mapping Register */ +#define SC520_WPVMAP 0x0d44 /* Write-Protect Interrupt Mapping Register */ +#define SC520_ICEMAP 0x0d45 /* AMDebug JTAG RX/TX Interrupt Mapping Register */ +#define SC520_FERRMAP 0x0d46 /* Floating Point Error Interrupt Mapping Register */ +#define SC520_GP0IMAP 0x0d50 /* GPIRQ0 Interrupt Mapping Register */ +#define SC520_GP1IMAP 0x0d51 /* GPIRQ1 Interrupt Mapping Register */ +#define SC520_GP2IMAP 0x0d52 /* GPIRQ2 Interrupt Mapping Register */ +#define SC520_GP3IMAP 0x0d53 /* GPIRQ3 Interrupt Mapping Register */ +#define SC520_GP4IMAP 0x0d54 /* GPIRQ4 Interrupt Mapping Register */ +#define SC520_GP5IMAP 0x0d55 /* GPIRQ5 Interrupt Mapping Register */ +#define SC520_GP6IMAP 0x0d56 /* GPIRQ6 Interrupt Mapping Register */ +#define SC520_GP7IMAP 0x0d57 /* GPIRQ7 Interrupt Mapping Register */ +#define SC520_GP8IMAP 0x0d58 /* GPIRQ8 Interrupt Mapping Register */ +#define SC520_GP9IMAP 0x0d59 /* GPIRQ9 Interrupt Mapping Register */ +#define SC520_GP10IMAP 0x0d5a /* GPIRQ10 Interrupt Mapping Register */ +#define SC520_SYSINFO 0x0d70 /* System Board Information Register */ +#define SC520_RESCFG 0x0d72 /* Reset Configuration Register */ +#define SC520_RESSTA 0x0d74 /* Reset Status Register */ +#define SC520_GPDMAMMIO 0x0d81 /* GP-DMA Memory-Mapped I/O Register */ +#define SC520_GPDMAEXTCHMAPA 0x0d82 /* GP-DMA Resource Channel Map A */ +#define SC520_GPDMAEXTCHMAPB 0x0d84 /* GP-DMA Resource Channel Map B */ +#define SC520_GPDMAEXTPG0 0x0d86 /* GP-DMA Channel 0 Extended Page */ +#define SC520_GPDMAEXTPG1 0x0d87 /* GP-DMA Channel 1 Extended Page */ +#define SC520_GPDMAEXTPG2 0x0d88 /* GP-DMA Channel 2 Extended Page */ +#define SC520_GPDMAEXTPG3 0x0d89 /* GP-DMA Channel 3 Extended Page */ +#define SC520_GPDMAEXTPG5 0x0d8a /* GP-DMA Channel 5 Extended Page */ +#define SC520_GPDMAEXTPG6 0x0d8b /* GP-DMA Channel 6 Extended Page */ +#define SC520_GPDMAEXTPG7 0x0d8c /* GP-DMA Channel 7 Extended Page */ +#define SC520_GPDMAEXTTC3 0x0d90 /* GP-DMA Channel 3 Extender Transfer count */ +#define SC520_GPDMAEXTTC5 0x0d91 /* GP-DMA Channel 5 Extender Transfer count */ +#define SC520_GPDMAEXTTC6 0x0d92 /* GP-DMA Channel 6 Extender Transfer count */ +#define SC520_GPDMAEXTTC7 0x0d93 /* GP-DMA Channel 7 Extender Transfer count */ +#define SC520_GPDMABCCTL 0x0d98 /* Buffer Chaining Control */ +#define SC520_GPDMABCSTA 0x0d99 /* Buffer Chaining Status */ +#define SC520_GPDMABSINTENB 0x0d9a /* Buffer Chaining Interrupt Enable */ +#define SC520_GPDMABCVAL 0x0d9b /* Buffer Chaining Valid */ +#define SC520_GPDMANXTADDL3 0x0da0 /* GP-DMA Channel 3 Next Address Low */ +#define SC520_GPDMANXTADDH3 0x0da2 /* GP-DMA Channel 3 Next Address High */ +#define SC520_GPDMANXTADDL5 0x0da4 /* GP-DMA Channel 5 Next Address Low */ +#define SC520_GPDMANXTADDH5 0x0da6 /* GP-DMA Channel 5 Next Address High */ +#define SC520_GPDMANXTADDL6 0x0da8 /* GP-DMA Channel 6 Next Address Low */ +#define SC520_GPDMANXTADDH6 0x0daa /* GP-DMA Channel 6 Next Address High */ +#define SC520_GPDMANXTADDL7 0x0dac /* GP-DMA Channel 7 Next Address Low */ +#define SC520_GPDMANXTADDH7 0x0dae /* GP-DMA Channel 7 Next Address High */ +#define SC520_GPDMANXTTCL3 0x0db0 /* GP-DMA Channel 3 Next Transfer Count Low */ +#define SC520_GPDMANXTTCH3 0x0db2 /* GP-DMA Channel 3 Next Transfer Count High */ +#define SC520_GPDMANXTTCL5 0x0db4 /* GP-DMA Channel 5 Next Transfer Count Low */ +#define SC520_GPDMANXTTCH5 0x0db6 /* GP-DMA Channel 5 Next Transfer Count High */ +#define SC520_GPDMANXTTCL6 0x0db8 /* GP-DMA Channel 6 Next Transfer Count Low */ +#define SC520_GPDMANXTTCH6 0x0dba /* GP-DMA Channel 6 Next Transfer Count High */ +#define SC520_GPDMANXTTCL7 0x0dbc /* GP-DMA Channel 7 Next Transfer Count Low */ +#define SC520_GPDMANXTTCH7 0x0dbe /* GP-DMA Channel 7 Next Transfer Count High */ + +/* MMCR Register bits (not all of them :) ) */ + +/* BITS for SC520_ADDDECCTL: */ +#define WPV_INT_ENB 0x80 /* Write-Protect Violation Interrupt Enable */ +#define IO_HOLE_DEST 0x10 /* I/O Hole Access Destination */ +#define RTC_DIS 0x04 /* RTC Disable */ +#define UART2_DIS 0x02 /* UART2 Disable */ +#define UART1_DIS 0x01 /* UART1 Disable */ + +/* bus mapping constants (used for PCI core initialization) */ /* bus mapping constants */ +#define SC520_REG_ADDR 0x00000cf8 +#define SC520_REG_DATA 0x00000cfc + + +#define SC520_ISA_MEM_PHYS 0x00000000 +#define SC520_ISA_MEM_BUS 0x00000000 +#define SC520_ISA_MEM_SIZE 0x01000000 + +#define SC520_ISA_IO_PHYS 0x00000000 +#define SC520_ISA_IO_BUS 0x00000000 +#define SC520_ISA_IO_SIZE 0x00001000 + +/* PCI I/O space from 0x1000 to 0xfdff */ +#define SC520_PCI_IO_PHYS 0x00001000 +#define SC520_PCI_IO_BUS 0x00001000 +#define SC520_PCI_IO_SIZE 0x0000ee00 + +/* system memory from 0x00000000 to 0x0fffffff */ +#define SC520_PCI_MEMORY_PHYS 0x00000000 +#define SC520_PCI_MEMORY_BUS 0x00000000 +#define SC520_PCI_MEMORY_SIZE 0x10000000 + +/* PCI bus memory from 0x10000000 to 0x27ffffff */ +#define SC520_PCI_MEM_PHYS 0x10000000 +#define SC520_PCI_MEM_BUS 0x10000000 +#define SC520_PCI_MEM_SIZE 0x18000000 + +/* 0x28000000 - 0x3fffffff is used by the flash banks */ + +/* 0x40000000 - 0xffffffff is not adressable by the SC520 */ + +/* utility functions */ +void write_mmcr_byte(u16 mmcr, u8 data); +void write_mmcr_word(u16 mmcr, u16 data); +void write_mmcr_long(u16 mmcr, u32 data); +u8 read_mmcr_byte(u16 mmcr); +u16 read_mmcr_word(u16 mmcr); +u32 read_mmcr_long(u16 mmcr); + +void init_sc520(void); +unsigned long init_sc520_dram(void); +void pci_sc520_init(struct pci_controller *hose); + +#endif diff --git a/include/asm-i386/io.h b/include/asm-i386/io.h new file mode 100644 index 000000000..d8c503ccb --- /dev/null +++ b/include/asm-i386/io.h @@ -0,0 +1,207 @@ +#ifndef _ASM_IO_H +#define _ASM_IO_H + +#include + +/* + * This file contains the definitions for the x86 IO instructions + * inb/inw/inl/outb/outw/outl and the "string versions" of the same + * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing" + * versions of the single-IO instructions (inb_p/inw_p/..). + * + * This file is not meant to be obfuscating: it's just complicated + * to (a) handle it all in a way that makes gcc able to optimize it + * as well as possible and (b) trying to avoid writing the same thing + * over and over again with slight variations and possibly making a + * mistake somewhere. + */ + +/* + * Thanks to James van Artsdalen for a better timing-fix than + * the two short jumps: using outb's to a nonexistent port seems + * to guarantee better timings even on fast machines. + * + * On the other hand, I'd like to be sure of a non-existent port: + * I feel a bit unsafe about using 0x80 (should be safe, though) + * + * Linus + */ + + /* + * Bit simplified and optimized by Jan Hubicka + * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999. + * + * isa_memset_io, isa_memcpy_fromio, isa_memcpy_toio added, + * isa_read[wl] and isa_write[wl] fixed + * - Arnaldo Carvalho de Melo + */ + +#define IO_SPACE_LIMIT 0xffff + + +#ifdef __KERNEL__ + + +/* + * readX/writeX() are used to access memory mapped devices. On some + * architectures the memory mapped IO stuff needs to be accessed + * differently. On the x86 architecture, we just read/write the + * memory location directly. + */ + +#define readb(addr) (*(volatile unsigned char *) (addr)) +#define readw(addr) (*(volatile unsigned short *) (addr)) +#define readl(addr) (*(volatile unsigned int *) (addr)) +#define __raw_readb readb +#define __raw_readw readw +#define __raw_readl readl + +#define writeb(b,addr) (*(volatile unsigned char *) (addr) = (b)) +#define writew(b,addr) (*(volatile unsigned short *) (addr) = (b)) +#define writel(b,addr) (*(volatile unsigned int *) (addr) = (b)) +#define __raw_writeb writeb +#define __raw_writew writew +#define __raw_writel writel + +#define memset_io(a,b,c) memset((a),(b),(c)) +#define memcpy_fromio(a,b,c) memcpy((a),(b),(c)) +#define memcpy_toio(a,b,c) memcpy((a),(b),(c)) + +/* + * ISA space is 'always mapped' on a typical x86 system, no need to + * explicitly ioremap() it. The fact that the ISA IO space is mapped + * to PAGE_OFFSET is pure coincidence - it does not mean ISA values + * are physical addresses. The following constant pointer can be + * used as the IO-area pointer (it can be iounmapped as well, so the + * analogy with PCI is quite large): + */ +#define isa_readb(a) readb((a)) +#define isa_readw(a) readw((a)) +#define isa_readl(a) readl((a)) +#define isa_writeb(b,a) writeb(b,(a)) +#define isa_writew(w,a) writew(w,(a)) +#define isa_writel(l,a) writel(l,(a)) +#define isa_memset_io(a,b,c) memset_io((a),(b),(c)) +#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),(b),(c)) +#define isa_memcpy_toio(a,b,c) memcpy_toio((a),(b),(c)) + + + +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; +} + +/** + * isa_check_signature - find BIOS signatures + * @io_addr: mmio address to check + * @signature: signature block + * @length: length of signature + * + * Perform a signature comparison with the ISA mmio address io_addr. + * Returns 1 on a match. + * + * This function is deprecated. New drivers should use ioremap and + * check_signature. + */ + + +static inline int isa_check_signature(unsigned long io_addr, + const unsigned char *signature, int length) +{ + int retval = 0; + do { + if (isa_readb(io_addr) != *signature) + goto out; + io_addr++; + signature++; + length--; + } while (length); + retval = 1; +out: + return retval; +} + +#endif /* __KERNEL__ */ + +#ifdef SLOW_IO_BY_JUMPING +#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:" +#else +#define __SLOW_DOWN_IO "\noutb %%al,$0x80" +#endif + +#ifdef REALLY_SLOW_IO +#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO +#else +#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO +#endif + + +/* + * Talk about misusing macros.. + */ +#define __OUT1(s,x) \ +static inline void out##s(unsigned x value, unsigned short port) { + +#define __OUT2(s,s1,s2) \ +__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1" + + +#define __OUT(s,s1,x) \ +__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \ +__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} + +#define __IN1(s) \ +static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v; + +#define __IN2(s,s1,s2) \ +__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0" + +#define __IN(s,s1,i...) \ +__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \ +__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } + +#define __INS(s) \ +static inline void ins##s(unsigned short port, void * addr, unsigned long count) \ +{ __asm__ __volatile__ ("rep ; ins" #s \ +: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); } + +#define __OUTS(s) \ +static inline void outs##s(unsigned short port, const void * addr, unsigned long count) \ +{ __asm__ __volatile__ ("rep ; outs" #s \ +: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); } + +#define RETURN_TYPE unsigned char +__IN(b,"") +#undef RETURN_TYPE +#define RETURN_TYPE unsigned short +__IN(w,"") +#undef RETURN_TYPE +#define RETURN_TYPE unsigned int +__IN(l,"") +#undef RETURN_TYPE + +__OUT(b,"b",char) +__OUT(w,"w",short) +__OUT(l,,int) + +__INS(b) +__INS(w) +__INS(l) + +__OUTS(b) +__OUTS(w) +__OUTS(l) + +#endif diff --git a/include/asm-i386/pci.h b/include/asm-i386/pci.h new file mode 100644 index 000000000..15c165b72 --- /dev/null +++ b/include/asm-i386/pci.h @@ -0,0 +1,31 @@ + + +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _PCI_I386_H_ +#define _PCI_I386_H_ 1 + +void pci_setup_type1(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data); + +#endif diff --git a/include/asm-i386/posix_types.h b/include/asm-i386/posix_types.h new file mode 100644 index 000000000..5529f3270 --- /dev/null +++ b/include/asm-i386/posix_types.h @@ -0,0 +1,80 @@ +#ifndef __ARCH_I386_POSIX_TYPES_H +#define __ARCH_I386_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#undef __FD_SET +#define __FD_SET(fd,fdsetp) \ + __asm__ __volatile__("btsl %1,%0": \ + "=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd))) + +#undef __FD_CLR +#define __FD_CLR(fd,fdsetp) \ + __asm__ __volatile__("btrl %1,%0": \ + "=m" (*(__kernel_fd_set *) (fdsetp)):"r" ((int) (fd))) + +#undef __FD_ISSET +#define __FD_ISSET(fd,fdsetp) (__extension__ ({ \ + unsigned char __result; \ + __asm__ __volatile__("btl %1,%2 ; setb %0" \ + :"=q" (__result) :"r" ((int) (fd)), \ + "m" (*(__kernel_fd_set *) (fdsetp))); \ + __result; })) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) \ +do { \ + int __d0, __d1; \ + __asm__ __volatile__("cld ; rep ; stosl" \ + :"=m" (*(__kernel_fd_set *) (fdsetp)), \ + "=&c" (__d0), "=&D" (__d1) \ + :"a" (0), "1" (__FDSET_LONGS), \ + "2" ((__kernel_fd_set *) (fdsetp)) : "memory"); \ +} while (0) + +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */ + +#endif diff --git a/include/asm-i386/ppcboot-i386.h b/include/asm-i386/ppcboot-i386.h new file mode 100644 index 000000000..704526e2f --- /dev/null +++ b/include/asm-i386/ppcboot-i386.h @@ -0,0 +1,53 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _PPCBOOT_I386_H_ +#define _PPCBOOT_I386_H_ 1 + +/* for the following variables, see start.S */ +extern ulong i386boot_start; /* code start (in flash) */ +extern ulong i386boot_end; /* code end (in flash) */ +extern ulong i386boot_romdata_start;/* datasegment in flash (also code+rodata end) */ +extern ulong i386boot_romdata_dest; /* data location segment in ram */ +extern ulong i386boot_romdata_size; /* size of data segment */ +extern ulong i386boot_bss_start; /* bss start */ +extern ulong i386boot_bss_size; /* bss size */ +extern ulong i386boot_stack_end; /* first usable RAM address after bss and stack */ +extern ulong i386boot_ram_end; /* end of ram */ + +extern ulong i386boot_realmode; /* start of realmode entry code */ +extern ulong i386boot_realmode_size;/* size of realmode entry code */ +extern ulong i386boot_bios; /* start of BIOS emulation code */ +extern ulong i386boot_bios_size; /* size of BIOS emulation code */ + + +/* cpu/.../cpu.c */ +int cpu_init(void); +int timer_init(void); + +/* board/.../... */ +int board_init(void); +int dram_init (void); + + +#endif /* _PPCBOOT_I386_H_ */ diff --git a/include/asm-i386/ptrace.h b/include/asm-i386/ptrace.h new file mode 100644 index 000000000..d99e46400 --- /dev/null +++ b/include/asm-i386/ptrace.h @@ -0,0 +1,66 @@ +#ifndef _I386_PTRACE_H +#define _I386_PTRACE_H + +#define EBX 0 +#define ECX 1 +#define EDX 2 +#define ESI 3 +#define EDI 4 +#define EBP 5 +#define EAX 6 +#define DS 7 +#define ES 8 +#define FS 9 +#define GS 10 +#define ORIG_EAX 11 +#define EIP 12 +#define CS 13 +#define EFL 14 +#define UESP 15 +#define SS 16 +#define FRAME_SIZE 17 + +/* this struct defines the way the registers are stored on the + stack during a system call. */ + +struct pt_regs { + long ebx; + long ecx; + long edx; + long esi; + long edi; + long ebp; + long eax; + int xds; + int xes; + int xfs; + int xgs; + long orig_eax; + long eip; + int xcs; + long eflags; + long esp; + int xss; +} __attribute__ ((packed)); + + +/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 +#define PTRACE_GETFPXREGS 18 +#define PTRACE_SETFPXREGS 19 + +#define PTRACE_SETOPTIONS 21 + +/* options set using PTRACE_SETOPTIONS */ +#define PTRACE_O_TRACESYSGOOD 0x00000001 + +#ifdef __KERNEL__ +#define user_mode(regs) ((VM_MASK & (regs)->eflags) || (3 & (regs)->xcs)) +#define instruction_pointer(regs) ((regs)->eip) +extern void show_regs(struct pt_regs *); +#endif + +#endif diff --git a/include/asm-i386/realmode.h b/include/asm-i386/realmode.h new file mode 100644 index 000000000..fcb76c336 --- /dev/null +++ b/include/asm-i386/realmode.h @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_REALMODE_H_ +#define __ASM_REALMODE_H_ +#include + +int bios_setup(void); +int enter_realmode(u16 seg, u16 off, struct pt_regs *in, struct pt_regs *out); + +#endif diff --git a/include/asm-i386/string.h b/include/asm-i386/string.h new file mode 100644 index 000000000..c37822248 --- /dev/null +++ b/include/asm-i386/string.h @@ -0,0 +1,30 @@ +#ifndef __ASM_I386_STRING_H +#define __ASM_I386_STRING_H + +/* + * We don't do inline string functions, since the + * optimised inline asm versions are not small. + */ + +#define __HAVE_ARCH_STRRCHR +extern char * strrchr(const char * s, int c); + +#define __HAVE_ARCH_STRCHR +extern char * strchr(const char * s, int c); + +#define __HAVE_ARCH_MEMCPY +extern void * memcpy(void *, const void *, __kernel_size_t); + +#define __HAVE_ARCH_MEMMOVE +extern void * memmove(void *, const void *, __kernel_size_t); + +#define __HAVE_ARCH_MEMCHR +extern void * memchr(const void *, int, __kernel_size_t); + +#define __HAVE_ARCH_MEMSET +extern void * memset(void *, int, __kernel_size_t); + +#define __HAVE_ARCH_MEMZERO +extern void memzero(void *ptr, __kernel_size_t n); + +#endif diff --git a/include/asm-i386/types.h b/include/asm-i386/types.h new file mode 100644 index 000000000..bb100ec4e --- /dev/null +++ b/include/asm-i386/types.h @@ -0,0 +1,51 @@ +#ifndef __ASM_I386_TYPES_H +#define __ASM_I386_TYPES_H + +typedef unsigned short umode_t; + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#define BITS_PER_LONG 32 + +/* Dma addresses are 32-bits wide. */ + +typedef u32 dma_addr_t; + +#endif /* __KERNEL__ */ + +#endif + diff --git a/include/asm-i386/u-boot.h b/include/asm-i386/u-boot.h new file mode 100644 index 000000000..554bc85ea --- /dev/null +++ b/include/asm-i386/u-boot.h @@ -0,0 +1,58 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _U_BOOT_H_ +#define _U_BOOT_H_ 1 + +typedef struct bd_info { + unsigned long bi_memstart; /* start of DRAM memory */ + unsigned long bi_memsize; /* size of DRAM memory in bytes */ + unsigned long bi_flashstart; /* start of FLASH memory */ + unsigned long bi_flashsize; /* size of FLASH memory */ + unsigned long bi_flashoffset; /* reserved area for startup monitor */ + unsigned long bi_sramstart; /* start of SRAM memory */ + unsigned long bi_sramsize; /* size of SRAM memory */ + unsigned long bi_bootflags; /* boot / reboot flag (for LynxOS) */ + unsigned long bi_ip_addr; /* IP Address */ + unsigned char bi_enetaddr[6]; /* Ethernet adress */ + unsigned short bi_ethspeed; /* Ethernet speed in Mbps */ + unsigned long bi_intfreq; /* Internal Freq, in MHz */ + unsigned long bi_busfreq; /* Bus Freq, in MHz */ + unsigned long bi_baudrate; /* Console Baudrate */ + struct environment_s *bi_env; + struct /* RAM configuration */ + { + ulong start; + ulong size; + }bi_dram[CONFIG_NR_DRAM_BANKS]; +} bd_t; + +#define bi_env_data bi_env->data +#define bi_env_crc bi_env->crc + +#endif /* _U_BOOT_H_ */ diff --git a/include/asm-i386/zimage.h b/include/asm-i386/zimage.h new file mode 100644 index 000000000..688682611 --- /dev/null +++ b/include/asm-i386/zimage.h @@ -0,0 +1,75 @@ +/* + * (C) Copyright 2002 + * Daniel Engström, Omicron Ceti AB, daniel@omicron.se + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _ASM_ZIMAGE_H_ +#define _ASM_ZIMAGE_H_ + +/* linux i386 zImage/bzImage header. Offsets relative to + * the start of the image */ + +#define CMD_LINE_MAGIC_OFF 0x020 /* Magic 0xa33f if the offset below is valid */ +#define CMD_LINE_OFFSET_OFF 0x022 /* Offset to comandline */ +#define SETUP_SECTS_OFF 0x1F1 /* The size of the setup in sectors */ +#define ROOT_FLAGS_OFF 0x1F2 /* If set, the root is mounted readonly */ +#define VID_MODE_OFF 0x1FA /* Video mode control */ +#define ROOT_DEV_OFF 0x1FC /* Default root device number */ +#define BOOT_FLAG_OFF 0x1FE /* 0xAA55 magic number */ +#define HEADER_OFF 0x202 /* Magic signature "HdrS" */ +#define VERSION_OFF 0x206 /* Boot protocol version supported */ +#define REALMODE_SWTCH_OFF 0x208 /* Boot loader hook (see below) */ +#define START_SYS_OFF 0x20C /* Points to kernel version string */ +#define TYPE_OF_LOADER_OFF 0x210 /* Boot loader identifier */ +#define LOADFLAGS_OFF 0x211 /* Boot protocol option flags */ +#define SETUP_MOVE_SIZE_OFF 0x212 /* Move to high memory size (used with hooks) */ +#define CODE32_START_OFF 0x214 /* Boot loader hook (see below) */ +#define RAMDISK_IMAGE_OFF 0x218 /* initrd load address (set by boot loader) */ +#define RAMDISK_SIZE_OFF 0x21C /* initrd size (set by boot loader) */ +#define HEAP_END_PTR_OFF 0x224 /* Free memory after setup end */ +#define CMD_LINE_PTR_OFF 0x228 /* 32-bit pointer to the kernel command line */ + + +#define HEAP_FLAG 0x80 +#define BIG_KERNEL_FLAG 0x01 + +/* magic numbers */ +#define KERNEL_MAGIC 0xaa55 +#define KERNEL_V2_MAGIC 0x53726448 +#define COMMAND_LINE_MAGIC 0xA33F + +/* limits */ +#define BZIMAGE_MAX_SIZE 15*1024*1024 /* 15MB */ +#define ZIMAGE_MAX_SIZE 512*1024 /* 512k */ +#define SETUP_MAX_SIZE 32768 + +#define SETUP_START_OFFSET 0x200 +#define BZIMAGE_LOAD_ADDR 0x100000 +#define ZIMAGE_LOAD_ADDR 0x10000 + +void *load_zimage(char *image, unsigned long kernel_size, + unsigned long initrd_addr, unsigned long initrd_size, + int auto_boot); + +void boot_zimage(void *setup_base); +image_header_t *fake_zimage_header(image_header_t *hdr, void *ptr, int size); + +#endif -- cgit v1.2.3